diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..57958d7af8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,50 @@ +# Prerequisites +*.d + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app + +# java +*.class + + +# ignore some directory +build +build/** +deps +deps/** +libraftseal.bak +libraftseal.bak/** +tool/java/web3j-v2.1.0_src/bin +tool/java/web3j-v2.1.0_src/bin/** +tool/java/JuDfsSDK/bin +tool/java/JuDfsSDK/bin/** + + diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000000..08cc4d6c3a --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,95 @@ +#------------------------------------------------------------------------------ +# Top-level CMake file for cpp-ethereum. +# +# The documentation for cpp-ethereum is hosted at http://cpp-ethereum.org +# +# ------------------------------------------------------------------------------ +# This file is part of cpp-ethereum. +# +# cpp-ethereum is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# cpp-ethereum 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cpp-ethereum. If not, see +# +# (c) 2014-2016 cpp-ethereum contributors. +#------------------------------------------------------------------------------ + +cmake_minimum_required(VERSION 3.0.0) + +set(ETH_CMAKE_DIR "${CMAKE_CURRENT_LIST_DIR}/cmake" CACHE PATH "The path to the cmake directory") +list(APPEND CMAKE_MODULE_PATH ${ETH_CMAKE_DIR}) + +set(CPP_ETHEREUM_DIR "${CMAKE_CURRENT_LIST_DIR}" CACHE PATH "Path to the root directory for cpp-ethereum") + +# set cmake_policies +include(EthPolicy) +eth_policy() + +# project name and version should be set after cmake_policy CMP0048 +project(cpp-ethereum VERSION "1.3.0") + +if (NOT EXISTS ${CMAKE_SOURCE_DIR}/evmjit/) + message(FATAL_ERROR "Git submodules not initialized, execute:\n git submodule update --init") +endif() + +set(CMAKE_SKIP_INSTALL_ALL_DEPENDENCY On) + +include(EthOptions) +include(EthCompilerSettings) +include(EthExecutableHelper) +include(EthDependencies) +include(EthUtils) + +include(ProjectBoost) +include(ProjectCryptopp) +include(ProjectJsonCpp) +include(ProjectJsonRpcCpp) +include(ProjectSecp256k1) + +configure_project(CPUID CURL EVMJIT FATDB MINIUPNPC ROCKSDB PARANOID VMTRACE) + +add_subdirectory(eth) +add_subdirectory(libdevcore) +add_subdirectory(libdevcrypto) +add_subdirectory(libcontract) +add_subdirectory(libsinglepoint) +add_subdirectory(libpbftseal) +add_subdirectory(libraftseal) +add_subdirectory(libpailler) +add_subdirectory(libethcore) +add_subdirectory(libethereum) +add_subdirectory(libevm) +add_subdirectory(libevmcore) +if (NOT EMSCRIPTEN) + add_subdirectory(libp2p) +endif() +add_subdirectory(libweb3jsonrpc) +add_subdirectory(libwebthree) +add_subdirectory(libwhisper) + +add_subdirectory(utils) + + +if (EVMJIT) + add_subdirectory(evmjit) +endif() + +if (TOOLS) + + + if (NOT EMSCRIPTEN) + + + endif() +endif() + +# TODO - split out json_spirit, libscrypt and sec256k1 + diff --git a/CodingStandards.txt b/CodingStandards.txt new file mode 100644 index 0000000000..31957f2d25 --- /dev/null +++ b/CodingStandards.txt @@ -0,0 +1,254 @@ +0. Formatting + +GOLDEN RULE: Follow the style of the existing code when you make changes. + +a. Use tabs for leading indentation +- tab stops are every 4 characters. +- One indentation level -> exactly one byte (i.e. a tab character) in the source file. +- If you have run-on lines, indent as you would for a block. +b. Line widths: +- Don't worry about having lines of code > 80-char wide. +- Lines of comments should be formatted according to ease of viewing, but simplicity is to be prefered over beauty. +c. Don't use braces for condition-body one-liners. +d. Never place condition bodies on same line as condition. +e. Space between first paren and keyword, but *not* following first paren or preceeding final paren. +f. No spaces when fewer than intra-expression three parens together; when three or more, space according to clarity. +g. No spaces for subscripting or unary operators. +h. No space before ':' but one after it, except in the ternary operator: one on both sides. +i. Space all other operators. +j. Braces, when used, always have their own lines and are at same indentation level as "parent" scope. + +(WRONG) +if( a==b[ i ] ) { printf ("Hello\n"); } +foo->bar(someLongVariableName, + anotherLongVariableName, + anotherLongVariableName, + anotherLongVariableName, + anotherLongVariableName); + +(RIGHT) +if (a == b[i]) + printf("Hello\n"); // NOTE spaces used instead of tab here for clarity - first byte should be '\t'. +foo->bar( + someLongVariableName, + anotherLongVariableName, + anotherLongVariableName, + anotherLongVariableName, + anotherLongVariableName +); + + + +1. Namespaces; + +a. No "using namespace" declarations in header files. +b. All symbols should be declared in a namespace except for final applications. +c. Preprocessor symbols should be prefixed with the namespace in all-caps and an underscore. + +(WRONG) +#include +using namespace std; +tuple meanAndSigma(vector const& _v); + +(CORRECT) +#include +std::tuple meanAndSigma(std::vector const& _v); + + + +2. Preprocessor; + +a. File comment is always at top, and includes: +- Copyright. +- License (e.g. see COPYING). +b. Never use #ifdef/#define/#endif file guards. Prefer #pragma once as first line below file comment. +c. Prefer static const variable to value macros. +d. Prefer inline constexpr functions to function macros. +e. Split complex macro on multiple lines with '\'. + + + +3. Capitalization; + +GOLDEN RULE: Preprocessor: ALL_CAPS; C++: camelCase. + +a. Use camelCase for splitting words in names, except where obviously extending STL/boost functionality in which case follow those naming conventions. +b. The following entities' first alpha is upper case: +- Type names. +- Template parameters. +- Enum members. +- static const variables that form an external API. +c. All preprocessor symbols (macros, macro argments) in full uppercase with underscore word separation. + + +All other entities' first alpha is lower case. + + + +4. Variable prefixes: + +a. Leading underscore "_" to parameter names (both normal and template). +- Exception: "o_parameterName" when it is used exclusively for output. See 6(f). +- Exception: "io_parameterName" when it is used for both input and output. See 6(f). +b. Leading "c_" to const variables (unless part of an external API). +c. Leading "g_" to global (non-const) variables. +d. Leading "s_" to static (non-const, non-global) variables. + + + +5. Error reporting: + +- Prefer exception to bool/int return type. + + + +6. Declarations: + +a. {Typename} + {qualifiers} + {name}. +b. Only one per line. +c. Associate */& with type, not variable (at ends with parser, but more readable, and safe if in conjunction with (b)). +d. Favour declarations close to use; don't habitually declare at top of scope ala C. +e. Always pass non-trivial parameters with a const& suffix. +f. If a function returns multiple values, use std::tuple (std::pair acceptable). Prefer not using */& arguments, except where efficiency requires. +g. Never use a macro where adequate non-preprocessor C++ can be written. +h. Make use of auto whenever type is clear or unimportant: +- Always avoid doubly-stating the type. +- Use to avoid vast and unimportant type declarations. +- However, avoid using auto where type is not immediately obvious from the context, and especially not for arithmetic expressions. +i. Don't pass bools: prefer enumerations instead. +j. Prefer enum class to straight enum. + + +(WRONG) +const double d = 0; +int i, j; +char *s; +float meanAndSigma(std::vector _v, float* _sigma, bool _approximate); +Derived* x(dynamic_cast(base)); +for (map::iterator i = l.begin(); i != l.end(); ++l) {} + + +(CORRECT) +enum class Accuracy +{ + Approximate, + Exact +}; +double const d = 0; +int i; +int j; +char* s; +std::tuple meanAndSigma(std::vector const& _v, Accuracy _a); +auto x = dynamic_cast(base); +for (auto i = x.begin(); i != x.end(); ++i) {} + + +7. Structs & classes + +a. Structs to be used when all members public and no virtual functions. +- In this case, members should be named naturally and not prefixed with 'm_' +b. Classes to be used in all other circumstances. + + + +8. Members: + +a. One member per line only. +b. Private, non-static, non-const fields prefixed with m_. +c. Avoid public fields, except in structs. +d. Use override, final and const as much as possible. +e. No implementations with the class declaration, except: +- template or force-inline method (though prefer implementation at bottom of header file). +- one-line implementation (in which case include it in same line as declaration). +f. For a property 'foo' +- Member: m_foo; +- Getter: foo() [ also: for booleans, isFoo() ]; +- Setter: setFoo(); + + + +9. Naming + +a. Collection conventions: +- -s means std::vector e.g. using MyTypes = std::vector +- -Set means std::set e.g. using MyTypeSet = std::set +- -Hash means std::unordered_set e.g. using MyTypeHash = std::unordered_set +b. Class conventions: +- -Face means the interface of some shared concept. (e.g. FooFace might be a pure virtual class.) +c. Avoid unpronouncable names; +- If you need to shorten a name favour a pronouncable slice of the original to a scattered set of consonants. +- e.g. Manager shortens to Man rather than Mgr. +d. Avoid prefixes of initials (e.g. DON'T use IMyInterface, CMyImplementation) +e. Find short, memorable & (at least semi-) descriptive names for commonly used classes or name-fragments. +- A dictionary and thesaurus are your friends. +- Spell correctly. +- Think carefully about the class's purpose. +- Imagine it as an isolated component to try to decontextualise it when considering its name. +- Don't be trapped into naming it (purely) in terms of its implementation. + + + +10. Type-definitions + +a. Prefer 'using' to 'typedef'. e.g. using ints = std::vector; rather than typedef std::vector ints; +b. Generally avoid shortening a standard form that already includes all important information: +- e.g. stick to shared_ptr rather than shortening to ptr. +c. Where there are exceptions to this (due to excessive use and clear meaning), note the change prominently and use it consistently. +- e.g. using Guard = std::lock_guard; ///< Guard is used throughout the codebase since it's clear in meaning and used commonly. +d. In general expressions should be roughly as important/semantically meaningful as the space they occupy. + + + +11. Commenting + +a. Comments should be doxygen-compilable, using @notation rather than \notation. +b. Document the interface, not the implementation. +- Documentation should be able to remain completely unchanged, even if the method is reimplemented. +- Comment in terms of the method properties and intended alteration to class state (or what aspects of the state it reports). +- Be careful to scrutinise documentation that extends only to intended purpose and usage. +- Reject documentation that is simply an English transaction of the implementation. + + + +12. Include Headers + +Includes should go in increasing order of generality (libethereum -> libethcore -> libdevcrypto -> libdevcore -> boost -> STL). For example: + +#include +#include +#include +#include +#include +#include +#include +#include + +See http://stackoverflow.com/questions/614302/c-header-order/614333#614333 for the reason: this makes it easier to find missing includes in header files. + + + +13. Logging + +Logging should be performed at appropriate verbosities depending on the logging message. +The more likely a message is to repeat (and thus cuase noise) the higher in verbosity it should be. +Some rules to keep in mind: + + - Verbosity == 0 -> Reserved for important stuff that users must see and can understand. + - Verbosity == 1 -> Reserved for stuff that users don't need to see but can understand. + - Verbosity >= 2 -> Anything that is or might be displayed more than once every minute + - Verbosity >= 3 -> Anything that only a developer would understand + - Verbosity >= 4 -> Anything that is low-level (e.g. peer disconnects, timers being cancelled) + + +14. Recommended reading + +Herb Sutter and Bjarne Stroustrup +- "C++ Core Guidelines" (https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md) + +Herb Sutter and Andrei Alexandrescu +- "C++ Coding Standards: 101 Rules, Guidelines, and Best Practices" + +Scott Meyers +- "Effective C++: 55 Specific Ways to Improve Your Programs and Designs (3rd Edition)" +- "More Effective C++: 35 New Ways to Improve Your Programs and Designs" +- "Effective Modern C++: 42 Specific Ways to Improve Your Use of C++11 and C++14" diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000..4e5f7cc040 --- /dev/null +++ b/LICENSE @@ -0,0 +1,673 @@ + Version 3, 29 June 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 General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is 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. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + 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. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + 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 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. Use with the GNU Affero General Public License. + + 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 Affero 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 special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU 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 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 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 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 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + 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 GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/README.md b/README.md new file mode 100644 index 0000000000..c203b4c24f --- /dev/null +++ b/README.md @@ -0,0 +1,38 @@ + +## 项目介绍 +BCOS平台(取BlockChainOpenSource涵义命名)是深圳前海微众银行股份有限公司、上海万向区块链股份公司、矩阵元技术(深圳)有限公司三方共同研发并且完全开源的区块链底层技术平台。 + +BCOS平台基于现有的区块链开源项目进行开发,综合考虑开源项目的成熟度、开发接口友好性、技术组件齐备性、可插件化程度、多样化复杂业务支持程度等多方面的表现,并根据企业级区块链系统的规范和需求,对开源项目从底层进行改造和升级,形成符合企业级应用场景功能、性能、安全性、监管等要求的技术平台,帮助各行业的用户来构建商用区块链服务。 + + +BCOS平台是聚焦于企业级应用服务的区块链技术平台,已经在多个具备海量用户的企业级应用场景中被充分验证。在真实生产数据的检验下,BCOS平台保持零故障运行,印证了其安全可控、业务可行、健壮可用的优点,其功能、性能、容错性、可靠性、安全性、保密性、可追溯、模块化、可维护性、可移植性、互操作性、数据一致性等特性亦被验证可达到高标准。 + + +## 支持平台 + +目前运行的操作系统平台如下: + +- Linux + +## 安装说明 + +初次安装时,请参考[BCOS使用说明书1.0](https://github.com/bcosorg/bcos/blob/master/doc/manual/manual.md)。 + +## 技术白皮书 + +参见[BCOS平台白皮书——面向分布式商业的区块链基础设施](https://github.com/bcosorg/bcos/blob/master/doc/BCOS_Whitepaper.pdf)。 + + +## License + +BCOS的开源协议为GPL3.0,详情参见[LICENSE](https://github.com/bcosorg/bcos/blob/master/LICENSE)。 + +## 联系我们 +邮箱:hi@bcos.org.cn。 + + + + + + + diff --git a/accounttool/accountCheck.js b/accounttool/accountCheck.js new file mode 100644 index 0000000000..f86f9493c8 --- /dev/null +++ b/accounttool/accountCheck.js @@ -0,0 +1,19 @@ +var crypto = require('crypto') +var utils = require('./utils.js') + +function newAccount(pwd) +{ + var pKey ="bcec428d5205abe0f0cc8a734083908d9eb8563e31f943d760786edf42ad77dd"; + var privKey =new Buffer(pKey, 'hex'); + var pubKey = utils.privateToPublic(privKey); + var address = utils.privateToAddress(privKey); + var str_pri = '0x' + privKey.toString('hex'); + var str_pub = '0x' + pubKey.toString('hex'); + var str_addr = '0x' + address.toString('hex'); + console.log("privKey : ",privKey," - " , str_pri," | pubKey : " ,pubKey," - ", str_pub," | address : ",address," - ",str_addr); +} + +newAccount(123); + + + diff --git a/accounttool/accountManager.js b/accounttool/accountManager.js new file mode 100644 index 0000000000..9c3ff48667 --- /dev/null +++ b/accounttool/accountManager.js @@ -0,0 +1,18 @@ +var crypto = require('crypto') +var utils = require('./utils.js') + +function newAccount(pwd) +{ + var privKey = crypto.randomBytes(32); + var pubKey = utils.privateToPublic(privKey); + var address = utils.privateToAddress(privKey); + var str_pri = '0x' + privKey.toString('hex'); + var str_pub = '0x' + pubKey.toString('hex'); + var str_addr = '0x' + address.toString('hex'); + console.log("privKey : ",privKey," - " , str_pri," | pubKey : " ,pubKey," - ", str_pub," | address : ",address," - ",str_addr); +} + +newAccount(); + + + diff --git a/accounttool/codeUtils.js b/accounttool/codeUtils.js new file mode 100644 index 0000000000..21088bf844 --- /dev/null +++ b/accounttool/codeUtils.js @@ -0,0 +1,45 @@ +/* +编码工具类,包含交易编码及日志编码 +*/ +var Web3 = require('web3'); +var sha3 = require("./sha3") +var Event = require('web3/lib/web3/event'); +var Coder = require('web3/lib/solidity/coder'); + +/* +#交易编码 +###参数编码 +*/ +function codeParams(types,params) +{ + var code_ret = Coder.encodeParams(types, params); + console.log("code_ret : ",code_ret); + return code_ret; +} + +/* +###函数名编码 +*/ +function codeFun(fun_str) +{ + + var code_fun = '0x' + sha3(fun_str).slice(0, 8); + console.log("code_fun : ",code_fun); + return code_fun; +} + +/* +###交易数据编码 +*/ +function codeTxData(fun_Str,types,params) +{ + var txData_code = codeFun(fun_Str); + txData_code += codeParams(types,params); + console.log("txData_code : ",txData_code); + return txData_code; +} + + + + +exports.codeTxData=codeTxData; \ No newline at end of file diff --git a/accounttool/config.js b/accounttool/config.js new file mode 100644 index 0000000000..5bf62b91ab --- /dev/null +++ b/accounttool/config.js @@ -0,0 +1,17 @@ +var abi_arr='[{"constant":false,"inputs":[{"name":"size","type":"uint256"}],"name":"add","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"get","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"inputs":[],"payable":false,"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"bidder","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"HighestBidIncreased","type":"event"}]'; +var contract_addr='0x52d0e7c989c06ff92553b17eced8c5099e353f5c';//合约地址 +var ip="127.0.0.1"; +var rpcport=8545; +var ipc_path="./data/geth.ipc"; //ipc文件 +var account="0x64fa644d2a694681bd6addd6c5e36cccd8dcdde3"; //区块链节点帐号 +var pwd=""; //帐号密码 +var privKey="bcec428d5205abe0f0cc8a734083908d9eb8563e31f943d760786edf42ad77dd"; + +exports.abi_arr = abi_arr; +exports.contract_addr = contract_addr; +exports.ip = ip; +exports.rpcport = rpcport; +exports.ipc_path = ipc_path; +exports.account = account; +exports.pwd = pwd; +exports.privKey = privKey; \ No newline at end of file diff --git a/accounttool/readMe.md b/accounttool/readMe.md new file mode 100644 index 0000000000..baba1b7e0e --- /dev/null +++ b/accounttool/readMe.md @@ -0,0 +1,10 @@ +1. 依赖库 + crypto + secp256k1 + keccak + assert + rlp + bn.js + + + \ No newline at end of file diff --git a/accounttool/sendRawTransaction.js b/accounttool/sendRawTransaction.js new file mode 100644 index 0000000000..bdebdd92af --- /dev/null +++ b/accounttool/sendRawTransaction.js @@ -0,0 +1,61 @@ +var fs = require("fs"); +var Web3 = require('web3'); +var net = require('net'); +var conf = require('./config'); +var txm = require('./transactionManager'); +var coder = require('./codeUtils'); + +//init web3 +var web3 = new Web3(); +var client = new net.Socket(); +web3.setProvider(new web3.providers.IpcProvider(conf.ipc_path,client)); + +//sendRawTransaction +function sendRawTransaction() +{ + web3.eth.getBlockNumber(function(e,d){ + console.log(e+','+d); + var blocknumber=d+100; + + var call_fun="add(uint256)"; + var types=['uint256']; + var params=['15']; + var tx_data = coder.codeTxData(call_fun,types,params); + + console.log('account:'+conf.account); + + var postdata = { + data: tx_data, + from: conf.account, + to:conf.contract_addr, + gas: 1000000, + randomid:Math.ceil(Math.random()*100000000), + blockLimit:blocknumber + } + + var signTX = txm.signTransaction(postdata,conf.privKey,null); + console.log("signTX : ",signTX); + web3.eth.sendRawTransaction(signTX, function(err, address) { + console.log(err,address); + if (!err) + { + console.log("发送交易成功!|",address); + process.exit(); + return; + } + else + { + console.log("发送交易失败!",err); + process.exit(); + return; + } + }); + + + }); + + +} + + +sendRawTransaction(); \ No newline at end of file diff --git a/accounttool/sendTransaction.js b/accounttool/sendTransaction.js new file mode 100644 index 0000000000..ece0351f69 --- /dev/null +++ b/accounttool/sendTransaction.js @@ -0,0 +1,192 @@ +var fs = require("fs"); +var Web3 = require('web3'); +var net = require('net'); +var conf = require('./config'); + +//init web3 +var web3 = new Web3(); +var client = new net.Socket(); +web3.setProvider(new web3.providers.IpcProvider(conf.ipc_path,client)); + +//sendTransaction +function sendTransaction() +{ + var postdata = { + data: params_data, + from: conf.account, + to:conf.contract_addr, + value:params_value, + gas: 1000000 + } + //发送交易 + web3.eth.sendTransaction(postdata, function(err, address) { + if (!err) + { + logger.debug(tx_id + " | 发送交易成功!|",address); + process.exit(); + return; + } + else + { + logger.debug(tx_id + "|发送交易失败!",err); + process.exit(); + return; + } + }); +} + +function callContract() +{ + var test_params = ''; + //调用合约 + var abi_obj = conf.abi_arr; + var args = test_params; + console.log(" |args : " + args); + if( typeof(abi_obj) === 'string' || Object.prototype.toString.call(abi_obj) === '[object String]') + { + abi_obj = JSON.parse(abi_obj); + } + if( typeof(args) === 'string' || Object.prototype.toString.call(args) === '[object String]') + { + args = JSON.parse(args); + } + console.log(typeof(abi_obj) + " | " + Object.prototype.toString.call(abi_obj)); + console.log(typeof(args) + " | " + Object.prototype.toString.call(args)); + if(typeof(abi_obj) !== 'object' || Object.prototype.toString.call(abi_obj) !== '[object Array]' || typeof(args) !== 'object' || Object.prototype.toString.call(args) !== '[object Array]') + { + console.log("参数格式不合法! abi_obj : " + JSON.stringify(abi_obj) +" | args : " + JSON.stringify(args)); + process.exit(); + return; + } + else + { + console.log(" |args : " + args + " | " + JSON.stringify(args)); + var breaked = false; + var abi_obj_size = abi_obj.length; + abi_obj.forEach(function (obj,index) + { + if(breaked) return;; + console.log("obj : " + JSON.stringify(obj) + " | " + abi_obj_size + " | " + index); + if(obj.constant !== undefined && obj.name !== undefined && obj.name === fun) + { + console.log("call fun : " + obj.name); + try{ + // creation of contract object + var MyContract = web3.eth.contract(abi_obj); + // initiate contract for an address + if( conf.contract_addr === '' || conf.contract_addr === undefined) + { + console.log("未传入合约地址!"); + process.exit(); + return; + } + var myContractInstance = MyContract.at(conf.contract_addr); + var f = myContractInstance[fun]; + if(obj.constant) + { + console.log(fun+" is a constant function, we should call it."); + if(typeof(f) === 'function') + { + try + { + var call_param = args; + function call_back(err,ret_data){ + console.log("err : " + err + " | ret_data : " + JSON.stringify(ret_data)); + if( !err ) + { + console.log(f + " result : " + JSON.stringify(ret_data)); + process.exit(); + return; + } + else + { + console.log(" 调用合约失败"); + process.exit(); + return; + } + } + call_param.push(call_back); + console.log("f:"+f + " | args : " + JSON.stringify(call_param)); + f.apply(myContractInstance, call_param); + } + catch(e) + { + console.log("exception:"+e.message); + process.exit(); + return; + } + } + else + { + console.log(f + " 不是合约函数!"); + process.exit(); + return; + } + } + else + { + console.log(fun+" is not a constant function, we should send a Transaction."); + if(typeof(f) === 'function') + { + try + { + var call_param = args; + var fromparam = { + from:conf.account, + gas:100000000 + }; + //gas: 1000000000 + call_param.push(fromparam); + function call_back(err,ret_data) + { + console.log("err : " + err + " | ret_data : " + JSON.stringify(ret_data)); + if( !err ) + { + console.log(f + " result : " + JSON.stringify(ret_data)); + process.exit(); + return; + } + else + { + console.log("调用合约失败!"); + process.exit(); + return; + } + } + call_param.push(call_back); + console.log("call_param : " + JSON.stringify(call_param)); + f.apply(myContractInstance, call_param); + } + catch(e) + { + console.log("调用合约失败! | exception:",e); + process.exit(); + return; + } + } + else + { + console.log(f + " 不是合约函数!"); + process.exit(); + return; + } + } + breaked = true; + } + catch(ex) + { + console.log("exception:",ex); + process.exit(); + return; + } + } + if( parseInt(abi_obj_size) === (parseInt(index)+1) && !breaked ) + { + console.log("合约未包含该函数!" + fun); + process.exit(); + return; + } + }); + } +} + diff --git a/accounttool/sha3.js b/accounttool/sha3.js new file mode 100644 index 0000000000..03e86683e9 --- /dev/null +++ b/accounttool/sha3.js @@ -0,0 +1,38 @@ +/* + This file is part of web3.js. + + web3.js is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + web3.js 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with web3.js. If not, see . +*/ +/** + * @file sha3.js + * @author Marek Kotewicz + * @date 2015 + */ + +var CryptoJS = require('crypto-js'); +var sha3 = require('crypto-js/sha3'); + +module.exports = function (value, options) { + if (options && options.encoding === 'hex') { + if (value.length > 2 && value.substr(0, 2) === '0x') { + value = value.substr(2); + } + value = CryptoJS.enc.Hex.parse(value); + } + + return sha3(value, { + outputLength: 256 + }).toString(); +}; + diff --git a/accounttool/signTransaction.js b/accounttool/signTransaction.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/accounttool/transactionManager.js b/accounttool/transactionManager.js new file mode 100644 index 0000000000..d6f33e9f7d --- /dev/null +++ b/accounttool/transactionManager.js @@ -0,0 +1,22 @@ +var Tx = require('./transactionObject.js'); + +function signTransaction(tx_data,privKey,callback) +{ + // convert string private key to a Buffer Object + var privateKey = new Buffer(privKey, 'hex'); + var tx = new Tx.Transaction(tx_data); + tx.sign(privateKey); + // Build a serialized hex version of the Tx + var serializedTx = '0x' + tx.serialize().toString('hex'); + if( null !== callback) + { + callback(serializedTx); + return ; + } + else + { + return serializedTx; + } +} + +exports.signTransaction=signTransaction; \ No newline at end of file diff --git a/accounttool/transactionObject.js b/accounttool/transactionObject.js new file mode 100644 index 0000000000..a05243dc62 --- /dev/null +++ b/accounttool/transactionObject.js @@ -0,0 +1,253 @@ +const ethUtil = require('./utils.js') +const BN = ethUtil.BN + +// secp256k1n/2 +const N_DIV_2 = new BN('7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0', 16) + +function Transaction(data) { + data = data || {} + // Define Properties + const fields = [{ + name: 'randomid', + length: 32, + allowLess: true, + default: new Buffer([]) + }, { + name: 'gasPrice', + length: 32, + allowLess: true, + default: new Buffer([]) + }, { + name: 'gasLimit', + alias: 'gas', + length: 32, + allowLess: true, + default: new Buffer([]) + }, { + name: 'blockLimit', + length: 32, + allowLess: true, + default: new Buffer([]) + },{ + name: 'to', + allowZero: true, + length: 20, + default: new Buffer([]) + }, { + name: 'value', + length: 32, + allowLess: true, + default: new Buffer([]) + }, { + name: 'data', + alias: 'input', + allowZero: true, + default: new Buffer([]) + }, { + name: 'v', + length: 1, + default: new Buffer([0x1c]) + }, { + name: 'r', + length: 32, + allowLess: true, + default: new Buffer([]) + }, { + name: 's', + length: 32, + allowLess: true, + default: new Buffer([]) + }] + + /** + * Returns the rlp encoding of the transaction + * @method serialize + * @return {Buffer} + */ + // attached serialize + ethUtil.defineProperties(this, fields, data) + + /** + * @prop {Buffer} from (read only) sender address of this transaction, mathematically derived from other parameters. + */ + Object.defineProperty(this, 'from', { + enumerable: true, + configurable: true, + get: this.getSenderAddress.bind(this) + }) + + // calculate chainId from signature + var sigV = ethUtil.bufferToInt(this.v) + var chainId = Math.floor((sigV - 35) / 2) + if (chainId < 0) chainId = 0 + + // set chainId + this._chainId = chainId || data.chainId || 0 + this._homestead = true + } + + /** + * If the tx's `to` is to the creation address + * @return {Boolean} + */ + Transaction.prototype.toCreationAddress=function () { + return this.to.toString('hex') === '' + } + + /** + * Computes a sha3-256 hash of the serialized tx + * @param {Boolean} [includeSignature=true] whether or not to inculde the signature + * @return {Buffer} + */ + Transaction.prototype.hash=function (includeSignature) { + if (includeSignature === undefined) includeSignature = true + // backup original signature + const rawCopy = this.raw.slice(0) + + // modify raw for signature generation only + if (this._chainId > 0) { + includeSignature = true + this.v = this._chainId + this.r = 0 + this.s = 0 + } + + // generate rlp params for hash + console.log(this.raw.length) + var txRawForHash = includeSignature ? this.raw : this.raw.slice(0, this.raw.length - 3) + //var txRawForHash = includeSignature ? this.raw : this.raw.slice(0, 7) + + // restore original signature + this.raw = rawCopy.slice() + + // create hash + return ethUtil.rlphash(txRawForHash) + } + + /** + * returns the public key of the sender + * @return {Buffer} + */ + Transaction.prototype.getChainId=function() { + return this._chainId + } + + /** + * returns the sender's address + * @return {Buffer} + */ + Transaction.prototype.getSenderAddress = function() { + if (this._from) { + return this._from + } + const pubkey = this.getSenderPublicKey() + this._from = ethUtil.publicToAddress(pubkey) + return this._from + } + + /** + * returns the public key of the sender + * @return {Buffer} + */ + Transaction.prototype.getSenderPublicKey =function() { + if (!this._senderPubKey || !this._senderPubKey.length) { + if (!this.verifySignature()) throw new Error('Invalid Signature') + } + return this._senderPubKey + } + + /** + * Determines if the signature is valid + * @return {Boolean} + */ + Transaction.prototype.verifySignature =function() { + const msgHash = this.hash(false) + // All transaction signatures whose s-value is greater than secp256k1n/2 are considered invalid. + if (this._homestead && new BN(this.s).cmp(N_DIV_2) === 1) { + return false + } + + try { + var v = ethUtil.bufferToInt(this.v) + if (this._chainId > 0) { + v -= this._chainId * 2 + 8 + } + this._senderPubKey = ethUtil.ecrecover(msgHash, v, this.r, this.s) + } catch (e) { + return false + } + + return !!this._senderPubKey + } + + /** + * sign a transaction with a given a private key + * @param {Buffer} privateKey + */ + Transaction.prototype.sign =function(privateKey) { + const msgHash = this.hash(false) + const sig = ethUtil.ecsign(msgHash, privateKey) + if (this._chainId > 0) { + sig.v += this._chainId * 2 + 8 + } + Object.assign(this, sig) + } + + /** + * The amount of gas paid for the data in this tx + * @return {BN} + */ + Transaction.prototype.getDataFee=function() { + const data = this.raw[5] + const cost = new BN(0) + for (var i = 0; i < data.length; i++) { + data[i] === 0 ? cost.iaddn(fees.txDataZeroGas.v) : cost.iaddn(fees.txDataNonZeroGas.v) + } + return cost + } + + /** + * the minimum amount of gas the tx must have (DataFee + TxFee + Creation Fee) + * @return {BN} + */ + Transaction.prototype.getBaseFee =function() { + const fee = this.getDataFee().iaddn(fees.txGas.v) + if (this._homestead && this.toCreationAddress()) { + fee.iaddn(fees.txCreation.v) + } + return fee + } + + /** + * the up front amount that an account must have for this transaction to be valid + * @return {BN} + */ + Transaction.prototype.getUpfrontCost =function() { + return new BN(this.gasLimit) + .imul(new BN(this.gasPrice)) + .iadd(new BN(this.value)) + } + + /** + * validates the signature and checks to see if it has enough gas + * @param {Boolean} [stringError=false] whether to return a string with a dscription of why the validation failed or return a Bloolean + * @return {Boolean|String} + */ + Transaction.prototype.validate =function(stringError) { + const errors = [] + if (!this.verifySignature()) { + errors.push('Invalid Signature') + } + + if (this.getBaseFee().cmp(new BN(this.gasLimit)) > 0) { + errors.push([`gas limit is to low. Need at least ${this.getBaseFee()}`]) + } + + if (stringError === undefined || stringError === false) { + return errors.length === 0 + } else { + return errors.join(' ') + } + } + +exports.Transaction=Transaction; diff --git a/accounttool/utils.js b/accounttool/utils.js new file mode 100644 index 0000000000..88a77a5bdc --- /dev/null +++ b/accounttool/utils.js @@ -0,0 +1,267 @@ +const secp256k1 = require('secp256k1') +const createKeccakHash = require('keccak') +const assert = require('assert') +const rlp = require('rlp') +const BN = require('bn.js') + +function privateToPublic(privateKey) { + privateKey = toBuffer(privateKey) + // skip the type flag and use the X, Y points + return secp256k1.publicKeyCreate(privateKey, false).slice(1) +} + +function privateToAddress(privateKey) { + return publicToAddress(privateToPublic(privateKey)) +} + +function publicToAddress(pubKey, sanitize) { + pubKey = toBuffer(pubKey) + if (sanitize && (pubKey.length !== 64)) { + pubKey = secp256k1.publicKeyConvert(pubKey, false).slice(1) + } + assert(pubKey.length === 64) + // Only take the lower 160bits of the hash + return sha3(pubKey).slice(-20) +} + + +function toBuffer(v) { + if (!Buffer.isBuffer(v)) { + if (Array.isArray(v)) { + v = Buffer.from(v) + } else if (typeof v === 'string') { + if (isHexPrefixed(v)) { + v = Buffer.from(padToEven(stripHexPrefix(v)), 'hex') + } else { + v = Buffer.from(v) + } + } else if (typeof v === 'number') { + v = intToBuffer(v) + } else if (v === null || v === undefined) { + v = Buffer.allocUnsafe(0) + } else if (v.toArray) { + // converts a BN to a Buffer + v = Buffer.from(v.toArray()) + } else { + throw new Error('invalid type') + } + } + return v +} + +function isHexPrefixed(str) { + return str.slice(0, 2) === '0x' +} + +function padToEven(a) { + if (a.length % 2) a = '0' + a + return a +} + +function stripHexPrefix(str) { + if (typeof str !== 'string') { + return str + } + return isHexPrefixed(str) ? str.slice(2) : str +} + +function intToBuffer(i) { + var hex = intToHex(i) + return Buffer.from(hex.slice(2), 'hex') +} + +function intToHex(i) { + assert(i % 1 === 0, 'number is not a integer') + assert(i >= 0, 'number must be positive') + var hex = i.toString(16) + if (hex.length % 2) { + hex = '0' + hex + } + return '0x' + hex +} + +function setLength(msg, length, right) { + var buf = zeros(length) + msg = toBuffer(msg) + if (right) { + if (msg.length < length) { + msg.copy(buf) + return buf + } + return msg.slice(0, length) + } else { + if (msg.length < length) { + msg.copy(buf, length - msg.length) + return buf + } + return msg.slice(-length) + } +} + +function sha3(a, bits) { + a = toBuffer(a) + if (!bits) bits = 256 + return createKeccakHash('keccak' + bits).update(a).digest() +} + +function baToJSON(ba) { + if (Buffer.isBuffer(ba)) { + return '0x' + ba.toString('hex') + } else if (ba instanceof Array) { + var array = [] + for (var i = 0; i < ba.length; i++) { + array.push(baToJSON(ba[i])) + } + return array + } +} + +function zeros(bytes) { + return Buffer.allocUnsafe(bytes).fill(0) +} + +function stripZeros(a) { + a = stripHexPrefix(a) + var first = a[0] + while (a.length > 0 && first.toString() === '0') { + a = a.slice(1) + first = a[0] + } + return a +} + +function defineProperties(self, fields, data) { + self.raw = [] + self._fields = [] + + // attach the `toJSON` + self.toJSON = function (label) { + if (label) { + var obj = {} + self._fields.forEach(function (field) { + obj[field] = '0x' + self[field].toString('hex') + }) + return obj + } + return baToJSON(this.raw) + } + + self.serialize = function serialize () { + return rlp.encode(self.raw) + } + + fields.forEach(function (field, i) { + self._fields.push(field.name) + function getter () { + return self.raw[i] + } + function setter (v) { + v = toBuffer(v) + + if (v.toString('hex') === '00' && !field.allowZero) { + v = Buffer.allocUnsafe(0) + } + + if (field.allowLess && field.length) { + v = stripZeros(v) + assert(field.length >= v.length, 'The field ' + field.name + ' must not have more ' + field.length + ' bytes') + } else if (!(field.allowZero && v.length === 0) && field.length) { + assert(field.length === v.length, 'The field ' + field.name + ' must have byte length of ' + field.length) + } + + self.raw[i] = v + } + + Object.defineProperty(self, field.name, { + enumerable: true, + configurable: true, + get: getter, + set: setter + }) + + if (field.default) { + self[field.name] = field.default + } + + // attach alias + if (field.alias) { + Object.defineProperty(self, field.alias, { + enumerable: false, + configurable: true, + set: setter, + get: getter + }) + } + }) + + // if the constuctor is passed data + if (data) { + if (typeof data === 'string') { + data = Buffer.from(stripHexPrefix(data), 'hex') + } + + if (Buffer.isBuffer(data)) { + data = rlp.decode(data) + } + + if (Array.isArray(data)) { + if (data.length > self._fields.length) { + throw (new Error('wrong number of fields in data')) + } + + // make sure all the items are buffers + data.forEach(function (d, i) { + self[self._fields[i]] = toBuffer(d) + }) + } else if (typeof data === 'object') { + const keys = Object.keys(data) + fields.forEach(function (field) { + if (keys.indexOf(field.name) !== -1) self[field.name] = data[field.name] + if (keys.indexOf(field.alias) !== -1) self[field.alias] = data[field.alias] + }) + } else { + throw new Error('invalid data') + } + } +} + +function bufferToInt(buf) { + return new BN(toBuffer(buf)).toNumber() +} + +function rlphash(a) { + return sha3(rlp.encode(a)) +} + +function ecrecover(msgHash, v, r, s) { + var signature = Buffer.concat([setLength(r, 32), setLength(s, 32)], 64) + var recovery = v - 27 + if (recovery !== 0 && recovery !== 1) { + throw new Error('Invalid signature v value') + } + var senderPubKey = secp256k1.recover(msgHash, signature, recovery) + return secp256k1.publicKeyConvert(senderPubKey, false).slice(1) +} + +function ecsign(msgHash, privateKey) { + var sig = secp256k1.sign(msgHash, privateKey) + + var ret = {} + ret.r = sig.signature.slice(0, 32) + ret.s = sig.signature.slice(32, 64) + ret.v = sig.recovery + 27 + return ret +} + +exports.privateToPublic=privateToPublic +exports.privateToAddress=privateToAddress +exports.publicToAddress=publicToAddress +exports.defineProperties=defineProperties +exports.bufferToInt=bufferToInt +exports.rlphash=rlphash +exports.ecrecover=ecrecover +exports.ecsign=ecsign + +exports.BN = BN +exports.rlp = rlp +exports.secp256k1 = secp256k1 \ No newline at end of file diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 0000000000..993749c70b --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,87 @@ +#------------------------------------------------------------------------------ +# Appveyor configuration file for cpp-ethereum. +# +# The documentation for cpp-ethereum is hosted at http://cpp-ethereum.org +# +# ------------------------------------------------------------------------------ +# This file is part of cpp-ethereum. +# +# cpp-ethereum is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# cpp-ethereum 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cpp-ethereum. If not, see +# +# (c) 2016 cpp-ethereum contributors. +#------------------------------------------------------------------------------ + +branches: + only: + - master + - develop +os: Visual Studio 2015 +configuration: + - RelWithDebInfo +environment: + TESTS: On +cache: build/evmjit/llvm +#RDP LOGIN details for trouble shooting +#init: +# - ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) +#on_finish: +# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) +install: + - git submodule update --init --recursive + - scripts/install_deps.bat + - set ETHEREUM_DEPS_PATH=%APPVEYOR_BUILD_FOLDER%\deps\install +before_build: + - if not exist build mkdir build + - cd build + - cmake -G "Visual Studio 14 2015 Win64" .. -DTESTS=%TESTS% -DEVMJIT=On +build_script: + - msbuild cpp-ethereum.sln /p:Configuration=%CONFIGURATION% /m:%NUMBER_OF_PROCESSORS% /v:minimal + - cd %APPVEYOR_BUILD_FOLDER% + - scripts\release.bat %CONFIGURATION% %ETHEREUM_DEPS_PATH% %TESTS% +test_script: + - cd %APPVEYOR_BUILD_FOLDER% + - scripts\tests.bat %TESTS% %CONFIGURATION% %APPVEYOR_BUILD_FOLDER% %ETHEREUM_DEPS_PATH% +artifacts: + - path: cpp-ethereum-windows.zip + name: cpp-ethereum-windows-zip + +# This is the deploy target for Windows which generates ZIPs per commit. +# We are in agreement that generating ZIPs per commit for the develop +# branch is probably just noise, so we only run this deployment target +# on 'release'. +# +# See https://www.appveyor.com/docs/deployment/github for information +# on GitHub Releases in Appveyor. +# +# You need to generate a GitHub personal access token for Appveyor +# See https://github.com/settings/tokens for more information on that. +# The token you generate there (in an encrypted form) is what is +# passed to this deployment target in the 'auth_token' parameter +# below. +deploy: + prerelease: true + provider: GitHub + auth_token: + secure: yukM9mHUbzuZSS5WSBLKSW0yGJerJEqAXkFhDhSHBBcKJE7GAryjQsdO9Kxh3yRv + artifact: cpp-ethereum-windows-zip + on: + branch: release + +# Disable slightly annoying AppVeyorBot. The comments it adds onto Github issues are +# redundant with the "Checks Passed/Failure" detail which is already on the issues. +notifications: + - provider: GitHubPullRequest + on_build_success: false + on_build_failure: false + on_build_status_changed: false diff --git a/cmake/CMakeParseArguments.cmake b/cmake/CMakeParseArguments.cmake new file mode 100644 index 0000000000..11f1ab9bb7 --- /dev/null +++ b/cmake/CMakeParseArguments.cmake @@ -0,0 +1,161 @@ +#.rst: +# CMakeParseArguments +# ------------------- +# +# +# +# CMAKE_PARSE_ARGUMENTS( +# args...) +# +# CMAKE_PARSE_ARGUMENTS() is intended to be used in macros or functions +# for parsing the arguments given to that macro or function. It +# processes the arguments and defines a set of variables which hold the +# values of the respective options. +# +# The argument contains all options for the respective macro, +# i.e. keywords which can be used when calling the macro without any +# value following, like e.g. the OPTIONAL keyword of the install() +# command. +# +# The argument contains all keywords for this macro +# which are followed by one value, like e.g. DESTINATION keyword of the +# install() command. +# +# The argument contains all keywords for this +# macro which can be followed by more than one value, like e.g. the +# TARGETS or FILES keywords of the install() command. +# +# When done, CMAKE_PARSE_ARGUMENTS() will have defined for each of the +# keywords listed in , and +# a variable composed of the given +# followed by "_" and the name of the respective keyword. These +# variables will then hold the respective value from the argument list. +# For the keywords this will be TRUE or FALSE. +# +# All remaining arguments are collected in a variable +# _UNPARSED_ARGUMENTS, this can be checked afterwards to see +# whether your macro was called with unrecognized parameters. +# +# As an example here a my_install() macro, which takes similar arguments +# as the real install() command: +# +# :: +# +# function(MY_INSTALL) +# set(options OPTIONAL FAST) +# set(oneValueArgs DESTINATION RENAME) +# set(multiValueArgs TARGETS CONFIGURATIONS) +# cmake_parse_arguments(MY_INSTALL "${options}" "${oneValueArgs}" +# "${multiValueArgs}" ${ARGN} ) +# ... +# +# +# +# Assume my_install() has been called like this: +# +# :: +# +# my_install(TARGETS foo bar DESTINATION bin OPTIONAL blub) +# +# +# +# After the cmake_parse_arguments() call the macro will have set the +# following variables: +# +# :: +# +# MY_INSTALL_OPTIONAL = TRUE +# MY_INSTALL_FAST = FALSE (this option was not used when calling my_install() +# MY_INSTALL_DESTINATION = "bin" +# MY_INSTALL_RENAME = "" (was not used) +# MY_INSTALL_TARGETS = "foo;bar" +# MY_INSTALL_CONFIGURATIONS = "" (was not used) +# MY_INSTALL_UNPARSED_ARGUMENTS = "blub" (no value expected after "OPTIONAL" +# +# +# +# You can then continue and process these variables. +# +# Keywords terminate lists of values, e.g. if directly after a +# one_value_keyword another recognized keyword follows, this is +# interpreted as the beginning of the new option. E.g. +# my_install(TARGETS foo DESTINATION OPTIONAL) would result in +# MY_INSTALL_DESTINATION set to "OPTIONAL", but MY_INSTALL_DESTINATION +# would be empty and MY_INSTALL_OPTIONAL would be set to TRUE therefor. + +#============================================================================= +# Copyright 2010 Alexander Neundorf +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + + +if(__CMAKE_PARSE_ARGUMENTS_INCLUDED) + return() +endif() +set(__CMAKE_PARSE_ARGUMENTS_INCLUDED TRUE) + + +function(CMAKE_PARSE_ARGUMENTS prefix _optionNames _singleArgNames _multiArgNames) + # first set all result variables to empty/FALSE + foreach(arg_name ${_singleArgNames} ${_multiArgNames}) + set(${prefix}_${arg_name}) + endforeach() + + foreach(option ${_optionNames}) + set(${prefix}_${option} FALSE) + endforeach() + + set(${prefix}_UNPARSED_ARGUMENTS) + + set(insideValues FALSE) + set(currentArgName) + + # now iterate over all arguments and fill the result variables + foreach(currentArg ${ARGN}) + list(FIND _optionNames "${currentArg}" optionIndex) # ... then this marks the end of the arguments belonging to this keyword + list(FIND _singleArgNames "${currentArg}" singleArgIndex) # ... then this marks the end of the arguments belonging to this keyword + list(FIND _multiArgNames "${currentArg}" multiArgIndex) # ... then this marks the end of the arguments belonging to this keyword + + if(${optionIndex} EQUAL -1 AND ${singleArgIndex} EQUAL -1 AND ${multiArgIndex} EQUAL -1) + if(insideValues) + if("${insideValues}" STREQUAL "SINGLE") + set(${prefix}_${currentArgName} ${currentArg}) + set(insideValues FALSE) + elseif("${insideValues}" STREQUAL "MULTI") + list(APPEND ${prefix}_${currentArgName} ${currentArg}) + endif() + else() + list(APPEND ${prefix}_UNPARSED_ARGUMENTS ${currentArg}) + endif() + else() + if(NOT ${optionIndex} EQUAL -1) + set(${prefix}_${currentArg} TRUE) + set(insideValues FALSE) + elseif(NOT ${singleArgIndex} EQUAL -1) + set(currentArgName ${currentArg}) + set(${prefix}_${currentArgName}) + set(insideValues "SINGLE") + elseif(NOT ${multiArgIndex} EQUAL -1) + set(currentArgName ${currentArg}) + set(${prefix}_${currentArgName}) + set(insideValues "MULTI") + endif() + endif() + + endforeach() + + # propagate the result variables to the caller: + foreach(arg_name ${_singleArgNames} ${_multiArgNames} ${_optionNames}) + set(${prefix}_${arg_name} ${${prefix}_${arg_name}} PARENT_SCOPE) + endforeach() + set(${prefix}_UNPARSED_ARGUMENTS ${${prefix}_UNPARSED_ARGUMENTS} PARENT_SCOPE) + +endfunction() diff --git a/cmake/EthBuildInfo.cmake b/cmake/EthBuildInfo.cmake new file mode 100644 index 0000000000..8bd0685bd0 --- /dev/null +++ b/cmake/EthBuildInfo.cmake @@ -0,0 +1,53 @@ +function(create_build_info) + + # Set build platform; to be written to BuildInfo.h + set(ETH_BUILD_OS "${CMAKE_SYSTEM_NAME}") + + if (CMAKE_COMPILER_IS_MINGW) + set(ETH_BUILD_COMPILER "mingw") + elseif (CMAKE_COMPILER_IS_MSYS) + set(ETH_BUILD_COMPILER "msys") + elseif (CMAKE_COMPILER_IS_GNUCXX) + set(ETH_BUILD_COMPILER "g++") + elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + set(ETH_BUILD_COMPILER "msvc") + elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") + set(ETH_BUILD_COMPILER "clang") + elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang") + set(ETH_BUILD_COMPILER "appleclang") + else () + set(ETH_BUILD_COMPILER "unknown") + endif () + + if (EVMJIT) + set(ETH_BUILD_JIT_MODE "JIT") + else () + set(ETH_BUILD_JIT_MODE "Interpreter") + endif () + + set(ETH_BUILD_PLATFORM "${ETH_BUILD_OS}/${ETH_BUILD_COMPILER}/${ETH_BUILD_JIT_MODE}") + + #cmake build type may be not speCified when using msvc + if (CMAKE_BUILD_TYPE) + set(_cmake_build_type ${CMAKE_BUILD_TYPE}) + else() + set(_cmake_build_type "${CMAKE_CFG_INTDIR}") + endif() + + # Generate header file containing useful build information + add_custom_target(BuildInfo.h ALL + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + COMMAND ${CMAKE_COMMAND} -DETH_SOURCE_DIR="${PROJECT_SOURCE_DIR}" -DETH_BUILDINFO_IN="${ETH_CMAKE_DIR}/templates/BuildInfo.h.in" -DETH_DST_DIR="${PROJECT_BINARY_DIR}/include" -DETH_CMAKE_DIR="${ETH_CMAKE_DIR}" + -DETH_BUILD_TYPE="${_cmake_build_type}" + -DETH_BUILD_OS="${ETH_BUILD_OS}" + -DETH_BUILD_COMPILER="${ETH_BUILD_COMPILER}" + -DETH_BUILD_JIT_MODE="${ETH_BUILD_JIT_MODE}" + -DETH_BUILD_PLATFORM="${ETH_BUILD_PLATFORM}" + -DETH_BUILD_NUMBER="${BUILD_NUMBER}" + -DETH_VERSION_SUFFIX="${VERSION_SUFFIX}" + -DPROJECT_VERSION="${PROJECT_VERSION}" + -DETH_FATDB="${FATDB10}" + -P "${ETH_SCRIPTS_DIR}/buildinfo.cmake" + ) + include_directories(BEFORE ${PROJECT_BINARY_DIR}) +endfunction() diff --git a/cmake/EthCompilerSettings.cmake b/cmake/EthCompilerSettings.cmake new file mode 100644 index 0000000000..aa011b5ce3 --- /dev/null +++ b/cmake/EthCompilerSettings.cmake @@ -0,0 +1,188 @@ +#------------------------------------------------------------------------------ +# EthCompilerSettings.cmake +# +# CMake file for cpp-ethereum project which specifies our compiler settings +# for each supported platform and build configuration. +# +# The documentation for cpp-ethereum is hosted at http://cpp-ethereum.org +# +# Copyright (c) 2014-2016 cpp-ethereum contributors. +#------------------------------------------------------------------------------ + +# Clang seeks to be command-line compatible with GCC as much as possible, so +# most of our compiler settings are common between GCC and Clang. +# +# These settings then end up spanning all POSIX platforms (Linux, OS X, BSD, etc) + +# Use ccache if available +find_program(CCACHE_FOUND ccache) +if(CCACHE_FOUND) + set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache) + set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache) + message("Using ccache") +endif(CCACHE_FOUND) + +if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")) + + # Use ISO C++11 standard language. + set(CMAKE_CXX_FLAGS -std=c++11) + set(CMAKE_C_FLAGS -std=c99) + + # Enables all the warnings about constructions that some users consider questionable, + # and that are easy to avoid. Also enable some extra warning flags that are not + # enabled by -Wall. Finally, treat at warnings-as-errors, which forces developers + # to fix warnings as they arise, so they don't accumulate "to be fixed later". + add_compile_options(-Wall) + add_compile_options(-Wno-unused-variable) + add_compile_options(-Wunused-parameter) + add_compile_options(-Wextra) + #add_compile_options(-Werror) + + # Disable warnings about unknown pragmas (which is enabled by -Wall). + add_compile_options(-Wno-unknown-pragmas) + + add_compile_options(-fno-omit-frame-pointer) + + # Configuration-specific compiler settings. + set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -DETH_DEBUG -DELPP_THREAD_SAFE") + set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG -DETH_RELEASE -DELPP_THREAD_SAFE") + set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG -DETH_RELEASE -DELPP_THREAD_SAFE") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g -DETH_RELEASE -DELPP_THREAD_SAFE") + + option(USE_LD_GOLD "Use GNU gold linker" ON) + if (USE_LD_GOLD) + execute_process(COMMAND ${CMAKE_C_COMPILER} -fuse-ld=gold -Wl,--version ERROR_QUIET OUTPUT_VARIABLE LD_VERSION) + if ("${LD_VERSION}" MATCHES "GNU gold") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=gold") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fuse-ld=gold") + endif () + endif () + + # Additional GCC-specific compiler settings. + if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") + + # Check that we've got GCC 4.7 or newer. + execute_process( + COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION) + if (NOT (GCC_VERSION VERSION_GREATER 4.7 OR GCC_VERSION VERSION_EQUAL 4.7)) + message(FATAL_ERROR "${PROJECT_NAME} requires g++ 4.7 or greater.") + endif () + + # Strong stack protection was only added in GCC 4.9. + # Use it if we have the option to do so. + # See https://lwn.net/Articles/584225/ + if (GCC_VERSION VERSION_GREATER 4.9 OR GCC_VERSION VERSION_EQUAL 4.9) + add_compile_options(-fstack-protector-strong) + add_compile_options(-fstack-protector) + endif() + + # Additional Clang-specific compiler settings. + elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") + + add_compile_options(-fstack-protector) + + # Enable strong stack protection only on Mac and only for OS X Yosemite + # or newer (AppleClang 7.0+). We should be able to re-enable this setting + # on non-Apple Clang as well, if we can work out what expression to use for + # the version detection. + + # The fact that the version-reporting for AppleClang loses the original + # Clang versioning is rather annoying. Ideally we could just have + # a single cross-platform "if version >= 3.4.1" check. + # + # There is debug text in the else clause below, to help us work out what + # such an expression should be, if we can get this running on a Trusty box + # with Clang. Greg Colvin previously replicated the issue there too. + # + # See https://github.com/ethereum/webthree-umbrella/issues/594 + + if (APPLE) + if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 7.0 OR CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 7.0) + add_compile_options(-fstack-protector-strong) + endif() + else() + message(WARNING "CMAKE_CXX_COMPILER_VERSION = ${CMAKE_CXX_COMPILER_VERSION}") + endif() + + # Some Linux-specific Clang settings. We don't want these for OS X. + if ("${CMAKE_SYSTEM_NAME}" MATCHES "Linux") + + # Tell Boost that we're using Clang's libc++. Not sure exactly why we need to do. + add_definitions(-DBOOST_ASIO_HAS_CLANG_LIBCXX) + + # Use fancy colors in the compiler diagnostics + add_compile_options(-fcolor-diagnostics) + endif() + endif() + +# The major alternative compiler to GCC/Clang is Microsoft's Visual C++ compiler, only available on Windows. +elseif (MSVC) + + add_compile_options(/MP) # enable parallel compilation + add_compile_options(/EHsc) # specify Exception Handling Model in msvc + add_compile_options(/WX) # enable warnings-as-errors + add_compile_options(/wd4068) # disable unknown pragma warning (4068) + add_compile_options(/wd4996) # disable unsafe function warning (4996) + add_compile_options(/wd4503) # disable decorated name length exceeded, name was truncated (4503) + add_compile_options(/wd4267) # disable conversion from 'size_t' to 'type', possible loss of data (4267) + add_compile_options(/wd4180) # disable qualifier applied to function type has no meaning; ignored (4180) + add_compile_options(/wd4290) # disable C++ exception specification ignored except to indicate a function is not __declspec(nothrow) (4290) + add_compile_options(/wd4297) # disable 's function assumed not to throw an exception but does (4297) + add_compile_options(/wd4244) # disable conversion from 'type1' to 'type2', possible loss of data (4244) + add_compile_options(/wd4800) # disable forcing value to bool 'true' or 'false' (performance warning) (4800) + add_compile_options(-D_WIN32_WINNT=0x0600) # declare Windows Vista API requirement + add_compile_options(-DNOMINMAX) # undefine windows.h MAX && MIN macros cause it cause conflicts with std::min && std::max functions + add_compile_options(-DMINIUPNP_STATICLIB) # define miniupnp static library + + # Always use Release variant of C++ runtime. + # We don't want to provide Debug variants of all dependencies. Some default + # flags set by CMake must be tweaked. + string(REPLACE "/MDd" "/MD" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}") + string(REPLACE "/D_DEBUG" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}") + string(REPLACE "/RTC1" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}") + string(REPLACE "/MDd" "/MD" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}") + string(REPLACE "/D_DEBUG" "" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}") + string(REPLACE "/RTC1" "" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}") + set_property(GLOBAL PROPERTY DEBUG_CONFIGURATIONS OFF) + + # disable empty object file warning + set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} /ignore:4221") + # warning LNK4075: ignoring '/EDITANDCONTINUE' due to '/SAFESEH' specification + # warning LNK4099: pdb was not found with lib + # stack size 16MB + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /ignore:4099,4075 /STACK:16777216") + +# If you don't have GCC, Clang or VC++ then you are on your own. Good luck! +else () + message(WARNING "Your compiler is not tested, if you run into any issues, we'd welcome any patches.") +endif () + +if (SANITIZE) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-omit-frame-pointer -fsanitize=${SANITIZE}") + if (${CMAKE_CXX_COMPILER_ID} MATCHES "Clang") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize-blacklist=${CMAKE_SOURCE_DIR}/sanitizer-blacklist.txt") + endif() +endif() + +if (PROFILING AND (("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang"))) + set(CMAKE_CXX_FLAGS "-g ${CMAKE_CXX_FLAGS}") + set(CMAKE_C_FLAGS "-g ${CMAKE_C_FLAGS}") + add_definitions(-DETH_PROFILING_GPERF) + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -lprofiler") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lprofiler") +endif () + +if (COVERAGE) + set(CMAKE_CXX_FLAGS "-g --coverage ${CMAKE_CXX_FLAGS}") + set(CMAKE_C_FLAGS "-g --coverage ${CMAKE_C_FLAGS}") + set(CMAKE_SHARED_LINKER_FLAGS "--coverage ${CMAKE_SHARED_LINKER_FLAGS}") + set(CMAKE_EXE_LINKER_FLAGS "--coverage ${CMAKE_EXE_LINKER_FLAGS}") + find_program(LCOV_TOOL lcov) + message(STATUS "lcov tool: ${LCOV_TOOL}") + if (LCOV_TOOL) + add_custom_target(coverage.info + COMMAND ${LCOV_TOOL} -o ${CMAKE_BINARY_DIR}/coverage.info -c -d ${CMAKE_BINARY_DIR} + COMMAND ${LCOV_TOOL} -o ${CMAKE_BINARY_DIR}/coverage.info -r ${CMAKE_BINARY_DIR}/coverage.info '/usr*' '${CMAKE_BINARY_DIR}/deps/*' '${CMAKE_SOURCE_DIR}/deps/*' + ) + endif() +endif () diff --git a/cmake/EthDependencies.cmake b/cmake/EthDependencies.cmake new file mode 100644 index 0000000000..76f5eeed95 --- /dev/null +++ b/cmake/EthDependencies.cmake @@ -0,0 +1,105 @@ +# all dependencies that are not directly included in the cpp-ethereum distribution are defined here +# for this to work, download the dependency via the cmake script in extdep or install them manually! + +function(eth_show_dependency DEP NAME) + get_property(DISPLAYED GLOBAL PROPERTY ETH_${DEP}_DISPLAYED) + if (NOT DISPLAYED) + set_property(GLOBAL PROPERTY ETH_${DEP}_DISPLAYED TRUE) + message(STATUS "${NAME} headers: ${${DEP}_INCLUDE_DIRS}") + message(STATUS "${NAME} lib : ${${DEP}_LIBRARIES}") + if (NOT("${${DEP}_DLLS}" STREQUAL "")) + message(STATUS "${NAME} dll : ${${DEP}_DLLS}") + endif() + endif() +endfunction() + +# The Windows platform has not historically had any standard packaging system for delivering +# versioned releases of libraries. Homebrew and PPA perform that function for macOS and Ubuntu +# respectively, and there are analogous standards for other Linux distros. In the absense of +# such a standard, we have chosen to make a "fake packaging system" for cpp-ethereum, which is +# implemented in https://github.com/ethereum/cpp-dependencies. +# +# NOTE - In the last couple of years, the NuGet packaging system, first created for delivery +# of .NET packages, has added support for C++ packages, and it may be possible for us to migrate +# our "fake package server" to that real package server. That would certainly be preferable +# to rolling our own, but it also puts us at the mercy of intermediate package maintainers who +# may be inactive. There is not a fantastic range of packages available at the time of writing, +# so we might find that such a move turns us into becoming the package maintainer for our +# dependencies. Not a net win :-) +# +# "Windows - Try to use NuGet C++ packages" +# https://github.com/ethereum/webthree-umbrella/issues/509 +# +# Perhaps a better alternative is to step away from dependencies onto binary releases entirely, +# and switching to build-from-source for some (or all) of our dependencies, especially if they +# are small. That gives us total control, but at the cost of longer build times. That is the +# approach which Pawel has taken for LLVM in https://github.com/ethereum/evmjit. + +if (MSVC) + if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.0.0) + message(FATAL_ERROR "ERROR - As of the 1.3.0 release, cpp-ethereum only supports Visual Studio 2015 or newer.\nPlease download from https://www.visualstudio.com/en-us/products/visual-studio-community-vs.aspx.") + else() + get_filename_component(ETH_DEPENDENCY_INSTALL_DIR "${CMAKE_CURRENT_LIST_DIR}/../deps/x64" ABSOLUTE) + endif() + set (CMAKE_PREFIX_PATH ${ETH_DEPENDENCY_INSTALL_DIR} ${CMAKE_PREFIX_PATH}) +endif() + +# custom cmake scripts +set(ETH_CMAKE_DIR ${CMAKE_CURRENT_LIST_DIR}) +set(ETH_SCRIPTS_DIR ${ETH_CMAKE_DIR}/scripts) + +find_program(CTEST_COMMAND ctest) + +# Use Boost "multithreaded mode" for Windows. The platform C/C++ runtime libraries come in +# two flavors on Windows, which causes an ABI schism across the whole ecosystem. This setting +# is declaring which side of that schism we fall on. +if (MSVC) + set(Boost_USE_MULTITHREADED ON) +endif() + +# Use the dynamic libraries for Boost for Linux and static linkage on Windows and macOS. +# We would like to use static linkage on Linux too, but on Ubuntu at least it appears that +# the prebuilt binaries for Boost won't support this. +# +# We will need to build Boost from source ourselves, with -fPIC enabled, before we are +# able to remove this conditional. That is exactly what has been happening for months for +# the doublethinkco cross-builds (see https://github.com/doublethinkco/cpp-ethereum-cross). +# +# Typical build error we get if trying to do static Boost on Ubunty Trusty (many of them): +# +# Linking CXX shared library libdevcore.so +# /usr/bin/ld.gold: error: /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/ +# libboost_thread.a(thread.o): requires dynamic R_X86_64_32 reloc which may overflow at +# runtime; recompile with -fPIC +# +# https://travis-ci.org/bobsummerwill/cpp-ethereum/jobs/145955041 + +if (UNIX AND NOT APPLE) + set(Boost_USE_STATIC_LIBS OFF) +else() + set(Boost_USE_STATIC_LIBS ON) +endif() + +include_directories(BEFORE "${PROJECT_BINARY_DIR}/include") + +function(eth_use TARGET REQUIRED) + if (NOT TARGET ${TARGET}) + message(FATAL_ERROR "eth_use called for non existing target ${TARGET}") + endif() + + foreach(MODULE ${ARGN}) + string(REPLACE "::" ";" MODULE_PARTS "${MODULE}") + list(GET MODULE_PARTS 0 MODULE_MAIN) + list(LENGTH MODULE_PARTS MODULE_LENGTH) + if (MODULE_LENGTH GREATER 1) + list(GET MODULE_PARTS 1 MODULE_SUB) + endif() + # TODO: check if file exists if not, throws FATAL_ERROR with detailed description + get_target_property(TARGET_APPLIED ${TARGET} TARGET_APPLIED_${MODULE_MAIN}_${MODULE_SUB}) + if (NOT TARGET_APPLIED) + include(Use${MODULE_MAIN}) + set_target_properties(${TARGET} PROPERTIES TARGET_APPLIED_${MODULE_MAIN}_${MODULE_SUB} TRUE) + eth_apply(${TARGET} ${REQUIRED} ${MODULE_SUB}) + endif() + endforeach() +endfunction() diff --git a/cmake/EthExecutableHelper.cmake b/cmake/EthExecutableHelper.cmake new file mode 100644 index 0000000000..422ccbdd8c --- /dev/null +++ b/cmake/EthExecutableHelper.cmake @@ -0,0 +1,155 @@ +# +# this function requires the following variables to be specified: +# ETH_VERSION +# PROJECT_NAME +# PROJECT_VERSION +# PROJECT_COPYRIGHT_YEAR +# PROJECT_VENDOR +# PROJECT_DOMAIN_SECOND +# PROJECT_DOMAIN_FIRST +# SRC_LIST +# HEADERS +# +# params: +# ICON +# + +macro(eth_add_executable EXECUTABLE) + set (extra_macro_args ${ARGN}) + set (options) + set (one_value_args ICON) + set (multi_value_args UI_RESOURCES WIN_RESOURCES) + cmake_parse_arguments (ETH_ADD_EXECUTABLE "${options}" "${one_value_args}" "${multi_value_args}" "${extra_macro_args}") + + if (APPLE) + + add_executable(${EXECUTABLE} MACOSX_BUNDLE ${SRC_LIST} ${HEADERS} ${ETH_ADD_EXECUTABLE_UI_RESOURCES}) + set(PROJECT_VERSION "${ETH_VERSION}") + set(MACOSX_BUNDLE_INFO_STRING "${PROJECT_NAME} ${PROJECT_VERSION}") + set(MACOSX_BUNDLE_BUNDLE_VERSION "${PROJECT_NAME} ${PROJECT_VERSION}") + set(MACOSX_BUNDLE_LONG_VERSION_STRING "${PROJECT_NAME} ${PROJECT_VERSION}") + set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${PROJECT_VERSION}") + set(MACOSX_BUNDLE_COPYRIGHT "${PROJECT_COPYRIGHT_YEAR} ${PROJECT_VENDOR}") + set(MACOSX_BUNDLE_GUI_IDENTIFIER "${PROJECT_DOMAIN_SECOND}.${PROJECT_DOMAIN_FIRST}") + set(MACOSX_BUNDLE_BUNDLE_NAME ${EXECUTABLE}) + set(MACOSX_BUNDLE_ICON_FILE ${ETH_ADD_EXECUTABLE_ICON}) + set_target_properties(${EXECUTABLE} PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/EthereumMacOSXBundleInfo.plist.in") + set_source_files_properties(${EXECUTABLE} PROPERTIES MACOSX_PACKAGE_LOCATION MacOS) + set_source_files_properties("${CMAKE_CURRENT_SOURCE_DIR}/${MACOSX_BUNDLE_ICON_FILE}.icns" PROPERTIES MACOSX_PACKAGE_LOCATION Resources) + + else () + add_executable(${EXECUTABLE} ${ETH_ADD_EXECUTABLE_UI_RESOURCES} ${ETH_ADD_EXECUTABLE_WIN_RESOURCES} ${SRC_LIST} ${HEADERS}) + endif() + +endmacro() + +macro(eth_copy_dll EXECUTABLE DLL) + # dlls must be unsubstitud list variable (without ${}) in format + # optimized;path_to_dll.dll;debug;path_to_dlld.dll + if(DEFINED MSVC) + list(GET ${DLL} 1 DLL_RELEASE) + list(GET ${DLL} 3 DLL_DEBUG) + add_custom_command(TARGET ${EXECUTABLE} + PRE_BUILD + COMMAND ${CMAKE_COMMAND} ARGS + -DDLL_RELEASE="${DLL_RELEASE}" + -DDLL_DEBUG="${DLL_DEBUG}" + -DCONF="$" + -DDESTINATION="${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}" + -P "${ETH_SCRIPTS_DIR}/copydlls.cmake" + ) + endif() +endmacro() + +macro(eth_copy_dlls EXECUTABLE) + foreach(dll ${ARGN}) + eth_copy_dll(${EXECUTABLE} ${dll}) + endforeach(dll) +endmacro() + + +macro(eth_install_executable EXECUTABLE) + + if (APPLE) + + # TODO - Why is this different than the branch Linux below, which has the RUNTIME keyword too? + install(TARGETS ${EXECUTABLE} DESTINATION bin) + + elseif (MSVC) + + set(COMPONENT ${EXECUTABLE}) + + install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Debug/" + DESTINATION . + CONFIGURATIONS Debug + COMPONENT ${COMPONENT} + ) + + install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Release/" + DESTINATION . + CONFIGURATIONS Release + COMPONENT ${COMPONENT} + ) + + install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo/" + DESTINATION . + CONFIGURATIONS RelWithDebInfo + COMPONENT ${COMPONENT} + ) + + else() + install( TARGETS ${EXECUTABLE} RUNTIME DESTINATION bin) + endif () + +endmacro() + +macro (eth_name KEY VALUE) + if (NOT (APPLE OR WIN32)) + string(TOLOWER ${VALUE} LVALUE ) + set(${KEY} ${LVALUE}) + else() + set(${KEY} ${VALUE}) + endif() +endmacro() + +macro(jsonrpcstub_client_create EXECUTABLE SPEC CLIENTNAME CLIENTDIR CLIENTFILENAME) + if (ETH_JSON_RPC_STUB) + add_custom_target(${SPEC}stub) + add_custom_command( + TARGET ${SPEC}stub + POST_BUILD + DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${SPEC}" + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + COMMAND ${CMAKE_COMMAND} -DETH_SPEC_PATH="${CMAKE_CURRENT_SOURCE_DIR}/${SPEC}" -DETH_SOURCE_DIR="${CMAKE_SOURCE_DIR}" -DETH_CMAKE_DIR="${ETH_CMAKE_DIR}" + -DETH_CLIENT_DIR="${CLIENTDIR}" + -DETH_CLIENT_NAME=${CLIENTNAME} + -DETH_CLIENT_FILENAME=${CLIENTFILENAME} + -DETH_JSON_RPC_STUB="${ETH_JSON_RPC_STUB}" + -P "${ETH_SCRIPTS_DIR}/jsonrpcstub.cmake" + ) + add_dependencies(${EXECUTABLE} ${SPEC}stub) + endif () +endmacro() + +macro(jsonrpcstub_create EXECUTABLE SPEC SERVERNAME SERVERDIR SERVERFILENAME CLIENTNAME CLIENTDIR CLIENTFILENAME) + if (ETH_JSON_RPC_STUB) + add_custom_target(${SPEC}stub) + add_custom_command( + TARGET ${SPEC}stub + POST_BUILD + DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${SPEC}" + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + COMMAND ${CMAKE_COMMAND} -DETH_SPEC_PATH="${CMAKE_CURRENT_SOURCE_DIR}/${SPEC}" -DETH_SOURCE_DIR="${CMAKE_SOURCE_DIR}" -DETH_CMAKE_DIR="${ETH_CMAKE_DIR}" + -DETH_CLIENT_DIR="${CLIENTDIR}" + -DETH_CLIENT_NAME=${CLIENTNAME} + -DETH_CLIENT_FILENAME=${CLIENTFILENAME} + -DETH_SERVER_DIR="${SERVERDIR}" + -DETH_SERVER_NAME=${SERVERNAME} + -DETH_SERVER_FILENAME=${SERVERFILENAME} + -DETH_JSON_RPC_STUB="${ETH_JSON_RPC_STUB}" + -P "${ETH_SCRIPTS_DIR}/jsonrpcstub.cmake" + ) + add_dependencies(${EXECUTABLE} ${SPEC}stub) + endif () +endmacro() + diff --git a/cmake/EthOptions.cmake b/cmake/EthOptions.cmake new file mode 100644 index 0000000000..6042e73600 --- /dev/null +++ b/cmake/EthOptions.cmake @@ -0,0 +1,138 @@ +macro(configure_project) + set(NAME ${PROJECT_NAME}) + + # Default to RelWithDebInfo configuration if no configuration is explicitly specified. + if (NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING + "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE) + endif() + + eth_default_option(BUILD_SHARED_LIBS OFF) + + # features + eth_default_option(VMTRACE OFF) + eth_default_option(PROFILING OFF) + eth_default_option(FATDB ON) + eth_default_option(ROCKSDB OFF) + eth_default_option(PARANOID OFF) + eth_default_option(MINIUPNPC ON) + + # components + eth_default_option(TESTS ON) + eth_default_option(TOOLS ON) + eth_default_option(EVMJIT OFF) + + # Resolve any clashes between incompatible options. + if ("${CMAKE_BUILD_TYPE}" STREQUAL "Release") + if (PARANOID) + message("Paranoia requires debug - disabling for release build.") + set(PARANOID OFF) + endif () + if (VMTRACE) + message("VM Tracing requires debug - disabling for release build.") + set (VMTRACE OFF) + endif () + endif () + + # Define a matching property name of each of the "features". + foreach(FEATURE ${ARGN}) + set(SUPPORT_${FEATURE} TRUE) + endforeach() + + # Temporary pre-processor symbol used for hiding broken unit-tests. + # Hiding them behind this pre-processor symbol lets us turn them off + # and on again easily enough, and also to grep for them. + add_definitions(-DDISABLE_BROKEN_UNIT_TESTS_UNTIL_WE_FIX_THEM) + + # Are we including the JIT EVM module? + # That pulls in a quite heavyweight LLVM dependency, which is + # not suitable for all platforms. + if (EVMJIT) + add_definitions(-DETH_EVMJIT) + endif () + + if (ODBC) + add_definitions(-DETH_ODBC) + endif () + + # FATDB is an option to include the reverse hashes for the trie, + # i.e. it allows you to iterate over the contents of the state. + if (FATDB) + add_definitions(-DETH_FATDB) + endif () + + # TODO: What does "paranoia" even mean? + if (PARANOID) + add_definitions(-DETH_PARANOIA) + endif () + + # TODO: What does "VM trace" even mean? + if (VMTRACE) + add_definitions(-DETH_VMTRACE) + endif () + + # CI Builds should provide (for user builds this is totally optional) + # -DBUILD_NUMBER - A number to identify the current build with. Becomes TWEAK component of project version. + # -DVERSION_SUFFIX - A string to append to the end of the version string where applicable. + if (NOT DEFINED BUILD_NUMBER) + # default is big so that local build is always considered greater + # and can easily replace CI build for for all platforms if needed. + # Windows max version component number is 65535 + set(BUILD_NUMBER 65535) + endif() + + # Suffix like "-rc1" e.t.c. to append to versions wherever needed. + if (NOT DEFINED VERSION_SUFFIX) + set(VERSION_SUFFIX "") + endif() + + include(EthBuildInfo) + create_build_info() + print_config(${NAME}) +endmacro() + +macro(print_config NAME) + message("") + message("------------------------------------------------------------------------") + message("-- Configuring ${NAME}") + message("------------------------------------------------------------------------") + message("-- CMake ${CMAKE_VERSION} (${CMAKE_COMMAND})") + message("-- CMAKE_BUILD_TYPE Build type ${CMAKE_BUILD_TYPE}") + message("-- TARGET_PLATFORM Target platform ${CMAKE_SYSTEM_NAME}") + message("-- STATIC BUILD ${STATIC_BUILD}") + message("--------------------------------------------------------------- features") +if (SUPPORT_CPUID) + message("-- Hardware identification support ${CPUID_FOUND}") +endif() +if (SUPPORT_CURL) + message("-- HTTP Request support ${CURL_FOUND}") +endif() +if (SUPPORT_VMTRACE) + message("-- VMTRACE VM execution tracing ${VMTRACE}") +endif() + message("-- PROFILING Profiling support ${PROFILING}") +if (SUPPORT_FATDB) + message("-- FATDB Full database exploring ${FATDB}") +endif() +if (SUPPORT_ROCKSDB) + message("-- ROCKSDB Prefer rocksdb to leveldb ${ROCKSDB}") +endif() +if (SUPPORT_PARANOID) + message("-- PARANOID - ${PARANOID}") +endif() +if (SUPPORT_MINIUPNPC) + message("-- MINIUPNPC - ${MINIUPNPC}") +endif() + message("------------------------------------------------------------- components") +if (SUPPORT_TESTS) + message("-- TESTS Build tests ${TESTS}") +endif() +if (SUPPORT_TOOLS) + message("-- TOOLS Build tools ${TOOLS}") +endif() +if (SUPPORT_EVMJIT) + message("-- EVMJIT Build LLVM-based JIT EVM ${EVMJIT}") +endif() + message("------------------------------------------------------------------------") + message("") +endmacro() diff --git a/cmake/EthPolicy.cmake b/cmake/EthPolicy.cmake new file mode 100644 index 0000000000..7f7b2d2490 --- /dev/null +++ b/cmake/EthPolicy.cmake @@ -0,0 +1,35 @@ +# it must be a macro cause policies have scopes +# http://www.cmake.org/cmake/help/v3.0/command/cmake_policy.html +macro (eth_policy) + # link_directories() treats paths relative to the source dir. + cmake_policy(SET CMP0015 NEW) + + # let cmake autolink dependencies on windows + cmake_policy(SET CMP0020 NEW) + + # CMake 2.8.12 and lower allowed the use of targets and files with double + # colons in target_link_libraries, + cmake_policy(SET CMP0028 NEW) + + if (${CMAKE_VERSION} VERSION_GREATER 3.0) + + # fix MACOSX_RPATH + cmake_policy(SET CMP0042 OLD) + + # ignore COMPILE_DEFINITIONS_ properties + cmake_policy(SET CMP0043 OLD) + + # allow VERSION argument in project() + cmake_policy(SET CMP0048 NEW) + + endif() + + if (${CMAKE_VERSION} VERSION_GREATER 3.1) + + # do not interpret if() arguments as variables! + cmake_policy(SET CMP0054 NEW) + + endif() + +endmacro() + diff --git a/cmake/EthUtils.cmake b/cmake/EthUtils.cmake new file mode 100644 index 0000000000..1096bb61b1 --- /dev/null +++ b/cmake/EthUtils.cmake @@ -0,0 +1,114 @@ +# +# renames the file if it is different from its destination +include(CMakeParseArguments) +# +macro(replace_if_different SOURCE DST) + set(extra_macro_args ${ARGN}) + set(options CREATE) + set(one_value_args) + set(multi_value_args) + cmake_parse_arguments(REPLACE_IF_DIFFERENT "${options}" "${one_value_args}" "${multi_value_args}" "${extra_macro_args}") + + if (REPLACE_IF_DIFFERENT_CREATE AND (NOT (EXISTS "${DST}"))) + file(WRITE "${DST}" "") + endif() + + execute_process(COMMAND ${CMAKE_COMMAND} -E compare_files "${SOURCE}" "${DST}" RESULT_VARIABLE DIFFERENT OUTPUT_QUIET ERROR_QUIET) + + if (DIFFERENT) + execute_process(COMMAND ${CMAKE_COMMAND} -E rename "${SOURCE}" "${DST}") + else() + execute_process(COMMAND ${CMAKE_COMMAND} -E remove "${SOURCE}") + endif() +endmacro() + +macro(eth_add_test NAME) + + # parse arguments here + set(commands) + set(current_command "") + foreach (arg ${ARGN}) + if (arg STREQUAL "ARGS") + if (current_command) + list(APPEND commands ${current_command}) + endif() + set(current_command "") + else () + set(current_command "${current_command} ${arg}") + endif() + endforeach(arg) + list(APPEND commands ${current_command}) + + message(STATUS "test: ${NAME} | ${commands}") + + # create tests + set(index 0) + list(LENGTH commands count) + while (index LESS count) + list(GET commands ${index} test_arguments) + + set(run_test "--run_test=${NAME}") + add_test(NAME "${NAME}.${index}" COMMAND testeth ${run_test} ${test_arguments}) + + math(EXPR index "${index} + 1") + endwhile(index LESS count) + + # add target to run them + add_custom_target("test.${NAME}" + DEPENDS testeth + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -DETH_TEST_NAME="${NAME}" -DCTEST_COMMAND="${CTEST_COMMAND}" -P "${ETH_SCRIPTS_DIR}/runtest.cmake" + ) + +endmacro() + +# Creates C resources file from files +function(eth_add_resources RESOURCE_FILE OUT_FILE ETH_RES_DIR) + include("${RESOURCE_FILE}") + set(OUTPUT "${ETH_RESOURCE_LOCATION}/${ETH_RESOURCE_NAME}.hpp") + #message(FATAL_ERROR "res:! ${ETH_RESOURCE_LOCATION}") + include_directories("${ETH_RESOURCE_LOCATION}") + set(${OUT_FILE} "${OUTPUT}" PARENT_SCOPE) + + set(filenames "${RESOURCE_FILE}") + list(APPEND filenames "${ETH_SCRIPTS_DIR}/resources.cmake") + foreach(resource ${ETH_RESOURCES}) + list(APPEND filenames "${${resource}}") + endforeach(resource) + + add_custom_command(OUTPUT ${OUTPUT} + COMMAND ${CMAKE_COMMAND} -DETH_RES_FILE="${RESOURCE_FILE}" -DETH_RES_DIR="${ETH_RES_DIR}" -P "${ETH_SCRIPTS_DIR}/resources.cmake" + DEPENDS ${filenames} + ) +endfunction() + +macro(eth_default_option O DEF) + if (DEFINED ${O}) + if (${${O}}) + set(${O} ON) + else () + set(${O} OFF) + endif() + else () + set(${O} ${DEF}) + endif() +endmacro() + +# In Windows split repositories build we need to be checking whether or not +# Debug/Release or both versions were built for the config phase to run smoothly +macro(eth_check_library_link L) + if (${${L}_LIBRARY} AND ${${L}_LIBRARY} EQUAL "${L}_LIBRARY-NOTFOUND") + unset(${${L}_LIBRARY}) + endif() + if (${${L}_LIBRARY_DEBUG} AND ${${L}_LIBRARY_DEBUG} EQUAL "${L}_LIBRARY_DEBUG-NOTFOUND") + unset(${${L}_LIBRARY_DEBUG}) + endif() + if (${${L}_LIBRARY} AND ${${L}_LIBRARY_DEBUG}) + set(${L}_LIBRARIES optimized ${${L}_LIBRARY} debug ${${L}_LIBRARY_DEBUG}) + elseif (${${L}_LIBRARY}) + set(${L}_LIBRARIES ${${L}_LIBRARY}) + elseif (${${L}_LIBRARY_DEBUG}) + set(${L}_LIBRARIES ${${L}_LIBRARY_DEBUG}) + endif() +endmacro() + diff --git a/cmake/FindCURL.cmake b/cmake/FindCURL.cmake new file mode 100644 index 0000000000..f3c1e28ff0 --- /dev/null +++ b/cmake/FindCURL.cmake @@ -0,0 +1,57 @@ +# Find CURL +# +# Find the curl includes and library +# +# if you nee to add a custom library search path, do it via via CMAKE_PREFIX_PATH +# +# This module defines +# CURL_INCLUDE_DIRS, where to find header, etc. +# CURL_LIBRARIES, the libraries needed to use curl. +# CURL_FOUND, If false, do not try to use curl. + +# only look in default directories +find_path( + CURL_INCLUDE_DIR + NAMES curl/curl.h + DOC "curl include dir" +) + +find_library( + CURL_LIBRARY + # names from cmake's FindCURL + NAMES curl curllib libcurl_imp curllib_static libcurl + DOC "curl library" +) + +set(CURL_INCLUDE_DIRS ${CURL_INCLUDE_DIR}) +set(CURL_LIBRARIES ${CURL_LIBRARY}) + +# debug library on windows +# same naming convention as in qt (appending debug library with d) +# boost is using the same "hack" as us with "optimized" and "debug" +if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + + find_library( + CURL_LIBRARY_DEBUG + NAMES curld libcurld + DOC "curl debug library" + ) + + set(CURL_LIBRARIES optimized ${CURL_LIBRARIES} debug ${CURL_LIBRARY_DEBUG}) + + # prepare dlls + string(REPLACE ".lib" ".dll" CURL_DLL "${CURL_LIBRARY}") + string(REPLACE "/lib/" "/bin/" CURL_DLL "${CURL_DLL}") + string(REPLACE ".lib" ".dll" CURL_DLL_DEBUG "${CURL_LIBRARY_DEBUG}") + string(REPLACE "/lib/" "/bin/" CURL_DLL_DEBUG "${CURL_DLL_DEBUG}") + set(CURL_DLLS optimized "${CURL_DLL}" debug "${CURL_DLL_DEBUG}") + +endif() + +# handle the QUIETLY and REQUIRED arguments and set CURL_FOUND to TRUE +# if all listed variables are TRUE, hide their existence from configuration view +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(CURL DEFAULT_MSG + CURL_LIBRARY CURL_INCLUDE_DIR) +mark_as_advanced (CURL_INCLUDE_DIR CURL_LIBRARY) + diff --git a/cmake/FindCpuid.cmake b/cmake/FindCpuid.cmake new file mode 100644 index 0000000000..53d03de662 --- /dev/null +++ b/cmake/FindCpuid.cmake @@ -0,0 +1,33 @@ +# Find libcpuid +# +# Find the libcpuid includes and library +# +# if you nee to add a custom library search path, do it via via CMAKE_PREFIX_PATH +# +# This module defines +# CPUID_INCLUDE_DIRS, where to find header, etc. +# CPUID_LIBRARIES, the libraries needed to use cpuid. +# CPUID_FOUND, If false, do not try to use cpuid. + +# only look in default directories +find_path( + CPUID_INCLUDE_DIR + NAMES libcpuid/libcpuid.h + DOC "libcpuid include dir" + ) + +find_library( + CPUID_LIBRARY + NAMES cpuid + DOC "libcpuid library" + ) + +set(CPUID_INCLUDE_DIRS ${CPUID_INCLUDE_DIR}) +set(CPUID_LIBRARIES ${CPUID_LIBRARY}) + +# handle the QUIETLY and REQUIRED arguments and set CPUID_FOUND to TRUE +# if all listed variables are TRUE, hide their existence from configuration view +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Cpuid DEFAULT_MSG CPUID_LIBRARY CPUID_INCLUDE_DIR) +mark_as_advanced (CPUID_INCLUDE_DIR CPUID_LIBRARY) + diff --git a/cmake/FindDev.cmake b/cmake/FindDev.cmake new file mode 100644 index 0000000000..bf84d5c1d9 --- /dev/null +++ b/cmake/FindDev.cmake @@ -0,0 +1,69 @@ +#------------------------------------------------------------------------------ +# CMake helper for libdevcore, libdevcrypto and libp2p modules. +# +# This module defines +# Dev_XXX_LIBRARIES, the libraries needed to use ethereum. +# Dev_INCLUDE_DIRS +# +# The documentation for cpp-ethereum is hosted at http://cpp-ethereum.org +# +# ------------------------------------------------------------------------------ +# This file is part of cpp-ethereum. +# +# cpp-ethereum is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# cpp-ethereum 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cpp-ethereum. If not, see +# +# (c) 2014-2016 cpp-ethereum contributors. +#------------------------------------------------------------------------------ + +include(EthUtils) +set(LIBS devcore;devcrypto;p2p;contract) + +set(Dev_INCLUDE_DIRS "${CPP_ETHEREUM_DIR}") + +# if the project is a subset of main cpp-ethereum project +# use same pattern for variables as Boost uses +if ((DEFINED cpp-ethereum_VERSION) OR (DEFINED dev_VERSION)) + + foreach (l ${LIBS}) + string(TOUPPER ${l} L) + set ("Dev_${L}_LIBRARIES" ${l}) + endforeach() + +else() + + foreach (l ${LIBS}) + string(TOUPPER ${l} L) + + find_library(Dev_${L}_LIBRARY + NAMES ${l} + PATHS ${CMAKE_LIBRARY_PATH} + PATH_SUFFIXES "lib${l}" "${l}" "lib${l}/Debug" "lib${l}/Release" + NO_DEFAULT_PATH + ) + + set(Dev_${L}_LIBRARIES ${Dev_${L}_LIBRARY}) + + if (MSVC) + find_library(Dev_${L}_LIBRARY_DEBUG + NAMES ${l} + PATHS ${CMAKE_LIBRARY_PATH} + PATH_SUFFIXES "lib${l}/Debug" + NO_DEFAULT_PATH + ) + eth_check_library_link(Dev_${L}) + endif() + endforeach() + +endif() + diff --git a/cmake/FindEth.cmake b/cmake/FindEth.cmake new file mode 100644 index 0000000000..5dde3e8779 --- /dev/null +++ b/cmake/FindEth.cmake @@ -0,0 +1,76 @@ +#------------------------------------------------------------------------------ +# CMake helper for the majority of the cpp-ethereum modules. +# +# This module defines +# ETH_XXX_LIBRARIES, the libraries needed to use ethereum. +# ETH_FOUND, If false, do not try to use ethereum. +# TODO: ETH_INCLUDE_DIRS +# +# The documentation for cpp-ethereum is hosted at http://cpp-ethereum.org +# +# ------------------------------------------------------------------------------ +# This file is part of cpp-ethereum. +# +# cpp-ethereum is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# cpp-ethereum 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cpp-ethereum. If not, see +# +# (c) 2014-2016 cpp-ethereum contributors. +#------------------------------------------------------------------------------ + +include(EthUtils) +if (ODBC) + set(LIBS ethashseal;ethereum;evm;ethcore;evmcore;ethash-cl;ethash;evmjit;testutils;pbftseal;raftseal;singlepoint;odbc) +else () + set(LIBS ethashseal;ethereum;evm;ethcore;evmcore;ethash-cl;ethash;evmjit;testutils;pbftseal;raftseal;singlepoint) +endif() +set(Eth_INCLUDE_DIRS "${CPP_ETHEREUM_DIR}") + +# if the project is a subset of main cpp-ethereum project +# use same pattern for variables as Boost uses +if ((DEFINED cpp-ethereum_VERSION) OR (DEFINED ethereum_VERSION)) + + foreach (l ${LIBS}) + string(TOUPPER ${l} L) + set ("Eth_${L}_LIBRARIES" ${l}) + endforeach() + +else() + + foreach (l ${LIBS}) + string(TOUPPER ${l} L) + + find_library(Eth_${L}_LIBRARY + NAMES ${l} + PATHS ${CMAKE_LIBRARY_PATH} + PATH_SUFFIXES "lib${l}" "${l}" "lib${l}/Debug" "lib${l}/Release" + # libevmjit is nested... + "evmjit/libevmjit" "evmjit/libevmjit/Release" + NO_DEFAULT_PATH + ) + + set(Eth_${L}_LIBRARIES ${Eth_${L}_LIBRARY}) + + if (MSVC) + find_library(Eth_${L}_LIBRARY_DEBUG + NAMES ${l} + PATHS ${CMAKE_LIBRARY_PATH} + PATH_SUFFIXES "lib${l}/Debug" + # libevmjit is nested... + "evmjit/libevmjit/Debug" + NO_DEFAULT_PATH + ) + eth_check_library_link(Eth_${L}) + endif() + endforeach() + +endif() diff --git a/cmake/FindGmp.cmake b/cmake/FindGmp.cmake new file mode 100644 index 0000000000..76af9fcb65 --- /dev/null +++ b/cmake/FindGmp.cmake @@ -0,0 +1,34 @@ +# Find gmp +# +# Find the gmp includes and library +# +# if you nee to add a custom library search path, do it via via CMAKE_PREFIX_PATH +# +# This module defines +# GMP_INCLUDE_DIRS, where to find header, etc. +# GMP_LIBRARIES, the libraries needed to use gmp. +# GMP_FOUND, If false, do not try to use gmp. + +# only look in default directories +find_path( + GMP_INCLUDE_DIR + NAMES gmp.h + DOC "gmp include dir" +) + +find_library( + GMP_LIBRARY + NAMES gmp + DOC "gmp library" +) + +set(GMP_INCLUDE_DIRS ${GMP_INCLUDE_DIR}) +set(GMP_LIBRARIES ${GMP_LIBRARY}) + +# handle the QUIETLY and REQUIRED arguments and set GMP_FOUND to TRUE +# if all listed variables are TRUE, hide their existence from configuration view +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(gmp DEFAULT_MSG + GMP_LIBRARY GMP_INCLUDE_DIR) +mark_as_advanced (GMP_INCLUDE_DIR GMP_LIBRARY) + diff --git a/cmake/FindLevelDB.cmake b/cmake/FindLevelDB.cmake new file mode 100644 index 0000000000..9a609c811e --- /dev/null +++ b/cmake/FindLevelDB.cmake @@ -0,0 +1,61 @@ +# Find leveldb +# +# Find the leveldb includes and library +# +# if you need to add a custom library search path, do it via via CMAKE_PREFIX_PATH +# +# This module defines +# LEVELDB_INCLUDE_DIRS, where to find header, etc. +# LEVELDB_LIBRARIES, the libraries needed to use leveldb. +# LEVELDB_FOUND, If false, do not try to use leveldb. + +# only look in default directories +find_path( + LEVELDB_INCLUDE_DIR + NAMES leveldb/db.h + DOC "leveldb include dir" +) + +find_library( + LEVELDB_LIBRARY + NAMES leveldb + DOC "leveldb library" +) + +set(LEVELDB_INCLUDE_DIRS ${LEVELDB_INCLUDE_DIR}) +set(LEVELDB_LIBRARIES ${LEVELDB_LIBRARY}) + +# When we're static linking (at least on OS X), leveldb also drags in snappy. +# This might be due to some dependency within leveldb which would be dead-code +# stripped if we were using a static lib for leveldb. We aren't (yet), because +# we only have partial static-linkage on OS X so far. +if (NOT BUILD_SHARED_LIBS AND APPLE) + find_path(SNAPPY_INCLUDE_DIR snappy.h PATH_SUFFIXES snappy) + find_library(SNAPPY_LIBRARY snappy) + set(LEVELDB_INCLUDE_DIRS ${LEVELDB_INCLUDE_DIR} ${SNAPPY_INCLUDE_DIR}) + set(LEVELDB_LIBRARIES ${LEVELDB_LIBRARY} ${SNAPPY_LIBRARY}) +endif() + +# debug library on windows +# same naming convention as in qt (appending debug library with d) +# boost is using the same "hack" as us with "optimized" and "debug" +if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + + find_library( + LEVELDB_LIBRARY_DEBUG + NAMES leveldbd + DOC "leveldb debug library" + ) + + list(APPEND LEVELDB_LIBRARIES "shlwapi") + list(APPEND LEVELDB_LIBRARY_DEBUG "shlwapi") + set(LEVELDB_LIBRARIES optimized ${LEVELDB_LIBRARIES} debug ${LEVELDB_LIBRARY_DEBUG}) +endif() + +# handle the QUIETLY and REQUIRED arguments and set LEVELDB_FOUND to TRUE +# if all listed variables are TRUE, hide their existence from configuration view +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(leveldb DEFAULT_MSG + LEVELDB_LIBRARY LEVELDB_INCLUDE_DIR) +mark_as_advanced (LEVELDB_INCLUDE_DIR LEVELDB_LIBRARY) + diff --git a/cmake/FindMHD.cmake b/cmake/FindMHD.cmake new file mode 100644 index 0000000000..c72d675c9b --- /dev/null +++ b/cmake/FindMHD.cmake @@ -0,0 +1,54 @@ +# Find microhttpd +# +# Find the microhttpd includes and library +# +# if you need to add a custom library search path, do it via via CMAKE_PREFIX_PATH +# +# This module defines +# MHD_INCLUDE_DIRS, where to find header, etc. +# MHD_LIBRARIES, the libraries needed to use jsoncpp. +# MHD_FOUND, If false, do not try to use jsoncpp. + +find_path( + MHD_INCLUDE_DIR + NAMES microhttpd.h + DOC "microhttpd include dir" +) + +find_library( + MHD_LIBRARY + NAMES microhttpd microhttpd-10 libmicrohttpd libmicrohttpd-dll + DOC "microhttpd library" +) + +set(MHD_INCLUDE_DIRS ${MHD_INCLUDE_DIR}) +set(MHD_LIBRARIES ${MHD_LIBRARY}) + +# debug library on windows +# same naming convention as in QT (appending debug library with d) +# boost is using the same "hack" as us with "optimized" and "debug" +# official MHD project actually uses _d suffix +if (MSVC) + + find_library( + MHD_LIBRARY_DEBUG + NAMES microhttpd_d microhttpd-10_d libmicrohttpd_d libmicrohttpd-dll_d + DOC "mhd debug library" + ) + + set(MHD_LIBRARIES optimized ${MHD_LIBRARIES} debug ${MHD_LIBRARY_DEBUG}) + + # prepare dlls + string(REPLACE ".lib" ".dll" MHD_DLL "${MHD_LIBRARY}") + string(REPLACE "/lib/" "/bin/" MHD_DLL "${MHD_DLL}") + string(REPLACE ".lib" ".dll" MHD_DLL_DEBUG "${MHD_LIBRARY_DEBUG}") + string(REPLACE "/lib/" "/bin/" MHD_DLL_DEBUG "${MHD_DLL_DEBUG}") + set(MHD_DLLS optimized ${MHD_DLL} debug "${MHD_DLL_DEBUG}") + +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(mhd DEFAULT_MSG + MHD_LIBRARY MHD_INCLUDE_DIR) + +mark_as_advanced(MHD_INCLUDE_DIR MHD_LIBRARY) diff --git a/cmake/FindMiniupnpc.cmake b/cmake/FindMiniupnpc.cmake new file mode 100644 index 0000000000..c0b086bc50 --- /dev/null +++ b/cmake/FindMiniupnpc.cmake @@ -0,0 +1,49 @@ +# Find miniupnpc +# +# Find the miniupnpc includes and library +# +# if you nee to add a custom library search path, do it via CMAKE_PREFIX_PATH +# +# This module defines +# MINIUPNPC_INCLUDE_DIRS, where to find header, etc. +# MINIUPNPC_LIBRARIES, the libraries needed to use miniupnpc. +# MINIUPNPC_FOUND, If false, do not try to use miniupnpc. + +# only look in default directories +find_path( + MINIUPNPC_INCLUDE_DIR + NAMES miniupnpc/miniupnpc.h + DOC "miniupnpc include dir" +) + +find_library( + MINIUPNPC_LIBRARY + NAMES miniupnpc + DOC "miniupnpc library" +) + +set(MINIUPNPC_INCLUDE_DIRS ${MINIUPNPC_INCLUDE_DIR}) +set(MINIUPNPC_LIBRARIES ${MINIUPNPC_LIBRARY}) + +# debug library on windows +# same naming convention as in QT (appending debug library with d) +# boost is using the same "hack" as us with "optimized" and "debug" +if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + + find_library( + MINIUPNPC_LIBRARY_DEBUG + NAMES miniupnpcd + DOC "miniupnpc debug library" + ) + + set(MINIUPNPC_LIBRARIES "iphlpapi" optimized ${MINIUPNPC_LIBRARIES} debug ${MINIUPNPC_LIBRARY_DEBUG}) + +endif() + +# handle the QUIETLY and REQUIRED arguments and set MINIUPNPC_FOUND to TRUE +# if all listed variables are TRUE, hide their existence from configuration view +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(miniupnpc DEFAULT_MSG + MINIUPNPC_LIBRARY MINIUPNPC_INCLUDE_DIR) +mark_as_advanced (MINIUPNPC_INCLUDE_DIR MINIUPNPC_LIBRARY) + diff --git a/cmake/FindPackageHandleStandardArgs.cmake b/cmake/FindPackageHandleStandardArgs.cmake new file mode 100644 index 0000000000..228ff0160f --- /dev/null +++ b/cmake/FindPackageHandleStandardArgs.cmake @@ -0,0 +1,382 @@ +#.rst: +# FindPackageHandleStandardArgs +# ----------------------------- +# +# +# +# FIND_PACKAGE_HANDLE_STANDARD_ARGS( ... ) +# +# This function is intended to be used in FindXXX.cmake modules files. +# It handles the REQUIRED, QUIET and version-related arguments to +# find_package(). It also sets the _FOUND variable. The +# package is considered found if all variables ... listed contain +# valid results, e.g. valid filepaths. +# +# There are two modes of this function. The first argument in both +# modes is the name of the Find-module where it is called (in original +# casing). +# +# The first simple mode looks like this: +# +# :: +# +# FIND_PACKAGE_HANDLE_STANDARD_ARGS( +# (DEFAULT_MSG|"Custom failure message") ... ) +# +# If the variables to are all valid, then +# _FOUND will be set to TRUE. If DEFAULT_MSG is given +# as second argument, then the function will generate itself useful +# success and error messages. You can also supply a custom error +# message for the failure case. This is not recommended. +# +# The second mode is more powerful and also supports version checking: +# +# :: +# +# FIND_PACKAGE_HANDLE_STANDARD_ARGS(NAME +# [FOUND_VAR ] +# [REQUIRED_VARS ...] +# [VERSION_VAR ] +# [HANDLE_COMPONENTS] +# [CONFIG_MODE] +# [FAIL_MESSAGE "Custom failure message"] ) +# +# In this mode, the name of the result-variable can be set either to +# either _FOUND or _FOUND using the +# FOUND_VAR option. Other names for the result-variable are not +# allowed. So for a Find-module named FindFooBar.cmake, the two +# possible names are FooBar_FOUND and FOOBAR_FOUND. It is recommended +# to use the original case version. If the FOUND_VAR option is not +# used, the default is _FOUND. +# +# As in the simple mode, if through are all valid, +# _FOUND will be set to TRUE. After REQUIRED_VARS the +# variables which are required for this package are listed. Following +# VERSION_VAR the name of the variable can be specified which holds the +# version of the package which has been found. If this is done, this +# version will be checked against the (potentially) specified required +# version used in the find_package() call. The EXACT keyword is also +# handled. The default messages include information about the required +# version and the version which has been actually found, both if the +# version is ok or not. If the package supports components, use the +# HANDLE_COMPONENTS option to enable handling them. In this case, +# find_package_handle_standard_args() will report which components have +# been found and which are missing, and the _FOUND variable +# will be set to FALSE if any of the required components (i.e. not the +# ones listed after OPTIONAL_COMPONENTS) are missing. Use the option +# CONFIG_MODE if your FindXXX.cmake module is a wrapper for a +# find_package(... NO_MODULE) call. In this case VERSION_VAR will be +# set to _VERSION and the macro will automatically check whether +# the Config module was found. Via FAIL_MESSAGE a custom failure +# message can be specified, if this is not used, the default message +# will be displayed. +# +# Example for mode 1: +# +# :: +# +# find_package_handle_standard_args(LibXml2 DEFAULT_MSG +# LIBXML2_LIBRARY LIBXML2_INCLUDE_DIR) +# +# +# +# LibXml2 is considered to be found, if both LIBXML2_LIBRARY and +# LIBXML2_INCLUDE_DIR are valid. Then also LIBXML2_FOUND is set to +# TRUE. If it is not found and REQUIRED was used, it fails with +# FATAL_ERROR, independent whether QUIET was used or not. If it is +# found, success will be reported, including the content of . On +# repeated Cmake runs, the same message won't be printed again. +# +# Example for mode 2: +# +# :: +# +# find_package_handle_standard_args(LibXslt +# FOUND_VAR LibXslt_FOUND +# REQUIRED_VARS LibXslt_LIBRARIES LibXslt_INCLUDE_DIRS +# VERSION_VAR LibXslt_VERSION_STRING) +# +# In this case, LibXslt is considered to be found if the variable(s) +# listed after REQUIRED_VAR are all valid, i.e. LibXslt_LIBRARIES and +# LibXslt_INCLUDE_DIRS in this case. The result will then be stored in +# LibXslt_FOUND . Also the version of LibXslt will be checked by using +# the version contained in LibXslt_VERSION_STRING. Since no +# FAIL_MESSAGE is given, the default messages will be printed. +# +# Another example for mode 2: +# +# :: +# +# find_package(Automoc4 QUIET NO_MODULE HINTS /opt/automoc4) +# find_package_handle_standard_args(Automoc4 CONFIG_MODE) +# +# In this case, FindAutmoc4.cmake wraps a call to find_package(Automoc4 +# NO_MODULE) and adds an additional search directory for automoc4. Here +# the result will be stored in AUTOMOC4_FOUND. The following +# FIND_PACKAGE_HANDLE_STANDARD_ARGS() call produces a proper +# success/error message. + +#============================================================================= +# Copyright 2007-2009 Kitware, Inc. +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +include(${CMAKE_CURRENT_LIST_DIR}/FindPackageMessage.cmake) +include(${CMAKE_CURRENT_LIST_DIR}/CMakeParseArguments.cmake) + +# internal helper macro +macro(_FPHSA_FAILURE_MESSAGE _msg) + if (${_NAME}_FIND_REQUIRED) + message(FATAL_ERROR "${_msg}") + else () + if (NOT ${_NAME}_FIND_QUIETLY) + message(STATUS "${_msg}") + endif () + endif () +endmacro() + + +# internal helper macro to generate the failure message when used in CONFIG_MODE: +macro(_FPHSA_HANDLE_FAILURE_CONFIG_MODE) + # _CONFIG is set, but FOUND is false, this means that some other of the REQUIRED_VARS was not found: + if(${_NAME}_CONFIG) + _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: missing: ${MISSING_VARS} (found ${${_NAME}_CONFIG} ${VERSION_MSG})") + else() + # If _CONSIDERED_CONFIGS is set, the config-file has been found, but no suitable version. + # List them all in the error message: + if(${_NAME}_CONSIDERED_CONFIGS) + set(configsText "") + list(LENGTH ${_NAME}_CONSIDERED_CONFIGS configsCount) + math(EXPR configsCount "${configsCount} - 1") + foreach(currentConfigIndex RANGE ${configsCount}) + list(GET ${_NAME}_CONSIDERED_CONFIGS ${currentConfigIndex} filename) + list(GET ${_NAME}_CONSIDERED_VERSIONS ${currentConfigIndex} version) + set(configsText "${configsText} ${filename} (version ${version})\n") + endforeach() + if (${_NAME}_NOT_FOUND_MESSAGE) + set(configsText "${configsText} Reason given by package: ${${_NAME}_NOT_FOUND_MESSAGE}\n") + endif() + _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} ${VERSION_MSG}, checked the following files:\n${configsText}") + + else() + # Simple case: No Config-file was found at all: + _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: found neither ${_NAME}Config.cmake nor ${_NAME_LOWER}-config.cmake ${VERSION_MSG}") + endif() + endif() +endmacro() + + +function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG) + +# set up the arguments for CMAKE_PARSE_ARGUMENTS and check whether we are in +# new extended or in the "old" mode: + set(options CONFIG_MODE HANDLE_COMPONENTS) + set(oneValueArgs FAIL_MESSAGE VERSION_VAR FOUND_VAR) + set(multiValueArgs REQUIRED_VARS) + set(_KEYWORDS_FOR_EXTENDED_MODE ${options} ${oneValueArgs} ${multiValueArgs} ) + list(FIND _KEYWORDS_FOR_EXTENDED_MODE "${_FIRST_ARG}" INDEX) + + if(${INDEX} EQUAL -1) + set(FPHSA_FAIL_MESSAGE ${_FIRST_ARG}) + set(FPHSA_REQUIRED_VARS ${ARGN}) + set(FPHSA_VERSION_VAR) + else() + + CMAKE_PARSE_ARGUMENTS(FPHSA "${options}" "${oneValueArgs}" "${multiValueArgs}" ${_FIRST_ARG} ${ARGN}) + + if(FPHSA_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "Unknown keywords given to FIND_PACKAGE_HANDLE_STANDARD_ARGS(): \"${FPHSA_UNPARSED_ARGUMENTS}\"") + endif() + + if(NOT FPHSA_FAIL_MESSAGE) + set(FPHSA_FAIL_MESSAGE "DEFAULT_MSG") + endif() + endif() + +# now that we collected all arguments, process them + + if("x${FPHSA_FAIL_MESSAGE}" STREQUAL "xDEFAULT_MSG") + set(FPHSA_FAIL_MESSAGE "Could NOT find ${_NAME}") + endif() + + # In config-mode, we rely on the variable _CONFIG, which is set by find_package() + # when it successfully found the config-file, including version checking: + if(FPHSA_CONFIG_MODE) + list(INSERT FPHSA_REQUIRED_VARS 0 ${_NAME}_CONFIG) + list(REMOVE_DUPLICATES FPHSA_REQUIRED_VARS) + set(FPHSA_VERSION_VAR ${_NAME}_VERSION) + endif() + + if(NOT FPHSA_REQUIRED_VARS) + message(FATAL_ERROR "No REQUIRED_VARS specified for FIND_PACKAGE_HANDLE_STANDARD_ARGS()") + endif() + + list(GET FPHSA_REQUIRED_VARS 0 _FIRST_REQUIRED_VAR) + + string(TOUPPER ${_NAME} _NAME_UPPER) + string(TOLOWER ${_NAME} _NAME_LOWER) + + if(FPHSA_FOUND_VAR) + if(FPHSA_FOUND_VAR MATCHES "^${_NAME}_FOUND$" OR FPHSA_FOUND_VAR MATCHES "^${_NAME_UPPER}_FOUND$") + set(_FOUND_VAR ${FPHSA_FOUND_VAR}) + else() + message(FATAL_ERROR "The argument for FOUND_VAR is \"${FPHSA_FOUND_VAR}\", but only \"${_NAME}_FOUND\" and \"${_NAME_UPPER}_FOUND\" are valid names.") + endif() + else() + set(_FOUND_VAR ${_NAME_UPPER}_FOUND) + endif() + + # collect all variables which were not found, so they can be printed, so the + # user knows better what went wrong (#6375) + set(MISSING_VARS "") + set(DETAILS "") + # check if all passed variables are valid + unset(${_FOUND_VAR}) + foreach(_CURRENT_VAR ${FPHSA_REQUIRED_VARS}) + if(NOT ${_CURRENT_VAR}) + set(${_FOUND_VAR} FALSE) + set(MISSING_VARS "${MISSING_VARS} ${_CURRENT_VAR}") + else() + set(DETAILS "${DETAILS}[${${_CURRENT_VAR}}]") + endif() + endforeach() + if(NOT "${${_FOUND_VAR}}" STREQUAL "FALSE") + set(${_FOUND_VAR} TRUE) + endif() + + # component handling + unset(FOUND_COMPONENTS_MSG) + unset(MISSING_COMPONENTS_MSG) + + if(FPHSA_HANDLE_COMPONENTS) + foreach(comp ${${_NAME}_FIND_COMPONENTS}) + if(${_NAME}_${comp}_FOUND) + + if(NOT DEFINED FOUND_COMPONENTS_MSG) + set(FOUND_COMPONENTS_MSG "found components: ") + endif() + set(FOUND_COMPONENTS_MSG "${FOUND_COMPONENTS_MSG} ${comp}") + + else() + + if(NOT DEFINED MISSING_COMPONENTS_MSG) + set(MISSING_COMPONENTS_MSG "missing components: ") + endif() + set(MISSING_COMPONENTS_MSG "${MISSING_COMPONENTS_MSG} ${comp}") + + if(${_NAME}_FIND_REQUIRED_${comp}) + set(${_FOUND_VAR} FALSE) + set(MISSING_VARS "${MISSING_VARS} ${comp}") + endif() + + endif() + endforeach() + set(COMPONENT_MSG "${FOUND_COMPONENTS_MSG} ${MISSING_COMPONENTS_MSG}") + set(DETAILS "${DETAILS}[c${COMPONENT_MSG}]") + endif() + + # version handling: + set(VERSION_MSG "") + set(VERSION_OK TRUE) + set(VERSION ${${FPHSA_VERSION_VAR}}) + + # check with DEFINED here as the requested or found version may be "0" + if (DEFINED ${_NAME}_FIND_VERSION) + if(DEFINED ${FPHSA_VERSION_VAR}) + + if(${_NAME}_FIND_VERSION_EXACT) # exact version required + # count the dots in the version string + string(REGEX REPLACE "[^.]" "" _VERSION_DOTS "${VERSION}") + # add one dot because there is one dot more than there are components + string(LENGTH "${_VERSION_DOTS}." _VERSION_DOTS) + if (_VERSION_DOTS GREATER ${_NAME}_FIND_VERSION_COUNT) + # Because of the C++ implementation of find_package() ${_NAME}_FIND_VERSION_COUNT + # is at most 4 here. Therefore a simple lookup table is used. + if (${_NAME}_FIND_VERSION_COUNT EQUAL 1) + set(_VERSION_REGEX "[^.]*") + elseif (${_NAME}_FIND_VERSION_COUNT EQUAL 2) + set(_VERSION_REGEX "[^.]*\\.[^.]*") + elseif (${_NAME}_FIND_VERSION_COUNT EQUAL 3) + set(_VERSION_REGEX "[^.]*\\.[^.]*\\.[^.]*") + else () + set(_VERSION_REGEX "[^.]*\\.[^.]*\\.[^.]*\\.[^.]*") + endif () + string(REGEX REPLACE "^(${_VERSION_REGEX})\\..*" "\\1" _VERSION_HEAD "${VERSION}") + unset(_VERSION_REGEX) + if (NOT ${_NAME}_FIND_VERSION VERSION_EQUAL _VERSION_HEAD) + set(VERSION_MSG "Found unsuitable version \"${VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"") + set(VERSION_OK FALSE) + else () + set(VERSION_MSG "(found suitable exact version \"${VERSION}\")") + endif () + unset(_VERSION_HEAD) + else () + if (NOT "${${_NAME}_FIND_VERSION}" VERSION_EQUAL "${VERSION}") + set(VERSION_MSG "Found unsuitable version \"${VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"") + set(VERSION_OK FALSE) + else () + set(VERSION_MSG "(found suitable exact version \"${VERSION}\")") + endif () + endif () + unset(_VERSION_DOTS) + + else() # minimum version specified: + if ("${${_NAME}_FIND_VERSION}" VERSION_GREATER "${VERSION}") + set(VERSION_MSG "Found unsuitable version \"${VERSION}\", but required is at least \"${${_NAME}_FIND_VERSION}\"") + set(VERSION_OK FALSE) + else () + set(VERSION_MSG "(found suitable version \"${VERSION}\", minimum required is \"${${_NAME}_FIND_VERSION}\")") + endif () + endif() + + else() + + # if the package was not found, but a version was given, add that to the output: + if(${_NAME}_FIND_VERSION_EXACT) + set(VERSION_MSG "(Required is exact version \"${${_NAME}_FIND_VERSION}\")") + else() + set(VERSION_MSG "(Required is at least version \"${${_NAME}_FIND_VERSION}\")") + endif() + + endif() + else () + if(VERSION) + set(VERSION_MSG "(found version \"${VERSION}\")") + endif() + endif () + + if(VERSION_OK) + set(DETAILS "${DETAILS}[v${VERSION}(${${_NAME}_FIND_VERSION})]") + else() + set(${_FOUND_VAR} FALSE) + endif() + + + # print the result: + if (${_FOUND_VAR}) + FIND_PACKAGE_MESSAGE(${_NAME} "Found ${_NAME}: ${${_FIRST_REQUIRED_VAR}} ${VERSION_MSG} ${COMPONENT_MSG}" "${DETAILS}") + else () + + if(FPHSA_CONFIG_MODE) + _FPHSA_HANDLE_FAILURE_CONFIG_MODE() + else() + if(NOT VERSION_OK) + _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: ${VERSION_MSG} (found ${${_FIRST_REQUIRED_VAR}})") + else() + _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} (missing: ${MISSING_VARS}) ${VERSION_MSG}") + endif() + endif() + + endif () + + set(${_FOUND_VAR} ${${_FOUND_VAR}} PARENT_SCOPE) + +endfunction() diff --git a/cmake/FindPackageMessage.cmake b/cmake/FindPackageMessage.cmake new file mode 100644 index 0000000000..73fef9af72 --- /dev/null +++ b/cmake/FindPackageMessage.cmake @@ -0,0 +1,57 @@ +#.rst: +# FindPackageMessage +# ------------------ +# +# +# +# FIND_PACKAGE_MESSAGE( "message for user" "find result details") +# +# This macro is intended to be used in FindXXX.cmake modules files. It +# will print a message once for each unique find result. This is useful +# for telling the user where a package was found. The first argument +# specifies the name (XXX) of the package. The second argument +# specifies the message to display. The third argument lists details +# about the find result so that if they change the message will be +# displayed again. The macro also obeys the QUIET argument to the +# find_package command. +# +# Example: +# +# :: +# +# if(X11_FOUND) +# FIND_PACKAGE_MESSAGE(X11 "Found X11: ${X11_X11_LIB}" +# "[${X11_X11_LIB}][${X11_INCLUDE_DIR}]") +# else() +# ... +# endif() + +#============================================================================= +# Copyright 2008-2009 Kitware, Inc. +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +function(FIND_PACKAGE_MESSAGE pkg msg details) + # Avoid printing a message repeatedly for the same find result. + if(NOT ${pkg}_FIND_QUIETLY) + string(REPLACE "\n" "" details "${details}") + set(DETAILS_VAR FIND_PACKAGE_MESSAGE_DETAILS_${pkg}) + if(NOT "${details}" STREQUAL "${${DETAILS_VAR}}") + # The message has not yet been printed. + message(STATUS "${msg}") + + # Save the find details in the cache to avoid printing the same + # message again. + set("${DETAILS_VAR}" "${details}" + CACHE INTERNAL "Details about finding ${pkg}") + endif() + endif() +endfunction() diff --git a/cmake/FindRocksDB.cmake b/cmake/FindRocksDB.cmake new file mode 100644 index 0000000000..5ffb5da55e --- /dev/null +++ b/cmake/FindRocksDB.cmake @@ -0,0 +1,49 @@ +# Find rocksdb +# +# Find the rocksdb includes and library +# +# if you nee to add a custom library search path, do it via via CMAKE_PREFIX_PATH +# +# This module defines +# ROCKSDB_INCLUDE_DIRS, where to find header, etc. +# ROCKSDB_LIBRARIES, the libraries needed to use rocksdb. +# ROCKSDB_FOUND, If false, do not try to use rocksdb. + +# only look in default directories +find_path( + ROCKSDB_INCLUDE_DIR + NAMES rocksdb/db.h + DOC "rocksdb include dir" +) + +find_library( + ROCKSDB_LIBRARY + NAMES rocksdb + DOC "rocksdb library" +) + +set(ROCKSDB_INCLUDE_DIRS ${ROCKSDB_INCLUDE_DIR}) +set(ROCKSDB_LIBRARIES ${ROCKSDB_LIBRARY}) + +# debug library on windows +# same naming convention as in qt (appending debug library with d) +# boost is using the same "hack" as us with "optimized" and "debug" +if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + + find_library( + ROCKSDB_LIBRARY_DEBUG + NAMES rocksdbd + DOC "rocksdb debug library" + ) + + set(ROCKSDB_LIBRARIES optimized ${ROCKSDB_LIBRARIES} debug ${ROCKSDB_LIBRARY_DEBUG}) + +endif() + +# handle the QUIETLY and REQUIRED arguments and set ROCKSDB_FOUND to TRUE +# if all listed variables are TRUE, hide their existence from configuration view +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(RocksDB DEFAULT_MSG + ROCKS_DB_LIBRARY ROCKSDB_INCLUDE_DIR) +mark_as_advanced (ROCKSDB_INCLUDE_DIR ROCKSDB_LIBRARY) + diff --git a/cmake/FindSSH2.cmake b/cmake/FindSSH2.cmake new file mode 100644 index 0000000000..fe51f9ff0e --- /dev/null +++ b/cmake/FindSSH2.cmake @@ -0,0 +1,30 @@ +# - Try to find the ssh2 libssh2 library +# Once done this will define +# +# SSH2_FOUND - system has the SSH2 libssh2 library +# SSH2_INCLUDE_DIR - the SSH2 libssh2 include directory +# SSH2_LIBRARIES - The libraries needed to use SSH2 libssh2 + +# only look in default directories +find_path( + SSH2_INCLUDE_DIR + NAMES libssh2.h + DOC "ssh2 include dir" +) + +find_library( + SSH2_LIBRARY + NAMES ssh2 libssh2 + DOC "ssh2 library" +) + +set(SSH2_INCLUDE_DIRS ${SSH2_INCLUDE_DIR}) +set(SSH2_LIBRARIES ${SSH2_LIBRARY}) + +# handle the QUIETLY and REQUIRED arguments and set CURL_FOUND to TRUE +# if all listed variables are TRUE, hide their existence from configuration view +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(SSH2 DEFAULT_MSG + SSH2_LIBRARY SSH2_INCLUDE_DIR) +mark_as_advanced (SSH2_INCLUDE_DIR SSH2_LIBRARY) + diff --git a/cmake/FindUtils.cmake b/cmake/FindUtils.cmake new file mode 100644 index 0000000000..e26db96394 --- /dev/null +++ b/cmake/FindUtils.cmake @@ -0,0 +1,70 @@ +#------------------------------------------------------------------------------ +# CMake helper for the "utils" modules, which are orphaned external +# packages - secp256k1, libscrypt and json_spirit. +# +# This module defines +# Utils_XXX_LIBRARIES, the libraries needed to use ethereum. +# Utils_INCLUDE_DIRS +# +# The documentation for cpp-ethereum is hosted at http://cpp-ethereum.org +# +# ------------------------------------------------------------------------------ +# This file is part of cpp-ethereum. +# +# cpp-ethereum is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# cpp-ethereum 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cpp-ethereum. If not, see +# +# (c) 2014-2016 cpp-ethereum contributors. +#------------------------------------------------------------------------------ + +include(EthUtils) +set(LIBS secp256k1;scrypt) + +set(Utils_INCLUDE_DIRS "${CPP_ETHEREUM_DIR}") + +# if the project is a subset of main cpp-ethereum project +# use same pattern for variables as Boost uses +if (DEFINED cpp-ethereum_VERSION) + + foreach (l ${LIBS}) + string(TOUPPER ${l} L) + set ("Utils_${L}_LIBRARIES" ${l}) + endforeach() + +else() + + foreach (l ${LIBS}) + string(TOUPPER ${l} L) + + find_library(Utils_${L}_LIBRARY + NAMES ${l} + PATHS ${CMAKE_LIBRARY_PATH} + PATH_SUFFIXES "lib${l}" "${l}" "lib${l}/Debug" "${l}/Debug" "lib${l}/Release" "${l}/Release" + NO_DEFAULT_PATH + ) + + set(Utils_${L}_LIBRARIES ${Utils_${L}_LIBRARY}) + + if (MSVC) + find_library(Utils_${L}_LIBRARY_DEBUG + NAMES ${l} + PATHS ${CMAKE_LIBRARY_PATH} + PATH_SUFFIXES "lib${l}/Debug" "${l}/Debug" + NO_DEFAULT_PATH + ) + eth_check_library_link(Utils_${L}) + endif() + endforeach() + +endif() + diff --git a/cmake/FindWeb3.cmake b/cmake/FindWeb3.cmake new file mode 100644 index 0000000000..a7988dda13 --- /dev/null +++ b/cmake/FindWeb3.cmake @@ -0,0 +1,68 @@ +#------------------------------------------------------------------------------ +# CMake helper for libwhisper, libwebthree and libweb3jsonrpc. +# +# This module defines +# Web3_XXX_LIBRARIES, the libraries needed to use ethereum. +# TODO: Web3_INCLUDE_DIRS +# +# The documentation for cpp-ethereum is hosted at http://cpp-ethereum.org +# +# ------------------------------------------------------------------------------ +# This file is part of cpp-ethereum. +# +# cpp-ethereum is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# cpp-ethereum 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cpp-ethereum. If not, see +# +# (c) 2014-2016 cpp-ethereum contributors. +#------------------------------------------------------------------------------ + +include(EthUtils) +set(LIBS whisper;webthree;web3jsonrpc) + +set(Web3_INCLUDE_DIRS ${CPP_ETHEREUM_DIR}) + +# if the project is a subset of cpp-ethereum +# use same pattern for variables as Boost uses +if ((DEFINED webthree_VERSION) OR (DEFINED cpp-ethereum_VERSION)) + + foreach (l ${LIBS}) + string(TOUPPER ${l} L) + set ("Web3_${L}_LIBRARIES" ${l}) + endforeach() + +else() + + foreach (l ${LIBS}) + string(TOUPPER ${l} L) + + find_library(Web3_${L}_LIBRARY + NAMES ${l} + PATHS ${CMAKE_LIBRARY_PATH} + PATH_SUFFIXES "lib${l}" "${l}" "lib${l}/Release" + NO_DEFAULT_PATH + ) + + set(Web3_${L}_LIBRARIES ${Web3_${L}_LIBRARY}) + + if (MSVC) + find_library(Web3_${L}_LIBRARY_DEBUG + NAMES ${l} + PATHS ${CMAKE_LIBRARY_PATH} + PATH_SUFFIXES "lib${l}/Debug" + NO_DEFAULT_PATH + ) + eth_check_library_link(Web3_${L}) + endif() + endforeach() + +endif() diff --git a/cmake/FindWindowsSDK.cmake b/cmake/FindWindowsSDK.cmake new file mode 100644 index 0000000000..6affcdb48e --- /dev/null +++ b/cmake/FindWindowsSDK.cmake @@ -0,0 +1,322 @@ +# - Find the Windows SDK aka Platform SDK +# +# Relevant Wikipedia article: http://en.wikipedia.org/wiki/Microsoft_Windows_SDK +# +# Variables: +# WINDOWSSDK_FOUND - if any version of the windows or platform SDK was found that is usable with the current version of visual studio +# WINDOWSSDK_LATEST_DIR +# WINDOWSSDK_LATEST_NAME +# WINDOWSSDK_FOUND_PREFERENCE - if we found an entry indicating a "preferred" SDK listed for this visual studio version +# WINDOWSSDK_PREFERRED_DIR +# WINDOWSSDK_PREFERRED_NAME +# +# WINDOWSSDK_DIRS - contains no duplicates, ordered most recent first. +# WINDOWSSDK_PREFERRED_FIRST_DIRS - contains no duplicates, ordered with preferred first, followed by the rest in descending recency +# +# Functions: +# windowssdk_name_lookup( ) - Find the name corresponding with the SDK directory you pass in, or +# NOTFOUND if not recognized. Your directory must be one of WINDOWSSDK_DIRS for this to work. +# +# get_windowssdk_from_component( ) - Given a library or include dir, +# find the Windows SDK root dir corresponding to it, or NOTFOUND if unrecognized. +# +# get_windowssdk_library_dirs( ) - Find the architecture-appropriate +# library directories corresponding to the SDK directory you pass in (or NOTFOUND if none) +# +# get_windowssdk_include_dirs( ) - Find the +# include directories corresponding to the SDK directory you pass in (or NOTFOUND if none) +# +# Requires these CMake modules: +# FindPackageHandleStandardArgs (known included with CMake >=2.6.2) +# +# Original Author: +# 2012 Ryan Pavlik +# http://academic.cleardefinition.com +# Iowa State University HCI Graduate Program/VRAC +# +# Copyright Iowa State University 2012. +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +set(_preferred_sdk_dirs) +set(_win_sdk_dirs) +set(_win_sdk_versanddirs) +if(MSVC_VERSION GREATER 1310) # Newer than VS .NET/VS Toolkit 2003 + + # Environment variable for SDK dir + if(EXISTS "$ENV{WindowsSDKDir}" AND (NOT "$ENV{WindowsSDKDir}" STREQUAL "")) + message(STATUS "Got $ENV{WindowsSDKDir} - Windows/Platform SDK directories: ${_win_sdk_dirs}") + list(APPEND _preferred_sdk_dirs "$ENV{WindowsSDKDir}") + endif() + + if(MSVC_VERSION LESS 1600) + # Per-user current Windows SDK for VS2005/2008 + get_filename_component(_sdkdir + "[HKEY_CURRENT_USER\\Software\\Microsoft\\Microsoft SDKs\\Windows;CurrentInstallFolder]" + ABSOLUTE) + if(EXISTS "${_sdkdir}") + list(APPEND _preferred_sdk_dirs "${_sdkdir}") + endif() + + # System-wide current Windows SDK for VS2005/2008 + get_filename_component(_sdkdir + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows;CurrentInstallFolder]" + ABSOLUTE) + if(EXISTS "${_sdkdir}") + list(APPEND _preferred_sdk_dirs "${_sdkdir}") + endif() + endif() + + if(MSVC_VERSION LESS 1700) + # VC 10 and older has broad target support + set(_winsdk_vistaonly) + else() + # VC 11 by default targets Vista and later only, so we can add a few more SDKs that (might?) only work on vista+ + if("${CMAKE_VS_PLATFORM_TOOLSET}" MATCHES "_xp") + # This is the XP-compatible v110 toolset + elseif("${CMAKE_VS_PLATFORM_TOOLSET}" STREQUAL "v100") + # This is the VS2010 toolset + else() + if(NOT WINDOWSSDK_FOUND AND NOT WindowsSDK_FIND_QUIETLY) + message(STATUS "FindWindowsSDK: Detected Visual Studio 2012 or newer, not using the _xp toolset variant: including SDK versions that drop XP support in search!") + endif() + # These versions have no XP (and possibly Vista pre-SP1) support + set(_winsdk_vistaonly) + if(NOT MSVC_VERSION LESS 1800) + list(APPEND _winsdk_vistaonly + # Windows Software Development Kit (SDK) for Windows 8.1 + # http://msdn.microsoft.com/en-gb/windows/desktop/bg162891 + v8.1) + endif() + list(APPEND _winsdk_vistaonly + # Included in Visual Studio 2012 + v8.0A + + # Microsoft Windows SDK for Windows 8 and .NET Framework 4.5 + # This is the first version to also include the DirectX SDK + # http://msdn.microsoft.com/en-US/windows/desktop/hh852363.aspx + v8.0 + + # Microsoft Windows SDK for Windows 7 and .NET Framework 4 + # http://www.microsoft.com/downloads/en/details.aspx?FamilyID=6b6c21d2-2006-4afa-9702-529fa782d63b + v7.1 + ) + endif() + endif() + foreach(_winsdkver + ${_winsdk_vistaonly} + + # Included in Visual Studio 2013 + # Includes the v120_xp toolset + v8.1A + + # Included with VS 2012 Update 1 or later + # Introduces v110_xp toolset + v7.1A + + # Included with VS 2010 + v7.0A + + # Windows SDK for Windows 7 and .NET Framework 3.5 SP1 + # Works with VC9 + #http://www.microsoft.com/en-us/download/details.aspx?id=18950 + v7.0 + + # Two versions call themselves "v6.1": + # Older: + # Windows Vista Update & .NET 3.0 SDK + # http://www.microsoft.com/en-us/download/details.aspx?id=14477 + + # Newer: + # Windows Server 2008 & .NET 3.5 SDK + # may have broken VS9SP1? they recommend v7.0 instead, or a KB... + # http://www.microsoft.com/en-us/download/details.aspx?id=24826 + v6.1 + + # Included in VS 2008 + v6.0A + + # Microsoft Windows Software Development Kit for Windows Vista and .NET Framework 3.0 Runtime Components + # http://blogs.msdn.com/b/stanley/archive/2006/11/08/microsoft-windows-software-development-kit-for-windows-vista-and-net-framework-3-0-runtime-components.aspx + v6.0) + + get_filename_component(_sdkdir + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\${_winsdkver};InstallationFolder]" + ABSOLUTE) + if(EXISTS "${_sdkdir}") + list(APPEND _win_sdk_dirs "${_sdkdir}") + list(APPEND + _win_sdk_versanddirs + "Windows SDK ${_winsdkver}" + "${_sdkdir}") + endif() + endforeach() +endif() +if(MSVC_VERSION GREATER 1200) + foreach(_platformsdkinfo + "D2FF9F89-8AA2-4373-8A31-C838BF4DBBE1_Microsoft Platform SDK for Windows Server 2003 R2" + "8F9E5EF3-A9A5-491B-A889-C58EFFECE8B3_Microsoft Platform SDK for Windows Server 2003 SP1") + string(SUBSTRING "${_platformsdkinfo}" 0 36 _platformsdkguid) + string(SUBSTRING "${_platformsdkinfo}" 37 -1 _platformsdkname) + foreach(HIVE HKEY_LOCAL_MACHINE HKEY_CURRENT_USER) + get_filename_component(_sdkdir + "[${HIVE}\\SOFTWARE\\Microsoft\\MicrosoftSDK\\InstalledSDKs\\${_platformsdkguid};Install Dir]" + ABSOLUTE) + if(EXISTS "${_sdkdir}") + list(APPEND _win_sdk_dirs "${_sdkdir}") + list(APPEND _win_sdk_versanddirs "${_platformsdkname}" "${_sdkdir}") + endif() + endforeach() + endforeach() +endif() + +set(_win_sdk_versanddirs + "${_win_sdk_versanddirs}" + CACHE + INTERNAL + "mapping between windows sdk version locations and names" + FORCE) + +function(windowssdk_name_lookup _dir _outvar) + list(FIND _win_sdk_versanddirs "${_dir}" _diridx) + math(EXPR _nameidx "${_diridx} - 1") + if(${_nameidx} GREATER -1) + list(GET _win_sdk_versanddirs ${_nameidx} _sdkname) + else() + set(_sdkname "NOTFOUND") + endif() + set(${_outvar} "${_sdkname}" PARENT_SCOPE) +endfunction() + +if(_win_sdk_dirs) + # Remove duplicates + list(REMOVE_DUPLICATES _win_sdk_dirs) + list(GET _win_sdk_dirs 0 WINDOWSSDK_LATEST_DIR) + windowssdk_name_lookup("${WINDOWSSDK_LATEST_DIR}" + WINDOWSSDK_LATEST_NAME) + set(WINDOWSSDK_DIRS ${_win_sdk_dirs}) +endif() +if(_preferred_sdk_dirs) + list(GET _preferred_sdk_dirs 0 WINDOWSSDK_PREFERRED_DIR) + windowssdk_name_lookup("${WINDOWSSDK_LATEST_DIR}" + WINDOWSSDK_PREFERRED_NAME) + set(WINDOWSSDK_PREFERRED_FIRST_DIRS + ${_preferred_sdk_dirs} + ${_win_sdk_dirs}) + list(REMOVE_DUPLICATES WINDOWSSDK_PREFERRED_FIRST_DIRS) + set(WINDOWSSDK_FOUND_PREFERENCE ON) + + # In case a preferred dir was found that isn't found otherwise + #set(WINDOWSSDK_DIRS ${WINDOWSSDK_DIRS} ${WINDOWSSDK_PREFERRED_FIRST_DIRS}) + #list(REMOVE_DUPLICATES WINDOWSSDK_DIRS) +else() + set(WINDOWSSDK_PREFERRED_DIR "${WINDOWSSDK_LATEST_DIR}") + set(WINDOWSSDK_PREFERRED_NAME "${WINDOWSSDK_LATEST_NAME}") + set(WINDOWSSDK_PREFERRED_FIRST_DIRS ${WINDOWSSDK_DIRS}) + set(WINDOWSSDK_FOUND_PREFERENCE OFF) +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(WindowsSDK + "No compatible version of the Windows SDK or Platform SDK found." + WINDOWSSDK_DIRS) + +if(WINDOWSSDK_FOUND) + if(NOT _winsdk_remembered_dirs STREQUAL WINDOWSSDK_DIRS) + set(_winsdk_remembered_dirs + "${WINDOWSSDK_DIRS}" + CACHE + INTERNAL + "" + FORCE) + if(NOT WindowsSDK_FIND_QUIETLY) + foreach(_sdkdir ${WINDOWSSDK_DIRS}) + windowssdk_name_lookup("${_sdkdir}" _sdkname) + message(STATUS " - Found ${_sdkname} at ${_sdkdir}") + endforeach() + endif() + endif() + + # Internal: Architecture-appropriate library directory names. + if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "ARM") + set(_winsdk_archbare /arm) # what the architecture used to be called in oldest SDKs + set(_winsdk_arch arm) # what the architecture used to be called + set(_winsdk_arch8 arm) # what the WDK for Win8+ calls this architecture + else() + if(CMAKE_SIZEOF_VOID_P MATCHES "8") + set(_winsdk_archbare /x64) # what the architecture used to be called in oldest SDKs + set(_winsdk_arch amd64) # what the architecture used to be called + set(_winsdk_arch8 x64) # what the WDK for Win8+ calls this architecture + else() + set(_winsdk_archbare ) # what the architecture used to be called in oldest SDKs + set(_winsdk_arch i386) # what the architecture used to be called + set(_winsdk_arch8 x86) # what the WDK for Win8+ calls this architecture + endif() + endif() + + function(get_windowssdk_from_component _component _var) + get_filename_component(_component "${_component}" ABSOLUTE) + file(TO_CMAKE_PATH "${_component}" _component) + foreach(_sdkdir ${WINDOWSSDK_DIRS}) + get_filename_component(_sdkdir "${_sdkdir}" ABSOLUTE) + string(LENGTH "${_sdkdir}" _sdklen) + file(RELATIVE_PATH _rel "${_sdkdir}" "${_component}") + # If we don't have any "parent directory" items... + if(NOT "${_rel}" MATCHES "[.][.]") + set(${_var} "${_sdkdir}" PARENT_SCOPE) + return() + endif() + endforeach() + # Fail. + set(${_var} "NOTFOUND" PARENT_SCOPE) + endfunction() + function(get_windowssdk_library_dirs _winsdk_dir _var) + set(_result) + foreach(_suffix + "lib${_winsdk_archbare}" # SDKs like 7.1A + "lib/w2k/${_winsdk_arch}" # Win2k min requirement + "lib/wxp/${_winsdk_arch}" # WinXP min requirement + "lib/wnet/${_winsdk_arch}" # Win Server 2003 min requirement + "lib/wlh/${_winsdk_arch}" # Win Vista ("Long Horn") min requirement + "lib/wlh/um/${_winsdk_arch8}" # Win Vista ("Long Horn") min requirement + "lib/win7/${_winsdk_arch}" # Win 7 min requirement + "lib/win7/um/${_winsdk_arch8}" # Win 7 min requirement + "lib/win8/um/${_winsdk_arch8}" # Win 8 min requirement + "lib/win8/km/${_winsdk_arch8}" # Win 8 min requirement + "lib/winv6.3/km/${_winsdk_arch8}" # Win 8.1 min requirement + "lib/winv6.3/um/${_winsdk_arch8}" # Win 8.1 min requirement + ) + # Check to see if a library actually exists here. + file(GLOB _libs "${_winsdk_dir}/${_suffix}/*.lib") + if(_libs) + list(APPEND _result "${_winsdk_dir}/${_suffix}") + endif() + endforeach() + if(NOT _result) + set(_result NOTFOUND) + endif() + set(${_var} ${_result} PARENT_SCOPE) + endfunction() + function(get_windowssdk_include_dirs _winsdk_dir _var) + set(_result) + foreach(_suffix + "Include" + "Include/shared" + "Include/um" + "Include/winrt" + "Include/km" + "Include/wdf" + ) + # Check to see if a header file actually exists here. + file(GLOB _headers "${_winsdk_dir}/${_suffix}/*.h") + if(_headers) + list(APPEND _result "${_winsdk_dir}/${_suffix}") + endif() + endforeach() + if(NOT _result) + set(_result NOTFOUND) + endif() + set(${_var} ${_result} PARENT_SCOPE) + endfunction() +endif() diff --git a/cmake/Findjson_rpc_cpp.cmake b/cmake/Findjson_rpc_cpp.cmake new file mode 100644 index 0000000000..3ff1487c5b --- /dev/null +++ b/cmake/Findjson_rpc_cpp.cmake @@ -0,0 +1,123 @@ +# Find json-rcp-cpp +# +# Find the json-rpc-cpp includes and library +# +# if you nee to add a custom library search path, do it via via CMAKE_PREFIX_PATH +# +# This module defines +# JSON_RCP_CPP_INCLUDE_DIRS, where to find header, etc. +# JSON_RCP_CPP_LIBRARIES, the libraries needed to use json-rpc-cpp. +# JSON_RPC_CPP_SERVER_LIBRARIES, the libraries needed to use json-rpc-cpp-server +# JSON_RPC_CPP_CLIENT_LIBRARIES, the libraries needed to use json-rpc-cpp-client +# JSON_RCP_CPP_FOUND, If false, do not try to use json-rpc-cpp. +# JSON_RPC_CPP_VERSION, version of library +# JSON_RPC_CPP_VERSION_MAJOR +# JSON_RPC_CPP_VERSION_MINOR +# JSON_RPC_CPP_VERSION_PATCH + + +# only look in default directories +find_path( + JSON_RPC_CPP_INCLUDE_DIR + NAMES jsonrpccpp/server.h jsonrpc/server.h + PATH_SUFFIXES jsonrpc + DOC "json-rpc-cpp include dir" +) + +find_library( + JSON_RPC_CPP_COMMON_LIBRARY + NAMES jsonrpccpp-common + DOC "json-rpc-cpp common library" +) + +find_library( + JSON_RPC_CPP_SERVER_LIBRARY + NAMES jsonrpccpp-server + DOC "json-rpc-cpp server library" +) + +find_library( + JSON_RPC_CPP_CLIENT_LIBRARY + NAMES jsonrpccpp-client + DOC "json-rpc-cpp client library" +) + +# these are the variables to be uses by the calling script +set (JSON_RPC_CPP_INCLUDE_DIRS ${JSON_RPC_CPP_INCLUDE_DIR}) +set (JSON_RPC_CPP_LIBRARIES ${JSON_RPC_CPP_COMMON_LIBRARY} ${JSON_RPC_CPP_SERVER_LIBRARY} ${JSON_RPC_CPP_CLIENT_LIBRARY}) +set (JSON_RPC_CPP_SERVER_LIBRARIES ${JSON_RPC_CPP_COMMON_LIBRARY} ${JSON_RPC_CPP_SERVER_LIBRARY}) +set (JSON_RPC_CPP_CLIENT_LIBRARIES ${JSON_RPC_CPP_COMMON_LIBRARY} ${JSON_RPC_CPP_CLIENT_LIBRARY}) + +# debug library on windows +# same naming convention as in qt (appending debug library with d) +# boost is using the same "hack" as us with "optimized" and "debug" +if (MSVC) + + find_library( + JSON_RPC_CPP_COMMON_LIBRARY_DEBUG + NAMES jsonrpccpp-commond + DOC "json-rpc-cpp common debug library" + ) + + find_library( + JSON_RPC_CPP_SERVER_LIBRARY_DEBUG + NAMES jsonrpccpp-serverd + DOC "json-rpc-cpp server debug library" + ) + + find_library( + JSON_RPC_CPP_CLIENT_LIBRARY_DEBUG + NAMES jsonrpccpp-clientd + DOC "json-rpc-cpp client debug library" + ) + + set (JSON_RPC_CPP_LIBRARIES + optimized ${JSON_RPC_CPP_COMMON_LIBRARY} + optimized ${JSON_RPC_CPP_SERVER_LIBRARY} + optimized ${JSON_RPC_CPP_CLIENT_LIBRARY} + debug ${JSON_RPC_CPP_COMMON_LIBRARY_DEBUG} + debug ${JSON_RPC_CPP_SERVER_LIBRARY_DEBUG} + debug ${JSON_RPC_CPP_CLIENT_LIBRARY_DEBUG} + ) + + set (JSON_RPC_CPP_SERVER_LIBRARIES + optimized ${JSON_RPC_CPP_COMMON_LIBRARY} + optimized ${JSON_RPC_CPP_SERVER_LIBRARY} + debug ${JSON_RPC_CPP_COMMON_LIBRARY_DEBUG} + debug ${JSON_RPC_CPP_SERVER_LIBRARY_DEBUG} + ) + + set (JSON_RPC_CPP_CLIENT_LIBRARIES + optimized ${JSON_RPC_CPP_COMMON_LIBRARY} + optimized ${JSON_RPC_CPP_CLIENT_LIBRARY} + debug ${JSON_RPC_CPP_COMMON_LIBRARY_DEBUG} + debug ${JSON_RPC_CPP_CLIENT_LIBRARY_DEBUG} + ) + +endif() + +if (JSON_RPC_CPP_INCLUDE_DIR) + set (JSON_RPC_CPP_VERSION_HEADER "${JSON_RPC_CPP_INCLUDE_DIR}/jsonrpccpp/version.h") + if (EXISTS ${JSON_RPC_CPP_VERSION_HEADER}) + file (STRINGS ${JSON_RPC_CPP_VERSION_HEADER} JSON_RPC_CPP_VERSION_MAJOR REGEX "^#define JSONRPC_CPP_MAJOR_VERSION[ \t]+[0-9]+$") + file (STRINGS ${JSON_RPC_CPP_VERSION_HEADER} JSON_RPC_CPP_VERSION_MINOR REGEX "^#define JSONRPC_CPP_MINOR_VERSION[ \t]+[0-9]+$") + file (STRINGS ${JSON_RPC_CPP_VERSION_HEADER} JSON_RPC_CPP_VERSION_PATCH REGEX "^#define JSONRPC_CPP_PATCH_VERSION[ \t]+[0-9]+$") + string (REGEX REPLACE "^#define JSONRPC_CPP_MAJOR_VERSION[ \t]+([0-9]+)" "\\1" JSON_RPC_CPP_VERSION_MAJOR ${JSON_RPC_CPP_VERSION_MAJOR}) + string (REGEX REPLACE "^#define JSONRPC_CPP_MINOR_VERSION[ \t]+([0-9]+)" "\\1" JSON_RPC_CPP_VERSION_MINOR ${JSON_RPC_CPP_VERSION_MINOR}) + string (REGEX REPLACE "^#define JSONRPC_CPP_PATCH_VERSION[ \t]+([0-9]+)" "\\1" JSON_RPC_CPP_VERSION_PATCH ${JSON_RPC_CPP_VERSION_PATCH}) + set (JSON_RPC_CPP_VERSION ${JSON_RPC_CPP_VERSION_MAJOR}.${JSON_RPC_CPP_VERSION_MINOR}.${JSON_RPC_CPP_VERSION_PATCH}) + endif() +endif() + +# handle the QUIETLY and REQUIRED arguments and set JSON_RPC_CPP_FOUND to TRUE +# if all listed variables are TRUE, hide their existence from configuration view +include(FindPackageHandleStandardArgs) + +find_package_handle_standard_args( + json_rpc_cpp + REQUIRED_VARS JSON_RPC_CPP_INCLUDE_DIR JSON_RPC_CPP_COMMON_LIBRARY JSON_RPC_CPP_SERVER_LIBRARY JSON_RPC_CPP_CLIENT_LIBRARY + VERSION_VAR JSON_RPC_CPP_VERSION +) + +mark_as_advanced (JSON_RPC_CPP_INCLUDE_DIR JSON_RPC_CPP_COMMON_LIBRARY JSON_RPC_CPP_SERVER_LIBRARY JSON_RPC_CPP_CLIENT_LIBRARY) + diff --git a/cmake/ProjectBoost.cmake b/cmake/ProjectBoost.cmake new file mode 100644 index 0000000000..484a29160c --- /dev/null +++ b/cmake/ProjectBoost.cmake @@ -0,0 +1,80 @@ +include(ExternalProject) +include(GNUInstallDirs) + +set(BOOST_CXXFLAGS "") +if (WIN32) + set(BOOST_BOOTSTRAP_COMMAND bootstrap.bat) + set(BOOST_BUILD_TOOL b2.exe) + set(BOOST_LIBRARY_SUFFIX -vc140-mt-1_63.lib) +else() + set(BOOST_BOOTSTRAP_COMMAND ./bootstrap.sh) + set(BOOST_BUILD_TOOL ./b2) + set(BOOST_LIBRARY_SUFFIX .a) + if (${BUILD_SHARED_LIBS}) + set(BOOST_CXXFLAGS "cxxflags=-fPIC") + endif() +endif() + +ExternalProject_Add(boost + PREFIX ${CMAKE_SOURCE_DIR}/deps + DOWNLOAD_NO_PROGRESS 1 + URL https://github.com/ethereum/cpp-dependencies/releases/download/cache/boost_1_63_0.tar.gz + URL_HASH SHA256=fe34a4e119798e10b8cc9e565b3b0284e9fd3977ec8a1b19586ad1dec397088b + BUILD_IN_SOURCE 1 + CONFIGURE_COMMAND ${BOOST_BOOTSTRAP_COMMAND} + LOG_CONFIGURE 1 + BUILD_COMMAND ${BOOST_BUILD_TOOL} stage + ${BOOST_CXXFLAGS} + threading=multi + link=static + variant=release + address-model=64 + --with-chrono + --with-date_time + --with-filesystem + --with-random + --with-regex + --with-test + --with-thread + LOG_BUILD 1 + INSTALL_COMMAND "" +) + +ExternalProject_Get_Property(boost SOURCE_DIR) +set(BOOST_INCLUDE_DIR ${SOURCE_DIR}) +set(BOOST_LIB_DIR ${SOURCE_DIR}/stage/lib) +unset(BUILD_DIR) + +add_library(Boost::Chrono STATIC IMPORTED) +set_property(TARGET Boost::Chrono PROPERTY IMPORTED_LOCATION ${BOOST_LIB_DIR}/libboost_chrono${BOOST_LIBRARY_SUFFIX}) +add_dependencies(Boost::Chrono boost) + +add_library(Boost::DataTime STATIC IMPORTED) +set_property(TARGET Boost::DataTime PROPERTY IMPORTED_LOCATION ${BOOST_LIB_DIR}/libboost_date_time${BOOST_LIBRARY_SUFFIX}) +add_dependencies(Boost::DataTime boost) + +add_library(Boost::Regex STATIC IMPORTED) +set_property(TARGET Boost::Regex PROPERTY IMPORTED_LOCATION ${BOOST_LIB_DIR}/libboost_regex${BOOST_LIBRARY_SUFFIX}) +add_dependencies(Boost::Regex boost) + +add_library(Boost::System STATIC IMPORTED) +set_property(TARGET Boost::System PROPERTY IMPORTED_LOCATION ${BOOST_LIB_DIR}/libboost_system${BOOST_LIBRARY_SUFFIX}) +add_dependencies(Boost::System boost) + +add_library(Boost::Filesystem STATIC IMPORTED) +set_property(TARGET Boost::Filesystem PROPERTY IMPORTED_LOCATION ${BOOST_LIB_DIR}/libboost_filesystem${BOOST_LIBRARY_SUFFIX}) +set_property(TARGET Boost::Filesystem PROPERTY INTERFACE_LINK_LIBRARIES Boost::System) +add_dependencies(Boost::Filesystem boost) + +add_library(Boost::Random STATIC IMPORTED) +set_property(TARGET Boost::Random PROPERTY IMPORTED_LOCATION ${BOOST_LIB_DIR}/libboost_random${BOOST_LIBRARY_SUFFIX}) +add_dependencies(Boost::Random boost) + +add_library(Boost::UnitTestFramework STATIC IMPORTED) +set_property(TARGET Boost::UnitTestFramework PROPERTY IMPORTED_LOCATION ${BOOST_LIB_DIR}/libboost_unit_test_framework${BOOST_LIBRARY_SUFFIX}) +add_dependencies(Boost::UnitTestFramework boost) + +add_library(Boost::Thread STATIC IMPORTED) +set_property(TARGET Boost::Thread PROPERTY IMPORTED_LOCATION ${BOOST_LIB_DIR}/libboost_thread${BOOST_LIBRARY_SUFFIX}) +set_property(TARGET Boost::Thread PROPERTY INTERFACE_LINK_LIBRARIES Boost::Chrono Boost::DataTime Boost::Regex) +add_dependencies(Boost::Thread boost) diff --git a/cmake/ProjectCryptopp.cmake b/cmake/ProjectCryptopp.cmake new file mode 100644 index 0000000000..01bcdbfde6 --- /dev/null +++ b/cmake/ProjectCryptopp.cmake @@ -0,0 +1,182 @@ +include(ExternalProject) +include(GNUInstallDirs) + +ExternalProject_Add(cryptopp + PREFIX ${CMAKE_SOURCE_DIR}/deps + # This points to unreleased version 5.6.5+ but contains very small + # warning fix: + # https://github.com/weidai11/cryptopp/commit/903b8feaa70199eb39a313b32a71268745ddb600 + DOWNLOAD_NAME cryptopp_bccc6443.tar.gz + DOWNLOAD_NO_PROGRESS 1 + URL https://github.com/weidai11/cryptopp/archive/bccc6443c4d4d611066c2de4c17109380cf97704.tar.gz + URL_HASH SHA256=f1fddacadd2a0873f795d5614a85fecd5b6ff1d1c6e21dedc251703c54ce63aa + PATCH_COMMAND ${CMAKE_COMMAND} -E remove + 3way.cpp + adler32.cpp + # algebra.cpp + # algparam.cpp + arc4.cpp + # asn.cpp + authenc.cpp + base32.cpp + base64.cpp + # basecode.cpp + bench1.cpp + bench2.cpp + bfinit.cpp + blake2.cpp + blowfish.cpp + blumshub.cpp + camellia.cpp + cast.cpp + casts.cpp + cbcmac.cpp + ccm.cpp + chacha.cpp + channels.cpp + cmac.cpp + # cpu.cpp + crc.cpp + # cryptlib.cpp + datatest.cpp + default.cpp + des.cpp + dessp.cpp + dh2.cpp + dh.cpp + # dll.cpp + dlltest.cpp + # dsa.cpp + eax.cpp + # ec2n.cpp + # eccrypto.cpp + # ecp.cpp + elgamal.cpp + emsa2.cpp + # eprecomp.cpp + esign.cpp + files.cpp + # filters.cpp + # fips140.cpp + fipsalgt.cpp + fipstest.cpp + gcm.cpp + gf2_32.cpp + gf256.cpp + # gf2n.cpp + # gfpcrypt.cpp + gost.cpp + gzip.cpp + # hex.cpp + # hmac.cpp + # hrtimer.cpp + ida.cpp + idea.cpp + # integer.cpp + # iterhash.cpp + # keccak.cpp + luc.cpp + mars.cpp + marss.cpp + md2.cpp + md4.cpp + md5.cpp + # misc.cpp + # modes.cpp + # mqueue.cpp + mqv.cpp + # nbtheory.cpp + network.cpp + # oaep.cpp + # osrng.cpp + panama.cpp + pch.cpp + pkcspad.cpp + poly1305.cpp + # polynomi.cpp + pssr.cpp + # pubkey.cpp + # queue.cpp + rabin.cpp + # randpool.cpp + rc2.cpp + rc5.cpp + rc6.cpp + rdrand.cpp + # rdtables.cpp + regtest.cpp + # rijndael.cpp + ripemd.cpp + # rng.cpp + rsa.cpp + rw.cpp + safer.cpp + salsa.cpp + seal.cpp + seed.cpp + serpent.cpp + sha3.cpp + shacal2.cpp + # sha.cpp + sharkbox.cpp + shark.cpp + simple.cpp + skipjack.cpp + socketft.cpp + sosemanuk.cpp + square.cpp + squaretb.cpp + # strciphr.cpp + tea.cpp + test.cpp + tftables.cpp + tiger.cpp + tigertab.cpp + trdlocal.cpp + ttmac.cpp + twofish.cpp + validat0.cpp + validat1.cpp + validat2.cpp + validat3.cpp + vmac.cpp + wait.cpp + wake.cpp + whrlpool.cpp + # winpipes.cpp + xtr.cpp + xtrcrypt.cpp + zdeflate.cpp + zinflate.cpp + zlib.cpp + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX= + -DCMAKE_BUILD_TYPE=Release + # Build static lib but suitable to be included in a shared lib. + -DCMAKE_POSITION_INDEPENDENT_CODE=${BUILD_SHARED_LIBS} + -DBUILD_SHARED=Off + -DBUILD_TESTING=Off + LOG_CONFIGURE 1 + # Overwrite build and install commands to force Release build on MSVC. + BUILD_COMMAND ${CMAKE_COMMAND} --build --config Release + INSTALL_COMMAND ${CMAKE_COMMAND} --build --config Release --target install + LOG_INSTALL 1 +) + +# Create cryptopp imported library +#ExternalProject_Get_Property(cryptopp INSTALL_DIR) + +set(INSTALL_DIR "${CMAKE_SOURCE_DIR}/deps") +#message("INSTALL_DIR = ${INSTALL_DIR}") + +add_library(Cryptopp STATIC IMPORTED) +if (MSVC) + set(CRYPTOPP_LIBRARY ${INSTALL_DIR}/${CMAKE_INSTALL_LIBDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}cryptopp-static${CMAKE_STATIC_LIBRARY_SUFFIX}) +else() + set(CRYPTOPP_LIBRARY ${INSTALL_DIR}/${CMAKE_INSTALL_LIBDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}cryptopp${CMAKE_STATIC_LIBRARY_SUFFIX}) +endif() +set(CRYPTOPP_INCLUDE_DIR ${INSTALL_DIR}/include) +file(MAKE_DIRECTORY ${CRYPTOPP_INCLUDE_DIR}) # Must exist. +set_property(TARGET Cryptopp PROPERTY IMPORTED_LOCATION ${CRYPTOPP_LIBRARY}) +set_property(TARGET Cryptopp PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${CRYPTOPP_INCLUDE_DIR}) +add_dependencies(Cryptopp cryptopp) +unset(INSTALL_DIR) diff --git a/cmake/ProjectJsonCpp.cmake b/cmake/ProjectJsonCpp.cmake new file mode 100644 index 0000000000..0c49d9836e --- /dev/null +++ b/cmake/ProjectJsonCpp.cmake @@ -0,0 +1,42 @@ +include(ExternalProject) + +if (${CMAKE_SYSTEM_NAME} STREQUAL "Emscripten") + set(JSONCPP_CMAKE_COMMAND emcmake cmake) +else() + set(JSONCPP_CMAKE_COMMAND ${CMAKE_COMMAND}) +endif() + +if (MSVC) + set(_only_release_configuration -DCMAKE_CONFIGURATION_TYPES=Release) + set(_overwrite_install_command INSTALL_COMMAND cmake --build --config Release --target install) +endif() + +ExternalProject_Add(jsoncpp + PREFIX ${CMAKE_SOURCE_DIR}/deps + DOWNLOAD_NAME jsoncpp-1.7.7.tar.gz + DOWNLOAD_NO_PROGRESS 1 + URL https://github.com/open-source-parsers/jsoncpp/archive/1.7.7.tar.gz + URL_HASH SHA256=087640ebcf7fbcfe8e2717a0b9528fff89c52fcf69fa2a18cc2b538008098f97 + CMAKE_COMMAND ${JSONCPP_CMAKE_COMMAND} + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX= + # Build static lib but suitable to be included in a shared lib. + -DCMAKE_POSITION_INDEPENDENT_CODE=${BUILD_SHARED_LIBS} + ${_only_release_configuration} + -DJSONCPP_WITH_TESTS=Off + -DJSONCPP_WITH_PKGCONFIG_SUPPORT=Off + LOG_CONFIGURE 1 + BUILD_COMMAND "" + ${_overwrite_install_command} + LOG_INSTALL 1 +) + +# Create jsoncpp imported library +ExternalProject_Get_Property(jsoncpp INSTALL_DIR) +add_library(JsonCpp STATIC IMPORTED) +set(JSONCPP_LIBRARY ${INSTALL_DIR}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}jsoncpp${CMAKE_STATIC_LIBRARY_SUFFIX}) +set(JSONCPP_INCLUDE_DIR ${INSTALL_DIR}/include) +file(MAKE_DIRECTORY ${JSONCPP_INCLUDE_DIR}) # Must exist. +set_property(TARGET JsonCpp PROPERTY IMPORTED_LOCATION ${JSONCPP_LIBRARY}) +set_property(TARGET JsonCpp PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${JSONCPP_INCLUDE_DIR}) +add_dependencies(JsonCpp jsoncpp) +unset(INSTALL_DIR) diff --git a/cmake/ProjectJsonRpcCpp.cmake b/cmake/ProjectJsonRpcCpp.cmake new file mode 100644 index 0000000000..083ea0d4a1 --- /dev/null +++ b/cmake/ProjectJsonRpcCpp.cmake @@ -0,0 +1,89 @@ +# HTTP client from JSON RPC CPP requires curl library. It can find it itself, +# but we need to know the libcurl location for static linking. +find_package(CURL REQUIRED) + +# HTTP server from JSON RPC CPP requires microhttpd library. It can find it itself, +# but we need to know the MHD location for static linking. +find_package(MHD REQUIRED) + +set(CMAKE_ARGS -DCMAKE_INSTALL_PREFIX= + -DCMAKE_BUILD_TYPE=Release + # Build static lib but suitable to be included in a shared lib. + -DCMAKE_POSITION_INDEPENDENT_CODE=${BUILD_SHARED_LIBS} + -DBUILD_STATIC_LIBS=On + -DBUILD_SHARED_LIBS=Off + -DUNIX_DOMAIN_SOCKET_SERVER=Off + -DUNIX_DOMAIN_SOCKET_CLIENT=Off + -DHTTP_SERVER=On + -DHTTP_CLIENT=On + -DCOMPILE_TESTS=Off + -DCOMPILE_STUBGEN=Off + -DCOMPILE_EXAMPLES=Off + # Point to jsoncpp library. + -DJSONCPP_INCLUDE_DIR=${JSONCPP_INCLUDE_DIR} + # Select jsoncpp include prefix: or + -DJSONCPP_INCLUDE_PREFIX=json + -DJSONCPP_LIBRARY=${JSONCPP_LIBRARY} + -DCURL_INCLUDE_DIR=${CURL_INCLUDE_DIR} + -DCURL_LIBRARY=${CURL_LIBRARY} + -DMHD_INCLUDE_DIR=${MHD_INCLUDE_DIR} + -DMHD_LIBRARY=${MHD_LIBRARY}) + +if (WIN32) + # For Windows we have to provide also locations for debug libraries. + set(CMAKE_ARGS ${CMAKE_ARGS} + -DJSONCPP_LIBRARY_DEBUG=${JSONCPP_LIBRARY} + -DCURL_LIBRARY_DEBUG=${CURL_LIBRARY} + -DMHD_LIBRARY_DEBUG=${MHD_LIBRARY}) +endif() + +ExternalProject_Add(jsonrpccpp + PREFIX ${CMAKE_SOURCE_DIR}/deps + DOWNLOAD_NAME jsonrcpcpp-0.7.0.tar.gz + DOWNLOAD_NO_PROGRESS 1 + URL https://github.com/cinemast/libjson-rpc-cpp/archive/v0.7.0.tar.gz + URL_HASH SHA256=669c2259909f11a8c196923a910f9a16a8225ecc14e6c30e2bcb712bab9097eb + # On Windows it tries to install this dir. Create it to prevent failure. + PATCH_COMMAND ${CMAKE_COMMAND} -E make_directory /win32-deps/include + CMAKE_ARGS ${CMAKE_ARGS} + LOG_CONFIGURE 1 + # Overwrite build and install commands to force Release build on MSVC. + BUILD_COMMAND ${CMAKE_COMMAND} --build --config Release + INSTALL_COMMAND ${CMAKE_COMMAND} --build --config Release --target install + LOG_INSTALL 1 +) + +add_dependencies(jsonrpccpp jsoncpp) + +# Create imported libraries +if (WIN32) + # On Windows CMAKE_INSTALL_PREFIX is ignored and installs to dist dir. + ExternalProject_Get_Property(jsonrpccpp BINARY_DIR) + set(INSTALL_DIR ${BINARY_DIR}/dist) +else() + ExternalProject_Get_Property(jsonrpccpp INSTALL_DIR) +endif() +set(JSONRPCCPP_INCLUDE_DIR ${INSTALL_DIR}/include) +file(MAKE_DIRECTORY ${JSONRPCCPP_INCLUDE_DIR}) # Must exist. + +add_library(JsonRpcCpp::Common STATIC IMPORTED) +set_property(TARGET JsonRpcCpp::Common PROPERTY IMPORTED_LOCATION ${INSTALL_DIR}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}jsonrpccpp-common${CMAKE_STATIC_LIBRARY_SUFFIX}) +set_property(TARGET JsonRpcCpp::Common PROPERTY INTERFACE_LINK_LIBRARIES JsonCpp) +set_property(TARGET JsonRpcCpp::Common PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${JSONRPCCPP_INCLUDE_DIR} ${JSONCPP_INCLUDE_DIR}) +add_dependencies(JsonRpcCpp::Common jsonrpccpp) + +add_library(JsonRpcCpp::Client STATIC IMPORTED) +set_property(TARGET JsonRpcCpp::Client PROPERTY IMPORTED_LOCATION ${INSTALL_DIR}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}jsonrpccpp-client${CMAKE_STATIC_LIBRARY_SUFFIX}) +set_property(TARGET JsonRpcCpp::Client PROPERTY INTERFACE_LINK_LIBRARIES JsonRpcCpp::Common ${CURL_LIBRARY}) +set_property(TARGET JsonRpcCpp::Client PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${CURL_INCLUDE_DIR}) +add_dependencies(JsonRpcCpp::Client jsonrpccpp) + +add_library(JsonRpcCpp::Server STATIC IMPORTED) +set_property(TARGET JsonRpcCpp::Server PROPERTY IMPORTED_LOCATION ${INSTALL_DIR}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}jsonrpccpp-server${CMAKE_STATIC_LIBRARY_SUFFIX}) +set_property(TARGET JsonRpcCpp::Server PROPERTY INTERFACE_LINK_LIBRARIES JsonRpcCpp::Common ${MHD_LIBRARY}) +set_property(TARGET JsonRpcCpp::Server PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${MHD_INCLUDE_DIR}) +add_dependencies(JsonRpcCpp::Server jsonrpccpp) + +unset(BINARY_DIR) +unset(INSTALL_DIR) +unset(CMAKE_ARGS) diff --git a/cmake/ProjectSecp256k1.cmake b/cmake/ProjectSecp256k1.cmake new file mode 100644 index 0000000000..682c59e594 --- /dev/null +++ b/cmake/ProjectSecp256k1.cmake @@ -0,0 +1,34 @@ +include(ExternalProject) + +if (MSVC) + set(_only_release_configuration -DCMAKE_CONFIGURATION_TYPES=Release) + set(_overwrite_install_command INSTALL_COMMAND cmake --build --config Release --target install) +endif() + +ExternalProject_Add(secp256k1 + PREFIX ${CMAKE_SOURCE_DIR}/deps + DOWNLOAD_NAME secp256k1-9d560f99.tar.gz + DOWNLOAD_NO_PROGRESS 1 + URL https://github.com/bitcoin-core/secp256k1/archive/9d560f992db26612ce2630b194aef5f44d63a530.tar.gz + URL_HASH SHA256=910b2535bdbb5d235e9212c92050e0f9b327e05129b449f8f3d3c6d558121284 + PATCH_COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${CMAKE_CURRENT_LIST_DIR}/secp256k1/CMakeLists.txt + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX= + -DCMAKE_POSITION_INDEPENDENT_CODE=${BUILD_SHARED_LIBS} + ${_only_release_configuration} + LOG_CONFIGURE 1 + BUILD_COMMAND "" + ${_overwrite_install_command} + LOG_INSTALL 1 +) + +# Create imported library +ExternalProject_Get_Property(secp256k1 INSTALL_DIR) +add_library(Secp256k1 STATIC IMPORTED) +set(SECP256K1_LIBRARY ${INSTALL_DIR}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}secp256k1${CMAKE_STATIC_LIBRARY_SUFFIX}) +set(SECP256K1_INCLUDE_DIR ${INSTALL_DIR}/include) +file(MAKE_DIRECTORY ${SECP256K1_INCLUDE_DIR}) # Must exist. +set_property(TARGET Secp256k1 PROPERTY IMPORTED_LOCATION ${SECP256K1_LIBRARY}) +set_property(TARGET Secp256k1 PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${SECP256K1_INCLUDE_DIR}) +add_dependencies(Secp256k1 secp256k1) +unset(INSTALL_DIR) diff --git a/cmake/UseCpuid.cmake b/cmake/UseCpuid.cmake new file mode 100644 index 0000000000..851b3d7030 --- /dev/null +++ b/cmake/UseCpuid.cmake @@ -0,0 +1,11 @@ +function(eth_apply TARGET REQUIRED) + find_package (Cpuid QUIET) + eth_show_dependency(CPUID Cpuid) + if (CPUID_FOUND) + target_include_directories(${TARGET} SYSTEM PUBLIC ${CPUID_INCLUDE_DIRS}) + target_link_libraries(${TARGET} ${CPUID_LIBRARIES}) + target_compile_definitions(${TARGET} PUBLIC ETH_CPUID) + elseif (NOT ${REQUIRED} STREQUAL "OPTIONAL") + message(FATAL_ERROR "CPUID library not found") + endif() +endfunction() diff --git a/cmake/UseDev.cmake b/cmake/UseDev.cmake new file mode 100644 index 0000000000..f9afa6bd1c --- /dev/null +++ b/cmake/UseDev.cmake @@ -0,0 +1,3 @@ +function(eth_apply TARGET REQUIRED SUBMODULE) + +endfunction() diff --git a/cmake/UseEth.cmake b/cmake/UseEth.cmake new file mode 100644 index 0000000000..36e4c8f33e --- /dev/null +++ b/cmake/UseEth.cmake @@ -0,0 +1,5 @@ +function(eth_apply TARGET REQUIRED SUBMODULE) + + find_package(Eth) + +endfunction() diff --git a/cmake/UseGmp.cmake b/cmake/UseGmp.cmake new file mode 100644 index 0000000000..babd44c6ae --- /dev/null +++ b/cmake/UseGmp.cmake @@ -0,0 +1,10 @@ +function(eth_apply TARGET REQUIRED) + find_package (Gmp 6.0.0) + eth_show_dependency(GMP Gmp) + if (GMP_FOUND) + target_include_directories(${TARGET} SYSTEM PUBLIC ${GMP_INCLUDE_DIRS}) + target_link_libraries(${TARGET} ${GMP_LIBRARIES}) + elseif (NOT ${REQUIRED} STREQUAL "OPTIONAL") + message(FATAL_ERROR "Gmp library not found") + endif() +endfunction() diff --git a/cmake/UseMhd.cmake b/cmake/UseMhd.cmake new file mode 100644 index 0000000000..4742815875 --- /dev/null +++ b/cmake/UseMhd.cmake @@ -0,0 +1,11 @@ +function(eth_apply TARGET REQUIRED) + find_package(MHD REQUIRED) + eth_show_dependency(MHD microhttpd) + if (MHD_FOUND) + target_include_directories(${TARGET} SYSTEM PUBLIC ${MHD_INCLUDE_DIRS}) + target_link_libraries(${TARGET} ${MHD_LIBRARIES}) + eth_copy_dlls(${TARGET} MHD_DLLS) + elseif (NOT ${REQUIRED} STREQUAL "OPTIONAL") + message(FATAL_ERROR "Microhttpd library not found") + endif() +endfunction() diff --git a/cmake/UseMiniupnpc.cmake b/cmake/UseMiniupnpc.cmake new file mode 100644 index 0000000000..3da9132144 --- /dev/null +++ b/cmake/UseMiniupnpc.cmake @@ -0,0 +1,11 @@ +function(eth_apply TARGET REQUIRED) + find_package (Miniupnpc 1.8.2013) + eth_show_dependency(MINIUPNPC miniupnpc) + if (MINIUPNPC AND MINIUPNPC_FOUND) + target_include_directories(${TARGET} SYSTEM PRIVATE ${MINIUPNPC_INCLUDE_DIRS}) + target_link_libraries(${TARGET} ${MINIUPNPC_LIBRARIES}) + target_compile_definitions(${TARGET} PUBLIC ETH_MINIUPNPC) + elseif (NOT ${REQUIRED} STREQUAL "OPTIONAL") + message(FATAL_ERROR "Miniupnpc library not found") + endif() +endfunction() diff --git a/cmake/UseOpenSSL.cmake b/cmake/UseOpenSSL.cmake new file mode 100644 index 0000000000..81c6f49689 --- /dev/null +++ b/cmake/UseOpenSSL.cmake @@ -0,0 +1,14 @@ +function(eth_apply TARGET REQUIRED) + find_package (OpenSSL) + + # cmake supplied FindOpenSSL doesn't set all our variables + set(OPENSSL_INCLUDE_DIRS ${OPENSSL_INCLUDE_DIR}) + + eth_show_dependency(OPENSSL OpenSSL) + if (OPENSSL_FOUND) + target_include_directories(${TARGET} SYSTEM PUBLIC ${OPENSSL_INCLUDE_DIRS}) + target_link_libraries(${TARGET} ${OPENSSL_LIBRARIES}) + elseif (NOT ${REQUIRED} STREQUAL "OPTIONAL") + message(FATAL_ERROR "OpenSSL library not found") + endif() +endfunction() diff --git a/cmake/UseSSH2.cmake b/cmake/UseSSH2.cmake new file mode 100644 index 0000000000..2211ae29de --- /dev/null +++ b/cmake/UseSSH2.cmake @@ -0,0 +1,11 @@ +function(eth_apply TARGET REQUIRED) + find_package (SSH2) + eth_show_dependency(SSH2 ssh2) + + if (SSH2_FOUND) + target_include_directories(${TARGET} SYSTEM PUBLIC ${SSH2_INCLUDE_DIRS}) + target_link_libraries(${TARGET} ${SSH2_LIBRARIES}) + elseif (NOT ${REQUIRED} STREQUAL "OPTIONAL") + message(FATAL_ERROR "ssh2 library not found") + endif() +endfunction() diff --git a/cmake/UseUtils.cmake b/cmake/UseUtils.cmake new file mode 100644 index 0000000000..f9afa6bd1c --- /dev/null +++ b/cmake/UseUtils.cmake @@ -0,0 +1,3 @@ +function(eth_apply TARGET REQUIRED SUBMODULE) + +endfunction() diff --git a/cmake/UseWeb3.cmake b/cmake/UseWeb3.cmake new file mode 100644 index 0000000000..f9afa6bd1c --- /dev/null +++ b/cmake/UseWeb3.cmake @@ -0,0 +1,3 @@ +function(eth_apply TARGET REQUIRED SUBMODULE) + +endfunction() diff --git a/cmake/UseZLIB.cmake b/cmake/UseZLIB.cmake new file mode 100644 index 0000000000..6e91e250f9 --- /dev/null +++ b/cmake/UseZLIB.cmake @@ -0,0 +1,11 @@ +function(eth_apply TARGET REQUIRED) + find_package (ZLIB) + eth_show_dependency(ZLIB Zlib) + if (ZLIB_FOUND) + target_include_directories(${TARGET} SYSTEM PUBLIC ${ZLIB_INCLUDE_DIRS}) + # target_link_libraries(${TARGET} ${ZLIB_LIBRARIES}) + target_link_libraries(${TARGET} z) + elseif (NOT ${REQUIRED} STREQUAL "OPTIONAL") + message(FATAL_ERROR "Zlib library not found") + endif() +endfunction() diff --git a/cmake/scripts/buildinfo.cmake b/cmake/scripts/buildinfo.cmake new file mode 100644 index 0000000000..4d6e3235aa --- /dev/null +++ b/cmake/scripts/buildinfo.cmake @@ -0,0 +1,49 @@ +# generates BuildInfo.h +# +# this module expects +# ETH_SOURCE_DIR - main CMAKE_SOURCE_DIR +# ETH_DST_DIR - main CMAKE_BINARY_DIR +# ETH_BUILD_TYPE +# ETH_BUILD_PLATFORM +# ETH_BUILD_NUMBER +# ETH_VERSION_SUFFIX +# +# example usage: +# cmake -DETH_SOURCE_DIR=. -DETH_DST_DIR=build -DETH_BUILD_TYPE=Debug -DETH_BUILD_PLATFORM=mac -DETH_BUILD_NUMBER=45 -DETH_VERSION_SUFFIX="-rc1" -P scripts/buildinfo.cmake + +if (NOT ETH_BUILD_TYPE) + set(ETH_BUILD_TYPE "unknown") +endif() + +if (NOT ETH_BUILD_PLATFORM) + set(ETH_BUILD_PLATFORM "unknown") +endif() + +execute_process( + COMMAND git --git-dir=${ETH_SOURCE_DIR}/.git --work-tree=${ETH_SOURCE_DIR} rev-parse HEAD + OUTPUT_VARIABLE ETH_COMMIT_HASH OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET +) + +if (NOT ETH_COMMIT_HASH) + set(ETH_COMMIT_HASH 0) +endif() + +execute_process( + COMMAND git --git-dir=${ETH_SOURCE_DIR}/.git --work-tree=${ETH_SOURCE_DIR} diff HEAD --shortstat + OUTPUT_VARIABLE ETH_LOCAL_CHANGES OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET +) + +if (ETH_LOCAL_CHANGES) + set(ETH_CLEAN_REPO 0) +else() + set(ETH_CLEAN_REPO 1) +endif() + +set(TMPFILE "${ETH_DST_DIR}/BuildInfo.h.tmp") +set(OUTFILE "${ETH_DST_DIR}/BuildInfo.h") + +configure_file("${ETH_BUILDINFO_IN}" "${TMPFILE}") + +include("${ETH_CMAKE_DIR}/EthUtils.cmake") +replace_if_different("${TMPFILE}" "${OUTFILE}" CREATE) + diff --git a/cmake/scripts/configure.cmake b/cmake/scripts/configure.cmake new file mode 100644 index 0000000000..5c2b443e99 --- /dev/null +++ b/cmake/scripts/configure.cmake @@ -0,0 +1,14 @@ +# adds possibility to run configure_file as buildstep +# reference: +# http://www.cmake.org/pipermail/cmake/2012-May/050227.html +# +# This module expects +# INFILE +# OUTFILE +# other custom vars +# +# example usage: +# cmake -DINFILE=blah.in -DOUTFILE=blah.out -Dvar1=value1 -Dvar2=value2 -P scripts/configure.cmake + +configure_file(${INFILE} ${OUTFILE}) + diff --git a/cmake/scripts/copydlls.cmake b/cmake/scripts/copydlls.cmake new file mode 100644 index 0000000000..7852f5161b --- /dev/null +++ b/cmake/scripts/copydlls.cmake @@ -0,0 +1,24 @@ +# this module expects +# DLLS +# CONF +# DESTINATION + +# example usage: +# cmake -DDLL_DEBUG=xd.dll -DDLL_RELEASE=x.dll -DCONFIGURATION=Release -DDESTINATION=dest -P scripts/copydlls.cmake + +# this script is created cause we do not know configuration in multiconfiguration generators at cmake configure phase ;) + +if ("${CONF}" STREQUAL "Debug") + execute_process(COMMAND ${CMAKE_COMMAND} -E copy "${DLL_DEBUG}" "${DESTINATION}") + + # hack, copy it twice. with and without d.dll suffix + # at first let's get the file name part + get_filename_component(DLL_DEBUG_D_NAME ${DLL_DEBUG} NAME) + string(REPLACE "d.dll" ".dll" DLL_DEBUG_D_NAME "${DLL_DEBUG_D_NAME}") + string(REPLACE "_.dll" ".dll" DLL_DEBUG_D_NAME "${DLL_DEBUG_D_NAME}") + + set(DESTINATION_D "${DESTINATION}/${DLL_DEBUG_D_NAME}") + execute_process(COMMAND ${CMAKE_COMMAND} -E copy "${DLL_DEBUG}" "${DESTINATION_D}") +else () + execute_process(COMMAND ${CMAKE_COMMAND} -E copy "${DLL_RELEASE}" "${DESTINATION}") +endif() diff --git a/cmake/scripts/helpers.cmake b/cmake/scripts/helpers.cmake new file mode 100644 index 0000000000..440d1de8a6 --- /dev/null +++ b/cmake/scripts/helpers.cmake @@ -0,0 +1,90 @@ +get_filename_component(ROOT_DIR "${CMAKE_CURRENT_LIST_DIR}/../.." ABSOLUTE) + +set(CACHE_DIR "${ROOT_DIR}/deps/src") +set(PACKAGES_DIR "${ROOT_DIR}/packages") + +function(download URL DST_FILE STATUS) + set(TMP_FILE "${DST_FILE}.part") + + get_filename_component(FILE_NAME ${DST_FILE} NAME) + if (NOT EXISTS ${DST_FILE}) + message("Downloading ${FILE_NAME}") + file(DOWNLOAD ${URL} ${TMP_FILE} SHOW_PROGRESS STATUS DOWNLOAD_STATUS) + list(GET DOWNLOAD_STATUS 0 STATUS_CODE) + if (STATUS_CODE EQUAL 0) + file(RENAME ${TMP_FILE} ${DST_FILE}) + else() + file(REMOVE ${TMP_FILE}) + list(GET DOWNLOAD_STATUS 1 ERROR_MSG) + + message("ERROR! Downloading '${FILE_NAME}' failed.") + message(STATUS "URL: ${URL}") + message(STATUS "Error: ${STATUS_CODE} ${ERROR_MSG}") + set(STATUS FALSE PARENT_SCOPE) + return() + endif() + else() + message("Using cached ${FILE_NAME}") + endif() + set(STATUS TRUE PARENT_SCOPE) +endfunction(download) + +function(download_and_unpack PACKAGE_URL DST_DIR) + get_filename_component(FILE_NAME ${PACKAGE_URL} NAME) + + set(DST_FILE "${CACHE_DIR}/${FILE_NAME}") + set(TMP_FILE "${DST_FILE}.part") + + file(MAKE_DIRECTORY ${CACHE_DIR}) + file(MAKE_DIRECTORY ${DST_DIR}) + + download(${PACKAGE_URL} ${DST_FILE} STATUS) + + if (STATUS) + message("Unpacking ${FILE_NAME} to ${DST_DIR}") + execute_process(COMMAND ${CMAKE_COMMAND} -E tar -xf ${DST_FILE} + WORKING_DIRECTORY ${DST_DIR}) + endif() +endfunction(download_and_unpack) + +# Packs installed package binaries and headers into an archive. +function(create_package NAME DIR) + message("Creating package ${NAME}") + file(MAKE_DIRECTORY ${PACKAGES_DIR}) + + # To create an archive without addicional top level directory + # (like package-X.Y.Z) we need to know all top level files/dirs. + # Usually it is just "win64" dir. + file(GLOB TOP_FILES RELATIVE ${DIR} "${DIR}/*") + + set(PACKAGE_FILE "${PACKAGES_DIR}/${NAME}.tar.gz") + execute_process(COMMAND ${CMAKE_COMMAND} -E + tar -czf ${PACKAGE_FILE} ${TOP_FILES} + WORKING_DIRECTORY ${DIR}) +endfunction(create_package) + +# Downloads the source code of the package and unpacks it to dedicated 'src' +# dir. Also creates 'build' and 'install' dir to be used by a build script. +function(prepare_package_source NAME VERSION URL) + set(PACKAGE_NAME "${NAME}-${VERSION}") + + set(PACKAGE_DIR "${CACHE_DIR}/${PACKAGE_NAME}") + set(SOURCE_DIR "${PACKAGE_DIR}/src") + set(BUILD_DIR "${PACKAGE_DIR}/build") + set(INSTALL_DIR "${PACKAGE_DIR}/install") + + if (NOT EXISTS ${SOURCE_DIR}) + download_and_unpack(${URL} ${PACKAGE_DIR} STATUS) + file(GLOB ORIG_SOURCE_DIR_NAME "${PACKAGE_DIR}/*") + file(RENAME ${ORIG_SOURCE_DIR_NAME} ${SOURCE_DIR}) + endif() + + file(MAKE_DIRECTORY ${BUILD_DIR}) + file(MAKE_DIRECTORY ${INSTALL_DIR}) + + # Export names and dirs to be used by a package-specific build script. + set(PACKAGE_NAME ${PACKAGE_NAME} PARENT_SCOPE) + set(SOURCE_DIR ${SOURCE_DIR} PARENT_SCOPE) + set(BUILD_DIR ${BUILD_DIR} PARENT_SCOPE) + set(INSTALL_DIR ${INSTALL_DIR} PARENT_SCOPE) +endfunction() diff --git a/cmake/scripts/install_deps.cmake b/cmake/scripts/install_deps.cmake new file mode 100644 index 0000000000..d88fd0163c --- /dev/null +++ b/cmake/scripts/install_deps.cmake @@ -0,0 +1,14 @@ +include("${CMAKE_CURRENT_LIST_DIR}/helpers.cmake") + +set(INSTALL_DIR "${ROOT_DIR}/deps") +set(SERVER "https://github.com/ethereum/cpp-dependencies/releases/download/vc140/") + +function(download_and_install PACKAGE_NAME) + download_and_unpack("${SERVER}${PACKAGE_NAME}.tar.gz" ${INSTALL_DIR}) +endfunction(download_and_install) + + +download_and_install("curl-7.4.2") +download_and_install("leveldb-1.2") +download_and_install("microhttpd-0.9.2") +download_and_install("miniupnpc-1.9") diff --git a/cmake/scripts/jsonrpcstub.cmake b/cmake/scripts/jsonrpcstub.cmake new file mode 100644 index 0000000000..5468d850a1 --- /dev/null +++ b/cmake/scripts/jsonrpcstub.cmake @@ -0,0 +1,82 @@ +# generates JSONRPC Stub Server && Client +# +# this script expects +# ETH_SOURCE_DIR - main CMAKE_SOURCE_DIR +# ETH_SPEC_PATH +# ETH_SERVER_DIR +# ETH_CLIENT_DIR +# ETH_SERVER_NAME +# ETH_CLIENT_NAME +# ETH_JSON_RPC_STUB +# +# example usage: +# cmake -DETH_SPEC_PATH=spec.json -DETH_SERVER_DIR=libweb3jsonrpc -DETH_CLIENT_DIR=test +# -DETH_SERVER_NAME=AbstractWebThreeStubServer -DETH_CLIENT_NAME=WebThreeStubClient -DETH_JSON_RPC_STUB=/usr/local/bin/jsonrpcstub + +# setup names, and allow different filename from classname for namespaced classes. +# For an example call look at libethereum/CMakeLists.txt for eth::dev::Sentinel +if (ETH_SERVER_FILENAME) + set(SERVER_TMPFILE "${ETH_SERVER_DIR}/${ETH_SERVER_FILENAME}.h.tmp") + set(SERVER_TMPFILE2 "${ETH_SERVER_DIR}/${ETH_SERVER_FILENAME}.h.tmp2") + set(SERVER_OUTFILE "${ETH_SERVER_DIR}/${ETH_SERVER_FILENAME}.h") +else () + set(SERVER_TMPFILE "${ETH_SERVER_DIR}/${ETH_SERVER_NAME}.h.tmp") + set(SERVER_TMPFILE2 "${ETH_SERVER_DIR}/${ETH_SERVER_NAME}.h.tmp2") + set(SERVER_OUTFILE "${ETH_SERVER_DIR}/${ETH_SERVER_NAME}.h") +endif() +if (ETH_CLIENT_FILENAME) + set(CLIENT_TMPFILE "${ETH_CLIENT_DIR}/${ETH_CLIENT_FILENAME}.h.tmp") + set(CLIENT_OUTFILE "${ETH_CLIENT_DIR}/${ETH_CLIENT_FILENAME}.h") +else () + set(CLIENT_TMPFILE "${ETH_CLIENT_DIR}/${ETH_CLIENT_NAME}.h.tmp") + set(CLIENT_OUTFILE "${ETH_CLIENT_DIR}/${ETH_CLIENT_NAME}.h") +endif () + +# create tmp files +if (NOT ETH_SERVER_DIR) + execute_process( + COMMAND ${ETH_JSON_RPC_STUB} ${ETH_SPEC_PATH} + --cpp-client=${ETH_CLIENT_NAME} --cpp-client-file=${CLIENT_TMPFILE} + OUTPUT_VARIABLE ERR ERROR_QUIET + ) +else () + execute_process( + COMMAND ${ETH_JSON_RPC_STUB} ${ETH_SPEC_PATH} + --cpp-server=${ETH_SERVER_NAME} --cpp-server-file=${SERVER_TMPFILE} + --cpp-client=${ETH_CLIENT_NAME} --cpp-client-file=${CLIENT_TMPFILE} + OUTPUT_VARIABLE ERR ERROR_QUIET + ) + + # get name without namespace + string(REPLACE "::" ";" SERVER_NAME_LIST "${ETH_SERVER_NAME}") + list(LENGTH SERVER_NAME_LIST SERVER_NAME_LENGTH) + math(EXPR SERVER_NAME_POS "${SERVER_NAME_LENGTH} - 1") + list(GET SERVER_NAME_LIST ${SERVER_NAME_POS} SERVER_NAME) + + file(READ ${SERVER_TMPFILE} SERVER_CONTENT) + + # The following cmake regexps are equal to this sed command + # sed -e s/include\ \/include\ ${INCLUDE_NAME}/g \ + # -e s/public\ jsonrpc::AbstractServer\<${NAME}\>/public\ ServerInterface\<${NAME}\>/g \ + # -e s/${NAME}\(jsonrpc::AbstractServerConnector\ \&conn,\ jsonrpc::serverVersion_t\ type\ =\ jsonrpc::JSONRPC_SERVER_V2\)\ :\ jsonrpc::AbstractServer\<${NAME}\>\(conn,\ type\)/${NAME}\(\)/g \ + string(REGEX REPLACE "include\ " "include\ \"ModularServer.h\"" SERVER_CONTENT "${SERVER_CONTENT}") + string(REGEX REPLACE "public\ jsonrpc::AbstractServer<${SERVER_NAME}>" "public ServerInterface<${SERVER_NAME}>" SERVER_CONTENT "${SERVER_CONTENT}") + string(REGEX REPLACE "${SERVER_NAME}\\(jsonrpc::AbstractServerConnector\ &conn,\ jsonrpc::serverVersion_t\ type\ =\ jsonrpc::JSONRPC_SERVER_V2\\)\ :\ jsonrpc::AbstractServer<${SERVER_NAME}>\\(conn, type\\)" "${SERVER_NAME}()" SERVER_CONTENT "${SERVER_CONTENT}") + + file(WRITE ${SERVER_TMPFILE2} "${SERVER_CONTENT}") +endif() + +# don't throw fatal error on jsonrpcstub error, someone might have old version of jsonrpcstub, +# he does not need to upgrade it if he is not working on JSON RPC +# show him warning instead +if (ERR) + message(WARNING "Your version of jsonrcpstub tool is not supported. Please upgrade it.") + message(WARNING "${ERR}") +else() + include("${ETH_CMAKE_DIR}/EthUtils.cmake") + if (ETH_SERVER_DIR) + file(REMOVE "${SERVER_TMPFILE}") + replace_if_different("${SERVER_TMPFILE2}" "${SERVER_OUTFILE}") + endif() + replace_if_different("${CLIENT_TMPFILE}" "${CLIENT_OUTFILE}") +endif() diff --git a/cmake/scripts/resource.hpp.in b/cmake/scripts/resource.hpp.in new file mode 100644 index 0000000000..cb658c5aad --- /dev/null +++ b/cmake/scripts/resource.hpp.in @@ -0,0 +1,30 @@ +// this file is autogenerated, do not modify!!! +#pragma once + +#include +#include + +namespace dev +{ +namespace eth +{ + +class ${ETH_RESOURCE_NAME} +{ +public: + ${ETH_RESOURCE_NAME}() + { +${ETH_RESULT_DATA} +${ETH_RESULT_INIT} + } + + std::string loadResourceAsString(std::string _name) { return std::string(m_resources[_name], m_sizes[_name]); } + +private: + std::map m_resources; + std::map m_sizes; +}; + +} +} + diff --git a/cmake/scripts/resources.cmake b/cmake/scripts/resources.cmake new file mode 100644 index 0000000000..bf538ab8c0 --- /dev/null +++ b/cmake/scripts/resources.cmake @@ -0,0 +1,57 @@ +# based on: http://stackoverflow.com/questions/11813271/embed-resources-eg-shader-code-images-into-executable-library-with-cmake +# +# example: +# cmake -DETH_RES_FILE=test.cmake -P resources.cmake +# +# where test.cmake is: +# +# # BEGIN OF cmake.test +# +# set(copydlls "copydlls.cmake") +# set(conf "configure.cmake") +# +# # this three properties must be set! +# +# set(ETH_RESOURCE_NAME "EthResources") +# set(ETH_RESOURCE_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}") +# set(ETH_RESOURCES "copydlls" "conf") +# +# # END of cmake.test +# + +# should define ETH_RESOURCES +include(${ETH_RES_FILE}) + +set(ETH_RESULT_DATA "") +set(ETH_RESULT_INIT "") + +# resource is a name visible for cpp application +foreach(resource ${ETH_RESOURCES}) + + # filename is the name of file which will be used in app + set(filename ${${resource}}) + + # filedata is a file content + file(READ ${filename} filedata HEX) + + # read full name of the file + file(GLOB filename ${filename}) + + # Convert hex data for C compatibility + string(REGEX REPLACE "([0-9a-f][0-9a-f])" "0x\\1," filedata ${filedata}) + + # append static variables to result variable + set(ETH_RESULT_DATA "${ETH_RESULT_DATA} static const unsigned char eth_${resource}[] = {\n // ${filename}\n ${filedata}\n};\n") + + # append init resources + set(ETH_RESULT_INIT "${ETH_RESULT_INIT} m_resources[\"${resource}\"] = (char const*)eth_${resource};\n") + set(ETH_RESULT_INIT "${ETH_RESULT_INIT} m_sizes[\"${resource}\"] = sizeof(eth_${resource});\n") + +endforeach(resource) + +set(ETH_DST_NAME "${ETH_RESOURCE_LOCATION}/${ETH_RESOURCE_NAME}") + +configure_file("${CMAKE_CURRENT_LIST_DIR}/resource.hpp.in" "${ETH_DST_NAME}.hpp.tmp") + +include("${CMAKE_CURRENT_LIST_DIR}/../EthUtils.cmake") +replace_if_different("${ETH_DST_NAME}.hpp.tmp" "${ETH_DST_NAME}.hpp") diff --git a/cmake/scripts/runtest.cmake b/cmake/scripts/runtest.cmake new file mode 100644 index 0000000000..3a680e2d1e --- /dev/null +++ b/cmake/scripts/runtest.cmake @@ -0,0 +1,15 @@ +# Should be used to run ctest +# +# example usage: +# cmake -DETH_TEST_NAME=TestInterfaceStub -DCTEST_COMMAND=/path/to/ctest -P scripts/runtest.cmake + +if (NOT CTEST_COMMAND) + message(FATAL_ERROR "ctest could not be found!") +endif() + +# verbosity is off, cause BOOST_MESSAGE is not thread safe and output is a trash +# see https://codecrafter.wordpress.com/2012/11/01/c-unit-test-framework-adapter-part-3/ +# +# output might not be usefull cause of thread safety issue +execute_process(COMMAND ${CTEST_COMMAND} --force-new-ctest-process -C Debug --output-on-failure -j 4 -R "${ETH_TEST_NAME}[.].*") + diff --git a/cmake/secp256k1/CMakeLists.txt b/cmake/secp256k1/CMakeLists.txt new file mode 100644 index 0000000000..1071be809b --- /dev/null +++ b/cmake/secp256k1/CMakeLists.txt @@ -0,0 +1,38 @@ +# This CMake config file for secp256k1 project from https://github.com/bitcoin-core/secp256k1 +# +# The secp256k1 project has been configured following official docs with following options: +# +# ./configure --disable-shared --disable-tests --disable-coverage --disable-openssl-tests --disable-exhaustive-tests --disable-jni --with-bignum=no --with-field=64bit --with-scalar=64bit --with-asm=no +# +# Build static context: +# make src/ecmult_static_context.h +# +# Copy src/ecmult_static_context.h and src/libsecp256k1-config.h +# +# Copy CFLAGS from Makefile to COMPILE_OPTIONS. + +cmake_minimum_required(VERSION 3.4) +project(secp256k1 LANGUAGES C) + +set(COMMON_COMPILE_FLAGS ENABLE_MODULE_RECOVERY USE_ECMULT_STATIC_PRECOMPUTATION USE_FIELD_INV_BUILTIN USE_NUM_NONE USE_SCALAR_INV_BUILTIN) +if (MSVC) + set(COMPILE_FLAGS USE_FIELD_10X26 USE_SCALAR_8X32) + set(COMPILE_OPTIONS "") +else() + set(COMPILE_FLAGS USE_FIELD_5X52 USE_SCALAR_4X64 HAVE_BUILTIN_EXPECT HAVE___INT128) + set(COMPILE_OPTIONS -O3 -W -std=c89 -pedantic -Wall -Wextra -Wcast-align -Wnested-externs -Wshadow -Wstrict-prototypes -Wno-unused-function -Wno-long-long -Wno-overlength-strings -fvisibility=hidden) +endif() + +add_executable(gen_context src/gen_context.c) +target_include_directories(gen_context PRIVATE ${CMAKE_SOURCE_DIR}) + +add_custom_target(ecmult_static_context gen_context WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) + +add_library(secp256k1 STATIC src/secp256k1.c) +target_compile_definitions(secp256k1 PRIVATE ${COMMON_COMPILE_FLAGS} ${COMPILE_FLAGS}) +target_include_directories(secp256k1 PRIVATE ${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/src) +target_compile_options(secp256k1 PRIVATE ${COMPILE_OPTIONS}) +add_dependencies(secp256k1 ecmult_static_context) + +install(TARGETS secp256k1 ARCHIVE DESTINATION lib) +install(DIRECTORY include/ DESTINATION include) diff --git a/cmake/templates/BuildInfo.h.in b/cmake/templates/BuildInfo.h.in new file mode 100644 index 0000000000..f7c2ef7bfc --- /dev/null +++ b/cmake/templates/BuildInfo.h.in @@ -0,0 +1,12 @@ +#pragma once + +#define ETH_PROJECT_VERSION "@PROJECT_VERSION@" +#define ETH_COMMIT_HASH @ETH_COMMIT_HASH@ +#define ETH_CLEAN_REPO @ETH_CLEAN_REPO@ +#define ETH_BUILD_TYPE @ETH_BUILD_TYPE@ +#define ETH_BUILD_OS @ETH_BUILD_OS@ +#define ETH_BUILD_COMPILER @ETH_BUILD_COMPILER@ +#define ETH_BUILD_JIT_MODE @ETH_BUILD_JIT_MODE@ +#define ETH_BUILD_PLATFORM @ETH_BUILD_PLATFORM@ +#define ETH_BUILD_NUMBER @ETH_BUILD_NUMBER@ +#define ETH_VERSION_SUFFIX "@ETH_VERSION_SUFFIX@" diff --git a/config.json b/config.json new file mode 100644 index 0000000000..54e2717ba5 --- /dev/null +++ b/config.json @@ -0,0 +1,39 @@ +{ + "sealEngine": "PBFT", + "systemproxyaddress":"0x0", + "systemproxyaddressDfsFile":"", + "systemproxyaddressDfsServer":"", + "listenip":"127.0.0.1", + "rpcport":"6801", + "p2pport":"30303", + "wallet":"keys.info", + "keystoredir":"keystore/", + "datadir":"", + "vm":"interpreter", + "networkid":"12345", + "logverbosity":"4", + "coverlog":"OFF", + "eventlog":"ON", + "logconf":"log.conf", + "dfsNode":"de0fa385816b505799433e54b88788e21cb42092a6ff5bcaa2285d7ace906e5e6ce8ef2b30134ff276a5834d58721291acc5864e07e6d52469b79b28e699dfde", + "dfsGroup":"group1", + "dfsStorage":"filestorage", + "params": { + "accountStartNonce": "0x0", + "maximumExtraDataSize": "0x0", + "tieBreakingGas": false, + "blockReward": "0x0", + "networkID" : "0x0" + }, + "NodeextraInfo":[ + { + "Nodeid":"de0fa385816b505799433e54b88788e21cb42092a6ff5bcaa2285d7ace906e5e6ce8ef2b30134ff276a5834d58721291acc5864e07e6d52469b79b28e699dfde", + "Nodedesc": "node1", + "Agencyinfo": "node1", + "Peerip": "127.0.0.1", + "Identitytype": 1, + "Port":30303, + "Idx":0 + } + ] +} \ No newline at end of file diff --git a/deps/LICENSE b/deps/LICENSE new file mode 100644 index 0000000000..4e5f7cc040 --- /dev/null +++ b/deps/LICENSE @@ -0,0 +1,673 @@ + Version 3, 29 June 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 General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is 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. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + 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. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + 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 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. Use with the GNU Affero General Public License. + + 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 Affero 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 special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU 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 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 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 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 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + 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 GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/deps/README.md b/deps/README.md new file mode 100644 index 0000000000..42ae78b988 --- /dev/null +++ b/deps/README.md @@ -0,0 +1,22 @@ +# cpp-dependencies + +download, compile && prepare cpp-ethereum dependencies for windows + +* Win32 - Debug +* Win32 - Release +* x64 - Debug +* x64 - Release + +### Requirements + +* git +* cmake 3.0 +* VisualStudio 2013 Community +* tar +* curl + +### Run + +```shell +main.bat +``` diff --git a/deps/appveyor.yml b/deps/appveyor.yml new file mode 100644 index 0000000000..029c91b0f5 --- /dev/null +++ b/deps/appveyor.yml @@ -0,0 +1,58 @@ +version: 1.6.2.{build} + +os: Windows Server 2012 R2 + +environment: + MSBuild: "\"c:/Program Files (x86)/MSBuild/12.0/bin/msbuild.exe\"" + #PLATFORM: - defined in appveyor env + #CONFIGURATION: - defined in appveyor env + +clone_folder: c:\projects\cpp-dependencies + +platform: + - Win32 + - x64 + +#configuration: + #- Debug + #- Release , this will be set later + +build: off # temporarily + +# scripts to run before build +#build_script: + #- cmake --version + #- cd c:\projects\cpp-dependencies + + #- set CONFIGURATION=Debug + + #- call build_jsoncpp.bat + #- call bundle_jsoncpp.bat + + #- call build_microhttpd.bat + #- call bundle_microhttpd.bat + + #- call build_curl.bat + #- call bundle_curl.bat + + #- set CONFIGURATION=Relase + + #- call build_jsoncpp.bat + #- call bundle_jsoncpp.bat + + #- call build_microhttpd.bat + #- call bundle_microhttpd.bat + + #- call build_curl.bat + #- call bundle_curl.bat + + #- set CONFIGURATION=Debug + + #- call build_jsonrpccpp.bat + #- call bundle_jsonrpccpp.bat + + #- set CONFIGURATION=Release + + #- call build_jsonrpccpp.bat + #- call bundle_jsonrpccpp.bat + diff --git a/deps/build_cryptopp.bat b/deps/build_cryptopp.bat new file mode 100644 index 0000000000..43dea0bc8b --- /dev/null +++ b/deps/build_cryptopp.bat @@ -0,0 +1,10 @@ +REM clone cryptopp +if not exist build\cryptopp git clone -q https://github.com/ethereum/cryptopp build\cryptopp +cd build\cryptopp\win +git checkout -qf eb2efc3eaec9a178c0f2049894417ca8c0b8bad4 + +REM build cryptopp +%MSBuild% LibCryptoPP.sln /property:Configuration=%CONFIGURATION% /property:Platform=%PLATFORM% /verbosity:minimal + +REM cryptopp built +cd ..\..\.. diff --git a/deps/build_curl.bat b/deps/build_curl.bat new file mode 100644 index 0000000000..58cf55caff --- /dev/null +++ b/deps/build_curl.bat @@ -0,0 +1,20 @@ +REM clone curl +if not exist build\curl git clone -q https://github.com/debris/curl build\curl +cd build\curl +git checkout -qf 139141f8d73eb5820a64b100485572a263f4156b + +REM create curl build dirs +if %PLATFORM% == Win32 if not exist build mkdir build +if %PLATFORM% == Win32 cd build +if %PLATFORM% == x64 if not exist build64 mkdir build64 +if %PLATFORM% == x64 cd build64 + +REM run curl cmake +if %PLATFORM% == Win32 cmake .. +if %PLATFORM% == x64 cmake -G "Visual Studio 14 2015 Win64" .. + +REM build curl +%MSBuild% CURL.sln /property:Configuration=%CONFIGURATION% /property:Platform=%PLATFORM% /target:libcurl /verbosity:minimal + +REM curl built +cd ..\..\.. diff --git a/deps/build_jsoncpp.bat b/deps/build_jsoncpp.bat new file mode 100644 index 0000000000..02054a8f0f --- /dev/null +++ b/deps/build_jsoncpp.bat @@ -0,0 +1,20 @@ +REM clone jsoncpp +if not exist build\jsoncpp git clone -q https://github.com/debris/jsoncpp build\jsoncpp +cd build\jsoncpp +git checkout -qf 24c0054c10e62e8359c0f96372dfa183de90f93c + +REM create jsoncpp build dirs +if %PLATFORM% == Win32 if not exist build mkdir build +if %PLATFORM% == Win32 cd build +if %PLATFORM% == x64 if not exist build64 mkdir build64 +if %PLATFORM% == x64 cd build64 + +REM run jsoncpp cmake +if %PLATFORM% == Win32 cmake .. +if %PLATFORM% == x64 cmake -G "Visual Studio 14 2015 Win64" .. + +REM build jsoncpp +%MSBuild% jsoncpp.sln /property:Configuration=%CONFIGURATION% /property:Platform=%PLATFORM% /target:jsoncpp_lib_static /verbosity:minimal + +REM jsoncpp built +cd ..\..\.. diff --git a/deps/build_jsonrpccpp.bat b/deps/build_jsonrpccpp.bat new file mode 100644 index 0000000000..4c80209dd6 --- /dev/null +++ b/deps/build_jsonrpccpp.bat @@ -0,0 +1,22 @@ +set MAINDIR="%cd%" +REM clone jsonrpccpp +if not exist build\jsonrpccpp git clone -q https://github.com/debris/libjson-rpc-cpp build\jsonrpccpp +cd build\jsonrpccpp +git checkout -qf fb5cde7cb677fd14f916cda04b28f45461bfc9e2 + +REM create jsonrpccpp build dirs +if %PLATFORM% == Win32 if not exist build mkdir build +if %PLATFORM% == Win32 cd build +if %PLATFORM% == x64 if not exist build64 mkdir build64 +if %PLATFORM% == x64 cd build64 + +REM run jsonrpccpp cmake +if %PLATFORM% == Win32 cmake -DCMAKE_PREFIX_PATH="%MAINDIR%\install\Win32" -DCOMPILE_STUBGEN=NO -DCOMPILE_TESTS=NO .. +if %PLATFORM% == x64 cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_PREFIX_PATH="%MAINDIR%\install\x64" -DCOMPILE_STUBGEN=NO -DCOMPILE_TESTS=NO .. + +REM build jsonrpccpp +%MSBuild% libjson-rpc-cpp.sln /property:Configuration=%CONFIGURATION% /property:Platform=%PLATFORM% /target:jsonrpcclientStatic /verbosity:minimal +%MSBuild% libjson-rpc-cpp.sln /property:Configuration=%CONFIGURATION% /property:Platform=%PLATFORM% /target:jsonrpcserverStatic /verbosity:minimal + +REM jsonrpcpp built +cd ..\..\.. diff --git a/deps/build_leveldb.bat b/deps/build_leveldb.bat new file mode 100644 index 0000000000..06a1fc4128 --- /dev/null +++ b/deps/build_leveldb.bat @@ -0,0 +1,11 @@ +REM clone leveldb +if not exist build\leveldb git clone https://github.com/ethereum/leveldb build\leveldb +cd build\leveldb\win + +REM build leveldb +@echo build leveldb +%MSBuild% LibLevelDB.sln /property:Configuration=%CONFIGURATION% /property:Platform=%PLATFORM% /verbosity:minimal + +@echo built +REM leveldb built +cd ..\..\.. diff --git a/deps/build_microhttpd.bat b/deps/build_microhttpd.bat new file mode 100644 index 0000000000..48eb2ff20a --- /dev/null +++ b/deps/build_microhttpd.bat @@ -0,0 +1,10 @@ +REM clone microhttpd +if not exist build\microhttpd git clone -q https://github.com/svn2github/libmicrohttpd build\microhttpd +cd build\microhttpd\w32\VS2015 +git checkout -qf 82ee737a39be28a32048248655d780ad8a240939 + +REM build microhttpd +%MSBuild% libmicrohttpd.sln /property:Configuration=%CONFIGURATION%-dll /property:Platform=%PLATFORM% /target:libmicrohttpd /verbosity:minimal + +REM microhttpd built +cd ..\..\..\.. diff --git a/deps/build_miniupnpc.bat b/deps/build_miniupnpc.bat new file mode 100644 index 0000000000..8eb7c3ab50 --- /dev/null +++ b/deps/build_miniupnpc.bat @@ -0,0 +1,20 @@ +REM clone miniupnpc +if not exist build\miniupnpc git clone -q https://github.com/debris/miniupnp build\miniupnpc +cd build\miniupnpc\miniupnpc +git checkout -qf 5459ab79cb5ba8f78e76daf698b70bc76ffef6f1 + +REM create miniupnpc build dirs +if %PLATFORM% == Win32 if not exist build mkdir build +if %PLATFORM% == Win32 cd build +if %PLATFORM% == x64 if not exist build64 mkdir build64 +if %PLATFORM% == x64 cd build64 + +REM run miniupnpc cmake +if %PLATFORM% == Win32 cmake .. +if %PLATFORM% == x64 cmake -G "Visual Studio 14 2015 Win64" .. + +REM build miniupnpc +%MSBuild% miniupnpc.sln /property:Configuration=%CONFIGURATION% /property:Platform=%PLATFORM% /target:upnpc-static /verbosity:minimal + +REM miniupnpc built +cd ..\..\..\.. diff --git a/deps/bundle_cryptopp.bat b/deps/bundle_cryptopp.bat new file mode 100644 index 0000000000..6eab62395b --- /dev/null +++ b/deps/bundle_cryptopp.bat @@ -0,0 +1,23 @@ +REM packaging cryptopp +if not exist package\cryptopp mkdir package\cryptopp + +if not exist package\cryptopp\%PLATFORM% mkdir package\cryptopp\%PLATFORM% +if not exist package\cryptopp\%PLATFORM%\lib mkdir package\cryptopp\%PLATFORM%\lib +if not exist package\cryptopp\%PLATFORM%\include mkdir package\cryptopp\%PLATFORM%\include +if not exist package\cryptopp\%PLATFORM%\include\cryptopp mkdir package\cryptopp\%PLATFORM%\include\cryptopp + +cd package\cryptopp\%PLATFORM% + +if %PLATFORM% == Win32 ( + if %CONFIGURATION% == Release cmake -E copy ..\..\..\build\cryptopp\win\Release\LibCryptoPP.lib lib\cryptopp.lib + if %CONFIGURATION% == Debug cmake -E copy ..\..\..\build\cryptopp\win\Debug\LibCryptoPP.lib lib\cryptoppd.lib +) + +if %PLATFORM% == x64 ( + if %CONFIGURATION% == Release cmake -E copy ..\..\..\build\cryptopp\win\x64\Release\LibCryptoPP.lib lib\cryptopp.lib + if %CONFIGURATION% == Debug cmake -E copy ..\..\..\build\cryptopp\win\x64\Debug\LibCryptoPP.lib lib\cryptoppd.lib +) + +xcopy ..\..\..\build\cryptopp\*.h include\cryptopp /sy +cd ..\..\.. + diff --git a/deps/bundle_curl.bat b/deps/bundle_curl.bat new file mode 100644 index 0000000000..b247b58fb3 --- /dev/null +++ b/deps/bundle_curl.bat @@ -0,0 +1,51 @@ +REM packaging curl +if not exist package\curl mkdir package\curl + +if not exist package\curl\%PLATFORM% mkdir package\curl\%PLATFORM% +if not exist package\curl\%PLATFORM%\lib mkdir package\curl\%PLATFORM%\lib +if not exist package\curl\%PLATFORM%\bin mkdir package\curl\%PLATFORM%\bin +if not exist package\curl\%PLATFORM%\include mkdir package\curl\%PLATFORM%\include +if not exist package\curl\%PLATFORM%\include\curl mkdir package\curl\%PLATFORM%\include\curl + +cd package\curl\%PLATFORM% + +if %PLATFORM% == Win32 ( + if %CONFIGURATION% == Release ( + cmake -E copy ..\..\..\build\curl\build\lib\Release\libcurl.dll bin\libcurl.dll + cmake -E copy ..\..\..\build\curl\build\lib\Release\libcurl_imp.exp lib\libcurl.exp + cmake -E copy ..\..\..\build\curl\build\lib\Release\libcurl_imp.lib lib\libcurl.lib + ) + + if %CONFIGURATION% == Debug ( + cmake -E copy ..\..\..\build\curl\build\lib\Debug\libcurl.dll bin\libcurld.dll + cmake -E copy ..\..\..\build\curl\build\lib\Debug\libcurl.ilk lib\libcurld.ilk + cmake -E copy ..\..\..\build\curl\build\lib\Debug\libcurl.pdb lib\libcurld.pdb + cmake -E copy ..\..\..\build\curl\build\lib\Debug\libcurl_imp.exp lib\libcurld.exp + cmake -E copy ..\..\..\build\curl\build\lib\Debug\libcurl_imp.lib lib\libcurld.lib + ) + + cmake -E copy ..\..\..\build\curl\build\include\curl\curlbuild.h include\curl\curlbuild.h +) + +if %PLATFORM% == x64 ( + if %CONFIGURATION% == Release ( + cmake -E copy ..\..\..\build\curl\build64\lib\Release\libcurl.dll bin\libcurl.dll + cmake -E copy ..\..\..\build\curl\build64\lib\Release\libcurl_imp.exp lib\libcurl.exp + cmake -E copy ..\..\..\build\curl\build64\lib\Release\libcurl_imp.lib lib\libcurl.lib + ) + + if %CONFIGURATION% == Debug ( + cmake -E copy ..\..\..\build\curl\build64\lib\Debug\libcurl.dll bin\libcurld.dll + cmake -E copy ..\..\..\build\curl\build64\lib\Debug\libcurl.ilk lib\libcurld.ilk + cmake -E copy ..\..\..\build\curl\build64\lib\Debug\libcurl.pdb lib\libcurld.pdb + cmake -E copy ..\..\..\build\curl\build64\lib\Debug\libcurl_imp.exp lib\libcurld.exp + cmake -E copy ..\..\..\build\curl\build64\lib\Debug\libcurl_imp.lib lib\libcurld.lib + ) + + cmake -E copy ..\..\..\build\curl\build64\include\curl\curlbuild.h include\curl\curlbuild.h +) + +cmake -E copy_directory ..\..\..\build\curl\include\curl include\curl + +cd ..\..\.. + diff --git a/deps/bundle_jsoncpp.bat b/deps/bundle_jsoncpp.bat new file mode 100644 index 0000000000..0e2ca99f97 --- /dev/null +++ b/deps/bundle_jsoncpp.bat @@ -0,0 +1,23 @@ +REM packaging jsoncpp +if not exist package\jsoncpp mkdir package\jsoncpp + +if not exist package\jsoncpp\%PLATFORM% mkdir package\jsoncpp\%PLATFORM% +if not exist package\jsoncpp\%PLATFORM%\lib mkdir package\jsoncpp\%PLATFORM%\lib +if not exist package\jsoncpp\%PLATFORM%\include mkdir package\jsoncpp\%PLATFORM%\include +if not exist package\jsoncpp\%PLATFORM%\include\json mkdir package\jsoncpp\%PLATFORM%\include\json + +cd package\jsoncpp\%PLATFORM% + +if %PLATFORM% == Win32 ( + if %CONFIGURATION% == Release cmake -E copy ..\..\..\build\jsoncpp\build\src\lib_json\Release\jsoncpp.lib lib\jsoncpp.lib + if %CONFIGURATION% == Debug cmake -E copy ..\..\..\build\jsoncpp\build\src\lib_json\Debug\jsoncpp.lib lib\jsoncppd.lib +) + +if %PLATFORM% == x64 ( + if %CONFIGURATION% == Release cmake -E copy ..\..\..\build\jsoncpp\build64\src\lib_json\Release\jsoncpp.lib lib\jsoncpp.lib + if %CONFIGURATION% == Debug cmake -E copy ..\..\..\build\jsoncpp\build64\src\lib_json\Debug\jsoncpp.lib lib\jsoncppd.lib +) + +cmake -E copy_directory ..\..\..\build\jsoncpp\include\json include\json +cd ..\..\.. + diff --git a/deps/bundle_jsonrpccpp.bat b/deps/bundle_jsonrpccpp.bat new file mode 100644 index 0000000000..db4a826dd8 --- /dev/null +++ b/deps/bundle_jsonrpccpp.bat @@ -0,0 +1,45 @@ +REM packaging jsonrpccpp +if not exist package\jsonrpccpp mkdir package\jsonrpccpp +if not exist package\jsonrpccpp\%PLATFORM% mkdir package\jsonrpccpp\%PLATFORM% +if not exist package\jsonrpccpp\%PLATFORM%\lib mkdir package\jsonrpccpp\%PLATFORM%\lib +if not exist package\jsonrpccpp\%PLATFORM%\include mkdir package\jsonrpccpp\%PLATFORM%\include +if not exist package\jsonrpccpp\%PLATFORM%\include\jsonrpccpp mkdir package\jsonrpccpp\%PLATFORM%\include\jsonrpccpp + +cd package\jsonrpccpp\%PLATFORM% + +if %PLATFORM% == Win32 ( + if %CONFIGURATION% == Release ( + cmake -E copy ..\..\..\build\jsonrpccpp\build\lib\Release\jsonrpccpp-common.lib lib\jsonrpccpp-common.lib + cmake -E copy ..\..\..\build\jsonrpccpp\build\lib\Release\jsonrpccpp-client.lib lib\jsonrpccpp-client.lib + cmake -E copy ..\..\..\build\jsonrpccpp\build\lib\Release\jsonrpccpp-server.lib lib\jsonrpccpp-server.lib + ) + + if %CONFIGURATION% == Debug ( + cmake -E copy ..\..\..\build\jsonrpccpp\build\lib\Debug\jsonrpccpp-common.lib lib\jsonrpccpp-commond.lib + cmake -E copy ..\..\..\build\jsonrpccpp\build\lib\Debug\jsonrpccpp-client.lib lib\jsonrpccpp-clientd.lib + cmake -E copy ..\..\..\build\jsonrpccpp\build\lib\Debug\jsonrpccpp-server.lib lib\jsonrpccpp-serverd.lib + ) + + xcopy ..\..\..\build\jsonrpccpp\build\gen\jsonrpccpp\*.h include\jsonrpccpp /sy +) + +if %PLATFORM% == x64 ( + if %CONFIGURATION% == Release ( + cmake -E copy ..\..\..\build\jsonrpccpp\build64\lib\Release\jsonrpccpp-common.lib lib\jsonrpccpp-common.lib + cmake -E copy ..\..\..\build\jsonrpccpp\build64\lib\Release\jsonrpccpp-client.lib lib\jsonrpccpp-client.lib + cmake -E copy ..\..\..\build\jsonrpccpp\build64\lib\Release\jsonrpccpp-server.lib lib\jsonrpccpp-server.lib + ) + + if %CONFIGURATION% == Debug ( + cmake -E copy ..\..\..\build\jsonrpccpp\build64\lib\Debug\jsonrpccpp-common.lib lib\jsonrpccpp-commond.lib + cmake -E copy ..\..\..\build\jsonrpccpp\build64\lib\Debug\jsonrpccpp-client.lib lib\jsonrpccpp-clientd.lib + cmake -E copy ..\..\..\build\jsonrpccpp\build64\lib\Debug\jsonrpccpp-server.lib lib\jsonrpccpp-serverd.lib + ) + + xcopy ..\..\..\build\jsonrpccpp\build64\gen\jsonrpccpp\*.h include\jsonrpccpp /sy +) + +xcopy ..\..\..\build\jsonrpccpp\src\jsonrpccpp\*.h include\jsonrpccpp /sy + +cd ..\..\.. + diff --git a/deps/bundle_leveldb.bat b/deps/bundle_leveldb.bat new file mode 100644 index 0000000000..c0e74b4dc6 --- /dev/null +++ b/deps/bundle_leveldb.bat @@ -0,0 +1,20 @@ +REM packaging leveldb +if not exist package\leveldb mkdir package\leveldb +if not exist package\leveldb\%PLATFORM% mkdir package\leveldb\%PLATFORM% +if not exist package\leveldb\%PLATFORM%lib\ mkdir package\leveldb\%PLATFORM%\lib +if not exist package\leveldb\%PLATFORM%\include mkdir package\leveldb\%PLATFORM%\include + +cd package\leveldb\%PLATFORM% + +if %PLATFORM% == Win32 ( + if %CONFIGURATION% == Release cmake -E copy ..\..\..\build\leveldb\win\Release\LibLevelDB.lib lib\leveldb.lib + if %CONFIGURATION% == Debug cmake -E copy ..\..\..\build\leveldb\win\Debug\LibLevelDB.lib lib\leveldbd.lib +) + +if %PLATFORM% == x64 ( + if %CONFIGURATION% == Release cmake -E copy ..\..\..\build\leveldb\win\x64\Release\LevelDB64.lib lib\leveldb.lib + if %CONFIGURATION% == Debug cmake -E copy ..\..\..\build\leveldb\win\x64\Debug\LevelDB64.lib lib\leveldbd.lib +) + +cmake -E copy_directory ..\..\..\build\leveldb\include include +cd ..\..\.. diff --git a/deps/bundle_microhttpd.bat b/deps/bundle_microhttpd.bat new file mode 100644 index 0000000000..0a916b2912 --- /dev/null +++ b/deps/bundle_microhttpd.bat @@ -0,0 +1,48 @@ +REM packaging microhttpd +if not exist package\microhttpd mkdir package\microhttpd +if not exist package\microhttpd\%PLATFORM% mkdir package\microhttpd\%PLATFORM% +if not exist package\microhttpd\%PLATFORM%\lib mkdir package\microhttpd\%PLATFORM%\lib +if not exist package\microhttpd\%PLATFORM%\bin mkdir package\microhttpd\%PLATFORM%\bin +if not exist package\microhttpd\%PLATFORM%\include mkdir package\microhttpd\%PLATFORM%\include + +cd package\microhttpd\%PLATFORM% + +if %PLATFORM% == Win32 ( + if %CONFIGURATION% == Release ( + cmake -E copy ..\..\..\build\microhttpd\w32\VS2015\Output\libmicrohttpd-dll.dll bin\libmicrohttpd-dll.dll + cmake -E copy ..\..\..\build\microhttpd\w32\VS2015\Output\libmicrohttpd-dll.exp lib\libmicrohttpd-dll.exp + cmake -E copy ..\..\..\build\microhttpd\w32\VS2015\Output\libmicrohttpd-dll.lib lib\libmicrohttpd-dll.lib + cmake -E copy ..\..\..\build\microhttpd\w32\VS2015\Output\libmicrohttpd-dll.pdb lib\libmicrohttpd-dll.pdb + ) + + if %CONFIGURATION% == Debug ( + cmake -E copy ..\..\..\build\microhttpd\w32\VS2015\Output\libmicrohttpd-dll_d.dll bin\libmicrohttpd-dll_d.dll + cmake -E copy ..\..\..\build\microhttpd\w32\VS2015\Output\libmicrohttpd-dll_d.exp lib\libmicrohttpd-dll_d.exp + cmake -E copy ..\..\..\build\microhttpd\w32\VS2015\Output\libmicrohttpd-dll_d.ilk lib\libmicrohttpd-dll_d.ilk + cmake -E copy ..\..\..\build\microhttpd\w32\VS2015\Output\libmicrohttpd-dll_d.lib lib\libmicrohttpd-dll_d.lib + cmake -E copy ..\..\..\build\microhttpd\w32\VS2015\Output\libmicrohttpd-dll_d.pdb lib\libmicrohttpd-dll_d.pdb + ) + + cmake -E copy ..\..\..\build\microhttpd\w32\VS2015\Output\microhttpd.h include\microhttpd.h +) + +if %PLATFORM% == x64 ( + if %CONFIGURATION% == Release ( + cmake -E copy ..\..\..\build\microhttpd\w32\VS2015\Output\x64\libmicrohttpd-dll.dll bin\libmicrohttpd-dll.dll + cmake -E copy ..\..\..\build\microhttpd\w32\VS2015\Output\x64\libmicrohttpd-dll.exp lib\libmicrohttpd-dll.exp + cmake -E copy ..\..\..\build\microhttpd\w32\VS2015\Output\x64\libmicrohttpd-dll.lib lib\libmicrohttpd-dll.lib + cmake -E copy ..\..\..\build\microhttpd\w32\VS2015\Output\x64\libmicrohttpd-dll.pdb lib\libmicrohttpd-dll.pdb + ) + + if %CONFIGURATION% == Debug ( + cmake -E copy ..\..\..\build\microhttpd\w32\VS2015\Output\x64\libmicrohttpd-dll_d.dll bin\libmicrohttpd-dll_d.dll + cmake -E copy ..\..\..\build\microhttpd\w32\VS2015\Output\x64\libmicrohttpd-dll_d.exp lib\libmicrohttpd-dll_d.exp + cmake -E copy ..\..\..\build\microhttpd\w32\VS2015\Output\x64\libmicrohttpd-dll_d.ilk lib\libmicrohttpd-dll_d.ilk + cmake -E copy ..\..\..\build\microhttpd\w32\VS2015\Output\x64\libmicrohttpd-dll_d.lib lib\libmicrohttpd-dll_d.lib + cmake -E copy ..\..\..\build\microhttpd\w32\VS2015\Output\x64\libmicrohttpd-dll_d.pdb lib\libmicrohttpd-dll_d.pdb + ) + + cmake -E copy ..\..\..\build\microhttpd\w32\VS2015\Output\x64\microhttpd.h include\microhttpd.h +) + +cd ..\..\.. diff --git a/deps/bundle_miniupnpc.bat b/deps/bundle_miniupnpc.bat new file mode 100644 index 0000000000..69367c2910 --- /dev/null +++ b/deps/bundle_miniupnpc.bat @@ -0,0 +1,24 @@ +REM packaging miniupnpc +if not exist package\miniupnpc mkdir package\miniupnpc + +if not exist package\miniupnpc\%PLATFORM% mkdir package\miniupnpc\%PLATFORM% +if not exist package\miniupnpc\%PLATFORM%\lib mkdir package\miniupnpc\%PLATFORM%\lib +if not exist package\miniupnpc\%PLATFORM%\include mkdir package\miniupnpc\%PLATFORM%\include +if not exist package\miniupnpc\%PLATFORM%\include\miniupnpc mkdir package\miniupnpc\%PLATFORM%\include\miniupnpc + +cd package\miniupnpc\%PLATFORM% + +if %PLATFORM% == Win32 ( + if %CONFIGURATION% == Release cmake -E copy ..\..\..\build\miniupnpc\miniupnpc\build\Release\miniupnpc.lib lib\miniupnpc.lib + if %CONFIGURATION% == Debug cmake -E copy ..\..\..\build\miniupnpc\miniupnpc\build\Debug\miniupnpc.lib lib\miniupnpcd.lib +) + +if %PLATFORM% == x64 ( + if %CONFIGURATION% == Release cmake -E copy ..\..\..\build\miniupnpc\miniupnpc\build64\Release\miniupnpc.lib lib\miniupnpc.lib + if %CONFIGURATION% == Debug cmake -E copy ..\..\..\build\miniupnpc\miniupnpc\build64\Debug\miniupnpc.lib lib\miniupnpcd.lib +) + +xcopy ..\..\..\build\miniupnpc\miniupnpc\*.h include\miniupnpc /sy + +cd ..\..\.. + diff --git a/deps/cryptopp.cmake b/deps/cryptopp.cmake new file mode 100644 index 0000000000..8f9b6a9c63 --- /dev/null +++ b/deps/cryptopp.cmake @@ -0,0 +1,192 @@ +include(ExternalProject) +include(GNUInstallDirs) + +# Support Emscripten builds by overwritting CMAKE_COMMAND. +if (${CMAKE_SYSTEM_NAME} STREQUAL "Emscripten") + set(CRYPTOPP_CMAKE_COMMAND emcmake cmake) +else() + set(CRYPTOPP_CMAKE_COMMAND ${CMAKE_COMMAND}) +endif() + +ExternalProject_Add(cryptopp-project + PREFIX deps/cryptopp + # This points to unreleased version 5.6.5+ but contains very small + # warning fix: + # https://github.com/weidai11/cryptopp/commit/903b8feaa70199eb39a313b32a71268745ddb600 + DOWNLOAD_NAME CRYPTOPP_bccc6443.tar.gz + URL https://github.com/weidai11/cryptopp/archive/bccc6443c4d4d611066c2de4c17109380cf97704.tar.gz + URL_HASH SHA256=f1fddacadd2a0873f795d5614a85fecd5b6ff1d1c6e21dedc251703c54ce63aa + # Keep source and archive in under source dir to avoid code duplication + # for multiple build types and allow injecting the archive in isolated + # builds (like Ubuntu PPA). + DOWNLOAD_DIR ${CMAKE_CURRENT_LIST_DIR}/src + SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/src/cryptopp + PATCH_COMMAND cmake -E remove + 3way.cpp + adler32.cpp + # algebra.cpp + # algparam.cpp + arc4.cpp + # asn.cpp + authenc.cpp + base32.cpp + base64.cpp + # basecode.cpp + bench1.cpp + bench2.cpp + bfinit.cpp + blake2.cpp + blowfish.cpp + blumshub.cpp + camellia.cpp + cast.cpp + casts.cpp + cbcmac.cpp + ccm.cpp + chacha.cpp + channels.cpp + cmac.cpp + # cpu.cpp + crc.cpp + # cryptlib.cpp + datatest.cpp + default.cpp + des.cpp + dessp.cpp + dh2.cpp + dh.cpp + # dll.cpp + dlltest.cpp + # dsa.cpp + eax.cpp + # ec2n.cpp + # eccrypto.cpp + # ecp.cpp + elgamal.cpp + emsa2.cpp + # eprecomp.cpp + esign.cpp + files.cpp + # filters.cpp + # fips140.cpp + fipsalgt.cpp + fipstest.cpp + gcm.cpp + gf2_32.cpp + gf256.cpp + # gf2n.cpp + # gfpcrypt.cpp + gost.cpp + gzip.cpp + # hex.cpp + # hmac.cpp + # hrtimer.cpp + ida.cpp + idea.cpp + # integer.cpp + # iterhash.cpp + # keccak.cpp + luc.cpp + mars.cpp + marss.cpp + md2.cpp + md4.cpp + md5.cpp + # misc.cpp + # modes.cpp + # mqueue.cpp + mqv.cpp + # nbtheory.cpp + network.cpp + # oaep.cpp + # osrng.cpp + panama.cpp + pch.cpp + pkcspad.cpp + poly1305.cpp + # polynomi.cpp + pssr.cpp + # pubkey.cpp + # queue.cpp + rabin.cpp + # randpool.cpp + rc2.cpp + rc5.cpp + rc6.cpp + rdrand.cpp + # rdtables.cpp + regtest.cpp + # rijndael.cpp + ripemd.cpp + # rng.cpp + rsa.cpp + rw.cpp + safer.cpp + salsa.cpp + seal.cpp + seed.cpp + serpent.cpp + sha3.cpp + shacal2.cpp + # sha.cpp + sharkbox.cpp + shark.cpp + simple.cpp + skipjack.cpp + socketft.cpp + sosemanuk.cpp + square.cpp + squaretb.cpp + # strciphr.cpp + tea.cpp + test.cpp + tftables.cpp + tiger.cpp + tigertab.cpp + trdlocal.cpp + ttmac.cpp + twofish.cpp + validat0.cpp + validat1.cpp + validat2.cpp + validat3.cpp + vmac.cpp + wait.cpp + wake.cpp + whrlpool.cpp + # winpipes.cpp + xtr.cpp + xtrcrypt.cpp + zdeflate.cpp + zinflate.cpp + zlib.cpp + CMAKE_COMMAND ${CRYPTOPP_CMAKE_COMMAND} + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX= + -DCMAKE_BUILD_TYPE=Release + # Build static lib but suitable to be included in a shared lib. + -DCMAKE_POSITION_INDEPENDENT_CODE=On + -DBUILD_SHARED=Off + -DBUILD_TESTING=Off + # Overwtire build and install commands to force Release build on MSVC. + BUILD_COMMAND cmake --build --config Release + INSTALL_COMMAND cmake --build --config Release --target install + ) + +# Create cryptopp imported library +#ExternalProject_Get_Property(cryptopp-project INSTALL_DIR) + +set(INSTALL_DIR "${CMAKE_SOURCE_DIR}/deps") +#message("INSTALL_DIR = ${INSTALL_DIR}") + +add_library(cryptopp STATIC IMPORTED) +if (MSVC) + set(CRYPTOPP_LIBRARY ${INSTALL_DIR}/${CMAKE_INSTALL_LIBDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}cryptopp-static${CMAKE_STATIC_LIBRARY_SUFFIX}) +else() + set(CRYPTOPP_LIBRARY ${INSTALL_DIR}/${CMAKE_INSTALL_LIBDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}cryptopp${CMAKE_STATIC_LIBRARY_SUFFIX}) +endif() +set(CRYPTOPP_INCLUDE_DIR ${INSTALL_DIR}/include) +file(MAKE_DIRECTORY ${CRYPTOPP_INCLUDE_DIR}) # Must exist. +set_property(TARGET cryptopp PROPERTY IMPORTED_LOCATION ${CRYPTOPP_LIBRARY}) +set_property(TARGET cryptopp PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${CRYPTOPP_INCLUDE_DIR}) +add_dependencies(cryptopp cryptopp-project) +unset(INSTALL_DIR) diff --git a/deps/install_cryptopp.bat b/deps/install_cryptopp.bat new file mode 100644 index 0000000000..5544d79d99 --- /dev/null +++ b/deps/install_cryptopp.bat @@ -0,0 +1,10 @@ +REM installing cryptopp +cmake -E copy_directory package\cryptopp install + +REM zipping cryptopp +cd package +if exist cryptopp-5.6.2 cmake -E remove_directory cryptopp-5.6.2 +cmake -E rename cryptopp cryptopp-5.6.2 +tar -zcvf cryptopp-5.6.2.tar.gz cryptopp-5.6.2 +cd .. + diff --git a/deps/install_curl.bat b/deps/install_curl.bat new file mode 100644 index 0000000000..1841e0eaba --- /dev/null +++ b/deps/install_curl.bat @@ -0,0 +1,10 @@ +REM installing curl +cmake -E copy_directory package\curl install + +REM zipping curl +cd package +if exist curl-7.4.2 cmake -E remove_directory curl-7.4.2 +cmake -E rename curl curl-7.4.2 +tar -zcvf curl-7.4.2.tar.gz curl-7.4.2 +cd .. + diff --git a/deps/install_deps.cmake b/deps/install_deps.cmake new file mode 100644 index 0000000000..9ddc37abef --- /dev/null +++ b/deps/install_deps.cmake @@ -0,0 +1,15 @@ +include("${CMAKE_CURRENT_LIST_DIR}/scripts/helpers.cmake") + +set(INSTALL_DIR "${ROOT_DIR}/install") +set(SERVER "https://github.com/ethereum/cpp-dependencies/releases/download/vc140/") + +function(download_and_install PACKAGE_NAME) + download_and_unpack("${SERVER}${PACKAGE_NAME}.tar.gz" ${INSTALL_DIR}) +endfunction(download_and_install) + + +download_and_install("boost-1.61") +download_and_install("curl-7.4.2") +download_and_install("leveldb-1.2") +download_and_install("microhttpd-0.9.2") +download_and_install("miniupnpc-1.9") diff --git a/deps/install_jsoncpp.bat b/deps/install_jsoncpp.bat new file mode 100644 index 0000000000..dc8641b2d3 --- /dev/null +++ b/deps/install_jsoncpp.bat @@ -0,0 +1,10 @@ +REM installing jsoncpp +cmake -E copy_directory package\jsoncpp install + +REM zipping jsoncpp +cd package +if exist jsoncpp-1.6.2 cmake -E remove_directory jsoncpp-1.6.2 +cmake -E rename jsoncpp jsoncpp-1.6.2 +tar -zcvf jsoncpp-1.6.2.tar.gz jsoncpp-1.6.2 +cd .. + diff --git a/deps/install_jsonrpccpp.bat b/deps/install_jsonrpccpp.bat new file mode 100644 index 0000000000..272e458df3 --- /dev/null +++ b/deps/install_jsonrpccpp.bat @@ -0,0 +1,10 @@ +REM installing jsonrpccpp +cmake -E copy_directory package\jsonrpccpp install + +REM zipping jsonrpccpp +cd package +if exist json-rpc-cpp-0.5.0 cmake -E remove_directory json-rpc-cpp-0.5.0 +cmake -E rename jsonrpccpp json-rpc-cpp-0.5.0 +tar -zcvf json-rpc-cpp-0.5.0.tar.gz json-rpc-cpp-0.5.0 +cd .. + diff --git a/deps/install_leveldb.bat b/deps/install_leveldb.bat new file mode 100644 index 0000000000..b151ea0bb6 --- /dev/null +++ b/deps/install_leveldb.bat @@ -0,0 +1,10 @@ +REM installing leveldb +cmake -E copy_directory package\leveldb install + +REM zipping leveldb +cd package +if exist leveldb-1.2 cmake -E remove_directory leveldb-1.2 +cmake -E rename leveldb leveldb-1.2 +tar -zcvf leveldb-1.2.tar.gz leveldb-1.2 +cd .. + diff --git a/deps/install_microhttpd.bat b/deps/install_microhttpd.bat new file mode 100644 index 0000000000..b820eb7887 --- /dev/null +++ b/deps/install_microhttpd.bat @@ -0,0 +1,10 @@ +REM installing microhttpd +cmake -E copy_directory package\microhttpd install + +REM zipping microhttpd +cd package +if exist microhttpd-0.9.2 cmake -E remove_directory microhttpd-0.9.2 +cmake -E rename microhttpd microhttpd-0.9.2 +tar -zcvf microhttpd-0.9.2.tar.gz microhttpd-0.9.2 +cd .. + diff --git a/deps/install_miniupnpc.bat b/deps/install_miniupnpc.bat new file mode 100644 index 0000000000..5add79a512 --- /dev/null +++ b/deps/install_miniupnpc.bat @@ -0,0 +1,10 @@ +REM installing miniupnpc +cmake -E copy_directory package\miniupnpc install + +REM zipping miniupnpc +cd package +if exist miniupnpc-1.9 cmake -E remove_directory miniupnpc-1.9 +cmake -E rename miniupnpc miniupnpc-1.9 +tar -zcvf miniupnpc-1.9.tar.gz miniupnpc-1.9 +cd .. + diff --git a/deps/jsoncpp.cmake b/deps/jsoncpp.cmake new file mode 100644 index 0000000000..cb04ffe0b2 --- /dev/null +++ b/deps/jsoncpp.cmake @@ -0,0 +1,35 @@ +include(ExternalProject) + +if (${CMAKE_SYSTEM_NAME} STREQUAL "Emscripten") + set(JSONCPP_CMAKE_COMMAND emcmake cmake) +else() + set(JSONCPP_CMAKE_COMMAND ${CMAKE_COMMAND}) +endif() + +ExternalProject_Add(jsoncpp-project + PREFIX deps/jsoncpp + DOWNLOAD_NAME jsoncpp-1.7.7.tar.gz + DOWNLOAD_DIR ${CMAKE_CURRENT_LIST_DIR}/downloads + URL https://github.com/open-source-parsers/jsoncpp/archive/1.7.7.tar.gz + URL_HASH SHA256=087640ebcf7fbcfe8e2717a0b9528fff89c52fcf69fa2a18cc2b538008098f97 + CMAKE_COMMAND ${JSONCPP_CMAKE_COMMAND} + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX= + # Build static lib but suitable to be included in a shared lib. + -DCMAKE_POSITION_INDEPENDENT_CODE=On + -DJSONCPP_WITH_TESTS=Off + -DJSONCPP_WITH_PKGCONFIG_SUPPORT=Off + # Overwtire build and install commands to force Release build on MSVC. + BUILD_COMMAND cmake --build --config Release + INSTALL_COMMAND cmake --build --config Release --target install +) + +# Create jsoncpp imported library +ExternalProject_Get_Property(jsoncpp-project INSTALL_DIR) +add_library(jsoncpp STATIC IMPORTED) +set(JSONCPP_LIBRARY ${INSTALL_DIR}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}jsoncpp${CMAKE_STATIC_LIBRARY_SUFFIX}) +set(JSONCPP_INCLUDE_DIR ${INSTALL_DIR}/include) +file(MAKE_DIRECTORY ${JSONCPP_INCLUDE_DIR}) # Must exist. +set_property(TARGET jsoncpp PROPERTY IMPORTED_LOCATION ${JSONCPP_LIBRARY}) +set_property(TARGET jsoncpp PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${JSONCPP_INCLUDE_DIR}) +add_dependencies(jsoncpp jsoncpp-project) +unset(INSTALL_DIR) diff --git a/deps/jsonrpc.cmake b/deps/jsonrpc.cmake new file mode 100644 index 0000000000..10b20b9960 --- /dev/null +++ b/deps/jsonrpc.cmake @@ -0,0 +1,89 @@ +if (NOT TARGET jsoncpp-project) + # Include jsoncpp dependency if not included yet. + include(${CMAKE_CURRENT_LIST_DIR}/jsoncpp.cmake) +endif() + +# HTTP client from JSON RPC CPP requires curl library. It can find it itself, +# but we need to know the libcurl location for static linking. +find_package(CURL REQUIRED) + +# HTTP server from JSON RPC CPP requires microhttpd library. It can find it itself, +# but we need to know the MHD location for static linking. +find_package(MHD REQUIRED) + +set(CMAKE_ARGS -DCMAKE_INSTALL_PREFIX= + -DCMAKE_BUILD_TYPE=Release + # Build static lib but suitable to be included in a shared lib. + -DCMAKE_POSITION_INDEPENDENT_CODE=On + -DBUILD_STATIC_LIBS=On + -DBUILD_SHARED_LIBS=Off + -DUNIX_DOMAIN_SOCKET_SERVER=Off + -DUNIX_DOMAIN_SOCKET_CLIENT=Off + -DHTTP_SERVER=On + -DHTTP_CLIENT=On + -DCOMPILE_TESTS=Off + -DCOMPILE_STUBGEN=Off + -DCOMPILE_EXAMPLES=Off + # Point to jsoncpp library. + -DJSONCPP_INCLUDE_DIR=${JSONCPP_INCLUDE_DIR} + # Select jsoncpp include prefix: or + -DJSONCPP_INCLUDE_PREFIX=json + -DJSONCPP_LIBRARY=${JSONCPP_LIBRARY} + -DCURL_INCLUDE_DIR=${CURL_INCLUDE_DIR} + -DCURL_LIBRARY=${CURL_LIBRARY} + -DMHD_INCLUDE_DIR=${MHD_INCLUDE_DIR} + -DMHD_LIBRARY=${MHD_LIBRARY}) + +if (WIN32) + # For Windows we have to provide also locations for debug libraries. + set(CMAKE_ARGS ${CMAKE_ARGS} + -DJSONCPP_LIBRARY_DEBUG=${JSONCPP_LIBRARY} + -DCURL_LIBRARY_DEBUG=${CURL_LIBRARY} + -DMHD_LIBRARY_DEBUG=${MHD_LIBRARY}) +endif() + +ExternalProject_Add(jsonrpc-project + PREFIX deps/jsonrpc + URL https://github.com/cinemast/libjson-rpc-cpp/archive/v0.7.0.tar.gz + URL_HASH SHA256=669c2259909f11a8c196923a910f9a16a8225ecc14e6c30e2bcb712bab9097eb + # On Windows it tries to install this dir. Create it to prevent failure. + PATCH_COMMAND cmake -E make_directory /win32-deps/include + CMAKE_ARGS ${CMAKE_ARGS} + # Overwtire build and install commands to force Release build on MSVC. + BUILD_COMMAND cmake --build --config Release + INSTALL_COMMAND cmake --build --config Release --target install +) + +add_dependencies(jsonrpc-project jsoncpp-project) + +# Create jsonrpc imported libraries +if (WIN32) + # On Windows CMAKE_INSTALL_PREFIX is ignored and installs to dist dir. + ExternalProject_Get_Property(jsonrpc-project BINARY_DIR) + set(INSTALL_DIR ${BINARY_DIR}/dist) +else() + ExternalProject_Get_Property(jsonrpc-project INSTALL_DIR) +endif() +set(JSONRPC_INCLUDE_DIR ${INSTALL_DIR}/include) +file(MAKE_DIRECTORY ${JSONRPC_INCLUDE_DIR}) # Must exist. + +add_library(jsonrpc::common STATIC IMPORTED) +set_property(TARGET jsonrpc::common PROPERTY IMPORTED_LOCATION ${INSTALL_DIR}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}jsonrpccpp-common${CMAKE_STATIC_LIBRARY_SUFFIX}) +set_property(TARGET jsonrpc::common PROPERTY INTERFACE_LINK_LIBRARIES jsoncpp) +set_property(TARGET jsonrpc::common PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${JSONRPC_INCLUDE_DIR} ${JSONCPP_INCLUDE_DIR}) +add_dependencies(jsonrpc::common jsonrpc-project) + +add_library(jsonrpc::client STATIC IMPORTED) +set_property(TARGET jsonrpc::client PROPERTY IMPORTED_LOCATION ${INSTALL_DIR}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}jsonrpccpp-client${CMAKE_STATIC_LIBRARY_SUFFIX}) +set_property(TARGET jsonrpc::client PROPERTY INTERFACE_LINK_LIBRARIES jsonrpc::common ${CURL_LIBRARY}) +set_property(TARGET jsonrpc::client PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${CURL_INCLUDE_DIR}) +add_dependencies(jsonrpc::client jsonrpc-project) + +add_library(jsonrpc::server STATIC IMPORTED) +set_property(TARGET jsonrpc::server PROPERTY IMPORTED_LOCATION ${INSTALL_DIR}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}jsonrpccpp-server${CMAKE_STATIC_LIBRARY_SUFFIX}) +set_property(TARGET jsonrpc::server PROPERTY INTERFACE_LINK_LIBRARIES jsonrpc::common ${MHD_LIBRARY}) +set_property(TARGET jsonrpc::server PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${MHD_INCLUDE_DIR}) +add_dependencies(jsonrpc::server jsonrpc-project) + +unset(INSTALL_DIR) +unset(CMAKE_ARGS) diff --git a/deps/main.bat b/deps/main.bat new file mode 100644 index 0000000000..230967e722 --- /dev/null +++ b/deps/main.bat @@ -0,0 +1,79 @@ +REM call vcvarsall +call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" + +REM add MSBuild to env variable +set MSBuild="c:/Program Files (x86)/MSBuild/14.0/bin/msbuild.exe" + +REM add vcvars32.bat to PATH +@set PATH=c:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin;%PATH% + +REM create build, package && install directory +if not exist build mkdir build +if not exist package mkdir package +if not exist install mkdir install + +rem =========================================================================== +rem Layer 0 is Boost. +rem Absolutely everything depends on Boost, whether they use it or not, +rem because of EthDependencies.cmake in webthree-helper, which does an +rem unconditional find_module() for boost, irrespective of what is being built. + +rem =========================================================================== +rem Layer 1 are the external libraries. Do any of these themselves depend on +rem Boost? I think that the majority or indeed all of them *might not*, and +rem that if we fixed up the CMake code so that the unconditional Boost +rem dependency could be skipped then we could improve the build ordering here. + +call :setup x64 Debug & call build_cryptopp.bat & call bundle_cryptopp.bat || goto :error +call :setup x64 Release & call build_cryptopp.bat & call bundle_cryptopp.bat || goto :error +call install_cryptopp.bat || goto :error + +call :setup x64 Debug & call build_curl.bat & call bundle_curl.bat || goto :error +call :setup x64 Release & call build_curl.bat & call bundle_curl.bat || goto :error +call install_curl.bat || goto :error + +rem Is GMP not used for Windows? + +call :setup x64 Debug & call build_jsoncpp.bat & call bundle_jsoncpp.bat || goto :error +call :setup x64 Release & call build_jsoncpp.bat & call bundle_jsoncpp.bat || goto :error +call install_jsoncpp.bat || goto :error + +call :setup x64 Debug & call build_leveldb.bat & call bundle_leveldb.bat || goto :error +call :setup x64 Release & call build_leveldb.bat & call bundle_leveldb.bat || goto :error +call install_leveldb.bat || goto :error + +rem libscrypt needs building for crosseth. Why don't we need it here? + +call :setup x64 Debug & call build_microhttpd.bat & call bundle_microhttpd.bat || goto :error +call :setup x64 Release & call build_microhttpd.bat & call bundle_microhttpd.bat || goto :error +call install_microhttpd.bat || goto :error + +rem We don't build libminiupnpc for crosseth, so I'll have to guess on its layering for now. +call :setup x64 Debug & call build_miniupnpc.bat & call bundle_miniupnpc.bat || goto :error +call :setup x64 Release & call build_miniupnpc.bat & call bundle_miniupnpc.bat || goto :error +call install_miniupnpc.bat || goto :error + +rem =========================================================================== +rem Layer 2 comprises secp256k1 and libjson-rpc-cpp (which are external +rem libraries which depend on Layer 1 external libraries) + +call :setup x64 Debug & call build_jsonrpccpp.bat & call bundle_jsonrpccpp.bat || goto :error +call :setup x64 Release & call build_jsonrpccpp.bat & call bundle_jsonrpccpp.bat || goto :error +call install_jsonrpccpp.bat || goto :error + +rem secp256k1 needs building for crosseth. Why don't we need it here? + + +goto :EOF + +:setup +set PLATFORM=%1 +set CONFIGURATION=%2 + +goto :EOF + +:error +echo Failed with error %errorlevel% +exit /b %errorlevel% + +:EOF diff --git a/deps/scripts/build_boost.cmake b/deps/scripts/build_boost.cmake new file mode 100644 index 0000000000..8d6bef277e --- /dev/null +++ b/deps/scripts/build_boost.cmake @@ -0,0 +1,30 @@ +include("${CMAKE_CURRENT_LIST_DIR}/helpers.cmake") + +prepare_package_source(boost 1.61 http://sourceforge.net/projects/boost/files/boost/1.61.0/boost_1_61_0.tar.gz) + +if (NOT EXISTS ${SOURCE_DIR}/b2.exe) + execute_process(COMMAND bootstrap.bat WORKING_DIRECTORY ${SOURCE_DIR}) +endif() + +execute_process(COMMAND ./b2 -j4 + stage --stagedir=${INSTALL_DIR}/win64 --build-dir=${BUILD_DIR} + link=static + runtime-link=shared + variant=release + threading=multi + address-model=64 + --with-filesystem + --with-system + --with-thread + --with-date_time + --with-regex + --with-test + --with-program_options + --with-random + --with-atomic + WORKING_DIRECTORY ${SOURCE_DIR}) + +message("Copying boost headers") +file(COPY ${SOURCE_DIR}/boost DESTINATION ${INSTALL_DIR}/win64/include) + +create_package(${PACKAGE_NAME} ${INSTALL_DIR}) diff --git a/deps/scripts/build_llvm.cmake b/deps/scripts/build_llvm.cmake new file mode 100644 index 0000000000..d9ab6402ea --- /dev/null +++ b/deps/scripts/build_llvm.cmake @@ -0,0 +1,32 @@ +# This script downloads LLVM source and builds it with Visual Studio. + +include("${CMAKE_CURRENT_LIST_DIR}/helpers.cmake") + +function(build_llvm CONFIGURATION) + if (CONFIGURATION STREQUAL "Release") + set(ASSERTS OFF) + set(CONFIG "Release") + elseif (CONFIGURATION STREQUAL "Debug") + set(ASSERTS ON) + set(CONFIG "RelWithDebInfo") + else() + message(FATAL_ERROR "Wrong configuration") + endif() + set(INSTALL_DIR "${INSTALL_DIR}/win64/${CONFIGURATION}") + + execute_process(COMMAND cmake ${SOURCE_DIR} -G "Visual Studio 14 2015 Win64" + -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} + -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_TOOLS=OFF + -DLLVM_ENABLE_ASSERTIONS=${ASSERTS} + WORKING_DIRECTORY ${BUILD_DIR}) + + execute_process(COMMAND cmake --build ${BUILD_DIR} + --target install --config ${CONFIG}) +endfunction(build_llvm) + +prepare_package_source(llvm 3.8.0 http://llvm.org/releases/3.8.0/llvm-3.8.0.src.tar.xz) + +build_llvm("Release") +# build_llvm("Debug") + +create_package(${PACKAGE_NAME} ${INSTALL_DIR}) diff --git a/deps/scripts/build_opencl-icd-loader.cmake b/deps/scripts/build_opencl-icd-loader.cmake new file mode 100644 index 0000000000..bac679f64d --- /dev/null +++ b/deps/scripts/build_opencl-icd-loader.cmake @@ -0,0 +1,23 @@ +# This scirpt builds universal OpenCL ICD Loader that searches for OpenCL +# implementations at run-time. The package also includes OpenCL headers. + +include("${CMAKE_CURRENT_LIST_DIR}/helpers.cmake") + +prepare_package_source(opencl-icd-loader 0.0 https://github.com/KhronosGroup/OpenCL-ICD-Loader/archive/master/OpenCL-ICD-Loader.tar.gz) + +if (NOT EXISTS ${SOURCE_DIR}/inc/CL) + download_and_unpack(https://github.com/KhronosGroup/OpenCL-Headers/archive/master/OpenCL-Headers.tar.gz ${SOURCE_DIR} STATUS) + file(RENAME ${SOURCE_DIR}/OpenCL-Headers-master ${SOURCE_DIR}/inc/CL) +endif() + +execute_process(COMMAND cmake ${SOURCE_DIR} -G "Visual Studio 14 2015 Win64" + WORKING_DIRECTORY ${BUILD_DIR}) + +execute_process(COMMAND cmake --build ${BUILD_DIR} + --target OpenCL --config Release) + +file(COPY ${BUILD_DIR}/Release/OpenCl.lib DESTINATION ${INSTALL_DIR}/win64/lib/) +file(COPY ${BUILD_DIR}/bin/Release/OpenCl.dll DESTINATION ${INSTALL_DIR}/win64/bin/) +file(COPY ${SOURCE_DIR}/inc/CL DESTINATION ${INSTALL_DIR}/win64/include/) + +create_package(${PACKAGE_NAME} ${INSTALL_DIR}) diff --git a/deps/scripts/helpers.cmake b/deps/scripts/helpers.cmake new file mode 100644 index 0000000000..6b86a61b52 --- /dev/null +++ b/deps/scripts/helpers.cmake @@ -0,0 +1,90 @@ +get_filename_component(ROOT_DIR "${CMAKE_CURRENT_LIST_DIR}/.." ABSOLUTE) + +set(CACHE_DIR "${ROOT_DIR}/cache") +set(PACKAGES_DIR "${ROOT_DIR}/packages") + +function(download URL DST_FILE STATUS) + set(TMP_FILE "${DST_FILE}.part") + + get_filename_component(FILE_NAME ${DST_FILE} NAME) + if (NOT EXISTS ${DST_FILE}) + message("Downloading ${FILE_NAME}") + file(DOWNLOAD ${URL} ${TMP_FILE} SHOW_PROGRESS STATUS DOWNLOAD_STATUS) + list(GET DOWNLOAD_STATUS 0 STATUS_CODE) + if (STATUS_CODE EQUAL 0) + file(RENAME ${TMP_FILE} ${DST_FILE}) + else() + file(REMOVE ${TMP_FILE}) + list(GET DOWNLOAD_STATUS 1 ERROR_MSG) + + message("ERROR! Downloading '${FILE_NAME}' failed.") + message(STATUS "URL: ${URL}") + message(STATUS "Error: ${STATUS_CODE} ${ERROR_MSG}") + set(STATUS FALSE PARENT_SCOPE) + return() + endif() + else() + message("Using cached ${FILE_NAME}") + endif() + set(STATUS TRUE PARENT_SCOPE) +endfunction(download) + +function(download_and_unpack PACKAGE_URL DST_DIR) + get_filename_component(FILE_NAME ${PACKAGE_URL} NAME) + + set(DST_FILE "${CACHE_DIR}/${FILE_NAME}") + set(TMP_FILE "${DST_FILE}.part") + + file(MAKE_DIRECTORY ${CACHE_DIR}) + file(MAKE_DIRECTORY ${DST_DIR}) + + download(${PACKAGE_URL} ${DST_FILE} STATUS) + + if (STATUS) + message("Unpacking ${FILE_NAME} to ${DST_DIR}") + execute_process(COMMAND ${CMAKE_COMMAND} -E tar -xf ${DST_FILE} + WORKING_DIRECTORY ${DST_DIR}) + endif() +endfunction(download_and_unpack) + +# Packs installed package binaries and headers into an archive. +function(create_package NAME DIR) + message("Creating package ${NAME}") + file(MAKE_DIRECTORY ${PACKAGES_DIR}) + + # To create an archive without addicional top level directory + # (like package-X.Y.Z) we need to know all top level files/dirs. + # Usually it is just "win64" dir. + file(GLOB TOP_FILES RELATIVE ${DIR} "${DIR}/*") + + set(PACKAGE_FILE "${PACKAGES_DIR}/${NAME}.tar.gz") + execute_process(COMMAND ${CMAKE_COMMAND} -E + tar -czf ${PACKAGE_FILE} ${TOP_FILES} + WORKING_DIRECTORY ${DIR}) +endfunction(create_package) + +# Downloads the source code of the package and unpacks it to dedicated 'src' +# dir. Also creates 'build' and 'install' dir to be used by a build script. +function(prepare_package_source NAME VERSION URL) + set(PACKAGE_NAME "${NAME}-${VERSION}") + + set(PACKAGE_DIR "${CACHE_DIR}/${PACKAGE_NAME}") + set(SOURCE_DIR "${PACKAGE_DIR}/src") + set(BUILD_DIR "${PACKAGE_DIR}/build") + set(INSTALL_DIR "${PACKAGE_DIR}/install") + + if (NOT EXISTS ${SOURCE_DIR}) + download_and_unpack(${URL} ${PACKAGE_DIR} STATUS) + file(GLOB ORIG_SOURCE_DIR_NAME "${PACKAGE_DIR}/*") + file(RENAME ${ORIG_SOURCE_DIR_NAME} ${SOURCE_DIR}) + endif() + + file(MAKE_DIRECTORY ${BUILD_DIR}) + file(MAKE_DIRECTORY ${INSTALL_DIR}) + + # Export names and dirs to be used by a package-specific build script. + set(PACKAGE_NAME ${PACKAGE_NAME} PARENT_SCOPE) + set(SOURCE_DIR ${SOURCE_DIR} PARENT_SCOPE) + set(BUILD_DIR ${BUILD_DIR} PARENT_SCOPE) + set(INSTALL_DIR ${INSTALL_DIR} PARENT_SCOPE) +endfunction() diff --git a/doc/BCOS_Whitepaper.pdf b/doc/BCOS_Whitepaper.pdf new file mode 100644 index 0000000000..73e7127868 Binary files /dev/null and b/doc/BCOS_Whitepaper.pdf differ diff --git a/doc/manual/images/i10.1.jpg b/doc/manual/images/i10.1.jpg new file mode 100644 index 0000000000..0022d95739 Binary files /dev/null and b/doc/manual/images/i10.1.jpg differ diff --git a/doc/manual/images/i2.1.png b/doc/manual/images/i2.1.png new file mode 100644 index 0000000000..efa09a50d3 Binary files /dev/null and b/doc/manual/images/i2.1.png differ diff --git a/doc/manual/images/i3.1.png b/doc/manual/images/i3.1.png new file mode 100644 index 0000000000..970853baa6 Binary files /dev/null and b/doc/manual/images/i3.1.png differ diff --git a/doc/manual/images/i3.2.png b/doc/manual/images/i3.2.png new file mode 100644 index 0000000000..429b579b48 Binary files /dev/null and b/doc/manual/images/i3.2.png differ diff --git a/doc/manual/images/i4.1.png b/doc/manual/images/i4.1.png new file mode 100644 index 0000000000..413860ab1c Binary files /dev/null and b/doc/manual/images/i4.1.png differ diff --git a/doc/manual/images/i5.1.png b/doc/manual/images/i5.1.png new file mode 100644 index 0000000000..78c70dbc36 Binary files /dev/null and b/doc/manual/images/i5.1.png differ diff --git a/doc/manual/images/i6.1.png b/doc/manual/images/i6.1.png new file mode 100644 index 0000000000..90a29a5dd5 Binary files /dev/null and b/doc/manual/images/i6.1.png differ diff --git a/doc/manual/images/i6.2.png b/doc/manual/images/i6.2.png new file mode 100644 index 0000000000..28553100a7 Binary files /dev/null and b/doc/manual/images/i6.2.png differ diff --git a/doc/manual/images/i6.3.png b/doc/manual/images/i6.3.png new file mode 100644 index 0000000000..8dab523e6f Binary files /dev/null and b/doc/manual/images/i6.3.png differ diff --git a/doc/manual/images/i6.4.png b/doc/manual/images/i6.4.png new file mode 100644 index 0000000000..baab4d03c2 Binary files /dev/null and b/doc/manual/images/i6.4.png differ diff --git a/doc/manual/images/i6.5.png b/doc/manual/images/i6.5.png new file mode 100644 index 0000000000..8531883861 Binary files /dev/null and b/doc/manual/images/i6.5.png differ diff --git a/doc/manual/images/i7.1.png b/doc/manual/images/i7.1.png new file mode 100644 index 0000000000..e69195b5a6 Binary files /dev/null and b/doc/manual/images/i7.1.png differ diff --git a/doc/manual/images/i7.2.png b/doc/manual/images/i7.2.png new file mode 100644 index 0000000000..e7a8207341 Binary files /dev/null and b/doc/manual/images/i7.2.png differ diff --git a/doc/manual/images/i7.3.png b/doc/manual/images/i7.3.png new file mode 100644 index 0000000000..b1ac536000 Binary files /dev/null and b/doc/manual/images/i7.3.png differ diff --git a/doc/manual/images/i7.4.png b/doc/manual/images/i7.4.png new file mode 100644 index 0000000000..2ec573a9c6 Binary files /dev/null and b/doc/manual/images/i7.4.png differ diff --git a/doc/manual/images/i7.5.png b/doc/manual/images/i7.5.png new file mode 100644 index 0000000000..1e50d6088a Binary files /dev/null and b/doc/manual/images/i7.5.png differ diff --git a/doc/manual/images/i7.6.png b/doc/manual/images/i7.6.png new file mode 100644 index 0000000000..11f49e9f39 Binary files /dev/null and b/doc/manual/images/i7.6.png differ diff --git a/doc/manual/images/i7.7.png b/doc/manual/images/i7.7.png new file mode 100644 index 0000000000..412d79651e Binary files /dev/null and b/doc/manual/images/i7.7.png differ diff --git a/doc/manual/images/i8.png b/doc/manual/images/i8.png new file mode 100644 index 0000000000..151463c982 Binary files /dev/null and b/doc/manual/images/i8.png differ diff --git a/doc/manual/images/i9.1.png b/doc/manual/images/i9.1.png new file mode 100644 index 0000000000..0d336237e5 Binary files /dev/null and b/doc/manual/images/i9.1.png differ diff --git a/doc/manual/manual.md b/doc/manual/manual.md new file mode 100644 index 0000000000..d6df0ace80 --- /dev/null +++ b/doc/manual/manual.md @@ -0,0 +1,1490 @@ +# 前言 + +本文档是BCOS区块链开源平台的一部分。 +BCOS区块链开源平台由深圳前海微众银行股份有限公司、万向区块链实验室和矩阵元Juzix共同发起。 +本文档面向读者是了解区块链基本概念的区块链技术开发人员、测试人员、产品经理、区块链爱好者、金融行业从业者等等。 + +为了让大家更好的了解BCOS区块链开源平台的使用方法。本文档按照Step By Step的步骤详细介绍了BCOS区块链的构建、安装、启动,智能合约部署、调用等初阶用法,还包括多节点组网、系统合约等高阶内容的介绍。 + +本文档不介绍BCOS区块链设计理念及思路,详情请参看白皮书。 + +# 第一章、搭建BCOS区块链环境 +本章主要介绍运行BCOS区块链执行程序所需要的软硬件环境、以及从源码编译的环境准备和编译步骤。 + +## 1.1硬件环境 + +| 配置 | 最低配置 | 推荐配置 | +|-------- |----------|---------| +|CPU |1.5GHz |2.4GHz| +|内存 |512MB |2GB| +|核心 |1核 |2核| +|带宽 |512Kb |1Mb| +|操作系统| |Ubuntu(16.04 64位)/CentOS (7.2 64位)| + + +以下代码及操作命令以在Centos操作系统上为示例。 + +## 1.2软件环境 + +① 安装nodejs(安装后版本nodejs版本大于6)、babel-node环境 +```bash +sudo yum install nodejs +sudo npm config set registry https://registry.npm.taobao.org +sudo npm install -g babel-cli babel-preset-es2017 +echo '{ "presets": ["es2017"] }' > ~/.babelrc +``` + +② 安装智能合约solidity编译器 +方式一:直接下载solc二进制执行程序 +```bash +wget https://github.com/ethereum/solidity/releases/download/v0.4.11/solc-static-linux +sudo cp solc-static-linux /usr/bin/solc +sudo chmod +x /usr/bin/solc +``` + +方式二: +从 [https://github.com/ethereum/solidity/releases](https://github.com/ethereum/solidity/releases) 上获取安装包自行安装 + +③ 安装控制台 +```bash +sudo yum install git +sudo npm install -g ethereum-console +``` + +## 1.3源码编译 + +### 1.3.1获取源代码 + +```bash +git clone https://github.com/bcosorg/bcos.git +``` + +### 1.3.2目录结构说明 + +|目录| 说明| +|---|---| +|eth | 主入口目录,其中main.cpp包含main函数入口 +|libdevcore |基础通用组件实现目录,如工具类函数、基础数据类型结构定义、IO操作函数、读写锁、内存DB、TrieDB、SHA3实现、RLP编解码实现、Worker模型等等 +|libethcore |区块链核心数据结构目录。如ABI、秘钥管理、区块头、预编译、交易结构等等 +|libethereum |区块链主框架逻辑目录。如交易池、系统合约、节点管理、块链、块、链参数等等 +|libevm |虚拟机主目录。如解释器、JIT等等 +|libevmcore |OPCODE指令集定义、定价 +|libp2p |区块链P2P网络主目录。如握手、网络包编解码、会话管理等等 +|libpbftseal| PBFT共识插件实现目录 +|libraftseal| RAFT共识插件实现目录 +|libweb3jsonrpc| web3 RPC实现目录 +|systemproxyv2 |系统合约实现目录 +|tool |工具脚本目录 + +### 1.3.3编译前准备 + +① 检查cmake 版本(cmake3 --version 必须>3.4.3) +如果版本不满足要求,需要升级。 +方式一:从源升级 +```bash +sudo yum -y install cmake3 +``` +方式二:到官网https://cmake.org/download/ 下载最新版本安装。 + +② 安装依赖的开发库 + +```bash +sudo yum install openssl openssl-devel +chmod +x scripts/install_deps.sh +./scripts/install_deps.sh +``` + +#### 1.3.4编译可执行程序 +```bash +mkdir -p build +cd build/ +cmake -DEVMJIT=OFF -DTESTS=OFF -DMINIUPNPC=OFF .. #注意命令末尾的.. +make -j2 +``` + +编译成功,eth/eth 即是区块链可执行程序。 + +# 第二章、启动创世节点 + +区块链节点的启动有两个必选参数。一个是创世块文件,另一个是运行参数配置文件。 + +其中创世块文件包含内置管理员账号,需要启动前提前生成。 +其中运行参数配置文件包含节点身份NodeId,需要启动前提前生成。 + +本章开始先介绍程序启动所需的创世块文件、配置文件、日志配置文件的字段含义。接着介绍NodeId的生成方法和管理员外部账号公私钥对的生成方法,及创世块文件、配置文件、日志配置文件的样例。 +最后介绍启动创世节点的命令方法。 + +## 2.1.创世块文件genesis.json说明 +创世块文件是对区块链第一个块的描述。是唯一的,不可变更的。 +它是节点启动的一个必选参数。 + + +源码目录下有示例创世块文件genesis.json,可以根据需要进行修改,关键字段说明如下: + +|配置项 |说明| +|----|----| +|timestamp| 创世块时间戳(毫秒)| +|god| 内置链管理员账号地址(生成方法可参看生成公私钥对)| +|alloc |内置合约数据| +|initMinerNodes |创世块节点NodeId(生成方法可参看生成NodeId)| + +在 多节点组网 章节之前,只需要变更god、initMinerNodes字段,其他保持默认即可。 + +## 2.2.运行参数配置文件config.json说明 + +配置文件是对区块链运行时参数的设置。配置值可变更,重启时生效。 +它是节点启动的一个必选参数。 + +源码目录下有示例创世块文件config.json,可以根据需要进行修改,关键字段说明如下: + +|配置项 |说明| +|----|----| +|sealEngine |共识算法(可选PBFT、RAFT、SinglePoint) +|systemproxyaddress |系统路由合约地址(生成方法可参看部署系统合约) +|listenip |监听IP(建议内网IP) +|rpcport |RPC监听端口)(若在同台机器上部署多个节点时,端口不能重复) +|p2pport| P2P网络监听端口(若在同台机器上部署多个节点时,端口不能重复) +|wallet |钱包文件路径 +|keystoredir| 账号文件目录路径 +|datadir| 节点数据目录路径 +|vm| vm引擎 (默认 interpreter ) +|networkid| 网络ID +|logverbosity| 日志级别(级别越高日志越详细,>8 TRACE日志,4<=x<8 DEBU G日志,<4 INFO日志) +|coverlog |覆盖率插件开关(ON或OFF) +|eventlog| 合约日志开关(ON或OFF) +|logconf| 日志配置文件路径(日志配置文件可参看日志配置文件说明) +|NodeextraInfo| 节点连接配置列表[{NodeId,Ip,port,nodedesc,agencyinfo,identitytype}]( 节点ID、外网IP、P2P网络端口、节点描述、节点信息、节点类型) +|dfsNode |分布式文件服务节点ID ,与节点身份NodeID一致 (可选功能配置参数) +|dfsGroup |分布式文件服务组ID (10 - 32个字符)(可选功能配置参数) +|dfsStorage| 指定分布式文件系统所使用文件存储目录(可选功能配置参数) + +在 多节点组网 章节之前,只需要更新rpcport、p2pport、wallet、keystoredir、datadir、NodeextraInfo字段,其他保持默认即可。 + +在接下来的说明中,假设节点数据目录(注意当前用户对目录需要有写入权限)路径为/mydata/nodedata-1/。 + +## 2.3.日志配置文件log.conf说明 +日志配置文件是对区块链运行过程日志输出的设置。配置值可变更,重启时生效。 + +其中log.conf的关键字段说明如下: + +|配置项 |说明| +|----|----| +|FORMAT| 日志格式,典型如%level|%datetime{%Y-%M-%d %H:%m:%s}|%msg +|FILENAME |日志文件输出的文件路径典型如/mydata/nodedata-1/log/log_%datetime{%Y%M%d%H}.log +|MAX_LOG_FILE_SIZE| 最大日志文件大小 +|LOG_FLUSH_THRESHOLD |超过多少条日志即可落盘 + +详细示例看参看创世块文件、运行参数配置文件、日志配置文件示例 + +## 2.4.生成节点身份NodeId +节点身份NodeId是一个公钥,代表节点的唯一身份标识。 +``` +./build/eth/eth --gennetworkrlp /mydata/nodedata-1/network.rlp +``` +将在/mydata/nodedata-1/ 目录下生成两个文件 network.rlp 和 network.rlp.pub。 +network.rlp是节点身份的私钥二进制文件。 +network.rlp.pub是节点身份的NodeId文件。 + +读取network.rlp.pub 将其更新到创世块文件genesis.json的initMinerNodes字段及 config.json中的NodeextraInfo字段,同时更新NodeextraInfo中的Nodedesc、 Agencyinfo、Peerip、Port为对应值。(Peerip为外网IP,Port为P2P网络监听端口) +## 2.5.生成管理员公私钥对 + +管理员公钥代表着对区块链的管理权限,生成的公钥和私钥是一一对应的,私钥代表着对公钥的所有权,私钥应妥善保管。 + +```bash +cd tool +node accountManager.js +``` + +将公钥address更新到创世块文件genesis.json的god字段。 + +## 2.6.创世块文件、运行参数配置文件、日志配置文件示例 +创世块文件示例如下: +```json +{ + "nonce": "0x0", + "difficulty": "0x0", + "mixhash": "0x0", + "coinbase": "0x0", + "timestamp": "0x0", + "parentHash": "0x0", + "extraData": "0x0", + "gasLimit": "0x13880000000000", + "god":"0x4d23de3297034cdd4a58db35f659a9b61fc7577b", + "alloc": {}, + "initMinerNodes":["de0fa385816b505799433e54b88788e21cb42092a6ff5bcaa2285d7ace906e5e6ce8ef2b30134ff276a5834d58721291acc5864e07e6d52469b79b28e699dfde"] +} +``` + +运行参数配置文件示例如下: +```json +{ + "sealEngine": "PBFT", + "systemproxyaddress":"0x0", + "listenip":"127.0.0.1", + "rpcport": "8545", + "p2pport": "30303", + "wallet":"/mydata/nodedata-1/keys.info", + "keystoredir":"/mydata/nodedata-1/keystore/", + "datadir":"/mydata/nodedata-1/", + "vm":"interpreter", + "networkid":"12345", + "logverbosity":"4", + "coverlog":"OFF", + "eventlog":"ON", + "logconf":"/mydata/nodedata-1/log.conf", + "params": { + "accountStartNonce": "0x0", + "maximumExtraDataSize": "0x0", + "tieBreakingGas": false, + "blockReward": "0x0", + "networkID" : "0x0" + }, + "NodeextraInfo":[ + { + "Nodeid":"de0fa385816b505799433e54b88788e21cb42092a6ff5bcaa2285d7ace906e5e6ce8ef2b30134ff276a5834d58721291acc5864e07e6d52469b79b28e699dfde", + "Nodedesc": "node1", + "Agencyinfo": "node1", + "Peerip": "127.0.0.1", + "Identitytype": 1, + "Port":30303, + "Idx":0 + } + ] +} +``` + +日志配置文件示例如下: +```bash +* GLOBAL: + ENABLED = true + TO_FILE = true + TO_STANDARD_OUTPUT = false + FORMAT = "%level|%datetime{%Y-%M-%d %H:%m:%s}|%msg" + FILENAME = "/mydata/nodedata-1/log/log_%datetime{%Y%M%d%H}.log" + MILLISECONDS_WIDTH = 3 + PERFORMANCE_TRACKING = false + MAX_LOG_FILE_SIZE = 209715200 ## 200MB - Comment starts with two hashes (##) + LOG_FLUSH_THRESHOLD = 100 ## Flush after every 100 logs + +* TRACE: + FILENAME = "/mydata/nodedata-1/log/trace_log_%datetime{%Y%M%d%H}.log" + +* DEBUG: + FILENAME = "/mydata/nodedata-1/log/debug_log_%datetime{%Y%M%d%H}.log" + FORMAT = "%level|%datetime|%file|%func|%line|%msg" + +* FATAL: + ENABLED = false + +* ERROR: + FILENAME = "/mydata/nodedata-1/log/error_log_%datetime{%Y%M%d%H}.log" + +* WARNING: + ENABLED = false + +* INFO: + FILENAME = "/mydata/nodedata-1/log/info_log_%datetime{%Y%M%d%H}.log" + +* VERBOSE: + ENABLED = false + +``` +## 2.7.创世节点启动 +命令行:区块链执行程序路径 --genesis 创世块文件 --config 配置文件 + +``` ./build/eth/eth --genesis ./genesis.json --config ./config.json & ``` + +查看日志是否正常出块 + +``` tail -f /mydata/nodedata-1/log/info* | grep Report ``` + +日志示例如下: + +![log example](./images/i2.1.png) + +日志中每行blk=563 都在正常增长,即是在正常出块。 + +至此,一个完整的区块链节点已经跑起来了! +# 第三章、开发说明 + +## 3.1 日志输出接口使用说明 +区块链运行日志文件都位于 日志配置文件说明 config.json所配置的log.conf 所指路径下。 +各个级别日志都有各自的日志文件。如TRACE日志写到trace_开头对应的文件中。 +其中TRACE日志为全量日志、INFO日志为关键信息、DEBUG为调试信息。 +查看区块链主线程日志可执行: +```bash +tail -f /mydata/nodedata-1/log/trace_log* | grep "|eth" +``` +输出示例图如下: + +![示例输出](./images/i3.2.png) + +日志输出的”Imported and best 3721” 代表块3721已经上链。 + +## 3.2 分布式文件系统使用说明 + +### 3.2.1 搭建服务节点群 + +1.参照多节点组网章节,进行多节点组网,并部署系统合约;系统合约部署成功以后将输出系统代理合约(SystemProxy)、FileInfoManager和FileServerManager三个合约地址, 示例输出如下: + +![系统合约部署][systemContract] + +2.配置config.json文件中的dfsGroup,dfsNode,dfsStorage三个参数,并更新systemproxyaddress参数为上一步得到的系统代理合约地址,具体参数定义请参看参数配置文件章节;在群组和节点的关系定义上,通常一个节点只允许加入一个群组,多个节点如果配置一样的群组ID,节点启动以后将加入到同一个群组当中,反之亦然。 + +3.重启群组所有节点即可用启动DFS服务。DFS服务启动后,即可以通过JAVA SDK提供的方法进行文件存取操作。 + +### 3.2.2使用说明 +JAVA SDK提供的接口功能包括文件上传,文件删除,文件下载,查询文件服务节点,添加服务节点,删除服务节点等。所提供接口为异步回调节接口,用户需要自定义回调监听处理类。SDK的核心类为DfsEngine,位于仓库的tool/java目录,为eclipse工程,依赖于同级目录的web3j项目。 + +#### 3.2.2.1接口说明 +##### (1). 初始化服务 + +- 接口名称:init +- 接口功能说明:初始化服务 +- 参数说明 + +|输入参数|参数类型|参数说明| +|:-----|:-----|:-----| +|host|String|主机地址| +|port|int|JSONRPC端口| +|listener|IJuListener|监听回调接口| +|walletPasswd|String|加密口令| +|walletFile|String|钱包文件| +|fileContract|String|文件合约地址| +|serverContract|String|文件服务合约地址| +|**输出参数**|**参数说明**|**参数说明**| +|返回值|int|0 :成功 其他:失败| + +##### (2). 添加服务节点(所有启动的节点都需要添加) + +- 接口名称:addServer +- 接口功能说明:添加服务节点 +- 参数说明 + +|输入参数|参数类型|参数说明| +|:-----|:-----|:-----| +|newServer|FileServer|分布式文件服务节点| +|**输出参数**|**参数类型**|**参数说明**| +|返回值|int|0 :成功 其他:失败| + +- 接口名称:addServerCallback +- 接口功能说明:添加文件服务节点对应回调接口(即注册监听器回调函数) +- 参数说明 + +|输入参数|参数类型|参数说明| +|:-----|:-----|:-----| +|server|FileInfo |文件信息| +|ret|int|返回值| +|**输出参数**|**参数类型**|**参数说明**| +|NA|NA|NA| + + +##### (3). 文件类操作类接口 + +###### a. 上传文件 + +- 接口名称:uploadFile +- 接口功能说明:上传文件 +- 参数说明 + +|输入参数|参数类型|参数说明| +|:-----|:-----|:-----| +|fileInfo|FileInfo |文件信息| +|file|String |文件路径| +|**输出参数**|**参数类型**|**参数说明**| +|返回值|int|0 :成功 其他:失败| + +- 接口名称:uploadFileCallback +- 接口功能说明:上传文件对应回调接口(即注册监听器回调函数) +- 参数说明 + +|输入参数|参数类型|参数说明| +|:-----|:-----|:-----| +|fileInfo|FileInfo|文件信息| +|ret|int|返回值| +|**输出参数**|**参数类型**|**参数说明**| +|NA|NA|NA| + +###### b. 下载文件 + +- 接口名称:downloadFile +- 接口功能说明:下载文件 +- 参数说明 + +|输入参数|参数类型|参数说明| +|:-----|:-----|:-----| +|fileServer|FileServer|文件服务节点信息| +|fileid|String |文件ID| +|store_path|String |文件存储完整路径| +|ret|int|返回值| +|**输出参数**|**参数类型**|**参数说明**| +|NA|NA|NA| + + +- 接口名称:downloadFileCallback +- 接口功能说明:下载文件对应回调接口(即注册监听器回调函数) +- 参数说明 + +|输入参数|参数类型|参数说明| +|:-----|:-----|:-----| +|fileInfo|FileInfo|文件信息| +|ret|int|返回值| +|**输出参数**|**参数类型**|**参数说明**| +|NA|NA|NA| + +###### c. 删除文件 + +- 接口名称:deleteFile +- 接口功能说明:删除文件 +- 参数说明 + +|输入参数|参数类型|参数说明| +|:-----|:-----|:-----| +|fileServer|FileServer|文件服务节点信息| +|fileid|String |文件ID| +|**输出参数**|**参数类型**|**参数说明**| +|返回值|int|0 :成功 其他:失败| + +- 接口名称:deleteFileCallback +- 接口功能说明:删除文件对应回调接口(即注册监听器回调函数) +- 参数说明 + +|输入参数|参数类型|参数说明| +|:-----|:-----|:-----| +|fileInfo|FileInfo|文件信息| +|ret|int|返回值| +|**输出参数**|**参数类型**|**参数说明**| +|NA|NA|NA| + +##### (4). 文件服务器信息节点操作类接口 + +###### a. 添加文件服务器节点 + +- 接口名称:addServer +- 接口功能说明:添加文件服务器节点 +- 参数说明 + +|输入参数|参数类型|参数说明| +|:-----|:-----|:-----| +|fileServer|FileServer|文件服务节点信息| +|**输出参数**|**参数类型**|**参数说明**| +|返回值|int|0 :成功 其他:失败| + +- 接口名称:addServerCallback +- 接口功能说明:添加文件服务器节点对应回调接口(即注册监听器回调函数) +- 参数说明 + +|输入参数|参数类型|参数说明| +|:-----|:-----|:-----| +|server|FileInfo |文件信息| +|ret|int|返回值| +|**输出参数**|**参数类型**|**参数说明**| +|NA|NA|NA| + + +- 接口名称:addServer +- 接口功能说明:添加文件服务器节点 +- 参数说明 + +|输入参数|参数类型|参数说明| +|:-----|:-----|:-----| +|server|FileServer|文件服务节点信息| +|ret|int|返回值| +|**输出参数**|**参数类型**|**参数说明**| +|NA|NA|NA| + +###### b. 删除文件服务器节点 + +- 接口名称:deleteServer +- 接口功能说明:删除文件服务器节点 +- 参数说明 + +|输入参数|参数类型|参数说明| +|:-----|:-----|:-----| +|serverid|String |文件服务节点ID| +|**输出参数**|**参数类型**|**参数说明**| +|返回值|int|0 :成功 其他:失败| + +- 接口名称:deleteServerCallback +- 接口功能说明:删除文件服务器节点对应回调接口(即注册监听器回调函数) +- 参数说明 + +|输入参数|参数类型|参数说明| +|:-----|:-----|:-----| +|server|FileServer |文件服务节点信息| +|ret|int|返回值| +|**输出参数**|**参数类型**|**参数说明**| +|NA|NA|NA| + +###### c. 查询文件服务器节点列表 + +- 接口名称:listServers +- 接口功能说明:获取文件服务节点列表 +- 参数说明 + +|输入参数|参数类型|参数说明| +|:-----|:-----|:-----| +|NA|NA|NA| +|**输出参数**|**参数类型**|**参数说明**| +|返回值|int|0 :成功 其他:失败| + +- 接口名称:listServersCallback +- 接口功能说明:获取文件服务节点列表对应回调接口(即注册监听器回调函数) +- 参数说明 + +|输入参数|参数类型|参数说明| +|:-----|:-----|:-----| +|fileservers|Vector|文件服务节点信息| +|ret|int|返回值| +|**输出参数**|**参数类型**|**参数说明**| +|NA|NA|NA| + +###### d. 按组查询文件服务器节点信息列表 + +- 接口名称:listFilesByGroup +- 接口功能说明:按节点群组列举出所有文件信息 +- 参数说明 + +|输入参数|参数类型|参数说明| +|:-----|:-----|:-----| +|group|String |服务节点群ID| +|**输出参数**|**参数类型**|**参数说明**| +|返回值|int|0 :成功 其他:失败| + +- 接口名称:listServersByGroupCallback +- 接口功能说明:按节点群组列举出所有文件信息对应回调接口(即注册监听器回调函数) +- 参数说明 + +|输入参数|参数类型|参数说明| +|:-----|:-----|:-----| +|fileservers|Vector|文件信息列表| +|ret|int|返回值| +|**输出参数**|**参数类型**|**参数说明**| +|NA|NA|NA| + +###### e. 操作异常或错误下的回调接口 + +- 接口名称:errorCallback +- 接口功能说明:按节点群组列举出所有文件信息 +- 参数说明 + +|输入参数|参数类型|参数说明| +|:-----|:-----|:-----| +|code|int |错误码| +|error|String |错误信息| +|**输出参数**|**参数类型**|**参数说明**| +|NA|NA|NA| + +#### 3.2.2.2使用举例 +下面是一个完整展示如何使用分布式文件存储和访问功能的实例。示例代码可以参看源码工程,源代码具体位置为com.sample包的HelloDfs类。 + +1.定义回调监听类 + +```cpp +public class HelloListener implements IDfsListener{ +//回调接口实现 +... +... +} +``` +2.初始化SDK + +```cpp +String walletPassword = "1111";//钱包口令 +String keyPath = "E:\\keys\\2429feaf-0e46-ddd5-5b72-0594e0a4ab00.json";//钱包文件 +String fileContract = "0x9e86c1b4c4d82607298faac27da7d78364434c58";//文件信息合约地址 +String fileServerContract = "0x0d76426479e438fe0d261dbb165cd3adcc4a1dd7";//文件服务合约地址 +Strign host = "10.10.8.232";//服务节点主机 +int port = 8545;//JSONRPC端口 +init(host, port, TestListener, walletPassword, keyPath, fileContract, fileServerContract);//初始化 +``` + +3.添加文件服务节点 + +```cpp +FileServer fileServer = new FileServer(); +fileServer.setGroup("group1"); +fileServer.setId("0c1585a170e75c14564427f2faa8d74850c65765a10ce9aa4fcc55c7cdd60ab7768dd7fa066145d0ebada2214705fca7f464186e61ea163a18e6ebb9c99c7627"); +fileServer.setHost("10.10.8.232"); +fileServer.setPort(8545); +fileServer.setInfo("the master node"); +fileServer.setOrganization("weiwan"); +fileServer.setEnable(1); +Calendar calendar = Calendar.getInstance(); +fileServer.setUpdateTime((int)calendar.getTime().getTime()/1000); +addServer(fileServer);//添加文件服务节点,等待回调add_server_back成功 +``` + +4.上传文件 + +```cpp +FileInfo fileInfo = new FileInfo(); +fileInfo.setOwner("weiwan"); +fileInfo.setPriviliges("rwx"); +String file = "E:"+ File.separatorChar + "test.txt"; +uploadFile(fileInfo, file);//上传文件,等待回调upload_file_back +//...回调成功 +//回调返回文件ID,可以使用文件ID下载和操作文件 +//另外在配置文件目录,可以查看文件 +``` + +## 3.3 加法同态接口使用说明 +对本版本所提供的加法同态运算功能,提供如下使用说明: +1.Java的API实现的同态加密算法,可以完成对需要运算的数据完成加解密操作,相关的代码工程路径为:{git_root}\tool\java\Pailler; + +2.Solidity合约语言提供一个Library,实现对两个加密后数据实现加法同态运算,相关的合约路径为:{git_root}\systemcontractv2\LibPaillier.sol; + +3.提供C语言同态加法算法实现,最终开放接口为智能合约同态加法运算API,相关代码路径为:{git_root}\libpailler; + +4.扩展VM中的sha3指令用以支持合约与C代码底层能力的桥接和适配,相关代码路径为:{git_root}\libevm. + +### 3.3.1 Java API说明 + +#### 3.3.1.1. 同态密钥管理对象(PaillierKeyPair) + +- 接口名称:generateKeyPair +- 接口功能说明:生成同态加密的密钥对 +- 参数说明 + +|输入参数|参数类型|参数说明| +|:-----|:-----|:-----| +|||| +|**输出参数**|**参数类型**|**参数说明**| +|返回值|KeyPair|生成的密钥对 (其他 :成功 null:失败)| + +#### 3.3.1.2. 同态算法对象(PaillierCipher) + +- 接口名称:encryption +- 接口功能说明:对数据进行同态加密 +- 参数说明 + +|输入参数|参数类型|参数说明| +|:-----|:-----|:-----| +|m|BigInteger|待加密的操作数| +|publickey|PublicKey|加密公钥,可以使用同态密钥管理对象获取| +|**输出参数**|**参数类型**|**参数说明**| +|返回值|String|加密后的输出 (其他 :成功 null:失败)| + +- 接口名称:decryption +- 接口功能说明:对加密数据进行解密还原操作数 +- 参数说明 + +|输入参数|参数类型|参数说明| +|:-----|:-----|:-----| +|||| +|**输出参数**|**参数类型**|**参数说明**| +|返回值||| + +- 接口名称:encryption +- 接口功能说明:对数据进行同态加密 +- 参数说明 + +|输入参数|参数类型|参数说明| +|:-----|:-----|:-----| +|ciphertext|String|加密的密文数据| +|privateKey|PrivateKey|加密公钥对应的私钥,可以使用同态密钥管理对象获取| +|**输出参数**|**参数类型**|**参数说明**| +|返回值|BigInteger|加密后的操作数 (其他 :成功 null:失败)| + +- 接口名称:ciphertextAdd +- 接口功能说明:加法同态实现 +- 参数说明 + +|输入参数|参数类型|参数说明| +|:-----|:-----|:-----| +|Ciphertext1|String|同态加密后的操作数1| +|Ciphertext2|String|同态加密后的操作数2| +|**输出参数**|**参数类型**|**参数说明**| +|返回值|String|加法同态后的结果数 (其他 :成功 null:失败) | + +#### 3.3.1.3. 使用样例 + +``` +// generate the key pair for encrypt and decrypt +KeyPair keypair = PaillierKeyPair.generateKeyPair(); +RSAPublicKey pubKey = (RSAPublicKey)keypair.getPublic(); +RSAPrivateKey priKey = (RSAPrivateKey)keypair.getPrivate(); + +// encrypt the first number with public key +BigInteger i1 = BigInteger.valueOf(1000000); +String c1 = PaillierCipher.encryption(i1, pubKey); + +// encrypt the second number with same public key +BigInteger i2 = BigInteger.valueOf(2012012012); +String c2 = PaillierCipher.encryption(i2, pubKey); + +// paillier add with numbers +String c3 = PaillierCipher.ciphertextAdd(c1,c2); + +// decrypt the result +BigInteger o3 = PaillierCipher.decryption(c3, priKey); +``` + + +### 3.3.2 Solidity API说明 + +#### 3.3.2.1. 同态加法库(LibPaillier.sol) + +- 接口名称:pai_add +- 接口功能说明:加法同态的合约实现 +- 参数说明 + +|输入参数|参数类型|参数说明| +|:-----|:-----|:-----| +|D1|String|加密后的第一个加法操作数| +|D2|String|加密后的第二个加法操作数| +|**输出参数**|**参数类型**|**参数说明**| +|返回值|String|同态加法的结果其他 :成功 空串:失败 | + +*注:该合约实现复用了sha3的机制,采用特定的前缀进行扩展算法实现* + +#### 3.3.2.2. 使用样例 + +``` +import "LibPaillier.sol"; + +contract Test { +  using LibPaillier for *; +   +  string balance; +   +  function addBalance(string n) public returns (int) { +   string memory result = LibPaillier.pai_add(balance, n); +   if (bytes(result).length == 0) { +   return 1; +    } +     +    balance = result; +    return 0; +  } +} +``` + +[systemContract]:images/i3.1.png "系统合约部署示例" + +# 第四章、部署合约 +本章以一个HelloWorld.sol智能合约为例介绍部署合约的方法。 +该合约中有一个name成员变量。同时有更新接口set和读取接口get,合约源码如下: +```javascript +contract HelloWorld{ + string name; + function HelloWorld(){ + name="Hi,Welcome!"; + } + function get()constant returns(string){ + return name; + } + function set(string n){ + name=n; + } +} +``` +工具目录下已有部署脚本。更新目录下config.js中的Ip(内网监听IP)和端口(RPC监听端口),及privKey(注意没有0x前缀)和account(注意有0x前缀) (生成方法参看生成公私钥对)后直接使用即可。 +```bash +cd tool +vim config.js +babel-node deploy.js HelloWorld +``` +输出示例如下: + +![示例输出](./images/i4.1.png) + +输出即是HelloWorld.sol智能合约地址。 +# 第五章、调用合约 +本章以第四章中的HelloWorld.sol智能合约为例介绍调用合约的方法。 +调用更新接口set和读取接口get。 +```bash +cd tool +babel-node demoHelloWorld.js +``` +输出示例如下: + +![示例输出](./images/i5.1.png) + +输出即是调用合约set接口后的结果。 +以上仅为示例,可以新建智能合约文件或查看、修改HelloWorld.sol,及对应的调用脚本 以符合需要。 +智能合约Solidity语言教程请参考http://solidity.readthedocs.io/en/latest/ +# 第六章、使用控制台 +控制台是通过IPC方式连接区块链节点进程的一种方式。 +控制台可以查看区块信息、查看交易信息、查看节点连接信息。 +打开控制台命令行:ethconsole geth.ipc文件路径 +```bash +ethconsole /mydata/nodedata-1/geth.ipc +``` +## 6.1. 查看区块 +命令行 :web3.eth.getBlock(块号,console.log) +如输出显示块号1的块信息 +```bash +web3.eth.getBlock(1,console.log) +``` +示例输出如下(字段含义请参看区块头结构): +![示例输出](./images/i6.1.png) +## 6.2. 查看交易 +命令行 :web3.eth.getTransaction(交易哈希,console.log) + +如输入 +```bash +web3.eth.getTransaction('0x32e7970afe197053b6b18771dea01e392da9cf9173b0a9a22ce3778de0a109d3',console.log) +``` +示例输出如下(字段含义请参看交易结构): + +![示例输出](./images/i6.2.png) + +## 6.3. 查看交易回执 +命令行 :web3.eth.getTransactionReceipt(交易哈希,console.log) + +如输入 +```bash +web3.eth.getTransactionReceipt('0x32e7970afe197053b6b18771dea01e392da9cf9173b0a9a22ce3778de0a109d3',console.log)console.log) +``` +示例输出如下(字段含义请参看交易回执结构): +![示例输出](./images/i6.3.png) +## 6.4. 查看合约 +命令行 :web3.eth.getCode(合约地址,console.log) + +如输入 +```bash +web3.eth.getCode('0x932169080dd008768f4bf1fbae7ca706d85525b9',console.log) +``` +示例输出如下(输出为合约二进制编码,非空即是表示合约存在): +![示例输出](./images/i6.4.png) +## 6.5. 查看节点连接 +命令行 :web3.admin.getPeers(console.log) + +如输入 +```bash +web3.admin.getPeers(console.log) +``` +示例输出如下(字段含义请参看节点连接信息): +![示例输出](./images/i6.5.png) +# 第七章、多节点组网 + +本章详细介绍在一个创始节点已正常运行的前提下,如何一步步操作,加入新的区块链节 点, 组成区块链网络的操作流程。 + +系统合约是 OpenDL 区块链的重要设计思路之一,也是控制网络节点加入和退出的重要方式, + +因此[部署系统合约](#7.1 部署系统合约)是多节点组网的前提条件。并且仅需执行一次。 + +新节点加入网络的过程主要有三个步骤[新建非创世节点](#7.2 新建非创世节点)、[非创世节点加入网络](#7.3 非创世节点加入网络)、[非创世节点启动](#7.4 非创世节点启动)。 + +## 7.1 部署系统合约 + +执行以下命令: + +```shell +cd systemcontractv2/output +tar xvf linux.tar +cd .. +vim config.js #更新内网监听Ip和RPC监听端口,及privKey和account(可复用第四章部署合约 中的或重新生成) +babel-node deploy.js +``` + +示例输出如下: + +![7.1](images/i7.1.png) + +1.从上面输出中获得系统代理合约地址,更新到创世节点运行参数配置文件```config.json```中的```systemproxyaddress``` 字段。然后重启创世节点区块链进程。 + +2.编辑系统合约目录下的```node1.json```。将其中的字段内容更新为创世节点的```config.json```中的```NodeextraInfo```部分自身的节点信息。(id=NodeId、ip=Peerip、port=Port、desc=Nodedesc、category=Identitytype、CAhash留空字符串即可、agencyinfo=Agencyinfo、idx=Idx注意字段值必须完全一样!) + + 示例如下: + + ![7.2](images/i7.2.png) + +3.添加创世节点入网 + +```shell +babel-node tool.js NodeAction registerNode node1.json +``` + +输出示例如下: + +![7.3](images/i7.3.png) + +“发送交易成功”即表示交易请求已发出。 + +4.查看创世节点是否已在节点列表中 + +```shell +babel-node tool.js NodeAction all +``` + +输出示例如下: + +![7.4](images/i7.4.png) + +输出中有```NodeIdsLength = 1```即是代表节点列表中有一个节点了。 + +## 7.2 新建非创世节点 + +1.新建节点目录,下文设定新节点目录为```/mydata/nodedata-2/ ``` + +2.参看[生成节点身份NodeId](#2.4 生成节点身份NodeId) ,并将新的```network.rlp network.rlp.pub``` 文件输出到 ```/mydata/nodedata-2/ ``` + +3.拷贝创世块文件```genesis.json```和创世节点的配置文件 ```config.json``` 及日志配置文件``` log.conf``` 到新节点目录```/mydata/nodedata-2/ ``` + +4.更新```/mydata/nodedata-2/ ```的```config.json```文件中的```rpcport、p2pport、wallet、keystoredir、datadir```字段(注意:若多个节点同在一台服务器,需要配置rpcport、 p2pport均不互相冲突)。 + +5.更新```/mydata/nodedata-2/ ```的log.conf中的日志路径。 + +6.追加非创世节点信息到 ```/mydata/nodedata-2/``` 的```config.json```文件中的 ```NodeextraInfo``` 字段。 + +示例如下: + +```json +"NodeextraInfo":[ + { "Nodeid":"de0fa385816b505799433e54b88788e21cb42092a6ff5bcaa2285d7ace906e5e6ce8ef2b30134ff276a5834d58721291acc5864e07e6d52469b79b28e699dfde", + "Nodedesc": "node1", + "Agencyinfo": "node1", + "Peerip": "119.29.57.154", + "Identitytype": 1, + "Port":30303, + "Idx":0 + }, + { "Nodeid":"2a0cb7425bd63835d346ae20ec6107d28f64009a9dcca7d485713f1dfe7c4edf6e79b7e08a70cb8220beb133327361313e6bc793433311ba997a81e14800a85f", + "Nodedesc": "node2", + "Agencyinfo": "node2", + "Peerip": "xxxx", + "Identitytype": 1, + "Port":30304, + "Idx":1 + } +] +``` + +其中字段说明如下: + +| **字段** | **说明** | +| ------------ | ----------------- | +| Nodeid | 节点ID | +| Nodedesc | 节点描述 | +| Agencyinfo | 节点信息 | +| Peerip | P2P网络监听端口(建议外网IP) | +| Identitytype | 节点类型 | +| Port | P2P网络端口 | + +## 7.3 非创世节点加入网络 + +执行以下命令: + +```shell +cd systemcontractv2/ +vim node2.json +``` + +1.编辑系统合约目录下的节点信息文件```node2.json```。将其中的字段内容更新为```/mydata/nodedata-2/``` 的```config.json```中的```NodeextraInfo```部分的```node2```的节点信息。(注意字段值必须完全一样!) + +2.添加节点入网 + + ``` + babel-node tool.js NodeAction registerNode node2.json + ``` + + 输出示例如下: + + ![7.5](images/i7.5.png) + +3.查看是否已经入网 + + ```shell + babel-node tool.js NodeAction all + ``` + + 输出示例如下: + + ![7.6](images/i7.6.png) + + 输出中有 ```NodeIdsLength = 2``` 即是代表节点列表中已有个节点了。 + +## 7.4 非创世节点启动 + +执行以下命令启动区块链节点进程: + +```shell +./build/eth/eth --genesis /mydata/nodedata-2/genesis.json --config /mydata/nodedata-2/config.json +``` + +查看块高变化及连接节点信息: + +```shell +babel-node monitor.js +``` + +输出示例如下: + +![7.7](images/i7.7.png) + +输出中“已连接节点数:1”代表已连接上的对端节点数。 + +输出中“当前块高11690”代表当前块高,块高不断增长说明在正常运行。 + + 至此,两个节点的区块链网络已组成功! + +若需要继续添加新节点入网,重复本章的[新建非创世节点](#7.2 新建非创世节点)、[非创世节点加入网络](#7.3 非创世节点加入网络)、[非创世节点启动](#7.4 非创世节点启动) 即可。 + +## 7.5 节点退出网络 + +命令行:```babel-node tool.js NodeAction cancelNode ``` 节点信息json文件 + +最后一个参数“节点信息json文件” 即是[非创世节点加入网络](#7.3 非创世节点加入网络) 中节点加入网络时对应的节点信息文件。 + +执行删除命令后,可以通过执行以下命令来查看当前节点列表: + +```shell +babel-node tool.js NodeAction all +``` + +# 第八章、机构证书准入介绍 + +## 8.1 机构证书的作用说明 + +机构身份认证功能,为机构备案公钥证书到区块链,作为准入机制,使得区块链上节点能 够与现实身份对应,节点接入联盟链时需验证该节点身份,节点身份验证通过才能接入联 盟链,节点行为可追溯。 + +## 8.2 注册新证书 + +生成私钥 private.key 和公钥 public.key + +```shell +openssl genrsa -out private.key 1024 +openssl rsa -in private.key -pubout -out public.key +``` + +## 8.3 启用机构证书验证 + +### 8.3.1 准备工作 + +1.假设本地有 public key 和 private key,然后放到如下位置目录: + + ```shell + /mydata/nodedata/CA/ + ``` + + public.key的内容如下(内容已省略): + + ``` + -----BEGIN PUBLIC KEY----- + *** + *** + -----END PUBLIC KEY----- + ``` + + private.key的内容如下(内容已省略) + + ``` + -----BEGIN RSA PRIVATE KEY----- + *** + *** + -----END RSA PRIVATE KEY----- + ``` + +2.把公钥public key写入合约 + + ```shell + babel-node tool.js CAAction update ca.json + ``` + + ca.json结构: + + ```json + { + "hash":"xxx", + "pubkey":"xxxx", + "orgname":"BCOS银行", + "notbefore":20170223, + "notafter":20180223, + "status":1, + "whitelist":"192.168.1.1;192.168.1.2;192.168.1.3", + "blacklist":"192.168.1.11;192.168.1.12;192.168.1.13" + } + ``` +其中字段说明如下: + +| **字段** | **说明** | +| ------------ | ----------------- | +| hash | 对证书的sha256sum后的hash,这里的证书是指能导出public.key的原有证书 | +| pubkey | public.key的整个文本信息,注意对换行符的替换 | +| orgname | 机构名称 | +| notbefore | 证书生效时间 | +| notafter | 证书过期时间 | +| status | 证书状态 0:不可用 1:可用 | +| whitelist | ip白名单,只允许哪些ip可以连接当前节点,默认为空字符串,允许所有ip | +| blacklist | ip黑名单,不允许哪些ip连接当前节点,默认为空字符串,代表没有禁止ip | + +### 8.3.2 打开开关 + +开关打开后,会对当前所有节点进行CA验证,如果节点在目录 ```/mydata/nodedata/CA/``` 没有相关的证书,那么会被对方节点拒绝。 + +开启开关前,先确保当前所有节点的证书已经上链。 + +开启全局CAVerify开关 + +```shell +babel-node tool.js ConfigAction set CAVerify true +``` + +查看开关是否生效 + +```shell +babel-node tool.js ConfigAction get CAVerify +``` + +若出现以下信息,则代表成功: + +![](images/i8.png) + +### 8.3.3 查看日志 + +开启开关并且通过CA模块验证后,通过以下命令找出相关记录 + +```shell +grep "verify ok" /mydata/nodedata-1/log/* +``` + +### 8.4 更新证书状态 + +如果证书过期或者被注销,可以通过以下命令来剔除用该证书的机构所有连接节点 + +```shell +babel-node tool.js CAAction updateStatus ca.json +``` + +其中,ca.json的 status 要设置为0。检查日志操作是否生效 + +```shell +grep "blockNumber is 0 or status is false" /mydata/nodedata-1/log/* +``` + +### 8.5 证书注意事项 + +1.妥善保管 private.key,切勿泄露,同时应把证书,public.key 和 private.key 备份到安全位置 + +2.开启全局 CA 开关 CAVerify 开关前,先确保当前所有连接节点已有相应的证书在指定目录,同时注意文件的名字 public.key,private.key。 + +3.一旦把 CAVerify 开关开启后,不建议再把 CAVerify 关闭。 + +# 第九章、系统合约介绍 +系统合约是BCOS区块链的内置智能合约。 +主要分为以下几种:系统代理合约、节点管理合约、机构证书合约、权限管理合约、全网配置合约。 + +系统合约一经部署,全网生效后,一般不轻易变更。 +若需重新部署变更升级,需全网所有节点都认可且重新更新运行参数配置文件的systemproxyaddress字段后重启。 +系统合约原则上只允许管理员账号调用。 + +以下依次介绍各个系统合约的源码路径、已实现接口说明、调用例子、工具使用方法。 + + + +## 9.1.系统代理合约 +系统代理合约是系统合约的统一入口。 +它提供了路由名称到合约地址的映射关系。 + +源码路径:systemcontractv2/SystemProxy.sol + +### ① 接口说明 +|接口名 |输入 |输出| 备注| +|----|----|----|----| +|获取路由信息 getRoute |路由名称 |路由地址、缓存标志位、生效块号 |无| +|注册路由信息setRoute| 路由名称、路由地址、缓存标志位 |无 |若该路由名称已存在,则覆盖| + +web3调用示例如下(可参看systemcontractv2/deploy.js): +```js +console.log("注册NodeAction....."); +func = "setRoute(string,address,bool)"; +params = ["NodeAction", NodeAction.address, false]; +receipt = await web3sync.sendRawTransaction(config.account, config.privKey, SystemProxy.address, func, params); +``` + +### ② 工具使用方法 +查看所有系统合约信息: + +``` babel-node tool.js SystemProxy ``` + + +示例输出如下: + +![output example](./images/i9.1.png) + +输出中即是当前系统路由表的所有路由信息。 + + +## 9.2.节点管理合约 +节点管理合约主要功能是维护网络中节点列表。 +网络中节点加入或退出都需要与节点管理合约进行交互。 + +源码路径:systemcontractv2/NodeAction.sol +### ① 接口说明 +|接口名 |输入| 输出| 备注| +|----|----|----|----| +|节点入网 registerNode |节点ID、IP、端口、节点类型、节点描述、节点CA哈希、节点agency、节点序号 |布尔结果 |若该节点ID已存在,则忽略| +|节点出网 cancelNode |节点ID |布尔结果 |若该路由名称不存在,则忽略 + +web3调用示例如下(可参看systemcontractv2/tool.js): +```js +var instance=getAction("NodeAction"); +var func = "registerNode(string,string,uint256,uint8,string,string,string,uint256)"; +var params = [node.id,node.ip,node.port,node.category,node.desc,node.CAhash,node.agencyinfo,node.idx]; +var receipt = web3sync.sendRawTransaction(config.account, config.privKey, instance.address, func, params); +``` + +### ② 工具使用方法 +请参看 添加非创世节点入网、节点出网 + +## 9.3.机构证书合约 +机构证书合约主要功能是维护机构证书信息。 + +源码路径:systemcontractv2/CAAction.sol + +### ① 接口说明 +|接口名 |输入 |输出| 备注| +|----|----|----|----| +|更新证书信息 update |证书哈希、公钥、组织名称、证书有效开始时间、证书失效时间、证书状态、白名单列表、黑名单列表 |布尔结果 |若该证书信息不存在,则新建| +|更新证书状态 updateStatus |证书哈希、证书状态 |布尔结果 |若该路由名称不存在,则忽略 +|查询证书信息 get |证书哈希 |证书哈希、公钥、组织名称、证书有效开始时间、证书失效时间、证书状态、块号 |无 +|查询证书黑白名单列表 getIp |证书哈希 |白名单列表、黑名单列表 |无 + +web3调用示例如下(可参看systemcontractv2/tool.js): +```js +var instance=getAction("CAAction"); +var func = "update(string,string,string,uint256,uint256,uint8,string,string)"; +var params = +[ca.hash,ca.pubkey,ca.orgname,ca.notbefore,ca.notafter,ca.status,ca.whitelist,ca.blacklist]; +var receipt = +web3sync.sendRawTransaction(config.account, config.privKey, instance.address, func, params); +``` + +### ② 工具使用方法 +查看证书列表 + +```babel-node tool.js CAAction all``` + +更新证书信息 + +```babel-node tool.js CAAction update``` + +更新证书状态 + +```babel-node tool.js CAAction updateStatus``` + + +## 9.4.权限管理合约 +权限管理合约是对区块链权限模型的实现。 +一个外部账户只属于一个角色,一个角色拥有一个权限项列表。 +一个权限项由合约地址加上合约接口来唯一标识。 + +源码路径:systemcontractv2/AuthorityFilter.sol 交易权限Filter + systemcontractv2/Group.sol 角色 + + +### ① 接口说明 + +|合约 |接口名 |输入| 输出| 备注| +|----|----|----|----|----| +|角色 |设置用户权限组 权限项 setPermission| 合约地址、合约接口、权限标记| 无 |无| +| | 获取权限标记 getPermission |合约地址、合约接口 |权限标记| 无| +|交易权限Filter |设置用户所属角色 setUserGroup |用户外部账户、用户所属角色合约 |无 |无| +| | 交易权限检查 process |用户外部账户、交易发起账户、合约地址、合约接口、交易输入数据 | |无| + +web3调用示例如下(可参看systemcontractv2/deploy.js): +```js +func = "setUserGroup(address,address)"; +params = [config.account, Group.address]; +receipt = await web3sync.sendRawTransaction(config.account, config.privKey, AuthorityFilter.address, func, params); +console.log("授予"+config.account+"角色"+Group.address); +``` + +### ② 工具使用方法 +检查用户外部账户权限 + +```babel-node tool.js AuthorityFilter 用户外部账户、合约地址、合约接口``` + + + +### ③ 自主定制 +继承TransactionFilterBase实现新的交易Filter合约。并通过addFilter接口将新Filter注册入TransactionFilterChain即可。 + +## 9.5.全网配置合约 +全网配置合约维护了区块链中部分全网运行配置信息。 +目标是为了通过交易的全网共识来达成全网配置的一致更新。 + +源码路径:systemcontractv2/ConfigAction.sol + +### ① 全网配置项说明 +|配置项| 说明 |默认值| 推荐值| +|----|----|----|----| +|maxBlockHeadGas |块最大GAS (16进制)| 200000000 |20000000000| +|intervalBlockTime| 块间隔(ms) (16进制)| 1000| 1000| +|maxBlockTranscations |块最大交易数(16进制) |1000| 1000| +|maxNonceCheckBlock |交易nonce检查最大块范围(16进制)| 1000| 1000| +|maxBlockLimit| blockLimit超过当前块号的偏移最大值(16进制) |1000| 1000| +|maxTranscationGas| 交易的最大gas(16进制)| 20000000 |20000000| +|CAVerify| CA验证开关| FALSE| FALSE| + +### ② 接口说明 +|接口名| 输入| 输出| 备注| +|----|----|----|----| +|设置配置项 set| 配置项、配置值 |无 |若配置表中已存在,则覆盖| +|查询配置值 get| 配置项| 配置值、块号| 无| + +web3调用示例如下(可参看systemcontractv2/tool.js): +```js +var func = "set(string,string)"; +var params = [key,value]; +var receipt = web3sync.sendRawTransaction(config.account, config.privKey, instance.address, func, params); +console.log("配置项:"+key+","+value); +``` + +### ③ 使用方法 +查询配置项 + +```babel-node tool.js ConfigAction get配置项``` + +设置配置项 + +```babel-node tool.js ConfigAction set配置项 配置值``` +# 第十章、分布式数据库 +区块链进程支持将区块、状态数据存储到数据库,在config.json中增加如下配置: + +``` +"dbconf": { + "stateDbConf": { + "dbInfo": "x.x.x.x:x@db", + "dbName": "db", + "tableName": "t_state", + "userName": "****", + "pwd": "******", + "cacheSize": 104857600, + "engineType": 1 //1-mysql 2-oracle + }, + "blockDbConf": { + "dbInfo": "x.x.x.x:x@db", + "dbName": "db", + "tableName": "t_block", + "userName": "****", + "pwd": "******", + "cacheSize": 104857600, + "engineType": 1 //1-mysql 2-oracle + }, + "extrasDbConf": { + "dbInfo": "x.x.x.x:x@db", + "dbName": "db", + "tableName": "tb_extras", + "userName": "*****", + "pwd": "******", + "cacheSize": 104857600, + "engineType": 1 //1-mysql 2-oracle + } +} +``` + +配置中,一共指定三个表,分别是状态存储、区块存储和额外存储; + +重新编译区块链进程,cmake时增加-DETH_ODBC选项,即可开启数据库存储。 + + +# 第十一章、其他可选工具介绍 + +本章介绍两个可选工具的使用场景与使用方法 + +## 11.1 创世块工具 +创世块工具主要是为了将当前区块链中现有的所有合约数据作为快照导出。 + +一旦新链以此快照作为创世块文件启动,新链就可以快速拥有了当前区块链的所有合约数据。 + +命令行: + +区块链执行程序路径 --genesis 创世块文件 --config 配置文件 --export-genesis 导出新创世块文件路径 + +示例如下: + +``` +./build/eth/eth --genesis ./genesis.json --config ./config.json +--export-genesis ./genesis.file +``` + +执行输出的genesis.file即是新创世块文件。 + + +## 11.2 监控脚本工具 + +为了方便快速的查看当前节点的网络连接及块高情况。可使用本工具。 + +``` +cd tool +babel-node monitor.js +``` + +示例输出如下: + +![](images/i10.1.jpg) + +输出中“已连接节点数”代表当前节点已连接上的区块链节点数。 + +输出中“当前块高”代表当前节点的区块链高度。如果在不断增长,代表区块链在正常运行。 + + +# 第十二章、问题反馈 +欢迎任何人对本文档指出不足、提出优化建议。 + +欢迎任何人参与BCOS区块链开源平台的使用、优化、改进。 + +欢迎任何人反馈BCOS区块链开源平台的任何问题。 + +若有问题反馈请尽可能包含以下信息: + +1.平台源码版本(如有) +2.所在的操作系统或平台 +3.问题重现的方法或步骤 +4.问题期望的表现 +5.源码文件及行数(如有) + +随时联系我们:hi@bcos.org.cn + + +# 第十三章、附录 + +## 13.1 区块头结构 +关键字段 | 说明 +------------ | ------------- +hash | 块哈希 +difficulty | 块难度(默认1) +parentHash | 父块哈希 +timestamp | 块时间戳 +gasLimit | 块GAS最大限制 +gasused | 块已使用GAS +number | 块号 +sha3uncles | 叔伯块哈希 +stateroot | 世界状态树根 +transcationroot | 交易树根 +receiptsroot | 交易收据树根 +genidx | 记账节点编号 +nodelist | 记账节点公钥列表 + +## 13.2 交易结构 +关键字段 | 说明 +------------ | ------------- +sender | 交易发送者外部账号 +gas | 交易GAS上限 +receiveaddress | 合约地址 +data | 交易数据 +sign | 交易签名 +randomid | 交易随机数 +blocklimit | 交易最大块号限制 + + +## 13.3 交易回执结构 +关键字段 | 说明 +------------ | ------------- +blockNumber | 交易所在块号 +contractAddress | 合约地址 +cumulativeGasUsed | 交易预估消耗GAS +gasUsed | 交易实际消耗GAS +logs | EventLog列表 +transactionHash | 交易哈希 +transactionIndex | 交易序号 + +## 13.4 节点连接信息 +关键字段 | 说明 +------------ | ------------- +id | 节点身份NodeId +name | 节点软件版本信息 +network | 节点网络IP信息 diff --git a/eth/AccountManager.cpp b/eth/AccountManager.cpp new file mode 100644 index 0000000000..3fa26fab45 --- /dev/null +++ b/eth/AccountManager.cpp @@ -0,0 +1,249 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file AccountManager.cpp + * @author Yann + * @date 2016 + */ + +#include +#include +#include +#include +#include +#include "AccountManager.h" +using namespace std; +using namespace dev; +using namespace dev::eth; + +void AccountManager::streamAccountHelp(ostream& _out) +{ + _out + << " account list List all keys available in wallet." << endl + << " account new Create a new key and add it to the wallet." << endl + << " account update [|
, ... ] Decrypt and re-encrypt given keys." << endl + << " account import [||] Import keys from given source and place in wallet." << endl; +} + +void AccountManager::streamWalletHelp(ostream& _out) +{ + _out + << " wallet import Import a presale wallet." << endl; +} + +bool AccountManager::execute(int argc, char** argv) +{ + if (string(argv[1]) == "wallet") + { + if (3 < argc && string(argv[2]) == "import") + { + if (!openWallet()) + return false; + string file = argv[3]; + string name = "presale wallet"; + string pw; + KeyPair k; + try + { + k = m_keyManager->presaleSecret( + contentsString(file), + [&](bool){ return (pw = getPassword("Enter the passphrase for the presale key: "));} + ); + } + catch (Exception const& _e) + { + if (auto err = boost::get_error_info(_e)) + cout << " Decryption failed: " << *err << endl; + else + cout << " Decryption failed: Unknown reason." << endl; + return false; + } + m_keyManager->import(k.secret(), name, pw, "Same passphrase as used for presale key"); + cout << " Address: {" << k.address().hex() << "}" << endl; + } + else + streamWalletHelp(cout); + return true; + } + else if (string(argv[1]) == "account") + { + if (argc < 3 || string(argv[2]) == "list") + { + openWallet(); + if (m_keyManager->store().keys().empty()) + cout << "No keys found." << endl; + else + { + vector bare; + AddressHash got; + int k = 0; + for (auto const& u: m_keyManager->store().keys()) + { + if (Address a = m_keyManager->address(u)) + { + got.insert(a); + cout << "Account #" << k << ": {" << a.hex() << "}" << endl; + k++; + } + else + bare.push_back(u); + } + for (auto const& a: m_keyManager->accounts()) + if (!got.count(a)) + { + cout << "Account #" << k << ": {" << a.hex() << "}" << " (Brain)" << endl; + k++; + } + for (auto const& u: bare) + { + cout << "Account #" << k << ": " << toUUID(u) << " (Bare)" << endl; + k++; + } + } + } + else if (2 < argc && string(argv[2]) == "new") + { + openWallet(); + string name; + string lock; + string lockHint; + lock = createPassword("Enter a passphrase with which to secure this account:"); + auto k = makeKey(); + h128 u = m_keyManager->import(k.secret(), name, lock, lockHint); + cout << "Created key " << toUUID(u) << endl; + cout << " ICAP: " << ICAP(k.address()).encoded() << endl; + cout << " Address: {" << k.address().hex() << "}" << endl; + } + else if (3 < argc && string(argv[2]) == "import") + { + openWallet(); + h128 u = m_keyManager->store().importKey(argv[3]); + if (!u) + { + LOG(ERROR) << "Error: reading key file failed" << endl; + return false; + } + string pw; + bytesSec s = m_keyManager->store().secret(u, [&](){ return (pw = getPassword("Enter the passphrase for the key: ")); }); + if (s.empty()) + { + LOG(ERROR) << "Error: couldn't decode key or invalid secret size." << endl; + return false; + } + else + { + string lockHint; + string name; + m_keyManager->importExisting(u, name, pw, lockHint); + auto a = m_keyManager->address(u); + cout << "Imported key " << toUUID(u) << endl; + cout << " ICAP: " << ICAP(a).encoded() << endl; + cout << " Address: {" << a.hex() << "}" << endl; + } + } + else if (3 < argc && string(argv[2]) == "update") + { + openWallet(); + for (int k = 3; k < argc; k++) + { + string i = argv[k]; + h128 u = fromUUID(i); + if (isHex(i) || u != h128()) + { + string newP = createPassword("Enter the new passphrase for the account " + i); + auto oldP = [&](){ return getPassword("Enter the current passphrase for the account " + i + ": "); }; + bool recoded = false; + if (isHex(i)) + { + recoded = m_keyManager->store().recode( + Address(i), + newP, + oldP, + dev::KDF::Scrypt + ); + } + else if (u != h128()) + { + recoded = m_keyManager->store().recode( + u, + newP, + oldP, + dev::KDF::Scrypt + ); + } + if (recoded) + LOG(ERROR) << "Re-encoded " << i << endl; + else + LOG(ERROR) << "Couldn't re-encode " << i << "; key does not exist, corrupt or incorrect passphrase supplied." << endl; + } + else + LOG(ERROR) << "Couldn't re-encode " << i << "; does not represent an address or uuid." << endl; + } + } + else + streamAccountHelp(cout); + return true; + } + else + return false; +} + +string AccountManager::createPassword(string const& _prompt) const +{ + string ret; + while (true) + { + ret = getPassword(_prompt); + string confirm = getPassword("Please confirm the passphrase by entering it again: "); + if (ret == confirm) + break; + cout << "Passwords were different. Try again." << endl; + } + return ret; +} + +KeyPair AccountManager::makeKey() const +{ + bool icap = true; + KeyPair k(Secret::random()); + while (icap && k.address()[0]) + k = KeyPair(Secret(sha3(k.secret().ref()))); + return k; +} + +bool AccountManager::openWallet() +{ + if (!m_keyManager) + { + m_keyManager.reset(new KeyManager()); + if (m_keyManager->exists()) + { + if (m_keyManager->load(std::string()) || m_keyManager->load(getPassword("Please enter your MASTER passphrase: "))) + return true; + else + { + LOG(ERROR) << "Couldn't open wallet. Please check passphrase." << endl; + return false; + } + } + else + { + LOG(ERROR) << "Couldn't open wallet. Does it exist?" << endl; + return false; + } + } + return true; +} diff --git a/eth/AccountManager.h b/eth/AccountManager.h new file mode 100644 index 0000000000..eed39b29f3 --- /dev/null +++ b/eth/AccountManager.h @@ -0,0 +1,53 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file AccountManager.h + * @author Yann + * @date 2016 + */ +#pragma once +#include + +/** + * Add account management functionnalities to CLI. + * account list + * account new + * account update + * account import + * wallet import (import presale wallet) + */ +class AccountManager +{ +public: + /// uses @a argc, @a argv provided by the CLI and executes implemented options. + bool execute(int argc, char** argv); + /// stream account help section + void static streamAccountHelp(std::ostream& _out); + /// stream wallet help section + void static streamWalletHelp(std::ostream& _out); + +private: + /// ask end user to create a password. + std::string createPassword(std::string const& _prompt) const; + /// creates a ramdom secret/address pair. It uses ICAP. + dev::KeyPair makeKey() const; + /// instanciate KeyManager and open the wallet. + bool openWallet(); + + std::unique_ptr m_keyManager; +}; + + diff --git a/eth/CMakeLists.txt b/eth/CMakeLists.txt new file mode 100644 index 0000000000..4086d86503 --- /dev/null +++ b/eth/CMakeLists.txt @@ -0,0 +1,43 @@ +aux_source_directory(. SRC_LIST) + +file(GLOB HEADERS "*.h") + + +include(EthDependencies) + +add_executable(eth ${SRC_LIST} ${HEADERS}) + +find_package(Eth) +find_package(Web3) + +target_include_directories(eth PRIVATE ..) + +include_directories(../libodbc/include + ../libodbc/include/db2_linux + ../libodbc/include/ibase + ../libodbc/include/infomix + ../libodbc/include/mysql + ../libodbc/include/odbc_linux + ../libodbc/include/pgsql + ../libodbc/include/sqlbase + ../libodbc/include/sqllite + ../libodbc/include/ss_linux + ../libodbc/include/sybase) + +target_link_libraries(eth ${Eth_EVM_LIBRARIES}) +target_link_libraries(eth ${Web3_WEB3JSONRPC_LIBRARIES}) +target_link_libraries(eth ${Web3_WEBTHREE_LIBRARIES}) +target_link_libraries(eth contract) +target_link_libraries(eth JsonRpcCpp::Client) + +if (EVMJIT) + # Do we need include paths here? + target_link_libraries(eth ${Eth_EVMJIT_LIBRARIES}) + eth_copy_dlls(eth EVMJIT_DLLS) +endif() + +if (UNIX AND NOT APPLE) + target_link_libraries(eth pthread) +endif() + +install(TARGETS eth DESTINATION bin) diff --git a/eth/Farm.h b/eth/Farm.h new file mode 100644 index 0000000000..ed1c18f472 --- /dev/null +++ b/eth/Farm.h @@ -0,0 +1,39 @@ +/** + * This file is generated by jsonrpcstub, DO NOT CHANGE IT MANUALLY! + */ + +#ifndef JSONRPC_CPP_STUB_FARM_H_ +#define JSONRPC_CPP_STUB_FARM_H_ + +#include + +class Farm : public jsonrpc::Client +{ + public: + Farm(jsonrpc::IClientConnector &conn, jsonrpc::clientVersion_t type = jsonrpc::JSONRPC_CLIENT_V2) : jsonrpc::Client(conn, type) {} + + Json::Value eth_getWork() throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p = Json::nullValue; + Json::Value result = this->CallMethod("eth_getWork",p); + if (result.isArray()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + bool eth_submitWork(const std::string& param1, const std::string& param2, const std::string& param3) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + p.append(param2); + p.append(param3); + Json::Value result = this->CallMethod("eth_submitWork",p); + if (result.isBool()) + return result.asBool(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } +}; + +#endif //JSONRPC_CPP_STUB_FARM_H_ diff --git a/eth/GenesisInfo.h b/eth/GenesisInfo.h new file mode 100644 index 0000000000..e401bb4248 --- /dev/null +++ b/eth/GenesisInfo.h @@ -0,0 +1,62 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file GenesisInfo.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include +#include +#include "genesisInfoForWe.h" + +namespace dev +{ +namespace eth +{ + +/// The network id. +enum class Network +{ + //Olympic = 0, ///< Normal Olympic chain. + MainNetwork = 1, ///< Normal Frontier/Homestead/DAO/EIP150/EIP158 chain. + //Morden = 2, ///< Normal Morden chain. + Ropsten = 3, ///< New Ropsten Test Network + MainNetworkTest = 69, ///< MainNetwork rules but without genesis accounts (for transaction tests). + TransitionnetTest = 70, ///< Normal Frontier/Homestead/DAO/EIP150/EIP158 chain without all the premine. + FrontierTest = 71, ///< Just test the Frontier-era characteristics "forever" (no Homestead portion). + HomesteadTest = 72, ///< Just test the Homestead-era characteristics "forever" (no Frontier portion). + EIP150Test = 73, ///< Homestead + EIP150 Rules active from block 0 For BlockchainTests + EIP158Test = 74, ///< Homestead + EIP150 + EIP158 Rules active from block 0 + Special = 0xff ///< Something else. +}; + + + +std::string const& genesisInfo(Network ) +{ + return c_configJsonForWe; +} +h256 const& genesisStateRoot(Network ) +{ + return c_genesisStateRootForWe; +} + +} +} diff --git a/eth/farm.json b/eth/farm.json new file mode 100644 index 0000000000..c2c31b7350 --- /dev/null +++ b/eth/farm.json @@ -0,0 +1,4 @@ +[ + { "name": "eth_getWork", "params": [], "order": [], "returns": []}, + { "name": "eth_submitWork", "params": ["", "", ""], "order": [], "returns": true} +] diff --git a/eth/genesisInfoForWe.cpp b/eth/genesisInfoForWe.cpp new file mode 100644 index 0000000000..d3f5a12faa --- /dev/null +++ b/eth/genesisInfoForWe.cpp @@ -0,0 +1 @@ + diff --git a/eth/genesisInfoForWe.h b/eth/genesisInfoForWe.h new file mode 100644 index 0000000000..766cae949d --- /dev/null +++ b/eth/genesisInfoForWe.h @@ -0,0 +1,71 @@ +#pragma once + +#include +#include + +using namespace std; + +static dev::h256 const c_genesisStateRootForWe; +static std::string const c_genesisJsonForWe = std::string() + +R"E( +{ + "nonce": "0x0", + "difficulty": "0x0", + "mixhash": "0x0", + "coinbase": "0x0", + "timestamp": "0x0", + "parentHash": "0x0", + "extraData": "0x0", + "gasLimit": "0x13880000000000", + "god":"0x4d23de3297034cdd4a58db35f659a9b61fc7577b", + "alloc": {}, + "initMinerNodes":["de0fa385816b505799433e54b88788e21cb42092a6ff5bcaa2285d7ace906e5e6ce8ef2b30134ff276a5834d58721291acc5864e07e6d52469b79b28e699dfde"] +} +)E"; + +static std::string const c_configJsonForWe = std::string() + +R"E( +{ + "sealEngine": "SinglePoint", + "systemproxyaddress":"0x0", + "listenip":"0.0.0.0", + "rpcport":"8545", + "p2pport":"30303", + "wallet":"keys.info", + "keystoredir":"keystore/", + "datadir":"/mydata/nodedata-1/", + "vm":"interpreter", + "networkid":"12345", + "logverbosity":"4", + "coverlog":"OFF", + "eventlog":"ON", + "logconf":"log.conf", + "params": { + "accountStartNonce": "0x0", + "maximumExtraDataSize": "0x0", + "tieBreakingGas": false, + "blockReward": "0x0", + "networkID" : "0x0" + }, + "accounts": { + "0000000000000000000000000000000000000001": { "precompiled": { "name": "ecrecover", "linear": { "base": 3000, "word": 0 } } }, + "0000000000000000000000000000000000000002": { "precompiled": { "name": "sha256", "linear": { "base": 60, "word": 12 } } }, + "0000000000000000000000000000000000000003": { "precompiled": { "name": "ripemd160", "linear": { "base": 600, "word": 120 } } }, + "0000000000000000000000000000000000000004": { "precompiled": { "name": "identity", "linear": { "base": 15, "word": 3 } } }, + "004f9d39c8424e7f86004622cef21a0bbe140bfa": { "balance": "999999999999000000000000000000" }, + "00dcf3367eab3b34d6a598f453d1aee9146b50f3": { "balance": "999999999999000000000000000000" } + }, + "NodeextraInfo":[ + { + "Nodeid":"de0fa385816b505799433e54b88788e21cb42092a6ff5bcaa2285d7ace906e5e6ce8ef2b30134ff276a5834d58721291acc5864e07e6d52469b79b28e699dfde", + "Nodedesc": "node1", + "Agencyinfo": "node1", + "Peerip": "127.0.0.1", + "Identitytype": 1, + "Port":30303, + "Idx":0 + } + ] +} +)E"; + diff --git a/eth/initProcess.h b/eth/initProcess.h new file mode 100644 index 0000000000..3a11418b2f --- /dev/null +++ b/eth/initProcess.h @@ -0,0 +1,515 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file main.cpp + * @author Gav Wood + * @date 2014 + * EVM Execution tool. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +using namespace std; +using namespace dev; +using namespace eth; +namespace js = json_spirit; + + +static const int64_t MaxBlockGasLimit = ChainParams(genesisInfo(Network::HomesteadTest)).u256Param("maxGasLimit").convert_to(); + +void initHelp() +{ + cout + << "Usage ethvm [trace|stats|output|test] (|-)" << endl + << "Transaction options:" << endl + << " --value Transaction should transfer the wei (default: 0)." << endl + << " --gas Transaction should be given gas (default: block gas limit)." << endl + << " --gas-limit Block gas limit (default: " << MaxBlockGasLimit << ")." << endl + << " --gas-price Transaction's gas price' should be (default: 0)." << endl + << " --sender Transaction sender should be (default: 0000...0069)." << endl + << " --origin Transaction origin should be (default: 0000...0069)." << endl + << " --input Transaction code should be " << endl + << " --code Contract code . Makes transaction a call to this contract" << endl +#if ETH_EVMJIT + << endl + << "VM options:" << endl + << " --vm Select VM. Options are: interpreter, jit, smart. (default: interpreter)" << endl +#endif // ETH_EVMJIT + << "Network options:" << endl + << " --network Olympic|Frontier|Morden|Homestead" << endl + << endl + << "Options for trace:" << endl + << " --flat Minimal whitespace in the JSON." << endl + << " --mnemonics Show instruction mnemonics in the trace (non-standard)." << endl + << endl + << "General options:" << endl + << " -V,--version Show the version and exit." << endl + << " -h,--help Show this help message and exit." << endl; + exit(0); +} + +void initVersion() +{ + cout << "ethvm version " << dev::Version << endl; + cout << "By Gav Wood, 2015." << endl; + cout << "Build: " << DEV_QUOTED(ETH_BUILD_PLATFORM) << "/" << DEV_QUOTED(ETH_BUILD_TYPE) << endl; + exit(0); +} + +/* +The equivalent of setlocale(LC_ALL, “C”) is called before any user code is run. +If the user has an invalid environment setting then it is possible for the call +to set locale to fail, so there are only two possible actions, the first is to +throw a runtime exception and cause the program to quit (default behaviour), +or the second is to modify the environment to something sensible (least +surprising behaviour). + +The follow code produces the least surprising behaviour. It will use the user +specified default locale if it is valid, and if not then it will modify the +environment the process is running in to use a sensible default. This also means +that users do not need to install language packs for their OS. +*/ +void initSetDefaultOrCLocale() +{ +#if __unix__ + if (!std::setlocale(LC_ALL, "")) + { + setenv("LC_ALL", "C", 1); + } +#endif +} + +enum class Mode +{ + Trace, + Statistics, + OutputOnly, + + /// Test mode -- output information needed for test verification and + /// benchmarking. The execution is not introspected not to degrade + /// performance. + Test +}; + +std::vector jsonToVector(std::string const& _json) +{ + std::vector ret; + + js::mValue val; + json_spirit::read_string(_json, val); + js::mObject obj = val.get_obj(); + std::string privilege = json_spirit::write_string(obj["privilege"], false); + //cout << "privilege=" << privilege; + + json_spirit::mValue arrayVal; + json_spirit::read_string(privilege, arrayVal); + json_spirit::mArray arrayObj = arrayVal.get_array(); + + for (auto action: arrayObj) + { + ret.push_back(action.get_obj()["action"].get_str()); + //cout << "action=" << action.get_obj()["action"].get_str(); + } + return ret; +} + +std::string string2val(const std::string &str) +{ + h256 staticPartLength(32); + h256 dynamicPartLength(str.length()); + + string ret = toHex(str); + + int len = ((ret.length() + 31)/32)*32 - ret.length(); + ret.append(len, '0'); + + return staticPartLength.hex() + dynamicPartLength.hex() + ret; +} + + + +void initProcess(int argc, char** argv) +{ + initSetDefaultOrCLocale(); + string inputFile; + Mode mode = Mode::Statistics; + VMKind vmKind = VMKind::Interpreter; + State state(0); + Address sender; + Address origin = Address(69); + u256 value = 0; + u256 gas = MaxBlockGasLimit; + u256 gasPrice = 0; + //bool styledJson = true; + StandardTrace st; + EnvInfo envInfo; + Network networkName = Network::HomesteadTest; + envInfo.setGasLimit(MaxBlockGasLimit); + bytes data; + bytes code; + Address innerAddr; + std::string strConfigJSON; + std::string strBlockChainName; // + std::string strCommonName;//CN + std::string strid;//id + std::string strName;// + std::string strIpList;//ipб + std::string strFileIdList;//ca֤id + std::vector vecPrivilegeJSON; + std::vector vecDepartMentJSON; + ChainParams cp; + + Ethash::init(); + NoProof::init(); + + for (int i = 1; i < argc; ++i) + { + string arg = argv[i]; + if(arg == "init") + { + continue; + } + else if(arg == "--inner" && i + 1 < argc) + { + strConfigJSON = contentsString(argv[++i]); + + cp = cp.loadInnerInfo(strConfigJSON); + //cout << "cp.size=" << cp.innerInfo.size(); + + } + else if(arg == "--action" && i + 1 < argc) + { + std::string strPrivilege; + strPrivilege = contentsString(argv[++i]); + vecPrivilegeJSON = jsonToVector(strPrivilege); + + //cout << "size = " << vecPrivilegeJSON.size(); + //std::vector::iterator iter; + //for (iter=vecPrivilegeJSON.begin();iter!=vecPrivilegeJSON.end();iter++) + //{ + // cout << "action=" << *iter; + + //} + //return; + //cp = cp.loadInnerInfo(strConfigJSON); + //cout << "cp.size=" << cp.innerInfo.size(); + + } + else if ((arg == "-a" || arg == "--address" || arg == "--author") && i + 1 < argc) + { + try + { + sender = h160(fromHex(argv[++i], WhenError::Throw)); + } + catch(...) + { + cerr << "address argument error: " << arg << '\n'; + } + } + else if(arg == "--block-chain-name" && i + 1 < argc)//department's + { + strBlockChainName = argv[++i]; + } + else if(arg == "--common-name" && i + 1 < argc)//department's + { + strCommonName = argv[++i]; + } + else if(arg == "--id" && i + 1 < argc)//department's + { + strid = argv[++i]; + } + else if(arg == "--name" && i + 1 < argc)//department's + { + strName = argv[++i]; + } + else if(arg == "--ip-list" && i + 1 < argc)//ip's + { + strIpList = argv[++i]; + } + else if(arg == "--file-id-list" && i + 1 < argc)//ca's id + { + strFileIdList = argv[++i]; + } + else + { + cerr << "Unknown argument: " << arg << '\n'; + } + } + + + VMFactory::setKind(vmKind); + + //Address contractDestination("1122334455667788990011223344556677889900"); + std::unordered_map map; + bytes output; + //sunordered_map> counts; + for(std::map:: iterator it = cp.innerInfo.begin(); it != cp.innerInfo.end(); it++) + { + code = fromHex(it->second); + Account account(0,0); + account.setNewCode(bytes{code}); + map[it->first] = account; + } + + std::string strOut = "{\"accounts\":{"; + state.populateFrom(map); + unique_ptr se(ChainParams(genesisInfo(networkName)).createSealEngine()); + + + int i = 0; + for(std::map:: iterator it = cp.innerInfo.begin(); it != cp.innerInfo.end(); it++) + { + //cout << "address=" << it->first.hex() << "i = "<< i; + Transaction t; + + t = Transaction(value, gasPrice, gas, it->first, data, i); + i++; + + state.addBalance(sender, value); + Executive executive(state, envInfo, *se); + ExecutionResult res; + executive.setResultRecipient(res); + t.forceSender(sender); + + unordered_map> counts; + unsigned total = 0; + bigint memTotal; + auto onOp = [&](uint64_t step, uint64_t PC, Instruction inst, bigint m, bigint gasCost, bigint gas, VM* vm, ExtVMFace const* extVM) { + if (mode == Mode::Statistics) + { + counts[(byte)inst].first++; + counts[(byte)inst].second += gasCost; + total++; + if (m > 0) + memTotal = m; + } + else if (mode == Mode::Trace) + st(step, PC, inst, m, gasCost, gas, vm, extVM); + }; + + + executive.initialize(t); + if (!code.empty()) + executive.call(it->first, sender, value, gasPrice, &data, gas); + else + executive.create(sender, value, gasPrice, gas, &data, origin); + + Timer timer; + if ((mode == Mode::Statistics || mode == Mode::Trace) && vmKind == VMKind::Interpreter) + executive.go(onOp); + else + executive.go(); + executive.finalize(); + output = std::move(res.output); + state.setNewCode(it->first, bytes{output}); + + } + + //insert inner contrator data + for (std::vector::iterator iter=vecPrivilegeJSON.begin();iter!=vecPrivilegeJSON.end();iter++) + { + //the address of actionmanage + Address innerContract("0000000000000000000000000000000000000015"); + h256 InnerTo(dev::padded(innerContract.asBytes(),32)); + + Transaction t; + t = Transaction(value, gasPrice, gas, innerContract, data, i); + ++i; + + //the called function + h256 funsha = sha3(bytesConstRef("insert(string)")); + std::string strSha = funsha.hex(); + + std::string strParam = string2val(*iter); + std::string strData = std::string("0x") + strSha.substr(0,8) + strParam; + bytes data = jsToBytes(strData); + //cout << "strData=" << strData; + + Executive e(state, envInfo, *se); + ExecutionResult res; + e.setResultRecipient(res); + t.forceSender(sender); + + unordered_map> counts; + unsigned total = 0; + bigint memTotal; + auto onOp = [&](uint64_t step, uint64_t PC, Instruction inst, bigint m, bigint gasCost, bigint gas, VM* vm, ExtVMFace const* extVM) { + if (mode == Mode::Statistics) + { + counts[(byte)inst].first++; + counts[(byte)inst].second += gasCost; + total++; + if (m > 0) + memTotal = m; + } + else if (mode == Mode::Trace) + st(step, PC, inst, m, gasCost, gas, vm, extVM); + }; + + //cout << "run here"; + e.initialize(t); + if (!e.call(innerContract, sender, value, gasPrice, bytesConstRef(&data), gas)) + e.go(onOp); + e.finalize(); + //output = std::move(res.output); + //cout << "output=" << output << endl; + } + + { + std::string strParam1 = "{\"id\":\"admin\",\"name\":"; + strParam1 = strParam1 + "\"" + strBlockChainName + "\"" + ",\"serialNum\":0,\"parentId\":\"\",\"description\":\"blockchain plat\",\"commonName\":"; + strParam1 = strParam1 + "\"Juzhen\"" + ",\"stateName\":\"guangdong\",\"countryName\":\"china\",\"email\":\"test@126.com\",\"type\":0,\"admin\":"; + strParam1 = strParam1 + "\"" + sender.hex() +"\"" + ",\"ipList\":" + "[]" + ",\"roleIdList\":[],\"fileIdList\":" + strFileIdList + "}"; + //cout << "strParam1=" << strParam1; + + std::string strParam2 = std::string("{\"id\":") + "\"" + strid + "\"" + ",\"name\":"; + strParam2 = strParam2 + "\"" + strName + "\"" + ",\"serialNum\":1,\"parentId\":\"admin\",\"description\":\"blockchain plat\",\"commonName\":"; + strParam2 = strParam2 + "\"" + strCommonName + "\"" + ",\"stateName\":\"guangdong\",\"countryName\":\"china\",\"email\":\"test@126.com\",\"type\":1,\"admin\":"; + strParam2 = strParam2 + "\"" + sender.hex() +"\"" + ",\"ipList\":" + strIpList + ",\"roleIdList\":[],\"fileIdList\":" + strFileIdList + "}"; + //cout << "strParam2=" << strParam2; + //"[\"192.168.1.1\",\"10.71.1.1\",\"127.0.0.1\"] + vecDepartMentJSON.push_back(strParam1); + vecDepartMentJSON.push_back(strParam2); + + for (std::vector::iterator iter=vecDepartMentJSON.begin();iter!=vecDepartMentJSON.end();iter++) + { + //the address of departmentmanage + Address innerContract("0000000000000000000000000000000000000014"); + h256 InnerTo(dev::padded(innerContract.asBytes(),32)); + + + + //the called function + h256 funsha = sha3(bytesConstRef("insert(string)")); + std::string strSha = funsha.hex(); + + std::string strParam = string2val(*iter); + std::string strData = std::string("0x") + strSha.substr(0,8) + strParam; + bytes data = jsToBytes(strData); + //cout << "strData=" << strData; + + Transaction t; + t = Transaction(value, gasPrice, gas, innerContract, data, i); + ++i; + + Executive e(state, envInfo, *se); + ExecutionResult res; + e.setResultRecipient(res); + t.forceSender(sender); + + unordered_map> counts; + unsigned total = 0; + bigint memTotal; + auto onOp = [&](uint64_t step, uint64_t PC, Instruction inst, bigint m, bigint gasCost, bigint gas, VM* vm, ExtVMFace const* extVM) { + if (mode == Mode::Statistics) + { + counts[(byte)inst].first++; + counts[(byte)inst].second += gasCost; + total++; + if (m > 0) + memTotal = m; + } + else if (mode == Mode::Trace) + st(step, PC, inst, m, gasCost, gas, vm, extVM); + }; + + //cout << "run here"; + e.initialize(t); + if (!e.call(innerContract, sender, value, gasPrice, bytesConstRef(&data), gas)) + e.go(onOp); + e.finalize(); + //output = std::move(res.output); + } + + } + + + if (mode == Mode::Statistics) + { + int j = 0; + std::unordered_map state_cache; + state_cache = (*state.getStorageCash()); + for(std::unordered_map::const_iterator itc = state_cache.begin(); itc != state_cache.end(); itc++) + { + if(0 == itc->second.code().size()) + { + continue; + } + if(0 == j) + { + strOut = strOut + "\"" + (itc->first).hex() + "\": {\"code\":\"0x" + toHex(itc->second.code()) + "\""; + } + else + { + strOut = strOut + ",\"" + (itc->first).hex() + "\": {\"code\":\"0x" + toHex(itc->second.code()) + "\""; + } + + int k = 0; + int ksize = itc->second.storageOverlay().size() - 1; + //cout << "ksize=" << ksize + 1; + std::unordered_map accountCash = itc->second.storageOverlay(); + for(std::unordered_map::const_iterator iter = accountCash.begin(); iter != accountCash.end(); iter++) + { + if(0 == k) + { + strOut = strOut + ",\"storage\": {\"" + dev::toJS(toCompactBigEndian(iter->first, 32)) + "\":" + "\"" + dev::toJS(toCompactBigEndian(iter->second, 32)) + "\""; + } + else + { + strOut = strOut + ",\"" + dev::toJS(toCompactBigEndian(iter->first, 32)) + "\":" + "\"" + dev::toJS(toCompactBigEndian(iter->second, 32)) + "\""; + } + + + if(k == ksize) + { + strOut = strOut + "}"; + } + + k++; + } + j++; + strOut += "}"; + + } + + strOut += "}"; + } + + strOut += "}"; + //cout << "strOut" << strOut; + writeFile("./config/innerConfig.json",strOut); + //cout << "strOut=" << strOut; +} diff --git a/eth/main.cpp b/eth/main.cpp new file mode 100644 index 0000000000..6635a7e16e --- /dev/null +++ b/eth/main.cpp @@ -0,0 +1,1724 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** + * @file main.cpp + * @author Gav Wood + * @author Tasha Carl - I here by place all my contributions in this file under MIT licence, as specified by http://opensource.org/licenses/MIT. + * @date 2014 + * Ethereum client. + + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Farm.h" + +#include "AccountManager.h" +#include + + + +INITIALIZE_EASYLOGGINGPP + +using namespace std; +using namespace dev; +using namespace dev::p2p; +using namespace dev::eth; +using namespace boost::algorithm; + +static std::atomic g_silence = {false}; + +#include "genesisInfoForWe.h" +#include "GenesisInfo.h" + + +void help() +{ + cout + << "Usage eth [OPTIONS]" << endl + << "Options:" << endl << endl + << "Wallet usage:" << endl; + AccountManager::streamAccountHelp(cout); + AccountManager::streamWalletHelp(cout); + cout + << endl; + cout + << "Client mode (default):" << endl + << " --mainnet Use the main network protocol." << endl + << " --ropsten Use the Ropsten testnet." << endl + << " --private Use a private chain." << endl + << " --test Testing mode: Disable PoW and provide test rpc interface." << endl + << " --config Configure specialised blockchain using given JSON information." << endl + << " --oppose-dao-fork Ignore DAO hard fork (default is to participate)." << endl + << endl + << " -o,--mode Start a full node or a peer node (default: full)." << endl + << endl + << " -j,--json-rpc Enable JSON-RPC server (default: off)." << endl + << " --ipc Enable IPC server (default: on)." << endl + << " --ipcpath Set .ipc socket path (default: data directory)" << endl + << " --admin-via-http Expose admin interface via http - UNSAFE! (default: off)." << endl + << " --no-ipc Disable IPC server." << endl + << " --json-rpc-port Specify JSON-RPC server port (implies '-j', default: " << SensibleHttpPort << ")." << endl + << " --rpccorsdomain Domain on which to send Access-Control-Allow-Origin header." << endl + << " --admin Specify admin session key for JSON-RPC (default: auto-generated and printed at start-up)." << endl + << " -K,--kill Kill the blockchain first." << endl + << " -R,--rebuild Rebuild the blockchain from the existing database." << endl + << " --rescue Attempt to rescue a corrupt database." << endl + << endl + << " --import-presale Import a pre-sale key; you'll need to specify the password to this key." << endl + << " -s,--import-secret Import a secret key into the key store." << endl + << " --master Give the master password for the key store. Use --master \"\" to show a prompt." << endl + << " --password Give a password for a private key." << endl + << endl + << "Client transacting:" << endl + /*<< " -B,--block-fees Set the block fee profit in the reference unit, e.g. ¢ (default: 15)." << endl + << " -e,--ether-price Set the ether price in the reference unit, e.g. ¢ (default: 30.679)." << endl + << " -P,--priority <0 - 100> Set the default priority percentage (%) of a transaction (default: 50)." << endl*/ + << " --ask Set the minimum ask gas price under which no transaction will be mined (default " << toString(DefaultGasPrice) << " )." << endl + << " --bid Set the bid gas price to pay for transactions (default " << toString(DefaultGasPrice) << " )." << endl + << " --unsafe-transactions Allow all transactions to proceed without verification. EXTREMELY UNSAFE." + << endl + << "Client mining:" << endl + << " -a,--address Set the author (mining payout) address to given address (default: auto)." << endl + << " -m,--mining Enable mining, optionally for a specified number of blocks (default: off)." << endl + << " -f,--force-mining Mine even when there are no transactions to mine (default: off)." << endl + << " -C,--cpu When mining, use the CPU." << endl + << " -t, --mining-threads Limit number of CPU/GPU miners to n (default: use everything available on selected platform)." << endl + << endl + << "Client networking:" << endl + << " --client-name Add a name to your client's version string (default: blank)." << endl + << " --bootstrap Connect to the default Ethereum peer servers (default unless --no-discovery used)." << endl + << " --no-bootstrap Do not connect to the default Ethereum peer servers (default only when --no-discovery is used)." << endl + << " -x,--peers Attempt to connect to a given number of peers (default: 11)." << endl + << " --peer-stretch Give the accepted connection multiplier (default: 7)." << endl + + << " --public-ip Force advertised public IP to the given IP (default: auto)." << endl + << " --listen-ip (:) Listen on the given IP for incoming connections (default: 0.0.0.0)." << endl + << " --listen Listen on the given port for incoming connections (default: 30303)." << endl + << " -r,--remote (:) Connect to the given remote host (default: none)." << endl + << " --port Connect to the given remote port (default: 30303)." << endl + << " --network-id Only connect to other hosts with this network id." << endl + << " --upnp Use UPnP for NAT (default: on)." << endl + + << " --peerset Space delimited list of peers; element format: type:publickey@ipAddress[:port]." << endl + << " Types:" << endl + << " default Attempt connection when no other peers are available and pinning is disabled." << endl + << " required Keep connected at all times." << endl +// TODO: +// << " --trust-peers Space delimited list of publickeys." << endl + + << " --no-discovery Disable node discovery, implies --no-bootstrap." << endl + << " --pin Only accept or connect to trusted peers." << endl + << " --hermit Equivalent to --no-discovery --pin." << endl + << " --sociable Force discovery and no pinning." << endl + << endl; + //MinerCLI::streamHelp(cout); + cout + << "Import/export modes:" << endl + << " --from Export only from block n; n may be a decimal, a '0x' prefixed hash, or 'latest'." << endl + << " --to Export only to block n (inclusive); n may be a decimal, a '0x' prefixed hash, or 'latest'." << endl + << " --only Equivalent to --export-from n --export-to n." << endl + << " --dont-check Prevent checking some block aspects. Faster importing, but to apply only when the data is known to be valid." << endl + << endl + << "General Options:" << endl + << " -d,--db-path,--datadir Load database from path (default: " << getDataDir() << ")." << endl +#if ETH_EVMJIT + << " --vm Select VM; options are: interpreter, jit or smart (default: interpreter)." << endl +#endif // ETH_EVMJIT + << " -v,--verbosity <0 - 9> Set the log verbosity from 0 to 9 (default: 8)." << endl + << " -V,--version Show the version and exit." << endl + << " -h,--help Show this help message and exit." << endl + << endl + << "Experimental / Proof of Concept:" << endl + << " --shh Enable Whisper." << endl + << " --singlepoint Enable singlepoint." << endl + << endl + ; + exit(0); +} + +string ethCredits(bool _interactive = false) +{ + std::ostringstream cout; + cout + << "cpp-ethereum " << dev::Version << endl + << dev::Copyright << endl + << " See the README for contributors and credits." << endl; + + if (_interactive) + cout + << "Type 'exit' to quit" << endl << endl; + return cout.str(); +} + +void version() +{ + cout << "eth version " << dev::Version << endl; + cout << "eth network protocol version: " << dev::eth::c_protocolVersion << endl; + cout << "Client database version: " << dev::eth::c_databaseVersion << endl; + cout << "Build: " << DEV_QUOTED(ETH_BUILD_PLATFORM) << "/" << DEV_QUOTED(ETH_BUILD_TYPE) << endl; + exit(0); +} + +void generateNetworkRlp(string sFilePath) +{ + KeyPair kp = KeyPair::create(); + RLPStream netData(3); + netData << dev::p2p::c_protocolVersion << kp.secret().ref(); + int count = 0; + netData.appendList(count); + + writeFile(sFilePath, netData.out()); + writeFile(sFilePath + ".pub", kp.pub().hex()); + + cout << "eth generate network.rlp. " << endl; + cout << "eth public id is :[" << kp.pub().hex() << "]" << endl; + cout << "write into file [" << sFilePath << "]" << endl; + exit(0); +} + +/* +The equivalent of setlocale(LC_ALL, “C”) is called before any user code is run. +If the user has an invalid environment setting then it is possible for the call +to set locale to fail, so there are only two possible actions, the first is to +throw a runtime exception and cause the program to quit (default behaviour), +or the second is to modify the environment to something sensible (least +surprising behaviour). + +The follow code produces the least surprising behaviour. It will use the user +specified default locale if it is valid, and if not then it will modify the +environment the process is running in to use a sensible default. This also means +that users do not need to install language packs for their OS. +*/ +void setDefaultOrCLocale() +{ +#if __unix__ + if (!std::setlocale(LC_ALL, "")) + { + setenv("LC_ALL", "C", 1); + } +#endif +} + +void importPresale(KeyManager& _km, string const& _file, function _pass) +{ + KeyPair k = _km.presaleSecret(contentsString(_file), [&](bool) { return _pass(); }); + _km.import(k.secret(), "Presale wallet" + _file + " (insecure)"); +} + +Address c_config = Address("ccdeac59d35627b7de09332e819d5159e7bb7250"); +string pretty(h160 _a, dev::eth::State const& _st) +{ + string ns; + h256 n; + if (h160 nameReg = (u160)_st.storage(c_config, 0)) + n = _st.storage(nameReg, (u160)(_a)); + if (n) + { + std::string s((char const*)n.data(), 32); + if (s.find_first_of('\0') != string::npos) + s.resize(s.find_first_of('\0')); + ns = " " + s; + } + return ns; +} + +inline bool isPrime(unsigned _number) +{ + if (((!(_number & 1)) && _number != 2 ) || (_number < 2) || (_number % 3 == 0 && _number != 3)) + return false; + for (unsigned k = 1; 36 * k * k - 12 * k < _number; ++k) + if ((_number % (6 * k + 1) == 0) || (_number % (6 * k - 1) == 0)) + return false; + return true; +} + +enum class NodeMode +{ + PeerServer, + Full +}; + +enum class OperationMode +{ + Node, + Import, + Export, + ExportGenesis +}; + +enum class Format +{ + Binary, + Hex, + Human +}; + +void stopSealingAfterXBlocks(eth::Client* _c, unsigned _start, unsigned& io_mining) +{ + try + { + if (io_mining != ~(unsigned)0 && io_mining && _c->isMining() && _c->blockChain().details().number - _start == io_mining) + { + _c->stopSealing(); + + io_mining = ~(unsigned)0; + } + } + catch (InvalidSealEngine&) + { + } + + this_thread::sleep_for(chrono::milliseconds(100)); +} + +class ExitHandler: public SystemManager +{ +public: + void exit() { exitHandler(0); } + static void exitHandler(int sig) {s_shouldExit = true; LOG(TRACE) << "sig = " << sig << ",s_shouldExit=" << s_shouldExit;} + bool shouldExit() const { return s_shouldExit; } + +private: + static bool s_shouldExit; +}; + +bool ExitHandler::s_shouldExit = false; + +static map s_mlogIndex; + +void rolloutHandler(const char* filename, std::size_t ) +{ + std::stringstream stream; + + map::iterator iter = s_mlogIndex.find(filename); + if (iter != s_mlogIndex.end()) + { + stream << filename << "." << iter->second++; + s_mlogIndex[filename] = iter->second++; + } + else + { + stream << filename << "." << 0; + s_mlogIndex[filename] = 0; + } + boost::filesystem::rename(filename, stream.str().c_str()); +} + +//日志配置文件放到log目录 +void initEasylogging(string logconf) +{ + el::Loggers::addFlag(el::LoggingFlag::MultiLoggerSupport); // Enables support for multiple loggers + el::Loggers::addFlag(el::LoggingFlag::StrictLogFileSizeCheck); + if (el::base::utils::File::pathExists(logconf.c_str(), true)) + { + el::Logger* fileLogger = el::Loggers::getLogger("fileLogger"); // Register new logger + el::Configurations conf(logconf.c_str()); + el::Configurations allConf; + allConf.set(conf.get(el::Level::Global, el::ConfigurationType::Enabled)); + allConf.set(conf.get(el::Level::Global, el::ConfigurationType::ToFile)); + allConf.set(conf.get(el::Level::Global, el::ConfigurationType::ToStandardOutput)); + allConf.set(conf.get(el::Level::Global, el::ConfigurationType::Format)); + allConf.set(conf.get(el::Level::Global, el::ConfigurationType::Filename)); + allConf.set(conf.get(el::Level::Global, el::ConfigurationType::SubsecondPrecision)); + allConf.set(conf.get(el::Level::Global, el::ConfigurationType::MillisecondsWidth)); + allConf.set(conf.get(el::Level::Global, el::ConfigurationType::PerformanceTracking)); + allConf.set(conf.get(el::Level::Global, el::ConfigurationType::MaxLogFileSize)); + allConf.set(conf.get(el::Level::Global, el::ConfigurationType::LogFlushThreshold)); + el::Loggers::reconfigureLogger("default", allConf); + el::Loggers::reconfigureLogger(fileLogger, conf); + } + el::Helpers::installPreRollOutCallback(rolloutHandler); +} + +bool isTrue(std::string const& _m) +{ + return _m == "on" || _m == "yes" || _m == "true" || _m == "1"; +} + +bool isFalse(std::string const& _m) +{ + return _m == "off" || _m == "no" || _m == "false" || _m == "0"; +} + +int main(int argc, char** argv) +{ + setDefaultOrCLocale(); + + // Init defaults + Defaults::get(); + NoProof::init(); + PBFT::init(); + //RaftSealEngine::init(); + Raft::init(); + SinglePoint::init(); + + g_logVerbosity = 4; + + /// Operating mode. + OperationMode mode = OperationMode::Node; +// unsigned prime = 0; +// bool yesIReallyKnowWhatImDoing = false; + strings scripts; + + /// File name for import/export. + string filename; + bool safeImport = false; + + /// Hashes/numbers for export range. + string exportFrom = "1"; + string exportTo = "latest"; + Format exportFormat = Format::Binary; + + /// General params for Node operation + NodeMode nodeMode = NodeMode::Full; + bool interactive = false; + + int jsonRPCURL = -1; + bool adminViaHttp = true; + bool ipc = true; + std::string rpcCorsDomain = ""; + + string jsonAdmin; + ChainParams chainParams(genesisInfo(eth::Network::MainNetwork), genesisStateRoot(eth::Network::MainNetwork)); + u256 gasFloor = Invalid256; + string privateChain; + + bool upnp = true; + WithExisting withExisting = WithExisting::Trust; + + /// Networking params. + string clientName; + string listenIP; + unsigned short listenPort = 16789; + string publicIP; + string remoteHost; + unsigned short remotePort = 16789; + + unsigned peers = 11; + unsigned peerStretch = 7; + std::map> preferredNodes; + bool bootstrap = true; + bool disableDiscovery = true; + bool pinning = false; + bool enableDiscovery = false; + bool noPinning = false; + static const unsigned NoNetworkID = (unsigned) - 1; + unsigned networkID = NoNetworkID; + + /// Mining params + unsigned mining = ~(unsigned)0; + Address author; + LOG(TRACE) << " Main:: author: " << author; + strings presaleImports; + bytes extraData; + + /// Transaction params +// TransactionPriority priority = TransactionPriority::Medium; +// double etherPrice = 30.679; +// double blockFees = 15.0; + u256 askPrice = DefaultGasPrice; + u256 bidPrice = DefaultGasPrice; + bool alwaysConfirm = true; + + /// Wallet password stuff + string masterPassword; + bool masterSet = false; + + /// Whisper + bool useWhisper = false; + bool testingMode = false; + + bool singlepoint = false; + + //string configFile = getDataDir() + "/config.rlp"; + //bytes b = contents(configFile); + //LOG(TRACE)<<"configFile="<(); + LOG(TRACE) << " Main:: author2: " << author; + } + catch (...) {} + }*/ + + if (argc > 1 && (string(argv[1]) == "wallet" || string(argv[1]) == "account")) + { + string ret; + cout << "请输入keystore 保存路径:"; + getline(cin, ret); + SecretStore::defaultpath = ret; + cout << "keystoredir:" << SecretStore::defaultPath() << endl; + AccountManager accountm; + return !accountm.execute(argc, argv); + } + + + //MinerCLI m(MinerCLI::OperationMode::None); + + bool listenSet = false; + string configJSON; + string genesisJSON; + string godminerJSON; + + int blockNumber = 0; + std::string contracts; + string innerJSON; + + //dfs related parameters + string strNodeId; + string strGroupId; + string strStoragePath; + Address fileContractAddr; + Address fileServerContractAddr; + + //extract input parameters + for (int i = 1; i < argc; ++i) + { + string arg = argv[i]; + /*if (m.interpretOption(i, argc, argv)) + { + } + else */if (arg == "--listen-ip" && i + 1 < argc) + { + listenIP = argv[++i]; + listenSet = true; + } + else if ((arg == "--listen" || arg == "--listen-port") && i + 1 < argc) + { + listenPort = (short)atoi(argv[++i]); + listenSet = true; + } + else if ((arg == "--public-ip" || arg == "--public") && i + 1 < argc) + { + publicIP = argv[++i]; + } + else if ((arg == "-r" || arg == "--remote") && i + 1 < argc) + { + string host = argv[++i]; + string::size_type found = host.find_first_of(':'); + if (found != std::string::npos) + { + remoteHost = host.substr(0, found); + remotePort = (short)atoi(host.substr(found + 1, host.length()).c_str()); + } + else + remoteHost = host; + } + else if (arg == "--port" && i + 1 < argc) + { + remotePort = (short)atoi(argv[++i]); + } + else if (arg == "--password" && i + 1 < argc) + passwordsToNote.push_back(argv[++i]); + else if (arg == "--master" && i + 1 < argc) + { + masterPassword = argv[++i]; + masterSet = true; + } + //创世块合约列表 + else if ((arg == "--contracts") && i + 1 < argc) { + contracts = argv[++i]; + } + //创世块blocknumber + else if ((arg == "--blocknumber") && i + 1 < argc) { + blockNumber = atoi(argv[++i]); + } + //创世块路径 + else if ((arg == "--export-genesis") && i + 1 < argc) { + mode = OperationMode::ExportGenesis; + filename = argv[++i]; + } + else if ((arg == "-I" || arg == "--import" || arg == "import") && i + 1 < argc) + { + mode = OperationMode::Import; + filename = argv[++i]; + } + else if (arg == "--dont-check") + safeImport = true; + else if ((arg == "-E" || arg == "--export" || arg == "export") && i + 1 < argc) + { + mode = OperationMode::Export; + filename = argv[++i]; + } + else if (arg == "--script" && i + 1 < argc) + scripts.push_back(argv[++i]); + else if (arg == "--format" && i + 1 < argc) + { + string m = argv[++i]; + if (m == "binary") + exportFormat = Format::Binary; + else if (m == "hex") + exportFormat = Format::Hex; + else if (m == "human") + exportFormat = Format::Human; + else + { + LOG(ERROR) << "Bad " << arg << " option: " << m << endl; + return -1; + } + } + else if (arg == "--to" && i + 1 < argc) + exportTo = argv[++i]; + else if (arg == "--from" && i + 1 < argc) + exportFrom = argv[++i]; + else if (arg == "--only" && i + 1 < argc) + exportTo = exportFrom = argv[++i]; + else if (arg == "--upnp" && i + 1 < argc) + { + string m = argv[++i]; + if (isTrue(m)) + upnp = true; + else if (isFalse(m)) + upnp = false; + else + { + LOG(ERROR) << "Bad " << arg << " option: " << m << endl; + return -1; + } + } + else if (arg == "--network-id" && i + 1 < argc) + try { + networkID = stol(argv[++i]); + } + catch (...) + { + LOG(ERROR) << "Bad " << arg << " option: " << argv[i] << endl; + return -1; + } + else if (arg == "--private" && i + 1 < argc) + try { + privateChain = argv[++i]; + } + catch (...) + { + LOG(ERROR) << "Bad " << arg << " option: " << argv[i] << endl; + return -1; + } + else if (arg == "--independent" && i + 1 < argc) + try { + privateChain = argv[++i]; + noPinning = enableDiscovery = true; + } + catch (...) + { + LOG(ERROR) << "Bad " << arg << " option: " << argv[i] << endl; + return -1; + } + else if (arg == "-K" || arg == "--kill-blockchain" || arg == "--kill") + withExisting = WithExisting::Kill; + else if (arg == "-R" || arg == "--rebuild") + withExisting = WithExisting::Verify; + else if (arg == "-R" || arg == "--rescue") + withExisting = WithExisting::Rescue; + else if (arg == "--client-name" && i + 1 < argc) + clientName = argv[++i]; + else if ((arg == "-a" || arg == "--address" || arg == "--author") && i + 1 < argc) + try { + author = h160(fromHex(argv[++i], WhenError::Throw)); + + } + catch (BadHexCharacter&) + { + LOG(ERROR) << "Bad hex in " << arg << " option: " << argv[i] << endl; + return -1; + } + catch (...) + { + LOG(ERROR) << "Bad " << arg << " option: " << argv[i] << endl; + return -1; + } + else if ((arg == "-s" || arg == "--import-secret") && i + 1 < argc) + { + Secret s(fromHex(argv[++i])); + toImport.emplace_back(s); + } + else if ((arg == "-S" || arg == "--import-session-secret") && i + 1 < argc) + { + Secret s(fromHex(argv[++i])); + toImport.emplace_back(s); + } + else if ((arg == "-d" || arg == "--path" || arg == "--db-path" || arg == "--datadir") && i + 1 < argc) + setDataDir(argv[++i]); + else if (arg == "--ipcpath" && i + 1 < argc ) + setIpcPath(argv[++i]); + else if ((arg == "--genesis-json" || arg == "--genesis") && i + 1 < argc) + { + try + { + genesisJSON = contentsString(argv[++i]); + } + catch (...) + { + LOG(ERROR) << "Bad " << arg << " option: " << argv[i] << endl; + return -1; + } + } + else if (arg == "--config" && i + 1 < argc) + { + try + { + setConfigPath(argv[++i]); + configJSON = contentsString(getConfigPath()); + } + catch (...) + { + LOG(ERROR) << "Bad " << arg << " option: " << argv[i] << endl; + return -1; + } + } + else if (arg == "--extra-data" && i + 1 < argc) + { + try + { + extraData = fromHex(argv[++i]); + } + catch (...) + { + LOG(ERROR) << "Bad " << arg << " option: " << argv[i] << endl; + return -1; + } + } + else if (arg == "--gas-floor" && i + 1 < argc) + gasFloor = u256(argv[++i]); + else if (arg == "--mainnet") + chainParams = ChainParams(genesisInfo(eth::Network::MainNetwork), genesisStateRoot(eth::Network::MainNetwork)); + else if (arg == "--ropsten" || arg == "--testnet") + chainParams = ChainParams(genesisInfo(eth::Network::Ropsten), genesisStateRoot(eth::Network::Ropsten)); + else if (arg == "--oppose-dao-fork") + { + chainParams = ChainParams(genesisInfo(eth::Network::MainNetwork), genesisStateRoot(eth::Network::MainNetwork)); + chainParams.otherParams["daoHardforkBlock"] = toHex(u256(-1) - 10, HexPrefix::Add); + } + else if (arg == "--support-dao-fork") + { + // default + } + else if (arg == "--bob") + { + cout << "Asking Bob for blocks (this should work in theoreum)..." << endl; + while (true) + { + u256 x(h256::random()); + u256 c; + for (; x != 1; ++c) + { + x = (x & 1) == 0 ? x / 2 : 3 * x + 1; + cout << toHex(x) << endl; + this_thread::sleep_for(chrono::seconds(1)); + } + cout << "Block number: " << hex << c << endl; + exit(0); + } + } + /* else if ((arg == "-B" || arg == "--block-fees") && i + 1 < argc) + { + try + { + blockFees = stof(argv[++i]); + } + catch (...) + { + LOG(ERROR) << "Bad " << arg << " option: " << argv[i] << endl; + return -1; + } + } + else if ((arg == "-e" || arg == "--ether-price") && i + 1 < argc) + { + try + { + etherPrice = stof(argv[++i]); + } + catch (...) + { + LOG(ERROR) << "Bad " << arg << " option: " << argv[i] << endl; + return -1; + } + }*/ + else if (arg == "--ask" && i + 1 < argc) + { + try + { + askPrice = u256(argv[++i]); + } + catch (...) + { + LOG(ERROR) << "Bad " << arg << " option: " << argv[i] << endl; + return -1; + } + } + else if (arg == "--bid" && i + 1 < argc) + { + try + { + bidPrice = u256(argv[++i]); + } + catch (...) + { + LOG(ERROR) << "Bad " << arg << " option: " << argv[i] << endl; + return -1; + } + } + /* else if ((arg == "-P" || arg == "--priority") && i + 1 < argc) + { + string m = boost::to_lower_copy(string(argv[++i])); + if (m == "lowest") + priority = TransactionPriority::Lowest; + else if (m == "low") + priority = TransactionPriority::Low; + else if (m == "medium" || m == "mid" || m == "default" || m == "normal") + priority = TransactionPriority::Medium; + else if (m == "high") + priority = TransactionPriority::High; + else if (m == "highest") + priority = TransactionPriority::Highest; + else + try { + priority = (TransactionPriority)(max(0, min(100, stoi(m))) * 8 / 100); + } + catch (...) { + LOG(ERROR) << "Unknown " << arg << " option: " << m << endl; + return -1; + } + }*/ + else if ((arg == "-m" || arg == "--mining") && i + 1 < argc) + { + string m = argv[++i]; + if (isTrue(m)) + mining = ~(unsigned)0; + else if (isFalse(m)) + mining = 0; + else + try { + mining = stoi(m); + } + catch (...) { + LOG(ERROR) << "Unknown " << arg << " option: " << m << endl; + return -1; + } + } + else if (arg == "-b" || arg == "--bootstrap") + bootstrap = true; + else if (arg == "--no-bootstrap") + bootstrap = false; + else if (arg == "--no-discovery") + { + disableDiscovery = true; + bootstrap = false; + } + else if (arg == "--pin") + pinning = true; + else if (arg == "--hermit") + pinning = disableDiscovery = true; + else if (arg == "--sociable") + noPinning = enableDiscovery = true; + else if (arg == "--unsafe-transactions") + alwaysConfirm = false; + else if (arg == "--import-presale" && i + 1 < argc) + presaleImports.push_back(argv[++i]); + else if (arg == "--old-interactive") + interactive = true; + + else if ((arg == "-j" || arg == "--json-rpc")) + jsonRPCURL = jsonRPCURL == -1 ? SensibleHttpPort : jsonRPCURL; + else if (arg == "--admin-via-http") + adminViaHttp = true; + else if (arg == "--json-rpc-port" && i + 1 < argc) + jsonRPCURL = atoi(argv[++i]); + else if (arg == "--rpccorsdomain" && i + 1 < argc) + rpcCorsDomain = argv[++i]; + else if (arg == "--json-admin" && i + 1 < argc) + jsonAdmin = argv[++i]; + else if (arg == "--ipc") + ipc = true; + else if (arg == "--no-ipc") + ipc = false; + + else if ((arg == "-v" || arg == "--verbosity") && i + 1 < argc) + g_logVerbosity = atoi(argv[++i]); + else if ((arg == "-x" || arg == "--peers") && i + 1 < argc) + peers = atoi(argv[++i]); + else if (arg == "--peer-stretch" && i + 1 < argc) + peerStretch = atoi(argv[++i]); + else if (arg == "--peerset" && i + 1 < argc) + { + string peerset = argv[++i]; + if (peerset.empty()) + { + LOG(ERROR) << "--peerset argument must not be empty"; + return -1; + } + + vector each; + boost::split(each, peerset, boost::is_any_of("\t ")); + for (auto const& p : each) + { + string type; + string pubk; + string hostIP; + unsigned short port = c_defaultListenPort; + + // type:key@ip[:port] + vector typeAndKeyAtHostAndPort; + boost::split(typeAndKeyAtHostAndPort, p, boost::is_any_of(":")); + if (typeAndKeyAtHostAndPort.size() < 2 || typeAndKeyAtHostAndPort.size() > 3) + continue; + + type = typeAndKeyAtHostAndPort[0]; + if (typeAndKeyAtHostAndPort.size() == 3) + port = (uint16_t)atoi(typeAndKeyAtHostAndPort[2].c_str()); + + vector keyAndHost; + boost::split(keyAndHost, typeAndKeyAtHostAndPort[1], boost::is_any_of("@")); + if (keyAndHost.size() != 2) + continue; + pubk = keyAndHost[0]; + if (pubk.size() != 128) + continue; + hostIP = keyAndHost[1]; + + // todo: use Network::resolveHost() + if (hostIP.size() < 4 /* g.it */) + continue; + + bool required = type == "required"; + if (!required && type != "default") + continue; + + Public publicKey(fromHex(pubk)); + try + { + preferredNodes[publicKey] = make_pair(NodeIPEndpoint(bi::address::from_string(hostIP), port, port), required); + } + catch (...) + { + LOG(ERROR) << "Unrecognized peerset: " << peerset << endl; + return -1; + } + } + } + else if ((arg == "-o" || arg == "--mode") && i + 1 < argc) + { + string m = argv[++i]; + if (m == "full") + nodeMode = NodeMode::Full; + else if (m == "peer") + nodeMode = NodeMode::PeerServer; + else + { + LOG(ERROR) << "Unknown mode: " << m << endl; + return -1; + } + } +#if ETH_EVMJIT + else if (arg == "--vm" && i + 1 < argc) + { + string vmKind = argv[++i]; + if (vmKind == "interpreter") + VMFactory::setKind(VMKind::Interpreter); + else if (vmKind == "jit") + VMFactory::setKind(VMKind::JIT); + else if (vmKind == "smart") + VMFactory::setKind(VMKind::Smart); + else + { + LOG(ERROR) << "Unknown VM kind: " << vmKind << endl; + return -1; + } + } +#endif + else if (arg == "--shh") + useWhisper = true; + else if (arg == "-h" || arg == "--help") + help(); + else if (arg == "-V" || arg == "--version") + version(); + else if (arg == "--cainittype") + { + setCaInitType(argv[++i]); + } + else if (arg == "--gennetworkrlp") + { + string sFilePath = argv[++i]; + generateNetworkRlp(sFilePath); + } + else if (arg == "--test") + { + testingMode = true; + enableDiscovery = false; + disableDiscovery = true; + noPinning = true; + bootstrap = false; + } + else if ( arg == "--singlepoint" ) + { + singlepoint = true; + enableDiscovery = false; + disableDiscovery = true; + noPinning = true; + bootstrap = false; + } + else if( arg == "--godminer" ) + { + try + { + godminerJSON = contentsString(argv[++i]); + } + catch (...) + { + cerr << "上帝模式参数文件异常! " << arg << " option: " << argv[i] << endl; + exit(-1); + } + + } + else + { + LOG(ERROR) << "Invalid argument: " << arg << endl; + exit(-1); + } + } + + if(configJSON.empty()){ + setConfigPath(getDataDir("ethereum") + "/config.json"); + configJSON = contentsString(getConfigPath()); + } + + if (!configJSON.empty()) + { + try + { + chainParams = chainParams.loadConfig(configJSON); + //初始化日志 + initEasylogging(chainParams.logFileConf); + } + catch (std::exception &e) + { + LOG(ERROR) << "provided configuration is not well formatted" << e.what() << endl; + LOG(ERROR) << "sample: " << endl << c_configJsonForWe << endl; + return 0; + } + } + else + { + LOG(ERROR) << "请指定配置文件 --config xxx" << endl; + LOG(ERROR) << "sample: " << endl << c_configJsonForWe << endl; + return 0; + } + + if (!godminerJSON.empty()) + { + try + { + chainParams = chainParams.loadGodMiner(godminerJSON); + + if( chainParams.godMinerStart< 1 ) + { + cerr << "上帝模式配置异常 godMinerStart不能小于0 "<< endl; + exit(-1); + } + if( chainParams.godMinerEnd<=chainParams.godMinerStart ) + { + cerr << "上帝模式配置异常 godMinerEnd<=godMinerStart "<< endl; + exit(-1); + } + if( chainParams.godMinerList.size() < 1 ) + { + cerr << "上帝模式配置异常 godMinerList不能为空 "<< endl; + exit(-1); + } + + cout<<"开启上帝模式!!!!! "<<"godMinerStart="< 0) + cout << EthGrayBold "---------------cpp-ethereum, a C++ Ethereum client--------------" EthReset << endl; + + chainParams.otherParams["allowFutureBlocks"] = "1";//默认打开 + if (testingMode) + { + chainParams.sealEngineName = "NoProof"; + } + else if ( singlepoint ) + { + chainParams.sealEngineName = "SinglePoint"; + } + if ( "SinglePoint" == chainParams.sealEngineName ) + { + enableDiscovery = false; + disableDiscovery = true; + noPinning = true; + bootstrap = false; + } + + //以配置文件中为准 + + cout << "RPCPORT:" << chainParams.rpcPort << endl; + cout << "LISTENIP:" << chainParams.listenIp << endl; + cout << "P2PPORT:" << chainParams.p2pPort << endl; + cout << "WALLET:" << chainParams.wallet << endl; + cout << "KEYSTOREDIR:" << chainParams.keystoreDir << endl; + cout << "DATADIR:" << chainParams.dataDir << endl; + cout << "VM:" << chainParams.vmKind << endl; + cout << "SEALENGINE:" << chainParams.sealEngineName << endl; + cout << "NETWORKID:" << chainParams.networkId << endl; + cout << "SYSTEMPROXYADDRESS:" << chainParams.sysytemProxyAddress << endl; + cout << "GOD:" << chainParams.god << endl; + cout << "LOGVERBOSITY:" << chainParams.logVerbosity << endl; + cout << "EVENTLOG:" << (chainParams.evmEventLog ? "ON" : "OFF") << endl; + cout << "COVERLOG:" << (chainParams.evmCoverLog ? "ON" : "OFF") << endl; + + jsonRPCURL = chainParams.rpcPort; + setDataDir(chainParams.dataDir); + listenIP = chainParams.listenIp; + if ( !listenIP.empty() ) + listenSet = true; + listenPort = chainParams.p2pPort; + remotePort = chainParams.p2pPort; + c_defaultListenPort = chainParams.p2pPort; + c_defaultIPPort = chainParams.p2pPort; + SecretStore::defaultpath = chainParams.keystoreDir; + KeyManager::defaultpath = chainParams.wallet; + networkID = chainParams.networkId; + g_logVerbosity = chainParams.logVerbosity; + strNodeId = chainParams.nodeId; + strGroupId = chainParams.groupId; + strStoragePath = chainParams.storagePath; + + + if (chainParams.vmKind == "interpreter") + VMFactory::setKind(VMKind::Interpreter); + else if (chainParams.vmKind == "jit") + VMFactory::setKind(VMKind::JIT); + else if (chainParams.vmKind == "smart") + VMFactory::setKind(VMKind::Smart); + else if (chainParams.vmKind == "dual") + VMFactory::setKind(VMKind::Dual); + else + { + LOG(ERROR) << "Error :Unknown VM kind " << chainParams.vmKind << endl; + return -1; + } + + cout << EthGrayBold "---------------------------------------------------------------" EthReset << endl; + + + //m.execute(); + + std::string secretsPath; + if (testingMode) + secretsPath = chainParams.keystoreDir; // (boost::filesystem::path(getDataDir()) / "keystore").string(); + else + secretsPath = SecretStore::defaultPath(); + + KeyManager keyManager(KeyManager::defaultPath(), secretsPath); + for (auto const& s : passwordsToNote) + keyManager.notePassword(s); + + // the first value is deprecated (never used) + //writeFile(configFile, rlpList(author, author)); + + if (!clientName.empty()) + clientName += "/"; + + string logbuf; + std::string additional; + if (interactive) + g_logPost = [&](std::string const & a, char const*) { + static SpinLock s_lock; + SpinGuard l(s_lock); + + if (g_silence) + logbuf += a + "\n"; + else + cout << "\r \r" << a << endl << additional << flush; + + // helpful to use OutputDebugString on windows +#if defined(_WIN32) + { + OutputDebugStringA(a.data()); + OutputDebugStringA("\n"); + } +#endif + }; + + auto getPassword = [&](string const & prompt) { + bool s = g_silence; + g_silence = true; + cout << endl; + string ret = dev::getPassword(prompt); + g_silence = s; + return ret; + }; + /*auto getResponse = [&](string const& prompt, unordered_set const& acceptable) { + bool s = g_silence; + g_silence = true; + cout << endl; + string ret; + while (true) + { + cout << prompt; + getline(cin, ret); + if (acceptable.count(ret)) + break; + cout << "Invalid response: " << ret << endl; + } + g_silence = s; + return ret; + };*/ + auto getAccountPassword = [&](Address const & ) { + + cout << "!!!!!!请通过web3解锁帐号!!!!!" << endl; + return string(); + + //return getPassword("Enter password for address " + keyManager.accountName(a) + " (" + a.abridged() + "; hint:" + keyManager.passwordHint(a) + "): "); + }; + + auto netPrefs = publicIP.empty() ? NetworkPreferences(listenIP, listenPort, upnp) : NetworkPreferences(publicIP, listenIP , listenPort, upnp); + netPrefs.discovery = (privateChain.empty() && !disableDiscovery) || enableDiscovery; + netPrefs.pin = (pinning || !privateChain.empty()) && !noPinning; + + auto nodesState = contents(getDataDir() + "/network.rlp"); + + auto caps = useWhisper ? set {"eth", "shh"} : set {"eth"}; + + + //建立web3网络 + dev::WebThreeDirect web3( + WebThreeDirect::composeClientVersion("eth"), + getDataDir(), + chainParams, + withExisting, + nodeMode == NodeMode::Full ? caps : set(), + netPrefs, + &nodesState, + testingMode + ); + + cout << "NodeID=" << toString(web3.id()) << endl; + + if (!extraData.empty()) + web3.ethereum()->setExtraData(extraData); + + auto toNumber = [&](string const & s) -> unsigned { + if (s == "latest") + return web3.ethereum()->number(); + if (s.size() == 64 || (s.size() == 66 && s.substr(0, 2) == "0x")) + return web3.ethereum()->blockChain().number(h256(s)); + try { + return stol(s); + } + catch (...) + { + LOG(ERROR) << "Bad block number/hash option: " << s << endl; + exit(-1); + } + }; + + //生成创世块 + if (mode == OperationMode::ExportGenesis) { + cnote << "生成创世块到:" << filename; + + ofstream fout(filename, std::ofstream::binary); + ostream& out = (filename.empty() || filename == "--") ? cout : fout; + + auto state = web3.ethereum()->block( + web3.ethereum()->blockChain().currentHash()).state(); + + if (blockNumber > 0) { + state = web3.ethereum()->block(blockNumber).state(); + } + + std::vector splitContract; + boost::split(splitContract, contracts, boost::is_any_of(";")); + + std::vector
contractList; + for (auto it = splitContract.begin(); it != splitContract.end(); ++it) { + if (!it->empty()) { + contractList.push_back(Address(*it)); + } + } + + if (contractList.empty()) { + cnote << "未指定合约地址列表,导出所有合约"; + unordered_map contractMap = state.addresses(); + + for (auto it = contractMap.begin(); it != contractMap.end(); ++it) { + contractList.push_back(it->first); + } + } + + Json::Value genesis; + Json::Reader reader; + reader.parse(genesisJSON, genesis, false); + + //写入json + Json::Value root; + Json::FastWriter writer; + + root["nonce"] = genesis["nonce"]; + root["difficulty"] = genesis["difficulty"]; + root["mixhash"] = genesis["mixhash"]; + root["coinbase"] = genesis["coinbase"]; + root["timestamp"] = genesis["timestamp"]; + root["parentHash"] = genesis["parentHash"]; + root["extraData"] = genesis["extraData"]; + root["gasLimit"] = genesis["gasLimit"]; + root["god"] = genesis["god"]; + root["initMinerNodes"] = genesis["initMinerNodes"]; + + Json::Value alloc; + auto allocFlag = false; + for (auto it = contractList.begin(); it != contractList.end(); ++it) { + cnote << "导出合约:" << *it; + + u256 balance = state.balance(*it); + bytes code = state.code(*it); + u256 nonce = state.getNonce(*it); + + auto storage = state.storage(*it); + + Json::Value contract; + contract["balance"] = toString(balance); + contract["code"] = toHex(code, 2, dev::HexPrefix::Add); + contract["nonce"] = toString(nonce); + + Json::Value storageJson; + auto flag = false; + for (auto storageIt = storage.begin(); storageIt != storage.end(); ++storageIt) { + storageJson[toString(storageIt->second.first)] = toString(storageIt->second.second); + flag = true; + } + if (flag) + { + contract["storage"] = storageJson; + } + alloc[it->hex()] = contract; + allocFlag = true; + } + if (allocFlag) + { + root["alloc"] = alloc; + } + else + { + root["alloc"] = "{}"; + } + + out << writer.write(root); + + out.flush(); + exit(0); + return 0; + } + + if (mode == OperationMode::Export) + { + ofstream fout(filename, std::ofstream::binary); + ostream& out = (filename.empty() || filename == "--") ? cout : fout; + + unsigned last = toNumber(exportTo); + for (unsigned i = toNumber(exportFrom); i <= last; ++i) + { + bytes block = web3.ethereum()->blockChain().block(web3.ethereum()->blockChain().numberHash(i)); + switch (exportFormat) + { + case Format::Binary: out.write((char const*)block.data(), block.size()); break; + case Format::Hex: out << toHex(block) << endl; break; + case Format::Human: out << RLP(block) << endl; break; + default:; + } + } + return 0; + } + + if (mode == OperationMode::Import) + { + ifstream fin(filename, std::ifstream::binary); + istream& in = (filename.empty() || filename == "--") ? cin : fin; + unsigned alreadyHave = 0; + unsigned good = 0; + unsigned futureTime = 0; + unsigned unknownParent = 0; + unsigned bad = 0; + chrono::steady_clock::time_point t = chrono::steady_clock::now(); + double last = 0; + unsigned lastImported = 0; + unsigned imported = 0; + while (in.peek() != -1) + { + bytes block(8); + in.read((char*)block.data(), 8); + block.resize(RLP(block, RLP::LaissezFaire).actualSize()); + in.read((char*)block.data() + 8, block.size() - 8); + + switch (web3.ethereum()->queueBlock(block, safeImport)) + { + case ImportResult::Success: good++; break; + case ImportResult::AlreadyKnown: alreadyHave++; break; + case ImportResult::UnknownParent: unknownParent++; break; + case ImportResult::FutureTimeUnknown: unknownParent++; futureTime++; break; + case ImportResult::FutureTimeKnown: futureTime++; break; + default: bad++; break; + } + + // sync chain with queue + tuple r = web3.ethereum()->syncQueue(10); + imported += get<2>(r); + + double e = chrono::duration_cast(chrono::steady_clock::now() - t).count() / 1000.0; + if ((unsigned)e >= last + 10) + { + auto i = imported - lastImported; + auto d = e - last; + cout << i << " more imported at " << (round(i * 10 / d) / 10) << " blocks/s. " << imported << " imported in " << e << " seconds at " << (round(imported * 10 / e) / 10) << " blocks/s (#" << web3.ethereum()->number() << ")" << endl; + last = (unsigned)e; + lastImported = imported; +// cout << web3.ethereum()->blockQueueStatus() << endl; + } + } + + while (web3.ethereum()->blockQueue().items().first + web3.ethereum()->blockQueue().items().second > 0) + { + this_thread::sleep_for(chrono::seconds(1)); + web3.ethereum()->syncQueue(100000); + } + double e = chrono::duration_cast(chrono::steady_clock::now() - t).count() / 1000.0; + cout << imported << " imported in " << e << " seconds at " << (round(imported * 10 / e) / 10) << " blocks/s (#" << web3.ethereum()->number() << ")" << endl; + return 0; + } + + try + { + if (keyManager.exists()) + { + if (!keyManager.load(masterPassword) && masterSet) + { + while (true) + { + masterPassword = getPassword("Please enter your MASTER password: "); + if (keyManager.load(masterPassword)) + break; + cout << "The password you entered is incorrect. If you have forgotten your password, and you wish to start afresh, manually remove the file: " + getDataDir("ethereum") + "/keys.info" << endl; + } + } + } + else + { + + + if (masterSet) + keyManager.create(masterPassword); + else + keyManager.create(std::string()); + + } + } + catch (...) + { + LOG(ERROR) << "Error initializing key manager: " << boost::current_exception_diagnostic_information() << endl; + return -1; + } + + for (auto const& presale : presaleImports) + importPresale(keyManager, presale, [&]() { return getPassword("Enter your wallet password for " + presale + ": "); }); + + for (auto const& s : toImport) + { + keyManager.import(s, "Imported key (UNSAFE)"); + } + + cout << ethCredits(); + web3.setIdealPeerCount(peers); + web3.setPeerStretch(peerStretch); +// std::shared_ptr gasPricer = make_shared(u256(double(ether / 1000) / etherPrice), u256(blockFees * 1000)); + std::shared_ptr gasPricer = make_shared(askPrice, bidPrice); + eth::Client* c = nodeMode == NodeMode::Full ? web3.ethereum() : nullptr; + if (c) + { + c->setGasPricer(gasPricer); + //DEV_IGNORE_EXCEPTIONS(asEthashClient(c)->setShouldPrecomputeDAG(true/*m.shouldPrecompute()*/)); + c->setSealer(""/*m.minerType()*/); + c->setAuthor(author); + if (networkID != NoNetworkID) + c->setNetworkId(networkID); + } + + auto renderFullAddress = [&](Address const & _a) -> std::string + { + return ICAP(_a).encoded() + " (" + toUUID(keyManager.uuid(_a)) + " - " + toHex(_a.ref().cropped(0, 4)) + ")"; + }; + + if (author) + LOG(TRACE) << " Main:: Mining Beneficiary: " << renderFullAddress(author) << "," << author; + + if (bootstrap || !remoteHost.empty() || enableDiscovery || listenSet) + { + //启动网络 + web3.startNetwork(); + cout << "Node ID: " << web3.enode() << endl; + } + else + cout << "Networking disabled. To start, use netstart or pass --bootstrap or a remote host." << endl; + + unique_ptr> jsonrpcHttpServer; + unique_ptr> jsonrpcIpcServer; + unique_ptr sessionManager; + unique_ptr accountHolder; + + AddressHash allowedDestinations; + + std::function authenticator; + if (testingMode) + authenticator = [](TransactionSkeleton const&, bool) -> bool { return true; }; + else + authenticator = [&](TransactionSkeleton const & _t, bool) -> bool { + // "unlockAccount" functionality is done in the AccountHolder. + if (!alwaysConfirm || allowedDestinations.count(_t.to)) + return true; + + string r = "always"; + if (r == "always") + allowedDestinations.insert(_t.to); + return r == "yes" || r == "always"; + }; + + ExitHandler exitHandler; + + if (jsonRPCURL > -1 || ipc) + { + using FullServer = ModularServer < + rpc::EthFace, rpc::DBFace, rpc::WhisperFace, + rpc::NetFace, rpc::Web3Face, rpc::PersonalFace, + rpc::AdminEthFace, rpc::AdminNetFace, rpc::AdminUtilsFace, + rpc::DebugFace, rpc::TestFace + >; + + sessionManager.reset(new rpc::SessionManager()); + accountHolder.reset(new SimpleAccountHolder([&]() { return web3.ethereum(); }, getAccountPassword, keyManager, authenticator)); + auto ethFace = new rpc::Eth(*web3.ethereum(), *accountHolder.get()); + rpc::TestFace* testEth = nullptr; + if (testingMode) + testEth = new rpc::Test(*web3.ethereum()); + + if (jsonRPCURL >= 0) + { + rpc::AdminEth* adminEth = nullptr; + rpc::PersonalFace* personal = nullptr; + rpc::AdminNet* adminNet = nullptr; + rpc::AdminUtils* adminUtils = nullptr; + if (adminViaHttp) + { + personal = new rpc::Personal(keyManager, *accountHolder, *web3.ethereum()); + adminEth = new rpc::AdminEth(*web3.ethereum(), *gasPricer.get(), keyManager, *sessionManager.get()); + adminNet = new rpc::AdminNet(web3, *sessionManager.get()); + adminUtils = new rpc::AdminUtils(*sessionManager.get()); + } + + jsonrpcHttpServer.reset(new FullServer( + ethFace, new rpc::LevelDB(), new rpc::Whisper(web3, {}), + new rpc::Net(web3), new rpc::Web3(web3.clientVersion()), personal, + adminEth, adminNet, adminUtils, + new rpc::Debug(*web3.ethereum()), + testEth + )); + auto httpConnector = new SafeHttpServer(web3.ethereum(), jsonRPCURL, "", "", "", SensibleHttpThreads); + httpConnector->setNode(strNodeId); + httpConnector->setGroup(strGroupId); + httpConnector->setStoragePath(strStoragePath); + httpConnector->setAllowedOrigin(rpcCorsDomain); + jsonrpcHttpServer->addConnector(httpConnector); + if ( false == jsonrpcHttpServer->StartListening() ) + { + cout << "RPC StartListening Fail!!!!" << endl; + exit(0); + } + + // 这个地方要判断rpc启动的返回 + } + if (ipc) + { + + jsonrpcIpcServer.reset(new FullServer( + ethFace, new rpc::LevelDB(), new rpc::Whisper(web3, {}), new rpc::Net(web3), + new rpc::Web3(web3.clientVersion()), new rpc::Personal(keyManager, *accountHolder, *web3.ethereum()), + new rpc::AdminEth(*web3.ethereum(), *gasPricer.get(), keyManager, *sessionManager.get()), + new rpc::AdminNet(web3, *sessionManager.get()), + new rpc::AdminUtils(*sessionManager.get()), + new rpc::Debug(*web3.ethereum()), + testEth + )); + auto ipcConnector = new IpcServer("geth"); + jsonrpcIpcServer->addConnector(ipcConnector); + ipcConnector->StartListening(); + } + + if (jsonAdmin.empty()) + jsonAdmin = sessionManager->newSession(rpc::SessionPermissions{{rpc::Privilege::Admin}}); + else + sessionManager->addSession(jsonAdmin, rpc::SessionPermissions{{rpc::Privilege::Admin}}); + + LOG(TRACE) << "JSONRPC Admin Session Key: " << jsonAdmin ; + writeFile(getDataDir("web3") + "/session.key", jsonAdmin); + writeFile(getDataDir("web3") + "/session.url", "http://localhost:" + toString(jsonRPCURL)); + } + + for (auto const& p : preferredNodes) + if (p.second.second) + web3.requirePeer(p.first, p.second.first); + else + web3.addNode(p.first, p.second.first); + + if (bootstrap && privateChain.empty()) + for (auto const& i : Host::pocHosts()) + web3.requirePeer(i.first, i.second); + if (!remoteHost.empty()) + web3.addNode(p2p::NodeID(), remoteHost + ":" + toString(remotePort)); + + signal(SIGABRT, &ExitHandler::exitHandler); + signal(SIGTERM, &ExitHandler::exitHandler); + signal(SIGINT, &ExitHandler::exitHandler); + + unsigned account_type = ~(unsigned)0; + if (NodeConnManagerSingleton::GetInstance().getAccountType(web3.id(), account_type)) { + mining = ~(unsigned)0; // 有account_type配置,是否挖矿由account_type决定 + } else { + std::cout << "getAccountType error......" << std::endl; + } + + if (c) + { + unsigned n = c->blockChain().details().number; + if (mining) { + int try_cnt = 0; + unsigned node_num = NodeConnManagerSingleton::GetInstance().getNodeNum(); + std::cout << "getNodeNum node_num is " << node_num << std::endl; + while (try_cnt++ < 5 && node_num > 0 && web3.peerCount() < node_num - 1) { + std::cout << "Wait for connecting to peers........" << std::endl; + std::this_thread::sleep_for(std::chrono::seconds(1)); + continue; + } + std::cout << "Connected to " << web3.peerCount() << " peers" << std::endl; + std::cout << "startSealing ....." << std::endl; + c->startSealing(); + } + + while (!exitHandler.shouldExit()) + stopSealingAfterXBlocks(c, n, mining); + } + else + while (!exitHandler.shouldExit()) + this_thread::sleep_for(chrono::milliseconds(1000)); + + if (jsonrpcHttpServer.get()) + jsonrpcHttpServer->StopListening(); + if (jsonrpcIpcServer.get()) + jsonrpcIpcServer->StopListening(); + + /* auto netData = web3.saveNetwork(); + if (!netData.empty()) + writeFile(getDataDir() + "/network.rlp", netData);*/ + return 0; +} diff --git a/evmjit/.clang-format b/evmjit/.clang-format new file mode 100644 index 0000000000..f36b7b4526 --- /dev/null +++ b/evmjit/.clang-format @@ -0,0 +1,89 @@ +--- +Language: Cpp +# BasedOnStyle: Chromium +AccessModifierOffset: -1 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlinesLeft: true +AlignOperands: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: true +AllowShortFunctionsOnASingleLine: Inline +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: true +AlwaysBreakTemplateDeclarations: true +BinPackArguments: true +BinPackParameters: false +BraceWrapping: + AfterClass: false + AfterControlStatement: false + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Allman +BreakBeforeTernaryOperators: false +BreakConstructorInitializersBeforeComma: false +ColumnLimit: 80 +CommentPragmas: '^ IWYU pragma:' +ConstructorInitializerAllOnOneLineOrOnePerLine: true +ConstructorInitializerIndentWidth: 2 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] +IncludeCategories: + - Regex: '^<.*\.h>' + Priority: 1 + - Regex: '^<.*' + Priority: 2 + - Regex: '.*' + Priority: 3 +IndentCaseLabels: false +IndentWidth: 4 +IndentWrappedFunctionNames: false +KeepEmptyLinesAtTheStartOfBlocks: false +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 2 +NamespaceIndentation: None +ObjCBlockIndentWidth: 2 +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: false +PenaltyBreakBeforeFirstCallParameter: 1 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 200 +PointerAlignment: Left +ReflowComments: true +SortIncludes: false +SpaceAfterCStyleCast: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 2 +SpacesInAngles: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Auto +TabWidth: 4 +UseTab: Always +... diff --git a/evmjit/.gitignore b/evmjit/.gitignore new file mode 100644 index 0000000000..f5dc8a6805 --- /dev/null +++ b/evmjit/.gitignore @@ -0,0 +1,6 @@ +# CLion files +/.idea/ + +# Convenient binary output and build dirs +/bin/ +/build/ diff --git a/evmjit/.travis.yml b/evmjit/.travis.yml new file mode 100644 index 0000000000..f75cc64ea6 --- /dev/null +++ b/evmjit/.travis.yml @@ -0,0 +1,35 @@ +language: cpp +branches: + only: + - master + - develop +os: + - linux + - osx +dist: trusty # cmake 3.2 +osx_image: xcode7.3 # OSX 10.11, cmake 3.5 +env: + global: + secure: "g3Ij6YqiOl/RaD3mdSHestkTDm49JPcJ90EbpFPfykkLZVAmZn6PP4WDvhBV9zcy4kUkERQs+8lj88wzw4JidxtT67WQBd/Lnvl06c+B1AB5jwoK9X5MKaOGvtXA18P8412rhB4a+1xFILuvM+2e74QUEPBV6tPlqZg9QZ9jwso=" + matrix: + - BUILD_TYPE=Release + - BUILD_TYPE=Debug +cache: + ccache: true + directories: build/llvm + + +before_install: + - cmake --version + +script: + - scripts/build.sh + - cd build && ctest + +deploy: + provider: script + script: scripts/travis_update_docs.sh + skip_cleanup: true + on: + branch: develop + condition: $TRAVIS_JOB_NUMBER == "$TRAVIS_BUILD_NUMBER.1" diff --git a/evmjit/CMakeLists.txt b/evmjit/CMakeLists.txt new file mode 100644 index 0000000000..35973f4b1f --- /dev/null +++ b/evmjit/CMakeLists.txt @@ -0,0 +1,53 @@ +cmake_minimum_required(VERSION 3.0.0) + +cmake_policy(SET CMP0042 OLD) # Fix MACOSX_RPATH. +cmake_policy(SET CMP0048 NEW) # Allow VERSION argument in project(). +if (POLICY CMP0054) + cmake_policy(SET CMP0054 NEW) # No longer implicitly dereference variables. +endif() + +project(EVMJIT VERSION 0.9.0.2 LANGUAGES CXX C) + +message(STATUS "EVM JIT ${EVMJIT_VERSION_MAJOR}.${EVMJIT_VERSION_MINOR}.${EVMJIT_VERSION_PATCH}") + +if (NOT ${CMAKE_SYSTEM_PROCESSOR} MATCHES "x86_64|AMD64") + message(FATAL_ERROR "Target ${CMAKE_SYSTEM_PROCESSOR} not supported -- EVM JIT works only on x86_64 architecture") +endif() + +option(EVMJIT_INCLUDE_EXAMPLES "Generate build targets for the EVMJIT examples" OFF) +option(EVMJIT_TESTS "Create targets for CTest" OFF) + +set_property(GLOBAL PROPERTY USE_FOLDERS ON) +set(CMAKE_AUTOMOC OFF) + +if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + # Always use Release variant of C++ runtime. + # We don't want to provide Debug variants of all dependencies. Some default + # flags set by CMake must be tweaked. + string(REPLACE "/MDd" "/MD" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG}) + string(REPLACE "/D_DEBUG" "" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG}) + string(REPLACE "/RTC1" "" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG}) + set_property(GLOBAL PROPERTY DEBUG_CONFIGURATIONS OFF) +else() + set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wextra -Wconversion -Wno-sign-conversion -Wno-unknown-pragmas ${CMAKE_CXX_FLAGS}") +endif() + +if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND NOT SANITIZE) + # Do not allow unresolved symbols in shared library (default on linux) + # unless sanitizer is used (sanity checks produce unresolved function calls) + set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--no-undefined") +endif() + +include(cmake/llvm.cmake) +configure_llvm_project(llvm) + +add_subdirectory(libevmjit) + +if (EVMJIT_INCLUDE_EXAMPLES) + add_subdirectory(examples) +endif() + +if (EVMJIT_TESTS) + enable_testing() + add_subdirectory(tests) +endif() diff --git a/evmjit/LICENSE.md b/evmjit/LICENSE.md new file mode 100644 index 0000000000..b1e4cf0eff --- /dev/null +++ b/evmjit/LICENSE.md @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 Paweł Bylica + +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. diff --git a/evmjit/README.md b/evmjit/README.md new file mode 100644 index 0000000000..9ed83747b2 --- /dev/null +++ b/evmjit/README.md @@ -0,0 +1,38 @@ +# The Ethereum EVM JIT + +[![Join the chat at https://gitter.im/ethereum/evmjit](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/ethereum/evmjit?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + +EVM JIT is a library for just-in-time compilation of Ethereum EVM code. +It can be used to substitute classic interpreter-like EVM Virtual Machine in Ethereum client. + +## Build + +### Linux / Ubuntu + +1. Install llvm-3.7-dev package + 1. For Ubuntu 14.04 using LLVM deb packages source: http://llvm.org/apt + 2. For Ubuntu 14.10 using Ubuntu packages +2. Build library with cmake + 1. `mkdir build && cd $_` + 2. `cmake .. && make` +3. Install library + 1. `sudo make install` + 2. `sudo ldconfig` + +### OSX + +1. Install llvm37 + 1. `brew install homebrew/versions/llvm37 --disable-shared` +2. Build library with cmake + 1. `mkdir build && cd $_` + 2. `cmake -DLLVM_DIR=/usr/local/lib/llvm-3.7/share/llvm/cmake .. && make` +3. Install library + 1. `make install` (with admin rights?) + +### Windows + +Ask me. + +## Options + +Options to evmjit library can be passed by environmental variable, e.g. `EVMJIT="-help" testeth --jit`. diff --git a/evmjit/appveyor.yml b/evmjit/appveyor.yml new file mode 100644 index 0000000000..6835f24eab --- /dev/null +++ b/evmjit/appveyor.yml @@ -0,0 +1,16 @@ +version: "{build}" +branches: + only: + - develop +configuration: +- Debug +- Release +cache: build/llvm +before_build: | + if not exist build mkdir build + cd build + cmake -G "Visual Studio 14 2015 Win64" .. +build: + project: c:/projects/evmjit/build/evmjit.sln + parallel: true + verbosity: minimal diff --git a/evmjit/circle.yml b/evmjit/circle.yml new file mode 100644 index 0000000000..8b7756dd16 --- /dev/null +++ b/evmjit/circle.yml @@ -0,0 +1,14 @@ +dependencies: + pre: + - sudo apt-add-repository -y ppa:george-edison55/cmake-3.x + - sudo apt -q update + - sudo apt -qy install cmake + override: + - BUILD_TYPE=RelWithDebInfo scripts/build.sh + cache_directories: + # TODO: add ccache + - build/llvm # Cache llvm build + +test: + override: + - cd build && ctest diff --git a/evmjit/cmake/llvm.cmake b/evmjit/cmake/llvm.cmake new file mode 100644 index 0000000000..a49205af41 --- /dev/null +++ b/evmjit/cmake/llvm.cmake @@ -0,0 +1,110 @@ + +# Configures LLVM dependency +# +# This function handles everything needed to setup LLVM project. +# By default it downloads and builds LLVM from source. +# In case LLVM_DIR variable is set it tries to use the pointed pre-built +# LLVM package. LLVM_DIR should point LLVM's shared cmake files to be used +# by find_package(... CONFIG) function. +# +# Creates a target representing all required LLVM libraries and include path. +function(configure_llvm_project TARGET_NAME) + if (LLVM_DIR) + find_package(LLVM REQUIRED CONFIG) + llvm_map_components_to_libnames(LIBS mcjit ipo x86codegen) + + # To create a fake imported library later on we need to know the + # location of some library + list(GET LIBS 0 MAIN_LIB) + get_property(CONFIGS TARGET ${MAIN_LIB} PROPERTY IMPORTED_CONFIGURATIONS) + list(GET CONFIGS 0 CONFIG) # Just get the first one. Usually there is only one. + if (CONFIG) + get_property(MAIN_LIB TARGET ${MAIN_LIB} PROPERTY IMPORTED_LOCATION_${CONFIG}) + else() + set(CONFIG Unknown) + get_property(MAIN_LIB TARGET ${MAIN_LIB} PROPERTY IMPORTED_LOCATION) + endif() + message(STATUS "LLVM ${LLVM_VERSION} (${CONFIG}; ${LLVM_ENABLE_ASSERTIONS}; ${LLVM_DIR})") + if (NOT EXISTS ${MAIN_LIB}) + # Add some diagnostics to detect issues before building. + message(FATAL_ERROR "LLVM library not found: ${MAIN_LIB}") + endif() + else() + # List of required LLVM libs. + # Generated with `llvm-config --libs mcjit ipo x86codegen` + # Only used here locally to setup the "llvm" imported target + set(LIBS + LLVMMCJIT + LLVMX86CodeGen LLVMX86Desc LLVMX86Info LLVMMCDisassembler LLVMX86AsmPrinter + LLVMX86Utils LLVMSelectionDAG LLVMAsmPrinter LLVMCodeGen + LLVMInstrumentation LLVMBitWriter LLVMipo LLVMVectorize LLVMScalarOpts + LLVMProfileData LLVMIRReader LLVMAsmParser LLVMInstCombine + LLVMTransformUtils LLVMExecutionEngine LLVMTarget LLVMAnalysis + LLVMRuntimeDyld LLVMObject LLVMMCParser LLVMBitReader LLVMMC + LLVMCore LLVMSupport + ) + + # System libs that LLVM depend on. + # See `llvm-config --system-libs` + if (APPLE) + set(SYSTEM_LIBS pthread) + elseif (UNIX) + set(SYSTEM_LIBS pthread dl) + endif() + + if (${CMAKE_GENERATOR} STREQUAL "Unix Makefiles") + set(BUILD_COMMAND $(MAKE)) + else() + set(BUILD_COMMAND cmake --build --config Release) + endif() + + include(ExternalProject) + ExternalProject_Add(llvm-project + PREFIX llvm + BINARY_DIR llvm # Build directly to install dir to avoid copy. + SOURCE_DIR llvm/src/llvm + URL http://llvm.org/releases/3.8.0/llvm-3.8.0.src.tar.xz + URL_HASH SHA256=555b028e9ee0f6445ff8f949ea10e9cd8be0d084840e21fbbe1d31d51fc06e46 + CMAKE_ARGS -DCMAKE_BUILD_TYPE=Release + -DCMAKE_INSTALL_PREFIX= + -DLLVM_ENABLE_TERMINFO=OFF # Disable terminal color support + -DLLVM_ENABLE_ZLIB=OFF # Disable compression support -- not needed at all + -DLLVM_TARGETS_TO_BUILD=X86 + -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF + -DLLVM_INCLUDE_TESTS=OFF + BUILD_COMMAND ${BUILD_COMMAND} + INSTALL_COMMAND cmake --build --config Release --target install + EXCLUDE_FROM_ALL TRUE + ) + + ExternalProject_Get_Property(llvm-project INSTALL_DIR) + set(LLVM_LIBRARY_DIRS ${INSTALL_DIR}/lib) + set(LLVM_INCLUDE_DIRS ${INSTALL_DIR}/include) + file(MAKE_DIRECTORY ${LLVM_INCLUDE_DIRS}) # Must exists. + + foreach(LIB ${LIBS}) + list(APPEND LIBFILES "${LLVM_LIBRARY_DIRS}/${CMAKE_STATIC_LIBRARY_PREFIX}${LIB}${CMAKE_STATIC_LIBRARY_SUFFIX}") + endforeach() + + # Pick one of the libraries to be the main one. It does not matter which one + # but the imported target requires the IMPORTED_LOCATION property. + list(GET LIBFILES 0 MAIN_LIB) + list(REMOVE_AT LIBFILES 0) + set(LIBS ${LIBFILES} ${SYSTEM_LIBS}) + endif() + + if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") + # Clang needs this to build LLVM. Weird that the GCC does not. + set(DEFINES __STDC_LIMIT_MACROS __STDC_CONSTANT_MACROS) + endif() + + # Create the target representing + add_library(${TARGET_NAME} STATIC IMPORTED) + set_property(TARGET ${TARGET_NAME} PROPERTY INTERFACE_COMPILE_DEFINITIONS ${DEFINES}) + set_property(TARGET ${TARGET_NAME} PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${LLVM_INCLUDE_DIRS}) + set_property(TARGET ${TARGET_NAME} PROPERTY IMPORTED_LOCATION ${MAIN_LIB}) + set_property(TARGET ${TARGET_NAME} PROPERTY INTERFACE_LINK_LIBRARIES ${LIBS}) + if (TARGET llvm-project) + add_dependencies(${TARGET_NAME} llvm-project) + endif() +endfunction() diff --git a/evmjit/docker/Dockerfile b/evmjit/docker/Dockerfile new file mode 100644 index 0000000000..662027e92f --- /dev/null +++ b/evmjit/docker/Dockerfile @@ -0,0 +1,11 @@ +FROM ubuntu:16.04 + +RUN echo "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-3.9 main" >> /etc/apt/sources.list \ + && apt-get update \ + && apt-get install -y --no-install-recommends --allow-unauthenticated \ + cmake \ + g++ \ + make \ + llvm-3.9-dev \ + zlib1g-dev \ + && rm -rf /var/lib/apt/lists/* diff --git a/evmjit/docker/test.sh b/evmjit/docker/test.sh new file mode 100644 index 0000000000..82cc6389c7 --- /dev/null +++ b/evmjit/docker/test.sh @@ -0,0 +1,11 @@ +#!/bin/sh +set -e + +SRC_DIR=$(dirname $(pwd)) + +CONTAINER=$(docker run -d -v $SRC_DIR:/src:ro chfast/cpp-ethereum-dev tail -f /dev/null) + +docker exec $CONTAINER sh -c 'mkdir build && cd build && cmake /src -DLLVM_DIR=/usr/lib/llvm-3.9/lib/cmake/llvm' +docker exec $CONTAINER cmake --build /build + +docker kill $CONTAINER diff --git a/evmjit/docs/Doxyfile b/evmjit/docs/Doxyfile new file mode 100644 index 0000000000..567a051ab6 --- /dev/null +++ b/evmjit/docs/Doxyfile @@ -0,0 +1,316 @@ +# Doxyfile 1.8.9.1 + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +DOXYFILE_ENCODING = UTF-8 +PROJECT_NAME = "EVMJIT" +PROJECT_NUMBER = +PROJECT_BRIEF = +PROJECT_LOGO = +OUTPUT_DIRECTORY = +CREATE_SUBDIRS = NO +ALLOW_UNICODE_NAMES = YES +OUTPUT_LANGUAGE = English +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = YES +STRIP_FROM_PATH = +STRIP_FROM_INC_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = YES +QT_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = NO +INHERIT_DOCS = YES +SEPARATE_MEMBER_PAGES = NO +TAB_SIZE = 4 +ALIASES = +TCL_SUBST = +OPTIMIZE_OUTPUT_FOR_C = NO +OPTIMIZE_OUTPUT_JAVA = NO +OPTIMIZE_FOR_FORTRAN = NO +OPTIMIZE_OUTPUT_VHDL = NO +EXTENSION_MAPPING = +MARKDOWN_SUPPORT = YES +AUTOLINK_SUPPORT = YES +BUILTIN_STL_SUPPORT = NO +CPP_CLI_SUPPORT = NO +SIP_SUPPORT = NO +IDL_PROPERTY_SUPPORT = YES +DISTRIBUTE_GROUP_DOC = NO +SUBGROUPING = YES +INLINE_GROUPED_CLASSES = NO +INLINE_SIMPLE_STRUCTS = NO +TYPEDEF_HIDES_STRUCT = NO +LOOKUP_CACHE_SIZE = 0 +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = NO +EXTRACT_PRIVATE = NO +EXTRACT_PACKAGE = NO +EXTRACT_STATIC = YES +EXTRACT_LOCAL_CLASSES = YES +EXTRACT_LOCAL_METHODS = NO +EXTRACT_ANON_NSPACES = NO +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = YES +HIDE_SCOPE_NAMES = NO +HIDE_COMPOUND_REFERENCE= NO +SHOW_INCLUDE_FILES = YES +SHOW_GROUPED_MEMB_INC = NO +FORCE_LOCAL_INCLUDES = NO +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +SORT_BRIEF_DOCS = NO +SORT_MEMBERS_CTORS_1ST = NO +SORT_GROUP_NAMES = NO +SORT_BY_SCOPE_NAME = NO +STRICT_PROTO_MATCHING = NO +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = YES +SHOW_FILES = YES +SHOW_NAMESPACES = YES +FILE_VERSION_FILTER = +LAYOUT_FILE = +CITE_BIB_FILES = +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = include/evm.h +INPUT_ENCODING = UTF-8 +FILE_PATTERNS = +RECURSIVE = NO +EXCLUDE = +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXCLUDE_SYMBOLS = +EXAMPLE_PATH = +EXAMPLE_PATTERNS = +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +FILTER_SOURCE_PATTERNS = +USE_MDFILE_AS_MAINPAGE = +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = YES +INLINE_SOURCES = YES +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = NO +REFERENCES_RELATION = NO +REFERENCES_LINK_SOURCE = YES +SOURCE_TOOLTIPS = YES +USE_HTAGS = NO +VERBATIM_HEADERS = YES +CLANG_ASSISTED_PARSING = NO +CLANG_OPTIONS = +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = YES +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = docs +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_EXTRA_STYLESHEET = +HTML_EXTRA_FILES = +HTML_COLORSTYLE_HUE = 220 +HTML_COLORSTYLE_SAT = 100 +HTML_COLORSTYLE_GAMMA = 80 +HTML_TIMESTAMP = YES +HTML_DYNAMIC_SECTIONS = NO +HTML_INDEX_NUM_ENTRIES = 100 +GENERATE_DOCSET = NO +DOCSET_FEEDNAME = "Doxygen generated docs" +DOCSET_BUNDLE_ID = org.doxygen.Project +DOCSET_PUBLISHER_ID = org.doxygen.Publisher +DOCSET_PUBLISHER_NAME = Publisher +GENERATE_HTMLHELP = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +CHM_INDEX_ENCODING = +BINARY_TOC = NO +TOC_EXPAND = NO +GENERATE_QHP = NO +QCH_FILE = +QHP_NAMESPACE = org.doxygen.Project +QHP_VIRTUAL_FOLDER = doc +QHP_CUST_FILTER_NAME = +QHP_CUST_FILTER_ATTRS = +QHP_SECT_FILTER_ATTRS = +QHG_LOCATION = +GENERATE_ECLIPSEHELP = NO +ECLIPSE_DOC_ID = org.doxygen.Project +DISABLE_INDEX = NO +GENERATE_TREEVIEW = NO +ENUM_VALUES_PER_LINE = 4 +TREEVIEW_WIDTH = 250 +EXT_LINKS_IN_WINDOW = NO +FORMULA_FONTSIZE = 10 +FORMULA_TRANSPARENT = YES +USE_MATHJAX = NO +MATHJAX_FORMAT = HTML-CSS +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest +MATHJAX_EXTENSIONS = +MATHJAX_CODEFILE = +SEARCHENGINE = NO +SERVER_BASED_SEARCH = NO +EXTERNAL_SEARCH = NO +SEARCHENGINE_URL = +SEARCHDATA_FILE = searchdata.xml +EXTERNAL_SEARCH_ID = +EXTRA_SEARCH_MAPPINGS = +#--------------------------------------------------------------------------- +# Configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = NO +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4 +EXTRA_PACKAGES = +LATEX_HEADER = +LATEX_FOOTER = +LATEX_EXTRA_STYLESHEET = +LATEX_EXTRA_FILES = +PDF_HYPERLINKS = YES +USE_PDFLATEX = YES +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +LATEX_SOURCE_CODE = NO +LATEX_BIB_STYLE = plain +#--------------------------------------------------------------------------- +# Configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +RTF_SOURCE_CODE = NO +#--------------------------------------------------------------------------- +# Configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_SUBDIR = +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# Configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = NO +XML_OUTPUT = xml +XML_PROGRAMLISTING = YES +#--------------------------------------------------------------------------- +# Configuration options related to the DOCBOOK output +#--------------------------------------------------------------------------- +GENERATE_DOCBOOK = NO +DOCBOOK_OUTPUT = docbook +DOCBOOK_PROGRAMLISTING = NO +#--------------------------------------------------------------------------- +# Configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# Configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = NO +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration options related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +EXTERNAL_PAGES = YES +PERL_PATH = /usr/bin/perl +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = NO +MSCGEN_PATH = +DIA_PATH = +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = NO +DOT_NUM_THREADS = 0 +DOT_FONTNAME = Helvetica +DOT_FONTSIZE = 10 +DOT_FONTPATH = +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +GROUP_GRAPHS = YES +UML_LOOK = NO +UML_LIMIT_NUM_FIELDS = 10 +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = NO +CALLER_GRAPH = NO +GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = YES +DOT_IMAGE_FORMAT = png +INTERACTIVE_SVG = NO +DOT_PATH = +DOTFILE_DIRS = +MSCFILE_DIRS = +DIAFILE_DIRS = +PLANTUML_JAR_PATH = +PLANTUML_INCLUDE_PATH = +DOT_GRAPH_MAX_NODES = 50 +MAX_DOT_GRAPH_DEPTH = 0 +DOT_TRANSPARENT = NO +DOT_MULTI_TARGETS = NO +GENERATE_LEGEND = YES +DOT_CLEANUP = YES diff --git a/evmjit/examples/CMakeLists.txt b/evmjit/examples/CMakeLists.txt new file mode 100644 index 0000000000..42f06c2bfc --- /dev/null +++ b/evmjit/examples/CMakeLists.txt @@ -0,0 +1,8 @@ +add_compile_options("-Wno-extra") # Override -Wextra, I don't know better option. + +add_library(example-vm STATIC EXCLUDE_FROM_ALL examplevm.c) +target_include_directories(example-vm PRIVATE ../include) + +add_executable(example-capi EXCLUDE_FROM_ALL capi.c) +target_include_directories(example-capi PRIVATE ../include) +target_link_libraries(example-capi PRIVATE example-vm) diff --git a/evmjit/examples/capi.c b/evmjit/examples/capi.c new file mode 100644 index 0000000000..af768ef886 --- /dev/null +++ b/evmjit/examples/capi.c @@ -0,0 +1,98 @@ +#include +#include +#include +#include "evm.h" + + +struct evm_uint256be balance(struct evm_env* env, struct evm_uint160be address) +{ + struct evm_uint256be ret = {.bytes = {1, 2, 3, 4}}; + return ret; +} + +struct evm_uint160be address(struct evm_env* env) +{ + struct evm_uint160be ret = {.bytes = {1, 2, 3, 4}}; + return ret; +} + +union evm_variant query(struct evm_env* env, + enum evm_query_key key, + union evm_variant arg) { + union evm_variant result; + printf("EVM-C: QUERY %d\n", key); + switch (key) { + case EVM_GAS_LIMIT: result.int64 = 314; break; + + case EVM_BALANCE: + result.uint256be = balance(env, arg.address); + break; + + case EVM_ADDRESS: + result.address = address(env); + break; + + default: result.int64 = 0; break; + } + return result; +} + +void update(struct evm_env* env, + enum evm_update_key key, + union evm_variant arg1, + union evm_variant arg2) +{ + printf("EVM-C: UPDATE %d\n", key); +} + +int64_t call( + struct evm_env* _opaqueEnv, + enum evm_call_kind _kind, + int64_t _gas, + struct evm_uint160be _address, + struct evm_uint256be _value, + uint8_t const* _inputData, + size_t _inputSize, + uint8_t* _outputData, + size_t _outputSize +) +{ + printf("EVM-C: CALL %d\n", _kind); + return EVM_CALL_FAILURE; +} + +/// Example how the API is supposed to be used. +int main(int argc, char *argv[]) { + struct evm_interface intf = examplevm_get_interface(); + struct evm_instance* jit = intf.create(query, update, call); + + char const code[] = "exec()"; + const size_t code_size = sizeof(code); + struct evm_uint256be code_hash = {.bytes = {1, 2, 3,}}; + char const input[] = "Hello World!"; + struct evm_uint256be value = {{1, 0, 0, 0}}; + + int64_t gas = 200000; + struct evm_result result = + intf.execute(jit, NULL, EVM_HOMESTEAD, code_hash, (const uint8_t *)code, code_size, gas, (const uint8_t *)input, + sizeof(input), value); + + printf("Execution result:\n"); + if (result.code != EVM_SUCCESS) { + printf(" EVM execution failure: %d\n", result.code); + } else { + printf(" Gas used: %ld\n", gas - result.gas_left); + printf(" Gas left: %ld\n", result.gas_left); + printf(" Output size: %zd\n", result.output_size); + + printf(" Output: "); + size_t i = 0; + for (i = 0; i < result.output_size; i++) { + printf("%02x ", result.output_data[i]); + } + printf("\n"); + } + + result.release(&result); + intf.destroy(jit); +} diff --git a/evmjit/examples/examplevm.c b/evmjit/examples/examplevm.c new file mode 100644 index 0000000000..c5422d8130 --- /dev/null +++ b/evmjit/examples/examplevm.c @@ -0,0 +1,78 @@ +#include +#include +#include "evm.h" + +struct evm_instance { + evm_query_fn query_fn; + evm_update_fn update_fn; + evm_call_fn call_fn; +}; + +static struct evm_instance* evm_create(evm_query_fn query_fn, + evm_update_fn update_fn, + evm_call_fn call_fn) +{ + struct evm_instance *ret = calloc(1, sizeof(struct evm_instance)); + + if (ret) { + ret->query_fn = query_fn; + ret->update_fn = update_fn; + ret->call_fn = call_fn; + } + + return ret; +} + +static void evm_destroy(struct evm_instance* evm) +{ + free(evm); +} + +/// Example options. +/// +/// VMs are allowed to omit this function implementation. +int evm_set_option(struct evm_instance* evm, + char const* name, + char const* value) +{ + if (strcmp(name, "example-option") == 0) + return 1; + return 0; +} + +static void evm_release_result(struct evm_result const* result) +{ +} + +static struct evm_result evm_execute(struct evm_instance* instance, + struct evm_env* env, + enum evm_mode mode, + struct evm_uint256be code_hash, + uint8_t const* code, + size_t code_size, + int64_t gas, + uint8_t const* input, + size_t input_size, + struct evm_uint256be value) +{ + struct evm_result ret = {}; + + // Execute code and refer to callbacks: instance->query_fn() + + ret.release = evm_release_result; + ret.code = EVM_FAILURE; + ret.gas_left = 0; + + return ret; +} + +struct evm_interface examplevm_get_interface() +{ + struct evm_interface intf = {}; + intf.abi_version = EVM_ABI_VERSION; + intf.create = evm_create; + intf.destroy = evm_destroy; + intf.execute = evm_execute; + intf.set_option = evm_set_option; + return intf; +} diff --git a/evmjit/include/evm.h b/evmjit/include/evm.h new file mode 100644 index 0000000000..ad10ac0909 --- /dev/null +++ b/evmjit/include/evm.h @@ -0,0 +1,493 @@ +/// EVM-C -- C interface to Ethereum Virtual Machine +/// +/// ## High level design rules +/// 1. Pass function arguments and results by value. +/// This rule comes from modern C++ and tries to avoid costly alias analysis +/// needed for optimization. As the result we have a lots of complex structs +/// and unions. And variable sized arrays of bytes cannot be passed by copy. +/// 2. The EVM operates on integers so it prefers values to be host-endian. +/// On the other hand, LLVM can generate good code for byte swaping. +/// The interface also tries to match host application "natural" endianess. +/// I would like to know what endianess you use and where. +/// +/// @defgroup EVMC EVM-C +/// @{ +#ifndef EVM_H +#define EVM_H + +#include // Definition of int64_t, uint64_t. +#include // Definition of size_t. + +#if __cplusplus +extern "C" { +#endif + +// BEGIN Python CFFI declarations + +/// The EVM-C ABI version number matching the interface declared in this file. +static const uint32_t EVM_ABI_VERSION = 0; + +/// Big-endian 256-bit integer. +/// +/// 32 bytes of data representing big-endian 256-bit integer. I.e. bytes[0] is +/// the most significant byte, bytes[31] is the least significant byte. +/// This type is used to transfer to/from the VM values interpreted by the user +/// as both 256-bit integers and 256-bit hashes. +struct evm_uint256be { + /// The 32 bytes of the big-endian integer or hash. + uint8_t bytes[32]; +}; + +/// Big-endian 160-bit hash suitable for keeping an Ethereum address. +struct evm_uint160be { + /// The 20 bytes of the hash. + uint8_t bytes[20]; +}; + +/// The execution result code. +enum evm_result_code { + EVM_SUCCESS = 0, ///< Execution finished with success. + EVM_FAILURE = 1, ///< Generic execution failure. + EVM_OUT_OF_GAS = 2, + EVM_BAD_INSTRUCTION = 3, + EVM_BAD_JUMP_DESTINATION = 4, + EVM_STACK_OVERFLOW = 5, + EVM_STACK_UNDERFLOW = 6, +}; + +struct evm_result; + +/// Releases resources assigned to an execution result. +/// +/// This function releases memory (and other resources, if any) assigned to the +/// specified execution result making the result object invalid. +/// +/// @param result The execution result which resource are to be released. The +/// result itself it not modified by this function, but becomes +/// invalid and user should discard it as well. +typedef void (*evm_release_result_fn)(struct evm_result const* result); + +/// The EVM code execution result. +struct evm_result { + /// The execution result code. + enum evm_result_code code; + + /// The amount of gas left after the execution. + /// + /// The value is valid only if evm_result::code == ::EVM_SUCCESS. + int64_t gas_left; + + union + { + struct + { + /// The reference to output data. The memory containing the output + /// data is owned by EVM and is freed with evm_result::release(). + uint8_t const* output_data; + + /// The size of the output data. + size_t output_size; + }; + + /// The address of the successfully created contract. + /// + /// This field has valid value only if the evm_result comes from a + /// successful CREATE opcode execution + /// (i.e. evm_call_fn(..., EVM_CREATE, ...)). + struct evm_uint160be create_address; + }; + + /// The pointer to the result release implementation. + /// + /// This function pointer must be set by the VM implementation and works + /// similary to C++ virtual destructor. Attaching the releaser to the result + /// itself allows VM composition. + evm_release_result_fn release; + + /// @name Optional + /// The optional information that EVM is not required to provide. + /// @{ + + /// The error message explaining the result code. + char const* error_message; + + /// The pointer to EVM-owned memory. For EVM internal use. + /// @see output_data. + void* internal_memory; + + /// @} +}; + +/// The query callback key. +enum evm_query_key { + EVM_SLOAD = 0, ///< Storage value of a given key for SLOAD. + EVM_ADDRESS = 1, ///< Address of the contract for ADDRESS. + EVM_CALLER = 2, ///< Message sender address for CALLER. + EVM_ORIGIN = 3, ///< Transaction origin address for ORIGIN. + EVM_GAS_PRICE = 4, ///< Transaction gas price for GASPRICE. + EVM_COINBASE = 5, ///< Current block miner address for COINBASE. + EVM_DIFFICULTY = 6, ///< Current block difficulty for DIFFICULTY. + EVM_GAS_LIMIT = 7, ///< Current block gas limit for GASLIMIT. + EVM_NUMBER = 8, ///< Current block number for NUMBER. + EVM_TIMESTAMP = 9, ///< Current block timestamp for TIMESTAMP. + EVM_CODE_BY_ADDRESS = 10, ///< Code by an address for EXTCODECOPY. + EVM_CODE_SIZE = 11, ///< Code size by an address for EXTCODESIZE. + EVM_BALANCE = 12, ///< Balance of a given address for BALANCE. + EVM_BLOCKHASH = 13, ///< Block hash of by block number for BLOCKHASH. + EVM_ACCOUNT_EXISTS = 14, ///< Check if an account exists. + EVM_CALL_DEPTH = 15, ///< Current call depth. +}; + + +/// Opaque struct representing execution enviroment managed by the host +/// application. +struct evm_env; + +/// Variant type to represent possible types of values used in EVM. +/// +/// Type-safety is lost around the code that uses this type. We should have +/// complete set of unit tests covering all possible cases. +/// The size of the type is 64 bytes and should fit in single cache line. +union evm_variant { + /// A host-endian 64-bit integer. + int64_t int64; + + /// A big-endian 256-bit integer or hash. + struct evm_uint256be uint256be; + + struct { + /// Additional padding to align the evm_variant::address with lower + /// bytes of a full 256-bit hash. + uint8_t address_padding[12]; + + /// An Ethereum address. + struct evm_uint160be address; + }; + + /// A memory reference. + struct { + /// Pointer to the data. + uint8_t const* data; + + /// Size of the referenced memory/data. + size_t data_size; + }; +}; + +/// Query callback function. +/// +/// This callback function is used by the EVM to query the host application +/// about additional data required to execute EVM code. +/// @param env Pointer to execution environment managed by the host +/// application. +/// @param key The kind of the query. See evm_query_key and details below. +/// @param arg Additional argument to the query. It has defined value only for +/// the subset of query keys. +/// +/// ## Types of queries +/// +/// - ::EVM_GAS_PRICE +/// @param arg n/a +/// @result evm_variant::uint256be The transaction gas price. +/// +/// - ::EVM_ADDRESS +/// @param arg n/a +/// @result evm_variant::address The address of the current contract. +/// +/// - ::EVM_CALLER +/// @param arg n/a +/// @result evm_variant::address The address of the caller. +/// +/// - ::EVM_ORIGIN +/// @param arg n/a +/// @result evm_variant::address The address of the transaction initiator. +/// +/// - ::EVM_COINBASE +/// @param arg n/a +/// @result evm_variant::address The address of the beneficiary of the block fees. +/// +/// - ::EVM_DIFFICULTY +/// @param arg n/a +/// @result evm_variant::uint256be The block difficulty. +/// +/// - ::EVM_GAS_LIMIT +/// @param arg n/a +/// @result evm_variant::uint256be The block gas limit. +/// +/// - ::EVM_NUMBER +/// @param arg n/a +/// @result evm_variant::int64 The block number. +/// +/// - ::EVM_TIMESTAMP +/// @param arg n/a +/// @result evm_variant::int64 The block timestamp. +/// +/// - ::EVM_CODE_BY_ADDRESS +/// @param arg evm_variant::address The address to look up. +/// @result evm_variant::data The appropriate code for the given address or NULL if not found. +/// +/// - ::EVM_CODE_SIZE +/// @param arg evm_variant::address The address to look up. +/// @result evm_variant::data The appropriate code size for the given address or 0 if not found. +/// +/// - ::EVM_BALANCE +/// @param arg evm_variant::address The address to look up. +/// @result evm_variant::data The appropriate balance for the given address or 0 if not found. +/// +/// - ::EVM_BLOCKHASH +/// @param arg evm_variant::int64 The block number to look up. +/// @result evm_variant::uint256be The hash of the requested block or 0 if not found. +/// +/// - ::EVM_SLOAD +/// @param arg evm_variant::uint256be The index of the storage entry. +/// @result evm_variant::uint256be The current value of the storage entry. +/// +typedef union evm_variant (*evm_query_fn)(struct evm_env* env, + enum evm_query_key key, + union evm_variant arg); + +/// The update callback key. +enum evm_update_key { + EVM_SSTORE = 0, ///< Update storage entry + EVM_LOG = 1, ///< Log. + EVM_SELFDESTRUCT = 2, ///< Mark contract as selfdestructed and set + /// beneficiary address. +}; + + +/// Update callback function. +/// +/// This callback function is used by the EVM to modify contract state in the +/// host application. +/// @param env Pointer to execution environment managed by the host +/// application. +/// @param key The kind of the update. See evm_update_key and details below. +/// +/// ## Kinds of updates +/// +/// - ::EVM_SSTORE +/// @param arg1 evm_variant::uint256be The index of the storage entry. +/// @param arg2 evm_variant::uint256be The value to be stored. +/// +/// - ::EVM_LOG +/// @param arg1 evm_variant::data The log unindexed data. +/// @param arg2 evm_variant::data The log topics. The referenced data is an +/// array of evm_uint256be[] of possible length +/// from 0 to 4. So the valid +/// evm_variant::data_size values are 0, 32, 64 +/// 92 and 128. +/// +/// - ::EVM_SELFDESTRUCT +/// @param arg1 evm_variant::address The beneficiary address. +/// @param arg2 n/a +typedef void (*evm_update_fn)(struct evm_env* env, + enum evm_update_key key, + union evm_variant arg1, + union evm_variant arg2); + +/// The kind of call-like instruction. +enum evm_call_kind { + EVM_CALL = 0, ///< Request CALL. + EVM_DELEGATECALL = 1, ///< Request DELEGATECALL. The value param ignored. + EVM_CALLCODE = 2, ///< Request CALLCODE. + EVM_CREATE = 3 ///< Request CREATE. Semantic of some params changes. +}; + +/// The flag indicating call failure in evm_call_fn(). +static const int64_t EVM_CALL_FAILURE = INT64_MIN; + +/// Pointer to the callback function supporting EVM calls. +/// +/// @param env Pointer to execution environment managed by the host +/// application. +/// @param kind The kind of call-like opcode requested. +/// @param gas The amount of gas for the call. +/// @param address The address of a contract to be called. Ignored in case +/// of CREATE. +/// @param value The value sent to the callee. The endowment in case of +/// CREATE. +/// @param input The call input data or the CREATE init code. +/// @param input_size The size of the input data. +/// @param output The reference to the memory where the call output is to +/// be copied. In case of CREATE, the memory is guaranteed +/// to be at least 20 bytes to hold the address of the +/// created contract. +/// @param output_data The size of the output data. In case of CREATE, expected +/// value is 20. +/// @return If non-negative - the amount of gas left, +/// If negative - an exception occurred during the call/create. +/// There is no need to set 0 address in the output in this case. +typedef int64_t (*evm_call_fn)( + struct evm_env* env, + enum evm_call_kind kind, + int64_t gas, + struct evm_uint160be address, + struct evm_uint256be value, + uint8_t const* input, + size_t input_size, + uint8_t* output, + size_t output_size); + + +/// Opaque type representing a EVM instance. +struct evm_instance; + +/// Creates new EVM instance. +/// +/// Creates new EVM instance. The instance must be destroyed in evm_destroy(). +/// Single instance is thread-safe and can be shared by many threads. Having +/// **multiple instances is safe but discouraged** as it has not benefits over +/// having the singleton. +/// +/// @param query_fn Pointer to query callback function. Nonnull. +/// @param update_fn Pointer to update callback function. Nonnull. +/// @param call_fn Pointer to call callback function. Nonnull. +/// @return Pointer to the created EVM instance. +typedef struct evm_instance* (*evm_create_fn)(evm_query_fn query_fn, + evm_update_fn update_fn, + evm_call_fn call_fn); + +/// Destroys the EVM instance. +/// +/// @param evm The EVM instance to be destroyed. +typedef void (*evm_destroy_fn)(struct evm_instance* evm); + + +/// Configures the EVM instance. +/// +/// Allows modifying options of the EVM instance. +/// Options: +/// - code cache behavior: on, off, read-only, ... +/// - optimizations, +/// +/// @param evm The EVM instance to be configured. +/// @param name The option name. NULL-terminated string. Cannot be NULL. +/// @param value The new option value. NULL-terminated string. Cannot be NULL. +/// @return 1 if the option set successfully, 0 otherwise. +typedef int (*evm_set_option_fn)(struct evm_instance* evm, + char const* name, + char const* value); + + +/// EVM compatibility mode aka chain mode. +/// The names for the last two hard forks come from Python implementation. +enum evm_mode { + EVM_FRONTIER = 0, + EVM_HOMESTEAD = 1, + EVM_ANTI_DOS = 2, + EVM_CLEARING = 3 +}; + + +/// Generates and executes machine code for given EVM bytecode. +/// +/// All the fun is here. This function actually does something useful. +/// +/// @param instance A EVM instance. +/// @param env A pointer to the execution environment provided by the +/// user and passed to callback functions. +/// @param mode EVM compatibility mode. +/// @param code_hash A hash of the bytecode, usually Keccak. The EVM uses it +/// as the code identifier. A EVM implementation is able to +/// hash the code itself if it requires it, but the host +/// application usually has the hash already. +/// @param code Reference to the bytecode to be executed. +/// @param code_size The length of the bytecode. +/// @param gas Gas for execution. Min 0, max 2^63-1. +/// @param input Reference to the input data. +/// @param input_size The size of the input data. +/// @param value Call value. +/// @return All execution results. +typedef struct evm_result (*evm_execute_fn)(struct evm_instance* instance, + struct evm_env* env, + enum evm_mode mode, + struct evm_uint256be code_hash, + uint8_t const* code, + size_t code_size, + int64_t gas, + uint8_t const* input, + size_t input_size, + struct evm_uint256be value); + + +/// Status of a code in VM. Useful for JIT-like implementations. +enum evm_code_status { + /// The code is uknown to the VM. + EVM_UNKNOWN, + + /// The code has been compiled and is available in memory. + EVM_READY, + + /// The compiled version of the code is available in on-disk cache. + EVM_CACHED, +}; + + +/// Get information the status of the code in the VM. +typedef enum evm_code_status +(*evm_get_code_status_fn)(struct evm_instance* instance, + enum evm_mode mode, + struct evm_uint256be code_hash); + +/// Request preparation of the code for faster execution. It is not required +/// to execute the code but allows compilation of the code ahead of time in +/// JIT-like VMs. +typedef void (*evm_prepare_code_fn)(struct evm_instance* instance, + enum evm_mode mode, + struct evm_uint256be code_hash, + uint8_t const* code, + size_t code_size); + +/// VM interface. +/// +/// Defines the implementation of EVM-C interface for a VM. +struct evm_interface { + /// EVM-C ABI version implemented by the VM. + /// + /// For future use to detect ABI incompatibilities. The EVM-C ABI version + /// represented by this file is in ::EVM_ABI_VERSION. + uint32_t abi_version; + + /// Pointer to function creating a VM's instance. + evm_create_fn create; + + /// Pointer to function destroying a VM's instance. + evm_destroy_fn destroy; + + /// Pointer to function execuing a code in a VM. + evm_execute_fn execute; + + /// Optional pointer to function returning a status of a code. + /// + /// If the VM does not support this feature the pointer can be NULL. + evm_get_code_status_fn get_code_status; + + /// Optional pointer to function compiling a code. + /// + /// If the VM does not support this feature the pointer can be NULL. + evm_prepare_code_fn prepare_code; + + /// Optional pointer to function modifying VM's options. + /// + /// If the VM does not support this feature the pointer can be NULL. + evm_set_option_fn set_option; +}; + +// END Python CFFI declarations + +/// Example of a function exporting an interface for an example VM. +/// +/// Each VM implementation is obligates to provided a function returning +/// VM's interface. +/// The function has to be named as `_get_interface(void)`. +/// +/// @return VM interface +struct evm_interface examplevm_get_interface(void); + + +#if __cplusplus +} +#endif + +#endif // EVM_H +/// @} diff --git a/evmjit/include/evmjit.h b/evmjit/include/evmjit.h new file mode 100644 index 0000000000..160b822740 --- /dev/null +++ b/evmjit/include/evmjit.h @@ -0,0 +1,27 @@ +#pragma once + +#include + +#ifdef _MSC_VER +#ifdef evmjit_EXPORTS +#define EXPORT __declspec(dllexport) +#else +#define EXPORT __declspec(dllimport) +#endif + +#else +#define EXPORT __attribute__ ((visibility ("default"))) +#endif + +#if __cplusplus +extern "C" { +#endif + +/// Get EVMJIT's EVM-C interface. +/// +/// @return EVMJIT's function table. +EXPORT struct evm_interface evmjit_get_interface(void); + +#if __cplusplus +} +#endif diff --git a/evmjit/libevmjit/Arith256.cpp b/evmjit/libevmjit/Arith256.cpp new file mode 100644 index 0000000000..462bf0bdcf --- /dev/null +++ b/evmjit/libevmjit/Arith256.cpp @@ -0,0 +1,572 @@ +#include "Arith256.h" + +#include +#include + +#include "preprocessor/llvm_includes_start.h" +#include +#include +#include "preprocessor/llvm_includes_end.h" + +#include "Type.h" +#include "Endianness.h" +#include "Utils.h" + +namespace dev +{ +namespace eth +{ +namespace jit +{ + +Arith256::Arith256(IRBuilder& _builder) : + CompilerHelper(_builder) +{} + +void Arith256::debug(llvm::Value* _value, char _c, llvm::Module& _module, IRBuilder& _builder) +{ + static const auto funcName = "debug"; + auto func = _module.getFunction(funcName); + if (!func) + func = llvm::Function::Create(llvm::FunctionType::get(Type::Void, {Type::Word, _builder.getInt8Ty()}, false), llvm::Function::ExternalLinkage, funcName, &_module); + + _builder.CreateCall(func, {_builder.CreateZExtOrTrunc(_value, Type::Word), _builder.getInt8(_c)}); +} + +namespace +{ +llvm::Function* generateLongMulFunc(char const* _funcName, llvm::IntegerType* _ty, llvm::IntegerType* _wordTy, llvm::Module& _module) +{ + // C++ reference implementation: + + // using word = std::uint64_t; + // using dword = __uint128_t; + // + // static const auto wordBits = sizeof(word) * 8; + // + // template + // struct i + // { + // static const unsigned N = _N/8/sizeof(word); + // word w[N]; + // }; + // + // using int256 = i<256>; + // + // template + // i long_mul(i a, i b) + // { + // decltype(a) r = {{0}}; + // + // for (int j = 0; j < b.N; ++j) + // { + // dword carry = 0; + // for (int i = 0; i < (a.N - j); ++i) + // { + // auto& slot = r.w[j + i]; + // + // // sum of current multiplication, carry and the value from previous round using dword type + // // no overflow because (2^N - 1)*(2^N - 1) + (2^N - 1) + (2^N - 1) == 2^2N - 1 + // auto s = (dword)b.w[j] * a.w[i] + carry + slot; // safe, no overflow + // + // slot = (word) s; + // carry = s >> wordBits; + // } + // } + // + // return r; + // } + + auto func = llvm::Function::Create(llvm::FunctionType::get(_ty, {_ty, _ty}, false), llvm::Function::PrivateLinkage, _funcName, &_module); + func->setDoesNotAccessMemory(); + func->setDoesNotThrow(); + + auto iter = func->arg_begin(); + llvm::Argument* x = &(*iter++); + x->setName("x"); + llvm::Argument* y = &(*iter); + y->setName("y"); + + auto entryBB = llvm::BasicBlock::Create(func->getContext(), "Entry", func); + auto outerLoopHeaderBB = llvm::BasicBlock::Create(func->getContext(), "OuterLoop.Header", func); + auto innerLoopBB = llvm::BasicBlock::Create(func->getContext(), "InnerLoop", func); + auto outerLoopFooterBB = llvm::BasicBlock::Create(func->getContext(), "OuterLoop.Footer", func); + auto exitBB = llvm::BasicBlock::Create(func->getContext(), "Exit", func); + + auto builder = IRBuilder{entryBB}; + auto dwordTy = builder.getIntNTy(_wordTy->getBitWidth() * 2); + auto indexTy = builder.getInt32Ty(); + auto _0 = builder.getInt32(0); + auto _1 = builder.getInt32(1); + auto wordMask = builder.CreateZExt(llvm::ConstantInt::get(_wordTy, -1, true), dwordTy); + auto wordBitWidth = builder.getInt32(_wordTy->getBitWidth()); + assert(_ty->getBitWidth() / _wordTy->getBitWidth() >= 4 && "Word type must be at least 4 times smaller than full type"); + auto dim = builder.getInt32(_ty->getBitWidth() / _wordTy->getBitWidth()); + builder.CreateBr(outerLoopHeaderBB); + + auto extractWordAsDword = [&](llvm::Value* _a, llvm::Value* _idx, llvm::Twine const& _name) + { + auto word = builder.CreateLShr(_a, builder.CreateZExt(builder.CreateNUWMul(_idx, wordBitWidth), _ty)); + word = builder.CreateAnd(builder.CreateTrunc(word, dwordTy), wordMask, _name); + return word; + }; + + builder.SetInsertPoint(outerLoopHeaderBB); + auto j = builder.CreatePHI(indexTy, 2, "j"); + auto p = builder.CreatePHI(_ty, 2, "p"); + auto yj = extractWordAsDword(y, j, "y.j"); + auto iEnd = builder.CreateSub(dim, j, "i.end", true, true); + builder.CreateBr(innerLoopBB); + + builder.SetInsertPoint(innerLoopBB); + auto i = builder.CreatePHI(indexTy, 2, "i"); + auto pInner = builder.CreatePHI(_ty, 2, "p.inner"); + auto carry = builder.CreatePHI(_wordTy, 2, "carry"); + + auto k = builder.CreateNUWAdd(i, j, "k"); + auto offset = builder.CreateZExt(builder.CreateNUWMul(k, wordBitWidth), _ty, "offset"); + auto xi = extractWordAsDword(x, i, "x.i"); + auto m = builder.CreateNUWMul(xi, yj, "m"); + auto mask = builder.CreateShl(builder.CreateZExt(wordMask, _ty), offset, "mask"); + auto nmask = builder.CreateXor(mask, llvm::ConstantInt::get(_ty, -1, true), "nmask"); + auto w = builder.CreateTrunc(builder.CreateLShr(pInner, offset), dwordTy); + w = builder.CreateAnd(w, wordMask, "w"); + auto s = builder.CreateAdd(w, builder.CreateZExt(carry, dwordTy), "s.wc", true, true); + s = builder.CreateNUWAdd(s, m, "s"); + auto carryNext = builder.CreateTrunc(builder.CreateLShr(s, llvm::ConstantInt::get(dwordTy, _wordTy->getBitWidth())), _wordTy, "carry.next"); + auto wNext = builder.CreateAnd(s, wordMask); + auto pMasked = builder.CreateAnd(pInner, nmask, "p.masked"); + auto pNext = builder.CreateOr(builder.CreateShl(builder.CreateZExt(wNext, _ty), offset), pMasked, "p.next"); + + auto iNext = builder.CreateNUWAdd(i, _1, "i.next"); + auto innerLoopCond = builder.CreateICmpEQ(iNext, iEnd, "i.cond"); + builder.CreateCondBr(innerLoopCond, outerLoopFooterBB, innerLoopBB); + i->addIncoming(_0, outerLoopHeaderBB); + i->addIncoming(iNext, innerLoopBB); + pInner->addIncoming(p, outerLoopHeaderBB); + pInner->addIncoming(pNext, innerLoopBB); + carry->addIncoming(llvm::ConstantInt::get(_wordTy, 0), outerLoopHeaderBB); + carry->addIncoming(carryNext, innerLoopBB); + + builder.SetInsertPoint(outerLoopFooterBB); + auto jNext = builder.CreateNUWAdd(j, _1, "j.next"); + auto outerLoopCond = builder.CreateICmpEQ(jNext, dim, "j.cond"); + builder.CreateCondBr(outerLoopCond, exitBB, outerLoopHeaderBB); + j->addIncoming(_0, entryBB); + j->addIncoming(jNext, outerLoopFooterBB); + p->addIncoming(llvm::ConstantInt::get(_ty, 0), entryBB); + p->addIncoming(pNext, outerLoopFooterBB); + + builder.SetInsertPoint(exitBB); + builder.CreateRet(pNext); + + return func; +} +} + + +llvm::Function* Arith256::getMulFunc(llvm::Module& _module) +{ + static const auto funcName = "evm.mul.i256"; + if (auto func = _module.getFunction(funcName)) + return func; + + return generateLongMulFunc(funcName, Type::Word, Type::Size, _module); +} + +llvm::Function* Arith256::getMul512Func(llvm::Module& _module) +{ + static const auto funcName = "evm.mul.i512"; + if (auto func = _module.getFunction(funcName)) + return func; + + auto i512Ty = llvm::IntegerType::get(_module.getContext(), 512); + return generateLongMulFunc(funcName, i512Ty, Type::Size, _module); +} + +namespace +{ +llvm::Function* createUDivRemFunc(llvm::Type* _type, llvm::Module& _module, char const* _funcName) +{ + // Based of "Improved shift divisor algorithm" from "Software Integer Division" by Microsoft Research + // The following algorithm also handles divisor of value 0 returning 0 for both quotient and remainder + + auto retType = llvm::VectorType::get(_type, 2); + auto func = llvm::Function::Create(llvm::FunctionType::get(retType, {_type, _type}, false), llvm::Function::PrivateLinkage, _funcName, &_module); + func->setDoesNotThrow(); + func->setDoesNotAccessMemory(); + + auto zero = llvm::ConstantInt::get(_type, 0); + auto one = llvm::ConstantInt::get(_type, 1); + + auto iter = func->arg_begin(); + llvm::Argument* x = &(*iter++); + x->setName("x"); + llvm::Argument* y = &(*iter); + y->setName("y"); + + auto entryBB = llvm::BasicBlock::Create(_module.getContext(), "Entry", func); + auto mainBB = llvm::BasicBlock::Create(_module.getContext(), "Main", func); + auto loopBB = llvm::BasicBlock::Create(_module.getContext(), "Loop", func); + auto continueBB = llvm::BasicBlock::Create(_module.getContext(), "Continue", func); + auto returnBB = llvm::BasicBlock::Create(_module.getContext(), "Return", func); + + auto builder = IRBuilder{entryBB}; + auto yLEx = builder.CreateICmpULE(y, x); + auto r0 = x; + builder.CreateCondBr(yLEx, mainBB, returnBB); + + builder.SetInsertPoint(mainBB); + auto ctlzIntr = llvm::Intrinsic::getDeclaration(&_module, llvm::Intrinsic::ctlz, _type); + // both y and r are non-zero + auto yLz = builder.CreateCall(ctlzIntr, {y, builder.getInt1(true)}, "y.lz"); + auto rLz = builder.CreateCall(ctlzIntr, {r0, builder.getInt1(true)}, "r.lz"); + auto i0 = builder.CreateNUWSub(yLz, rLz, "i0"); + auto y0 = builder.CreateShl(y, i0); + builder.CreateBr(loopBB); + + builder.SetInsertPoint(loopBB); + auto yPhi = builder.CreatePHI(_type, 2, "y.phi"); + auto rPhi = builder.CreatePHI(_type, 2, "r.phi"); + auto iPhi = builder.CreatePHI(_type, 2, "i.phi"); + auto qPhi = builder.CreatePHI(_type, 2, "q.phi"); + auto rUpdate = builder.CreateNUWSub(rPhi, yPhi); + auto qUpdate = builder.CreateOr(qPhi, one); // q += 1, q lowest bit is 0 + auto rGEy = builder.CreateICmpUGE(rPhi, yPhi); + auto r1 = builder.CreateSelect(rGEy, rUpdate, rPhi, "r1"); + auto q1 = builder.CreateSelect(rGEy, qUpdate, qPhi, "q"); + auto iZero = builder.CreateICmpEQ(iPhi, zero); + builder.CreateCondBr(iZero, returnBB, continueBB); + + builder.SetInsertPoint(continueBB); + auto i2 = builder.CreateNUWSub(iPhi, one); + auto q2 = builder.CreateShl(q1, one); + auto y2 = builder.CreateLShr(yPhi, one); + builder.CreateBr(loopBB); + + yPhi->addIncoming(y0, mainBB); + yPhi->addIncoming(y2, continueBB); + rPhi->addIncoming(r0, mainBB); + rPhi->addIncoming(r1, continueBB); + iPhi->addIncoming(i0, mainBB); + iPhi->addIncoming(i2, continueBB); + qPhi->addIncoming(zero, mainBB); + qPhi->addIncoming(q2, continueBB); + + builder.SetInsertPoint(returnBB); + auto qRet = builder.CreatePHI(_type, 2, "q.ret"); + qRet->addIncoming(zero, entryBB); + qRet->addIncoming(q1, loopBB); + auto rRet = builder.CreatePHI(_type, 2, "r.ret"); + rRet->addIncoming(r0, entryBB); + rRet->addIncoming(r1, loopBB); + auto ret = builder.CreateInsertElement(llvm::UndefValue::get(retType), qRet, uint64_t(0), "ret0"); + ret = builder.CreateInsertElement(ret, rRet, 1, "ret"); + builder.CreateRet(ret); + + return func; +} +} + +llvm::Function* Arith256::getUDivRem256Func(llvm::Module& _module) +{ + static const auto funcName = "evm.udivrem.i256"; + if (auto func = _module.getFunction(funcName)) + return func; + + return createUDivRemFunc(Type::Word, _module, funcName); +} + +llvm::Function* Arith256::getUDivRem512Func(llvm::Module& _module) +{ + static const auto funcName = "evm.udivrem.i512"; + if (auto func = _module.getFunction(funcName)) + return func; + + return createUDivRemFunc(llvm::IntegerType::get(_module.getContext(), 512), _module, funcName); +} + +llvm::Function* Arith256::getUDiv256Func(llvm::Module& _module) +{ + static const auto funcName = "evm.udiv.i256"; + if (auto func = _module.getFunction(funcName)) + return func; + + auto udivremFunc = getUDivRem256Func(_module); + + auto func = llvm::Function::Create(llvm::FunctionType::get(Type::Word, {Type::Word, Type::Word}, false), llvm::Function::PrivateLinkage, funcName, &_module); + func->setDoesNotThrow(); + func->setDoesNotAccessMemory(); + + auto iter = func->arg_begin(); + llvm::Argument* x = &(*iter++); + x->setName("x"); + llvm::Argument* y = &(*iter); + y->setName("y"); + + auto bb = llvm::BasicBlock::Create(_module.getContext(), {}, func); + auto builder = IRBuilder{bb}; + auto udivrem = builder.CreateCall(udivremFunc, {x, y}); + auto udiv = builder.CreateExtractElement(udivrem, uint64_t(0)); + builder.CreateRet(udiv); + + return func; +} + +namespace +{ +llvm::Function* createURemFunc(llvm::Type* _type, llvm::Module& _module, char const* _funcName) +{ + auto udivremFunc = _type == Type::Word ? Arith256::getUDivRem256Func(_module) : Arith256::getUDivRem512Func(_module); + + auto func = llvm::Function::Create(llvm::FunctionType::get(_type, {_type, _type}, false), llvm::Function::PrivateLinkage, _funcName, &_module); + func->setDoesNotThrow(); + func->setDoesNotAccessMemory(); + + auto iter = func->arg_begin(); + llvm::Argument* x = &(*iter++); + x->setName("x"); + llvm::Argument* y = &(*iter); + y->setName("y"); + + auto bb = llvm::BasicBlock::Create(_module.getContext(), {}, func); + auto builder = IRBuilder{bb}; + auto udivrem = builder.CreateCall(udivremFunc, {x, y}); + auto r = builder.CreateExtractElement(udivrem, uint64_t(1)); + builder.CreateRet(r); + + return func; +} +} + +llvm::Function* Arith256::getURem256Func(llvm::Module& _module) +{ + static const auto funcName = "evm.urem.i256"; + if (auto func = _module.getFunction(funcName)) + return func; + return createURemFunc(Type::Word, _module, funcName); +} + +llvm::Function* Arith256::getURem512Func(llvm::Module& _module) +{ + static const auto funcName = "evm.urem.i512"; + if (auto func = _module.getFunction(funcName)) + return func; + return createURemFunc(llvm::IntegerType::get(_module.getContext(), 512), _module, funcName); +} + +llvm::Function* Arith256::getSDivRem256Func(llvm::Module& _module) +{ + static const auto funcName = "evm.sdivrem.i256"; + if (auto func = _module.getFunction(funcName)) + return func; + + auto udivremFunc = getUDivRem256Func(_module); + + auto retType = llvm::VectorType::get(Type::Word, 2); + auto func = llvm::Function::Create(llvm::FunctionType::get(retType, {Type::Word, Type::Word}, false), llvm::Function::PrivateLinkage, funcName, &_module); + func->setDoesNotThrow(); + func->setDoesNotAccessMemory(); + + auto iter = func->arg_begin(); + llvm::Argument* x = &(*iter++); + x->setName("x"); + llvm::Argument* y = &(*iter); + y->setName("y"); + + auto bb = llvm::BasicBlock::Create(_module.getContext(), "", func); + auto builder = IRBuilder{bb}; + auto xIsNeg = builder.CreateICmpSLT(x, Constant::get(0)); + auto xNeg = builder.CreateSub(Constant::get(0), x); + auto xAbs = builder.CreateSelect(xIsNeg, xNeg, x); + + auto yIsNeg = builder.CreateICmpSLT(y, Constant::get(0)); + auto yNeg = builder.CreateSub(Constant::get(0), y); + auto yAbs = builder.CreateSelect(yIsNeg, yNeg, y); + + auto res = builder.CreateCall(udivremFunc, {xAbs, yAbs}); + auto qAbs = builder.CreateExtractElement(res, uint64_t(0)); + auto rAbs = builder.CreateExtractElement(res, 1); + + // the remainder has the same sign as dividend + auto rNeg = builder.CreateSub(Constant::get(0), rAbs); + auto r = builder.CreateSelect(xIsNeg, rNeg, rAbs); + + auto qNeg = builder.CreateSub(Constant::get(0), qAbs); + auto xyOpposite = builder.CreateXor(xIsNeg, yIsNeg); + auto q = builder.CreateSelect(xyOpposite, qNeg, qAbs); + + auto ret = builder.CreateInsertElement(llvm::UndefValue::get(retType), q, uint64_t(0)); + ret = builder.CreateInsertElement(ret, r, 1); + builder.CreateRet(ret); + + return func; +} + +llvm::Function* Arith256::getSDiv256Func(llvm::Module& _module) +{ + static const auto funcName = "evm.sdiv.i256"; + if (auto func = _module.getFunction(funcName)) + return func; + + auto sdivremFunc = getSDivRem256Func(_module); + + auto func = llvm::Function::Create(llvm::FunctionType::get(Type::Word, {Type::Word, Type::Word}, false), llvm::Function::PrivateLinkage, funcName, &_module); + func->setDoesNotThrow(); + func->setDoesNotAccessMemory(); + + auto iter = func->arg_begin(); + llvm::Argument* x = &(*iter++); + x->setName("x"); + llvm::Argument* y = &(*iter); + y->setName("y"); + + auto bb = llvm::BasicBlock::Create(_module.getContext(), {}, func); + auto builder = IRBuilder{bb}; + auto sdivrem = builder.CreateCall(sdivremFunc, {x, y}); + auto q = builder.CreateExtractElement(sdivrem, uint64_t(0)); + builder.CreateRet(q); + + return func; +} + +llvm::Function* Arith256::getSRem256Func(llvm::Module& _module) +{ + static const auto funcName = "evm.srem.i256"; + if (auto func = _module.getFunction(funcName)) + return func; + + auto sdivremFunc = getSDivRem256Func(_module); + + auto func = llvm::Function::Create(llvm::FunctionType::get(Type::Word, {Type::Word, Type::Word}, false), llvm::Function::PrivateLinkage, funcName, &_module); + func->setDoesNotThrow(); + func->setDoesNotAccessMemory(); + + auto iter = func->arg_begin(); + llvm::Argument* x = &(*iter++); + x->setName("x"); + llvm::Argument* y = &(*iter); + y->setName("y"); + + auto bb = llvm::BasicBlock::Create(_module.getContext(), {}, func); + auto builder = IRBuilder{bb}; + auto sdivrem = builder.CreateCall(sdivremFunc, {x, y}); + auto r = builder.CreateExtractElement(sdivrem, uint64_t(1)); + builder.CreateRet(r); + + return func; +} + +llvm::Function* Arith256::getExpFunc() +{ + if (!m_exp) + { + llvm::Type* argTypes[] = {Type::Word, Type::Word}; + m_exp = llvm::Function::Create(llvm::FunctionType::get(Type::Word, argTypes, false), llvm::Function::PrivateLinkage, "exp", getModule()); + m_exp->setDoesNotThrow(); + m_exp->setDoesNotAccessMemory(); + + auto iter = m_exp->arg_begin(); + llvm::Argument* base = &(*iter++); + base->setName("base"); + llvm::Argument* exponent = &(*iter); + exponent->setName("exponent"); + + InsertPointGuard guard{m_builder}; + + // while (e != 0) { + // if (e % 2 == 1) + // r *= b; + // b *= b; + // e /= 2; + // } + + auto entryBB = llvm::BasicBlock::Create(m_builder.getContext(), "Entry", m_exp); + auto headerBB = llvm::BasicBlock::Create(m_builder.getContext(), "LoopHeader", m_exp); + auto bodyBB = llvm::BasicBlock::Create(m_builder.getContext(), "LoopBody", m_exp); + auto updateBB = llvm::BasicBlock::Create(m_builder.getContext(), "ResultUpdate", m_exp); + auto continueBB = llvm::BasicBlock::Create(m_builder.getContext(), "Continue", m_exp); + auto returnBB = llvm::BasicBlock::Create(m_builder.getContext(), "Return", m_exp); + + m_builder.SetInsertPoint(entryBB); + m_builder.CreateBr(headerBB); + + m_builder.SetInsertPoint(headerBB); + auto r = m_builder.CreatePHI(Type::Word, 2, "r"); + auto b = m_builder.CreatePHI(Type::Word, 2, "b"); + auto e = m_builder.CreatePHI(Type::Word, 2, "e"); + auto eNonZero = m_builder.CreateICmpNE(e, Constant::get(0), "e.nonzero"); + m_builder.CreateCondBr(eNonZero, bodyBB, returnBB); + + m_builder.SetInsertPoint(bodyBB); + auto eOdd = m_builder.CreateICmpNE(m_builder.CreateAnd(e, Constant::get(1)), Constant::get(0), "e.isodd"); + m_builder.CreateCondBr(eOdd, updateBB, continueBB); + + m_builder.SetInsertPoint(updateBB); + auto mul256Func = getMulFunc(*getModule()); + auto r0 = m_builder.CreateCall(mul256Func, {r, b}); + m_builder.CreateBr(continueBB); + + m_builder.SetInsertPoint(continueBB); + auto r1 = m_builder.CreatePHI(Type::Word, 2, "r1"); + r1->addIncoming(r, bodyBB); + r1->addIncoming(r0, updateBB); + auto b1 = m_builder.CreateCall(mul256Func, {b, b}); + auto e1 = m_builder.CreateLShr(e, Constant::get(1), "e1"); + m_builder.CreateBr(headerBB); + + r->addIncoming(Constant::get(1), entryBB); + r->addIncoming(r1, continueBB); + b->addIncoming(base, entryBB); + b->addIncoming(b1, continueBB); + e->addIncoming(exponent, entryBB); + e->addIncoming(e1, continueBB); + + m_builder.SetInsertPoint(returnBB); + m_builder.CreateRet(r); + } + return m_exp; +} + +llvm::Value* Arith256::exp(llvm::Value* _arg1, llvm::Value* _arg2) +{ + // while (e != 0) { + // if (e % 2 == 1) + // r *= b; + // b *= b; + // e /= 2; + // } + + if (auto c1 = llvm::dyn_cast(_arg1)) + { + if (auto c2 = llvm::dyn_cast(_arg2)) + { + auto b = c1->getValue(); + auto e = c2->getValue(); + auto r = llvm::APInt{256, 1}; + while (e != 0) + { + if (e[0]) + r *= b; + b *= b; + e = e.lshr(1); + } + return Constant::get(r); + } + } + + return m_builder.CreateCall(getExpFunc(), {_arg1, _arg2}); +} + +} +} +} + +extern "C" +{ + EXPORT void debug(uint64_t a, uint64_t b, uint64_t c, uint64_t d, char z) + { + DLOG(JIT) << "DEBUG " << std::dec << z << ": " //<< d << c << b << a + << " [" << std::hex << std::setfill('0') << std::setw(16) << d << std::setw(16) << c << std::setw(16) << b << std::setw(16) << a << "]\n"; + } +} diff --git a/evmjit/libevmjit/Arith256.h b/evmjit/libevmjit/Arith256.h new file mode 100644 index 0000000000..6c30f2e41f --- /dev/null +++ b/evmjit/libevmjit/Arith256.h @@ -0,0 +1,41 @@ +#pragma once + +#include "CompilerHelper.h" + +namespace dev +{ +namespace eth +{ +namespace jit +{ + +class Arith256 : public CompilerHelper +{ +public: + Arith256(IRBuilder& _builder); + + llvm::Value* exp(llvm::Value* _arg1, llvm::Value* _arg2); + + static void debug(llvm::Value *_value, char _c, llvm::Module &_module, IRBuilder &_builder); + + static llvm::Function* getMulFunc(llvm::Module& _module); + static llvm::Function* getMul512Func(llvm::Module& _module); + static llvm::Function* getUDiv256Func(llvm::Module& _module); + static llvm::Function* getURem256Func(llvm::Module& _module); + static llvm::Function* getURem512Func(llvm::Module& _module); + static llvm::Function* getUDivRem256Func(llvm::Module& _module); + static llvm::Function* getSDiv256Func(llvm::Module& _module); + static llvm::Function* getSRem256Func(llvm::Module& _module); + static llvm::Function* getSDivRem256Func(llvm::Module& _module); + static llvm::Function* getUDivRem512Func(llvm::Module& _module); + +private: + llvm::Function* getExpFunc(); + + llvm::Function* m_exp = nullptr; +}; + + +} +} +} diff --git a/evmjit/libevmjit/Array.cpp b/evmjit/libevmjit/Array.cpp new file mode 100644 index 0000000000..a0e22bf257 --- /dev/null +++ b/evmjit/libevmjit/Array.cpp @@ -0,0 +1,262 @@ +#include "Array.h" + +#include "preprocessor/llvm_includes_start.h" +#include +#include +#include "preprocessor/llvm_includes_end.h" + +#include "RuntimeManager.h" +#include "Utils.h" + +namespace dev +{ +namespace eth +{ +namespace jit +{ + +static const auto c_reallocStep = 1; + +llvm::Value* LazyFunction::call(IRBuilder& _builder, std::initializer_list const& _args, llvm::Twine const& _name) +{ + if (!m_func) + m_func = m_creator(); + + return _builder.CreateCall(m_func, {_args.begin(), _args.size()}, _name); +} + +llvm::Function* Array::createArrayPushFunc() +{ + llvm::Type* argTypes[] = {m_array->getType(), Type::Word}; + auto func = llvm::Function::Create(llvm::FunctionType::get(Type::Void, argTypes, false), llvm::Function::PrivateLinkage, "array.push", getModule()); + func->setDoesNotThrow(); + func->setDoesNotCapture(1); + + auto iter = func->arg_begin(); + llvm::Argument* arrayPtr = &(*iter++); + arrayPtr->setName("arrayPtr"); + llvm::Argument* value = &(*iter); + value->setName("value"); + + InsertPointGuard guard{m_builder}; + auto entryBB = llvm::BasicBlock::Create(m_builder.getContext(), "Entry", func); + auto reallocBB = llvm::BasicBlock::Create(m_builder.getContext(), "Realloc", func); + auto pushBB = llvm::BasicBlock::Create(m_builder.getContext(), "Push", func); + + m_builder.SetInsertPoint(entryBB); + auto dataPtr = m_builder.CreateStructGEP(getType(), arrayPtr, 0, "dataPtr"); + auto sizePtr = m_builder.CreateStructGEP(getType(), arrayPtr, 1, "sizePtr"); + auto capPtr = m_builder.CreateStructGEP(getType(), arrayPtr, 2, "capPtr"); + auto data = m_builder.CreateLoad(dataPtr, "data"); + auto size = m_builder.CreateLoad(sizePtr, "size"); + auto cap = m_builder.CreateLoad(capPtr, "cap"); + auto reallocReq = m_builder.CreateICmpEQ(cap, size, "reallocReq"); + m_builder.CreateCondBr(reallocReq, reallocBB, pushBB); + + m_builder.SetInsertPoint(reallocBB); + auto newCap = m_builder.CreateNUWAdd(cap, m_builder.getInt64(c_reallocStep), "newCap"); + auto reallocSize = m_builder.CreateShl(newCap, 5, "reallocSize"); // size in bytes: newCap * 32 + auto bytes = m_builder.CreateBitCast(data, Type::BytePtr, "bytes"); + auto newBytes = m_reallocFunc.call(m_builder, {bytes, reallocSize}, "newBytes"); + auto newData = m_builder.CreateBitCast(newBytes, Type::WordPtr, "newData"); + m_builder.CreateStore(newData, dataPtr); + m_builder.CreateStore(newCap, capPtr); + m_builder.CreateBr(pushBB); + + m_builder.SetInsertPoint(pushBB); + auto dataPhi = m_builder.CreatePHI(Type::WordPtr, 2, "dataPhi"); + dataPhi->addIncoming(data, entryBB); + dataPhi->addIncoming(newData, reallocBB); + auto newElemPtr = m_builder.CreateGEP(dataPhi, size, "newElemPtr"); + m_builder.CreateStore(value, newElemPtr); + auto newSize = m_builder.CreateNUWAdd(size, m_builder.getInt64(1), "newSize"); + m_builder.CreateStore(newSize, sizePtr); + m_builder.CreateRetVoid(); + + return func; +} + +llvm::Function* Array::createArraySetFunc() +{ + llvm::Type* argTypes[] = {m_array->getType(), Type::Size, Type::Word}; + auto func = llvm::Function::Create(llvm::FunctionType::get(Type::Void, argTypes, false), llvm::Function::PrivateLinkage, "array.set", getModule()); + func->setDoesNotThrow(); + func->setDoesNotCapture(1); + + auto iter = func->arg_begin(); + llvm::Argument* arrayPtr = &(*iter++); + arrayPtr->setName("arrayPtr"); + llvm::Argument* index = &(*iter++); + index->setName("index"); + llvm::Argument* value = &(*iter); + value->setName("value"); + + InsertPointGuard guard{m_builder}; + m_builder.SetInsertPoint(llvm::BasicBlock::Create(m_builder.getContext(), {}, func)); + auto dataPtr = m_builder.CreateStructGEP(getType(), arrayPtr, 0, "dataPtr"); + auto data = m_builder.CreateLoad(dataPtr, "data"); + auto valuePtr = m_builder.CreateGEP(data, index, "valuePtr"); + m_builder.CreateStore(value, valuePtr); + m_builder.CreateRetVoid(); + return func; +} + +llvm::Function* Array::createArrayGetFunc() +{ + llvm::Type* argTypes[] = {m_array->getType(), Type::Size}; + auto func = llvm::Function::Create(llvm::FunctionType::get(Type::Word, argTypes, false), llvm::Function::PrivateLinkage, "array.get", getModule()); + func->setDoesNotThrow(); + func->setDoesNotCapture(1); + + auto iter = func->arg_begin(); + llvm::Argument* arrayPtr = &(*iter++); + arrayPtr->setName("arrayPtr"); + llvm::Argument* index = &(*iter++); + index->setName("index"); + + InsertPointGuard guard{m_builder}; + m_builder.SetInsertPoint(llvm::BasicBlock::Create(m_builder.getContext(), {}, func)); + auto dataPtr = m_builder.CreateStructGEP(getType(), arrayPtr, 0, "dataPtr"); + auto data = m_builder.CreateLoad(dataPtr, "data"); + auto valuePtr = m_builder.CreateGEP(data, index, "valuePtr"); + auto value = m_builder.CreateLoad(valuePtr, "value"); + m_builder.CreateRet(value); + return func; +} + +llvm::Function* Array::createGetPtrFunc() +{ + llvm::Type* argTypes[] = {m_array->getType(), Type::Size}; + auto func = llvm::Function::Create(llvm::FunctionType::get(Type::WordPtr, argTypes, false), llvm::Function::PrivateLinkage, "array.getPtr", getModule()); + func->setDoesNotThrow(); + func->setDoesNotCapture(1); + + auto iter = func->arg_begin(); + llvm::Argument* arrayPtr = &(*iter++); + arrayPtr->setName("arrayPtr"); + llvm::Argument* index = &(*iter++); + index->setName("index"); + + InsertPointGuard guard{m_builder}; + m_builder.SetInsertPoint(llvm::BasicBlock::Create(m_builder.getContext(), {}, func)); + auto dataPtr = m_builder.CreateBitCast(arrayPtr, Type::BytePtr->getPointerTo(), "dataPtr"); + auto data = m_builder.CreateLoad(dataPtr, "data"); + auto bytePtr = m_builder.CreateGEP(data, index, "bytePtr"); + auto wordPtr = m_builder.CreateBitCast(bytePtr, Type::WordPtr, "wordPtr"); + m_builder.CreateRet(wordPtr); + return func; +} + +llvm::Function* Array::createFreeFunc() +{ + auto func = llvm::Function::Create(llvm::FunctionType::get(Type::Void, m_array->getType(), false), llvm::Function::PrivateLinkage, "array.free", getModule()); + func->setDoesNotThrow(); + func->setDoesNotCapture(1); + + auto freeFunc = llvm::Function::Create(llvm::FunctionType::get(Type::Void, Type::BytePtr, false), llvm::Function::ExternalLinkage, "free", getModule()); + freeFunc->setDoesNotThrow(); + freeFunc->setDoesNotCapture(1); + + auto arrayPtr = &func->getArgumentList().front(); + arrayPtr->setName("arrayPtr"); + + InsertPointGuard guard{m_builder}; + m_builder.SetInsertPoint(llvm::BasicBlock::Create(m_builder.getContext(), {}, func)); + auto dataPtr = m_builder.CreateStructGEP(getType(), arrayPtr, 0, "dataPtr"); + auto data = m_builder.CreateLoad(dataPtr, "data"); + auto mem = m_builder.CreateBitCast(data, Type::BytePtr, "mem"); + m_builder.CreateCall(freeFunc, mem); + m_builder.CreateRetVoid(); + return func; +} + +llvm::Function* Array::getReallocFunc() +{ + if (auto func = getModule()->getFunction("realloc")) + return func; + + llvm::Type* reallocArgTypes[] = {Type::BytePtr, Type::Size}; + auto reallocFunc = llvm::Function::Create(llvm::FunctionType::get(Type::BytePtr, reallocArgTypes, false), llvm::Function::ExternalLinkage, "realloc", getModule()); + reallocFunc->setDoesNotThrow(); + reallocFunc->setDoesNotAlias(0); + reallocFunc->setDoesNotCapture(1); + return reallocFunc; +} + +llvm::Function* Array::createExtendFunc() +{ + llvm::Type* argTypes[] = {m_array->getType(), Type::Size}; + auto func = llvm::Function::Create(llvm::FunctionType::get(Type::Void, argTypes, false), llvm::Function::PrivateLinkage, "array.extend", getModule()); + func->setDoesNotThrow(); + func->setDoesNotCapture(1); + + auto iter = func->arg_begin(); + llvm::Argument* arrayPtr = &(*iter++); + arrayPtr->setName("arrayPtr"); + llvm::Argument* newSize = &(*iter++); + newSize->setName("newSize"); + + InsertPointGuard guard{m_builder}; + m_builder.SetInsertPoint(llvm::BasicBlock::Create(m_builder.getContext(), {}, func)); + auto dataPtr = m_builder.CreateBitCast(arrayPtr, Type::BytePtr->getPointerTo(), "dataPtr");// TODO: Use byte* in Array + auto sizePtr = m_builder.CreateStructGEP(getType(), arrayPtr, 1, "sizePtr"); + auto capPtr = m_builder.CreateStructGEP(getType(), arrayPtr, 2, "capPtr"); + auto data = m_builder.CreateLoad(dataPtr, "data"); + auto size = m_builder.CreateLoad(sizePtr, "size"); + auto extSize = m_builder.CreateNUWSub(newSize, size, "extSize"); + auto newData = m_reallocFunc.call(m_builder, {data, newSize}, "newData"); // TODO: Check realloc result for null + auto extPtr = m_builder.CreateGEP(newData, size, "extPtr"); + m_builder.CreateMemSet(extPtr, m_builder.getInt8(0), extSize, 16); + m_builder.CreateStore(newData, dataPtr); + m_builder.CreateStore(newSize, sizePtr); + m_builder.CreateStore(newSize, capPtr); + m_builder.CreateRetVoid(); + return func; +} + +llvm::Type* Array::getType() +{ + llvm::Type* elementTys[] = {Type::WordPtr, Type::Size, Type::Size}; + static auto arrayTy = llvm::StructType::create(elementTys, "Array"); + return arrayTy; +} + +Array::Array(IRBuilder& _builder, char const* _name) : + CompilerHelper(_builder) +{ + m_array = m_builder.CreateAlloca(getType(), nullptr, _name); + m_builder.CreateStore(llvm::ConstantAggregateZero::get(getType()), m_array); +} + +Array::Array(IRBuilder& _builder, llvm::Value* _array) : + CompilerHelper(_builder), + m_array(_array) +{ + m_builder.CreateStore(llvm::ConstantAggregateZero::get(getType()), m_array); +} + + +void Array::pop(llvm::Value* _count) +{ + auto sizePtr = m_builder.CreateStructGEP(getType(), m_array, 1, "sizePtr"); + auto size = m_builder.CreateLoad(sizePtr, "size"); + auto newSize = m_builder.CreateNUWSub(size, _count, "newSize"); + m_builder.CreateStore(newSize, sizePtr); +} + +llvm::Value* Array::size(llvm::Value* _array) +{ + auto sizePtr = m_builder.CreateStructGEP(getType(), _array ? _array : m_array, 1, "sizePtr"); + return m_builder.CreateLoad(sizePtr, "array.size"); +} + +void Array::extend(llvm::Value* _arrayPtr, llvm::Value* _size) +{ + assert(_arrayPtr->getType() == m_array->getType()); + assert(_size->getType() == Type::Size); + m_extendFunc.call(m_builder, {_arrayPtr, _size}); +} + +} +} +} diff --git a/evmjit/libevmjit/Array.h b/evmjit/libevmjit/Array.h new file mode 100644 index 0000000000..4c295ab1da --- /dev/null +++ b/evmjit/libevmjit/Array.h @@ -0,0 +1,72 @@ +#pragma once + +#include + +#include "CompilerHelper.h" + +namespace dev +{ +namespace eth +{ +namespace jit +{ + +class LazyFunction +{ +public: + using Creator = std::function; + + LazyFunction(Creator _creator) : + m_creator(_creator) + {} + + llvm::Value* call(IRBuilder& _builder, std::initializer_list const& _args, llvm::Twine const& _name = ""); + +private: + llvm::Function* m_func = nullptr; + Creator m_creator; +}; + +class Array : public CompilerHelper +{ +public: + Array(IRBuilder& _builder, char const* _name); + Array(IRBuilder& _builder, llvm::Value* _array); + + void push(llvm::Value* _value) { m_pushFunc.call(m_builder, {m_array, _value}); } + void set(llvm::Value* _index, llvm::Value* _value) { m_setFunc.call(m_builder, {m_array, _index, _value}); } + llvm::Value* get(llvm::Value* _index) { return m_getFunc.call(m_builder, {m_array, _index}); } + void pop(llvm::Value* _count); + llvm::Value* size(llvm::Value* _array = nullptr); + void free() { m_freeFunc.call(m_builder, {m_array}); } + + void extend(llvm::Value* _arrayPtr, llvm::Value* _size); + llvm::Value* getPtr(llvm::Value* _arrayPtr, llvm::Value* _index) { return m_getPtrFunc.call(m_builder, {_arrayPtr, _index}); } + + llvm::Value* getPointerTo() const { return m_array; } + + static llvm::Type* getType(); + +private: + llvm::Value* m_array = nullptr; + + llvm::Function* createArrayPushFunc(); + llvm::Function* createArraySetFunc(); + llvm::Function* createArrayGetFunc(); + llvm::Function* createGetPtrFunc(); + llvm::Function* createFreeFunc(); + llvm::Function* createExtendFunc(); + llvm::Function* getReallocFunc(); + + LazyFunction m_pushFunc = {[this](){ return createArrayPushFunc(); }}; + LazyFunction m_setFunc = {[this](){ return createArraySetFunc(); }}; + LazyFunction m_getPtrFunc = {[this](){ return createGetPtrFunc(); }}; + LazyFunction m_getFunc = {[this](){ return createArrayGetFunc(); }}; + LazyFunction m_freeFunc = {[this](){ return createFreeFunc(); }}; + LazyFunction m_extendFunc = {[this](){ return createExtendFunc(); }}; + LazyFunction m_reallocFunc = {[this](){ return getReallocFunc(); }}; +}; + +} +} +} diff --git a/evmjit/libevmjit/BasicBlock.cpp b/evmjit/libevmjit/BasicBlock.cpp new file mode 100644 index 0000000000..4fe177e66c --- /dev/null +++ b/evmjit/libevmjit/BasicBlock.cpp @@ -0,0 +1,205 @@ +#include "BasicBlock.h" + +#include + +#include "preprocessor/llvm_includes_start.h" +#include +#include +#include +#include +#include +#include +#include +#include "preprocessor/llvm_includes_end.h" + +#include "RuntimeManager.h" +#include "Type.h" +#include "Utils.h" + +namespace dev +{ +namespace eth +{ +namespace jit +{ + +BasicBlock::BasicBlock(instr_idx _firstInstrIdx, code_iterator _begin, code_iterator _end, llvm::Function* _mainFunc): + m_firstInstrIdx{_firstInstrIdx}, + m_begin(_begin), + m_end(_end), + m_llvmBB(llvm::BasicBlock::Create(_mainFunc->getContext(), {".", std::to_string(_firstInstrIdx)}, _mainFunc)) +{} + +LocalStack::LocalStack(IRBuilder& _builder, RuntimeManager& _runtimeManager): + CompilerHelper(_builder) +{ + // Call stack.prepare. min, max, size args will be filled up in finalize(). + auto undef = llvm::UndefValue::get(Type::Size); + m_sp = m_builder.CreateCall(getStackPrepareFunc(), + {_runtimeManager.getStackBase(), _runtimeManager.getStackSize(), undef, undef, undef, _runtimeManager.getJmpBuf()}, + {"sp", m_builder.GetInsertBlock()->getName()}); +} + +void LocalStack::push(llvm::Value* _value) +{ + assert(_value->getType() == Type::Word); + m_local.push_back(_value); + m_maxSize = std::max(m_maxSize, size()); +} + +llvm::Value* LocalStack::pop() +{ + auto item = get(0); + assert(!m_local.empty() || !m_input.empty()); + + if (m_local.size() > 0) + m_local.pop_back(); + else + ++m_globalPops; + + m_minSize = std::min(m_minSize, size()); + return item; +} + +/// Copies the _index-th element of the local stack and pushes it back on the top. +void LocalStack::dup(size_t _index) +{ + auto val = get(_index); + push(val); +} + +/// Swaps the top element with the _index-th element of the local stack. +void LocalStack::swap(size_t _index) +{ + assert(_index > 0); ///< _index must not be 0. + auto val = get(_index); + auto tos = get(0); + set(_index, tos); + set(0, val); +} + +llvm::Value* LocalStack::get(size_t _index) +{ + if (_index < m_local.size()) + return *(m_local.rbegin() + _index); // count from back + + auto idx = _index - m_local.size() + m_globalPops; + if (idx >= m_input.size()) + m_input.resize(idx + 1); + auto& item = m_input[idx]; + + if (!item) + { + // Fetch an item from global stack + ssize_t globalIdx = -static_cast(idx) - 1; + auto slot = m_builder.CreateConstGEP1_64(m_sp, globalIdx); + item = m_builder.CreateAlignedLoad(slot, 16); // TODO: Handle malloc alignment. Also for 32-bit systems. + m_minSize = std::min(m_minSize, globalIdx); // remember required stack size + } + + return item; +} + +void LocalStack::set(size_t _index, llvm::Value* _word) +{ + if (_index < m_local.size()) + { + *(m_local.rbegin() + _index) = _word; + return; + } + + auto idx = _index - m_local.size() + m_globalPops; + assert(idx < m_input.size()); + m_input[idx] = _word; +} + + +void LocalStack::finalize() +{ + m_sp->setArgOperand(2, m_builder.getInt64(minSize())); + m_sp->setArgOperand(3, m_builder.getInt64(maxSize())); + m_sp->setArgOperand(4, m_builder.getInt64(size())); + + if (auto term = m_builder.GetInsertBlock()->getTerminator()) + m_builder.SetInsertPoint(term); // Insert before terminator + + auto inputIt = m_input.rbegin(); + auto localIt = m_local.begin(); + for (auto globalIdx = -static_cast(m_input.size()); globalIdx < size(); ++globalIdx) + { + llvm::Value* item = nullptr; + if (globalIdx < -m_globalPops) + { + item = *inputIt++; // update input items (might contain original value) + if (!item) // some items are skipped + continue; + } + else + item = *localIt++; // store new items + + auto slot = m_builder.CreateConstGEP1_64(m_sp, globalIdx); + m_builder.CreateAlignedStore(item, slot, 16); // TODO: Handle malloc alignment. Also for 32-bit systems. + } +} + + +llvm::Function* LocalStack::getStackPrepareFunc() +{ + static const auto c_funcName = "stack.prepare"; + if (auto func = getModule()->getFunction(c_funcName)) + return func; + + llvm::Type* argsTys[] = {Type::WordPtr, Type::Size->getPointerTo(), Type::Size, Type::Size, Type::Size, Type::BytePtr}; + auto func = llvm::Function::Create(llvm::FunctionType::get(Type::WordPtr, argsTys, false), llvm::Function::PrivateLinkage, c_funcName, getModule()); + func->setDoesNotThrow(); + func->setDoesNotAccessMemory(1); + func->setDoesNotAlias(2); + func->setDoesNotCapture(2); + + auto checkBB = llvm::BasicBlock::Create(func->getContext(), "Check", func); + auto updateBB = llvm::BasicBlock::Create(func->getContext(), "Update", func); + auto outOfStackBB = llvm::BasicBlock::Create(func->getContext(), "OutOfStack", func); + + auto iter = func->arg_begin(); + llvm::Argument* base = &(*iter++); + base->setName("base"); + llvm::Argument* sizePtr = &(*iter++); + sizePtr->setName("size.ptr"); + llvm::Argument* min = &(*iter++); + min->setName("min"); + llvm::Argument* max = &(*iter++); + max->setName("max"); + llvm::Argument* diff = &(*iter++); + diff->setName("diff"); + llvm::Argument* jmpBuf = &(*iter); + jmpBuf->setName("jmpBuf"); + + InsertPointGuard guard{m_builder}; + m_builder.SetInsertPoint(checkBB); + auto sizeAlignment = getModule()->getDataLayout().getABITypeAlignment(Type::Size); + auto size = m_builder.CreateAlignedLoad(sizePtr, sizeAlignment, "size"); + auto minSize = m_builder.CreateAdd(size, min, "size.min", false, true); + auto maxSize = m_builder.CreateAdd(size, max, "size.max", true, true); + auto minOk = m_builder.CreateICmpSGE(minSize, m_builder.getInt64(0), "ok.min"); + auto maxOk = m_builder.CreateICmpULE(maxSize, m_builder.getInt64(RuntimeManager::stackSizeLimit), "ok.max"); + auto ok = m_builder.CreateAnd(minOk, maxOk, "ok"); + m_builder.CreateCondBr(ok, updateBB, outOfStackBB, Type::expectTrue); + + m_builder.SetInsertPoint(updateBB); + auto newSize = m_builder.CreateNSWAdd(size, diff, "size.next"); + m_builder.CreateAlignedStore(newSize, sizePtr, sizeAlignment); + auto sp = m_builder.CreateGEP(base, size, "sp"); + m_builder.CreateRet(sp); + + m_builder.SetInsertPoint(outOfStackBB); + auto longjmp = llvm::Intrinsic::getDeclaration(getModule(), llvm::Intrinsic::eh_sjlj_longjmp); + m_builder.CreateCall(longjmp, {jmpBuf}); + m_builder.CreateUnreachable(); + + return func; +} + + +} +} +} diff --git a/evmjit/libevmjit/BasicBlock.h b/evmjit/libevmjit/BasicBlock.h new file mode 100644 index 0000000000..eb16a1c0bc --- /dev/null +++ b/evmjit/libevmjit/BasicBlock.h @@ -0,0 +1,88 @@ +#pragma once + +#include + +#include "Common.h" +#include "CompilerHelper.h" + +namespace dev +{ +namespace eth +{ +namespace jit +{ +using namespace evmjit; +using instr_idx = uint64_t; + +class RuntimeManager; + +class LocalStack: public CompilerHelper +{ +public: + explicit LocalStack(IRBuilder& _builder, RuntimeManager& _runtimeManager); + + /// Pushes value on stack + void push(llvm::Value* _value); + + /// Pops and returns top value + llvm::Value* pop(); + + /// Duplicates _index'th value on stack + void dup(size_t _index); + + /// Swaps _index'th value on stack with a value on stack top. + /// @param _index Index of value to be swaped. Must be > 0. + void swap(size_t _index); + + ssize_t size() const { return static_cast(m_local.size()) - m_globalPops; } + ssize_t minSize() const { return m_minSize; } + ssize_t maxSize() const { return m_maxSize; } + + /// Finalize local stack: check the requirements and update of the global stack. + void finalize(); + +private: + /// Gets _index'th value from top (counting from 0) + llvm::Value* get(size_t _index); + + /// Sets _index'th value from top (counting from 0) + void set(size_t _index, llvm::Value* _value); + + llvm::Function* getStackPrepareFunc(); + + /// Items fetched from global stack. First element matches the top of the global stack. + /// Can contain nulls if some items has been skipped. + std::vector m_input; + + /// Local stack items that has not been pushed to global stack. First item is just above global stack. + std::vector m_local; + + llvm::CallInst* m_sp = nullptr; ///< Call to stack.prepare function which returns stack pointer for current basic block. + + ssize_t m_globalPops = 0; ///< Number of items poped from global stack. In other words: global - local stack overlap. + ssize_t m_minSize = 0; ///< Minimum reached local stack size. Can be negative. + ssize_t m_maxSize = 0; ///< Maximum reached local stack size. +}; + +class BasicBlock +{ +public: + explicit BasicBlock(instr_idx _firstInstrIdx, code_iterator _begin, code_iterator _end, llvm::Function* _mainFunc); + + llvm::BasicBlock* llvm() { return m_llvmBB; } + + instr_idx firstInstrIdx() const { return m_firstInstrIdx; } + code_iterator begin() const { return m_begin; } + code_iterator end() const { return m_end; } + +private: + instr_idx const m_firstInstrIdx = 0; ///< Code index of first instruction in the block + code_iterator const m_begin = {}; ///< Iterator pointing code beginning of the block + code_iterator const m_end = {}; ///< Iterator pointing code end of the block + + llvm::BasicBlock* const m_llvmBB; ///< Reference to the LLVM BasicBlock +}; + +} +} +} diff --git a/evmjit/libevmjit/BuildInfo.h.in b/evmjit/libevmjit/BuildInfo.h.in new file mode 100644 index 0000000000..1fd995a227 --- /dev/null +++ b/evmjit/libevmjit/BuildInfo.h.in @@ -0,0 +1,9 @@ + +#define EVMJIT_VERSION "${EVMJIT_VERSION}" +#define EVMJIT_VERSION_MAJOR ${EVMJIT_VERSION_MAJOR} +#define EVMJIT_VERSION_MINOR ${EVMJIT_VERSION_MINOR} +#define EVMJIT_VERSION_PATCH ${EVMJIT_VERSION_PATCH} + +#define LLVM_VERSION "${LLVM_PACKAGE_VERSION}" +#define LLVM_ASSERTIONS "${LLVM_ENABLE_ASSERTIONS}" +#define LLVM_DEBUG ${LLVM_DEBUG} diff --git a/evmjit/libevmjit/CMakeLists.txt b/evmjit/libevmjit/CMakeLists.txt new file mode 100644 index 0000000000..f6d9822dc4 --- /dev/null +++ b/evmjit/libevmjit/CMakeLists.txt @@ -0,0 +1,169 @@ +get_filename_component(EVMJIT_INCLUDE_DIR ../include ABSOLUTE) + +set(SOURCES + ${EVMJIT_INCLUDE_DIR}/evm.h + JIT.cpp JIT.h + Arith256.cpp Arith256.h + Array.cpp Array.h + BasicBlock.cpp BasicBlock.h + Cache.cpp Cache.h + Common.h + Compiler.cpp Compiler.h + CompilerHelper.cpp CompilerHelper.h + Endianness.cpp Endianness.h + ExecStats.cpp ExecStats.h + Ext.cpp Ext.h + GasMeter.cpp GasMeter.h + Instruction.cpp Instruction.h + Memory.cpp Memory.h + Optimizer.cpp Optimizer.h + RuntimeManager.cpp RuntimeManager.h + Type.cpp Type.h + Utils.cpp Utils.h +) +source_group("" FILES ${SOURCES}) + +if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") +else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti -fvisibility=hidden") + if(CMAKE_SYSTEM_NAME STREQUAL "Linux") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--exclude-libs,ALL") # Do not export symbols from dependies, mostly LLVM libs + endif() +endif() + +if(EVMJIT_VERSION_MAJOR EQUAL 0) + set(EVMJIT_SOVERSION "0.${EVMJIT_VERSION_MINOR}") +else() + set(EVMJIT_SOVERSION ${EVMJIT_VERSION_MAJOR}) +endif() + + +string(COMPARE EQUAL "${LLVM_ENABLE_ASSERTIONS}" "ON" LLVM_DEBUG) +configure_file(BuildInfo.h.in ${CMAKE_CURRENT_BINARY_DIR}/gen/BuildInfo.gen.h) + +# "Object" library to allow building both static and shared libraries. +add_library(evmjit-objs OBJECT ${SOURCES} gen/BuildInfo.gen.h) +# Explicit dependency on llvm to download LLVM header files. +add_dependencies(evmjit-objs llvm) +# PIC is required by shared libraries. We want it in the static library as well, +# because it is going to be used to create e.g. Python modules (shared libraries). +set_target_properties(evmjit-objs PROPERTIES POSITION_INDEPENDENT_CODE On) +target_compile_definitions(evmjit-objs PRIVATE evmjit_EXPORTS) +get_target_property(LLVM_COMPILE_DEFINITIONS llvm INTERFACE_COMPILE_DEFINITIONS) +if (LLVM_COMPILE_DEFINITIONS) + target_compile_definitions(evmjit-objs PRIVATE ${LLVM_COMPILE_DEFINITIONS}) +endif() +get_target_property(LLVM_INCLUDE_DIRECTORIES llvm INTERFACE_INCLUDE_DIRECTORIES) +target_include_directories(evmjit-objs SYSTEM PRIVATE ${LLVM_INCLUDE_DIRECTORIES}) +target_include_directories(evmjit-objs PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/gen) +target_include_directories(evmjit-objs PUBLIC ${EVMJIT_INCLUDE_DIR}) + +# Static library. +add_library(evmjit-static STATIC $) +target_link_libraries(evmjit-static PRIVATE llvm) + +# Shared library. +add_library(evmjit SHARED $) +set_target_properties(evmjit PROPERTIES + VERSION ${EVMJIT_VERSION} + SOVERSION ${EVMJIT_SOVERSION} + FOLDER "libs") +target_link_libraries(evmjit PRIVATE llvm) + +include(GNUInstallDirs) +install(TARGETS evmjit + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) +install(DIRECTORY ${EVMJIT_INCLUDE_DIR}/ + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) + +# This section configures evmjit-standalone -- a static library containing +# evmjit and all its static dependencies. + +# This function tries to get a list of all static library dependencies of +# a target. It probably does not handle all cases to be generic, but works for +# LLVM case. +function(get_link_libraries OUTPUT_LIST TARGET) + get_target_property(IMPORTED ${TARGET} IMPORTED) + list(APPEND VISITED_TARGETS ${TARGET}) + if (IMPORTED) + get_target_property(LIBS ${TARGET} INTERFACE_LINK_LIBRARIES) + else() + get_target_property(LIBS ${TARGET} LINK_LIBRARIES) + endif() + set(LIB_FILES "") + foreach(LIB ${LIBS}) + if (TARGET ${LIB}) + list(FIND VISITED_TARGETS ${LIB} VISITED) + if (${VISITED} EQUAL -1) + get_target_property(LIB_FILE ${LIB} LOCATION) + get_link_libraries(LINK_LIB_FILES ${LIB}) + list(APPEND LIB_FILES ${LIB_FILE} ${LINK_LIB_FILES}) + endif() + elseif (IS_ABSOLUTE ${LIB}) + # Here LIB is a full path to a (hopefuly static) library. We don't + # want system libs (usually dynamic) here. + list(APPEND LIB_FILES ${LIB}) + endif() + endforeach() + set(VISITED_TARGETS ${VISITED_TARGETS} PARENT_SCOPE) + list(REMOVE_DUPLICATES LIB_FILES) + set(${OUTPUT_LIST} ${LIB_FILES} PARENT_SCOPE) +endfunction() + + +get_link_libraries(EVMJIT_LINK_LIBRARIES evmjit) +set(EVMJIT_STANDALONE_FILE ${CMAKE_STATIC_LIBRARY_PREFIX}evmjit-standalone${CMAKE_STATIC_LIBRARY_SUFFIX}) +if (MSVC) + add_library(evmjit-standalone STATIC EXCLUDE_FROM_ALL $) + string(REPLACE ";" " " FLAGS "${EVMJIT_LINK_LIBRARIES}") + set_target_properties(evmjit-standalone PROPERTIES STATIC_LIBRARY_FLAGS "${FLAGS}") + install(TARGETS evmjit-standalone + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) +elseif (APPLE) + add_custom_command(OUTPUT ${EVMJIT_STANDALONE_FILE} + COMMAND libtool -static -o ${EVMJIT_STANDALONE_FILE} $ ${EVMJIT_LINK_LIBRARIES} + VERBATIM) + add_custom_target(evmjit-standalone DEPENDS ${EVMJIT_STANDALONE_FILE}) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${EVMJIT_STANDALONE_FILE} DESTINATION ${CMAKE_INSTALL_LIBDIR} OPTIONAL) +elseif (CMAKE_AR) + # For platforms using ar a linker scripts is created and used to create + # the standalone library. + + string(REPLACE ";" "\\naddlib " AR_SCRIPT ";${EVMJIT_LINK_LIBRARIES}") + set(AR_SCRIPT "create ${EVMJIT_STANDALONE_FILE}\\naddlib $${AR_SCRIPT}\\nsave\\nend\\n") + set(AR_SCRIPT_FILE ${CMAKE_STATIC_LIBRARY_PREFIX}evmjit-standalone.ar-script) + + # Generate the linker script. + add_custom_command(OUTPUT ${AR_SCRIPT_FILE} + COMMAND printf ${AR_SCRIPT} > ${AR_SCRIPT_FILE} + DEPENDS $ + VERBATIM) + + # Execute the script. + add_custom_command(OUTPUT ${EVMJIT_STANDALONE_FILE} + COMMAND ${CMAKE_AR} -M < ${AR_SCRIPT_FILE} + MAIN_DEPENDENCY ${AR_SCRIPT_FILE} + VERBATIM) + + add_custom_target(evmjit-standalone DEPENDS ${EVMJIT_STANDALONE_FILE}) + + # The "thin" library is also provided. It is smaller that the standalone one + # but cannot be redistributed. + set(EVMJIT_STANDALONE_THIN_FILE ${CMAKE_STATIC_LIBRARY_PREFIX}evmjit-standalone-thin${CMAKE_STATIC_LIBRARY_SUFFIX}) + + add_custom_command(OUTPUT ${EVMJIT_STANDALONE_THIN_FILE} + COMMAND ${CMAKE_AR} cTq ${EVMJIT_STANDALONE_THIN_FILE} $ ${EVMJIT_LINK_LIBRARIES}) + + add_custom_target(evmjit-standalone-thin ALL DEPENDS ${EVMJIT_STANDALONE_THIN_FILE}) + # FIXME: Looks it will be better to create evmjit-standalone as a library with costum steps instead of custom taget. + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${EVMJIT_STANDALONE_FILE} DESTINATION ${CMAKE_INSTALL_LIBDIR} OPTIONAL) +endif() + +# Export the full path to evmjit-standalone library to be used in tests. +# TODO: It would be easier if evmjit-standalone was a library target, but it +# works for now. +set(EVMJIT_STANDALONE_LIB ${CMAKE_CURRENT_BINARY_DIR}/${EVMJIT_STANDALONE_FILE} PARENT_SCOPE) diff --git a/evmjit/libevmjit/Cache.cpp b/evmjit/libevmjit/Cache.cpp new file mode 100644 index 0000000000..3e10845555 --- /dev/null +++ b/evmjit/libevmjit/Cache.cpp @@ -0,0 +1,181 @@ +#include "Cache.h" + +#include + +#include "preprocessor/llvm_includes_start.h" +#include +#include +#include +#include +#include +#include +#include +#include "preprocessor/llvm_includes_end.h" + +#include "ExecStats.h" +#include "Utils.h" + +namespace dev +{ +namespace evmjit +{ + +namespace +{ + /// The ABI version of jitted codes. It reflects how a generated code + /// communicates with outside world. When this communication changes old + /// cached code must be invalidated. + const auto c_internalABIVersion = 4; + + using Guard = std::lock_guard; + std::mutex x_cacheMutex; + CacheMode g_mode; + std::unique_ptr g_lastObject; + JITListener* g_listener; + + std::string getVersionedCacheDir() + { + llvm::SmallString<256> path; + llvm::sys::path::user_cache_directory(path, "ethereum", "evmjit", + std::to_string(c_internalABIVersion)); + return path.str(); + } + +} + +ObjectCache* Cache::init(CacheMode _mode, JITListener* _listener) +{ + DLOG(cache) << "Cache dir: " << getVersionedCacheDir() << "\n"; + + Guard g{x_cacheMutex}; + + g_mode = _mode; + g_listener = _listener; + + if (g_mode == CacheMode::clear) + { + Cache::clear(); + g_mode = CacheMode::off; + } + + if (g_mode != CacheMode::off) + { + static ObjectCache objectCache; + return &objectCache; + } + return nullptr; +} + +void Cache::clear() +{ + Guard g{x_cacheMutex}; + + auto cachePath = getVersionedCacheDir(); + std::error_code err; + for (auto it = llvm::sys::fs::directory_iterator{cachePath, err}; it != decltype(it){}; it.increment(err)) + llvm::sys::fs::remove(it->path()); +} + +void Cache::preload(llvm::ExecutionEngine& _ee, std::unordered_map& _funcCache, + llvm::LLVMContext& _llvmContext) +{ + Guard g{x_cacheMutex}; + + // Disable listener + auto listener = g_listener; + g_listener = nullptr; + + auto cachePath = getVersionedCacheDir(); + std::error_code err; + for (auto it = llvm::sys::fs::directory_iterator{cachePath, err}; it != decltype(it){}; it.increment(err)) + { + auto name = it->path().substr(cachePath.size() + 1); + if (auto module = getObject(name, _llvmContext)) + { + DLOG(cache) << "Preload: " << name << "\n"; + _ee.addModule(std::move(module)); + auto addr = _ee.getFunctionAddress(name); + assert(addr); + _funcCache[std::move(name)] = addr; + } + } + + g_listener = listener; +} + +std::unique_ptr Cache::getObject(std::string const& id, llvm::LLVMContext& _llvmContext) +{ + Guard g{x_cacheMutex}; + + if (g_mode != CacheMode::on && g_mode != CacheMode::read) + return nullptr; + + // TODO: Disabled because is not thread-safe. + //if (g_listener) + // g_listener->stateChanged(ExecState::CacheLoad); + + DLOG(cache) << id << ": search\n"; + if (!CHECK(!g_lastObject)) + g_lastObject = nullptr; + + llvm::SmallString<256> cachePath{getVersionedCacheDir()}; + llvm::sys::path::append(cachePath, id); + + if (auto r = llvm::MemoryBuffer::getFile(cachePath, -1, false)) + g_lastObject = llvm::MemoryBuffer::getMemBufferCopy(r.get()->getBuffer()); + else if (r.getError() != std::make_error_code(std::errc::no_such_file_or_directory)) + DLOG(cache) << r.getError().message(); // TODO: Add warning log + + if (g_lastObject) // if object found create fake module + { + DLOG(cache) << id << ": found\n"; + auto module = llvm::make_unique(id, _llvmContext); + auto mainFuncType = llvm::FunctionType::get(llvm::Type::getVoidTy(_llvmContext), {}, false); + auto mainFunc = llvm::Function::Create(mainFuncType, llvm::Function::ExternalLinkage, id, module.get()); + auto bb = llvm::BasicBlock::Create(_llvmContext, {}, mainFunc); + bb->getInstList().push_back(new llvm::UnreachableInst{_llvmContext}); + return module; + } + DLOG(cache) << id << ": not found\n"; + return nullptr; +} + + +void ObjectCache::notifyObjectCompiled(llvm::Module const* _module, llvm::MemoryBufferRef _object) +{ + Guard g{x_cacheMutex}; + + // Only in "on" and "write" mode + if (g_mode != CacheMode::on && g_mode != CacheMode::write) + return; + + // TODO: Disabled because is not thread-safe. + // if (g_listener) + // g_listener->stateChanged(ExecState::CacheWrite); + + auto&& id = _module->getModuleIdentifier(); + llvm::SmallString<256> cachePath{getVersionedCacheDir()}; + if (auto err = llvm::sys::fs::create_directories(cachePath)) + { + DLOG(cache) << "Cannot create cache dir " << cachePath.str().str() << " (error: " << err.message() << "\n"; + return; + } + + llvm::sys::path::append(cachePath, id); + + DLOG(cache) << id << ": write\n"; + std::error_code error; + llvm::raw_fd_ostream cacheFile(cachePath, error, llvm::sys::fs::F_None); + cacheFile << _object.getBuffer(); +} + +std::unique_ptr ObjectCache::getObject(llvm::Module const* _module) +{ + Guard g{x_cacheMutex}; + + DLOG(cache) << _module->getModuleIdentifier() << ": use\n"; + return std::move(g_lastObject); +} + +} +} diff --git a/evmjit/libevmjit/Cache.h b/evmjit/libevmjit/Cache.h new file mode 100644 index 0000000000..45eb8daa84 --- /dev/null +++ b/evmjit/libevmjit/Cache.h @@ -0,0 +1,61 @@ +#pragma once + +#include +#include + +#include "preprocessor/llvm_includes_start.h" +#include +#include +#include "preprocessor/llvm_includes_end.h" + +namespace llvm +{ + class ExecutionEngine; +} + +namespace dev +{ +namespace evmjit +{ +class JITListener; + +enum class CacheMode +{ + off, + on, + read, + write, + clear, + preload +}; + +class ObjectCache : public llvm::ObjectCache +{ +public: + /// notifyObjectCompiled - Provides a pointer to compiled code for Module M. + virtual void notifyObjectCompiled(llvm::Module const* _module, llvm::MemoryBufferRef _object) final override; + + /// getObjectCopy - Returns a pointer to a newly allocated MemoryBuffer that + /// contains the object which corresponds with Module M, or 0 if an object is + /// not available. The caller owns both the MemoryBuffer returned by this + /// and the memory it references. + virtual std::unique_ptr getObject(llvm::Module const* _module) final override; +}; + + +class Cache +{ +public: + static ObjectCache* init(CacheMode _mode, JITListener* _listener); + static std::unique_ptr getObject(std::string const& id, llvm::LLVMContext& _llvmContext); + + /// Clears cache storage + static void clear(); + + /// Loads all available cached objects to ExecutionEngine + static void preload(llvm::ExecutionEngine& _ee, std::unordered_map& _funcCache, + llvm::LLVMContext& _llvmContext); +}; + +} +} diff --git a/evmjit/libevmjit/Common.h b/evmjit/libevmjit/Common.h new file mode 100644 index 0000000000..d4b23c70da --- /dev/null +++ b/evmjit/libevmjit/Common.h @@ -0,0 +1,16 @@ +#pragma once + +#include + +namespace dev +{ +namespace evmjit +{ + +using byte = uint8_t; +using code_iterator = byte const*; + +#define UNTESTED assert(false) + +} +} diff --git a/evmjit/libevmjit/Compiler.cpp b/evmjit/libevmjit/Compiler.cpp new file mode 100644 index 0000000000..27696233cc --- /dev/null +++ b/evmjit/libevmjit/Compiler.cpp @@ -0,0 +1,941 @@ +#include "Compiler.h" + +#include +#include +#include + +#include "preprocessor/llvm_includes_start.h" +#include +#include +#include +#include "preprocessor/llvm_includes_end.h" + +#include "JIT.h" +#include "Instruction.h" +#include "Type.h" +#include "Memory.h" +#include "Ext.h" +#include "GasMeter.h" +#include "Utils.h" +#include "Endianness.h" +#include "Arith256.h" +#include "RuntimeManager.h" + +namespace dev +{ +namespace eth +{ +namespace jit +{ + +static const auto c_destIdxLabel = "destIdx"; + +Compiler::Compiler(Options const& _options, evm_mode _mode, llvm::LLVMContext& _llvmContext): + m_options(_options), + m_mode(_mode), + m_builder(_llvmContext) +{ + Type::init(m_builder.getContext()); +} + +std::vector Compiler::createBasicBlocks(code_iterator _codeBegin, code_iterator _codeEnd) +{ + /// Helper function that skips push data and finds next iterator (can be the end) + auto skipPushDataAndGetNext = [](code_iterator _curr, code_iterator _end) + { + static const auto push1 = static_cast(Instruction::PUSH1); + static const auto push32 = static_cast(Instruction::PUSH32); + size_t offset = 1; + if (*_curr >= push1 && *_curr <= push32) + offset += std::min(*_curr - push1 + 1, (_end - _curr) - 1); + return _curr + offset; + }; + + std::vector blocks; + + bool isDead = false; + auto begin = _codeBegin; // begin of current block + for (auto curr = begin, next = begin; curr != _codeEnd; curr = next) + { + next = skipPushDataAndGetNext(curr, _codeEnd); + + if (isDead) + { + if (Instruction(*curr) == Instruction::JUMPDEST) + { + isDead = false; + begin = curr; + } + else + continue; + } + + bool isEnd = false; + switch (Instruction(*curr)) + { + case Instruction::JUMP: + case Instruction::RETURN: + case Instruction::STOP: + case Instruction::SUICIDE: + isDead = true; + case Instruction::JUMPI: + isEnd = true; + break; + + default: + break; + } + + assert(next <= _codeEnd); + if (next == _codeEnd || Instruction(*next) == Instruction::JUMPDEST) + isEnd = true; + + if (isEnd) + { + auto beginIdx = begin - _codeBegin; + blocks.emplace_back(beginIdx, begin, next, m_mainFunc); + begin = next; + } + } + + return blocks; +} + +void Compiler::resolveJumps() +{ + auto jumpTable = llvm::cast(m_jumpTableBB->getTerminator()); + auto jumpTableInput = llvm::cast(m_jumpTableBB->begin()); + + // Iterate through all EVM instructions blocks (skip first one and last 4 - special blocks). + for (auto it = std::next(m_mainFunc->begin()), end = std::prev(m_mainFunc->end(), 4); it != end; ++it) + { + auto nextBlockIter = it; + ++nextBlockIter; // If the last code block, that will be "stop" block. + auto currentBlockPtr = &(*it); + auto nextBlockPtr = &(*nextBlockIter); + + auto term = it->getTerminator(); + llvm::BranchInst* jump = nullptr; + + if (!term) // Block may have no terminator if the next instruction is a jump destination. + IRBuilder{currentBlockPtr}.CreateBr(nextBlockPtr); + else if ((jump = llvm::dyn_cast(term)) && jump->getSuccessor(0) == m_jumpTableBB) + { + auto destIdx = llvm::cast(jump->getMetadata(c_destIdxLabel)->getOperand(0))->getValue(); + if (auto constant = llvm::dyn_cast(destIdx)) + { + // If destination index is a constant do direct jump to the destination block. + auto bb = jumpTable->findCaseValue(constant).getCaseSuccessor(); + jump->setSuccessor(0, bb); + } + else + jumpTableInput->addIncoming(destIdx, currentBlockPtr); // Fill up PHI node + + if (jump->isConditional()) + jump->setSuccessor(1, &(*nextBlockIter)); // Set next block for conditional jumps + } + } + + auto simplifiedInput = jumpTableInput->getNumIncomingValues() == 0 ? + llvm::UndefValue::get(jumpTableInput->getType()) : + jumpTableInput->hasConstantValue(); + if (simplifiedInput) + { + jumpTableInput->replaceAllUsesWith(simplifiedInput); + jumpTableInput->eraseFromParent(); + } +} + +std::unique_ptr Compiler::compile(code_iterator _begin, code_iterator _end, std::string const& _id) +{ + auto module = llvm::make_unique(_id, m_builder.getContext()); // TODO: Provide native DataLayout + + // Create main function + auto mainFuncType = llvm::FunctionType::get(Type::MainReturn, Type::RuntimePtr, false); + m_mainFunc = llvm::Function::Create(mainFuncType, llvm::Function::ExternalLinkage, _id, module.get()); + m_mainFunc->getArgumentList().front().setName("rt"); + + // Create entry basic block + auto entryBB = llvm::BasicBlock::Create(m_builder.getContext(), "Entry", m_mainFunc); + + auto blocks = createBasicBlocks(_begin, _end); + + // Special "Stop" block. Guarantees that there exists a next block after the code blocks (also when there are no code blocks). + auto stopBB = llvm::BasicBlock::Create(m_mainFunc->getContext(), "Stop", m_mainFunc); + m_jumpTableBB = llvm::BasicBlock::Create(m_mainFunc->getContext(), "JumpTable", m_mainFunc); + auto abortBB = llvm::BasicBlock::Create(m_mainFunc->getContext(), "Abort", m_mainFunc); + + m_builder.SetInsertPoint(m_jumpTableBB); // Must be before basic blocks compilation + auto target = m_builder.CreatePHI(Type::Word, 16, "target"); + m_builder.CreateSwitch(target, abortBB); + + m_builder.SetInsertPoint(entryBB); + + + // Init runtime structures. + RuntimeManager runtimeManager(m_builder, _begin, _end); + GasMeter gasMeter(m_builder, runtimeManager, m_mode); + Memory memory(runtimeManager, gasMeter); + Ext ext(runtimeManager, memory); + Arith256 arith(m_builder); + + auto jmpBufWords = m_builder.CreateAlloca(Type::BytePtr, m_builder.getInt64(3), "jmpBuf.words"); + auto frameaddress = llvm::Intrinsic::getDeclaration(module.get(), llvm::Intrinsic::frameaddress); + auto fp = m_builder.CreateCall(frameaddress, m_builder.getInt32(0), "fp"); + m_builder.CreateStore(fp, jmpBufWords); + auto stacksave = llvm::Intrinsic::getDeclaration(module.get(), llvm::Intrinsic::stacksave); + auto sp = m_builder.CreateCall(stacksave, {}, "sp"); + auto jmpBufSp = m_builder.CreateConstInBoundsGEP1_64(jmpBufWords, 2, "jmpBuf.sp"); + m_builder.CreateStore(sp, jmpBufSp); + auto setjmp = llvm::Intrinsic::getDeclaration(module.get(), llvm::Intrinsic::eh_sjlj_setjmp); + auto jmpBuf = m_builder.CreateBitCast(jmpBufWords, Type::BytePtr, "jmpBuf"); + auto r = m_builder.CreateCall(setjmp, jmpBuf); + auto normalFlow = m_builder.CreateICmpEQ(r, m_builder.getInt32(0)); + runtimeManager.setJmpBuf(jmpBuf); + m_builder.CreateCondBr(normalFlow, entryBB->getNextNode(), abortBB, Type::expectTrue); + + for (auto& block: blocks) + compileBasicBlock(block, runtimeManager, arith, memory, ext, gasMeter); + + // Code for special blocks: + m_builder.SetInsertPoint(stopBB); + runtimeManager.exit(ReturnCode::Stop); + + m_builder.SetInsertPoint(abortBB); + runtimeManager.exit(ReturnCode::OutOfGas); + + resolveJumps(); + + return module; +} + + +void Compiler::compileBasicBlock(BasicBlock& _basicBlock, RuntimeManager& _runtimeManager, + Arith256& _arith, Memory& _memory, Ext& _ext, GasMeter& _gasMeter) +{ + m_builder.SetInsertPoint(_basicBlock.llvm()); + LocalStack stack{m_builder, _runtimeManager}; + + for (auto it = _basicBlock.begin(); it != _basicBlock.end(); ++it) + { + auto inst = Instruction(*it); + + _gasMeter.count(inst); + + switch (inst) + { + + case Instruction::ADD: + { + auto lhs = stack.pop(); + auto rhs = stack.pop(); + auto result = m_builder.CreateAdd(lhs, rhs); + stack.push(result); + break; + } + + case Instruction::SUB: + { + auto lhs = stack.pop(); + auto rhs = stack.pop(); + auto result = m_builder.CreateSub(lhs, rhs); + stack.push(result); + break; + } + + case Instruction::MUL: + { + auto lhs = stack.pop(); + auto rhs = stack.pop(); + auto res = m_builder.CreateMul(lhs, rhs); + stack.push(res); + break; + } + + case Instruction::DIV: + { + auto d = stack.pop(); + auto n = stack.pop(); + auto divByZero = m_builder.CreateICmpEQ(n, Constant::get(0)); + n = m_builder.CreateSelect(divByZero, Constant::get(1), n); // protect against hardware signal + auto r = m_builder.CreateUDiv(d, n); + r = m_builder.CreateSelect(divByZero, Constant::get(0), r); + stack.push(r); + break; + } + + case Instruction::SDIV: + { + auto d = stack.pop(); + auto n = stack.pop(); + auto divByZero = m_builder.CreateICmpEQ(n, Constant::get(0)); + auto divByMinusOne = m_builder.CreateICmpEQ(n, Constant::get(-1)); + n = m_builder.CreateSelect(divByZero, Constant::get(1), n); // protect against hardware signal + auto r = m_builder.CreateSDiv(d, n); + r = m_builder.CreateSelect(divByZero, Constant::get(0), r); + auto dNeg = m_builder.CreateSub(Constant::get(0), d); + r = m_builder.CreateSelect(divByMinusOne, dNeg, r); // protect against undef i256.min / -1 + stack.push(r); + break; + } + + case Instruction::MOD: + { + auto d = stack.pop(); + auto n = stack.pop(); + auto divByZero = m_builder.CreateICmpEQ(n, Constant::get(0)); + n = m_builder.CreateSelect(divByZero, Constant::get(1), n); // protect against hardware signal + auto r = m_builder.CreateURem(d, n); + r = m_builder.CreateSelect(divByZero, Constant::get(0), r); + stack.push(r); + break; + } + + case Instruction::SMOD: + { + auto d = stack.pop(); + auto n = stack.pop(); + auto divByZero = m_builder.CreateICmpEQ(n, Constant::get(0)); + auto divByMinusOne = m_builder.CreateICmpEQ(n, Constant::get(-1)); + n = m_builder.CreateSelect(divByZero, Constant::get(1), n); // protect against hardware signal + auto r = m_builder.CreateSRem(d, n); + r = m_builder.CreateSelect(divByZero, Constant::get(0), r); + r = m_builder.CreateSelect(divByMinusOne, Constant::get(0), r); // protect against undef i256.min / -1 + stack.push(r); + break; + } + + case Instruction::ADDMOD: + { + auto i512Ty = m_builder.getIntNTy(512); + auto a = stack.pop(); + auto b = stack.pop(); + auto m = stack.pop(); + auto divByZero = m_builder.CreateICmpEQ(m, Constant::get(0)); + a = m_builder.CreateZExt(a, i512Ty); + b = m_builder.CreateZExt(b, i512Ty); + m = m_builder.CreateZExt(m, i512Ty); + auto s = m_builder.CreateNUWAdd(a, b); + s = m_builder.CreateURem(s, m); + s = m_builder.CreateTrunc(s, Type::Word); + s = m_builder.CreateSelect(divByZero, Constant::get(0), s); + stack.push(s); + break; + } + + case Instruction::MULMOD: + { + auto i512Ty = m_builder.getIntNTy(512); + auto a = stack.pop(); + auto b = stack.pop(); + auto m = stack.pop(); + auto divByZero = m_builder.CreateICmpEQ(m, Constant::get(0)); + a = m_builder.CreateZExt(a, i512Ty); + b = m_builder.CreateZExt(b, i512Ty); + m = m_builder.CreateZExt(m, i512Ty); + auto p = m_builder.CreateNUWMul(a, b); + p = m_builder.CreateURem(p, m); + p = m_builder.CreateTrunc(p, Type::Word); + p = m_builder.CreateSelect(divByZero, Constant::get(0), p); + stack.push(p); + break; + } + + case Instruction::EXP: + { + auto base = stack.pop(); + auto exponent = stack.pop(); + _gasMeter.countExp(exponent); + auto ret = _arith.exp(base, exponent); + stack.push(ret); + break; + } + + case Instruction::NOT: + { + auto value = stack.pop(); + auto ret = m_builder.CreateXor(value, Constant::get(-1), "bnot"); + stack.push(ret); + break; + } + + case Instruction::LT: + { + auto lhs = stack.pop(); + auto rhs = stack.pop(); + auto res1 = m_builder.CreateICmpULT(lhs, rhs); + auto res256 = m_builder.CreateZExt(res1, Type::Word); + stack.push(res256); + break; + } + + case Instruction::GT: + { + auto lhs = stack.pop(); + auto rhs = stack.pop(); + auto res1 = m_builder.CreateICmpUGT(lhs, rhs); + auto res256 = m_builder.CreateZExt(res1, Type::Word); + stack.push(res256); + break; + } + + case Instruction::SLT: + { + auto lhs = stack.pop(); + auto rhs = stack.pop(); + auto res1 = m_builder.CreateICmpSLT(lhs, rhs); + auto res256 = m_builder.CreateZExt(res1, Type::Word); + stack.push(res256); + break; + } + + case Instruction::SGT: + { + auto lhs = stack.pop(); + auto rhs = stack.pop(); + auto res1 = m_builder.CreateICmpSGT(lhs, rhs); + auto res256 = m_builder.CreateZExt(res1, Type::Word); + stack.push(res256); + break; + } + + case Instruction::EQ: + { + auto lhs = stack.pop(); + auto rhs = stack.pop(); + auto res1 = m_builder.CreateICmpEQ(lhs, rhs); + auto res256 = m_builder.CreateZExt(res1, Type::Word); + stack.push(res256); + break; + } + + case Instruction::ISZERO: + { + auto top = stack.pop(); + auto iszero = m_builder.CreateICmpEQ(top, Constant::get(0), "iszero"); + auto result = m_builder.CreateZExt(iszero, Type::Word); + stack.push(result); + break; + } + + case Instruction::AND: + { + auto lhs = stack.pop(); + auto rhs = stack.pop(); + auto res = m_builder.CreateAnd(lhs, rhs); + stack.push(res); + break; + } + + case Instruction::OR: + { + auto lhs = stack.pop(); + auto rhs = stack.pop(); + auto res = m_builder.CreateOr(lhs, rhs); + stack.push(res); + break; + } + + case Instruction::XOR: + { + auto lhs = stack.pop(); + auto rhs = stack.pop(); + auto res = m_builder.CreateXor(lhs, rhs); + stack.push(res); + break; + } + + case Instruction::BYTE: + { + const auto idx = stack.pop(); + auto value = Endianness::toBE(m_builder, stack.pop()); + + auto idxValid = m_builder.CreateICmpULT(idx, Constant::get(32), "idxValid"); + auto bytes = m_builder.CreateBitCast(value, llvm::VectorType::get(Type::Byte, 32), "bytes"); + // TODO: Workaround for LLVM bug. Using big value of index causes invalid memory access. + auto safeIdx = m_builder.CreateTrunc(idx, m_builder.getIntNTy(5)); + // TODO: Workaround for LLVM bug. DAG Builder used sext on index instead of zext + safeIdx = m_builder.CreateZExt(safeIdx, Type::Size); + auto byte = m_builder.CreateExtractElement(bytes, safeIdx, "byte"); + value = m_builder.CreateZExt(byte, Type::Word); + value = m_builder.CreateSelect(idxValid, value, Constant::get(0)); + stack.push(value); + break; + } + + case Instruction::SIGNEXTEND: + { + auto idx = stack.pop(); + auto word = stack.pop(); + + auto k32_ = m_builder.CreateTrunc(idx, m_builder.getIntNTy(5), "k_32"); + auto k32 = m_builder.CreateZExt(k32_, Type::Size); + auto k32x8 = m_builder.CreateMul(k32, m_builder.getInt64(8), "kx8"); + + // test for word >> (k * 8 + 7) + auto bitpos = m_builder.CreateAdd(k32x8, m_builder.getInt64(7), "bitpos"); + auto bitposEx = m_builder.CreateZExt(bitpos, Type::Word); + auto bitval = m_builder.CreateLShr(word, bitposEx, "bitval"); + auto bittest = m_builder.CreateTrunc(bitval, Type::Bool, "bittest"); + + auto mask_ = m_builder.CreateShl(Constant::get(1), bitposEx); + auto mask = m_builder.CreateSub(mask_, Constant::get(1), "mask"); + + auto negmask = m_builder.CreateXor(mask, llvm::ConstantInt::getAllOnesValue(Type::Word), "negmask"); + auto val1 = m_builder.CreateOr(word, negmask); + auto val0 = m_builder.CreateAnd(word, mask); + + auto kInRange = m_builder.CreateICmpULE(idx, llvm::ConstantInt::get(Type::Word, 30)); + auto result = m_builder.CreateSelect(kInRange, + m_builder.CreateSelect(bittest, val1, val0), + word); + stack.push(result); + break; + } + + case Instruction::SHA3: + { + auto inOff = stack.pop(); + auto inSize = stack.pop(); + _memory.require(inOff, inSize); + _gasMeter.countSha3Data(inSize); + auto hash = _ext.sha3(inOff, inSize); + stack.push(hash); + break; + } + + case Instruction::POP: + { + stack.pop(); + break; + } + + case Instruction::ANY_PUSH: + { + auto value = readPushData(it, _basicBlock.end()); + stack.push(Constant::get(value)); + break; + } + + case Instruction::ANY_DUP: + { + auto index = static_cast(inst) - static_cast(Instruction::DUP1); + stack.dup(index); + break; + } + + case Instruction::ANY_SWAP: + { + auto index = static_cast(inst) - static_cast(Instruction::SWAP1) + 1; + stack.swap(index); + break; + } + + case Instruction::MLOAD: + { + auto addr = stack.pop(); + auto word = _memory.loadWord(addr); + stack.push(word); + break; + } + + case Instruction::MSTORE: + { + auto addr = stack.pop(); + auto word = stack.pop(); + _memory.storeWord(addr, word); + break; + } + + case Instruction::MSTORE8: + { + auto addr = stack.pop(); + auto word = stack.pop(); + _memory.storeByte(addr, word); + break; + } + + case Instruction::MSIZE: + { + auto word = _memory.getSize(); + stack.push(word); + break; + } + + case Instruction::SLOAD: + { + auto index = stack.pop(); + auto value = _ext.sload(index); + stack.push(value); + break; + } + + case Instruction::SSTORE: + { + auto index = stack.pop(); + auto value = stack.pop(); + _gasMeter.countSStore(_ext, index, value); + _ext.sstore(index, value); + break; + } + + case Instruction::JUMP: + case Instruction::JUMPI: + { + auto destIdx = llvm::MDNode::get(m_builder.getContext(), llvm::ValueAsMetadata::get(stack.pop())); + + // Create branch instruction, initially to jump table. + // Destination will be optimized with direct jump during jump resolving if destination index is a constant. + auto jumpInst = (inst == Instruction::JUMP) ? + m_builder.CreateBr(m_jumpTableBB) : + m_builder.CreateCondBr(m_builder.CreateICmpNE(stack.pop(), Constant::get(0), "jump.check"), m_jumpTableBB, nullptr); + + // Attach medatada to branch instruction with information about destination index. + jumpInst->setMetadata(c_destIdxLabel, destIdx); + break; + } + + case Instruction::JUMPDEST: + { + // Add the basic block to the jump table. + assert(it == _basicBlock.begin() && "JUMPDEST must be the first instruction of a basic block"); + auto jumpTable = llvm::cast(m_jumpTableBB->getTerminator()); + jumpTable->addCase(Constant::get(_basicBlock.firstInstrIdx()), _basicBlock.llvm()); + break; + } + + case Instruction::PC: + { + auto value = Constant::get(it - _basicBlock.begin() + _basicBlock.firstInstrIdx()); + stack.push(value); + break; + } + + case Instruction::GAS: + { + _gasMeter.commitCostBlock(); + stack.push(m_builder.CreateZExt(_runtimeManager.getGas(), Type::Word)); + break; + } + + case Instruction::ADDRESS: + stack.push(_ext.query(EVM_ADDRESS)); + break; + case Instruction::CALLER: + stack.push(_ext.query(EVM_CALLER)); + break; + case Instruction::ORIGIN: + stack.push(_ext.query(EVM_ORIGIN)); + break; + case Instruction::COINBASE: + stack.push(_ext.query(EVM_COINBASE)); + break; + + case Instruction::GASPRICE: + stack.push(_ext.query(EVM_GAS_PRICE)); + break; + + case Instruction::DIFFICULTY: + stack.push(_ext.query(EVM_DIFFICULTY)); + break; + + case Instruction::GASLIMIT: + stack.push(_ext.query(EVM_GAS_LIMIT)); + break; + + case Instruction::NUMBER: + stack.push(_ext.query(EVM_NUMBER)); + break; + + case Instruction::TIMESTAMP: + stack.push(_ext.query(EVM_TIMESTAMP)); + break; + + case Instruction::CALLVALUE: + { + auto beValue = _runtimeManager.getValue(); + stack.push(Endianness::toNative(m_builder, beValue)); + break; + } + + case Instruction::CODESIZE: + stack.push(_runtimeManager.getCodeSize()); + break; + + case Instruction::CALLDATASIZE: + stack.push(_runtimeManager.getCallDataSize()); + break; + + case Instruction::BLOCKHASH: + { + auto number = stack.pop(); + // If number bigger than int64 assume the result is 0. + auto limitC = m_builder.getInt64(std::numeric_limits::max()); + auto limit = m_builder.CreateZExt(limitC, Type::Word); + auto isBigNumber = m_builder.CreateICmpUGT(number, limit); + auto hash = _ext.blockHash(number); + // TODO: Try to eliminate the call if the number is invalid. + hash = m_builder.CreateSelect(isBigNumber, Constant::get(0), hash); + stack.push(hash); + break; + } + + case Instruction::BALANCE: + { + auto address = stack.pop(); + auto value = _ext.balance(address); + stack.push(value); + break; + } + + case Instruction::EXTCODESIZE: + { + auto addr = stack.pop(); + auto codesize = _ext.extcodesize(addr); + stack.push(codesize); + break; + } + + case Instruction::CALLDATACOPY: + { + auto destMemIdx = stack.pop(); + auto srcIdx = stack.pop(); + auto reqBytes = stack.pop(); + + auto srcPtr = _runtimeManager.getCallData(); + auto srcSize = _runtimeManager.getCallDataSize(); + + _memory.copyBytes(srcPtr, srcSize, srcIdx, destMemIdx, reqBytes); + break; + } + + case Instruction::CODECOPY: + { + auto destMemIdx = stack.pop(); + auto srcIdx = stack.pop(); + auto reqBytes = stack.pop(); + + auto srcPtr = _runtimeManager.getCode(); // TODO: Code & its size are constants, feature #80814234 + auto srcSize = _runtimeManager.getCodeSize(); + + _memory.copyBytes(srcPtr, srcSize, srcIdx, destMemIdx, reqBytes); + break; + } + + case Instruction::EXTCODECOPY: + { + auto addr = stack.pop(); + auto destMemIdx = stack.pop(); + auto srcIdx = stack.pop(); + auto reqBytes = stack.pop(); + + auto codeRef = _ext.extcode(addr); + + _memory.copyBytes(codeRef.ptr, codeRef.size, srcIdx, destMemIdx, reqBytes); + break; + } + + case Instruction::CALLDATALOAD: + { + auto idx = stack.pop(); + auto value = _ext.calldataload(idx); + stack.push(value); + break; + } + + case Instruction::CREATE: + { + auto endowment = stack.pop(); + auto initOff = stack.pop(); + auto initSize = stack.pop(); + _memory.require(initOff, initSize); + + _gasMeter.commitCostBlock(); + auto gas = _runtimeManager.getGas(); + llvm::Value* gasKept = (m_mode >= EVM_ANTI_DOS) ? + m_builder.CreateLShr(gas, 6) : + m_builder.getInt64(0); + auto createGas = m_builder.CreateSub(gas, gasKept, "create.gas", true, true); + llvm::Value* r = nullptr; + llvm::Value* pAddr = nullptr; + std::tie(r, pAddr) = _ext.create(createGas, endowment, initOff, initSize); + + auto ret = + m_builder.CreateICmpSGE(r, m_builder.getInt64(0), "create.ret"); + auto rmagic = m_builder.CreateSelect( + ret, m_builder.getInt64(0), m_builder.getInt64(EVM_CALL_FAILURE), + "call.rmagic"); + // TODO: optimize + auto gasLeft = m_builder.CreateSub(r, rmagic, "create.gasleft"); + gas = m_builder.CreateAdd(gasLeft, gasKept); + _runtimeManager.setGas(gas); + + llvm::Value* addr = m_builder.CreateLoad(pAddr); + addr = Endianness::toNative(m_builder, addr); + addr = m_builder.CreateZExt(addr, Type::Word); + addr = m_builder.CreateSelect(ret, addr, Constant::get(0)); + stack.push(addr); + break; + } + + case Instruction::DELEGATECALL: + if (m_mode == EVM_FRONTIER) + { + // Invalid opcode in Frontier compatibility mode. + _runtimeManager.exit(ReturnCode::OutOfGas); + it = _basicBlock.end() - 1; // finish block compilation + break; + } + // else, fall-through + case Instruction::CALL: + case Instruction::CALLCODE: + { + auto kind = (inst == Instruction::CALL) ? + EVM_CALL : + (inst == Instruction::CALLCODE) ? EVM_CALLCODE : + EVM_DELEGATECALL; + auto callGas = stack.pop(); + auto address = stack.pop(); + auto value = (kind == EVM_DELEGATECALL) ? Constant::get(0) : stack.pop(); + + auto inOff = stack.pop(); + auto inSize = stack.pop(); + auto outOff = stack.pop(); + auto outSize = stack.pop(); + + _gasMeter.commitCostBlock(); + + // Require memory for in and out buffers + _memory.require(outOff, outSize); // Out buffer first as we guess + // it will be after the in one + _memory.require(inOff, inSize); + + auto noTransfer = m_builder.CreateICmpEQ(value, Constant::get(0)); + auto transferCost = m_builder.CreateSelect( + noTransfer, m_builder.getInt64(0), + m_builder.getInt64(JITSchedule::valueTransferGas::value)); + _gasMeter.count(transferCost, _runtimeManager.getJmpBuf(), + _runtimeManager.getGasPtr()); + + if (inst == Instruction::CALL) + { + auto accountExists = _ext.exists(address); + auto noPenaltyCond = accountExists; + if (m_mode >= EVM_CLEARING) + noPenaltyCond = m_builder.CreateOr(accountExists, noTransfer); + auto penalty = m_builder.CreateSelect(noPenaltyCond, + m_builder.getInt64(0), + m_builder.getInt64(JITSchedule::callNewAccount::value)); + _gasMeter.count(penalty, _runtimeManager.getJmpBuf(), + _runtimeManager.getGasPtr()); + } + + if (m_mode >= EVM_ANTI_DOS) + { + auto gas = _runtimeManager.getGas(); + auto gas64th = m_builder.CreateLShr(gas, 6); + auto gasMaxAllowed = m_builder.CreateZExt( + m_builder.CreateSub(gas, gas64th, "gas.maxallowed", + true, true), Type::Word); + auto cmp = m_builder.CreateICmpUGT(callGas, gasMaxAllowed); + callGas = m_builder.CreateSelect(cmp, gasMaxAllowed, callGas); + } + + _gasMeter.count(callGas, _runtimeManager.getJmpBuf(), + _runtimeManager.getGasPtr()); + auto stipend = m_builder.CreateSelect( + noTransfer, m_builder.getInt64(0), + m_builder.getInt64(JITSchedule::callStipend::value)); + auto gas = m_builder.CreateTrunc(callGas, Type::Gas, "call.gas.declared"); + gas = m_builder.CreateAdd(gas, stipend, "call.gas", true, true); + auto r = _ext.call(kind, gas, address, value, inOff, inSize, outOff, + outSize); + auto ret = + m_builder.CreateICmpSGE(r, m_builder.getInt64(0), "call.ret"); + auto rmagic = m_builder.CreateSelect( + ret, m_builder.getInt64(0), m_builder.getInt64(EVM_CALL_FAILURE), + "call.rmagic"); + // TODO: optimize + auto finalGas = m_builder.CreateSub(r, rmagic, "call.finalgas"); + _gasMeter.giveBack(finalGas); + stack.push(m_builder.CreateZExt(ret, Type::Word)); + break; + } + + case Instruction::RETURN: + { + auto index = stack.pop(); + auto size = stack.pop(); + + _memory.require(index, size); + _runtimeManager.registerReturnData(index, size); + + _runtimeManager.exit(ReturnCode::Return); + break; + } + + case Instruction::SUICIDE: + { + auto dest = stack.pop(); + if (m_mode >= EVM_ANTI_DOS) + { + auto destExists = _ext.exists(dest); + auto noPenaltyCond = destExists; + if (m_mode >= EVM_CLEARING) + { + auto addr = _ext.query(EVM_ADDRESS); + auto balance = _ext.balance(addr); + auto noTransfer = m_builder.CreateICmpEQ(balance, + Constant::get(0)); + noPenaltyCond = m_builder.CreateOr(destExists, noTransfer); + } + auto penalty = m_builder.CreateSelect( + noPenaltyCond, m_builder.getInt64(0), + m_builder.getInt64(JITSchedule::callNewAccount::value)); + _gasMeter.count(penalty, _runtimeManager.getJmpBuf(), + _runtimeManager.getGasPtr()); + } + _ext.selfdestruct(dest); + } + // Fallthrough. + case Instruction::STOP: + _runtimeManager.exit(ReturnCode::Stop); + break; + + case Instruction::LOG0: + case Instruction::LOG1: + case Instruction::LOG2: + case Instruction::LOG3: + case Instruction::LOG4: + { + auto beginIdx = stack.pop(); + auto numBytes = stack.pop(); + _memory.require(beginIdx, numBytes); + + // This will commit the current cost block + _gasMeter.countLogData(numBytes); + + llvm::SmallVector topics; + auto numTopics = static_cast(inst) - static_cast(Instruction::LOG0); + for (size_t i = 0; i < numTopics; ++i) + topics.emplace_back(stack.pop()); + + _ext.log(beginIdx, numBytes, topics); + break; + } + + default: // Invalid instruction - abort + _runtimeManager.exit(ReturnCode::OutOfGas); + it = _basicBlock.end() - 1; // finish block compilation + } + } + + _gasMeter.commitCostBlock(); + + stack.finalize(); +} + + +} +} +} diff --git a/evmjit/libevmjit/Compiler.h b/evmjit/libevmjit/Compiler.h new file mode 100644 index 0000000000..9455fe8f71 --- /dev/null +++ b/evmjit/libevmjit/Compiler.h @@ -0,0 +1,56 @@ +#pragma once + +#include "JIT.h" +#include "BasicBlock.h" + +namespace dev +{ +namespace eth +{ +namespace jit +{ + +class Compiler +{ +public: + + struct Options + { + /// Rewrite switch instructions to sequences of branches + bool rewriteSwitchToBranches = true; + + /// Dump CFG as a .dot file for graphviz + bool dumpCFG = false; + }; + + Compiler(Options const& _options, evm_mode _mode, llvm::LLVMContext& _llvmContext); + + std::unique_ptr compile(code_iterator _begin, code_iterator _end, std::string const& _id); + +private: + + std::vector createBasicBlocks(code_iterator _begin, code_iterator _end); + + void compileBasicBlock(BasicBlock& _basicBlock, class RuntimeManager& _runtimeManager, class Arith256& _arith, class Memory& _memory, class Ext& _ext, class GasMeter& _gasMeter); + + void resolveJumps(); + + /// Compiler options + Options const& m_options; + + /// EVM compatibility mode. + evm_mode m_mode; + + /// Helper class for generating IR + IRBuilder m_builder; + + /// Block with a jump table. + llvm::BasicBlock* m_jumpTableBB = nullptr; + + /// Main program function + llvm::Function* m_mainFunc = nullptr; +}; + +} +} +} diff --git a/evmjit/libevmjit/CompilerHelper.cpp b/evmjit/libevmjit/CompilerHelper.cpp new file mode 100644 index 0000000000..25e456350c --- /dev/null +++ b/evmjit/libevmjit/CompilerHelper.cpp @@ -0,0 +1,46 @@ +#include "CompilerHelper.h" + +#include "preprocessor/llvm_includes_start.h" +#include +#include "preprocessor/llvm_includes_end.h" + +#include "RuntimeManager.h" + +namespace dev +{ +namespace eth +{ +namespace jit +{ + +CompilerHelper::CompilerHelper(IRBuilder& _builder) : + m_builder(_builder) +{} + +llvm::Module* CompilerHelper::getModule() +{ + assert(m_builder.GetInsertBlock()); + assert(m_builder.GetInsertBlock()->getParent()); // BB must be in a function + return m_builder.GetInsertBlock()->getParent()->getParent(); +} + +llvm::Function* CompilerHelper::getMainFunction() +{ + // TODO: Rename or change semantics of getMainFunction() function + assert(m_builder.GetInsertBlock()); + auto mainFunc = m_builder.GetInsertBlock()->getParent(); + assert(mainFunc); + if (mainFunc == &mainFunc->getParent()->getFunctionList().front()) // Main function is the first one in module + return mainFunc; + return nullptr; +} + + +RuntimeHelper::RuntimeHelper(RuntimeManager& _runtimeManager): + CompilerHelper(_runtimeManager.m_builder), + m_runtimeManager(_runtimeManager) +{} + +} +} +} diff --git a/evmjit/libevmjit/CompilerHelper.h b/evmjit/libevmjit/CompilerHelper.h new file mode 100644 index 0000000000..c5a5205fab --- /dev/null +++ b/evmjit/libevmjit/CompilerHelper.h @@ -0,0 +1,63 @@ +#pragma once + +#include "preprocessor/llvm_includes_start.h" +#include +#include "preprocessor/llvm_includes_end.h" + + +namespace dev +{ +namespace eth +{ +namespace jit +{ +class RuntimeManager; + +using IRBuilder = llvm::IRBuilder<>; + +/// Base class for compiler helpers like Memory, GasMeter, etc. +class CompilerHelper +{ +protected: + CompilerHelper(IRBuilder& _builder); + + CompilerHelper(const CompilerHelper&) = delete; + CompilerHelper& operator=(CompilerHelper) = delete; + + /// Reference to the IR module being compiled + llvm::Module* getModule(); + + /// Reference to the main module function + llvm::Function* getMainFunction(); + + /// Reference to parent compiler IR builder + IRBuilder& m_builder; + + friend class RuntimeHelper; +}; + +/// Compiler helper that depends on runtime data +class RuntimeHelper : public CompilerHelper +{ +protected: + RuntimeHelper(RuntimeManager& _runtimeManager); + + RuntimeManager& getRuntimeManager() { return m_runtimeManager; } + +private: + RuntimeManager& m_runtimeManager; +}; + +struct InsertPointGuard +{ + explicit InsertPointGuard(llvm::IRBuilderBase& _builder): m_builder(_builder), m_insertPoint(_builder.saveIP()) {} + ~InsertPointGuard() { m_builder.restoreIP(m_insertPoint); } + +private: + llvm::IRBuilderBase& m_builder; + llvm::IRBuilderBase::InsertPoint m_insertPoint; +}; + +} +} +} diff --git a/evmjit/libevmjit/Endianness.cpp b/evmjit/libevmjit/Endianness.cpp new file mode 100644 index 0000000000..0358824abc --- /dev/null +++ b/evmjit/libevmjit/Endianness.cpp @@ -0,0 +1,33 @@ +#include "Endianness.h" + +#include "preprocessor/llvm_includes_start.h" +#include +#include +#include "preprocessor/llvm_includes_end.h" + +#include "Type.h" + +namespace dev +{ +namespace eth +{ +namespace jit +{ + +llvm::Value* Endianness::bswapIfLE(IRBuilder& _builder, llvm::Value* _value) +{ + if (llvm::sys::IsLittleEndianHost) + { + if (auto constant = llvm::dyn_cast(_value)) + return _builder.getInt(constant->getValue().byteSwap()); + + // OPT: Cache func declaration? + auto bswapFunc = llvm::Intrinsic::getDeclaration(_builder.GetInsertBlock()->getParent()->getParent(), llvm::Intrinsic::bswap, _value->getType()); + return _builder.CreateCall(bswapFunc, _value); + } + return _value; +} + +} +} +} diff --git a/evmjit/libevmjit/Endianness.h b/evmjit/libevmjit/Endianness.h new file mode 100644 index 0000000000..d0a8e7bb52 --- /dev/null +++ b/evmjit/libevmjit/Endianness.h @@ -0,0 +1,23 @@ +#pragma once + +#include "CompilerHelper.h" + +namespace dev +{ +namespace eth +{ +namespace jit +{ + +struct Endianness +{ + static llvm::Value* toBE(IRBuilder& _builder, llvm::Value* _word) { return bswapIfLE(_builder, _word); } + static llvm::Value* toNative(IRBuilder& _builder, llvm::Value* _word) { return bswapIfLE(_builder, _word); } + +private: + static llvm::Value* bswapIfLE(IRBuilder& _builder, llvm::Value* _word); +}; + +} +} +} diff --git a/evmjit/libevmjit/ExecStats.cpp b/evmjit/libevmjit/ExecStats.cpp new file mode 100644 index 0000000000..2891f35e78 --- /dev/null +++ b/evmjit/libevmjit/ExecStats.cpp @@ -0,0 +1,95 @@ +#include "ExecStats.h" + +#include +#include +#include + +#include "Utils.h" + +namespace dev +{ +namespace evmjit +{ + +void ExecStats::stateChanged(ExecState _state) +{ + if (!CHECK(m_state != ExecState::Finished)) + return; + + auto now = clock::now(); + if (_state != ExecState::Started) + { + assert(time[(int)m_state] == ExecStats::duration::zero()); + time[(int)m_state] = now - m_tp; + } + m_state = _state; + m_tp = now; +} + +namespace +{ +struct StatsAgg +{ + using unit = std::chrono::microseconds; + ExecStats::duration tot = ExecStats::duration::zero(); + ExecStats::duration min = ExecStats::duration::max(); + ExecStats::duration max = ExecStats::duration::zero(); + size_t count = 0; + + void update(ExecStats::duration _d) + { + ++count; + tot += _d; + min = _d < min ? _d : min; + max = _d > max ? _d : max; + } + + void output(char const* _name, std::ostream& _os) + { + auto avg = tot / count; + _os << std::setfill(' ') + << std::setw(12) << std::left << _name + << std::setw(10) << std::right << std::chrono::duration_cast(tot).count() + << std::setw(10) << std::right << std::chrono::duration_cast(avg).count() + << std::setw(10) << std::right << std::chrono::duration_cast(min).count() + << std::setw(10) << std::right << std::chrono::duration_cast(max).count() + << std::endl; + } +}; + +char const* getExecStateName(ExecState _state) +{ + switch (_state) + { + case ExecState::Started: return "Start"; + case ExecState::CacheLoad: return "CacheLoad"; + case ExecState::CacheWrite: return "CacheWrite"; + case ExecState::Compilation: return "Compilation"; + case ExecState::Optimization: return "Optimization"; + case ExecState::CodeGen: return "CodeGen"; + case ExecState::Execution: return "Execution"; + case ExecState::Return: return "Return"; + case ExecState::Finished: return "Finish"; + } + return nullptr; +} +} + +StatsCollector::~StatsCollector() +{ + if (stats.empty()) + return; + + std::cout << " [us] total avg min max\n"; + for (int i = 0; i < (int)ExecState::Finished; ++i) + { + StatsAgg agg; + for (auto&& s : stats) + agg.update(s->time[i]); + + agg.output(getExecStateName(ExecState(i)), std::cout); + } +} + +} +} diff --git a/evmjit/libevmjit/ExecStats.h b/evmjit/libevmjit/ExecStats.h new file mode 100644 index 0000000000..dffd373d4a --- /dev/null +++ b/evmjit/libevmjit/ExecStats.h @@ -0,0 +1,68 @@ +#pragma once + +#include +#include +#include +#include + +namespace dev +{ +namespace evmjit +{ + +enum class ExecState +{ + Started, + CacheLoad, + CacheWrite, + Compilation, + Optimization, + CodeGen, + Execution, + Return, + Finished +}; + +class JITListener +{ +public: + JITListener() = default; + JITListener(JITListener const&) = delete; + JITListener& operator=(JITListener) = delete; + virtual ~JITListener() {} + + virtual void executionStarted() {} + virtual void executionEnded() {} + + virtual void stateChanged(ExecState) {} +}; + +class ExecStats : public JITListener +{ +public: + using clock = std::chrono::high_resolution_clock; + using duration = clock::duration; + using time_point = clock::time_point; + + std::string id; + duration time[(int)ExecState::Finished] = {}; + + void stateChanged(ExecState _state) override; + +private: + ExecState m_state = {}; + time_point m_tp = {}; + +}; + + +class StatsCollector +{ +public: + std::vector> stats; + + ~StatsCollector(); +}; + +} +} diff --git a/evmjit/libevmjit/Ext.cpp b/evmjit/libevmjit/Ext.cpp new file mode 100644 index 0000000000..55df108a79 --- /dev/null +++ b/evmjit/libevmjit/Ext.cpp @@ -0,0 +1,528 @@ +#include "Ext.h" + +#include "preprocessor/llvm_includes_start.h" +#include +#include +#include "preprocessor/llvm_includes_end.h" + +#include "RuntimeManager.h" +#include "Memory.h" +#include "Type.h" +#include "Endianness.h" + +namespace dev +{ +namespace eth +{ +namespace jit +{ + +Ext::Ext(RuntimeManager& _runtimeManager, Memory& _memoryMan) : + RuntimeHelper(_runtimeManager), + m_memoryMan(_memoryMan) +{ + m_funcs = decltype(m_funcs)(); + m_argAllocas = decltype(m_argAllocas)(); + m_size = m_builder.CreateAlloca(Type::Size, nullptr, "env.size"); +} + +namespace +{ + +using FuncDesc = std::tuple; + +llvm::FunctionType* getFunctionType(llvm::Type* _returnType, std::initializer_list const& _argsTypes) +{ + return llvm::FunctionType::get(_returnType, llvm::ArrayRef{_argsTypes.begin(), _argsTypes.size()}, false); +} + +std::array::value> const& getEnvFuncDescs() +{ + static std::array::value> descs{{ + FuncDesc{"env_sload", getFunctionType(Type::Void, {Type::EnvPtr, Type::WordPtr, Type::WordPtr})}, + FuncDesc{"env_sstore", getFunctionType(Type::Void, {Type::EnvPtr, Type::WordPtr, Type::WordPtr})}, + FuncDesc{"env_sha3", getFunctionType(Type::Void, {Type::BytePtr, Type::Size, Type::WordPtr})}, + FuncDesc{"env_balance", getFunctionType(Type::Void, {Type::WordPtr, Type::EnvPtr, Type::WordPtr})}, + FuncDesc{"env_create", getFunctionType(Type::Void, {Type::EnvPtr, Type::GasPtr, Type::WordPtr, Type::BytePtr, Type::Size, Type::WordPtr})}, + FuncDesc{"env_call", getFunctionType(Type::Bool, {Type::EnvPtr, Type::GasPtr, Type::Gas, Type::WordPtr, Type::WordPtr, Type::WordPtr, Type::WordPtr, Type::WordPtr, Type::BytePtr, Type::Size, Type::BytePtr, Type::Size})}, + FuncDesc{"env_log", getFunctionType(Type::Void, {Type::EnvPtr, Type::BytePtr, Type::Size, Type::WordPtr, Type::WordPtr, Type::WordPtr, Type::WordPtr})}, + FuncDesc{"env_blockhash", getFunctionType(Type::Void, {Type::EnvPtr, Type::WordPtr, Type::WordPtr})}, + FuncDesc{"env_extcode", getFunctionType(Type::BytePtr, {Type::EnvPtr, Type::WordPtr, Type::Size->getPointerTo()})}, + }}; + + return descs; +} + +llvm::Function* createFunc(EnvFunc _id, llvm::Module* _module) +{ + auto&& desc = getEnvFuncDescs()[static_cast(_id)]; + return llvm::Function::Create(std::get<1>(desc), llvm::Function::ExternalLinkage, std::get<0>(desc), _module); +} + +llvm::Function* getQueryFunc(llvm::Module* _module) +{ + static const auto funcName = "evm.query"; + auto func = _module->getFunction(funcName); + if (!func) + { + // TODO: Mark the function as pure to eliminate multiple calls. + auto i32 = llvm::IntegerType::getInt32Ty(_module->getContext()); + auto fty = llvm::FunctionType::get(Type::Void, {Type::WordPtr, Type::EnvPtr, i32, Type::WordPtr}, false); + func = llvm::Function::Create(fty, llvm::Function::ExternalLinkage, funcName, _module); + func->addAttribute(1, llvm::Attribute::StructRet); + func->addAttribute(1, llvm::Attribute::NoAlias); + func->addAttribute(1, llvm::Attribute::NoCapture); + func->addAttribute(4, llvm::Attribute::ByVal); + func->addAttribute(4, llvm::Attribute::ReadOnly); + func->addAttribute(4, llvm::Attribute::NoAlias); + func->addAttribute(4, llvm::Attribute::NoCapture); + } + return func; +} + +llvm::Function* getUpdateFunc(llvm::Module* _module) +{ + static const auto funcName = "evm.update"; + auto func = _module->getFunction(funcName); + if (!func) + { + auto i32 = llvm::IntegerType::getInt32Ty(_module->getContext()); + auto fty = llvm::FunctionType::get(Type::Void, {Type::EnvPtr, i32, Type::WordPtr, Type::WordPtr}, false); + func = llvm::Function::Create(fty, llvm::Function::ExternalLinkage, funcName, _module); + func->addAttribute(3, llvm::Attribute::ByVal); + func->addAttribute(3, llvm::Attribute::ReadOnly); + func->addAttribute(3, llvm::Attribute::NoAlias); + func->addAttribute(3, llvm::Attribute::NoCapture); + func->addAttribute(4, llvm::Attribute::ByVal); + func->addAttribute(4, llvm::Attribute::ReadOnly); + func->addAttribute(4, llvm::Attribute::NoAlias); + func->addAttribute(4, llvm::Attribute::NoCapture); + } + return func; +} + +llvm::StructType* getMemRefTy(llvm::Module* _module) +{ + static const auto name = "evm.memref"; + auto ty = _module->getTypeByName(name); + if (!ty) + ty = llvm::StructType::create({Type::BytePtr, Type::Size}, name); + return ty; +} + +llvm::Function* getCallFunc(llvm::Module* _module) +{ + static const auto funcName = "call"; + auto func = _module->getFunction(funcName); + if (!func) + { + auto i32 = llvm::IntegerType::getInt32Ty(_module->getContext()); + auto hash160Ty = llvm::IntegerType::getIntNTy(_module->getContext(), 160); + // TODO: Should be use Triple here? + #ifdef _MSC_VER + auto onWindows = true; + #else + auto onWindows = false; + #endif + auto fty = llvm::FunctionType::get( + Type::Gas, + {Type::EnvPtr, i32, Type::Gas, hash160Ty->getPointerTo(), Type::WordPtr, Type::BytePtr, Type::Size, Type::BytePtr, Type::Size}, + false); + func = llvm::Function::Create(fty, llvm::Function::ExternalLinkage, "evm.call", _module); + func->addAttribute(4, llvm::Attribute::ByVal); + func->addAttribute(4, llvm::Attribute::ReadOnly); + func->addAttribute(4, llvm::Attribute::NoAlias); + func->addAttribute(4, llvm::Attribute::NoCapture); + if (!onWindows) + func->addAttribute(5, llvm::Attribute::ByVal); + func->addAttribute(5, llvm::Attribute::ReadOnly); + func->addAttribute(5, llvm::Attribute::NoAlias); + func->addAttribute(5, llvm::Attribute::NoCapture); + func->addAttribute(6, llvm::Attribute::ReadOnly); + func->addAttribute(6, llvm::Attribute::NoCapture); + func->addAttribute(8, llvm::Attribute::NoCapture); + auto callFunc = func; + + // Create a call wrapper to handle additional checks. + func = llvm::Function::Create(fty, llvm::Function::PrivateLinkage, funcName, _module); + func->addAttribute(4, llvm::Attribute::ByVal); + func->addAttribute(4, llvm::Attribute::ReadOnly); + func->addAttribute(4, llvm::Attribute::NoAlias); + func->addAttribute(4, llvm::Attribute::NoCapture); + if (!onWindows) + func->addAttribute(5, llvm::Attribute::ByVal); + func->addAttribute(5, llvm::Attribute::ReadOnly); + func->addAttribute(5, llvm::Attribute::NoAlias); + func->addAttribute(5, llvm::Attribute::NoCapture); + func->addAttribute(6, llvm::Attribute::ReadOnly); + func->addAttribute(6, llvm::Attribute::NoCapture); + func->addAttribute(8, llvm::Attribute::NoCapture); + + auto iter = func->arg_begin(); + auto& env = *iter; + std::advance(iter, 1); + auto& callKind = *iter; + std::advance(iter, 1); + auto& gas = *iter; + std::advance(iter, 2); + auto& valuePtr = *iter; + + auto& ctx = _module->getContext(); + llvm::IRBuilder<> builder(ctx); + auto entryBB = llvm::BasicBlock::Create(ctx, "Entry", func); + auto checkTransferBB = llvm::BasicBlock::Create(ctx, "CheckTransfer", func); + auto checkBalanceBB = llvm::BasicBlock::Create(ctx, "CheckBalance", func); + auto callBB = llvm::BasicBlock::Create(ctx, "Call", func); + auto failBB = llvm::BasicBlock::Create(ctx, "Fail", func); + + builder.SetInsertPoint(entryBB); + auto v = builder.CreateAlloca(Type::Word); + auto addr = builder.CreateAlloca(Type::Word); + auto queryFn = getQueryFunc(_module); + auto undef = llvm::UndefValue::get(Type::WordPtr); + builder.CreateCall(queryFn, {v, &env, builder.getInt32(EVM_CALL_DEPTH), undef}); + auto depthPtr = builder.CreateBitCast(v, builder.getInt64Ty()->getPointerTo()); + auto depth = builder.CreateLoad(depthPtr); + auto depthOk = builder.CreateICmpSLT(depth, builder.getInt64(1024)); + builder.CreateCondBr(depthOk, checkTransferBB, failBB); + + builder.SetInsertPoint(checkTransferBB); + auto notDelegateCall = builder.CreateICmpNE(&callKind, builder.getInt32(EVM_DELEGATECALL)); + llvm::Value* value = builder.CreateLoad(&valuePtr); + auto valueNonZero = builder.CreateICmpNE(value, Constant::get(0)); + auto transfer = builder.CreateAnd(notDelegateCall, valueNonZero); + builder.CreateCondBr(transfer, checkBalanceBB, callBB); + + builder.SetInsertPoint(checkBalanceBB); + builder.CreateCall(queryFn, {addr, &env, builder.getInt32(EVM_ADDRESS), undef}); + builder.CreateCall(queryFn, {v, &env, builder.getInt32(EVM_BALANCE), addr}); + llvm::Value* balance = builder.CreateLoad(v); + balance = Endianness::toNative(builder, balance); + value = Endianness::toNative(builder, value); + auto balanceOk = builder.CreateICmpUGE(balance, value); + builder.CreateCondBr(balanceOk, callBB, failBB); + + builder.SetInsertPoint(callBB); + llvm::Value* args[9]; + auto outIt = std::begin(args); + for (auto it = func->arg_begin(); it != func->arg_end(); ++it, ++outIt) + *outIt = &*it; + auto ret = builder.CreateCall(callFunc, args); + builder.CreateRet(ret); + + builder.SetInsertPoint(failBB); + auto failRet = builder.CreateOr(&gas, builder.getInt64(EVM_CALL_FAILURE)); + builder.CreateRet(failRet); + } + return func; +} + +} + + + +llvm::Value* Ext::getArgAlloca() +{ + auto& a = m_argAllocas[m_argCounter]; + if (!a) + { + InsertPointGuard g{m_builder}; + auto allocaIt = getMainFunction()->front().begin(); + auto allocaPtr = &(*allocaIt); + std::advance(allocaIt, m_argCounter); // Skip already created allocas + m_builder.SetInsertPoint(allocaPtr); + a = m_builder.CreateAlloca(Type::Word, nullptr, {"a.", std::to_string(m_argCounter)}); + } + ++m_argCounter; + return a; +} + +llvm::Value* Ext::byPtr(llvm::Value* _value) +{ + auto a = getArgAlloca(); + m_builder.CreateStore(_value, a); + return a; +} + +llvm::CallInst* Ext::createCall(EnvFunc _funcId, std::initializer_list const& _args) +{ + auto& func = m_funcs[static_cast(_funcId)]; + if (!func) + func = createFunc(_funcId, getModule()); + + m_argCounter = 0; + return m_builder.CreateCall(func, {_args.begin(), _args.size()}); +} + +llvm::Value* Ext::createCABICall(llvm::Function* _func, std::initializer_list const& _args, bool _derefOutput) +{ + auto args = llvm::SmallVector{_args}; + + auto hasSRet = _func->hasStructRetAttr(); + if (hasSRet) // Prepare memory for return struct. + args.insert(args.begin(), getArgAlloca()); + + for (auto&& farg: _func->args()) + { + if (farg.hasByValAttr()) + { + auto& arg = args[farg.getArgNo()]; + // TODO: Remove defensive check and always use it this way. + if (!arg->getType()->isPointerTy()) + { + auto mem = getArgAlloca(); + // TODO: The bitcast may be redundant + mem = m_builder.CreateBitCast(mem, arg->getType()->getPointerTo()); + m_builder.CreateStore(arg, mem); + arg = mem; + } + } + } + + m_argCounter = 0; + llvm::Value* callRet = m_builder.CreateCall(_func, args); + if (hasSRet) + return _derefOutput ? m_builder.CreateLoad(args[0]) : args[0]; + else + return callRet; +} + +llvm::Value* Ext::sload(llvm::Value* _index) +{ + auto index = Endianness::toBE(m_builder, _index); + auto func = getQueryFunc(getModule()); + auto value = createCABICall(func, {getRuntimeManager().getEnvPtr(), m_builder.getInt32(EVM_SLOAD), index}); + return Endianness::toNative(m_builder, value); +} + +void Ext::sstore(llvm::Value* _index, llvm::Value* _value) +{ + auto index = Endianness::toBE(m_builder, _index); + auto value = Endianness::toBE(m_builder, _value); + auto func = getUpdateFunc(getModule()); + createCABICall(func, {getRuntimeManager().getEnvPtr(), m_builder.getInt32(EVM_SSTORE), index, value}); +} + +void Ext::selfdestruct(llvm::Value* _beneficiary) +{ + auto func = getUpdateFunc(getModule()); + auto b = Endianness::toBE(m_builder, _beneficiary); + auto undef = llvm::UndefValue::get(Type::WordPtr); + createCABICall(func, {getRuntimeManager().getEnvPtr(), m_builder.getInt32(EVM_SELFDESTRUCT), b, undef}); +} + +llvm::Value* Ext::calldataload(llvm::Value* _idx) +{ + auto ret = getArgAlloca(); + auto result = m_builder.CreateBitCast(ret, Type::BytePtr); + + auto callDataSize = getRuntimeManager().getCallDataSize(); + auto callDataSize64 = m_builder.CreateTrunc(callDataSize, Type::Size); + auto idxValid = m_builder.CreateICmpULT(_idx, callDataSize); + auto idx = m_builder.CreateTrunc(m_builder.CreateSelect(idxValid, _idx, callDataSize), Type::Size, "idx"); + + auto end = m_builder.CreateNUWAdd(idx, m_builder.getInt64(32)); + end = m_builder.CreateSelect(m_builder.CreateICmpULE(end, callDataSize64), end, callDataSize64); + auto copySize = m_builder.CreateNUWSub(end, idx); + auto padSize = m_builder.CreateNUWSub(m_builder.getInt64(32), copySize); + auto dataBegin = m_builder.CreateGEP(Type::Byte, getRuntimeManager().getCallData(), idx); + m_builder.CreateMemCpy(result, dataBegin, copySize, 1); + auto pad = m_builder.CreateGEP(Type::Byte, result, copySize); + m_builder.CreateMemSet(pad, m_builder.getInt8(0), padSize, 1); + + m_argCounter = 0; // Release args allocas. TODO: This is a bad design + return Endianness::toNative(m_builder, m_builder.CreateLoad(ret)); +} + +llvm::Value* Ext::query(evm_query_key _key) +{ + auto func = getQueryFunc(getModule()); + auto undef = llvm::UndefValue::get(Type::WordPtr); + auto v = createCABICall(func, {getRuntimeManager().getEnvPtr(), m_builder.getInt32(_key), undef}); + + switch (_key) + { + case EVM_GAS_PRICE: + case EVM_DIFFICULTY: + v = Endianness::toNative(m_builder, v); + break; + case EVM_ADDRESS: + case EVM_CALLER: + case EVM_ORIGIN: + case EVM_COINBASE: + { + auto mask160 = llvm::APInt(160, -1, true).zext(256); + v = Endianness::toNative(m_builder, v); + v = m_builder.CreateAnd(v, mask160); + break; + } + case EVM_GAS_LIMIT: + case EVM_NUMBER: + case EVM_TIMESTAMP: + { + // Use only 64-bit -- single word. The rest is uninitialized. + // We could have mask 63 bits, but there is very little to gain in cost + // of additional and operation. + auto mask64 = llvm::APInt(256, std::numeric_limits::max()); + v = m_builder.CreateAnd(v, mask64); + break; + } + default: + break; + } + + return v; +} + +llvm::Value* Ext::balance(llvm::Value* _address) +{ + auto func = getQueryFunc(getModule()); + auto address = Endianness::toBE(m_builder, _address); + auto v = createCABICall(func, {getRuntimeManager().getEnvPtr(), m_builder.getInt32(EVM_BALANCE), address}); + return Endianness::toNative(m_builder, v); +} + +llvm::Value* Ext::exists(llvm::Value* _address) +{ + auto func = getQueryFunc(getModule()); + auto address = Endianness::toBE(m_builder, _address); + auto v = createCABICall(func, {getRuntimeManager().getEnvPtr(), m_builder.getInt32(EVM_ACCOUNT_EXISTS), address}); + return m_builder.CreateTrunc(v, m_builder.getInt1Ty()); +} + +llvm::Value* Ext::blockHash(llvm::Value* _number) +{ + auto func = getQueryFunc(getModule()); + // TODO: We can explicitly trunc the number to i64. The optimizer will know + // that we care only about these 64 bit, not all 256. + auto hash = createCABICall(func, {getRuntimeManager().getEnvPtr(), m_builder.getInt32(EVM_BLOCKHASH), _number}); + return Endianness::toNative(m_builder, hash); +} + +llvm::Value* Ext::sha3(llvm::Value* _inOff, llvm::Value* _inSize) +{ + auto begin = m_memoryMan.getBytePtr(_inOff); + auto size = m_builder.CreateTrunc(_inSize, Type::Size, "size"); + auto ret = getArgAlloca(); + createCall(EnvFunc::sha3, {begin, size, ret}); + llvm::Value* hash = m_builder.CreateLoad(ret); + return Endianness::toNative(m_builder, hash); +} + +MemoryRef Ext::extcode(llvm::Value* _addr) +{ + auto func = getQueryFunc(getModule()); + // TODO: We care only about 20 bytes here. Can we do it better? + auto address = Endianness::toBE(m_builder, _addr); + auto vPtr = createCABICall(func, {getRuntimeManager().getEnvPtr(), m_builder.getInt32(EVM_CODE_BY_ADDRESS), address}, false); + auto memRefTy = getMemRefTy(getModule()); + auto memRefPtr = m_builder.CreateBitCast(vPtr, memRefTy->getPointerTo()); + auto memRef = m_builder.CreateLoad(memRefTy, memRefPtr, "memref"); + auto code = m_builder.CreateExtractValue(memRef, 0, "code"); + auto size = m_builder.CreateExtractValue(memRef, 1, "codesize"); + auto size256 = m_builder.CreateZExt(size, Type::Word); + return {code, size256}; +} + +llvm::Value* Ext::extcodesize(llvm::Value* _addr) +{ + auto func = getQueryFunc(getModule()); + // TODO: We care only about 20 bytes here. Can we do it better? + auto address = Endianness::toBE(m_builder, _addr); + auto vPtr = createCABICall(func, {getRuntimeManager().getEnvPtr(), m_builder.getInt32(EVM_CODE_SIZE), address}, false); + auto int64ty = m_builder.getInt64Ty(); + auto sizePtr = m_builder.CreateBitCast(vPtr, int64ty->getPointerTo()); + auto size = m_builder.CreateLoad(int64ty, sizePtr, "codesize"); + return m_builder.CreateZExt(size, Type::Word); +} + +void Ext::log(llvm::Value* _memIdx, llvm::Value* _numBytes, llvm::ArrayRef _topics) +{ + if (!m_topics) + { + InsertPointGuard g{m_builder}; + auto& entryBB = getMainFunction()->front(); + m_builder.SetInsertPoint(&entryBB, entryBB.begin()); + m_topics = m_builder.CreateAlloca(Type::Word, m_builder.getInt32(4), "topics"); + } + + auto begin = m_memoryMan.getBytePtr(_memIdx); + auto size = m_builder.CreateTrunc(_numBytes, Type::Size, "size"); + + for (size_t i = 0; i < _topics.size(); ++i) + { + auto t = Endianness::toBE(m_builder, _topics[i]); + auto p = m_builder.CreateConstGEP1_32(m_topics, static_cast(i)); + m_builder.CreateStore(t, p); + } + + auto func = getUpdateFunc(getModule()); + auto a = getArgAlloca(); + auto memRefTy = getMemRefTy(getModule()); + auto pMemRef = m_builder.CreateBitCast(a, memRefTy->getPointerTo()); + auto pData = m_builder.CreateConstGEP2_32(memRefTy, pMemRef, 0, 0, "log.data"); + m_builder.CreateStore(begin, pData); + auto pSize = m_builder.CreateConstGEP2_32(memRefTy, pMemRef, 0, 1, "log.size"); + m_builder.CreateStore(size, pSize); + + auto b = getArgAlloca(); + pMemRef = m_builder.CreateBitCast(b, memRefTy->getPointerTo()); + pData = m_builder.CreateConstGEP2_32(memRefTy, pMemRef, 0, 0, "topics.data"); + m_builder.CreateStore(m_builder.CreateBitCast(m_topics, m_builder.getInt8PtrTy()), pData); + pSize = m_builder.CreateConstGEP2_32(memRefTy, pMemRef, 0, 1, "topics.size"); + m_builder.CreateStore(m_builder.getInt64(_topics.size() * 32), pSize); + + createCABICall(func, {getRuntimeManager().getEnvPtr(), m_builder.getInt32(EVM_LOG), a, b}); +} + +llvm::Value* Ext::call(evm_call_kind _kind, + llvm::Value* _gas, + llvm::Value* _addr, + llvm::Value* _value, + llvm::Value* _inOff, + llvm::Value* _inSize, + llvm::Value* _outOff, + llvm::Value* _outSize) +{ + auto gas = m_builder.CreateTrunc(_gas, Type::Size); + auto addr = m_builder.CreateTrunc(_addr, m_builder.getIntNTy(160)); + addr = Endianness::toBE(m_builder, addr); + auto inData = m_memoryMan.getBytePtr(_inOff); + auto inSize = m_builder.CreateTrunc(_inSize, Type::Size); + auto outData = m_memoryMan.getBytePtr(_outOff); + auto outSize = m_builder.CreateTrunc(_outSize, Type::Size); + + auto value = getArgAlloca(); + m_builder.CreateStore(Endianness::toBE(m_builder, _value), value); + + auto func = getCallFunc(getModule()); + return createCABICall( + func, {getRuntimeManager().getEnvPtr(), m_builder.getInt32(_kind), gas, + addr, value, inData, inSize, outData, outSize}); +} + +std::tuple Ext::create(llvm::Value* _gas, + llvm::Value* _endowment, + llvm::Value* _initOff, + llvm::Value* _initSize) +{ + auto addrTy = m_builder.getIntNTy(160); + auto value = getArgAlloca(); + m_builder.CreateStore(Endianness::toBE(m_builder, _endowment), value); + auto inData = m_memoryMan.getBytePtr(_initOff); + auto inSize = m_builder.CreateTrunc(_initSize, Type::Size); + auto pAddr = + m_builder.CreateBitCast(getArgAlloca(), m_builder.getInt8PtrTy()); + + auto func = getCallFunc(getModule()); + auto ret = createCABICall( + func, {getRuntimeManager().getEnvPtr(), m_builder.getInt32(EVM_CREATE), + _gas, llvm::UndefValue::get(addrTy), value, inData, inSize, pAddr, + m_builder.getInt64(20)}); + + pAddr = m_builder.CreateBitCast(pAddr, addrTy->getPointerTo()); + return std::tuple{ret, pAddr}; +} +} +} +} diff --git a/evmjit/libevmjit/Ext.h b/evmjit/libevmjit/Ext.h new file mode 100644 index 0000000000..4b1d09ea2b --- /dev/null +++ b/evmjit/libevmjit/Ext.h @@ -0,0 +1,100 @@ +#pragma once + +#include + +#include "JIT.h" +#include "CompilerHelper.h" + +namespace dev +{ +namespace eth +{ +namespace jit +{ + class Memory; + +struct MemoryRef +{ + llvm::Value* ptr; + llvm::Value* size; +}; + +template +struct sizeOf +{ + static const size_t value = static_cast(_EnumT::_size); +}; + +enum class EnvFunc +{ + sload, + sstore, + sha3, + balance, + create, + call, + log, + blockhash, + extcode, + + _size +}; + +class Ext : public RuntimeHelper +{ +public: + Ext(RuntimeManager& _runtimeManager, Memory& _memoryMan); + + llvm::Value* sload(llvm::Value* _index); + void sstore(llvm::Value* _index, llvm::Value* _value); + + llvm::Value* query(evm_query_key _key); + llvm::Value* balance(llvm::Value* _address); + llvm::Value* exists(llvm::Value* _address); + llvm::Value* calldataload(llvm::Value* _index); + std::tuple create(llvm::Value* _gas, llvm::Value* _endowment, llvm::Value* _initOff, llvm::Value* _initSize); + llvm::Value* blockHash(llvm::Value* _number); + + llvm::Value* sha3(llvm::Value* _inOff, llvm::Value* _inSize); + MemoryRef extcode(llvm::Value* _addr); + llvm::Value* extcodesize(llvm::Value* _addr); + + void log(llvm::Value* _memIdx, llvm::Value* _numBytes, llvm::ArrayRef _topics); + void selfdestruct(llvm::Value* _beneficiary); + + llvm::Value* call(evm_call_kind _kind, + llvm::Value* _gas, + llvm::Value* _addr, + llvm::Value* _value, + llvm::Value* _inOff, + llvm::Value* _inSize, + llvm::Value* _outOff, + llvm::Value* _outSize); + +private: + Memory& m_memoryMan; + + llvm::Value* m_size; + + std::array::value> m_funcs; + std::array m_argAllocas; + size_t m_argCounter = 0; + + /// Memory for array of up to 4 log topics + /// TODO: Merge this memory with args allocas. + llvm::Value* m_topics = nullptr; + + llvm::CallInst* createCall(EnvFunc _funcId, std::initializer_list const& _args); + llvm::Value* getArgAlloca(); + llvm::Value* byPtr(llvm::Value* _value); + + llvm::Value* createCABICall(llvm::Function* _func, + std::initializer_list const& _args, + bool _derefOutput = true); +}; + + +} +} +} + diff --git a/evmjit/libevmjit/GasMeter.cpp b/evmjit/libevmjit/GasMeter.cpp new file mode 100644 index 0000000000..cbf587d71e --- /dev/null +++ b/evmjit/libevmjit/GasMeter.cpp @@ -0,0 +1,289 @@ +#include "GasMeter.h" + +#include "preprocessor/llvm_includes_start.h" +#include +#include "preprocessor/llvm_includes_end.h" + +#include "JIT.h" +#include "Ext.h" +#include "RuntimeManager.h" + +namespace dev +{ +namespace eth +{ +namespace jit +{ + +GasMeter::GasMeter(IRBuilder& _builder, RuntimeManager& _runtimeManager, evm_mode mode): + CompilerHelper(_builder), + m_runtimeManager(_runtimeManager), + m_mode(mode) +{ + llvm::Type* gasCheckArgs[] = {Type::Gas->getPointerTo(), Type::Gas, Type::BytePtr}; + m_gasCheckFunc = llvm::Function::Create(llvm::FunctionType::get(Type::Void, gasCheckArgs, false), llvm::Function::PrivateLinkage, "gas.check", getModule()); + m_gasCheckFunc->setDoesNotThrow(); + m_gasCheckFunc->setDoesNotCapture(1); + + auto checkBB = llvm::BasicBlock::Create(_builder.getContext(), "Check", m_gasCheckFunc); + auto updateBB = llvm::BasicBlock::Create(_builder.getContext(), "Update", m_gasCheckFunc); + auto outOfGasBB = llvm::BasicBlock::Create(_builder.getContext(), "OutOfGas", m_gasCheckFunc); + + auto iter = m_gasCheckFunc->arg_begin(); + llvm::Argument* gasPtr = &(*iter++); + gasPtr->setName("gasPtr"); + llvm::Argument* cost = &(*iter++); + cost->setName("cost"); + llvm::Argument* jmpBuf = &(*iter); + jmpBuf->setName("jmpBuf"); + + InsertPointGuard guard(m_builder); + m_builder.SetInsertPoint(checkBB); + auto gas = m_builder.CreateLoad(gasPtr, "gas"); + auto gasUpdated = m_builder.CreateNSWSub(gas, cost, "gasUpdated"); + auto gasOk = m_builder.CreateICmpSGE(gasUpdated, m_builder.getInt64(0), "gasOk"); // gas >= 0, with gas == 0 we can still do 0 cost instructions + m_builder.CreateCondBr(gasOk, updateBB, outOfGasBB, Type::expectTrue); + + m_builder.SetInsertPoint(updateBB); + m_builder.CreateStore(gasUpdated, gasPtr); + m_builder.CreateRetVoid(); + + m_builder.SetInsertPoint(outOfGasBB); + m_runtimeManager.abort(jmpBuf); + m_builder.CreateUnreachable(); +} + +void GasMeter::count(Instruction _inst) +{ + if (!m_checkCall) + { + // Create gas check call with mocked block cost at begining of current cost-block + m_checkCall = m_builder.CreateCall(m_gasCheckFunc, {m_runtimeManager.getGasPtr(), llvm::UndefValue::get(Type::Gas), m_runtimeManager.getJmpBuf()}); + } + + m_blockCost += getStepCost(_inst); +} + +void GasMeter::count(llvm::Value* _cost, llvm::Value* _jmpBuf, llvm::Value* _gasPtr) +{ + if (_cost->getType() == Type::Word) + { + auto gasMax256 = m_builder.CreateZExt(Constant::gasMax, Type::Word); + auto tooHigh = m_builder.CreateICmpUGT(_cost, gasMax256, "costTooHigh"); + auto cost64 = m_builder.CreateTrunc(_cost, Type::Gas); + _cost = m_builder.CreateSelect(tooHigh, Constant::gasMax, cost64, "cost"); + } + + assert(_cost->getType() == Type::Gas); + m_builder.CreateCall(m_gasCheckFunc, {_gasPtr ? _gasPtr : m_runtimeManager.getGasPtr(), _cost, _jmpBuf ? _jmpBuf : m_runtimeManager.getJmpBuf()}); +} + +void GasMeter::countExp(llvm::Value* _exponent) +{ + // Additional cost is 1 per significant byte of exponent + // lz - leading zeros + // cost = ((256 - lz) + 7) / 8 + + // OPT: Can gas update be done in exp algorithm? + auto ctlz = llvm::Intrinsic::getDeclaration(getModule(), llvm::Intrinsic::ctlz, Type::Word); + auto lz256 = m_builder.CreateCall(ctlz, {_exponent, m_builder.getInt1(false)}); + auto lz = m_builder.CreateTrunc(lz256, Type::Gas, "lz"); + auto sigBits = m_builder.CreateSub(m_builder.getInt64(256), lz, "sigBits"); + auto sigBytes = m_builder.CreateUDiv(m_builder.CreateAdd(sigBits, m_builder.getInt64(7)), m_builder.getInt64(8)); + auto exponentByteCost = m_mode >= EVM_CLEARING ? 50 : JITSchedule::expByteGas::value; + count(m_builder.CreateNUWMul(sigBytes, m_builder.getInt64(exponentByteCost))); +} + +void GasMeter::countSStore(Ext& _ext, llvm::Value* _index, llvm::Value* _newValue) +{ + auto oldValue = _ext.sload(_index); + auto oldValueIsZero = m_builder.CreateICmpEQ(oldValue, Constant::get(0), "oldValueIsZero"); + auto newValueIsntZero = m_builder.CreateICmpNE(_newValue, Constant::get(0), "newValueIsntZero"); + auto isInsert = m_builder.CreateAnd(oldValueIsZero, newValueIsntZero, "isInsert"); + assert(JITSchedule::sstoreResetGas::value == JITSchedule::sstoreClearGas::value && "Update SSTORE gas cost"); + auto cost = m_builder.CreateSelect(isInsert, m_builder.getInt64(JITSchedule::sstoreSetGas::value), m_builder.getInt64(JITSchedule::sstoreResetGas::value), "cost"); + count(cost); +} + +void GasMeter::countLogData(llvm::Value* _dataLength) +{ + assert(m_checkCall); + assert(m_blockCost > 0); // LOGn instruction is already counted + assert(JITSchedule::logDataGas::value != 1 && "Log data gas cost has changed. Update GasMeter."); + count(m_builder.CreateNUWMul(_dataLength, Constant::get(JITSchedule::logDataGas::value))); // TODO: Use i64 +} + +void GasMeter::countSha3Data(llvm::Value* _dataLength) +{ + assert(m_checkCall); + assert(m_blockCost > 0); // SHA3 instruction is already counted + + // TODO: This round ups to 32 happens in many places + assert(JITSchedule::sha3WordGas::value != 1 && "SHA3 data cost has changed. Update GasMeter"); + auto dataLength64 = m_builder.CreateTrunc(_dataLength, Type::Gas); + auto words64 = m_builder.CreateUDiv(m_builder.CreateNUWAdd(dataLength64, m_builder.getInt64(31)), m_builder.getInt64(32)); + auto cost64 = m_builder.CreateNUWMul(m_builder.getInt64(JITSchedule::sha3WordGas::value), words64); + count(cost64); +} + +void GasMeter::giveBack(llvm::Value* _gas) +{ + assert(_gas->getType() == Type::Gas); + m_runtimeManager.setGas(m_builder.CreateAdd(m_runtimeManager.getGas(), _gas)); +} + +void GasMeter::commitCostBlock() +{ + // If any uncommited block + if (m_checkCall) + { + if (m_blockCost == 0) // Do not check 0 + { + m_checkCall->eraseFromParent(); // Remove the gas check call + m_checkCall = nullptr; + return; + } + + m_checkCall->setArgOperand(1, m_builder.getInt64(m_blockCost)); // Update block cost in gas check call + m_checkCall = nullptr; // End cost-block + m_blockCost = 0; + } + assert(m_blockCost == 0); +} + +void GasMeter::countMemory(llvm::Value* _additionalMemoryInWords, llvm::Value* _jmpBuf, llvm::Value* _gasPtr) +{ + assert(JITSchedule::memoryGas::value != 1 && "Memory gas cost has changed. Update GasMeter."); + count(_additionalMemoryInWords, _jmpBuf, _gasPtr); +} + +void GasMeter::countCopy(llvm::Value* _copyWords) +{ + assert(JITSchedule::copyGas::value != 1 && "Copy gas cost has changed. Update GasMeter."); + count(m_builder.CreateNUWMul(_copyWords, m_builder.getInt64(JITSchedule::copyGas::value))); +} + +int64_t GasMeter::getStepCost(Instruction inst) const +{ + switch (inst) + { + // Tier 0 + case Instruction::STOP: + case Instruction::RETURN: + case Instruction::SSTORE: // Handle cost of SSTORE separately in GasMeter::countSStore() + return JITSchedule::stepGas0::value; + + // Tier 1 + case Instruction::ADDRESS: + case Instruction::ORIGIN: + case Instruction::CALLER: + case Instruction::CALLVALUE: + case Instruction::CALLDATASIZE: + case Instruction::CODESIZE: + case Instruction::GASPRICE: + case Instruction::COINBASE: + case Instruction::TIMESTAMP: + case Instruction::NUMBER: + case Instruction::DIFFICULTY: + case Instruction::GASLIMIT: + case Instruction::POP: + case Instruction::PC: + case Instruction::MSIZE: + case Instruction::GAS: + return JITSchedule::stepGas1::value; + + // Tier 2 + case Instruction::ADD: + case Instruction::SUB: + case Instruction::LT: + case Instruction::GT: + case Instruction::SLT: + case Instruction::SGT: + case Instruction::EQ: + case Instruction::ISZERO: + case Instruction::AND: + case Instruction::OR: + case Instruction::XOR: + case Instruction::NOT: + case Instruction::BYTE: + case Instruction::CALLDATALOAD: + case Instruction::CALLDATACOPY: + case Instruction::CODECOPY: + case Instruction::MLOAD: + case Instruction::MSTORE: + case Instruction::MSTORE8: + case Instruction::ANY_PUSH: + case Instruction::ANY_DUP: + case Instruction::ANY_SWAP: + return JITSchedule::stepGas2::value; + + // Tier 3 + case Instruction::MUL: + case Instruction::DIV: + case Instruction::SDIV: + case Instruction::MOD: + case Instruction::SMOD: + case Instruction::SIGNEXTEND: + return JITSchedule::stepGas3::value; + + // Tier 4 + case Instruction::ADDMOD: + case Instruction::MULMOD: + case Instruction::JUMP: + return JITSchedule::stepGas4::value; + + // Tier 5 + case Instruction::EXP: + case Instruction::JUMPI: + return JITSchedule::stepGas5::value; + + // Tier 6 + case Instruction::BALANCE: + return m_mode >= EVM_ANTI_DOS ? 400 : JITSchedule::stepGas6::value; + + case Instruction::EXTCODESIZE: + case Instruction::EXTCODECOPY: + return m_mode >= EVM_ANTI_DOS ? 700 : JITSchedule::stepGas6::value; + + case Instruction::BLOCKHASH: + return JITSchedule::stepGas6::value; + + case Instruction::SHA3: + return JITSchedule::sha3Gas::value; + + case Instruction::SLOAD: + return m_mode >= EVM_ANTI_DOS ? 200 : JITSchedule::sloadGas::value; + + case Instruction::JUMPDEST: + return JITSchedule::jumpdestGas::value; + + case Instruction::LOG0: + case Instruction::LOG1: + case Instruction::LOG2: + case Instruction::LOG3: + case Instruction::LOG4: + { + auto numTopics = static_cast(inst) - static_cast(Instruction::LOG0); + return JITSchedule::logGas::value + numTopics * JITSchedule::logTopicGas::value; + } + + case Instruction::CALL: + case Instruction::CALLCODE: + case Instruction::DELEGATECALL: + return m_mode >= EVM_ANTI_DOS ? 700 : JITSchedule::callGas::value; + + case Instruction::CREATE: + return JITSchedule::createGas::value; + + case Instruction::SUICIDE: + return m_mode >= EVM_ANTI_DOS ? 5000 : JITSchedule::stepGas0::value; + + default: + // For invalid instruction just return 0. + return 0; + } +} + +} +} +} diff --git a/evmjit/libevmjit/GasMeter.h b/evmjit/libevmjit/GasMeter.h new file mode 100644 index 0000000000..2703c67dc4 --- /dev/null +++ b/evmjit/libevmjit/GasMeter.h @@ -0,0 +1,70 @@ +#pragma once + +#include +#include "CompilerHelper.h" +#include "Instruction.h" + +namespace dev +{ +namespace eth +{ +namespace jit +{ +class RuntimeManager; +using namespace evmjit; + +class GasMeter : public CompilerHelper // TODO: Use RuntimeHelper +{ +public: + GasMeter(IRBuilder& _builder, RuntimeManager& _runtimeManager, evm_mode mode); + + /// Count step cost of instruction + void count(Instruction _inst); + + /// Count additional cost + void count(llvm::Value* _cost, llvm::Value* _jmpBuf = nullptr, llvm::Value* _gasPtr = nullptr); + + /// Calculate & count gas cost for SSTORE instruction + void countSStore(class Ext& _ext, llvm::Value* _index, llvm::Value* _newValue); + + /// Calculate & count additional gas cost for EXP instruction + void countExp(llvm::Value* _exponent); + + /// Count gas cost of LOG data + void countLogData(llvm::Value* _dataLength); + + /// Count gas cost of SHA3 data + void countSha3Data(llvm::Value* _dataLength); + + /// Finalize cost-block by checking gas needed for the block before the block + void commitCostBlock(); + + /// Give back an amount of gas not used by a call + void giveBack(llvm::Value* _gas); + + /// Generate code that checks the cost of additional memory used by program + void countMemory(llvm::Value* _additionalMemoryInWords, llvm::Value* _jmpBuf, llvm::Value* _gasPtr); + + /// Count addional gas cost for memory copy + void countCopy(llvm::Value* _copyWords); + +private: + int64_t getStepCost(Instruction inst) const; + + /// Cumulative gas cost of a block of instructions + /// @TODO Handle overflow + int64_t m_blockCost = 0; + + llvm::CallInst* m_checkCall = nullptr; + llvm::Function* m_gasCheckFunc = nullptr; + + RuntimeManager& m_runtimeManager; + + /// EVM compatibility mode. + evm_mode m_mode; +}; + +} +} +} + diff --git a/evmjit/libevmjit/Instruction.cpp b/evmjit/libevmjit/Instruction.cpp new file mode 100644 index 0000000000..806e97aa05 --- /dev/null +++ b/evmjit/libevmjit/Instruction.cpp @@ -0,0 +1,39 @@ +#include "Instruction.h" + +#include "preprocessor/llvm_includes_start.h" +#include +#include "preprocessor/llvm_includes_end.h" + +namespace dev +{ +namespace evmjit +{ + +llvm::APInt readPushData(code_iterator& _curr, code_iterator _end) +{ + auto pushInst = *_curr; + assert(Instruction(pushInst) >= Instruction::PUSH1 && Instruction(pushInst) <= Instruction::PUSH32); + auto numBytes = pushInst - static_cast(Instruction::PUSH1) + 1; + llvm::APInt value(256, 0); + ++_curr; // Point the data + for (decltype(numBytes) i = 0; i < numBytes; ++i) + { + byte b = (_curr != _end) ? *_curr++ : 0; + value <<= 8; + value |= b; + } + --_curr; // Point the last real byte read + return value; +} + +void skipPushData(code_iterator& _curr, code_iterator _end) +{ + auto pushInst = *_curr; + assert(Instruction(pushInst) >= Instruction::PUSH1 && Instruction(pushInst) <= Instruction::PUSH32); + auto numBytes = pushInst - static_cast(Instruction::PUSH1) + 1; + --_end; + for (decltype(numBytes) i = 0; i < numBytes && _curr < _end; ++i, ++_curr) {} +} + +} +} diff --git a/evmjit/libevmjit/Instruction.h b/evmjit/libevmjit/Instruction.h new file mode 100644 index 0000000000..e97b6c4966 --- /dev/null +++ b/evmjit/libevmjit/Instruction.h @@ -0,0 +1,237 @@ +#pragma once + +#include "Common.h" + +namespace llvm +{ + class APInt; +} + +namespace dev +{ +namespace evmjit +{ + +/// Virtual machine bytecode instruction. +enum class Instruction: uint8_t +{ + STOP = 0x00, ///< halts execution + ADD, ///< addition operation + MUL, ///< mulitplication operation + SUB, ///< subtraction operation + DIV, ///< integer division operation + SDIV, ///< signed integer division operation + MOD, ///< modulo remainder operation + SMOD, ///< signed modulo remainder operation + ADDMOD, ///< unsigned modular addition + MULMOD, ///< unsigned modular multiplication + EXP, ///< exponential operation + SIGNEXTEND, ///< extend length of signed integer + + LT = 0x10, ///< less-than comparision + GT, ///< greater-than comparision + SLT, ///< signed less-than comparision + SGT, ///< signed greater-than comparision + EQ, ///< equality comparision + ISZERO, ///< simple not operator + AND, ///< bitwise AND operation + OR, ///< bitwise OR operation + XOR, ///< bitwise XOR operation + NOT, ///< bitwise NOT opertation + BYTE, ///< retrieve single byte from word + + SHA3 = 0x20, ///< compute SHA3-256 hash + + ADDRESS = 0x30, ///< get address of currently executing account + BALANCE, ///< get balance of the given account + ORIGIN, ///< get execution origination address + CALLER, ///< get caller address + CALLVALUE, ///< get deposited value by the instruction/transaction responsible for this execution + CALLDATALOAD, ///< get input data of current environment + CALLDATASIZE, ///< get size of input data in current environment + CALLDATACOPY, ///< copy input data in current environment to memory + CODESIZE, ///< get size of code running in current environment + CODECOPY, ///< copy code running in current environment to memory + GASPRICE, ///< get price of gas in current environment + EXTCODESIZE, ///< get external code size (from another contract) + EXTCODECOPY, ///< copy external code (from another contract) + + BLOCKHASH = 0x40, ///< get hash of most recent complete block + COINBASE, ///< get the block's coinbase address + TIMESTAMP, ///< get the block's timestamp + NUMBER, ///< get the block's number + DIFFICULTY, ///< get the block's difficulty + GASLIMIT, ///< get the block's gas limit + + POP = 0x50, ///< remove item from stack + MLOAD, ///< load word from memory + MSTORE, ///< save word to memory + MSTORE8, ///< save byte to memory + SLOAD, ///< load word from storage + SSTORE, ///< save word to storage + JUMP, ///< alter the program counter + JUMPI, ///< conditionally alter the program counter + PC, ///< get the program counter + MSIZE, ///< get the size of active memory + GAS, ///< get the amount of available gas + JUMPDEST, ///< set a potential jump destination + + PUSH1 = 0x60, ///< place 1 byte item on stack + PUSH2, ///< place 2 byte item on stack + PUSH3, ///< place 3 byte item on stack + PUSH4, ///< place 4 byte item on stack + PUSH5, ///< place 5 byte item on stack + PUSH6, ///< place 6 byte item on stack + PUSH7, ///< place 7 byte item on stack + PUSH8, ///< place 8 byte item on stack + PUSH9, ///< place 9 byte item on stack + PUSH10, ///< place 10 byte item on stack + PUSH11, ///< place 11 byte item on stack + PUSH12, ///< place 12 byte item on stack + PUSH13, ///< place 13 byte item on stack + PUSH14, ///< place 14 byte item on stack + PUSH15, ///< place 15 byte item on stack + PUSH16, ///< place 16 byte item on stack + PUSH17, ///< place 17 byte item on stack + PUSH18, ///< place 18 byte item on stack + PUSH19, ///< place 19 byte item on stack + PUSH20, ///< place 20 byte item on stack + PUSH21, ///< place 21 byte item on stack + PUSH22, ///< place 22 byte item on stack + PUSH23, ///< place 23 byte item on stack + PUSH24, ///< place 24 byte item on stack + PUSH25, ///< place 25 byte item on stack + PUSH26, ///< place 26 byte item on stack + PUSH27, ///< place 27 byte item on stack + PUSH28, ///< place 28 byte item on stack + PUSH29, ///< place 29 byte item on stack + PUSH30, ///< place 30 byte item on stack + PUSH31, ///< place 31 byte item on stack + PUSH32, ///< place 32 byte item on stack + + DUP1 = 0x80, ///< copies the highest item in the stack to the top of the stack + DUP2, ///< copies the second highest item in the stack to the top of the stack + DUP3, ///< copies the third highest item in the stack to the top of the stack + DUP4, ///< copies the 4th highest item in the stack to the top of the stack + DUP5, ///< copies the 5th highest item in the stack to the top of the stack + DUP6, ///< copies the 6th highest item in the stack to the top of the stack + DUP7, ///< copies the 7th highest item in the stack to the top of the stack + DUP8, ///< copies the 8th highest item in the stack to the top of the stack + DUP9, ///< copies the 9th highest item in the stack to the top of the stack + DUP10, ///< copies the 10th highest item in the stack to the top of the stack + DUP11, ///< copies the 11th highest item in the stack to the top of the stack + DUP12, ///< copies the 12th highest item in the stack to the top of the stack + DUP13, ///< copies the 13th highest item in the stack to the top of the stack + DUP14, ///< copies the 14th highest item in the stack to the top of the stack + DUP15, ///< copies the 15th highest item in the stack to the top of the stack + DUP16, ///< copies the 16th highest item in the stack to the top of the stack + + SWAP1 = 0x90, ///< swaps the highest and second highest value on the stack + SWAP2, ///< swaps the highest and third highest value on the stack + SWAP3, ///< swaps the highest and 4th highest value on the stack + SWAP4, ///< swaps the highest and 5th highest value on the stack + SWAP5, ///< swaps the highest and 6th highest value on the stack + SWAP6, ///< swaps the highest and 7th highest value on the stack + SWAP7, ///< swaps the highest and 8th highest value on the stack + SWAP8, ///< swaps the highest and 9th highest value on the stack + SWAP9, ///< swaps the highest and 10th highest value on the stack + SWAP10, ///< swaps the highest and 11th highest value on the stack + SWAP11, ///< swaps the highest and 12th highest value on the stack + SWAP12, ///< swaps the highest and 13th highest value on the stack + SWAP13, ///< swaps the highest and 14th highest value on the stack + SWAP14, ///< swaps the highest and 15th highest value on the stack + SWAP15, ///< swaps the highest and 16th highest value on the stack + SWAP16, ///< swaps the highest and 17th highest value on the stack + + LOG0 = 0xa0, ///< Makes a log entry; no topics. + LOG1, ///< Makes a log entry; 1 topic. + LOG2, ///< Makes a log entry; 2 topics. + LOG3, ///< Makes a log entry; 3 topics. + LOG4, ///< Makes a log entry; 4 topics. + + CREATE = 0xf0, ///< create a new account with associated code + CALL, ///< message-call into an account + CALLCODE, ///< message-call with another account's code only + RETURN, ///< halt execution returning output data + DELEGATECALL, ///< like CALLCODE but keeps caller's value and sender (only from homestead on) + SUICIDE = 0xff ///< halt execution and register account for later deletion +}; + +/// Reads PUSH data from pointed fragment of bytecode and constructs number out of it +/// Reading out of bytecode means reading 0 +/// @param _curr is updated and points the last real byte read +llvm::APInt readPushData(code_iterator& _curr, code_iterator _end); + +/// Skips PUSH data in pointed fragment of bytecode. +/// @param _curr is updated and points the last real byte skipped +void skipPushData(code_iterator& _curr, code_iterator _end); + +#define ANY_PUSH PUSH1: \ + case Instruction::PUSH2: \ + case Instruction::PUSH3: \ + case Instruction::PUSH4: \ + case Instruction::PUSH5: \ + case Instruction::PUSH6: \ + case Instruction::PUSH7: \ + case Instruction::PUSH8: \ + case Instruction::PUSH9: \ + case Instruction::PUSH10: \ + case Instruction::PUSH11: \ + case Instruction::PUSH12: \ + case Instruction::PUSH13: \ + case Instruction::PUSH14: \ + case Instruction::PUSH15: \ + case Instruction::PUSH16: \ + case Instruction::PUSH17: \ + case Instruction::PUSH18: \ + case Instruction::PUSH19: \ + case Instruction::PUSH20: \ + case Instruction::PUSH21: \ + case Instruction::PUSH22: \ + case Instruction::PUSH23: \ + case Instruction::PUSH24: \ + case Instruction::PUSH25: \ + case Instruction::PUSH26: \ + case Instruction::PUSH27: \ + case Instruction::PUSH28: \ + case Instruction::PUSH29: \ + case Instruction::PUSH30: \ + case Instruction::PUSH31: \ + case Instruction::PUSH32 + +#define ANY_DUP DUP1: \ + case Instruction::DUP2: \ + case Instruction::DUP3: \ + case Instruction::DUP4: \ + case Instruction::DUP5: \ + case Instruction::DUP6: \ + case Instruction::DUP7: \ + case Instruction::DUP8: \ + case Instruction::DUP9: \ + case Instruction::DUP10: \ + case Instruction::DUP11: \ + case Instruction::DUP12: \ + case Instruction::DUP13: \ + case Instruction::DUP14: \ + case Instruction::DUP15: \ + case Instruction::DUP16 + +#define ANY_SWAP SWAP1: \ + case Instruction::SWAP2: \ + case Instruction::SWAP3: \ + case Instruction::SWAP4: \ + case Instruction::SWAP5: \ + case Instruction::SWAP6: \ + case Instruction::SWAP7: \ + case Instruction::SWAP8: \ + case Instruction::SWAP9: \ + case Instruction::SWAP10: \ + case Instruction::SWAP11: \ + case Instruction::SWAP12: \ + case Instruction::SWAP13: \ + case Instruction::SWAP14: \ + case Instruction::SWAP15: \ + case Instruction::SWAP16 + +} +} diff --git a/evmjit/libevmjit/JIT.cpp b/evmjit/libevmjit/JIT.cpp new file mode 100644 index 0000000000..8ee72c2f8c --- /dev/null +++ b/evmjit/libevmjit/JIT.cpp @@ -0,0 +1,431 @@ +#include "JIT.h" + +#include + +#include "preprocessor/llvm_includes_start.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "preprocessor/llvm_includes_end.h" + +#include "Compiler.h" +#include "Optimizer.h" +#include "Cache.h" +#include "ExecStats.h" +#include "Utils.h" +#include "BuildInfo.gen.h" + + +static_assert(sizeof(evm_uint256be) == 32, "evm_uint256be is too big"); +static_assert(sizeof(evm_uint160be) == 20, "evm_uint160be is too big"); +static_assert(sizeof(evm_result) <= 64, "evm_result does not fit cache line"); + +// Check enums match int size. +// On GCC/clang the underlying type should be unsigned int, on MSVC int +static_assert(sizeof(evm_query_key) == sizeof(int), "Enum `evm_query_key` is not the size of int"); +static_assert(sizeof(evm_update_key) == sizeof(int), "Enum `evm_update_key` is not the size of int"); +static_assert(sizeof(evm_call_kind) == sizeof(int), "Enum `evm_call_kind` is not the size of int"); +static_assert(sizeof(evm_mode) == sizeof(int), "Enum `evm_mode` is not the size of int"); + + +namespace dev +{ +namespace evmjit +{ +using namespace eth::jit; + +namespace +{ +using ExecFunc = ReturnCode(*)(ExecutionContext*); + +char modeToChar(evm_mode mode) +{ + switch (mode) + { + case EVM_FRONTIER: return 'F'; + case EVM_HOMESTEAD: return 'H'; + case EVM_ANTI_DOS: return 'A'; + case EVM_CLEARING: return 'C'; + } + LLVM_BUILTIN_UNREACHABLE; +} + +/// Combine code hash and compatibility mode into a printable code identifier. +std::string makeCodeId(evm_uint256be codeHash, evm_mode mode) +{ + static const auto hexChars = "0123456789abcdef"; + std::string str; + str.reserve(sizeof(codeHash) * 2 + 1); + for (auto b: codeHash.bytes) + { + str.push_back(hexChars[b & 0xf]); + str.push_back(hexChars[b >> 4]); + } + str.push_back(modeToChar(mode)); + return str; +} + +void printVersion() +{ + std::cout << "Ethereum EVM JIT Compiler (http://github.com/ethereum/evmjit):\n" + << " EVMJIT version " << EVMJIT_VERSION << "\n" +#ifdef NDEBUG + << " Optimized build, " +#else + << " DEBUG build, " +#endif + << __DATE__ << " (" << __TIME__ << ")\n" + << std::endl; +} + +namespace cl = llvm::cl; +cl::opt g_optimize{"O", cl::desc{"Optimize"}}; +cl::opt g_cache{"cache", cl::desc{"Cache compiled EVM code on disk"}, + cl::values( + clEnumValN(CacheMode::off, "0", "Disabled"), + clEnumValN(CacheMode::on, "1", "Enabled"), + clEnumValN(CacheMode::read, "r", "Read only. No new objects are added to cache."), + clEnumValN(CacheMode::write, "w", "Write only. No objects are loaded from cache."), + clEnumValN(CacheMode::clear, "c", "Clear the cache storage. Cache is disabled."), + clEnumValN(CacheMode::preload, "p", "Preload all cached objects."), + clEnumValEnd)}; +cl::opt g_stats{"st", cl::desc{"Statistics"}}; +cl::opt g_dump{"dump", cl::desc{"Dump LLVM IR module"}}; + +void parseOptions() +{ + static llvm::llvm_shutdown_obj shutdownObj{}; + cl::AddExtraVersionPrinter(printVersion); + cl::ParseEnvironmentOptions("evmjit", "EVMJIT", "Ethereum EVM JIT Compiler"); +} + +class JITImpl +{ + std::unique_ptr m_engine; + mutable std::mutex x_codeMap; + std::unordered_map m_codeMap; + + static llvm::LLVMContext& getLLVMContext() + { + // TODO: This probably should be thread_local, but for now that causes + // a crash when MCJIT is destroyed. + static llvm::LLVMContext llvmContext; + return llvmContext; + } + +public: + static JITImpl& instance() + { + // We need to keep this a singleton. + // so we only call changeVersion on it. + static JITImpl s_instance; + return s_instance; + } + + JITImpl(); + + llvm::ExecutionEngine& engine() { return *m_engine; } + + ExecFunc getExecFunc(std::string const& _codeIdentifier) const; + void mapExecFunc(std::string const& _codeIdentifier, ExecFunc _funcAddr); + + ExecFunc compile(evm_mode _mode, byte const* _code, uint64_t _codeSize, std::string const& _codeIdentifier); + + evm_query_fn queryFn = nullptr; + evm_update_fn updateFn = nullptr; + evm_call_fn callFn = nullptr; +}; + + +class SymbolResolver : public llvm::SectionMemoryManager +{ + llvm::RuntimeDyld::SymbolInfo findSymbol(std::string const& _name) override + { + auto& jit = JITImpl::instance(); + auto addr = llvm::StringSwitch(_name) + .Case("env_sha3", reinterpret_cast(&keccak)) + .Case("evm.query", reinterpret_cast(jit.queryFn)) + .Case("evm.update", reinterpret_cast(jit.updateFn)) + .Case("evm.call", reinterpret_cast(jit.callFn)) + .Default(0); + if (addr) + return {addr, llvm::JITSymbolFlags::Exported}; + + // Fallback to default implementation that would search for the symbol + // in the current process. + // TODO: In the future we should control the whole set of requested + // symbols (like memcpy, memset, etc) to improve performance. + return llvm::SectionMemoryManager::findSymbol(_name); + } + + void reportMemorySize(size_t _addedSize) + { + if (!g_stats) + return; + + m_totalMemorySize += _addedSize; + if (m_totalMemorySize >= m_printMemoryLimit) + { + static const auto M = 1024 * 1024; + auto value = double(m_totalMemorySize) / M; + LOG(ERROR) << "EVMJIT total memory size: " << value << '\n'; + m_printMemoryLimit += M; + } + } + + uint8_t* allocateCodeSection(uintptr_t _size, unsigned _a, unsigned _id, + llvm::StringRef _name) override + { + reportMemorySize(_size); + return llvm::SectionMemoryManager::allocateCodeSection(_size, _a, _id, _name); + } + + uint8_t* allocateDataSection(uintptr_t _size, unsigned _a, unsigned _id, + llvm::StringRef _name, bool _ro) override + { + reportMemorySize(_size); + return llvm::SectionMemoryManager::allocateDataSection(_size, _a, _id, _name, _ro); + } + + size_t m_totalMemorySize = 0; + size_t m_printMemoryLimit = 1024 * 1024; +}; + + +JITImpl::JITImpl() +{ + parseOptions(); + + bool preloadCache = g_cache == CacheMode::preload; + if (preloadCache) + g_cache = CacheMode::on; + + llvm::InitializeNativeTarget(); + llvm::InitializeNativeTargetAsmPrinter(); + + auto module = llvm::make_unique("", getLLVMContext()); + + // FIXME: LLVM 3.7: test on Windows + auto triple = llvm::Triple(llvm::sys::getProcessTriple()); + if (triple.getOS() == llvm::Triple::OSType::Win32) + triple.setObjectFormat(llvm::Triple::ObjectFormatType::ELF); // MCJIT does not support COFF format + module->setTargetTriple(triple.str()); + + llvm::EngineBuilder builder(std::move(module)); + builder.setEngineKind(llvm::EngineKind::JIT); + builder.setMCJITMemoryManager(llvm::make_unique()); + builder.setOptLevel(g_optimize ? llvm::CodeGenOpt::Default : llvm::CodeGenOpt::None); + #ifndef NDEBUG + builder.setVerifyModules(true); + #endif + + m_engine.reset(builder.create()); + + // TODO: Update cache listener + m_engine->setObjectCache(Cache::init(g_cache, nullptr)); + + // FIXME: Disabled during API changes + //if (preloadCache) + // Cache::preload(*m_engine, funcCache); +} + +ExecFunc JITImpl::getExecFunc(std::string const& _codeIdentifier) const +{ + std::lock_guard lock{x_codeMap}; + auto it = m_codeMap.find(_codeIdentifier); + if (it != m_codeMap.end()) + return it->second; + return nullptr; +} + +void JITImpl::mapExecFunc(std::string const& _codeIdentifier, ExecFunc _funcAddr) +{ + std::lock_guard lock{x_codeMap}; + m_codeMap.emplace(_codeIdentifier, _funcAddr); +} + +ExecFunc JITImpl::compile(evm_mode _mode, byte const* _code, uint64_t _codeSize, + std::string const& _codeIdentifier) +{ + auto module = Cache::getObject(_codeIdentifier, getLLVMContext()); + if (!module) + { + // TODO: Listener support must be redesigned. These should be a feature of JITImpl + //listener->stateChanged(ExecState::Compilation); + assert(_code || !_codeSize); + //TODO: Can the Compiler be stateless? + module = Compiler({}, _mode, getLLVMContext()).compile(_code, _code + _codeSize, _codeIdentifier); + + if (g_optimize) + { + //listener->stateChanged(ExecState::Optimization); + optimize(*module); + } + + prepare(*module); + } + if (g_dump) + module->dump(); + + m_engine->addModule(std::move(module)); + //listener->stateChanged(ExecState::CodeGen); + return (ExecFunc)m_engine->getFunctionAddress(_codeIdentifier); +} + +} // anonymous namespace + + +ExecutionContext::~ExecutionContext() noexcept +{ + if (m_memData) + std::free(m_memData); // Use helper free to check memory leaks +} + +bytes_ref ExecutionContext::getReturnData() const +{ + auto data = m_data->callData; + auto size = static_cast(m_data->callDataSize); + + if (data < m_memData || data >= m_memData + m_memSize || size == 0) + { + assert(size == 0); // data can be an invalid pointer only if size is 0 + m_data->callData = nullptr; + return {}; + } + + return bytes_ref{data, size}; +} + + +extern "C" +{ + +static evm_instance* create(evm_query_fn queryFn, evm_update_fn updateFn, + evm_call_fn callFn) +{ + // Let's always return the same instance. It's a bit of faking, but actually + // this might be a compliant implementation. + auto& jit = JITImpl::instance(); + jit.queryFn = queryFn; + jit.updateFn = updateFn; + jit.callFn = callFn; + return reinterpret_cast(&jit); +} + +static void destroy(evm_instance* instance) +{ + (void)instance; + assert(instance == static_cast(&JITImpl::instance())); +} + +static void release_result(evm_result const* result) +{ + if (result->internal_memory) + std::free(result->internal_memory); +} + +static evm_result execute(evm_instance* instance, evm_env* env, evm_mode mode, + evm_uint256be code_hash, uint8_t const* code, size_t code_size, + int64_t gas, uint8_t const* input, size_t input_size, evm_uint256be value) +{ + auto& jit = *reinterpret_cast(instance); + + RuntimeData rt; + rt.code = code; + rt.codeSize = code_size; + rt.gas = gas; + rt.callData = input; + rt.callDataSize = input_size; + std::memcpy(&rt.apparentValue, &value, sizeof(value)); + + ExecutionContext ctx{rt, env}; + + evm_result result; + result.code = EVM_SUCCESS; + result.gas_left = 0; + result.output_data = nullptr; + result.output_size = 0; + result.internal_memory = nullptr; + result.release = release_result; + + auto codeIdentifier = makeCodeId(code_hash, mode); + auto execFunc = jit.getExecFunc(codeIdentifier); + if (!execFunc) + { + execFunc = jit.compile(mode, ctx.code(), ctx.codeSize(), codeIdentifier); + if (!execFunc) + return result; + jit.mapExecFunc(codeIdentifier, execFunc); + } + + auto returnCode = execFunc(&ctx); + + if (returnCode == ReturnCode::OutOfGas) + { + // EVMJIT does not provide information what exactly type of failure + // it was, so use generic EVM_FAILURE. + result.code = EVM_FAILURE; + } + else + { + // In case of success return the amount of gas left. + result.gas_left = rt.gas; + } + + if (returnCode == ReturnCode::Return) + { + auto out = ctx.getReturnData(); + result.output_data = std::get<0>(out); + result.output_size = std::get<1>(out); + } + + // Take care of the internal memory. + result.internal_memory = ctx.m_memData; + ctx.m_memData = nullptr; + + return result; +} + +static int set_option(evm_instance* instance, char const* name, + char const* value) +{ + (void)instance, (void)name, (void)value; + return 0; +} + +static evm_code_status get_code_status(evm_instance* instance, + evm_mode mode, evm_uint256be code_hash) +{ + auto& jit = *reinterpret_cast(instance); + auto codeIdentifier = makeCodeId(code_hash, mode); + if (jit.getExecFunc(codeIdentifier) != nullptr) + return EVM_READY; + // TODO: Add support for EVM_CACHED. + return EVM_UNKNOWN; +} + +static void prepare_code(evm_instance* instance, evm_mode mode, + evm_uint256be code_hash, unsigned char const* code, size_t code_size) +{ + auto& jit = *reinterpret_cast(instance); + auto codeIdentifier = makeCodeId(code_hash, mode); + auto execFunc = jit.compile(mode, code, code_size, codeIdentifier); + if (execFunc) // FIXME: What with error? + jit.mapExecFunc(codeIdentifier, execFunc); +} + +EXPORT evm_interface evmjit_get_interface() +{ + return {EVM_ABI_VERSION, create, destroy, execute, + get_code_status, prepare_code, set_option}; +} + +} // extern "C" +} +} diff --git a/evmjit/libevmjit/JIT.h b/evmjit/libevmjit/JIT.h new file mode 100644 index 0000000000..9e69398221 --- /dev/null +++ b/evmjit/libevmjit/JIT.h @@ -0,0 +1,130 @@ +#pragma once + +#include +#include +#include +#include + +#include + +namespace dev +{ +namespace evmjit +{ + +using byte = uint8_t; +using bytes_ref = std::tuple; + +/// Representation of 256-bit value binary compatible with LLVM i256 +struct i256 +{ + uint64_t words[4]; + + i256() = default; +}; + +// TODO: Merge with ExecutionContext +struct RuntimeData +{ + enum Index + { + Gas, + GasPrice, + CallData, + CallDataSize, + ApparentCallValue, // value of msg.value - different during DELEGATECALL + Code, + CodeSize, + + ReturnData = CallData, ///< Return data pointer (set only in case of RETURN) + ReturnDataSize = CallDataSize, ///< Return data size (set only in case of RETURN) + }; + + static size_t const numElements = CodeSize + 1; + + int64_t gas = 0; + int64_t gasPrice = 0; + byte const* callData = nullptr; + uint64_t callDataSize = 0; + i256 apparentValue; + byte const* code = nullptr; + uint64_t codeSize = 0; +}; + +struct JITSchedule +{ + // TODO: Move to constexpr once all our target compilers support it. + typedef std::integral_constant stackLimit; + typedef std::integral_constant stepGas0; + typedef std::integral_constant stepGas1; + typedef std::integral_constant stepGas2; + typedef std::integral_constant stepGas3; + typedef std::integral_constant stepGas4; + typedef std::integral_constant stepGas5; + typedef std::integral_constant stepGas6; + typedef std::integral_constant stepGas7; + typedef std::integral_constant expByteGas; + typedef std::integral_constant sha3Gas; + typedef std::integral_constant sha3WordGas; + typedef std::integral_constant sloadGas; + typedef std::integral_constant sstoreSetGas; + typedef std::integral_constant sstoreResetGas; + typedef std::integral_constant sstoreClearGas; + typedef std::integral_constant jumpdestGas; + typedef std::integral_constant logGas; + typedef std::integral_constant logDataGas; + typedef std::integral_constant logTopicGas; + typedef std::integral_constant createGas; + typedef std::integral_constant callGas; + typedef std::integral_constant memoryGas; + typedef std::integral_constant copyGas; + typedef std::integral_constant valueTransferGas; + typedef std::integral_constant callStipend; + typedef std::integral_constant callNewAccount; +}; + +enum class ReturnCode +{ + // Success codes + Stop = 0, + Return = 1, + + // Standard error codes + OutOfGas = -1, + + // Internal error codes + LLVMError = -101, + + UnexpectedException = -111, +}; + +class ExecutionContext +{ +public: + ExecutionContext() = default; + ExecutionContext(RuntimeData& _data, evm_env* _env) { init(_data, _env); } + ExecutionContext(ExecutionContext const&) = delete; + ExecutionContext& operator=(ExecutionContext const&) = delete; + ~ExecutionContext() noexcept; + + void init(RuntimeData& _data, evm_env* _env) { m_data = &_data; m_env = _env; } + + byte const* code() const { return m_data->code; } + uint64_t codeSize() const { return m_data->codeSize; } + + bytes_ref getReturnData() const; + +public: + RuntimeData* m_data = nullptr; ///< Pointer to data. Expected by compiled contract. + evm_env* m_env = nullptr; ///< Pointer to environment proxy. Expected by compiled contract. + byte* m_memData = nullptr; + uint64_t m_memSize = 0; + uint64_t m_memCap = 0; + +public: + /// Reference to returned data (RETURN opcode used) + bytes_ref returnData; +}; + +} +} diff --git a/evmjit/libevmjit/Memory.cpp b/evmjit/libevmjit/Memory.cpp new file mode 100644 index 0000000000..bae208b721 --- /dev/null +++ b/evmjit/libevmjit/Memory.cpp @@ -0,0 +1,249 @@ +#include "Memory.h" + +#include "preprocessor/llvm_includes_start.h" +#include +#include "preprocessor/llvm_includes_end.h" + +#include "Type.h" +#include "GasMeter.h" +#include "Endianness.h" +#include "RuntimeManager.h" + +namespace dev +{ +namespace eth +{ +namespace jit +{ + +Memory::Memory(RuntimeManager& _runtimeManager, GasMeter& _gasMeter): + RuntimeHelper(_runtimeManager), // TODO: RuntimeHelper not needed + m_memory{m_builder, _runtimeManager.getMem()}, + m_gasMeter(_gasMeter) +{} + +llvm::Function* Memory::getRequireFunc() +{ + auto& func = m_require; + if (!func) + { + llvm::Type* argTypes[] = {Array::getType()->getPointerTo(), Type::Word, Type::Word, Type::BytePtr, Type::GasPtr}; + func = llvm::Function::Create(llvm::FunctionType::get(Type::Void, argTypes, false), llvm::Function::PrivateLinkage, "mem.require", getModule()); + func->setDoesNotThrow(); + + auto iter = func->arg_begin(); + llvm::Argument* mem = &(*iter++); + mem->setName("mem"); + llvm::Argument* blkOffset = &(*iter++); + blkOffset->setName("blkOffset"); + llvm::Argument* blkSize = &(*iter++); + blkSize->setName("blkSize"); + llvm::Argument* jmpBuf = &(*iter++); + jmpBuf->setName("jmpBuf"); + llvm::Argument* gas = &(*iter); + gas->setName("gas"); + + auto preBB = llvm::BasicBlock::Create(func->getContext(), "Pre", func); + auto checkBB = llvm::BasicBlock::Create(func->getContext(), "Check", func); + auto resizeBB = llvm::BasicBlock::Create(func->getContext(), "Resize", func); + auto returnBB = llvm::BasicBlock::Create(func->getContext(), "Return", func); + + InsertPointGuard guard(m_builder); // Restores insert point at function exit + + // BB "Pre": Ignore checks with size 0 + m_builder.SetInsertPoint(preBB); + m_builder.CreateCondBr(m_builder.CreateICmpNE(blkSize, Constant::get(0)), checkBB, returnBB, Type::expectTrue); + + // BB "Check" + m_builder.SetInsertPoint(checkBB); + static const auto c_inputMax = uint64_t(1) << 33; // max value of blkSize and blkOffset that will not result in integer overflow in calculations below + auto blkOffsetOk = m_builder.CreateICmpULE(blkOffset, Constant::get(c_inputMax), "blkOffsetOk"); + auto blkO = m_builder.CreateSelect(blkOffsetOk, m_builder.CreateTrunc(blkOffset, Type::Size), m_builder.getInt64(c_inputMax), "bklO"); + auto blkSizeOk = m_builder.CreateICmpULE(blkSize, Constant::get(c_inputMax), "blkSizeOk"); + auto blkS = m_builder.CreateSelect(blkSizeOk, m_builder.CreateTrunc(blkSize, Type::Size), m_builder.getInt64(c_inputMax), "bklS"); + + auto sizeReq0 = m_builder.CreateNUWAdd(blkO, blkS, "sizeReq0"); + auto sizeReq = m_builder.CreateAnd(m_builder.CreateNUWAdd(sizeReq0, m_builder.getInt64(31)), uint64_t(-1) << 5, "sizeReq"); // s' = ((s0 + 31) / 32) * 32 + auto sizeCur = m_memory.size(mem); + auto sizeOk = m_builder.CreateICmpULE(sizeReq, sizeCur, "sizeOk"); + + m_builder.CreateCondBr(sizeOk, returnBB, resizeBB, Type::expectTrue); + + // BB "Resize" + m_builder.SetInsertPoint(resizeBB); + // Check gas first + auto w1 = m_builder.CreateLShr(sizeReq, 5); + auto w1s = m_builder.CreateNUWMul(w1, w1); + auto c1 = m_builder.CreateAdd(m_builder.CreateNUWMul(w1, m_builder.getInt64(3)), m_builder.CreateLShr(w1s, 9)); + auto w0 = m_builder.CreateLShr(sizeCur, 5); + auto w0s = m_builder.CreateNUWMul(w0, w0); + auto c0 = m_builder.CreateAdd(m_builder.CreateNUWMul(w0, m_builder.getInt64(3)), m_builder.CreateLShr(w0s, 9)); + auto cc = m_builder.CreateNUWSub(c1, c0); + auto costOk = m_builder.CreateAnd(blkOffsetOk, blkSizeOk, "costOk"); + auto c = m_builder.CreateSelect(costOk, cc, m_builder.getInt64(std::numeric_limits::max()), "c"); + m_gasMeter.count(c, jmpBuf, gas); + // Resize + m_memory.extend(mem, sizeReq); + m_builder.CreateBr(returnBB); + + // BB "Return" + m_builder.SetInsertPoint(returnBB); + m_builder.CreateRetVoid(); + } + return func; +} + +llvm::Function* Memory::createFunc(bool _isStore, llvm::Type* _valueType) +{ + auto isWord = _valueType == Type::Word; + + llvm::Type* storeArgs[] = {Array::getType()->getPointerTo(), Type::Word, _valueType}; + llvm::Type* loadArgs[] = {Array::getType()->getPointerTo(), Type::Word}; + auto name = _isStore ? isWord ? "mstore" : "mstore8" : "mload"; + auto funcType = _isStore ? llvm::FunctionType::get(Type::Void, storeArgs, false) : llvm::FunctionType::get(Type::Word, loadArgs, false); + auto func = llvm::Function::Create(funcType, llvm::Function::PrivateLinkage, name, getModule()); + + InsertPointGuard guard(m_builder); // Restores insert point at function exit + + m_builder.SetInsertPoint(llvm::BasicBlock::Create(func->getContext(), {}, func)); + + auto iter = func->arg_begin(); + llvm::Argument* mem = &(*iter++); + mem->setName("mem"); + llvm::Argument* index = &(*iter++); + index->setName("index"); + + if (_isStore) + { + llvm::Argument* valueArg = &(*iter); + valueArg->setName("value"); + auto value = isWord ? Endianness::toBE(m_builder, valueArg) : valueArg; + auto memPtr = m_memory.getPtr(mem, m_builder.CreateTrunc(index, Type::Size)); + auto valuePtr = m_builder.CreateBitCast(memPtr, _valueType->getPointerTo(), "valuePtr"); + m_builder.CreateStore(value, valuePtr); + m_builder.CreateRetVoid(); + } + else + { + auto memPtr = m_memory.getPtr(mem, m_builder.CreateTrunc(index, Type::Size)); + llvm::Value* ret = m_builder.CreateLoad(memPtr); + ret = Endianness::toNative(m_builder, ret); + m_builder.CreateRet(ret); + } + + return func; +} + +llvm::Function* Memory::getLoadWordFunc() +{ + auto& func = m_loadWord; + if (!func) + func = createFunc(false, Type::Word); + return func; +} + +llvm::Function* Memory::getStoreWordFunc() +{ + auto& func = m_storeWord; + if (!func) + func = createFunc(true, Type::Word); + return func; +} + +llvm::Function* Memory::getStoreByteFunc() +{ + auto& func = m_storeByte; + if (!func) + func = createFunc(true, Type::Byte); + return func; +} + + +llvm::Value* Memory::loadWord(llvm::Value* _addr) +{ + require(_addr, Constant::get(Type::Word->getPrimitiveSizeInBits() / 8)); + return m_builder.CreateCall(getLoadWordFunc(), {getRuntimeManager().getMem(), _addr}); +} + +void Memory::storeWord(llvm::Value* _addr, llvm::Value* _word) +{ + require(_addr, Constant::get(Type::Word->getPrimitiveSizeInBits() / 8)); + m_builder.CreateCall(getStoreWordFunc(), {getRuntimeManager().getMem(), _addr, _word}); +} + +void Memory::storeByte(llvm::Value* _addr, llvm::Value* _word) +{ + require(_addr, Constant::get(Type::Byte->getPrimitiveSizeInBits() / 8)); + auto byte = m_builder.CreateTrunc(_word, Type::Byte, "byte"); + m_builder.CreateCall(getStoreByteFunc(), {getRuntimeManager().getMem(), _addr, byte}); +} + +llvm::Value* Memory::getData() +{ + auto memPtr = m_builder.CreateBitCast(getRuntimeManager().getMem(), Type::BytePtr->getPointerTo()); + auto data = m_builder.CreateLoad(memPtr, "data"); + assert(data->getType() == Type::BytePtr); + return data; +} + +llvm::Value* Memory::getSize() +{ + return m_builder.CreateZExt(m_memory.size(), Type::Word, "msize"); +} + +llvm::Value* Memory::getBytePtr(llvm::Value* _index) +{ + return m_builder.CreateGEP(getData(), _index, "ptr"); +} + +void Memory::require(llvm::Value* _offset, llvm::Value* _size) +{ + if (auto constant = llvm::dyn_cast(_size)) + { + if (!constant->getValue()) + return; + } + m_builder.CreateCall(getRequireFunc(), {getRuntimeManager().getMem(), _offset, _size, getRuntimeManager().getJmpBuf(), getRuntimeManager().getGasPtr()}); +} + +void Memory::copyBytes(llvm::Value* _srcPtr, llvm::Value* _srcSize, llvm::Value* _srcIdx, + llvm::Value* _destMemIdx, llvm::Value* _reqBytes) +{ + require(_destMemIdx, _reqBytes); + + // Additional copy cost + // TODO: This round ups to 32 happens in many places + auto reqBytes = m_builder.CreateTrunc(_reqBytes, Type::Gas); + auto copyWords = m_builder.CreateUDiv(m_builder.CreateNUWAdd(reqBytes, m_builder.getInt64(31)), m_builder.getInt64(32)); + m_gasMeter.countCopy(copyWords); + + // Algorithm: + // isOutsideData = idx256 >= size256 + // idx64 = trunc idx256 + // size64 = trunc size256 + // dataLeftSize = size64 - idx64 // safe if not isOutsideData + // reqBytes64 = trunc _reqBytes // require() handles large values + // bytesToCopy0 = select(reqBytes64 > dataLeftSize, dataSizeLeft, reqBytes64) // min + // bytesToCopy = select(isOutsideData, 0, bytesToCopy0) + + auto isOutsideData = m_builder.CreateICmpUGE(_srcIdx, _srcSize); + auto idx64 = m_builder.CreateTrunc(_srcIdx, Type::Size); + auto size64 = m_builder.CreateTrunc(_srcSize, Type::Size); + auto dataLeftSize = m_builder.CreateNUWSub(size64, idx64); + auto outOfBound = m_builder.CreateICmpUGT(reqBytes, dataLeftSize); + auto bytesToCopyInner = m_builder.CreateSelect(outOfBound, dataLeftSize, reqBytes); + auto bytesToCopy = m_builder.CreateSelect(isOutsideData, m_builder.getInt64(0), bytesToCopyInner, "bytesToCopy"); + auto bytesToZero = m_builder.CreateNUWSub(reqBytes, bytesToCopy, "bytesToZero"); + + auto src = m_builder.CreateGEP(_srcPtr, idx64, "src"); + auto dstIdx = m_builder.CreateTrunc(_destMemIdx, Type::Size, "dstIdx"); + auto padIdx = m_builder.CreateNUWAdd(dstIdx, bytesToCopy, "padIdx"); + auto dst = m_memory.getPtr(getRuntimeManager().getMem(), dstIdx); + auto pad = m_memory.getPtr(getRuntimeManager().getMem(), padIdx); + m_builder.CreateMemCpy(dst, src, bytesToCopy, 0); + m_builder.CreateMemSet(pad, m_builder.getInt8(0), bytesToZero, 0); +} + +} +} +} diff --git a/evmjit/libevmjit/Memory.h b/evmjit/libevmjit/Memory.h new file mode 100644 index 0000000000..bc6cf748ed --- /dev/null +++ b/evmjit/libevmjit/Memory.h @@ -0,0 +1,51 @@ +#pragma once + +#include "Array.h" + +namespace dev +{ +namespace eth +{ +namespace jit +{ +class GasMeter; + +class Memory : public RuntimeHelper +{ +public: + Memory(RuntimeManager& _runtimeManager, GasMeter& _gasMeter); + + llvm::Value* loadWord(llvm::Value* _addr); + void storeWord(llvm::Value* _addr, llvm::Value* _word); + void storeByte(llvm::Value* _addr, llvm::Value* _byte); + llvm::Value* getData(); + llvm::Value* getSize(); + llvm::Value* getBytePtr(llvm::Value* _index); + void copyBytes(llvm::Value* _srcPtr, llvm::Value* _srcSize, llvm::Value* _srcIndex, + llvm::Value* _destMemIdx, llvm::Value* _byteCount); + + /// Requires the amount of memory to for data defined by offset and size. And counts gas fee for that memory. + void require(llvm::Value* _offset, llvm::Value* _size); + +private: + Array m_memory; + + GasMeter& m_gasMeter; + + llvm::Function* createFunc(bool _isStore, llvm::Type* _type); + + llvm::Function* getRequireFunc(); + llvm::Function* getLoadWordFunc(); + llvm::Function* getStoreWordFunc(); + llvm::Function* getStoreByteFunc(); + + llvm::Function* m_require = nullptr; + llvm::Function* m_loadWord = nullptr; + llvm::Function* m_storeWord = nullptr; + llvm::Function* m_storeByte = nullptr; +}; + +} +} +} + diff --git a/evmjit/libevmjit/Optimizer.cpp b/evmjit/libevmjit/Optimizer.cpp new file mode 100644 index 0000000000..9b8f4dbd9c --- /dev/null +++ b/evmjit/libevmjit/Optimizer.cpp @@ -0,0 +1,182 @@ +#include "Optimizer.h" + +#include "preprocessor/llvm_includes_start.h" +#include +#include +#include +#include +#include +#include +#include +#include "preprocessor/llvm_includes_end.h" + +#include "Arith256.h" +#include "Type.h" + +namespace dev +{ +namespace eth +{ +namespace jit +{ + +namespace +{ + +class LongJmpEliminationPass: public llvm::FunctionPass +{ + static char ID; + +public: + LongJmpEliminationPass(): + llvm::FunctionPass(ID) + {} + + virtual bool runOnFunction(llvm::Function& _func) override; +}; + +char LongJmpEliminationPass::ID = 0; + +bool LongJmpEliminationPass::runOnFunction(llvm::Function& _func) +{ + auto iter = _func.getParent()->begin(); + if (&_func != &(*iter)) + return false; + + auto& mainFunc = _func; + auto& ctx = _func.getContext(); + auto abortCode = llvm::ConstantInt::get(llvm::Type::getInt32Ty(ctx), -1); + + auto& exitBB = mainFunc.back(); + assert(exitBB.getName() == "Exit"); + auto retPhi = llvm::cast(&exitBB.front()); + + auto modified = false; + for (auto bbIt = mainFunc.begin(); bbIt != mainFunc.end(); ++bbIt) + { + if (auto term = llvm::dyn_cast(bbIt->getTerminator())) + { + auto longjmp = term->getPrevNode(); + assert(llvm::isa(longjmp)); + auto bbPtr = &(*bbIt); + retPhi->addIncoming(abortCode, bbPtr); + llvm::ReplaceInstWithInst(term, llvm::BranchInst::Create(&exitBB)); + longjmp->eraseFromParent(); + modified = true; + } + } + + return modified; +} + +} + +bool optimize(llvm::Module& _module) +{ + auto pm = llvm::legacy::PassManager{}; + pm.add(llvm::createFunctionInliningPass(2, 2)); + pm.add(new LongJmpEliminationPass{}); // TODO: Takes a lot of time with little effect + pm.add(llvm::createCFGSimplificationPass()); + pm.add(llvm::createInstructionCombiningPass()); + pm.add(llvm::createAggressiveDCEPass()); + pm.add(llvm::createLowerSwitchPass()); + return pm.run(_module); +} + +namespace +{ + +class LowerEVMPass: public llvm::BasicBlockPass +{ + static char ID; + +public: + LowerEVMPass(): + llvm::BasicBlockPass(ID) + {} + + virtual bool runOnBasicBlock(llvm::BasicBlock& _bb) override; + + using llvm::BasicBlockPass::doFinalization; + virtual bool doFinalization(llvm::Module& _module) override; +}; + +char LowerEVMPass::ID = 0; + +bool LowerEVMPass::runOnBasicBlock(llvm::BasicBlock& _bb) +{ + auto modified = false; + auto module = _bb.getParent()->getParent(); + auto i512Ty = llvm::IntegerType::get(_bb.getContext(), 512); + for (auto it = _bb.begin(); it != _bb.end(); ++it) + { + auto& inst = *it; + llvm::Function* func = nullptr; + if (inst.getType() == Type::Word) + { + switch (inst.getOpcode()) + { + case llvm::Instruction::Mul: + func = Arith256::getMulFunc(*module); + break; + + case llvm::Instruction::UDiv: + func = Arith256::getUDiv256Func(*module); + break; + + case llvm::Instruction::URem: + func = Arith256::getURem256Func(*module); + break; + + case llvm::Instruction::SDiv: + func = Arith256::getSDiv256Func(*module); + break; + + case llvm::Instruction::SRem: + func = Arith256::getSRem256Func(*module); + break; + } + } + else if (inst.getType() == i512Ty) + { + switch (inst.getOpcode()) + { + case llvm::Instruction::Mul: + func = Arith256::getMul512Func(*module); + break; + + case llvm::Instruction::URem: + func = Arith256::getURem512Func(*module); + break; + } + } + + if (func) + { + auto call = llvm::CallInst::Create(func, {inst.getOperand(0), inst.getOperand(1)}); + llvm::ReplaceInstWithInst(_bb.getInstList(), it, call); + modified = true; + } + } + return modified; +} + +bool LowerEVMPass::doFinalization(llvm::Module&) +{ + return false; +} + +} + +bool prepare(llvm::Module& _module) +{ + auto pm = llvm::legacy::PassManager{}; + pm.add(llvm::createCFGSimplificationPass()); + pm.add(llvm::createDeadCodeEliminationPass()); + pm.add(new LowerEVMPass{}); + return pm.run(_module); +} + +} +} +} diff --git a/evmjit/libevmjit/Optimizer.h b/evmjit/libevmjit/Optimizer.h new file mode 100644 index 0000000000..e455c0361a --- /dev/null +++ b/evmjit/libevmjit/Optimizer.h @@ -0,0 +1,21 @@ +#pragma once + +namespace llvm +{ + class Module; +} + +namespace dev +{ +namespace eth +{ +namespace jit +{ + +bool optimize(llvm::Module& _module); + +bool prepare(llvm::Module& _module); + +} +} +} diff --git a/evmjit/libevmjit/RuntimeManager.cpp b/evmjit/libevmjit/RuntimeManager.cpp new file mode 100644 index 0000000000..5831925fde --- /dev/null +++ b/evmjit/libevmjit/RuntimeManager.cpp @@ -0,0 +1,238 @@ +#include "RuntimeManager.h" + +#include "preprocessor/llvm_includes_start.h" +#include +#include +#include "preprocessor/llvm_includes_end.h" + +#include "Array.h" +#include "Utils.h" + +namespace dev +{ +namespace eth +{ +namespace jit +{ + +llvm::StructType* RuntimeManager::getRuntimeDataType() +{ + static llvm::StructType* type = nullptr; + if (!type) + { + llvm::Type* elems[] = + { + Type::Size, // gas + Type::Size, // gasPrice + Type::BytePtr, // callData + Type::Size, // callDataSize + Type::Word, // apparentValue + Type::BytePtr, // code + Type::Size, // codeSize + }; + type = llvm::StructType::create(elems, "RuntimeData"); + } + return type; +} + +llvm::StructType* RuntimeManager::getRuntimeType() +{ + static llvm::StructType* type = nullptr; + if (!type) + { + llvm::Type* elems[] = + { + Type::RuntimeDataPtr, // data + Type::EnvPtr, // Env* + Array::getType() // memory + }; + type = llvm::StructType::create(elems, "Runtime"); + } + return type; +} + +namespace +{ +llvm::Twine getName(RuntimeData::Index _index) +{ + switch (_index) + { + default: return ""; + case RuntimeData::Gas: return "msg.gas"; + case RuntimeData::GasPrice: return "tx.gasprice"; + case RuntimeData::CallData: return "msg.data.ptr"; + case RuntimeData::CallDataSize: return "msg.data.size"; + case RuntimeData::ApparentCallValue: return "msg.value"; + case RuntimeData::Code: return "code.ptr"; + case RuntimeData::CodeSize: return "code.size"; + } +} +} + +RuntimeManager::RuntimeManager(IRBuilder& _builder, code_iterator _codeBegin, code_iterator _codeEnd): + CompilerHelper(_builder), + m_codeBegin(_codeBegin), + m_codeEnd(_codeEnd) +{ + // Unpack data + auto rtPtr = getRuntimePtr(); + m_dataPtr = m_builder.CreateLoad(m_builder.CreateStructGEP(getRuntimeType(), rtPtr, 0), "dataPtr"); + assert(m_dataPtr->getType() == Type::RuntimeDataPtr); + m_memPtr = m_builder.CreateStructGEP(getRuntimeType(), rtPtr, 2, "mem"); + assert(m_memPtr->getType() == Array::getType()->getPointerTo()); + m_envPtr = m_builder.CreateLoad(m_builder.CreateStructGEP(getRuntimeType(), rtPtr, 1), "env"); + assert(m_envPtr->getType() == Type::EnvPtr); + + auto mallocFunc = llvm::Function::Create(llvm::FunctionType::get(Type::WordPtr, {Type::Size}, false), llvm::Function::ExternalLinkage, "malloc", getModule()); + mallocFunc->setDoesNotThrow(); + mallocFunc->setDoesNotAlias(0); + + m_stackBase = m_builder.CreateCall(mallocFunc, m_builder.getInt64(Type::Word->getPrimitiveSizeInBits() / 8 * stackSizeLimit), "stack.base"); // TODO: Use Type::SizeT type + m_stackSize = m_builder.CreateAlloca(Type::Size, nullptr, "stack.size"); + m_builder.CreateStore(m_builder.getInt64(0), m_stackSize); + + auto data = m_builder.CreateLoad(m_dataPtr, "data"); + for (unsigned i = 0; i < m_dataElts.size(); ++i) + m_dataElts[i] = m_builder.CreateExtractValue(data, i, getName(RuntimeData::Index(i))); + + m_gasPtr = m_builder.CreateAlloca(Type::Gas, nullptr, "gas.ptr"); + m_builder.CreateStore(m_dataElts[RuntimeData::Index::Gas], m_gasPtr); + + m_exitBB = llvm::BasicBlock::Create(m_builder.getContext(), "Exit", getMainFunction()); + InsertPointGuard guard{m_builder}; + m_builder.SetInsertPoint(m_exitBB); + auto retPhi = m_builder.CreatePHI(Type::MainReturn, 16, "ret"); + auto freeFunc = getModule()->getFunction("free"); + if (!freeFunc) + { + freeFunc = llvm::Function::Create(llvm::FunctionType::get(Type::Void, Type::WordPtr, false), llvm::Function::ExternalLinkage, "free", getModule()); + freeFunc->setDoesNotThrow(); + freeFunc->setDoesNotCapture(1); + } + m_builder.CreateCall(freeFunc, {m_stackBase}); + auto extGasPtr = m_builder.CreateStructGEP(getRuntimeDataType(), getDataPtr(), RuntimeData::Index::Gas, "msg.gas.ptr"); + m_builder.CreateStore(getGas(), extGasPtr); + m_builder.CreateRet(retPhi); +} + +llvm::Value* RuntimeManager::getRuntimePtr() +{ + // Expect first argument of a function to be a pointer to Runtime + auto func = m_builder.GetInsertBlock()->getParent(); + auto rtPtr = &func->getArgumentList().front(); + assert(rtPtr->getType() == Type::RuntimePtr); + return rtPtr; +} + +llvm::Value* RuntimeManager::getDataPtr() +{ + if (getMainFunction()) + return m_dataPtr; + + auto rtPtr = getRuntimePtr(); + auto dataPtr = m_builder.CreateLoad(m_builder.CreateStructGEP(getRuntimeType(), rtPtr, 0), "data"); + assert(dataPtr->getType() == getRuntimeDataType()->getPointerTo()); + return dataPtr; +} + +llvm::Value* RuntimeManager::getEnvPtr() +{ + assert(getMainFunction()); // Available only in main function + return m_envPtr; +} + +llvm::Value* RuntimeManager::getPtr(RuntimeData::Index _index) +{ + auto ptr = m_builder.CreateStructGEP(getRuntimeDataType(), getDataPtr(), _index); + assert(getRuntimeDataType()->getElementType(_index)->getPointerTo() == ptr->getType()); + return ptr; +} + +llvm::Value* RuntimeManager::getValue() +{ + return m_dataElts[RuntimeData::ApparentCallValue]; +} + +void RuntimeManager::set(RuntimeData::Index _index, llvm::Value* _value) +{ + auto ptr = getPtr(_index); + assert(ptr->getType() == _value->getType()->getPointerTo()); + m_builder.CreateStore(_value, ptr); +} + +void RuntimeManager::registerReturnData(llvm::Value* _offset, llvm::Value* _size) +{ + auto memPtr = m_builder.CreateBitCast(getMem(), Type::BytePtr->getPointerTo()); + auto mem = m_builder.CreateLoad(memPtr, "memory"); + auto returnDataPtr = m_builder.CreateGEP(mem, _offset); + set(RuntimeData::ReturnData, returnDataPtr); + + auto size64 = m_builder.CreateTrunc(_size, Type::Size); + set(RuntimeData::ReturnDataSize, size64); +} + +void RuntimeManager::exit(ReturnCode _returnCode) +{ + m_builder.CreateBr(m_exitBB); + auto retPhi = llvm::cast(&m_exitBB->front()); + retPhi->addIncoming(Constant::get(_returnCode), m_builder.GetInsertBlock()); +} + +void RuntimeManager::abort(llvm::Value* _jmpBuf) +{ + auto longjmp = llvm::Intrinsic::getDeclaration(getModule(), llvm::Intrinsic::eh_sjlj_longjmp); + m_builder.CreateCall(longjmp, {_jmpBuf}); +} + +llvm::Value* RuntimeManager::getCallData() +{ + return m_dataElts[RuntimeData::CallData]; +} + +llvm::Value* RuntimeManager::getCode() +{ + // OPT Check what is faster + //return get(RuntimeData::Code); + if (!m_codePtr) + m_codePtr = m_builder.CreateGlobalStringPtr({reinterpret_cast(m_codeBegin), static_cast(m_codeEnd - m_codeBegin)}, "code"); + return m_codePtr; +} + +llvm::Value* RuntimeManager::getCodeSize() +{ + return Constant::get(m_codeEnd - m_codeBegin); +} + +llvm::Value* RuntimeManager::getCallDataSize() +{ + auto value = m_dataElts[RuntimeData::CallDataSize]; + assert(value->getType() == Type::Size); + return m_builder.CreateZExt(value, Type::Word); +} + +llvm::Value* RuntimeManager::getGas() +{ + return m_builder.CreateLoad(getGasPtr(), "gas"); +} + +llvm::Value* RuntimeManager::getGasPtr() +{ + assert(getMainFunction()); + return m_gasPtr; +} + +llvm::Value* RuntimeManager::getMem() +{ + assert(getMainFunction()); + return m_memPtr; +} + +void RuntimeManager::setGas(llvm::Value* _gas) +{ + assert(_gas->getType() == Type::Gas); + m_builder.CreateStore(_gas, getGasPtr()); +} + +} +} +} diff --git a/evmjit/libevmjit/RuntimeManager.h b/evmjit/libevmjit/RuntimeManager.h new file mode 100644 index 0000000000..a877242dfd --- /dev/null +++ b/evmjit/libevmjit/RuntimeManager.h @@ -0,0 +1,80 @@ +#pragma once + +#include + +#include "CompilerHelper.h" +#include "Type.h" +#include "Instruction.h" + +namespace dev +{ +namespace eth +{ +namespace jit +{ +using namespace evmjit; + +class RuntimeManager: public CompilerHelper +{ +public: + RuntimeManager(IRBuilder& _builder, code_iterator _codeBegin, code_iterator _codeEnd); + + llvm::Value* getRuntimePtr(); + llvm::Value* getDataPtr(); + llvm::Value* getEnvPtr(); + + llvm::Value* getValue(); + llvm::Value* getGas(); + llvm::Value* getGasPtr(); + llvm::Value* getCallData(); + llvm::Value* getCode(); + llvm::Value* getCodeSize(); + llvm::Value* getCallDataSize(); + llvm::Value* getJmpBuf() { return m_jmpBuf; } + void setGas(llvm::Value* _gas); + + llvm::Value* getMem(); + + void registerReturnData(llvm::Value* _index, llvm::Value* _size); // TODO: Move to Memory. + + void exit(ReturnCode _returnCode); + + void abort(llvm::Value* _jmpBuf); + + llvm::Value* getStackBase() const { return m_stackBase; } + llvm::Value* getStackSize() const { return m_stackSize; } + + void setJmpBuf(llvm::Value* _jmpBuf) { m_jmpBuf = _jmpBuf; } + void setExitBB(llvm::BasicBlock* _bb) { m_exitBB = _bb; } + + static llvm::StructType* getRuntimeType(); + static llvm::StructType* getRuntimeDataType(); + + //TODO Move to schedule + static const size_t stackSizeLimit = 1024; + +private: + llvm::Value* getPtr(RuntimeData::Index _index); + void set(RuntimeData::Index _index, llvm::Value* _value); + + llvm::Value* m_jmpBuf = nullptr; + llvm::Value* m_dataPtr = nullptr; + llvm::Value* m_gasPtr = nullptr; + llvm::Value* m_memPtr = nullptr; + llvm::Value* m_envPtr = nullptr; + + std::array m_dataElts; + + llvm::Value* m_stackBase = nullptr; + llvm::Value* m_stackSize = nullptr; + + llvm::BasicBlock* m_exitBB = nullptr; + + code_iterator m_codeBegin = {}; + code_iterator m_codeEnd = {}; + llvm::Value* m_codePtr = nullptr; +}; + +} +} +} diff --git a/evmjit/libevmjit/Type.cpp b/evmjit/libevmjit/Type.cpp new file mode 100644 index 0000000000..697d814c76 --- /dev/null +++ b/evmjit/libevmjit/Type.cpp @@ -0,0 +1,73 @@ +#include "Type.h" + +#include + +#include "RuntimeManager.h" + +namespace dev +{ +namespace eth +{ +namespace jit +{ + +llvm::IntegerType* Type::Word; +llvm::PointerType* Type::WordPtr; +llvm::IntegerType* Type::Bool; +llvm::IntegerType* Type::Size; +llvm::IntegerType* Type::Gas; +llvm::PointerType* Type::GasPtr; +llvm::IntegerType* Type::Byte; +llvm::PointerType* Type::BytePtr; +llvm::Type* Type::Void; +llvm::IntegerType* Type::MainReturn; +llvm::PointerType* Type::EnvPtr; +llvm::PointerType* Type::RuntimeDataPtr; +llvm::PointerType* Type::RuntimePtr; +llvm::ConstantInt* Constant::gasMax; +llvm::MDNode* Type::expectTrue; + +void Type::init(llvm::LLVMContext& _context) +{ + if (!Word) // Do init only once + { + Word = llvm::Type::getIntNTy(_context, 256); + WordPtr = Word->getPointerTo(); + Bool = llvm::Type::getInt1Ty(_context); + Size = llvm::Type::getInt64Ty(_context); + Gas = Size; + GasPtr = Gas->getPointerTo(); + Byte = llvm::Type::getInt8Ty(_context); + BytePtr = Byte->getPointerTo(); + Void = llvm::Type::getVoidTy(_context); + MainReturn = llvm::Type::getInt32Ty(_context); + + EnvPtr = llvm::StructType::create(_context, "Env")->getPointerTo(); + RuntimeDataPtr = RuntimeManager::getRuntimeDataType()->getPointerTo(); + RuntimePtr = RuntimeManager::getRuntimeType()->getPointerTo(); + + Constant::gasMax = llvm::ConstantInt::getSigned(Type::Gas, std::numeric_limits::max()); + + expectTrue = llvm::MDBuilder{_context}.createBranchWeights(1, 0); + } +} + +llvm::ConstantInt* Constant::get(int64_t _n) +{ + return llvm::ConstantInt::getSigned(Type::Word, _n); +} + +llvm::ConstantInt* Constant::get(llvm::APInt const& _n) +{ + return llvm::ConstantInt::get(Type::Word->getContext(), _n); +} + +llvm::ConstantInt* Constant::get(ReturnCode _returnCode) +{ + return llvm::ConstantInt::get(Type::MainReturn, static_cast(_returnCode)); +} + +} +} +} + diff --git a/evmjit/libevmjit/Type.h b/evmjit/libevmjit/Type.h new file mode 100644 index 0000000000..f054adef0a --- /dev/null +++ b/evmjit/libevmjit/Type.h @@ -0,0 +1,61 @@ +#pragma once + +#include "preprocessor/llvm_includes_start.h" +#include +#include +#include +#include "preprocessor/llvm_includes_end.h" + +#include "JIT.h" + +namespace dev +{ +namespace eth +{ +namespace jit +{ +using namespace evmjit; + +struct Type +{ + static llvm::IntegerType* Word; + static llvm::PointerType* WordPtr; + + static llvm::IntegerType* Bool; + static llvm::IntegerType* Size; + static llvm::IntegerType* Gas; + static llvm::PointerType* GasPtr; + + static llvm::IntegerType* Byte; + static llvm::PointerType* BytePtr; + + static llvm::Type* Void; + + /// Main function return type + static llvm::IntegerType* MainReturn; + + static llvm::PointerType* EnvPtr; + static llvm::PointerType* RuntimeDataPtr; + static llvm::PointerType* RuntimePtr; + + // TODO: Redesign static LLVM objects + static llvm::MDNode* expectTrue; + + static void init(llvm::LLVMContext& _context); +}; + +struct Constant +{ + static llvm::ConstantInt* gasMax; + + /// Returns word-size constant + static llvm::ConstantInt* get(int64_t _n); + static llvm::ConstantInt* get(llvm::APInt const& _n); + + static llvm::ConstantInt* get(ReturnCode _returnCode); +}; + +} +} +} + diff --git a/evmjit/libevmjit/Utils.cpp b/evmjit/libevmjit/Utils.cpp new file mode 100644 index 0000000000..82c5b0cfe7 --- /dev/null +++ b/evmjit/libevmjit/Utils.cpp @@ -0,0 +1,184 @@ +#include "Utils.h" + +#include + +#include + +#include "BuildInfo.gen.h" + +namespace dev +{ +namespace evmjit +{ + +#if !defined(NDEBUG) // Debug + +std::ostream& getLogStream(char const* _channel) +{ + static std::ostream nullStream{nullptr}; +#if LLVM_DEBUG + return (llvm::DebugFlag && llvm::isCurrentDebugType(_channel)) ? LOG(ERROR) : nullStream; +#else + return (void)_channel, nullStream; +#endif +} + +#endif + +namespace +{ + +/** libkeccak-tiny + * + * A single-file implementation of SHA-3 and SHAKE. + * + * Implementor: David Leon Gil + * License: CC0, attribution kindly requested. Blame taken too, + * but not liability. + */ + +/******** The Keccak-f[1600] permutation ********/ + +/*** Constants. ***/ +static const uint8_t rho[24] = \ + { 1, 3, 6, 10, 15, 21, + 28, 36, 45, 55, 2, 14, + 27, 41, 56, 8, 25, 43, + 62, 18, 39, 61, 20, 44}; +static const uint8_t pi[24] = \ + {10, 7, 11, 17, 18, 3, + 5, 16, 8, 21, 24, 4, + 15, 23, 19, 13, 12, 2, + 20, 14, 22, 9, 6, 1}; +static const uint64_t RC[24] = \ + {1ULL, 0x8082ULL, 0x800000000000808aULL, 0x8000000080008000ULL, + 0x808bULL, 0x80000001ULL, 0x8000000080008081ULL, 0x8000000000008009ULL, + 0x8aULL, 0x88ULL, 0x80008009ULL, 0x8000000aULL, + 0x8000808bULL, 0x800000000000008bULL, 0x8000000000008089ULL, 0x8000000000008003ULL, + 0x8000000000008002ULL, 0x8000000000000080ULL, 0x800aULL, 0x800000008000000aULL, + 0x8000000080008081ULL, 0x8000000000008080ULL, 0x80000001ULL, 0x8000000080008008ULL}; + +/*** Helper macros to unroll the permutation. ***/ +#define rol(x, s) (((x) << s) | ((x) >> (64 - s))) +#define REPEAT6(e) e e e e e e +#define REPEAT24(e) REPEAT6(e e e e) +#define REPEAT5(e) e e e e e +#define FOR5(v, s, e) \ + v = 0; \ + REPEAT5(e; v = decltype(v)(v + s);) + +/*** Keccak-f[1600] ***/ +static inline void keccakf(void* state) { + uint64_t* a = (uint64_t*)state; + uint64_t b[5] = {0}; + uint64_t t = 0; + uint8_t x, y; + + for (int i = 0; i < 24; i++) { + // Theta + FOR5(x, 1, + b[x] = 0; + FOR5(y, 5, + b[x] ^= a[x + y]; )) + FOR5(x, 1, + FOR5(y, 5, + a[y + x] ^= b[(x + 4) % 5] ^ rol(b[(x + 1) % 5], 1); )) + // Rho and pi + t = a[1]; + x = 0; + REPEAT24(b[0] = a[pi[x]]; + a[pi[x]] = rol(t, rho[x]); + t = b[0]; + x++; ) + // Chi + FOR5(y, + 5, + FOR5(x, 1, + b[x] = a[y + x];) + FOR5(x, 1, + a[y + x] = b[x] ^ ((~b[(x + 1) % 5]) & b[(x + 2) % 5]); )) + // Iota + a[0] ^= RC[i]; + } +} + +/******** The FIPS202-defined functions. ********/ + +/*** Some helper macros. ***/ + +#define _(S) do { S } while (0) +#define FOR(i, ST, L, S) \ + _(for (size_t i = 0; i < L; i += ST) { S; }) +#define mkapply_ds(NAME, S) \ + static inline void NAME(uint8_t* dst, \ + const uint8_t* src, \ + size_t len) { \ + FOR(i, 1, len, S); \ + } +#define mkapply_sd(NAME, S) \ + static inline void NAME(const uint8_t* src, \ + uint8_t* dst, \ + size_t len) { \ + FOR(i, 1, len, S); \ + } + +mkapply_ds(xorin, dst[i] ^= src[i]) // xorin +mkapply_sd(setout, dst[i] = src[i]) // setout + +#define P keccakf +#define Plen 200 + +// Fold P*F over the full blocks of an input. +#define foldP(I, L, F) \ + while (L >= rate) { \ + F(a, I, rate); \ + P(a); \ + I += rate; \ + L -= rate; \ + } + +/** The sponge-based hash construction. **/ +static inline int hash(uint8_t* out, size_t outlen, + const uint8_t* in, size_t inlen, + size_t rate, uint8_t delim) { + if ((out == NULL) || ((in == NULL) && inlen != 0) || (rate >= Plen)) { + return -1; + } + uint8_t a[Plen] = {0}; + // Absorb input. + foldP(in, inlen, xorin); + // Xor in the DS and pad frame. + a[inlen] ^= delim; + a[rate - 1] ^= 0x80; + // Xor in the last block. + xorin(a, in, inlen); + // Apply P + P(a); + // Squeeze output. + foldP(out, outlen, setout); + setout(a, out, outlen); + memset(a, 0, 200); + return 0; +} + +/*** Helper macros to define SHA3 and SHAKE instances. ***/ +#define defkeccak(bits) \ + static int keccak_##bits(uint8_t* out, size_t outlen, \ + const uint8_t* in, size_t inlen) { \ + if (outlen > (bits/8)) { \ + return -1; \ + } \ + return hash(out, outlen, in, inlen, 200 - (bits / 4), 0x01); \ + } + +defkeccak(256) + +} + +void keccak(uint8_t const* _data, uint64_t _size, uint8_t* o_hash) +{ + keccak_256(o_hash, 32, _data, _size); +} + +} +} diff --git a/evmjit/libevmjit/Utils.h b/evmjit/libevmjit/Utils.h new file mode 100644 index 0000000000..0a02136386 --- /dev/null +++ b/evmjit/libevmjit/Utils.h @@ -0,0 +1,32 @@ +#pragma once + +#include +#include + +namespace dev { +namespace evmjit { + +void keccak(uint8_t const *_data, uint64_t _size, uint8_t *o_hash); + +// The same as assert, but expression is always evaluated and result returned +#define CHECK(expr) (assert(expr), expr) + +#if !defined(NDEBUG) // Debug + +std::ostream &getLogStream(char const *_channel); + +#define DLOG(CHANNEL) ::dev::evmjit::getLogStream(#CHANNEL) + +#else // Release + +struct Voider +{ + void operator=(std::ostream const&) {} +}; + +#define DLOG(CHANNEL) true ? (void)0 : ::dev::evmjit::Voider{} = std::cerr + +#endif + +} +} diff --git a/evmjit/libevmjit/preprocessor/llvm_includes_end.h b/evmjit/libevmjit/preprocessor/llvm_includes_end.h new file mode 100644 index 0000000000..9ad9f4c0bb --- /dev/null +++ b/evmjit/libevmjit/preprocessor/llvm_includes_end.h @@ -0,0 +1,3 @@ +#if defined(_MSC_VER) + #pragma warning(pop) +#endif diff --git a/evmjit/libevmjit/preprocessor/llvm_includes_start.h b/evmjit/libevmjit/preprocessor/llvm_includes_start.h new file mode 100644 index 0000000000..0bc0b2f710 --- /dev/null +++ b/evmjit/libevmjit/preprocessor/llvm_includes_start.h @@ -0,0 +1,4 @@ +#if defined(_MSC_VER) + #pragma warning(push) + #pragma warning(disable: 4267 4244 4800 4624 4141 4291) +#endif diff --git a/evmjit/scripts/build.sh b/evmjit/scripts/build.sh new file mode 100644 index 0000000000..982a68e9f6 --- /dev/null +++ b/evmjit/scripts/build.sh @@ -0,0 +1,8 @@ +#!/bin/sh +set -x -e + +mkdir -p build && cd build +cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DEVMJIT_INCLUDE_EXAMPLES=On -DEVMJIT_TESTS=On .. +cmake --build . +cmake --build . --target evmjit-standalone +cmake --build . --target example-capi diff --git a/evmjit/scripts/travis_update_docs.sh b/evmjit/scripts/travis_update_docs.sh new file mode 100644 index 0000000000..3def0f7eec --- /dev/null +++ b/evmjit/scripts/travis_update_docs.sh @@ -0,0 +1,8 @@ +#!/bin/sh +set -e -x + +sudo apt-get -qq install -y doxygen +doxygen docs/Doxyfile +git add docs +git commit -m "Update docs" +git push -f "https://$GITHUB_TOKEN@github.com/ethereum/evmjit.git" HEAD:gh-pages diff --git a/evmjit/tests/CMakeLists.txt b/evmjit/tests/CMakeLists.txt new file mode 100644 index 0000000000..89cf03ca69 --- /dev/null +++ b/evmjit/tests/CMakeLists.txt @@ -0,0 +1,15 @@ + +add_executable(test-evmjit-standalone test-evmjit-standalone.c) +target_include_directories(test-evmjit-standalone PRIVATE ../include) +if (MSVC) + set(SYSTEM_LIBS "") +elseif (APPLE) + set(SYSTEM_LIBS stdc++ pthread) +else() + set(SYSTEM_LIBS stdc++ pthread dl m) +endif() +target_link_libraries(test-evmjit-standalone PRIVATE ${EVMJIT_STANDALONE_LIB} ${SYSTEM_LIBS}) +add_dependencies(test-evmjit-standalone evmjit-standalone) + + +add_test(evmjit-standalone test-evmjit-standalone) diff --git a/evmjit/tests/test-evmjit-standalone.c b/evmjit/tests/test-evmjit-standalone.c new file mode 100644 index 0000000000..ec2b13c691 --- /dev/null +++ b/evmjit/tests/test-evmjit-standalone.c @@ -0,0 +1,15 @@ +#include +#include + +int main() +{ + struct evm_interface evmjit = evmjit_get_interface(); + static const unsigned expected_abi_version = 0; + printf("EVMJIT ABI version %u\n", evmjit.abi_version); + if (expected_abi_version != evmjit.abi_version) + { + printf("Error: expected ABI version %u!\n", expected_abi_version); + return 1; + } + return 0; +} diff --git a/evmjit/wercker.yml b/evmjit/wercker.yml new file mode 100644 index 0000000000..6f049572e9 --- /dev/null +++ b/evmjit/wercker.yml @@ -0,0 +1,18 @@ +box: chfast/cpp-ethereum-dev + +# This is the build pipeline. Pipelines are the core of wercker +# Read more about pipelines on our dev center +# http://devcenter.wercker.com/docs/pipelines/index.html +build: + # Steps make up the actions in your pipeline + # Read more about steps on our dev center: + # http://devcenter.wercker.com/docs/steps/index.html + steps: + - script: + name: configure + code: | + mkdir build && cd build + cmake .. -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DLLVM_DIR=/usr/lib/llvm-3.9/lib/cmake/llvm + - script: + name: build + code: cmake --build build diff --git a/genesis.json b/genesis.json new file mode 100644 index 0000000000..f38aba29de --- /dev/null +++ b/genesis.json @@ -0,0 +1,13 @@ +{ + "nonce": "0x0", + "difficulty": "0x0", + "mixhash": "0x0", + "coinbase": "0x0", + "timestamp": "0x0", + "parentHash": "0x0", + "extraData": "0x0", + "gasLimit": "0x13880000000000", + "god":"0x4d23de3297034cdd4a58db35f659a9b61fc7577b", + "alloc": {}, + "initMinerNodes":["de0fa385816b505799433e54b88788e21cb42092a6ff5bcaa2285d7ace906e5e6ce8ef2b30134ff276a5834d58721291acc5864e07e6d52469b79b28e699dfde"] +} \ No newline at end of file diff --git a/homebrew/INSTALL_RECEIPT.json b/homebrew/INSTALL_RECEIPT.json new file mode 100644 index 0000000000..2a934482ea --- /dev/null +++ b/homebrew/INSTALL_RECEIPT.json @@ -0,0 +1 @@ +{"used_options":["--with-evmjit"],"unused_options":["--with-gui","--without-gpu-mining","--with-debug","--with-vmtrace","--with-paranoia","--successful"],"built_as_bottle":true,"poured_from_bottle":false,"time":1440062311,"HEAD":"4511a6ad3149f514d161dc6c64505f795a0f9cc1","stdlib":"libcxx","compiler":"clang","source":{"path":"/Users/administrator/slave/build-cpp-osx-develop-brew/brew/cpp-ethereum.rb","tap":null,"spec":"devel"}} diff --git a/homebrew/fix_homebrew_paths_in_standalone_zip.py b/homebrew/fix_homebrew_paths_in_standalone_zip.py new file mode 100644 index 0000000000..74f2e99b4e --- /dev/null +++ b/homebrew/fix_homebrew_paths_in_standalone_zip.py @@ -0,0 +1,65 @@ +# ------------------------------------------------------------------------------ +# This file is part of cpp-ethereum. +# +# cpp-ethereum is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# cpp-ethereum 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cpp-ethereum. If not, see +# +# ----------------------------------------------------------------------------- +# +# This Python script is used within the OS X release process, to ensure +# that the standalone OS X ZIP files which we make are actually +# standalone, and not implicitly dependent on Homebrew installs for +# external libraries which we use. +# +# This implicit dependencies seem to show up only where we have +# external dependencies which are dependent on each other, and the +# path from one to another is an absolute path to "/usr/local/opt", +# the Homebrew install location. External dependencies which only +# depend on system libraries are fine. Our main applications seem +# to be fine. +# +# An example of a dependency which requires this fix-up at the time +# of writing is the following dependency edge: +# +# libjsonrpccpp-client.0.dylib +# -> /usr/local/opt/jsoncpp/lib/libjsoncpp.0.dylib +# +# See https://blogs.oracle.com/dipol/entry/dynamic_libraries_rpath_and_mac +# for a little overview of "install_name_tool" and "otool". +# +# ----------------------------------------------------------------------------- + +import os +import subprocess +import sys + + +def readDependencies(fname): + with open(fname) as f: + o = subprocess.Popen(['otool', '-L', fname], stdout=subprocess.PIPE) + for line in o.stdout: + if line[0] == '\t': + library = line.split(' ', 1)[0][1:] + if library.startswith("/usr/local/lib") or library.startswith("/usr/local/opt") or library.startswith("/Users/"): + if (os.path.basename(library) != os.path.basename(fname)): + command = "install_name_tool -change " + \ + library + " @executable_path/./" + \ + os.path.basename(library) + " " + fname + print command + os.system("chmod +w " + fname) + os.system(command) + +root = sys.argv[1] +for (dirpath, dirnames, filenames) in os.walk(root): + for filename in filenames: + readDependencies(os.path.join(root, filename)) diff --git a/homebrew/homebrew.mxcl.cpp-ethereum.plist b/homebrew/homebrew.mxcl.cpp-ethereum.plist new file mode 100644 index 0000000000..82d29218e8 --- /dev/null +++ b/homebrew/homebrew.mxcl.cpp-ethereum.plist @@ -0,0 +1,23 @@ + + + + + Label + homebrew.mxcl.cpp-ethereum + RunAtLoad + + KeepAlive + + ThrottleInterval + 300 + ProgramArguments + + @@HOMEBREW_PREFIX@@/opt/cpp-ethereum/bin/eth + -d + @@HOMEBREW_CELLAR@@/cpp-ethereum/0.9.41-61/.ethereum + -b + + WorkingDirectory + @@HOMEBREW_PREFIX@@ + + diff --git a/homebrew/prepare_receipt.sh b/homebrew/prepare_receipt.sh new file mode 100644 index 0000000000..3c3944f2a6 --- /dev/null +++ b/homebrew/prepare_receipt.sh @@ -0,0 +1,71 @@ +#/bin/bash + +# this script should be run from build directory + +VERSION=1 # eg 1.0rc2 +NUMBER=1 # jenkins build number + +# Detect whether we are running on a Yosemite or El Capitan machine, and generate +# an appropriately named ZIP file for the Homebrew receipt to point at. +if echo `sw_vers` | grep "10.11"; then + OSX_VERSION=el_capitan +elif echo `sw_vers` | grep "10.10"; then + OSX_VERSION=yosemite +else + echo Unsupported OS X version. We only support Yosemite and El Capitan + exit 1 +fi + +while [ "$1" != "" ]; do + case $1 in + --version ) + shift + VERSION=$1 + ;; + --number ) + shift + NUMBER=$1 + ;; + esac + shift +done + +# prepare template directory +rm -rf cpp-ethereum +mkdir cpp-ethereum +mkdir cpp-ethereum/$VERSION +p="../webthree-helpers/homebrew/" +cp ${p}homebrew.mxcl.cpp-ethereum.plist ${p}INSTALL_RECEIPT.json ../web-helpers/LICENSE cpp-ethereum/$VERSION + +# build umbrella project and move install directory to destination +# +# TODO - Except it isn't actually building it is? Maybe it used to +# at some point in the past? Does that mean that we are dependent +# on some previous build/install steps having happened by the time +# we run this script? Probably. +mkdir -p install +cp -rf install/* cpp-ethereum/$VERSION + +# tar everything +NAME="cpp-ethereum-${VERSION}.${OSX_VERSION}.bottle.${NUMBER}.tar.gz" +tar -zcvf $NAME cpp-ethereum + +# get variables +HASH=`git rev-parse HEAD` +SIGNATURE=`openssl sha1 ${NAME} | cut -d " " -f 2` + +# Pull the current cpp-ethereum.rb file from Github. We used to use a template file. +curl https://raw.githubusercontent.com/ethereum/homebrew-ethereum/master/cpp-ethereum.rb > cpp-ethereum.rb.in + +# prepare receipt +if [ ${OSX_VERSION} == yosemite ]; then + sed -e s/revision\ \=\>\ \'[[:xdigit:]][[:xdigit:]]*\'/revision\ \=\>\ \'${HASH}\'/g \ + -e s/version\ \'.*\'/version\ \'${VERSION}\'/g \ + -e s/sha1\ \'[[:xdigit:]][[:xdigit:]]*\'\ \=\>\ \:\yosemite/sha1\ \'${SIGNATURE}\'\ \=\>\ \:yosemite/g \ + -e s/revision[[:space:]][[:digit:]][[:digit:]]*/revision\ ${NUMBER}/g < cpp-ethereum.rb.in > "cpp-ethereum.rb" +else + sed -e s/revision\ \=\>\ \'[[:xdigit:]][[:xdigit:]]*\'/revision\ \=\>\ \'${HASH}\'/g \ + -e s/version\ \'.*\'/version\ \'${VERSION}\'/g \ + -e s/sha1\ \'[[:xdigit:]][[:xdigit:]]*\'\ \=\>\ \:\el\_capitan/sha1\ \'${SIGNATURE}\'\ \=\>\ \:el\_capitan/g \ + -e s/revision[[:space:]][[:digit:]][[:digit:]]*/revision\ ${NUMBER}/g < cpp-ethereum.rb.in > "cpp-ethereum.rb" +fi diff --git a/libcontract/BaseContract.cpp b/libcontract/BaseContract.cpp new file mode 100644 index 0000000000..64254ce77c --- /dev/null +++ b/libcontract/BaseContract.cpp @@ -0,0 +1,165 @@ +/****************************************************************************** + * Copyright (c) 2012-2020, Juzhen TECHNOLOGIES (SHENZHEN) LTD. + * File : BaseContract.cpp + * Version : ethereum + * Description : - + + * modification history + * -------------------- + * author: fuxideng 2017-3-2 8:54:43 + * -------------------- +*******************************************************************************/ + +#include "BaseContract.h" + +using namespace dev; +using namespace contract; + +BaseContract::BaseContract(eth::Client * client, dev::Address contractAddr) : m_client(client), m_contractAddr(contractAddr) +{ + m_paramNum = 0; +} + +BaseContract::~BaseContract() +{ + +} + +BaseContract* BaseContract::setFunction(const std::string& name) +{ + if (!name.empty()) + { + m_functionName = name; + } + + return this; +} + +BaseContract* BaseContract::addParam(int value) +{ + m_fixedParams[m_paramNum++] = h256(value).asBytes(); + return this; +} + +BaseContract* BaseContract::addParam(const dev::Address& value) +{ + m_fixedParams[m_paramNum++] = bytes(16, 0) + value.asBytes(); + return this; +} + +BaseContract* BaseContract::addParam(const std::string& value) +{ + bytes data = h256(u256(value.size())).asBytes(); + data.resize(data.size() + (value.size() + 31) / 32 * 32); + bytesConstRef(&value).populate(bytesRef(&data).cropped(32)); + + m_dynamicParams[m_paramNum++] = data; + return this; +} + +const bytes& BaseContract::call() +{ + m_res.output.clear(); + if (m_client == NULL || m_contractAddr.data() == NULL || m_functionName.empty()) + { + return m_res.output; + } + + dev::bytes request = dev::sha3(m_functionName).ref().cropped(0, 4).toBytes(); + int offset = 32 * (m_fixedParams.size() + m_dynamicParams.size()); + for (int i=0; i::iterator itr = m_dynamicParams.begin(); itr != m_dynamicParams.end(); ++itr) + { + request += itr->second; + } + + try + { + m_res = m_client->call(m_contractAddr, request, 99999999); + reset(); + } + catch(...) + { + reset(); + return m_res.output; + } + + return response(); +} + +int BaseContract::call(int& result) +{ + result = -1; + m_res.output.clear(); + if (m_client == NULL || m_contractAddr.data() == NULL || m_functionName.empty()) + { + return -1; + } + + dev::bytes request = dev::sha3(m_functionName).ref().cropped(0, 4).toBytes(); + int offset = 32 * (m_fixedParams.size() + m_dynamicParams.size()); + for (int i=0; i::iterator itr = m_dynamicParams.begin(); itr != m_dynamicParams.end(); ++itr) + { + request += itr->second; + } + + try + { + m_res = m_client->call(m_contractAddr, request, 99999999); + if (0 != m_client->getResultInt(m_res, result)) + { + reset(); + return -1; + } + + reset(); + + } + catch(...) + { + reset(); + return -1; + } + + return 0; +} + + +const bytes& BaseContract::response() +{ + return m_res.output; +} + +void BaseContract::reset() +{ + m_functionName = ""; + m_paramNum = 0; + m_fixedParams.clear(); + m_dynamicParams.clear(); +} + diff --git a/libcontract/BaseContract.h b/libcontract/BaseContract.h new file mode 100644 index 0000000000..994bd93ce2 --- /dev/null +++ b/libcontract/BaseContract.h @@ -0,0 +1,59 @@ +/****************************************************************************** + * Copyright (c) 2012-2020, Juzhen TECHNOLOGIES (SHENZHEN) LTD. + * File : BaseContract.h + * Version : ethereum + * Description : - + + * modification history + * -------------------- + * author: fuxideng 2017-3-2 8:52:55 + * -------------------- +*******************************************************************************/ +#ifndef __ETHEREUM_BASECONTRACT_H +#define __ETHEREUM_BASECONTRACT_H + +/****************************************************************************** + * BaseContract - ڲԼʵĻ + * DESCRIPTION: + * 1. ṩԼĻ + * 2. ԼӸúԼ̳жijԱʵַʷ + + * modification history + * -------------------- + * author: fuxideng 2017-3-2 8:53:13 + * -------------------- +*******************************************************************************/ + +#include + +namespace contract +{ +class BaseContract +{ +public: + BaseContract(dev::eth::Client * client, dev::Address contractAddr); + virtual ~BaseContract(); + +public: + BaseContract* setFunction(const std::string& name); + BaseContract* addParam(int value); + BaseContract* addParam(const dev::Address& value); + BaseContract* addParam(const std::string& value); + const dev::bytes& call(); + int call(int& result); + const dev::bytes& response(); + void reset(); + +private: + dev::eth::Client * m_client; + dev::Address m_contractAddr; + std::string m_functionName; + int m_paramNum; + std::map m_fixedParams; + std::map m_dynamicParams; + dev::eth::ExecutionResult m_res; +}; +} + +#endif /* __ETHEREUM_BASECONTRACT_H */ + diff --git a/libcontract/CMakeLists.txt b/libcontract/CMakeLists.txt new file mode 100644 index 0000000000..88be8aa86e --- /dev/null +++ b/libcontract/CMakeLists.txt @@ -0,0 +1,14 @@ +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") + +aux_source_directory(. SRC_LIST) + +file(GLOB HEADERS "*.h") + +add_library(contract ${SRC_LIST} ${HEADERS}) + +find_package(Dev) + +target_include_directories(contract PRIVATE ..) +target_link_libraries(contract ${Dev_DEVCORE_LIBRARIES}) + +install(TARGETS contract RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib) diff --git a/libcontract/ContractDefine.h b/libcontract/ContractDefine.h new file mode 100644 index 0000000000..f45487c493 --- /dev/null +++ b/libcontract/ContractDefine.h @@ -0,0 +1,23 @@ +/****************************************************************************** + * Copyright (c) 2012-2020, Juzhen TECHNOLOGIES (SHENZHEN) LTD. + * File : ContractDefine.h + * Version : ethereum + * Description : - + + * modification history + * -------------------- + * author: fuxideng 2017-3-4 14:31:54 + * -------------------- +*******************************************************************************/ +#ifndef __ETHEREUM_CONTRACTDEFINE_H +#define __ETHEREUM_CONTRACTDEFINE_H + +namespace contract +{ + +#define CONTRACT_ADDRESS_DEPARTMENT_MANAGER "0x0000000000000000000000000000000000000014" + +} + +#endif /* __ETHEREUM_CONTRACTDEFINE_H */ + diff --git a/libcontract/FileInfoManagerContract.cpp b/libcontract/FileInfoManagerContract.cpp new file mode 100644 index 0000000000..28beb941b7 --- /dev/null +++ b/libcontract/FileInfoManagerContract.cpp @@ -0,0 +1,132 @@ +#include "FileInfoManagerContract.h" + + +using namespace dev; +using namespace contract; + + +const static std::string sc_FileInfoManagerAddr = "0x1000000000000000000000000000000000000018"; + + +FileInfoManagerContract::FileInfoManagerContract(dev::eth::Client * client, const dev::Address& contractAddr) : BaseContract(client, dev::Address(contractAddr)) +{ +} + +FileInfoManagerContract::~FileInfoManagerContract() +{ +} + + +/** +*@desc 分页查询组文件信息 +*/ +int FileInfoManagerContract::pageByGroup(std::string _group, int _pageNo, std::string& result) +{ + reset(); + + this->setFunction("pageByGroup(string,uint256)"); + this->addParam(_group); + this->addParam(_pageNo); + + const bytes& response = this->call(); + + result = eth::abiOut(response); + if (result.empty()) + { + return -1; + } + + return 0; +} + + +int FileInfoManagerContract::listFileinfoByGroup(const std::string& groupName, std::string& ret) +{ + reset(); + + this->setFunction("listByGroup(string)"); + this->addParam(groupName); + + const bytes& response = this->call(); + + ret = eth::abiOut(response); + if (ret.empty()) + { + return -1; + } + + return 0; +} + +//从FileInfoManager合约获取所有文件信息json结果 +int FileInfoManagerContract::listFileinfo(std::string& ret) +{ + reset(); + + this->setFunction("listAll()"); + const bytes& response = this->call(); + + ret = eth::abiOut(response); + if (ret.empty()) + { + return -1; + } + + return 0; +} + +//从FileInfoManager合约获取指定文件信息json结果 +int FileInfoManagerContract::findFileInfo(const std::string& _id, std::string& ret) +{ + reset(); + + this->setFunction("findFileInfo(string)"); + this->addParam(_id); + + const bytes& response = this->call(); + + ret = eth::abiOut(response); + if (ret.empty()) + { + return -1; + } + + return 0; +} + +/** +*@desc 获取组pageSize +*/ +int FileInfoManagerContract::getGroupPageCount(const std::string& group, int& result) +{ + reset(); + + this->setFunction("getGroupPageCount(string)"); + this->addParam(group); + + if (0 != this->call(result)) + { + return -1; + } + + return 0; +} + +/** +*@desc 获取pageSize +*/ +int FileInfoManagerContract::getPageCount(int& result) +{ + reset(); + + this->setFunction("getPageCount()"); + + if (0 != this->call(result)) + { + return -1; + } + + return 0; +} + + diff --git a/libcontract/FileInfoManagerContract.h b/libcontract/FileInfoManagerContract.h new file mode 100644 index 0000000000..e828fd33ff --- /dev/null +++ b/libcontract/FileInfoManagerContract.h @@ -0,0 +1,52 @@ +/** +FileInfoManager contract call +*/ + +#pragma once + +#include +#include +#include "libcontract/BaseContract.h" + +namespace contract +{ + +class FileInfoManagerContract : public BaseContract { +public: + FileInfoManagerContract(dev::eth::Client * client, const dev::Address& contractAddr = Address()); + ~FileInfoManagerContract(); + + /** + *@desc 分页查询组文件信息 + */ + int pageByGroup(std::string _group, int _pageNo, std::string& result); + + /** + *@desc 列出文件组 + */ + int listFileinfoByGroup(const std::string& groupName, std::string& ret); + + /** + *@desc 从FileInfoManager合约获取所有文件信息json结果 + */ + int listFileinfo(std::string& ret); + + /** + *@desc 从FileInfoManager合约获取指定文件信息json结果 + */ + int findFileInfo(const std::string& _id, std::string& ret); + + /** + *@desc 获取组pageSize + */ + int getGroupPageCount(const std::string& group, int& result); + + /** + *@desc 获取pageSize + */ + int getPageCount(int& result); + + +}; + +} diff --git a/libcontract/FileServerManagerContract.cpp b/libcontract/FileServerManagerContract.cpp new file mode 100644 index 0000000000..d0c9e687b9 --- /dev/null +++ b/libcontract/FileServerManagerContract.cpp @@ -0,0 +1,76 @@ +#include "FileServerManagerContract.h" + + + +using namespace dev; +using namespace contract; + + +FileServerManagerContract::FileServerManagerContract(dev::eth::Client* client, const dev::Address& contractAddr) : BaseContract(client, dev::Address(contractAddr)) +{ + +} + +FileServerManagerContract::~FileServerManagerContract() +{ +} + + + +//从FileInfoManager合约获取所有文件服务器信息json结果 +int FileServerManagerContract::listFileServer(std::string& ret) +{ + reset(); + + this->setFunction("listAll()"); + const bytes& response = this->call(); + + ret = eth::abiOut(response); + if (ret.empty()) + { + return -1; + } + + return 0; +} + +/** +*@desc 查询指定文件服务器信息 +*/ +int FileServerManagerContract::findServerInfo(const std::string& serverid, std::string& ret) +{ + reset(); + + this->setFunction("find(string)"); + this->addParam(serverid); + const bytes& response = this->call(); + + ret = eth::abiOut(response); + if (ret.empty()) + { + return -1; + } + + return 0; +} + +/** +*@desc 查询服务节点是否开启 +*/ +int FileServerManagerContract::isServerEnable(const std::string& serverid, bool& enable) +{ + reset(); + + enable = false; + this->setFunction("isServerEnable(string)"); + this->addParam(serverid); + + int result = 0; + if (0 != this->call(result)) + { + return -1; + } + + enable = result != 0 ? true : false; + return 0; +} \ No newline at end of file diff --git a/libcontract/FileServerManagerContract.h b/libcontract/FileServerManagerContract.h new file mode 100644 index 0000000000..0598a2a08f --- /dev/null +++ b/libcontract/FileServerManagerContract.h @@ -0,0 +1,40 @@ +/** +FileServerManager contract call +*/ + +#pragma once + +#include +#include +#include "libcontract/BaseContract.h" + +using namespace contract; + +namespace contract +{ + + +class FileServerManagerContract : public BaseContract { +public: + FileServerManagerContract(dev::eth::Client* client, const dev::Address& contractAddr = Address()); + ~FileServerManagerContract(); + + /** + *@desc 从FileInfoManager合约获取所有文件服务器信息json结果 + */ + int listFileServer(std::string& ret); + + + /** + *@desc 查询指定文件服务器信息 + */ + int findServerInfo(const std::string& serverid, std::string& ret); + + /** + *@desc 查询服务节点是否开启 + */ + int isServerEnable(const std::string& serverid, bool& enable); + +}; + +} diff --git a/libdevcore/Assertions.h b/libdevcore/Assertions.h new file mode 100644 index 0000000000..fceefaa1ba --- /dev/null +++ b/libdevcore/Assertions.h @@ -0,0 +1,111 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** + * @file Assertions.h + * @author Christian + * @date 2015 + * + * Assertion handling. + */ + +#pragma once + +#include "Exceptions.h" +#include "debugbreak.h" + +namespace dev +{ + +#if defined(_MSC_VER) +#define ETH_FUNC __FUNCSIG__ +#elif defined(__GNUC__) +#define ETH_FUNC __PRETTY_FUNCTION__ +#else +#define ETH_FUNC __func__ +#endif + +#define asserts(A) ::dev::assertAux(A, #A, __LINE__, __FILE__, ETH_FUNC) +#define assertsEqual(A, B) ::dev::assertEqualAux(A, B, #A, #B, __LINE__, __FILE__, ETH_FUNC) + +inline bool assertAux(bool _a, char const* _aStr, unsigned _line, char const* _file, char const* _func) +{ + bool ret = _a; + if (!ret) + { + std::cerr << "Assertion failed:" << _aStr << " [func=" << _func << ", line=" << _line << ", file=" << _file << "]" << std::endl; +#if ETH_DEBUG + debug_break(); +#endif + } + return !ret; +} + +template +inline bool assertEqualAux(A const& _a, B const& _b, char const* _aStr, char const* _bStr, unsigned _line, char const* _file, char const* _func) +{ + bool ret = _a == _b; + if (!ret) + { + std::cerr << "Assertion failed: " << _aStr << " == " << _bStr << " [func=" << _func << ", line=" << _line << ", file=" << _file << "]" << std::endl; + std::cerr << " Fail equality: " << _a << "==" << _b << std::endl; +#if ETH_DEBUG + debug_break(); +#endif + } + return !ret; +} + +/// Assertion that throws an exception containing the given description if it is not met. +/// Use it as assertThrow(1 == 1, ExceptionType, "Mathematics is wrong."); +/// Do NOT supply an exception object as the second parameter. +#define assertThrow(_condition, _ExceptionType, _description) \ + ::dev::assertThrowAux<_ExceptionType>(_condition, _description, __LINE__, __FILE__, ETH_FUNC) + +using errinfo_comment = boost::error_info; + +template +inline void assertThrowAux( + bool _condition, + ::std::string const& _errorDescription, + unsigned _line, + char const* _file, + char const* _function +) +{ + if (!_condition) + ::boost::throw_exception( + _ExceptionType() << + ::dev::errinfo_comment(_errorDescription) << + ::boost::throw_function(_function) << + ::boost::throw_file(_file) << + ::boost::throw_line(_line) + ); +} + +template +inline void assertThrowAux( + void const* _pointer, + ::std::string const& _errorDescription, + unsigned _line, + char const* _file, + char const* _function +) +{ + assertThrowAux<_ExceptionType>(_pointer != nullptr, _errorDescription, _line, _file, _function); +} + +} diff --git a/libdevcore/Base58.cpp b/libdevcore/Base58.cpp new file mode 100644 index 0000000000..943a6adf32 --- /dev/null +++ b/libdevcore/Base58.cpp @@ -0,0 +1,119 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Base58.cpp + * Adapted from code found on https://github.com/bitcoin/bitcoin/blob/master/src/base58.cpp + * Licenced under The MIT License. + * @author The Bitcoin core developers (original) + * @author Gav Wood (minor modifications and reformating) + * @date 2015 + */ + +#include "Base58.h" +using namespace std; +using namespace dev; + +std::string dev::AlphabetIPFS("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"); +std::string dev::AlphabetFlickr("123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ"); + +bytes dev::fromBase58(string const& _s, string const& _alphabet) +{ + auto index = _s.begin(); + + // Skip and count leading '1's. + int zeroes = 0; + while (*index == _alphabet[0]) + { + zeroes++; + index++; + } + + // Allocate enough space in big-endian base256 representation. + // log(58) / log(256), rounded up. + bytes ret((_s.size() - zeroes) * 733 / 1000 + 1); + + // Process the characters. + while (index != _s.end()) + { + // Decode base58 character + size_t carry = _alphabet.find(*index); + if (carry == string::npos) + throw invalid_argument("Invalid character in base-58 string"); + // Apply "ret = ret * 58 + ch". + for (auto it = ret.rbegin(); it != ret.rend(); it++) + { + carry += 58 * (*it); + *it = carry % 256; + carry /= 256; + } + assert(carry == 0); + index++; + } + + // Skip leading zeroes. + while (!ret.front()) + ret.erase(ret.begin()); + + // Re-insert zeroes. + for (int i = 0; i < zeroes; ++i) + ret.insert(ret.begin(), 0); + + return ret; +} + +string dev::toBase58(bytesConstRef _d, string const& _alphabet) +{ + auto begin = _d.data(); + auto end = _d.data() + _d.size(); + + // Skip & count leading zeroes. + int zeroes = 0; + for (; begin != end && !*begin; begin++, zeroes++) {} + + // Allocate enough space in big-endian base58 representation. + // log(256) / log(58), rounded up. + std::vector b58((end - begin) * 138 / 100 + 1); + + // Process the bytes. + while (begin != end) + { + int carry = *begin; + // Apply "b58 = b58 * 256 + ch". + for (auto it = b58.rbegin(); it != b58.rend(); it++) + { + carry += 256 * (*it); + *it = carry % 58; + carry /= 58; + } + assert(!carry); + begin++; + } + + // Skip leading zeroes in base58 result. + auto it = b58.begin(); + while (it != b58.end() && !*it) + it++; + + // Translate the result into a string. + std::string ret; + ret.reserve(zeroes + (b58.end() - it)); + ret.assign(zeroes, '1'); + while (it != b58.end()) + ret += _alphabet[*(it++)]; + + return ret; +} + diff --git a/libdevcore/Base58.h b/libdevcore/Base58.h new file mode 100644 index 0000000000..62ec7c51c7 --- /dev/null +++ b/libdevcore/Base58.h @@ -0,0 +1,39 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Base58.cpp + * Adapted from code found on https://github.com/bitcoin/bitcoin/blob/master/src/base58.cpp + * Licenced under The MIT License. + * @author The Bitcoin core developers (original) + * @author Gav Wood (minor modifications and reformating) + * @date 2015 + */ +#pragma once + +#include +#include "Common.h" +#include "FixedHash.h" + +namespace dev +{ + +extern std::string AlphabetIPFS; +extern std::string AlphabetFlickr; + +std::string toBase58(bytesConstRef _in, std::string const& _alphabet = AlphabetIPFS); +bytes fromBase58(std::string const& _in, std::string const& _alphabet = AlphabetIPFS); + +} diff --git a/libdevcore/Base64.cpp b/libdevcore/Base64.cpp new file mode 100644 index 0000000000..1496606697 --- /dev/null +++ b/libdevcore/Base64.cpp @@ -0,0 +1,146 @@ +/* + base64.cpp and base64.h + + Copyright (C) 2004-2008 René Nyffenegger + + This source code is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this source code must not be misrepresented; you must not + claim that you wrote the original source code. If you use this source code + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original source code. + + 3. This notice may not be removed or altered from any source distribution. + + René Nyffenegger rene.nyffenegger@adp-gmbh.ch +*/ +/// Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c +/// Originally by René Nyffenegger, modified by some other guy and then devified by Gav Wood. + +#include "Base64.h" + +using namespace std; +using namespace dev; + +static inline bool is_base64(byte c) +{ + return (isalnum(c) || (c == '+') || (c == '/')); +} + +static inline byte find_base64_char_index(byte c) +{ + if ('A' <= c && c <= 'Z') return c - 'A'; + else if ('a' <= c && c <= 'z') return c - 'a' + 1 + find_base64_char_index('Z'); + else if ('0' <= c && c <= '9') return c - '0' + 1 + find_base64_char_index('z'); + else if (c == '+') return 1 + find_base64_char_index('9'); + else if (c == '/') return 1 + find_base64_char_index('+'); + else return 1 + find_base64_char_index('/'); +} + +string dev::toBase64(bytesConstRef _in) +{ + static const char base64_chars[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"; + + string ret; + int i = 0; + int j = 0; + byte char_array_3[3]; + byte char_array_4[4]; + + auto buf = _in.data(); + auto bufLen = _in.size(); + + while (bufLen--) + { + char_array_3[i++] = *(buf++); + if (i == 3) + { + char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; + char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); + char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); + char_array_4[3] = char_array_3[2] & 0x3f; + + for (i = 0; i < 4; i++) + ret += base64_chars[char_array_4[i]]; + i = 0; + } + } + + if (i) + { + for (j = i; j < 3; j++) + char_array_3[j] = '\0'; + + char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; + char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); + char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); + char_array_4[3] = char_array_3[2] & 0x3f; + + for (j = 0; j < i + 1; j++) + ret += base64_chars[char_array_4[j]]; + + while (i++ < 3) + ret += '='; + } + + return ret; +} + +bytes dev::fromBase64(string const& encoded_string) +{ + auto in_len = encoded_string.size(); + int i = 0; + int j = 0; + int in_ = 0; + byte char_array_3[3]; + byte char_array_4[4]; + bytes ret; + + while (in_len-- && encoded_string[in_] != '=' && is_base64(encoded_string[in_])) + { + char_array_4[i++] = encoded_string[in_]; in_++; + if (i == 4) + { + for (i = 0; i < 4; i++) + char_array_4[i] = find_base64_char_index(char_array_4[i]); + + char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); + char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); + char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; + + for (i = 0; (i < 3); i++) + ret.push_back(char_array_3[i]); + i = 0; + } + } + + if (i) + { + for (j = i; j < 4; j++) + char_array_4[j] = 0; + + for (j = 0; j < 4; j++) + char_array_4[j] = find_base64_char_index(char_array_4[j]); + + char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); + char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); + char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; + + for (j = 0; j < i - 1; j++) + ret.push_back(char_array_3[j]); + } + + return ret; +} diff --git a/libdevcore/Base64.h b/libdevcore/Base64.h new file mode 100644 index 0000000000..6ef8be4983 --- /dev/null +++ b/libdevcore/Base64.h @@ -0,0 +1,62 @@ +/* + base64.cpp and base64.h + + Copyright (C) 2004-2008 René Nyffenegger + + This source code is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this source code must not be misrepresented; you must not + claim that you wrote the original source code. If you use this source code + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original source code. + + 3. This notice may not be removed or altered from any source distribution. + + René Nyffenegger rene.nyffenegger@adp-gmbh.ch +*/ +/// Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c +/// Originally by René Nyffenegger. +/// DEVified by Gav Wood. +#pragma once + +#include +#include "Common.h" +#include "FixedHash.h" + +namespace dev +{ + +std::string toBase64(bytesConstRef _in); +bytes fromBase64(std::string const& _in); + +template inline std::string toBase36(FixedHash const& _h) +{ + static char const* c_alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + typename FixedHash::Arith a = _h; + std::string ret; + for (; a > 0; a /= 36) + { + unsigned r = (unsigned)(a - a / 36 * 36); // boost's % is broken + ret = c_alphabet[r] + ret; + } + return ret; +} + +template inline FixedHash fromBase36(std::string const& _h) +{ + typename FixedHash::Arith ret = 0; + for (char c: _h) + ret = ret * 36 + (c < 'A' ? c - '0' : (c - 'A' + 10)); + return ret; +} + +} diff --git a/libdevcore/CMakeLists.txt b/libdevcore/CMakeLists.txt new file mode 100644 index 0000000000..d405ab08ac --- /dev/null +++ b/libdevcore/CMakeLists.txt @@ -0,0 +1,28 @@ +file(GLOB SRC_LIST "*.cpp") +file(GLOB HEADERS "*.h") + +add_library(devcore ${SRC_LIST} ${HEADERS}) + +target_include_directories(devcore PRIVATE ..) +target_include_directories(devcore SYSTEM PUBLIC ${BOOST_INCLUDE_DIR}) + +find_package(Eth) +include_directories(../libodbc/include + ../libodbc/include/db2_linux + ../libodbc/include/ibase + ../libodbc/include/infomix + ../libodbc/include/mysql + ../libodbc/include/odbc_linux + ../libodbc/include/pgsql + ../libodbc/include/sqlbase + ../libodbc/include/sqllite + ../libodbc/include/ss_linux + ../libodbc/include/sybase) + +add_dependencies(devcore BuildInfo.h) + +if (NOT EMSCRIPTEN) + find_package(LevelDB) + target_include_directories(devcore SYSTEM PUBLIC ${LEVELDB_INCLUDE_DIRS}) + target_link_libraries(devcore Boost::Filesystem Boost::Random Boost::Thread ${LEVELDB_LIBRARIES}) +endif() diff --git a/libdevcore/Common.cpp b/libdevcore/Common.cpp new file mode 100644 index 0000000000..13109d9c36 --- /dev/null +++ b/libdevcore/Common.cpp @@ -0,0 +1,107 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Common.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "Common.h" +#include "Exceptions.h" +#include "Log.h" +#include "BuildInfo.h" +using namespace std; +using namespace dev; + +namespace dev +{ + +char const* Version = ETH_PROJECT_VERSION; +char const* Copyright="By OpenDl (c) 2017."; + +const u256 Invalid256 = ~(u256)0; + +void InvariantChecker::checkInvariants(HasInvariants const* _this, char const* _fn, char const* _file, int _line, bool _pre) +{ + if (!_this->invariants()) + { + LOG(WARNING) << (_pre ? "Pre" : "Post") << "invariant failed in" << _fn << "at" << _file << ":" << _line; + ::boost::exception_detail::throw_exception_(FailedInvariant(), _fn, _file, _line); + } +} + +struct TimerChannel: public LogChannel { static const char* name(); static const int verbosity = 0; }; + +#if defined(_WIN32) +const char* TimerChannel::name() { return EthRed " ! "; } +#else +const char* TimerChannel::name() { return EthRed " ⚡ "; } +#endif + +TimerHelper::~TimerHelper() +{ + auto e = std::chrono::high_resolution_clock::now() - m_t; + if (!m_ms || e > chrono::milliseconds(m_ms)) + clog(TimerChannel) << m_id << chrono::duration_cast(e).count() << "ms"; +} + +uint64_t utcTime() +{ + struct timeval tv; + gettimeofday(&tv,NULL); + return tv.tv_sec * 1000 + tv.tv_usec / 1000; +} + +string inUnits(bigint const& _b, strings const& _units) +{ + ostringstream ret; + u256 b; + if (_b < 0) + { + ret << "-"; + b = (u256)-_b; + } + else + b = (u256)_b; + + u256 biggest = 1; + for (unsigned i = _units.size() - 1; !!i; --i) + biggest *= 1000; + + if (b > biggest * 1000) + { + ret << (b / biggest) << " " << _units.back(); + return ret.str(); + } + ret << setprecision(3); + + u256 unit = biggest; + for (auto it = _units.rbegin(); it != _units.rend(); ++it) + { + auto i = *it; + if (i != _units.front() && b >= unit) + { + ret << (double(b / (unit / 1000)) / 1000.0) << " " << i; + return ret.str(); + } + else + unit /= 1000; + } + ret << b << " " << _units.front(); + return ret.str(); +} + +} diff --git a/libdevcore/Common.h b/libdevcore/Common.h new file mode 100644 index 0000000000..5900cc5cee --- /dev/null +++ b/libdevcore/Common.h @@ -0,0 +1,385 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Common.h + * @author Gav Wood + * @date 2014 + * + * Very common stuff (i.e. that every other header needs except vector_ref.h). + */ + +#pragma once + +// way to many unsigned to size_t warnings in 32 bit build +#ifdef _M_IX86 +#pragma warning(disable:4244) +#endif + +#if _MSC_VER && _MSC_VER < 1900 +#define _ALLOW_KEYWORD_MACROS +#define noexcept throw() +#endif + +#ifdef __INTEL_COMPILER +#pragma warning(disable:3682) //call through incomplete class +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#pragma warning(push) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#include +#if (BOOST_VERSION == 105800) +#include "boost_multiprecision_number_compare_bug_workaround.hpp" +#endif +#include +#pragma warning(pop) +#pragma GCC diagnostic pop +#include "vector_ref.h" + +// CryptoPP defines byte in the global namespace, so must we. +using byte = uint8_t; + +// Quote a given token stream to turn it into a string. +#define DEV_QUOTED_HELPER(s) #s +#define DEV_QUOTED(s) DEV_QUOTED_HELPER(s) + +#define DEV_IGNORE_EXCEPTIONS(X) try { X; } catch (...) {} + +#define DEV_IF_NO_ELSE(X) if(!(X)){}else +#define DEV_IF_THROWS(X) try{X;}catch(...) + +namespace dev +{ + +extern char const* Version; +extern char const* Copyright; + +static const std::string EmptyString; + +// Binary data types. +using bytes = std::vector; +using bytesRef = vector_ref; +using bytesConstRef = vector_ref; + +template +class secure_vector +{ +public: + secure_vector() {} + secure_vector(secure_vector const& /*_c*/) = default; // See https://github.com/ethereum/libweb3core/pull/44 + explicit secure_vector(unsigned _size): m_data(_size) {} + explicit secure_vector(unsigned _size, T _item): m_data(_size, _item) {} + explicit secure_vector(std::vector const& _c): m_data(_c) {} + explicit secure_vector(vector_ref _c): m_data(_c.data(), _c.data() + _c.size()) {} + explicit secure_vector(vector_ref _c): m_data(_c.data(), _c.data() + _c.size()) {} + ~secure_vector() { ref().cleanse(); } + + secure_vector& operator=(secure_vector const& _c) + { + if (&_c == this) + return *this; + + ref().cleanse(); + m_data = _c.m_data; + return *this; + } + std::vector& writable() { clear(); return m_data; } + std::vector const& makeInsecure() const { return m_data; } + + void clear() { ref().cleanse(); } + + vector_ref ref() { return vector_ref(&m_data); } + vector_ref ref() const { return vector_ref(&m_data); } + + size_t size() const { return m_data.size(); } + bool empty() const { return m_data.empty(); } + + void swap(secure_vector& io_other) { m_data.swap(io_other.m_data); } + +private: + std::vector m_data; +}; + +using bytesSec = secure_vector; + +// Numeric types. +using bigint = boost::multiprecision::number>; +using u64 = boost::multiprecision::number>; +using u128 = boost::multiprecision::number>; +using u256 = boost::multiprecision::number>; +using s256 = boost::multiprecision::number>; +using u160 = boost::multiprecision::number>; +using s160 = boost::multiprecision::number>; +using u512 = boost::multiprecision::number>; +using s512 = boost::multiprecision::number>; +using u256s = std::vector; +using u160s = std::vector; +using u256Set = std::set; +using u160Set = std::set; + +// Map types. +using StringMap = std::map; +using BytesMap = std::map; +using u256Map = std::map; +using HexMap = std::map; + +// Hash types. +using StringHashMap = std::unordered_map; +using u256HashMap = std::unordered_map; + +// String types. +using strings = std::vector; + +// Fixed-length string types. +using string32 = std::array; +static const string32 ZeroString32 = {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }}; + +// Null/Invalid values for convenience. +static const bytes NullBytes; +static const std::map EmptyMapU256U256; +extern const u256 Invalid256; + +/// Interprets @a _u as a two's complement signed number and returns the resulting s256. +inline s256 u2s(u256 _u) +{ + static const bigint c_end = bigint(1) << 256; + if (boost::multiprecision::bit_test(_u, 255)) + return s256(-(c_end - _u)); + else + return s256(_u); +} + +/// @returns the two's complement signed representation of the signed number _u. +inline u256 s2u(s256 _u) +{ + static const bigint c_end = bigint(1) << 256; + if (_u >= 0) + return u256(_u); + else + return u256(c_end + _u); +} + +/// Converts given int to a string and appends one of a series of units according to its size. +std::string inUnits(bigint const& _b, strings const& _units); + +/// @returns the smallest n >= 0 such that (1 << n) >= _x +inline unsigned int toLog2(u256 _x) +{ + unsigned ret; + for (ret = 0; _x >>= 1; ++ret) {} + return ret; +} + +template inline u256 exp10() +{ + return exp10 < n - 1 > () * u256(10); +} + +template <> inline u256 exp10<0>() +{ + return u256(1); +} + +/// @returns the absolute distance between _a and _b. +template +inline N diff(N const& _a, N const& _b) +{ + return std::max(_a, _b) - std::min(_a, _b); +} + +/// RAII utility class whose destructor calls a given function. +class ScopeGuard +{ +public: + ScopeGuard(std::function _f): m_f(_f) {} + ~ScopeGuard() { m_f(); } + +private: + std::function m_f; +}; + +/// Inheritable for classes that have invariants. +class HasInvariants +{ +public: + /// Reimplement to specify the invariants. + virtual bool invariants() const = 0; +}; + +/// RAII checker for invariant assertions. +class InvariantChecker +{ +public: + InvariantChecker(HasInvariants* _this, char const* _fn, char const* _file, int _line): m_this(_this), m_function(_fn), m_file(_file), m_line(_line) { checkInvariants(_this, _fn , _file, _line, true); } + ~InvariantChecker() { checkInvariants(m_this, m_function, m_file, m_line, false); } + /// Check invariants are met, throw if not. + static void checkInvariants(HasInvariants const* _this, char const* _fn, char const* _file, int line, bool _pre); + +private: + HasInvariants const* m_this; + char const* m_function; + char const* m_file; + int m_line; +}; + +/// Scope guard for invariant check in a class derived from HasInvariants. +#if ETH_DEBUG +#define DEV_INVARIANT_CHECK ::dev::InvariantChecker __dev_invariantCheck(this, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__) +#define DEV_INVARIANT_CHECK_HERE ::dev::InvariantChecker::checkInvariants(this, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__, true) +#else +#define DEV_INVARIANT_CHECK (void)0; +#define DEV_INVARIANT_CHECK_HERE (void)0; +#endif + +/// Simple scope-based timer helper. +class TimerHelper +{ +public: + TimerHelper(std::string const& _id, unsigned _msReportWhenGreater = 0): m_t(std::chrono::high_resolution_clock::now()), m_id(_id), m_ms(_msReportWhenGreater) {} + ~TimerHelper(); + +private: + std::chrono::high_resolution_clock::time_point m_t; + std::string m_id; + unsigned m_ms; +}; + +class Timer +{ +public: + Timer() { restart(); } + + std::chrono::high_resolution_clock::duration duration() const { return std::chrono::high_resolution_clock::now() - m_t; } + double elapsed() const { return std::chrono::duration_cast(duration()).count() / 1000000.0; } + void restart() { m_t = std::chrono::high_resolution_clock::now(); } + +private: + std::chrono::high_resolution_clock::time_point m_t; +}; + +#define DEV_TIMED(S) for (::std::pair<::dev::TimerHelper, bool> __eth_t(S, true); __eth_t.second; __eth_t.second = false) +#define DEV_TIMED_SCOPE(S) ::dev::TimerHelper __eth_t(S) +#if defined(_WIN32) +#define DEV_TIMED_FUNCTION DEV_TIMED_SCOPE(__FUNCSIG__) +#else +#define DEV_TIMED_FUNCTION DEV_TIMED_SCOPE(__PRETTY_FUNCTION__) +#endif + +#define DEV_TIMED_ABOVE(S, MS) for (::std::pair<::dev::TimerHelper, bool> __eth_t(::dev::TimerHelper(S, MS), true); __eth_t.second; __eth_t.second = false) +#define DEV_TIMED_SCOPE_ABOVE(S, MS) ::dev::TimerHelper __eth_t(S, MS) +#if defined(_WIN32) +#define DEV_TIMED_FUNCTION_ABOVE(MS) DEV_TIMED_SCOPE_ABOVE(__FUNCSIG__, MS) +#else +#define DEV_TIMED_FUNCTION_ABOVE(MS) DEV_TIMED_SCOPE_ABOVE(__PRETTY_FUNCTION__, MS) +#endif + +#ifdef _MSC_VER +// TODO. +#define DEV_UNUSED +#else +#define DEV_UNUSED __attribute__((unused)) +#endif + +enum class WithExisting : int +{ + Trust = 0, + Verify, + Rescue, + Kill +}; + +/// Get the current time in seconds since the epoch in UTC +uint64_t utcTime(); + +template +class QueueSet { +public: + bool push(T const& _t) { + if (m_set.count(_t) == 0) { + m_set.insert(_t); + m_queue.push(_t); + return true; + } + return false; + } + + bool pop() { + if (m_queue.size() == 0) { + return false; + } + auto t = m_queue.front(); + m_queue.pop(); + m_set.erase(t); + return true; + } + + void insert(T const & _t) { + push(_t); + } + + size_t count(T const& _t) const { + return exist(_t) ? 1 : 0; + } + + bool exist(T const& _t) const { + return m_set.count(_t) > 0; + } + + size_t size() const { + return m_set.size(); + } + + void clear() { + m_set.clear(); + while (!m_queue.empty()) m_queue.pop(); + } + +private: + std::unordered_set m_set; + std::queue m_queue; +}; + +} + +namespace std +{ + +inline dev::WithExisting max(dev::WithExisting _a, dev::WithExisting _b) +{ + return static_cast(max(static_cast(_a), static_cast(_b))); +} + +template <> struct hash +{ + size_t operator()(dev::u256 const& _a) const + { + unsigned size = _a.backend().size(); + auto limbs = _a.backend().limbs(); + return boost::hash_range(limbs, limbs + size); + } +}; + +} diff --git a/libdevcore/CommonData.cpp b/libdevcore/CommonData.cpp new file mode 100644 index 0000000000..95c6779e15 --- /dev/null +++ b/libdevcore/CommonData.cpp @@ -0,0 +1,147 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file CommonData.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "CommonData.h" +#include + +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable:4724) // potential mod by 0, line 78 of boost/random/uniform_int_distribution.hpp (boost 1.55) +#endif +#include +#if defined(_MSC_VER) +#pragma warning(pop) +#endif +#include "Exceptions.h" +#include "Log.h" +using namespace std; +using namespace dev; + +namespace +{ +int fromHexChar(char _i) noexcept +{ + if (_i >= '0' && _i <= '9') + return _i - '0'; + if (_i >= 'a' && _i <= 'f') + return _i - 'a' + 10; + if (_i >= 'A' && _i <= 'F') + return _i - 'A' + 10; + return -1; +} +} + +bool dev::isHex(string const& _s) noexcept +{ + auto it = _s.begin(); + if (_s.compare(0, 2, "0x") == 0) + it += 2; + return std::all_of(it, _s.end(), [](char c){ return fromHexChar(c) != -1; }); +} + +std::string dev::escaped(std::string const& _s, bool _all) +{ + static const map prettyEscapes{{'\r', 'r'}, {'\n', 'n'}, {'\t', 't'}, {'\v', 'v'}}; + std::string ret; + ret.reserve(_s.size() + 2); + ret.push_back('"'); + for (auto i: _s) + if (i == '"' && !_all) + ret += "\\\""; + else if (i == '\\' && !_all) + ret += "\\\\"; + else if (prettyEscapes.count(i) && !_all) + { + ret += '\\'; + ret += prettyEscapes.find(i)->second; + } + else if (i < ' ' || _all) + { + ret += "\\x"; + ret.push_back("0123456789abcdef"[(uint8_t)i / 16]); + ret.push_back("0123456789abcdef"[(uint8_t)i % 16]); + } + else + ret.push_back(i); + ret.push_back('"'); + return ret; +} + +std::string dev::randomWord() +{ + static std::mt19937_64 s_eng(0); + std::string ret(boost::random::uniform_int_distribution(1, 5)(s_eng), ' '); + char const n[] = "qwertyuiop";//asdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890"; + boost::random::uniform_int_distribution d(0, sizeof(n) - 2); + for (char& c: ret) + c = n[d(s_eng)]; + return ret; +} + +bytes dev::fromHex(std::string const& _s, WhenError _throw) +{ + unsigned s = (_s.size() >= 2 && _s[0] == '0' && _s[1] == 'x') ? 2 : 0; + std::vector ret; + ret.reserve((_s.size() - s + 1) / 2); + + if (_s.size() % 2) + { + int h = fromHexChar(_s[s++]); + if (h != -1) + ret.push_back(h); + else if (_throw == WhenError::Throw) + BOOST_THROW_EXCEPTION(BadHexCharacter()); + else + return bytes(); + } + for (unsigned i = s; i < _s.size(); i += 2) + { + int h = fromHexChar(_s[i]); + int l = fromHexChar(_s[i + 1]); + if (h != -1 && l != -1) + ret.push_back((byte)(h * 16 + l)); + else if (_throw == WhenError::Throw) + BOOST_THROW_EXCEPTION(BadHexCharacter()); + else + return bytes(); + } + return ret; +} + +bytes dev::asNibbles(bytesConstRef const& _s) +{ + std::vector ret; + ret.reserve(_s.size() * 2); + for (auto i: _s) + { + ret.push_back(i / 16); + ret.push_back(i % 16); + } + return ret; +} + +std::string dev::toString(string32 const& _s) +{ + std::string ret; + for (unsigned i = 0; i < 32 && _s[i]; ++i) + ret.push_back(_s[i]); + return ret; +} diff --git a/libdevcore/CommonData.h b/libdevcore/CommonData.h new file mode 100644 index 0000000000..1a5b010fe3 --- /dev/null +++ b/libdevcore/CommonData.h @@ -0,0 +1,384 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file CommonData.h + * @author Gav Wood + * @date 2014 + * + * Shared algorithms and data types. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include "Common.h" + +namespace dev +{ + +// String conversion functions, mainly to/from hex/nibble/byte representations. + +enum class WhenError +{ + DontThrow = 0, + Throw = 1, +}; + +enum class HexPrefix +{ + DontAdd = 0, + Add = 1, +}; +/// Convert a series of bytes to the corresponding string of hex duplets. +/// @param _w specifies the width of the first of the elements. Defaults to two - enough to represent a byte. +/// @example toHex("A\x69") == "4169" +template +std::string toHex(T const& _data, int _w = 2, HexPrefix _prefix = HexPrefix::DontAdd) +{ + std::ostringstream ret; + unsigned ii = 0; + for (auto i: _data) + ret << std::hex << std::setfill('0') << std::setw(ii++ ? 2 : _w) << (int)(typename std::make_unsigned::type)i; + return (_prefix == HexPrefix::Add) ? "0x" + ret.str() : ret.str(); +} + +/// Converts a (printable) ASCII hex string into the corresponding byte stream. +/// @example fromHex("41626261") == asBytes("Abba") +/// If _throw = ThrowType::DontThrow, it replaces bad hex characters with 0's, otherwise it will throw an exception. +bytes fromHex(std::string const& _s, WhenError _throw = WhenError::DontThrow); + +/// @returns true if @a _s is a hex string. +bool isHex(std::string const& _s) noexcept; + +/// @returns true if @a _hash is a hash conforming to FixedHash type @a T. +template static bool isHash(std::string const& _hash) +{ + return (_hash.size() == T::size * 2 || (_hash.size() == T::size * 2 + 2 && _hash.substr(0, 2) == "0x")) && isHex(_hash); +} + +/// Converts byte array to a string containing the same (binary) data. Unless +/// the byte array happens to contain ASCII data, this won't be printable. +inline std::string asString(bytes const& _b) +{ + return std::string((char const*)_b.data(), (char const*)(_b.data() + _b.size())); +} + +/// Converts byte array ref to a string containing the same (binary) data. Unless +/// the byte array happens to contain ASCII data, this won't be printable. +inline std::string asString(bytesConstRef _b) +{ + return std::string((char const*)_b.data(), (char const*)(_b.data() + _b.size())); +} + +/// Converts a string to a byte array containing the string's (byte) data. +inline bytes asBytes(std::string const& _b) +{ + return bytes((byte const*)_b.data(), (byte const*)(_b.data() + _b.size())); +} + +/// Converts a string into the big-endian base-16 stream of integers (NOT ASCII). +/// @example asNibbles("A")[0] == 4 && asNibbles("A")[1] == 1 +bytes asNibbles(bytesConstRef const& _s); + + +// Big-endian to/from host endian conversion functions. + +/// Converts a templated integer value to the big-endian byte-stream represented on a templated collection. +/// The size of the collection object will be unchanged. If it is too small, it will not represent the +/// value properly, if too big then the additional elements will be zeroed out. +/// @a Out will typically be either std::string or bytes. +/// @a T will typically by unsigned, u160, u256 or bigint. +template +inline void toBigEndian(T _val, Out& o_out) +{ + static_assert(std::is_same::value || !std::numeric_limits::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift + for (auto i = o_out.size(); i != 0; _val >>= 8, i--) + { + T v = _val & (T)0xff; + o_out[i - 1] = (typename Out::value_type)(uint8_t)v; + } +} + +/// Converts a big-endian byte-stream represented on a templated collection to a templated integer value. +/// @a _In will typically be either std::string or bytes. +/// @a T will typically by unsigned, u160, u256 or bigint. +template +inline T fromBigEndian(_In const& _bytes) +{ + T ret = (T)0; + for (auto i: _bytes) + ret = (T)((ret << 8) | (byte)(typename std::make_unsigned::type)i); + return ret; +} + +/// Convenience functions for toBigEndian +inline std::string toBigEndianString(u256 _val) { std::string ret(32, '\0'); toBigEndian(_val, ret); return ret; } +inline std::string toBigEndianString(u160 _val) { std::string ret(20, '\0'); toBigEndian(_val, ret); return ret; } +inline bytes toBigEndian(u256 _val) { bytes ret(32); toBigEndian(_val, ret); return ret; } +inline bytes toBigEndian(u160 _val) { bytes ret(20); toBigEndian(_val, ret); return ret; } + +/// Convenience function for toBigEndian. +/// @returns a byte array just big enough to represent @a _val. +template +inline bytes toCompactBigEndian(T _val, unsigned _min = 0) +{ + static_assert(std::is_same::value || !std::numeric_limits::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift + int i = 0; + for (T v = _val; v; ++i, v >>= 8) {} + bytes ret(std::max(_min, i), 0); + toBigEndian(_val, ret); + return ret; +} +inline bytes toCompactBigEndian(byte _val, unsigned _min = 0) +{ + return (_min || _val) ? bytes{ _val } : bytes{}; +} + +/// Convenience function for toBigEndian. +/// @returns a string just big enough to represent @a _val. +template +inline std::string toCompactBigEndianString(T _val, unsigned _min = 0) +{ + static_assert(std::is_same::value || !std::numeric_limits::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift + int i = 0; + for (T v = _val; v; ++i, v >>= 8) {} + std::string ret(std::max(_min, i), '\0'); + toBigEndian(_val, ret); + return ret; +} + +/// Convenience function for conversion of a u256 to hex +inline std::string toHex(u256 val, HexPrefix prefix = HexPrefix::DontAdd) +{ + std::string str = toHex(toBigEndian(val)); + return (prefix == HexPrefix::Add) ? "0x" + str : str; +} + +inline std::string toCompactHex(u256 val, HexPrefix prefix = HexPrefix::DontAdd, unsigned _min = 0) +{ + std::string str = toHex(toCompactBigEndian(val, _min)); + return (prefix == HexPrefix::Add) ? "0x" + str : str; +} + +// Algorithms for string and string-like collections. + +/// Escapes a string into the C-string representation. +/// @p _all if true will escape all characters, not just the unprintable ones. +std::string escaped(std::string const& _s, bool _all = true); + +/// Determines the length of the common prefix of the two collections given. +/// @returns the number of elements both @a _t and @a _u share, in order, at the beginning. +/// @example commonPrefix("Hello world!", "Hello, world!") == 5 +template +unsigned commonPrefix(T const& _t, _U const& _u) +{ + unsigned s = std::min(_t.size(), _u.size()); + for (unsigned i = 0;; ++i) + if (i == s || _t[i] != _u[i]) + return i; + return s; +} + +/// Creates a random, printable, word. +std::string randomWord(); + +/// Determine bytes required to encode the given integer value. @returns 0 if @a _i is zero. +template +inline unsigned bytesRequired(T _i) +{ + static_assert(std::is_same::value || !std::numeric_limits::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift + unsigned i = 0; + for (; _i != 0; ++i, _i >>= 8) {} + return i; +} + +/// Trims a given number of elements from the front of a collection. +/// Only works for POD element types. +template +void trimFront(T& _t, unsigned _elements) +{ + static_assert(std::is_pod::value, ""); + memmove(_t.data(), _t.data() + _elements, (_t.size() - _elements) * sizeof(_t[0])); + _t.resize(_t.size() - _elements); +} + +/// Pushes an element on to the front of a collection. +/// Only works for POD element types. +template +void pushFront(T& _t, _U _e) +{ + static_assert(std::is_pod::value, ""); + _t.push_back(_e); + memmove(_t.data() + 1, _t.data(), (_t.size() - 1) * sizeof(_e)); + _t[0] = _e; +} + +/// Concatenate two vectors of elements of POD types. +template +inline std::vector& operator+=(std::vector::value, T>::type>& _a, std::vector const& _b) +{ + auto s = _a.size(); + _a.resize(_a.size() + _b.size()); + memcpy(_a.data() + s, _b.data(), _b.size() * sizeof(T)); + return _a; + +} + +/// Concatenate two vectors of elements. +template +inline std::vector& operator+=(std::vector::value, T>::type>& _a, std::vector const& _b) +{ + _a.reserve(_a.size() + _b.size()); + for (auto& i: _b) + _a.push_back(i); + return _a; +} + +/// Insert the contents of a container into a set +template std::set& operator+=(std::set& _a, U const& _b) +{ + for (auto const& i: _b) + _a.insert(i); + return _a; +} + +/// Insert the contents of a container into an unordered_set +template std::unordered_set& operator+=(std::unordered_set& _a, U const& _b) +{ + for (auto const& i: _b) + _a.insert(i); + return _a; +} + +/// Concatenate the contents of a container onto a vector +template std::vector& operator+=(std::vector& _a, U const& _b) +{ + for (auto const& i: _b) + _a.push_back(i); + return _a; +} + +/// Insert the contents of a container into a set +template std::set operator+(std::set _a, U const& _b) +{ + return _a += _b; +} + +/// Insert the contents of a container into an unordered_set +template std::unordered_set operator+(std::unordered_set _a, U const& _b) +{ + return _a += _b; +} + +/// Concatenate the contents of a container onto a vector +template std::vector operator+(std::vector _a, U const& _b) +{ + return _a += _b; +} + +/// Concatenate two vectors of elements. +template +inline std::vector operator+(std::vector const& _a, std::vector const& _b) +{ + std::vector ret(_a); + return ret += _b; +} + +/// Merge two sets of elements. +template +inline std::set& operator+=(std::set& _a, std::set const& _b) +{ + for (auto& i: _b) + _a.insert(i); + return _a; +} + +/// Merge two sets of elements. +template +inline std::set operator+(std::set const& _a, std::set const& _b) +{ + std::set ret(_a); + return ret += _b; +} + +template +std::unordered_map& operator+=(std::unordered_map& _x, std::unordered_map const& _y) +{ + for (auto const& i: _y) + _x.insert(i); + return _x; +} + +template +std::unordered_map operator+(std::unordered_map const& _x, std::unordered_map const& _y) +{ + std::unordered_map ret(_x); + return ret += _y; +} + +/// Make normal string from fixed-length string. +std::string toString(string32 const& _s); + +template +std::vector keysOf(std::map const& _m) +{ + std::vector ret; + for (auto const& i: _m) + ret.push_back(i.first); + return ret; +} + +template +std::vector keysOf(std::unordered_map const& _m) +{ + std::vector ret; + for (auto const& i: _m) + ret.push_back(i.first); + return ret; +} + +template +std::vector valuesOf(std::map const& _m) +{ + std::vector ret; + ret.reserve(_m.size()); + for (auto const& i: _m) + ret.push_back(i.second); + return ret; +} + +template +std::vector valuesOf(std::unordered_map const& _m) +{ + std::vector ret; + ret.reserve(_m.size()); + for (auto const& i: _m) + ret.push_back(i.second); + return ret; +} + +template +bool contains(T const& _t, V const& _v) +{ + return std::end(_t) != std::find(std::begin(_t), std::end(_t), _v); +} + +} diff --git a/libdevcore/CommonIO.cpp b/libdevcore/CommonIO.cpp new file mode 100644 index 0000000000..d5657c8f90 --- /dev/null +++ b/libdevcore/CommonIO.cpp @@ -0,0 +1,206 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file CommonIO.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "CommonIO.h" +#include +#include +#include +#include +#if defined(_WIN32) +#include +#else +#include +#endif +#include +#include "Exceptions.h" +using namespace std; +using namespace dev; + +string dev::memDump(bytes const& _bytes, unsigned _width, bool _html) +{ + stringstream ret; + if (_html) + ret << "
";
+	for (unsigned i = 0; i < _bytes.size(); i += _width)
+	{
+		ret << hex << setw(4) << setfill('0') << i << " ";
+		for (unsigned j = i; j < i + _width; ++j)
+			if (j < _bytes.size())
+				if (_bytes[j] >= 32 && _bytes[j] < 127)
+					if ((char)_bytes[j] == '<' && _html)
+						ret << "<";
+					else if ((char)_bytes[j] == '&' && _html)
+						ret << "&";
+					else
+						ret << (char)_bytes[j];
+				else
+					ret << '?';
+			else
+				ret << ' ';
+		ret << " ";
+		for (unsigned j = i; j < i + _width && j < _bytes.size(); ++j)
+			ret << setfill('0') << setw(2) << hex << (unsigned)_bytes[j] << " ";
+		ret << "\n";
+	}
+	if (_html)
+		ret << "
"; + return ret.str(); +} + +template +inline _T contentsGeneric(std::string const& _file) +{ + _T ret; + size_t const c_elementSize = sizeof(typename _T::value_type); + std::ifstream is(_file, std::ifstream::binary); + if (!is) + return ret; + + // get length of file: + is.seekg(0, is.end); + streamoff length = is.tellg(); + if (length == 0) + return ret; // do not read empty file (MSVC does not like it) + is.seekg(0, is.beg); + + ret.resize((length + c_elementSize - 1) / c_elementSize); + is.read(const_cast(reinterpret_cast(ret.data())), length); + return ret; +} + +bytes dev::contents(string const& _file) +{ + return contentsGeneric(_file); +} + +bytesSec dev::contentsSec(string const& _file) +{ + bytes b = contentsGeneric(_file); + bytesSec ret(b); + bytesRef(&b).cleanse(); + return ret; +} + +string dev::contentsString(string const& _file) +{ + return contentsGeneric(_file); +} + +void dev::writeFile(std::string const& _file, bytesConstRef _data, bool _writeDeleteRename) +{ + namespace fs = boost::filesystem; + if (_writeDeleteRename) + { + fs::path tempPath = fs::unique_path(_file + "-%%%%%%"); + writeFile(tempPath.string(), _data, false); + // will delete _file if it exists + fs::rename(tempPath, _file); + } + else + { + // create directory if not existent + fs::path p(_file); + if (!fs::exists(p.parent_path())) + { + fs::create_directories(p.parent_path()); + DEV_IGNORE_EXCEPTIONS(fs::permissions(p.parent_path(), fs::owner_all)); + } + + ofstream s(_file, ios::trunc | ios::binary); + s.write(reinterpret_cast(_data.data()), _data.size()); + if (!s) + BOOST_THROW_EXCEPTION(FileError() << errinfo_comment("Could not write to file: " + _file)); + DEV_IGNORE_EXCEPTIONS(fs::permissions(_file, fs::owner_read|fs::owner_write)); + } +} + + + +//追加内容到文件 +void dev::appendFile(std::string const& _file, bytesConstRef _data) +{ + namespace fs = boost::filesystem; + + // create directory if not existent + fs::path p(_file); + if (!fs::exists(p.parent_path())) + { + fs::create_directories(p.parent_path()); + DEV_IGNORE_EXCEPTIONS(fs::permissions(p.parent_path(), fs::owner_all)); + } + + ofstream s(_file, ios::app | ios::binary); + s.write(reinterpret_cast(_data.data()), _data.size()); + if (!s) + BOOST_THROW_EXCEPTION(FileError() << errinfo_comment("Could not append write to file: " + _file)); + DEV_IGNORE_EXCEPTIONS(fs::permissions(_file, fs::owner_read|fs::owner_write)); + +} + +std::string dev::getPassword(std::string const& _prompt) +{ +#if defined(_WIN32) + cout << _prompt << flush; + // Get current Console input flags + HANDLE hStdin; + DWORD fdwSaveOldMode; + if ((hStdin = GetStdHandle(STD_INPUT_HANDLE)) == INVALID_HANDLE_VALUE) + BOOST_THROW_EXCEPTION(ExternalFunctionFailure("GetStdHandle")); + if (!GetConsoleMode(hStdin, &fdwSaveOldMode)) + BOOST_THROW_EXCEPTION(ExternalFunctionFailure("GetConsoleMode")); + // Set console flags to no echo + if (!SetConsoleMode(hStdin, fdwSaveOldMode & (~ENABLE_ECHO_INPUT))) + BOOST_THROW_EXCEPTION(ExternalFunctionFailure("SetConsoleMode")); + // Read the string + std::string ret; + std::getline(cin, ret); + // Restore old input mode + if (!SetConsoleMode(hStdin, fdwSaveOldMode)) + BOOST_THROW_EXCEPTION(ExternalFunctionFailure("SetConsoleMode")); + return ret; +#else + + struct termios oflags; + struct termios nflags; + char password[256]; + + // disable echo in the terminal + tcgetattr(fileno(stdin), &oflags); + nflags = oflags; + nflags.c_lflag &= ~ECHO; + nflags.c_lflag |= ECHONL; + + if (tcsetattr(fileno(stdin), TCSANOW, &nflags) != 0) + BOOST_THROW_EXCEPTION(ExternalFunctionFailure("tcsetattr")); + + printf("%s", _prompt.c_str()); + if (!fgets(password, sizeof(password), stdin)) + BOOST_THROW_EXCEPTION(ExternalFunctionFailure("fgets")); + password[strlen(password) - 1] = 0; + + // restore terminal + if (tcsetattr(fileno(stdin), TCSANOW, &oflags) != 0) + BOOST_THROW_EXCEPTION(ExternalFunctionFailure("tcsetattr")); + + + return password; +#endif +} diff --git a/libdevcore/CommonIO.h b/libdevcore/CommonIO.h new file mode 100644 index 0000000000..95f9f6e466 --- /dev/null +++ b/libdevcore/CommonIO.h @@ -0,0 +1,275 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file CommonIO.h + * @author Gav Wood + * @date 2014 + * + * File & stream I/O routines. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Common.h" +#include "Base64.h" + +namespace dev +{ + +/// Requests the user to enter a password on the console. +std::string getPassword(std::string const& _prompt); + +/// Retrieve and returns the contents of the given file. +/// If the file doesn't exist or isn't readable, returns an empty container / bytes. +bytes contents(std::string const& _file); +/// Secure variation. +bytesSec contentsSec(std::string const& _file); +/// Retrieve and returns the contents of the given file as a std::string. +/// If the file doesn't exist or isn't readable, returns an empty container / bytes. +std::string contentsString(std::string const& _file); +/// Retrieve and returns the allocated contents of the given file; if @_dest is given, don't allocate, use it directly. +/// If the file doesn't exist or isn't readable, returns bytesRef(). Don't forget to delete [] the returned value's data when finished. +bytesRef contentsNew(std::string const& _file, bytesRef _dest = bytesRef()); + +/// Write the given binary data into the given file, replacing the file if it pre-exists. +/// Throws exception on error. +/// @param _writeDeleteRename useful not to lose any data: If set, first writes to another file in +/// the same directory and then moves that file. +void writeFile(std::string const& _file, bytesConstRef _data, bool _writeDeleteRename = false); +/// Write the given binary data into the given file, replacing the file if it pre-exists. +inline void writeFile(std::string const& _file, bytes const& _data, bool _writeDeleteRename = false) { writeFile(_file, bytesConstRef(&_data), _writeDeleteRename); } +inline void writeFile(std::string const& _file, std::string const& _data, bool _writeDeleteRename = false) { writeFile(_file, bytesConstRef(_data), _writeDeleteRename); } + + +void appendFile(std::string const& _file, bytesConstRef _data); +inline void appendFile(std::string const& _file, std::string const& _data) { appendFile(_file, bytesConstRef(_data)); } + + +/// Nicely renders the given bytes to a string, optionally as HTML. +/// @a _bytes: bytes array to be rendered as string. @a _width of a bytes line. +std::string memDump(bytes const& _bytes, unsigned _width = 8, bool _html = false); + +// Stream I/O functions. +// Provides templated stream I/O for all STL collections so they can be shifted on to any iostream-like interface. + +template struct StreamOut { static S& bypass(S& _out, T const& _t) { _out << _t; return _out; } }; +template struct StreamOut { static S& bypass(S& _out, uint8_t const& _t) { _out << (int)_t; return _out; } }; + +template inline std::ostream& operator<<(std::ostream& _out, std::vector const& _e); +template inline std::ostream& operator<<(std::ostream& _out, std::array const& _e); +template inline std::ostream& operator<<(std::ostream& _out, std::pair const& _e); +template inline std::ostream& operator<<(std::ostream& _out, std::list const& _e); +template inline std::ostream& operator<<(std::ostream& _out, std::tuple const& _e); +template inline std::ostream& operator<<(std::ostream& _out, std::map const& _e); +template inline std::ostream& operator<<(std::ostream& _out, std::unordered_map const& _e); +template inline std::ostream& operator<<(std::ostream& _out, std::set const& _e); +template inline std::ostream& operator<<(std::ostream& _out, std::unordered_set const& _e); +template inline std::ostream& operator<<(std::ostream& _out, std::multimap const& _e); +template _S& operator<<(_S& _out, std::shared_ptr<_T> const& _p); + +#if defined(_WIN32) +template inline std::string toString(std::chrono::time_point const& _e, std::string _format = "%Y-%m-%d %H:%M:%S") +#else +template inline std::string toString(std::chrono::time_point const& _e, std::string _format = "%F %T") +#endif +{ + unsigned long milliSecondsSinceEpoch = std::chrono::duration_cast(_e.time_since_epoch()).count(); + auto const durationSinceEpoch = std::chrono::milliseconds(milliSecondsSinceEpoch); + std::chrono::time_point const tpAfterDuration(durationSinceEpoch); + + tm timeValue; + auto time = std::chrono::system_clock::to_time_t(tpAfterDuration); +#if defined(_WIN32) + gmtime_s(&timeValue, &time); +#else + gmtime_r(&time, &timeValue); +#endif + + unsigned const millisRemainder = milliSecondsSinceEpoch % 1000; + char buffer[1024]; + if (strftime(buffer, sizeof(buffer), _format.c_str(), &timeValue)) + return std::string(buffer) + "." + (millisRemainder < 1 ? "000" : millisRemainder < 10 ? "00" : millisRemainder < 100 ? "0" : "") + std::to_string(millisRemainder) + "Z"; + return std::string(); +} + +template +inline S& streamout(S& _out, std::vector const& _e) +{ + _out << "["; + if (!_e.empty()) + { + StreamOut::bypass(_out, _e.front()); + for (auto i = ++_e.begin(); i != _e.end(); ++i) + StreamOut::bypass(_out << ",", *i); + } + _out << "]"; + return _out; +} + +template inline std::ostream& operator<<(std::ostream& _out, std::vector const& _e) { streamout(_out, _e); return _out; } + +template +inline S& streamout(S& _out, std::array const& _e) +{ + _out << "["; + if (!_e.empty()) + { + StreamOut::bypass(_out, _e.front()); + auto i = _e.begin(); + for (++i; i != _e.end(); ++i) + StreamOut::bypass(_out << ",", *i); + } + _out << "]"; + return _out; +} +template inline std::ostream& operator<<(std::ostream& _out, std::array const& _e) { streamout(_out, _e); return _out; } + +template +inline S& streamout(S& _out, std::list const& _e) +{ + _out << "["; + if (!_e.empty()) + { + _out << _e.front(); + for (auto i = ++_e.begin(); i != _e.end(); ++i) + _out << "," << *i; + } + _out << "]"; + return _out; +} +template inline std::ostream& operator<<(std::ostream& _out, std::list const& _e) { streamout(_out, _e); return _out; } + +template +inline S& streamout(S& _out, std::pair const& _e) +{ + _out << "(" << _e.first << "," << _e.second << ")"; + return _out; +} +template inline std::ostream& operator<<(std::ostream& _out, std::pair const& _e) { streamout(_out, _e); return _out; } + +template +inline S& streamout(S& _out, std::tuple const& _t) +{ + _out << "(" << std::get<0>(_t) << "," << std::get<1>(_t) << "," << std::get<2>(_t) << ")"; + return _out; +} +template inline std::ostream& operator<<(std::ostream& _out, std::tuple const& _e) { streamout(_out, _e); return _out; } + +template +S& streamout(S& _out, std::map const& _v) +{ + if (_v.empty()) + return _out << "{}"; + int i = 0; + for (auto p: _v) + _out << (!(i++) ? "{ " : "; ") << p.first << " => " << p.second; + return _out << " }"; +} +template inline std::ostream& operator<<(std::ostream& _out, std::map const& _e) { streamout(_out, _e); return _out; } + +template +S& streamout(S& _out, std::unordered_map const& _v) +{ + if (_v.empty()) + return _out << "{}"; + int i = 0; + for (auto p: _v) + _out << (!(i++) ? "{ " : "; ") << p.first << " => " << p.second; + return _out << " }"; +} +template inline std::ostream& operator<<(std::ostream& _out, std::unordered_map const& _e) { streamout(_out, _e); return _out; } + +template +S& streamout(S& _out, std::set const& _v) +{ + if (_v.empty()) + return _out << "{}"; + int i = 0; + for (auto p: _v) + _out << (!(i++) ? "{ " : ", ") << p; + return _out << " }"; +} +template inline std::ostream& operator<<(std::ostream& _out, std::set const& _e) { streamout(_out, _e); return _out; } + +template +S& streamout(S& _out, std::unordered_set const& _v) +{ + if (_v.empty()) + return _out << "{}"; + int i = 0; + for (auto p: _v) + _out << (!(i++) ? "{ " : ", ") << p; + return _out << " }"; +} +template inline std::ostream& operator<<(std::ostream& _out, std::unordered_set const& _e) { streamout(_out, _e); return _out; } + +template +S& streamout(S& _out, std::multiset const& _v) +{ + if (_v.empty()) + return _out << "{}"; + int i = 0; + for (auto p: _v) + _out << (!(i++) ? "{ " : ", ") << p; + return _out << " }"; +} +template inline std::ostream& operator<<(std::ostream& _out, std::multiset const& _e) { streamout(_out, _e); return _out; } + +template +S& streamout(S& _out, std::multimap const& _v) +{ + if (_v.empty()) + return _out << "{}"; + T l; + int i = 0; + for (auto p: _v) + if (!(i++)) + _out << "{ " << (l = p.first) << " => " << p.second; + else if (l == p.first) + _out << ", " << p.second; + else + _out << "; " << (l = p.first) << " => " << p.second; + return _out << " }"; +} +template inline std::ostream& operator<<(std::ostream& _out, std::multimap const& _e) { streamout(_out, _e); return _out; } + +template _S& operator<<(_S& _out, std::shared_ptr<_T> const& _p) { if (_p) _out << "@" << (*_p); else _out << "nullptr"; return _out; } + +// Functions that use streaming stuff. + +/// Converts arbitrary value to string representation using std::stringstream. +template +std::string toString(_T const& _t) +{ + std::ostringstream o; + o << _t; + return o.str(); +} + +} diff --git a/libdevcore/CommonJS.cpp b/libdevcore/CommonJS.cpp new file mode 100644 index 0000000000..7a8d40fa24 --- /dev/null +++ b/libdevcore/CommonJS.cpp @@ -0,0 +1,100 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file CommonJS.cpp + * @authors: + * Gav Wood + * Marek Kotewicz + * @date 2014 + */ + +#include "CommonJS.h" + +using namespace std; + +namespace dev +{ + +bytes jsToBytes(string const& _s, OnFailed _f) +{ + try + { + return fromHex(_s, WhenError::Throw); + } + catch (...) + { + if (_f == OnFailed::InterpretRaw) + return asBytes(_s); + else if (_f == OnFailed::Throw) + throw invalid_argument("Cannot intepret '" + _s + "' as bytes; must be 0x-prefixed hex or decimal."); + } + return bytes(); +} + +bytes padded(bytes _b, unsigned _l) +{ + while (_b.size() < _l) + _b.insert(_b.begin(), 0); + return asBytes(asString(_b).substr(_b.size() - max(_l, _l))); +} + +bytes paddedRight(bytes _b, unsigned _l) +{ + _b.resize(_l); + return _b; +} + +bytes unpadded(bytes _b) +{ + auto p = asString(_b).find_last_not_of((char)0); + _b.resize(p == string::npos ? 0 : (p + 1)); + return _b; +} + +bytes unpadLeft(bytes _b) +{ + unsigned int i = 0; + if (_b.size() == 0) + return _b; + + while (i < _b.size() && _b[i] == byte(0)) + i++; + + if (i != 0) + _b.erase(_b.begin(), _b.begin() + i); + return _b; +} + +string fromRaw(h256 _n) +{ + if (_n) + { + string s((char const*)_n.data(), 32); + auto l = s.find_first_of('\0'); + if (!l) + return ""; + if (l != string::npos) + s.resize(l); + for (auto i: s) + if (i < 32) + return ""; + return s; + } + return ""; +} + +} + diff --git a/libdevcore/CommonJS.h b/libdevcore/CommonJS.h new file mode 100644 index 0000000000..a0dbe6d5f1 --- /dev/null +++ b/libdevcore/CommonJS.h @@ -0,0 +1,127 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file CommonJS.h + * @authors: + * Gav Wood + * Marek Kotewicz + * @date 2014 + */ + +#pragma once + +#include +#include "FixedHash.h" +#include "CommonData.h" +#include "CommonIO.h" + +namespace dev +{ + +template std::string toJS(FixedHash const& _h) +{ + return "0x" + toHex(_h.ref()); +} + +template std::string toJS(boost::multiprecision::number> const& _n) +{ + std::string h = toHex(toCompactBigEndian(_n, 1)); + // remove first 0, if it is necessary; + std::string res = h[0] != '0' ? h : h.substr(1); + return "0x" + res; +} + +inline std::string toJS(bytes const& _n, std::size_t _padding = 0) +{ + bytes n = _n; + n.resize(std::max(n.size(), _padding)); + return "0x" + toHex(n); +} + +template std::string toJS(SecureFixedHash const& _i) +{ + std::stringstream stream; + stream << "0x" << _i.makeInsecure().hex(); + return stream.str(); +} + +template std::string toJS(T const& _i) +{ + std::stringstream stream; + stream << "0x" << std::hex << _i; + return stream.str(); +} + +enum class OnFailed { InterpretRaw, Empty, Throw }; + +/// Convert string to byte array. Input parameter is hex, optionally prefixed by "0x". +/// Returns empty array if invalid input. +bytes jsToBytes(std::string const& _s, OnFailed _f = OnFailed::Empty); +/// Add '0' on, or remove items from, the front of @a _b until it is of length @a _l. +bytes padded(bytes _b, unsigned _l); +/// Add '0' on, or remove items from, the back of @a _b until it is of length @a _l. +bytes paddedRight(bytes _b, unsigned _l); +/// Removing all trailing '0'. Returns empty array if input contains only '0' char. +bytes unpadded(bytes _s); +/// Remove all 0 byte on the head of @a _s. +bytes unpadLeft(bytes _s); +/// Convert h256 into user-readable string (by directly using std::string constructor). If it can't be interpreted as an ASCII string, empty string is returned. +std::string fromRaw(h256 _n); + +template FixedHash jsToFixed(std::string const& _s) +{ + if (_s.substr(0, 2) == "0x") + // Hex + return FixedHash(_s.substr(2 + std::max(N * 2, _s.size() - 2) - N * 2)); + else if (_s.find_first_not_of("0123456789") == std::string::npos) + // Decimal + return (typename FixedHash::Arith)(_s); + else + // Binary + return FixedHash(); // FAIL +} + +template boost::multiprecision::number> jsToInt(std::string const& _s) +{ + if (_s.substr(0, 2) == "0x") + // Hex + return fromBigEndian>>(fromHex(_s.substr(2))); + else if (_s.find_first_not_of("0123456789") == std::string::npos) + // Decimal + return boost::multiprecision::number>(_s); + else + // Binary + return 0; // FAIL +} + +inline u256 jsToU256(std::string const& _s) { return jsToInt<32>(_s); } + +/// Convert a string representation of a number to an int +/// String can be a normal decimal number, or a hex prefixed by 0x or 0X, or an octal if prefixed by 0 +/// Returns 0 in case of failure +inline int jsToInt(std::string const& _s) +{ + int ret = 0; + DEV_IGNORE_EXCEPTIONS(ret = std::stoi(_s, nullptr, 0)); + return ret; +} + +inline std::string jsToDecimal(std::string const& _s) +{ + return toString(jsToU256(_s)); +} + +} diff --git a/libdevcore/Exceptions.h b/libdevcore/Exceptions.h new file mode 100644 index 0000000000..e724f0d31d --- /dev/null +++ b/libdevcore/Exceptions.h @@ -0,0 +1,87 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Exceptions.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include "CommonData.h" +#include "FixedHash.h" + +namespace dev +{ + +/// Base class for all exceptions. +struct Exception: virtual std::exception, virtual boost::exception +{ + Exception(std::string _message = std::string()): m_message(std::move(_message)) {} + const char* what() const noexcept override { return m_message.empty() ? std::exception::what() : m_message.c_str(); } + +private: + std::string m_message; +}; + +#define DEV_SIMPLE_EXCEPTION(X) struct X: virtual Exception { const char* what() const noexcept override { return #X; } } + +/// Base class for all RLP exceptions. +struct RLPException: virtual Exception { RLPException(std::string _message = std::string()): Exception(_message) {} }; +#define DEV_SIMPLE_EXCEPTION_RLP(X) struct X: virtual RLPException { const char* what() const noexcept override { return #X; } } + +DEV_SIMPLE_EXCEPTION_RLP(BadCast); +DEV_SIMPLE_EXCEPTION_RLP(BadRLP); +DEV_SIMPLE_EXCEPTION_RLP(OversizeRLP); +DEV_SIMPLE_EXCEPTION_RLP(UndersizeRLP); + +DEV_SIMPLE_EXCEPTION(BadHexCharacter); +DEV_SIMPLE_EXCEPTION(NoNetworking); +DEV_SIMPLE_EXCEPTION(NoUPnPDevice); +DEV_SIMPLE_EXCEPTION(RootNotFound); +struct BadRoot: virtual Exception { public: BadRoot(h256 const& _root): Exception("BadRoot " + _root.hex()), root(_root) {} h256 root; }; +DEV_SIMPLE_EXCEPTION(FileError); +DEV_SIMPLE_EXCEPTION(Overflow); +DEV_SIMPLE_EXCEPTION(FailedInvariant); +DEV_SIMPLE_EXCEPTION(ValueTooLarge); + +struct InterfaceNotSupported: virtual Exception { public: InterfaceNotSupported(std::string _f): Exception("Interface " + _f + " not supported.") {} }; +struct ExternalFunctionFailure: virtual Exception { public: ExternalFunctionFailure(std::string _f): Exception("Function " + _f + "() failed.") {} }; + +// error information to be added to exceptions +using errinfo_invalidSymbol = boost::error_info; +using errinfo_wrongAddress = boost::error_info; +using errinfo_comment = boost::error_info; +using errinfo_required = boost::error_info; +using errinfo_got = boost::error_info; +using errinfo_min = boost::error_info; +using errinfo_max = boost::error_info; +using RequirementError = boost::tuple; +using errinfo_hash256 = boost::error_info; +using errinfo_required_h256 = boost::error_info; +using errinfo_got_h256 = boost::error_info; +using Hash256RequirementError = boost::tuple; +using errinfo_extraData = boost::error_info; + +} diff --git a/libdevcore/FileSystem.cpp b/libdevcore/FileSystem.cpp new file mode 100644 index 0000000000..e34f55f996 --- /dev/null +++ b/libdevcore/FileSystem.cpp @@ -0,0 +1,149 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file FileSystem.cpp + * @authors + * Eric Lombrozo + * Gav Wood + * @date 2014 + */ + +#include "FileSystem.h" +#include "Common.h" +#include "Log.h" + +#if defined(_WIN32) +#include +#else +#include +#include +#include +#include +#endif +#include +using namespace std; +using namespace dev; + +//TODO: remove init_priority, use a better way. +// Should be written to only once during startup +//ubuntu 编过 +//static string s_ethereumDatadir; +static string s_ethereumDatadir __attribute__ ((init_priority (1000))); //centos + +static string s_ethereumIpcPath; +static string s_ehtereumConfigPath; +static string s_caInitType; + +void dev::setDataDir(string const& _dataDir) +{ + s_ethereumDatadir = _dataDir; +} + +void dev::setIpcPath(string const& _ipcDir) +{ + s_ethereumIpcPath = _ipcDir; +} + +void dev::setConfigPath(string const& _configPath) +{ + s_ehtereumConfigPath = _configPath; +} + +void dev::setCaInitType(string const& _caInitType) +{ + s_caInitType = _caInitType; +} + +string dev::getCaInitType() +{ + if (s_caInitType.empty()) + { + return "webank"; + } + + return s_caInitType; +} + +string dev::getConfigPath() +{ + if (s_ehtereumConfigPath.empty()) + { + return getDataDir() + "/config.json"; + } + + return s_ehtereumConfigPath; +} + +string dev::getIpcPath() +{ + if (s_ethereumIpcPath.empty()) + return string(getDataDir()); + else + { + size_t socketPos = s_ethereumIpcPath.rfind("geth.ipc"); + if (socketPos != string::npos) + return s_ethereumIpcPath.substr(0, socketPos); + return s_ethereumIpcPath; + } +} + +string dev::getDataDir(string _prefix) +{ + if (_prefix.empty()) + _prefix = "ethereum"; + if (_prefix == "ethereum" && !s_ethereumDatadir.empty()) + return s_ethereumDatadir; + if (_prefix == "web3" && !s_ethereumDatadir.empty()) + return s_ethereumDatadir+".web3"; + + return getDefaultDataDir(_prefix); +} + +string dev::getDefaultDataDir(string _prefix) +{ + if (_prefix.empty()) + _prefix = "ethereum"; + +#if defined(_WIN32) + _prefix[0] = toupper(_prefix[0]); + char path[1024] = ""; + if (SHGetSpecialFolderPathA(NULL, path, CSIDL_APPDATA, true)) + return (boost::filesystem::path(path) / _prefix).string(); + else + { + #ifndef _MSC_VER // todo? + LOG(WARNING) << "getDataDir(): SHGetSpecialFolderPathA() failed."; + #endif + BOOST_THROW_EXCEPTION(std::runtime_error("getDataDir() - SHGetSpecialFolderPathA() failed.")); + } +#else + boost::filesystem::path dataDirPath; + char const* homeDir = getenv("HOME"); + if (!homeDir || strlen(homeDir) == 0) + { + struct passwd* pwd = getpwuid(getuid()); + if (pwd) + homeDir = pwd->pw_dir; + } + + if (!homeDir || strlen(homeDir) == 0) + dataDirPath = boost::filesystem::path("/"); + else + dataDirPath = boost::filesystem::path(homeDir); + + return (dataDirPath / ("." + _prefix)).string(); +#endif +} diff --git a/libdevcore/FileSystem.h b/libdevcore/FileSystem.h new file mode 100644 index 0000000000..52e9beb9b4 --- /dev/null +++ b/libdevcore/FileSystem.h @@ -0,0 +1,50 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file FileSystem.h + * @authors + * Eric Lombrozo + * Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include "CommonIO.h" + +namespace dev +{ + +/// Sets the data dir for the default ("ethereum") prefix. +void setDataDir(std::string const& _dir); +/// @returns the path for user data. +std::string getDataDir(std::string _prefix = "ethereum"); +/// @returns the default path for user data, ignoring the one set by `setDataDir`. +std::string getDefaultDataDir(std::string _prefix = "ethereum"); +/// Sets the ipc socket dir +void setIpcPath(std::string const& _ipcPath); +/// @returns the ipc path (default is DataDir) +std::string getIpcPath(); + +void setConfigPath(std::string const& _configPath); + +std::string getConfigPath(); + +void setCaInitType(std::string const& _caInitType = "webank"); + +std::string getCaInitType(); +} diff --git a/libdevcore/FixedHash.cpp b/libdevcore/FixedHash.cpp new file mode 100644 index 0000000000..b1b17f1b9d --- /dev/null +++ b/libdevcore/FixedHash.cpp @@ -0,0 +1,50 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file FixedHash.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "FixedHash.h" +#include +#include + +using namespace std; +using namespace dev; + +boost::random_device dev::s_fixedHashEngine; + +h128 dev::fromUUID(std::string const& _uuid) +{ + try + { + return h128(boost::replace_all_copy(_uuid, "-", "")); + } + catch (...) + { + return h128(); + } +} + +std::string dev::toUUID(h128 const& _uuid) +{ + std::string ret = toHex(_uuid.ref()); + for (unsigned i: {20, 16, 12, 8}) + ret.insert(ret.begin() + i, '-'); + return ret; +} + diff --git a/libdevcore/FixedHash.h b/libdevcore/FixedHash.h new file mode 100644 index 0000000000..9b12ba5f42 --- /dev/null +++ b/libdevcore/FixedHash.h @@ -0,0 +1,392 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file FixedHash.h + * @author Gav Wood + * @date 2014 + * + * The FixedHash fixed-size "hash" container type. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include "CommonData.h" + +namespace dev +{ + +/// Compile-time calculation of Log2 of constant values. +template struct StaticLog2 { enum { result = 1 + StaticLog2::result }; }; +template <> struct StaticLog2<1> { enum { result = 0 }; }; + +extern boost::random_device s_fixedHashEngine; + +/// Fixed-size raw-byte array container type, with an API optimised for storing hashes. +/// Transparently converts to/from the corresponding arithmetic type; this will +/// assume the data contained in the hash is big-endian. +template +class FixedHash +{ +public: + /// The corresponding arithmetic type. + using Arith = boost::multiprecision::number>; + + /// The size of the container. + enum { size = N }; + + /// A dummy flag to avoid accidental construction from pointer. + enum ConstructFromPointerType { ConstructFromPointer }; + + /// Method to convert from a string. + enum ConstructFromStringType { FromHex, FromBinary }; + + /// Method to convert from a string. + enum ConstructFromHashType { AlignLeft, AlignRight, FailIfDifferent }; + + /// Construct an empty hash. + FixedHash() { m_data.fill(0); } + + /// Construct from another hash, filling with zeroes or cropping as necessary. + template explicit FixedHash(FixedHash const& _h, ConstructFromHashType _t = AlignLeft) { m_data.fill(0); unsigned c = std::min(M, N); for (unsigned i = 0; i < c; ++i) m_data[_t == AlignRight ? N - 1 - i : i] = _h[_t == AlignRight ? M - 1 - i : i]; } + + /// Convert from the corresponding arithmetic type. + FixedHash(Arith const& _arith) { toBigEndian(_arith, m_data); } + + /// Convert from unsigned + explicit FixedHash(unsigned _u) { toBigEndian(_u, m_data); } + + /// Explicitly construct, copying from a byte array. + explicit FixedHash(bytes const& _b, ConstructFromHashType _t = FailIfDifferent) { if (_b.size() == N) memcpy(m_data.data(), _b.data(), std::min(_b.size(), N)); else { m_data.fill(0); if (_t != FailIfDifferent) { auto c = std::min(_b.size(), N); for (unsigned i = 0; i < c; ++i) m_data[_t == AlignRight ? N - 1 - i : i] = _b[_t == AlignRight ? _b.size() - 1 - i : i]; } } } + + /// Explicitly construct, copying from a byte array. + explicit FixedHash(bytesConstRef _b, ConstructFromHashType _t = FailIfDifferent) { if (_b.size() == N) memcpy(m_data.data(), _b.data(), std::min(_b.size(), N)); else { m_data.fill(0); if (_t != FailIfDifferent) { auto c = std::min(_b.size(), N); for (unsigned i = 0; i < c; ++i) m_data[_t == AlignRight ? N - 1 - i : i] = _b[_t == AlignRight ? _b.size() - 1 - i : i]; } } } + + /// Explicitly construct, copying from a bytes in memory with given pointer. + explicit FixedHash(byte const* _bs, ConstructFromPointerType) { memcpy(m_data.data(), _bs, N); } + + /// Explicitly construct, copying from a string. + explicit FixedHash(std::string const& _s, ConstructFromStringType _t = FromHex, ConstructFromHashType _ht = FailIfDifferent): FixedHash(_t == FromHex ? fromHex(_s, WhenError::Throw) : dev::asBytes(_s), _ht) {} + + /// Convert to arithmetic type. + operator Arith() const { return fromBigEndian(m_data); } + + /// @returns true iff this is the empty hash. + explicit operator bool() const { return std::any_of(m_data.begin(), m_data.end(), [](byte _b) { return _b != 0; }); } + + // The obvious comparison operators. + bool operator==(FixedHash const& _c) const { return m_data == _c.m_data; } + bool operator!=(FixedHash const& _c) const { return m_data != _c.m_data; } + bool operator<(FixedHash const& _c) const { for (unsigned i = 0; i < N; ++i) if (m_data[i] < _c.m_data[i]) return true; else if (m_data[i] > _c.m_data[i]) return false; return false; } + bool operator>=(FixedHash const& _c) const { return !operator<(_c); } + bool operator<=(FixedHash const& _c) const { return operator==(_c) || operator<(_c); } + bool operator>(FixedHash const& _c) const { return !operator<=(_c); } + + // The obvious binary operators. + FixedHash& operator^=(FixedHash const& _c) { for (unsigned i = 0; i < N; ++i) m_data[i] ^= _c.m_data[i]; return *this; } + FixedHash operator^(FixedHash const& _c) const { return FixedHash(*this) ^= _c; } + FixedHash& operator|=(FixedHash const& _c) { for (unsigned i = 0; i < N; ++i) m_data[i] |= _c.m_data[i]; return *this; } + FixedHash operator|(FixedHash const& _c) const { return FixedHash(*this) |= _c; } + FixedHash& operator&=(FixedHash const& _c) { for (unsigned i = 0; i < N; ++i) m_data[i] &= _c.m_data[i]; return *this; } + FixedHash operator&(FixedHash const& _c) const { return FixedHash(*this) &= _c; } + FixedHash operator~() const { FixedHash ret; for (unsigned i = 0; i < N; ++i) ret[i] = ~m_data[i]; return ret; } + + // Big-endian increment. + FixedHash& operator++() { for (unsigned i = size; i > 0 && !++m_data[--i]; ) {} return *this; } + + /// @returns true if all one-bits in @a _c are set in this object. + bool contains(FixedHash const& _c) const { return (*this & _c) == _c; } + + /// @returns a particular byte from the hash. + byte& operator[](unsigned _i) { return m_data[_i]; } + /// @returns a particular byte from the hash. + byte operator[](unsigned _i) const { return m_data[_i]; } + + /// @returns an abridged version of the hash as a user-readable hex string. + std::string abridged() const { return toHex(ref().cropped(0, 4)) + "\342\200\246"; } + + /// @returns a version of the hash as a user-readable hex string that leaves out the middle part. + std::string abridgedMiddle() const { return toHex(ref().cropped(0, 4)) + "\342\200\246" + toHex(ref().cropped(N - 4)); } + + /// @returns the hash as a user-readable hex string. + std::string hex() const { return toHex(ref()); } + + /// @returns a mutable byte vector_ref to the object's data. + bytesRef ref() { return bytesRef(m_data.data(), N); } + + /// @returns a constant byte vector_ref to the object's data. + bytesConstRef ref() const { return bytesConstRef(m_data.data(), N); } + + /// @returns a mutable byte pointer to the object's data. + byte* data() { return m_data.data(); } + + /// @returns a constant byte pointer to the object's data. + byte const* data() const { return m_data.data(); } + + /// @returns a copy of the object's data as a byte vector. + bytes asBytes() const { return bytes(data(), data() + N); } + + /// @returns a mutable reference to the object's data as an STL array. + std::array& asArray() { return m_data; } + + /// @returns a constant reference to the object's data as an STL array. + std::array const& asArray() const { return m_data; } + + /// Populate with random data. + template + void randomize(Engine& _eng) + { + for (auto& i: m_data) + i = (uint8_t)boost::random::uniform_int_distribution(0, 255)(_eng); + } + + /// @returns a random valued object. + static FixedHash random() { FixedHash ret; ret.randomize(s_fixedHashEngine); return ret; } + + struct hash + { + /// Make a hash of the object's data. + size_t operator()(FixedHash const& _value) const { return boost::hash_range(_value.m_data.cbegin(), _value.m_data.cend()); } + }; + + template inline FixedHash& shiftBloom(FixedHash const& _h) + { + return (*this |= _h.template bloomPart()); + } + + template inline bool containsBloom(FixedHash const& _h) + { + return contains(_h.template bloomPart()); + } + + template inline FixedHash bloomPart() const + { + unsigned const c_bloomBits = M * 8; + unsigned const c_mask = c_bloomBits - 1; + unsigned const c_bloomBytes = (StaticLog2::result + 7) / 8; + + static_assert((M & (M - 1)) == 0, "M must be power-of-two"); + static_assert(P * c_bloomBytes <= N, "out of range"); + + FixedHash ret; + byte const* p = data(); + for (unsigned i = 0; i < P; ++i) + { + unsigned index = 0; + for (unsigned j = 0; j < c_bloomBytes; ++j, ++p) + index = (index << 8) | *p; + index &= c_mask; + ret[M - 1 - index / 8] |= (1 << (index % 8)); + } + return ret; + } + + /// Returns the index of the first bit set to one, or size() * 8 if no bits are set. + inline unsigned firstBitSet() const + { + unsigned ret = 0; + for (auto d: m_data) + if (d) + for (;; ++ret, d <<= 1) + if (d & 0x80) + return ret; + else {} + else + ret += 8; + return ret; + } + + void clear() { m_data.fill(0); } + +private: + std::array m_data; ///< The binary data. +}; + +template +class SecureFixedHash: private FixedHash +{ +public: + using ConstructFromHashType = typename FixedHash::ConstructFromHashType; + using ConstructFromStringType = typename FixedHash::ConstructFromStringType; + using ConstructFromPointerType = typename FixedHash::ConstructFromPointerType; + SecureFixedHash() = default; + explicit SecureFixedHash(bytes const& _b, ConstructFromHashType _t = FixedHash::FailIfDifferent): FixedHash(_b, _t) {} + explicit SecureFixedHash(bytesConstRef _b, ConstructFromHashType _t = FixedHash::FailIfDifferent): FixedHash(_b, _t) {} + explicit SecureFixedHash(bytesSec const& _b, ConstructFromHashType _t = FixedHash::FailIfDifferent): FixedHash(_b.ref(), _t) {} + template explicit SecureFixedHash(FixedHash const& _h, ConstructFromHashType _t = FixedHash::AlignLeft): FixedHash(_h, _t) {} + template explicit SecureFixedHash(SecureFixedHash const& _h, ConstructFromHashType _t = FixedHash::AlignLeft): FixedHash(_h.makeInsecure(), _t) {} + explicit SecureFixedHash(std::string const& _s, ConstructFromStringType _t = FixedHash::FromHex, ConstructFromHashType _ht = FixedHash::FailIfDifferent): FixedHash(_s, _t, _ht) {} + explicit SecureFixedHash(bytes const* _d, ConstructFromPointerType _t): FixedHash(_d, _t) {} + ~SecureFixedHash() { ref().cleanse(); } + + SecureFixedHash& operator=(SecureFixedHash const& _c) + { + if (&_c == this) + return *this; + ref().cleanse(); + FixedHash::operator=(static_cast const&>(_c)); + return *this; + } + + using FixedHash::size; + + bytesSec asBytesSec() const { return bytesSec(ref()); } + + FixedHash const& makeInsecure() const { return static_cast const&>(*this); } + FixedHash& writable() { clear(); return static_cast&>(*this); } + + using FixedHash::operator bool; + + // The obvious comparison operators. + bool operator==(SecureFixedHash const& _c) const { return static_cast const&>(*this).operator==(static_cast const&>(_c)); } + bool operator!=(SecureFixedHash const& _c) const { return static_cast const&>(*this).operator!=(static_cast const&>(_c)); } + bool operator<(SecureFixedHash const& _c) const { return static_cast const&>(*this).operator<(static_cast const&>(_c)); } + bool operator>=(SecureFixedHash const& _c) const { return static_cast const&>(*this).operator>=(static_cast const&>(_c)); } + bool operator<=(SecureFixedHash const& _c) const { return static_cast const&>(*this).operator<=(static_cast const&>(_c)); } + bool operator>(SecureFixedHash const& _c) const { return static_cast const&>(*this).operator>(static_cast const&>(_c)); } + + using FixedHash::operator==; + using FixedHash::operator!=; + using FixedHash::operator<; + using FixedHash::operator>=; + using FixedHash::operator<=; + using FixedHash::operator>; + + // The obvious binary operators. + SecureFixedHash& operator^=(FixedHash const& _c) { static_cast&>(*this).operator^=(_c); return *this; } + SecureFixedHash operator^(FixedHash const& _c) const { return SecureFixedHash(*this) ^= _c; } + SecureFixedHash& operator|=(FixedHash const& _c) { static_cast&>(*this).operator^=(_c); return *this; } + SecureFixedHash operator|(FixedHash const& _c) const { return SecureFixedHash(*this) |= _c; } + SecureFixedHash& operator&=(FixedHash const& _c) { static_cast&>(*this).operator^=(_c); return *this; } + SecureFixedHash operator&(FixedHash const& _c) const { return SecureFixedHash(*this) &= _c; } + + SecureFixedHash& operator^=(SecureFixedHash const& _c) { static_cast&>(*this).operator^=(static_cast const&>(_c)); return *this; } + SecureFixedHash operator^(SecureFixedHash const& _c) const { return SecureFixedHash(*this) ^= _c; } + SecureFixedHash& operator|=(SecureFixedHash const& _c) { static_cast&>(*this).operator^=(static_cast const&>(_c)); return *this; } + SecureFixedHash operator|(SecureFixedHash const& _c) const { return SecureFixedHash(*this) |= _c; } + SecureFixedHash& operator&=(SecureFixedHash const& _c) { static_cast&>(*this).operator^=(static_cast const&>(_c)); return *this; } + SecureFixedHash operator&(SecureFixedHash const& _c) const { return SecureFixedHash(*this) &= _c; } + SecureFixedHash operator~() const { auto r = ~static_cast const&>(*this); return static_cast(r); } + + using FixedHash::abridged; + using FixedHash::abridgedMiddle; + + bytesConstRef ref() const { return FixedHash::ref(); } + byte const* data() const { return FixedHash::data(); } + + static SecureFixedHash random() { SecureFixedHash ret; ret.randomize(s_fixedHashEngine); return ret; } + using FixedHash::firstBitSet; + + void clear() { ref().cleanse(); } +}; + +/// Fast equality operator for h256. +template<> inline bool FixedHash<32>::operator==(FixedHash<32> const& _other) const +{ + const uint64_t* hash1 = (const uint64_t*)data(); + const uint64_t* hash2 = (const uint64_t*)_other.data(); + return (hash1[0] == hash2[0]) && (hash1[1] == hash2[1]) && (hash1[2] == hash2[2]) && (hash1[3] == hash2[3]); +} + +/// Fast std::hash compatible hash function object for h256. +template<> inline size_t FixedHash<32>::hash::operator()(FixedHash<32> const& value) const +{ + uint64_t const* data = reinterpret_cast(value.data()); + return boost::hash_range(data, data + 4); +} + +/// Stream I/O for the FixedHash class. +template +inline std::ostream& operator<<(std::ostream& _out, FixedHash const& _h) +{ + _out << std::noshowbase << std::hex << std::setfill('0'); + for (unsigned i = 0; i < N; ++i) + _out << std::setw(2) << (int)_h[i]; + _out << std::dec; + return _out; +} + +/// Stream I/O for the SecureFixedHash class. +template +inline std::ostream& operator<<(std::ostream& _out, SecureFixedHash const& _h) +{ + _out << "SecureFixedHash#" << std::hex << typename FixedHash::hash()(_h.makeInsecure()) << std::dec; + return _out; +} + +// Common types of FixedHash. +using h2048 = FixedHash<256>; +using h1024 = FixedHash<128>; +using h520 = FixedHash<65>; +using h512 = FixedHash<64>; +using h256 = FixedHash<32>; +using h160 = FixedHash<20>; +using h128 = FixedHash<16>; +using h64 = FixedHash<8>; +using h512s = std::vector; +using h256s = std::vector; +using h160s = std::vector; +using h256Set = std::set; +using h160Set = std::set; +using h256Hash = std::unordered_set; +using h160Hash = std::unordered_set; + +/// Convert the given value into h160 (160-bit unsigned integer) using the right 20 bytes. +inline h160 right160(h256 const& _t) +{ + h160 ret; + memcpy(ret.data(), _t.data() + 12, 20); + return ret; +} + +/// Convert the given value into h160 (160-bit unsigned integer) using the left 20 bytes. +inline h160 left160(h256 const& _t) +{ + h160 ret; + memcpy(&ret[0], _t.data(), 20); + return ret; +} + +h128 fromUUID(std::string const& _uuid); + +std::string toUUID(h128 const& _uuid); + +inline std::string toString(h256s const& _bs) +{ + std::ostringstream out; + out << "[ "; + for (auto i: _bs) + out << i.abridged() << ", "; + out << "]"; + return out.str(); +} + +} + +namespace std +{ + /// Forward std::hash to dev::FixedHash::hash. + template<> struct hash: dev::h64::hash {}; + template<> struct hash: dev::h128::hash {}; + template<> struct hash: dev::h160::hash {}; + template<> struct hash: dev::h256::hash {}; + template<> struct hash: dev::h512::hash {}; +} diff --git a/libdevcore/Guards.cpp b/libdevcore/Guards.cpp new file mode 100644 index 0000000000..12e7ddf77e --- /dev/null +++ b/libdevcore/Guards.cpp @@ -0,0 +1,29 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Guards.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "Guards.h" +using namespace std; +using namespace dev; + +namespace dev +{ + +} diff --git a/libdevcore/Guards.h b/libdevcore/Guards.h new file mode 100644 index 0000000000..fda8141f0c --- /dev/null +++ b/libdevcore/Guards.h @@ -0,0 +1,159 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Guards.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include +#include +#pragma warning(push) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#include +#pragma warning(pop) +#pragma GCC diagnostic pop + +namespace dev +{ + +using Mutex = std::mutex; +using RecursiveMutex = std::recursive_mutex; +using SharedMutex = boost::shared_mutex; + +using Guard = std::lock_guard; +using UniqueGuard = std::unique_lock; +using RecursiveGuard = std::lock_guard; +using ReadGuard = boost::shared_lock; +using UpgradableGuard = boost::upgrade_lock; +using UpgradeGuard = boost::upgrade_to_unique_lock; +using WriteGuard = boost::unique_lock; + +template +struct GenericGuardBool: GuardType +{ + GenericGuardBool(MutexType& _m): GuardType(_m) {} + bool b = true; +}; +template +struct GenericUnguardBool +{ + GenericUnguardBool(MutexType& _m): m(_m) { m.unlock(); } + ~GenericUnguardBool() { m.lock(); } + bool b = true; + MutexType& m; +}; +template +struct GenericUnguardSharedBool +{ + GenericUnguardSharedBool(MutexType& _m): m(_m) { m.unlock_shared(); } + ~GenericUnguardSharedBool() { m.lock_shared(); } + bool b = true; + MutexType& m; +}; + +/** @brief Simple lock that waits for release without making context switch */ +class SpinLock +{ +public: + SpinLock() { m_lock.clear(); } + void lock() { while (m_lock.test_and_set(std::memory_order_acquire)) {} } + void unlock() { m_lock.clear(std::memory_order_release); } +private: + std::atomic_flag m_lock; +}; +using SpinGuard = std::lock_guard; + +template +class Notified +{ +public: + Notified() {} + Notified(N const& _v): m_value(_v) {} + Notified(Notified const&) = delete; + Notified& operator=(N const& _v) { UniqueGuard l(m_mutex); m_value = _v; m_cv.notify_all(); return *this; } + + operator N() const { UniqueGuard l(m_mutex); return m_value; } + + void wait() const { N old; { UniqueGuard l(m_mutex); old = m_value; } waitNot(old); } + void wait(N const& _v) const { UniqueGuard l(m_mutex); m_cv.wait(l, [&](){return m_value == _v;}); } + void waitNot(N const& _v) const { UniqueGuard l(m_mutex); m_cv.wait(l, [&](){return m_value != _v;}); } + template void wait(F const& _f) const { UniqueGuard l(m_mutex); m_cv.wait(l, _f); } + + template void wait(std::chrono::duration _d) const { N old; { UniqueGuard l(m_mutex); old = m_value; } waitNot(_d, old); } + template void wait(std::chrono::duration _d, N const& _v) const { UniqueGuard l(m_mutex); m_cv.wait_for(l, _d, [&](){return m_value == _v;}); } + template void waitNot(std::chrono::duration _d, N const& _v) const { UniqueGuard l(m_mutex); m_cv.wait_for(l, _d, [&](){return m_value != _v;}); } + template void wait(std::chrono::duration _d, F const& _f) const { UniqueGuard l(m_mutex); m_cv.wait_for(l, _d, _f); } + +private: + mutable Mutex m_mutex; + mutable std::condition_variable m_cv; + N m_value; +}; + +/** @brief Simple block guard. + * The expression/block following is guarded though the given mutex. + * Usage: + * @code + * Mutex m; + * unsigned d; + * ... + * ETH_(m) d = 1; + * ... + * ETH_(m) { for (auto d = 10; d > 0; --d) foo(d); d = 0; } + * @endcode + * + * There are several variants of this basic mechanism for different Mutex types and Guards. + * + * There is also the UNGUARD variant which allows an unguarded expression/block to exist within a + * guarded expression. eg: + * + * @code + * Mutex m; + * int d; + * ... + * ETH_GUARDED(m) + * { + * for (auto d = 50; d > 25; --d) + * foo(d); + * ETH_UNGUARDED(m) + * bar(); + * for (; d > 0; --d) + * foo(d); + * } + * @endcode + */ + +#define DEV_GUARDED(MUTEX) \ + for (GenericGuardBool __eth_l(MUTEX); __eth_l.b; __eth_l.b = false) +#define DEV_READ_GUARDED(MUTEX) \ + for (GenericGuardBool __eth_l(MUTEX); __eth_l.b; __eth_l.b = false) +#define DEV_WRITE_GUARDED(MUTEX) \ + for (GenericGuardBool __eth_l(MUTEX); __eth_l.b; __eth_l.b = false) +#define DEV_RECURSIVE_GUARDED(MUTEX) \ + for (GenericGuardBool __eth_l(MUTEX); __eth_l.b; __eth_l.b = false) +#define DEV_UNGUARDED(MUTEX) \ + for (GenericUnguardBool __eth_l(MUTEX); __eth_l.b; __eth_l.b = false) +#define DEV_READ_UNGUARDED(MUTEX) \ + for (GenericUnguardSharedBool __eth_l(MUTEX); __eth_l.b; __eth_l.b = false) +#define DEV_WRITE_UNGUARDED(MUTEX) \ + for (GenericUnguardBool __eth_l(MUTEX); __eth_l.b; __eth_l.b = false) + +} diff --git a/libdevcore/Hash.cpp b/libdevcore/Hash.cpp new file mode 100644 index 0000000000..18cfe91fae --- /dev/null +++ b/libdevcore/Hash.cpp @@ -0,0 +1,440 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Hash.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "Hash.h" +#include +#include +#include +#include "picosha2.h" +using namespace std; +using namespace dev; + +namespace dev +{ + +h256 sha256(bytesConstRef _input) +{ + h256 ret; + picosha2::hash256(_input.begin(), _input.end(), ret.data(), ret.data() + 32); + return ret; +} + +namespace rmd160 +{ + +/********************************************************************\ + * + * FILE: rmd160.h + * FILE: rmd160.c + * + * CONTENTS: Header file for a sample C-implementation of the + * RIPEMD-160 hash-function. + * TARGET: any computer with an ANSI C compiler + * + * AUTHOR: Antoon Bosselaers, ESAT-COSIC + * DATE: 1 March 1996 + * VERSION: 1.0 + * + * Copyright (c) Katholieke Universiteit Leuven + * 1996, All Rights Reserved + * + \********************************************************************/ + +// Adapted into "header-only" format by Gav Wood. + +/* macro definitions */ + +#define RMDsize 160 + +/* collect four bytes into one word: */ +#define BYTES_TO_DWORD(strptr) \ +(((uint32_t) *((strptr)+3) << 24) | \ +((uint32_t) *((strptr)+2) << 16) | \ +((uint32_t) *((strptr)+1) << 8) | \ +((uint32_t) *(strptr))) + +/* ROL(x, n) cyclically rotates x over n bits to the left */ +/* x must be of an unsigned 32 bits type and 0 <= n < 32. */ +#define ROL(x, n) (((x) << (n)) | ((x) >> (32-(n)))) + +/* the five basic functions F(), G() and H() */ +#define F(x, y, z) ((x) ^ (y) ^ (z)) +#define G(x, y, z) (((x) & (y)) | (~(x) & (z))) +#define H(x, y, z) (((x) | ~(y)) ^ (z)) +#define I(x, y, z) (((x) & (z)) | ((y) & ~(z))) +#define J(x, y, z) ((x) ^ ((y) | ~(z))) + +/* the ten basic operations FF() through III() */ +#define FF(a, b, c, d, e, x, s) {\ +(a) += F((b), (c), (d)) + (x);\ +(a) = ROL((a), (s)) + (e);\ +(c) = ROL((c), 10);\ +} +#define GG(a, b, c, d, e, x, s) {\ +(a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\ +(a) = ROL((a), (s)) + (e);\ +(c) = ROL((c), 10);\ +} +#define HH(a, b, c, d, e, x, s) {\ +(a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\ +(a) = ROL((a), (s)) + (e);\ +(c) = ROL((c), 10);\ +} +#define II(a, b, c, d, e, x, s) {\ +(a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\ +(a) = ROL((a), (s)) + (e);\ +(c) = ROL((c), 10);\ +} +#define JJ(a, b, c, d, e, x, s) {\ +(a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\ +(a) = ROL((a), (s)) + (e);\ +(c) = ROL((c), 10);\ +} +#define FFF(a, b, c, d, e, x, s) {\ +(a) += F((b), (c), (d)) + (x);\ +(a) = ROL((a), (s)) + (e);\ +(c) = ROL((c), 10);\ +} +#define GGG(a, b, c, d, e, x, s) {\ +(a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\ +(a) = ROL((a), (s)) + (e);\ +(c) = ROL((c), 10);\ +} +#define HHH(a, b, c, d, e, x, s) {\ +(a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\ +(a) = ROL((a), (s)) + (e);\ +(c) = ROL((c), 10);\ +} +#define III(a, b, c, d, e, x, s) {\ +(a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\ +(a) = ROL((a), (s)) + (e);\ +(c) = ROL((c), 10);\ +} +#define JJJ(a, b, c, d, e, x, s) {\ +(a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\ +(a) = ROL((a), (s)) + (e);\ +(c) = ROL((c), 10);\ +} + +void MDinit(uint32_t *MDbuf) +{ + MDbuf[0] = 0x67452301UL; + MDbuf[1] = 0xefcdab89UL; + MDbuf[2] = 0x98badcfeUL; + MDbuf[3] = 0x10325476UL; + MDbuf[4] = 0xc3d2e1f0UL; + + return; +} + +/********************************************************************/ + +void MDcompress(uint32_t *MDbuf, uint32_t *X) +{ + uint32_t aa = MDbuf[0], bb = MDbuf[1], cc = MDbuf[2], + dd = MDbuf[3], ee = MDbuf[4]; + uint32_t aaa = MDbuf[0], bbb = MDbuf[1], ccc = MDbuf[2], + ddd = MDbuf[3], eee = MDbuf[4]; + + /* round 1 */ + FF(aa, bb, cc, dd, ee, X[ 0], 11); + FF(ee, aa, bb, cc, dd, X[ 1], 14); + FF(dd, ee, aa, bb, cc, X[ 2], 15); + FF(cc, dd, ee, aa, bb, X[ 3], 12); + FF(bb, cc, dd, ee, aa, X[ 4], 5); + FF(aa, bb, cc, dd, ee, X[ 5], 8); + FF(ee, aa, bb, cc, dd, X[ 6], 7); + FF(dd, ee, aa, bb, cc, X[ 7], 9); + FF(cc, dd, ee, aa, bb, X[ 8], 11); + FF(bb, cc, dd, ee, aa, X[ 9], 13); + FF(aa, bb, cc, dd, ee, X[10], 14); + FF(ee, aa, bb, cc, dd, X[11], 15); + FF(dd, ee, aa, bb, cc, X[12], 6); + FF(cc, dd, ee, aa, bb, X[13], 7); + FF(bb, cc, dd, ee, aa, X[14], 9); + FF(aa, bb, cc, dd, ee, X[15], 8); + + /* round 2 */ + GG(ee, aa, bb, cc, dd, X[ 7], 7); + GG(dd, ee, aa, bb, cc, X[ 4], 6); + GG(cc, dd, ee, aa, bb, X[13], 8); + GG(bb, cc, dd, ee, aa, X[ 1], 13); + GG(aa, bb, cc, dd, ee, X[10], 11); + GG(ee, aa, bb, cc, dd, X[ 6], 9); + GG(dd, ee, aa, bb, cc, X[15], 7); + GG(cc, dd, ee, aa, bb, X[ 3], 15); + GG(bb, cc, dd, ee, aa, X[12], 7); + GG(aa, bb, cc, dd, ee, X[ 0], 12); + GG(ee, aa, bb, cc, dd, X[ 9], 15); + GG(dd, ee, aa, bb, cc, X[ 5], 9); + GG(cc, dd, ee, aa, bb, X[ 2], 11); + GG(bb, cc, dd, ee, aa, X[14], 7); + GG(aa, bb, cc, dd, ee, X[11], 13); + GG(ee, aa, bb, cc, dd, X[ 8], 12); + + /* round 3 */ + HH(dd, ee, aa, bb, cc, X[ 3], 11); + HH(cc, dd, ee, aa, bb, X[10], 13); + HH(bb, cc, dd, ee, aa, X[14], 6); + HH(aa, bb, cc, dd, ee, X[ 4], 7); + HH(ee, aa, bb, cc, dd, X[ 9], 14); + HH(dd, ee, aa, bb, cc, X[15], 9); + HH(cc, dd, ee, aa, bb, X[ 8], 13); + HH(bb, cc, dd, ee, aa, X[ 1], 15); + HH(aa, bb, cc, dd, ee, X[ 2], 14); + HH(ee, aa, bb, cc, dd, X[ 7], 8); + HH(dd, ee, aa, bb, cc, X[ 0], 13); + HH(cc, dd, ee, aa, bb, X[ 6], 6); + HH(bb, cc, dd, ee, aa, X[13], 5); + HH(aa, bb, cc, dd, ee, X[11], 12); + HH(ee, aa, bb, cc, dd, X[ 5], 7); + HH(dd, ee, aa, bb, cc, X[12], 5); + + /* round 4 */ + II(cc, dd, ee, aa, bb, X[ 1], 11); + II(bb, cc, dd, ee, aa, X[ 9], 12); + II(aa, bb, cc, dd, ee, X[11], 14); + II(ee, aa, bb, cc, dd, X[10], 15); + II(dd, ee, aa, bb, cc, X[ 0], 14); + II(cc, dd, ee, aa, bb, X[ 8], 15); + II(bb, cc, dd, ee, aa, X[12], 9); + II(aa, bb, cc, dd, ee, X[ 4], 8); + II(ee, aa, bb, cc, dd, X[13], 9); + II(dd, ee, aa, bb, cc, X[ 3], 14); + II(cc, dd, ee, aa, bb, X[ 7], 5); + II(bb, cc, dd, ee, aa, X[15], 6); + II(aa, bb, cc, dd, ee, X[14], 8); + II(ee, aa, bb, cc, dd, X[ 5], 6); + II(dd, ee, aa, bb, cc, X[ 6], 5); + II(cc, dd, ee, aa, bb, X[ 2], 12); + + /* round 5 */ + JJ(bb, cc, dd, ee, aa, X[ 4], 9); + JJ(aa, bb, cc, dd, ee, X[ 0], 15); + JJ(ee, aa, bb, cc, dd, X[ 5], 5); + JJ(dd, ee, aa, bb, cc, X[ 9], 11); + JJ(cc, dd, ee, aa, bb, X[ 7], 6); + JJ(bb, cc, dd, ee, aa, X[12], 8); + JJ(aa, bb, cc, dd, ee, X[ 2], 13); + JJ(ee, aa, bb, cc, dd, X[10], 12); + JJ(dd, ee, aa, bb, cc, X[14], 5); + JJ(cc, dd, ee, aa, bb, X[ 1], 12); + JJ(bb, cc, dd, ee, aa, X[ 3], 13); + JJ(aa, bb, cc, dd, ee, X[ 8], 14); + JJ(ee, aa, bb, cc, dd, X[11], 11); + JJ(dd, ee, aa, bb, cc, X[ 6], 8); + JJ(cc, dd, ee, aa, bb, X[15], 5); + JJ(bb, cc, dd, ee, aa, X[13], 6); + + /* parallel round 1 */ + JJJ(aaa, bbb, ccc, ddd, eee, X[ 5], 8); + JJJ(eee, aaa, bbb, ccc, ddd, X[14], 9); + JJJ(ddd, eee, aaa, bbb, ccc, X[ 7], 9); + JJJ(ccc, ddd, eee, aaa, bbb, X[ 0], 11); + JJJ(bbb, ccc, ddd, eee, aaa, X[ 9], 13); + JJJ(aaa, bbb, ccc, ddd, eee, X[ 2], 15); + JJJ(eee, aaa, bbb, ccc, ddd, X[11], 15); + JJJ(ddd, eee, aaa, bbb, ccc, X[ 4], 5); + JJJ(ccc, ddd, eee, aaa, bbb, X[13], 7); + JJJ(bbb, ccc, ddd, eee, aaa, X[ 6], 7); + JJJ(aaa, bbb, ccc, ddd, eee, X[15], 8); + JJJ(eee, aaa, bbb, ccc, ddd, X[ 8], 11); + JJJ(ddd, eee, aaa, bbb, ccc, X[ 1], 14); + JJJ(ccc, ddd, eee, aaa, bbb, X[10], 14); + JJJ(bbb, ccc, ddd, eee, aaa, X[ 3], 12); + JJJ(aaa, bbb, ccc, ddd, eee, X[12], 6); + + /* parallel round 2 */ + III(eee, aaa, bbb, ccc, ddd, X[ 6], 9); + III(ddd, eee, aaa, bbb, ccc, X[11], 13); + III(ccc, ddd, eee, aaa, bbb, X[ 3], 15); + III(bbb, ccc, ddd, eee, aaa, X[ 7], 7); + III(aaa, bbb, ccc, ddd, eee, X[ 0], 12); + III(eee, aaa, bbb, ccc, ddd, X[13], 8); + III(ddd, eee, aaa, bbb, ccc, X[ 5], 9); + III(ccc, ddd, eee, aaa, bbb, X[10], 11); + III(bbb, ccc, ddd, eee, aaa, X[14], 7); + III(aaa, bbb, ccc, ddd, eee, X[15], 7); + III(eee, aaa, bbb, ccc, ddd, X[ 8], 12); + III(ddd, eee, aaa, bbb, ccc, X[12], 7); + III(ccc, ddd, eee, aaa, bbb, X[ 4], 6); + III(bbb, ccc, ddd, eee, aaa, X[ 9], 15); + III(aaa, bbb, ccc, ddd, eee, X[ 1], 13); + III(eee, aaa, bbb, ccc, ddd, X[ 2], 11); + + /* parallel round 3 */ + HHH(ddd, eee, aaa, bbb, ccc, X[15], 9); + HHH(ccc, ddd, eee, aaa, bbb, X[ 5], 7); + HHH(bbb, ccc, ddd, eee, aaa, X[ 1], 15); + HHH(aaa, bbb, ccc, ddd, eee, X[ 3], 11); + HHH(eee, aaa, bbb, ccc, ddd, X[ 7], 8); + HHH(ddd, eee, aaa, bbb, ccc, X[14], 6); + HHH(ccc, ddd, eee, aaa, bbb, X[ 6], 6); + HHH(bbb, ccc, ddd, eee, aaa, X[ 9], 14); + HHH(aaa, bbb, ccc, ddd, eee, X[11], 12); + HHH(eee, aaa, bbb, ccc, ddd, X[ 8], 13); + HHH(ddd, eee, aaa, bbb, ccc, X[12], 5); + HHH(ccc, ddd, eee, aaa, bbb, X[ 2], 14); + HHH(bbb, ccc, ddd, eee, aaa, X[10], 13); + HHH(aaa, bbb, ccc, ddd, eee, X[ 0], 13); + HHH(eee, aaa, bbb, ccc, ddd, X[ 4], 7); + HHH(ddd, eee, aaa, bbb, ccc, X[13], 5); + + /* parallel round 4 */ + GGG(ccc, ddd, eee, aaa, bbb, X[ 8], 15); + GGG(bbb, ccc, ddd, eee, aaa, X[ 6], 5); + GGG(aaa, bbb, ccc, ddd, eee, X[ 4], 8); + GGG(eee, aaa, bbb, ccc, ddd, X[ 1], 11); + GGG(ddd, eee, aaa, bbb, ccc, X[ 3], 14); + GGG(ccc, ddd, eee, aaa, bbb, X[11], 14); + GGG(bbb, ccc, ddd, eee, aaa, X[15], 6); + GGG(aaa, bbb, ccc, ddd, eee, X[ 0], 14); + GGG(eee, aaa, bbb, ccc, ddd, X[ 5], 6); + GGG(ddd, eee, aaa, bbb, ccc, X[12], 9); + GGG(ccc, ddd, eee, aaa, bbb, X[ 2], 12); + GGG(bbb, ccc, ddd, eee, aaa, X[13], 9); + GGG(aaa, bbb, ccc, ddd, eee, X[ 9], 12); + GGG(eee, aaa, bbb, ccc, ddd, X[ 7], 5); + GGG(ddd, eee, aaa, bbb, ccc, X[10], 15); + GGG(ccc, ddd, eee, aaa, bbb, X[14], 8); + + /* parallel round 5 */ + FFF(bbb, ccc, ddd, eee, aaa, X[12] , 8); + FFF(aaa, bbb, ccc, ddd, eee, X[15] , 5); + FFF(eee, aaa, bbb, ccc, ddd, X[10] , 12); + FFF(ddd, eee, aaa, bbb, ccc, X[ 4] , 9); + FFF(ccc, ddd, eee, aaa, bbb, X[ 1] , 12); + FFF(bbb, ccc, ddd, eee, aaa, X[ 5] , 5); + FFF(aaa, bbb, ccc, ddd, eee, X[ 8] , 14); + FFF(eee, aaa, bbb, ccc, ddd, X[ 7] , 6); + FFF(ddd, eee, aaa, bbb, ccc, X[ 6] , 8); + FFF(ccc, ddd, eee, aaa, bbb, X[ 2] , 13); + FFF(bbb, ccc, ddd, eee, aaa, X[13] , 6); + FFF(aaa, bbb, ccc, ddd, eee, X[14] , 5); + FFF(eee, aaa, bbb, ccc, ddd, X[ 0] , 15); + FFF(ddd, eee, aaa, bbb, ccc, X[ 3] , 13); + FFF(ccc, ddd, eee, aaa, bbb, X[ 9] , 11); + FFF(bbb, ccc, ddd, eee, aaa, X[11] , 11); + + /* combine results */ + ddd += cc + MDbuf[1]; /* final result for MDbuf[0] */ + MDbuf[1] = MDbuf[2] + dd + eee; + MDbuf[2] = MDbuf[3] + ee + aaa; + MDbuf[3] = MDbuf[4] + aa + bbb; + MDbuf[4] = MDbuf[0] + bb + ccc; + MDbuf[0] = ddd; + + return; +} + +void MDfinish(uint32_t *MDbuf, byte const *strptr, uint32_t lswlen, uint32_t mswlen) +{ + unsigned int i; /* counter */ + uint32_t X[16]; /* message words */ + + memset(X, 0, 16*sizeof(uint32_t)); + + /* put bytes from strptr into X */ + for (i=0; i<(lswlen&63); i++) { + /* byte i goes into word X[i div 4] at pos. 8*(i mod 4) */ + X[i>>2] ^= (uint32_t) *strptr++ << (8 * (i&3)); + } + + /* append the bit m_n == 1 */ + X[(lswlen>>2)&15] ^= (uint32_t)1 << (8*(lswlen&3) + 7); + + if ((lswlen & 63) > 55) { + /* length goes to next block */ + MDcompress(MDbuf, X); + memset(X, 0, 16*sizeof(uint32_t)); + } + + /* append length in bits*/ + X[14] = lswlen << 3; + X[15] = (lswlen >> 29) | (mswlen << 3); + MDcompress(MDbuf, X); + + return; +} + +#undef ROL +#undef F +#undef G +#undef H +#undef I +#undef J +#undef FF +#undef GG +#undef HH +#undef II +#undef JJ +#undef FFF +#undef GGG +#undef HHH +#undef III +#undef JJJ + +} + +/* + * @returns RMD(_input) + */ +h160 ripemd160(bytesConstRef _input) +{ + h160 hashcode; + uint32_t buffer[RMDsize / 32]; // contains (A, B, C, D(, E)) + uint32_t current[16]; // current 16-word chunk + + // initialize + rmd160::MDinit(buffer); + byte const* message = _input.data(); + uint32_t remaining = _input.size(); // # of bytes not yet processed + + // process message in 16x 4-byte chunks + for (; remaining >= 64; remaining -= 64) + { + for (unsigned i = 0; i < 16; i++) + { + current[i] = BYTES_TO_DWORD(message); + message += 4; + } + rmd160::MDcompress(buffer, current); + } + // length mod 64 bytes left + + // finish: + rmd160::MDfinish(buffer, message, _input.size(), 0); + + for (unsigned i = 0; i < RMDsize / 8; i += 4) + { + hashcode[i] = buffer[i >> 2]; // implicit cast to byte + hashcode[i + 1] = (buffer[i >> 2] >> 8); //extracts the 8 least + hashcode[i + 2] = (buffer[i >> 2] >> 16); // significant bits. + hashcode[i + 3] = (buffer[i >> 2] >> 24); + } + + return hashcode; +} + +#undef BYTES_TO_DWORD +#undef RMDsize + +} diff --git a/libdevcore/Hash.h b/libdevcore/Hash.h new file mode 100644 index 0000000000..f4ec8d969b --- /dev/null +++ b/libdevcore/Hash.h @@ -0,0 +1,38 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Hash.h + * @author Gav Wood + * @date 2014 + * + * The FixedHash fixed-size "hash" container type. + */ + +#pragma once + +#include +#include "FixedHash.h" +#include "vector_ref.h" +#include "SHA3.h" + +namespace dev +{ + +h256 sha256(bytesConstRef _input); + +h160 ripemd160(bytesConstRef _input); + +} diff --git a/libdevcore/Log.cpp b/libdevcore/Log.cpp new file mode 100644 index 0000000000..f9bf88f488 --- /dev/null +++ b/libdevcore/Log.cpp @@ -0,0 +1,227 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Log.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "Log.h" + +#include +#include +#include +#ifdef __APPLE__ +#include +#endif +#if !defined(ETH_EMSCRIPTEN) +#include +#endif +#include "Guards.h" +using namespace std; +using namespace dev; + +//⊳⊲◀▶■▣▢□▷◁▧▨▩▲◆◉◈◇◎●◍◌○◼☑☒☎☢☣☰☀♽♥♠✩✭❓✔✓✖✕✘✓✔✅⚒⚡⦸⬌∅⁕«««»»»⚙ + +// Logging +int dev::g_logVerbosity = 5; +mutex x_logOverride; + +/// Map of Log Channel types to bool, false forces the channel to be disabled, true forces it to be enabled. +/// If a channel has no entry, then it will output as long as its verbosity (LogChannel::verbosity) is less than +/// or equal to the currently output verbosity (g_logVerbosity). +static map s_logOverride; + +bool dev::isChannelVisible(std::type_info const* _ch, bool _default) +{ + Guard l(x_logOverride); + if (s_logOverride.count(_ch)) + return s_logOverride[_ch]; + return _default; +} + +LogOverrideAux::LogOverrideAux(std::type_info const* _ch, bool _value): + m_ch(_ch) +{ + Guard l(x_logOverride); + m_old = s_logOverride.count(_ch) ? (int)s_logOverride[_ch] : c_null; + s_logOverride[m_ch] = _value; +} + +LogOverrideAux::~LogOverrideAux() +{ + Guard l(x_logOverride); + if (m_old == c_null) + s_logOverride.erase(m_ch); + else + s_logOverride[m_ch] = (bool)m_old; +} + +#if defined(_WIN32) +const char* LogChannel::name() { return EthGray "..."; } +const char* LeftChannel::name() { return EthNavy "<--"; } +const char* RightChannel::name() { return EthGreen "-->"; } +const char* WarnChannel::name() { return EthOnRed EthBlackBold " X"; } +const char* NoteChannel::name() { return EthBlue " i"; } +const char* DebugChannel::name() { return EthWhite " D"; } +const char* TraceChannel::name() { return EthGray "..."; } +const char* TxStatChannel::name(){return "--TXSTAT--";} +const char* BlockStatChannel::name(){return "--BLOCKSTAT--";} + + +#else +const char* LogChannel::name() { return EthGray "···"; } +const char* LeftChannel::name() { return EthNavy "◀▬▬"; } +const char* RightChannel::name() { return EthGreen "▬▬▶"; } +const char* WarnChannel::name() { return EthOnRed EthBlackBold " ✘"; } +const char* NoteChannel::name() { return EthBlue " ℹ"; } +const char* DebugChannel::name() { return EthWhite " ◇"; } +const char* TraceChannel::name() { return EthGray "..."; } +const char* TxStatChannel::name(){return "--TXSTAT--";} +const char* BlockStatChannel::name(){return "--BLOCKSTAT--";} +#endif + +LogOutputStreamBase::LogOutputStreamBase(char const* _id, std::type_info const* _info, unsigned _v, bool _autospacing): + m_autospacing(_autospacing), + m_verbosity(_v) +{ + Guard l(x_logOverride); + auto it = s_logOverride.find(_info); + if ((it != s_logOverride.end() && it->second == true) || (it == s_logOverride.end() && (int)_v <= g_logVerbosity)) + { + time_t rawTime = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); + unsigned ms = chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count() % 1000; + char buf[24]; + if (strftime(buf, 24, "%X", localtime(&rawTime)) == 0) + buf[0] = '\0'; // empty if case strftime fails + static char const* c_begin = " " EthViolet; + static char const* c_sep1 = EthReset EthBlack "|" EthNavy; + static char const* c_sep2 = EthReset EthBlack "|" EthTeal; + static char const* c_end = EthReset " "; + m_sstr << _id << c_begin << buf << "." << setw(3) << setfill('0') << ms; + m_sstr << c_sep1 << getThreadName() << ThreadContext::join(c_sep2) << c_end; + } +} + +#if !defined(ETH_EMSCRIPTEN) +void LogOutputStreamBase::append(boost::asio::ip::basic_endpoint const& _t) +{ + m_sstr << EthNavyUnder "tcp://" << _t << EthReset; +} +#endif + +/// Associate a name with each thread for nice logging. +struct ThreadLocalLogName +{ + ThreadLocalLogName(std::string const& _name) { m_name.reset(new string(_name)); } + boost::thread_specific_ptr m_name; +}; + +/// Associate a name with each thread for nice logging. +struct ThreadLocalLogContext +{ + ThreadLocalLogContext() = default; + + void push(std::string const& _name) + { + if (!m_contexts.get()) + m_contexts.reset(new vector); + m_contexts->push_back(_name); + } + + void pop() + { + m_contexts->pop_back(); + } + + string join(string const& _prior) + { + string ret; + if (m_contexts.get()) + for (auto const& i: *m_contexts) + ret += _prior + i; + return ret; + } + + boost::thread_specific_ptr> m_contexts; +}; + +ThreadLocalLogContext g_logThreadContext; + +ThreadLocalLogName g_logThreadName("main"); + +void dev::ThreadContext::push(string const& _n) +{ + g_logThreadContext.push(_n); +} + +void dev::ThreadContext::pop() +{ + g_logThreadContext.pop(); +} + +string dev::ThreadContext::join(string const& _prior) +{ + return g_logThreadContext.join(_prior); +} + +// foward declare without all of Windows.h +#if defined(_WIN32) +extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA(const char* lpOutputString); +#endif + + +string dev::getThreadName() +{ +#if defined(__GLIBC__) || defined(__APPLE__) + char buffer[128]; + pthread_getname_np(pthread_self(), buffer, 127); + buffer[127] = 0; + return buffer; +#else + return g_logThreadName.m_name.get() ? *g_logThreadName.m_name.get() : ""; +#endif +} + +void dev::setThreadName(string const& _n) +{ +#if defined(__GLIBC__) + pthread_setname_np(pthread_self(), _n.c_str()); +#elif defined(__APPLE__) + pthread_setname_np(_n.c_str()); +#else + g_logThreadName.m_name.reset(new std::string(_n)); +#endif +} + + +void dev::simpleDebugOut(std::string const& _s, char const*) +{ + static SpinLock s_lock; + SpinGuard l(s_lock); + + LOG(ERROR) << _s << endl << flush; + + // helpful to use OutputDebugString on windows + #if defined(_WIN32) + { + OutputDebugStringA(_s.data()); + OutputDebugStringA("\n"); + } + #endif +} + +std::function dev::g_logPost = simpleDebugOut; diff --git a/libdevcore/Log.h b/libdevcore/Log.h new file mode 100644 index 0000000000..f6a8ececda --- /dev/null +++ b/libdevcore/Log.h @@ -0,0 +1,347 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Log.h + * @author Gav Wood + * @date 2014 + * + * The logging subsystem. + */ + +#pragma once + +#include +#include +#include "vector_ref.h" +#include "Common.h" +#include "CommonIO.h" +#include "CommonData.h" +#include "FixedHash.h" +#include "Terminal.h" +#include "easylog.h" + +namespace boost { namespace asio { namespace ip { templateclass basic_endpoint; class tcp; } } } + +namespace dev +{ + +/// The null output stream. Used when logging is disabled. +class NullOutputStream +{ +public: + template NullOutputStream& operator<<(T const&) { return *this; } +}; + +/// A simple log-output function that prints log messages to stdout. +void simpleDebugOut(std::string const&, char const*); + +/// The logging system's current verbosity. +extern int g_logVerbosity; + +/// The current method that the logging system uses to output the log messages. Defaults to simpleDebugOut(). +extern std::function g_logPost; + +class LogOverrideAux +{ +protected: + LogOverrideAux(std::type_info const* _ch, bool _value); + ~LogOverrideAux(); + +private: + std::type_info const* m_ch; + static const int c_null = -1; + int m_old; +}; + +template +class LogOverride: LogOverrideAux +{ +public: + LogOverride(bool _value): LogOverrideAux(&typeid(Channel), _value) {} +}; + +bool isChannelVisible(std::type_info const* _ch, bool _default); +template bool isChannelVisible() { return isChannelVisible(&typeid(Channel), Channel::verbosity <= g_logVerbosity); } + +/// Temporary changes system's verbosity for specific function. Restores the old verbosity when function returns. +/// Not thread-safe, use with caution! +struct VerbosityHolder +{ + VerbosityHolder(int _temporaryValue, bool _force = false): oldLogVerbosity(g_logVerbosity) { if (g_logVerbosity >= 0 || _force) g_logVerbosity = _temporaryValue; } + ~VerbosityHolder() { g_logVerbosity = oldLogVerbosity; } + int oldLogVerbosity; +}; + +#define ETH_THREAD_CONTEXT(name) for (std::pair __eth_thread_context(name, true); p.second; p.second = false) + +class ThreadContext +{ +public: + ThreadContext(std::string const& _info) { push(_info); } + ~ThreadContext() { pop(); } + + static void push(std::string const& _n); + static void pop(); + static std::string join(std::string const& _prior); +}; + +/// Set the current thread's log name. +/// +/// It appears that there is not currently any cross-platform way of setting +/// thread names either in Boost or in the C++11 runtime libraries. What is +/// more, the API for 'pthread_setname_np' is not even consistent across +/// platforms which implement it. +/// +/// A proposal to add such functionality on the Boost mailing list, which +/// I assume never happened, but which I should follow-up and ask about. +/// http://boost.2283326.n4.nabble.com/Adding-an-option-to-set-the-name-of-a-boost-thread-td4638283.html +/// +/// man page for 'pthread_setname_np', including this crucial snippet of +/// information ... "These functions are nonstandard GNU extensions." +/// http://man7.org/linux/man-pages/man3/pthread_setname_np.3.html +/// +/// Stack Overflow "Can I set the name of a thread in pthreads / linux?" +/// which includes useful information on the minor API differences between +/// Linux, BSD and OS X. +/// http://stackoverflow.com/questions/2369738/can-i-set-the-name-of-a-thread-in-pthreads-linux/7989973#7989973 +/// +/// musl mailng list posting "pthread set name on MIPs" which includes the +/// information that musl doesn't currently implement 'pthread_setname_np' +/// https://marc.info/?l=musl&m=146171729013062&w=1 +void setThreadName(std::string const& _n); + +/// Set the current thread's log name. +std::string getThreadName(); + +/// The default logging channels. Each has an associated verbosity and three-letter prefix (name() ). +/// Channels should inherit from LogChannel and define name() and verbosity. +struct LogChannel { static const char* name(); static const int verbosity = 1; static const bool debug = true; }; +struct LeftChannel: public LogChannel { static const char* name(); }; +struct RightChannel: public LogChannel { static const char* name(); }; +struct WarnChannel: public LogChannel { static const char* name(); static const int verbosity = 0; static const bool debug = false; }; +struct NoteChannel: public LogChannel { static const char* name(); static const bool debug = false; }; +struct DebugChannel: public LogChannel { static const char* name(); static const int verbosity = 0; }; +struct TraceChannel: public LogChannel { static const char* name(); static const int verbosity = 5; static const bool debug = true; }; + +struct TxStatChannel: public LogChannel { static const char* name(); static const int verbosity = 1; static const bool debug = true; }; +struct BlockStatChannel: public LogChannel { static const char* name(); static const int verbosity = 1; static const bool debug = true; }; + +enum class LogTag +{ + None, + Url, + Error, + Special +}; + +class LogOutputStreamBase +{ +public: + LogOutputStreamBase(char const* _id, std::type_info const* _info, unsigned _v, bool _autospacing); + + void comment(std::string const& _t) + { + switch (m_logTag) + { + case LogTag::Url: m_sstr << EthNavyUnder; break; + case LogTag::Error: m_sstr << EthRedBold; break; + case LogTag::Special: m_sstr << EthWhiteBold; break; + default:; + } + m_sstr << _t << EthReset; + m_logTag = LogTag::None; + } + + void append(unsigned long _t) { m_sstr << EthBlue << _t << EthReset; } + void append(long _t) { m_sstr << EthBlue << _t << EthReset; } + void append(unsigned int _t) { m_sstr << EthBlue << _t << EthReset; } + void append(int _t) { m_sstr << EthBlue << _t << EthReset; } + void append(bigint const& _t) { m_sstr << EthNavy << _t << EthReset; } + void append(u256 const& _t) { m_sstr << EthNavy << _t << EthReset; } + void append(u160 const& _t) { m_sstr << EthNavy << _t << EthReset; } + void append(double _t) { m_sstr << EthBlue << _t << EthReset; } + template void append(FixedHash const& _t) { m_sstr << EthTeal "#" << _t.abridged() << EthReset; } + void append(h160 const& _t) { m_sstr << EthRed "@" << _t.abridged() << EthReset; } + void append(h256 const& _t) { m_sstr << EthCyan "#" << _t.abridged() << EthReset; } + void append(h512 const& _t) { m_sstr << EthTeal "##" << _t.abridged() << EthReset; } + void append(std::string const& _t) { m_sstr << EthGreen "\"" + _t + "\"" EthReset; } + void append(bytes const& _t) { m_sstr << EthYellow "%" << toHex(_t) << EthReset; } + void append(bytesConstRef _t) { m_sstr << EthYellow "%" << toHex(_t) << EthReset; } +#if !defined(ETH_EMSCRIPTEN) + void append(boost::asio::ip::basic_endpoint const& _t); +#endif + template void append(std::vector const& _t) + { + m_sstr << EthWhite "[" EthReset; + int n = 0; + for (auto const& i : _t) + { + m_sstr << (n++ ? EthWhite ", " EthReset : ""); + append(i); + } + m_sstr << EthWhite "]" EthReset; + } + template void append(std::set const& _t) + { + m_sstr << EthYellow "{" EthReset; + int n = 0; + for (auto const& i : _t) + { + m_sstr << (n++ ? EthYellow ", " EthReset : ""); + append(i); + } + m_sstr << EthYellow "}" EthReset; + } + template void append(std::map const& _t) + { + m_sstr << EthLime "{" EthReset; + int n = 0; + for (auto const& i : _t) + { + m_sstr << (n++ ? EthLime ", " EthReset : ""); + append(i.first); + m_sstr << (n++ ? EthLime ": " EthReset : ""); + append(i.second); + } + m_sstr << EthLime "}" EthReset; + } + template void append(std::unordered_set const& _t) + { + m_sstr << EthYellow "{" EthReset; + int n = 0; + for (auto const& i : _t) + { + m_sstr << (n++ ? EthYellow ", " EthReset : ""); + append(i); + } + m_sstr << EthYellow "}" EthReset; + } + template void append(std::unordered_map const& _t) + { + m_sstr << EthLime "{" EthReset; + int n = 0; + for (auto const& i : _t) + { + m_sstr << (n++ ? EthLime ", " EthReset : ""); + append(i.first); + m_sstr << (n++ ? EthLime ": " EthReset : ""); + append(i.second); + } + m_sstr << EthLime "}" EthReset; + } + template void append(std::pair const& _t) + { + m_sstr << EthPurple "(" EthReset; + append(_t.first); + m_sstr << EthPurple ", " EthReset; + append(_t.second); + m_sstr << EthPurple ")" EthReset; + } + template void append(T const& _t) + { + m_sstr << toString(_t); + } + +protected: + bool m_autospacing = false; + unsigned m_verbosity = 0; + std::stringstream m_sstr; ///< The accrued log entry. + LogTag m_logTag = LogTag::None; +}; + +/// Logging class, iostream-like, that can be shifted to. +template +class LogOutputStream: LogOutputStreamBase +{ +public: + /// Construct a new object. + /// If _term is true the the prefix info is terminated with a ']' character; if not it ends only with a '|' character. + LogOutputStream(): LogOutputStreamBase(Id::name(), &typeid(Id), Id::verbosity, _AutoSpacing) {} + + /// Destructor. Posts the accrued log entry to the g_logPost function. + ~LogOutputStream() + { + if (Id::verbosity <= g_logVerbosity) //g_logPost(m_sstr.str(), Id::name()); + { + //g_logPost(m_sstr.str(), Id::name()); + + //改用新log + if ( Id::verbosity >= 8 ) + { + LOG(TRACE) << Id::name() << "|" << m_sstr.str(); + } + else if ( Id::verbosity >= 4 ) + { + LOG(DEBUG) << Id::name() << "|" << m_sstr.str(); + //LOG(TRACE) < LogOutputStream& operator<<(T const& _t) { if (Id::verbosity <= g_logVerbosity) { if (_AutoSpacing && m_sstr.str().size() && m_sstr.str().back() != ' ') m_sstr << " "; append(_t); } return *this; } +}; + +/// A "hacky" way to execute the next statement on COND. +/// We need such a thing due to the dangling else problem and the need +/// for the logging macros to end with the stream object and not a closing brace '}' +#define DEV_STATEMENT_IF(COND) for (bool i_eth_if_ = (COND); i_eth_if_; i_eth_if_ = false) +/// A "hacky" way to skip the next statement. +/// We need such a thing due to the dangling else problem and the need +/// for the logging macros to end with the stream object and not a closing brace '}' +#define DEV_STATEMENT_SKIP() while (/*CONSTCOND*/ false) /*NOTREACHED*/ +// Kill all logs when when NLOG is defined. +#if NLOG +#define clog(X) nlog(X) +#define cslog(X) nslog(X) +#else +#if NDEBUG +#define clog(X) DEV_STATEMENT_IF(!(X::debug)) dev::LogOutputStream() +#define cslog(X) DEV_STATEMENT_IF(!(X::debug)) dev::LogOutputStream() +#else +#define clog(X) dev::LogOutputStream() +#define cslog(X) dev::LogOutputStream() +#endif +#endif + +// Simple cout-like stream objects for accessing common log channels. +// Dirties the global namespace, but oh so convenient... +#define cdebug clog(dev::DebugChannel) +#define cnote clog(dev::NoteChannel) +#define cwarn clog(dev::WarnChannel) +#define ctrace clog(dev::TraceChannel) +#define ctxstat clog(dev::TxStatChannel) +#define cblockstat clog(dev::BlockStatChannel) + +// Null stream-like objects. +#define ndebug DEV_STATEMENT_SKIP() dev::NullOutputStream() +#define nlog(X) DEV_STATEMENT_SKIP() dev::NullOutputStream() +#define nslog(X) DEV_STATEMENT_SKIP() dev::NullOutputStream() + +#define DEV_BLOCK_STAT_LOG(_hash, _blk, _timestamp, _desc) clog(dev::BlockStatChannel) << "BLOCK_TIMESTAMP_STAT:[" << toString(_hash) <<"][" << _blk << "][" << _timestamp << "][" << _desc << "]" + +} diff --git a/libdevcore/MemoryDB.cpp b/libdevcore/MemoryDB.cpp new file mode 100644 index 0000000000..b3b82093b0 --- /dev/null +++ b/libdevcore/MemoryDB.cpp @@ -0,0 +1,191 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file MemoryDB.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "Common.h" +#include "MemoryDB.h" +using namespace std; +using namespace dev; + +namespace dev +{ + +const char* DBChannel::name() { return "TDB"; } +const char* DBWarn::name() { return "TDB"; } + +std::unordered_map MemoryDB::get() const +{ +#if DEV_GUARDED_DB + ReadGuard l(x_this); +#endif + std::unordered_map ret; + for (auto const& i: m_main) + if (!m_enforceRefs || i.second.second > 0) + ret.insert(make_pair(i.first, i.second.first)); + return ret; +} + +MemoryDB& MemoryDB::operator=(MemoryDB const& _c) +{ + if (this == &_c) + return *this; +#if DEV_GUARDED_DB + ReadGuard l(_c.x_this); + WriteGuard l2(x_this); +#endif + m_main = _c.m_main; + m_aux = _c.m_aux; + return *this; +} + +std::string MemoryDB::lookup(h256 const& _h) const +{ +#if DEV_GUARDED_DB + ReadGuard l(x_this); +#endif + auto it = m_main.find(_h); + if (it != m_main.end()) + { + if (!m_enforceRefs || it->second.second > 0) + return it->second.first; + else + LOG(WARNING) << "Lookup required for value with refcount == 0. This is probably a critical trie issue" << _h; + } + return std::string(); +} + +bool MemoryDB::exists(h256 const& _h) const +{ +#if DEV_GUARDED_DB + ReadGuard l(x_this); +#endif + auto it = m_main.find(_h); + if (it != m_main.end() && (!m_enforceRefs || it->second.second > 0)) + return true; + return false; +} + +void MemoryDB::insert(h256 const& _h, bytesConstRef _v) +{ +#if DEV_GUARDED_DB + WriteGuard l(x_this); +#endif + auto it = m_main.find(_h); + if (it != m_main.end()) + { + it->second.first = _v.toString(); + it->second.second++; + } + else + m_main[_h] = make_pair(_v.toString(), 1); +#if ETH_PARANOIA + dbdebug << "INST" << _h << "=>" << m_main[_h].second; +#endif +} + +bool MemoryDB::kill(h256 const& _h) +{ +#if DEV_GUARDED_DB + ReadGuard l(x_this); +#endif + if (m_main.count(_h)) + { + if (m_main[_h].second > 0) + { + m_main[_h].second--; + return true; + } +#if ETH_PARANOIA + else + { + // If we get to this point, then there was probably a node in the level DB which we need to remove and which we have previously + // used as part of the memory-based MemoryDB. Nothing to be worried about *as long as the node exists in the DB*. + dbdebug << "NOKILL-WAS" << _h; + } + dbdebug << "KILL" << _h << "=>" << m_main[_h].second; + } + else + { + dbdebug << "NOKILL" << _h; +#endif + } + return false; +} + +bytes MemoryDB::lookupAux(h256 const& _h) const +{ +#if DEV_GUARDED_DB + ReadGuard l(x_this); +#endif + auto it = m_aux.find(_h); + if (it != m_aux.end() && (!m_enforceRefs || it->second.second)) + return it->second.first; + return bytes(); +} + +void MemoryDB::removeAux(h256 const& _h) +{ +#if DEV_GUARDED_DB + WriteGuard l(x_this); +#endif + m_aux[_h].second = false; +} + +void MemoryDB::insertAux(h256 const& _h, bytesConstRef _v) +{ +#if DEV_GUARDED_DB + WriteGuard l(x_this); +#endif + m_aux[_h] = make_pair(_v.toBytes(), true); +} + +void MemoryDB::purge() +{ +#if DEV_GUARDED_DB + WriteGuard l(x_this); +#endif + // purge m_main + for (auto it = m_main.begin(); it != m_main.end(); ) + if (it->second.second) + ++it; + else + it = m_main.erase(it); + + // purge m_aux + for (auto it = m_aux.begin(); it != m_aux.end(); ) + if (it->second.second) + ++it; + else + it = m_aux.erase(it); +} + +h256Hash MemoryDB::keys() const +{ +#if DEV_GUARDED_DB + ReadGuard l(x_this); +#endif + h256Hash ret; + for (auto const& i: m_main) + if (i.second.second) + ret.insert(i.first); + return ret; +} + +} diff --git a/libdevcore/MemoryDB.h b/libdevcore/MemoryDB.h new file mode 100644 index 0000000000..3db75c69e9 --- /dev/null +++ b/libdevcore/MemoryDB.h @@ -0,0 +1,99 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file MemoryDB.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include "Common.h" +#include "Guards.h" +#include "FixedHash.h" +#include "Log.h" +#include "RLP.h" +#include "SHA3.h" + +namespace dev +{ + +struct DBChannel: public LogChannel { static const char* name(); static const int verbosity = 18; }; +struct DBWarn: public LogChannel { static const char* name(); static const int verbosity = 1; }; + +#define dbdebug clog(DBChannel) +#define dbwarn clog(DBWarn) + +class MemoryDB +{ + friend class EnforceRefs; + +public: + MemoryDB() {} + MemoryDB(MemoryDB const& _c) { operator=(_c); } + + MemoryDB& operator=(MemoryDB const& _c); + + void clear() { m_main.clear(); m_aux.clear(); } // WARNING !!!! didn't originally clear m_refCount!!! + std::unordered_map get() const; + + std::string lookup(h256 const& _h) const; + bool exists(h256 const& _h) const; + void insert(h256 const& _h, bytesConstRef _v); + bool kill(h256 const& _h); + void purge(); + + bytes lookupAux(h256 const& _h) const; + void removeAux(h256 const& _h); + void insertAux(h256 const& _h, bytesConstRef _v); + + h256Hash keys() const; + +protected: +#if DEV_GUARDED_DB + mutable SharedMutex x_this; +#endif + std::unordered_map> m_main; + std::unordered_map> m_aux; + + mutable bool m_enforceRefs = false; +}; + +class EnforceRefs +{ +public: + EnforceRefs(MemoryDB const& _o, bool _r): m_o(_o), m_r(_o.m_enforceRefs) { _o.m_enforceRefs = _r; } + ~EnforceRefs() { m_o.m_enforceRefs = m_r; } + +private: + MemoryDB const& m_o; + bool m_r; +}; + +inline std::ostream& operator<<(std::ostream& _out, MemoryDB const& _m) +{ + for (auto const& i: _m.get()) + { + _out << i.first << ": "; + _out << RLP(i.second); + _out << " " << toHex(i.second); + _out << std::endl; + } + return _out; +} + +} diff --git a/libdevcore/OverlayDB.cpp b/libdevcore/OverlayDB.cpp new file mode 100644 index 0000000000..6c4063c3be --- /dev/null +++ b/libdevcore/OverlayDB.cpp @@ -0,0 +1,180 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file OverlayDB.cpp + * @author Gav Wood + * @date 2014 + */ +#if !defined(ETH_EMSCRIPTEN) + +#include +#include +#include +#include "OverlayDB.h" +using namespace std; +using namespace dev; + +namespace dev +{ + +h256 const EmptyTrie = sha3(rlp("")); + +OverlayDB::~OverlayDB() +{ + if (m_db.use_count() == 1 && m_db.get()) + LOG(TRACE) << "Closing state DB"; +} + +class WriteBatchNoter: public ldb::WriteBatch::Handler +{ + virtual void Put(ldb::Slice const& _key, ldb::Slice const& _value) { cnote << "Put" << toHex(bytesConstRef(_key)) << "=>" << toHex(bytesConstRef(_value)); } + virtual void Delete(ldb::Slice const& _key) { cnote << "Delete" << toHex(bytesConstRef(_key)); } +}; + +void OverlayDB::commit() +{ + if (m_db) + { + ldb::WriteBatch batch; +// cnote << "Committing nodes to disk DB:"; +#if DEV_GUARDED_DB + DEV_READ_GUARDED(x_this) +#endif + { + for (auto const& i: m_main) + { + if (i.second.second) + { + batch.Put(ldb::Slice((char const*)i.first.data(), i.first.size), ldb::Slice(i.second.first.data(), i.second.first.size())); + } + } + for (auto const& i: m_aux) + if (i.second.second) + { + bytes b = i.first.asBytes(); + b.push_back(255); // for aux + batch.Put(bytesConstRef(&b), bytesConstRef(&i.second.first)); + } + } + + for (unsigned i = 0; i < 10; ++i) + { + ldb::Status o = m_db->Write(m_writeOptions, &batch); + if (o.ok()) + break; + if (i == 9) + { + LOG(WARNING) << "Fail writing to state database. Bombing out."; + exit(-1); + } + LOG(WARNING) << "Error writing to state database: " << o.ToString(); + WriteBatchNoter n; + batch.Iterate(&n); + LOG(WARNING) << "Sleeping for" << (i + 1) << "seconds, then retrying."; + this_thread::sleep_for(chrono::seconds(i + 1)); + } +#if DEV_GUARDED_DB + DEV_WRITE_GUARDED(x_this) +#endif + { + m_aux.clear(); + m_main.clear(); + } + } +} + +bytes OverlayDB::lookupAux(h256 const& _h) const +{ + bytes ret = MemoryDB::lookupAux(_h); + if (!ret.empty() || !m_db) + return ret; + std::string v; + bytes b = _h.asBytes(); + b.push_back(255); // for aux + m_db->Get(m_readOptions, bytesConstRef(&b), &v); + if (v.empty()) + LOG(WARNING) << "Aux not found: " << _h; + return asBytes(v); +} + +void OverlayDB::rollback() +{ +#if DEV_GUARDED_DB + WriteGuard l(x_this); +#endif + m_main.clear(); +} + +std::string OverlayDB::lookup(h256 const& _h) const +{ + std::string ret = MemoryDB::lookup(_h); + if (ret.empty() && m_db) + { + m_db->Get(m_readOptions, ldb::Slice((char const*)_h.data(), 32), &ret); + } + return ret; +} + +bool OverlayDB::exists(h256 const& _h) const +{ + if (MemoryDB::exists(_h)) + { + return true; + } + std::string ret; + if (m_db) + { + m_db->Get(m_readOptions, ldb::Slice((char const*)_h.data(), 32), &ret); + } + return !ret.empty(); +} + +void OverlayDB::kill(h256 const& _h) +{ +#if ETH_PARANOIA || 1 + if (!MemoryDB::kill(_h)) + { + std::string ret; + if (m_db) + m_db->Get(m_readOptions, ldb::Slice((char const*)_h.data(), 32), &ret); + // No point node ref decreasing for EmptyTrie since we never bother incrementing it in the first place for + // empty storage tries. + if (ret.empty() && _h != EmptyTrie) + cnote << "Decreasing DB node ref count below zero with no DB node. Probably have a corrupt Trie." << _h; + + // TODO: for 1.1: ref-counted triedb. + } +#else + MemoryDB::kill(_h); +#endif +} + +bool OverlayDB::deepkill(h256 const& _h) +{ + // kill in memoryDB + kill(_h); + + //kill in overlayDB + ldb::Status s = m_db->Delete(m_writeOptions, ldb::Slice((char const*)_h.data(), 32)); + if (s.ok()) + return true; + else + return false; +} + +} + +#endif // ETH_EMSCRIPTEN diff --git a/libdevcore/OverlayDB.h b/libdevcore/OverlayDB.h new file mode 100644 index 0000000000..fa1af69757 --- /dev/null +++ b/libdevcore/OverlayDB.h @@ -0,0 +1,70 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file OverlayDB.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include +#include +#include +#include + +//жǷodbc +#if defined ETH_HAVE_ODBC +#include "" +#endif + +namespace dev +{ + +class OverlayDB: public MemoryDB +{ +public: + OverlayDB(ldb::DB* _db = nullptr): m_db(_db) {} + ~OverlayDB(); + + ldb::DB* db() const { return m_db.get(); } + + void commit(); + void rollback(); + + std::string lookup(h256 const& _h) const; + bool exists(h256 const& _h) const; + void kill(h256 const& _h); + bool deepkill(h256 const& _h); + + bytes lookupAux(h256 const& _h) const; + +private: + using MemoryDB::clear; + + //жǷodbc + #if defined ETH_HAVE_ODBC + std::shared_ptr m_db; + #else + std::shared_ptr m_db; + #endif + + ldb::ReadOptions m_readOptions; + ldb::WriteOptions m_writeOptions; +}; + +} diff --git a/libdevcore/RLP.cpp b/libdevcore/RLP.cpp new file mode 100644 index 0000000000..216abda587 --- /dev/null +++ b/libdevcore/RLP.cpp @@ -0,0 +1,378 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file RLP.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "RLP.h" +using namespace std; +using namespace dev; + +bytes dev::RLPNull = rlp(""); +bytes dev::RLPEmptyList = rlpList(); + +RLP::RLP(bytesConstRef _d, Strictness _s): + m_data(_d) +{ + if ((_s & FailIfTooBig) && actualSize() < _d.size()) + { + if (_s & ThrowOnFail) + BOOST_THROW_EXCEPTION(OversizeRLP()); + else + m_data.reset(); + } + if ((_s & FailIfTooSmall) && actualSize() > _d.size()) + { + if (_s & ThrowOnFail) + BOOST_THROW_EXCEPTION(UndersizeRLP()); + else + m_data.reset(); + } +} + +RLP::iterator& RLP::iterator::operator++() +{ + if (m_remaining) + { + m_currentItem.retarget(m_currentItem.next().data(), m_remaining); + m_currentItem = m_currentItem.cropped(0, sizeAsEncoded(m_currentItem)); + m_remaining -= std::min(m_remaining, m_currentItem.size()); + } + else + m_currentItem.retarget(m_currentItem.next().data(), 0); + return *this; +} + +RLP::iterator::iterator(RLP const& _parent, bool _begin) +{ + if (_begin && _parent.isList()) + { + auto pl = _parent.payload(); + m_currentItem = pl.cropped(0, sizeAsEncoded(pl)); + m_remaining = pl.size() - m_currentItem.size(); + } + else + { + m_currentItem = _parent.data().cropped(_parent.data().size()); + m_remaining = 0; + } +} + +RLP RLP::operator[](size_t _i) const +{ + if (_i < m_lastIndex) + { + m_lastEnd = sizeAsEncoded(payload()); + m_lastItem = payload().cropped(0, m_lastEnd); + m_lastIndex = 0; + } + for (; m_lastIndex < _i && m_lastItem.size(); ++m_lastIndex) + { + m_lastItem = payload().cropped(m_lastEnd); + m_lastItem = m_lastItem.cropped(0, sizeAsEncoded(m_lastItem)); + m_lastEnd += m_lastItem.size(); + } + return RLP(m_lastItem, ThrowOnFail | FailIfTooSmall); +} + +RLPs RLP::toList(int _flags) const +{ + RLPs ret; + if (!isList()) + { + if (_flags & ThrowOnFail) + BOOST_THROW_EXCEPTION(BadCast()); + else + return ret; + } + for (auto const& i: *this) + ret.push_back(i); + return ret; +} + +size_t RLP::actualSize() const +{ + if (isNull()) + return 0; + if (isSingleByte()) + return 1; + if (isData() || isList()) + return payloadOffset() + length(); + return 0; +} + +void RLP::requireGood() const +{ + if (isNull()) + BOOST_THROW_EXCEPTION(BadRLP()); + byte n = m_data[0]; + if (n != c_rlpDataImmLenStart + 1) + return; + if (m_data.size() < 2) + BOOST_THROW_EXCEPTION(BadRLP()); + if (m_data[1] < c_rlpDataImmLenStart) + BOOST_THROW_EXCEPTION(BadRLP()); +} + +bool RLP::isInt() const +{ + if (isNull()) + return false; + requireGood(); + byte n = m_data[0]; + if (n < c_rlpDataImmLenStart) + return !!n; + else if (n == c_rlpDataImmLenStart) + return true; + else if (n <= c_rlpDataIndLenZero) + { + if (m_data.size() <= 1) + BOOST_THROW_EXCEPTION(BadRLP()); + return m_data[1] != 0; + } + else if (n < c_rlpListStart) + { + if (m_data.size() <= size_t(1 + n - c_rlpDataIndLenZero)) + BOOST_THROW_EXCEPTION(BadRLP()); + return m_data[1 + n - c_rlpDataIndLenZero] != 0; + } + else + return false; + return false; +} + +size_t RLP::length() const +{ + if (isNull()) + return 0; + requireGood(); + size_t ret = 0; + byte const n = m_data[0]; + if (n < c_rlpDataImmLenStart) + return 1; + else if (n <= c_rlpDataIndLenZero) + return n - c_rlpDataImmLenStart; + else if (n < c_rlpListStart) + { + if (m_data.size() <= size_t(n - c_rlpDataIndLenZero)) + BOOST_THROW_EXCEPTION(BadRLP()); + if (m_data.size() > 1) + if (m_data[1] == 0) + BOOST_THROW_EXCEPTION(BadRLP()); + unsigned lengthSize = n - c_rlpDataIndLenZero; + if (lengthSize > sizeof(ret)) + // We did not check, but would most probably not fit in our memory. + BOOST_THROW_EXCEPTION(UndersizeRLP()); + // No leading zeroes. + if (!m_data[1]) + BOOST_THROW_EXCEPTION(BadRLP()); + for (unsigned i = 0; i < lengthSize; ++i) + ret = (ret << 8) | m_data[i + 1]; + // Must be greater than the limit. + if (ret < c_rlpListStart - c_rlpDataImmLenStart - c_rlpMaxLengthBytes) + BOOST_THROW_EXCEPTION(BadRLP()); + } + else if (n <= c_rlpListIndLenZero) + return n - c_rlpListStart; + else + { + unsigned lengthSize = n - c_rlpListIndLenZero; + if (m_data.size() <= lengthSize) + BOOST_THROW_EXCEPTION(BadRLP()); + if (m_data.size() > 1) + if (m_data[1] == 0) + BOOST_THROW_EXCEPTION(BadRLP()); + if (lengthSize > sizeof(ret)) + // We did not check, but would most probably not fit in our memory. + BOOST_THROW_EXCEPTION(UndersizeRLP()); + if (!m_data[1]) + BOOST_THROW_EXCEPTION(BadRLP()); + for (unsigned i = 0; i < lengthSize; ++i) + ret = (ret << 8) | m_data[i + 1]; + if (ret < 0x100 - c_rlpListStart - c_rlpMaxLengthBytes) + BOOST_THROW_EXCEPTION(BadRLP()); + } + // We have to be able to add payloadOffset to length without overflow. + // This rejects roughly 4GB-sized RLPs on some platforms. + if (ret >= std::numeric_limits::max() - 0x100) + BOOST_THROW_EXCEPTION(UndersizeRLP()); + return ret; +} + +size_t RLP::items() const +{ + if (isList()) + { + bytesConstRef d = payload(); + size_t i = 0; + for (; d.size(); ++i) + d = d.cropped(sizeAsEncoded(d)); + return i; + } + return 0; +} + +RLPStream& RLPStream::appendRaw(bytesConstRef _s, size_t _itemCount) +{ + m_out.insert(m_out.end(), _s.begin(), _s.end()); + noteAppended(_itemCount); + return *this; +} + +void RLPStream::noteAppended(size_t _itemCount) +{ + if (!_itemCount) + return; +// LOG(DEBUG) << "noteAppended(" << _itemCount << ")"; + while (m_listStack.size()) + { + if (m_listStack.back().first < _itemCount) + BOOST_THROW_EXCEPTION(RLPException() << errinfo_comment("itemCount too large") << RequirementError((bigint)m_listStack.back().first, (bigint)_itemCount)); + m_listStack.back().first -= _itemCount; + if (m_listStack.back().first) + break; + else + { + auto p = m_listStack.back().second; + m_listStack.pop_back(); + size_t s = m_out.size() - p; // list size + auto brs = bytesRequired(s); + unsigned encodeSize = s < c_rlpListImmLenCount ? 1 : (1 + brs); +// LOG(DEBUG) << "s: " << s << ", p: " << p << ", m_out.size(): " << m_out.size() << ", encodeSize: " << encodeSize << " (br: " << brs << ")"; + auto os = m_out.size(); + m_out.resize(os + encodeSize); + memmove(m_out.data() + p + encodeSize, m_out.data() + p, os - p); + if (s < c_rlpListImmLenCount) + m_out[p] = (byte)(c_rlpListStart + s); + else if (c_rlpListIndLenZero + brs <= 0xff) + { + m_out[p] = (byte)(c_rlpListIndLenZero + brs); + byte* b = &(m_out[p + brs]); + for (; s; s >>= 8) + *(b--) = (byte)s; + } + else + BOOST_THROW_EXCEPTION(RLPException() << errinfo_comment("itemCount too large for RLP")); + } + _itemCount = 1; // for all following iterations, we've effectively appended a single item only since we completed a list. + } +} + +RLPStream& RLPStream::appendList(size_t _items) +{ +// LOG(DEBUG) << "appendList(" << _items << ")"; + if (_items) + m_listStack.push_back(std::make_pair(_items, m_out.size())); + else + appendList(bytes()); + return *this; +} + +RLPStream& RLPStream::appendList(bytesConstRef _rlp) +{ + if (_rlp.size() < c_rlpListImmLenCount) + m_out.push_back((byte)(_rlp.size() + c_rlpListStart)); + else + pushCount(_rlp.size(), c_rlpListIndLenZero); + appendRaw(_rlp, 1); + return *this; +} + +RLPStream& RLPStream::append(bytesConstRef _s, bool _compact) +{ + size_t s = _s.size(); + byte const* d = _s.data(); + if (_compact) + for (size_t i = 0; i < _s.size() && !*d; ++i, --s, ++d) {} + + if (s == 1 && *d < c_rlpDataImmLenStart) + m_out.push_back(*d); + else + { + if (s < c_rlpDataImmLenCount) + m_out.push_back((byte)(s + c_rlpDataImmLenStart)); + else + pushCount(s, c_rlpDataIndLenZero); + appendRaw(bytesConstRef(d, s), 0); + } + noteAppended(); + return *this; +} + +RLPStream& RLPStream::append(bigint _i) +{ + if (!_i) + m_out.push_back(c_rlpDataImmLenStart); + else if (_i < c_rlpDataImmLenStart) + m_out.push_back((byte)_i); + else + { + unsigned br = bytesRequired(_i); + if (br < c_rlpDataImmLenCount) + m_out.push_back((byte)(br + c_rlpDataImmLenStart)); + else + { + auto brbr = bytesRequired(br); + if (c_rlpDataIndLenZero + brbr > 0xff) + BOOST_THROW_EXCEPTION(RLPException() << errinfo_comment("Number too large for RLP")); + m_out.push_back((byte)(c_rlpDataIndLenZero + brbr)); + pushInt(br, brbr); + } + pushInt(_i, br); + } + noteAppended(); + return *this; +} + +void RLPStream::pushCount(size_t _count, byte _base) +{ + auto br = bytesRequired(_count); + if (int(br) + _base > 0xff) + BOOST_THROW_EXCEPTION(RLPException() << errinfo_comment("Count too large for RLP")); + m_out.push_back((byte)(br + _base)); // max 8 bytes. + pushInt(_count, br); +} + +static void streamOut(std::ostream& _out, dev::RLP const& _d, unsigned _depth = 0) +{ + if (_depth > 64) + _out << ""; + else if (_d.isNull()) + _out << "null"; + else if (_d.isInt()) + _out << std::showbase << std::hex << std::nouppercase << _d.toInt(RLP::LaissezFaire) << dec; + else if (_d.isData()) + _out << escaped(_d.toString(), false); + else if (_d.isList()) + { + _out << "["; + int j = 0; + for (auto i: _d) + { + _out << (j++ ? ", " : " "); + streamOut(_out, i, _depth + 1); + } + _out << " ]"; + } +} + +std::ostream& dev::operator<<(std::ostream& _out, RLP const& _d) +{ + streamOut(_out, _d); + return _out; +} diff --git a/libdevcore/RLP.h b/libdevcore/RLP.h new file mode 100644 index 0000000000..638940d1ea --- /dev/null +++ b/libdevcore/RLP.h @@ -0,0 +1,487 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file RLP.h + * @author Gav Wood + * @date 2014 + * + * RLP (de-)serialisation. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include "vector_ref.h" +#include "Common.h" +#include "Exceptions.h" +#include "FixedHash.h" + +namespace dev +{ + +class RLP; +using RLPs = std::vector; + +template struct intTraits { static const unsigned maxSize = sizeof(_T); }; +template <> struct intTraits { static const unsigned maxSize = 20; }; +template <> struct intTraits { static const unsigned maxSize = 32; }; +template <> struct intTraits { static const unsigned maxSize = ~(unsigned)0; }; + +static const byte c_rlpMaxLengthBytes = 8; +static const byte c_rlpDataImmLenStart = 0x80; +static const byte c_rlpListStart = 0xc0; + +static const byte c_rlpDataImmLenCount = c_rlpListStart - c_rlpDataImmLenStart - c_rlpMaxLengthBytes; +static const byte c_rlpDataIndLenZero = c_rlpDataImmLenStart + c_rlpDataImmLenCount - 1; +static const byte c_rlpListImmLenCount = 256 - c_rlpListStart - c_rlpMaxLengthBytes; +static const byte c_rlpListIndLenZero = c_rlpListStart + c_rlpListImmLenCount - 1; + +template struct Converter { static T convert(RLP const&, int) { BOOST_THROW_EXCEPTION(BadCast()); } }; + +/** + * @brief Class for interpreting Recursive Linear-Prefix Data. + * @by Gav Wood, 2013 + * + * Class for reading byte arrays of data in RLP format. + */ +class RLP +{ +public: + /// Conversion flags + enum + { + AllowNonCanon = 1, + ThrowOnFail = 4, + FailIfTooBig = 8, + FailIfTooSmall = 16, + Strict = ThrowOnFail | FailIfTooBig, + VeryStrict = ThrowOnFail | FailIfTooBig | FailIfTooSmall, + LaissezFaire = AllowNonCanon + }; + + using Strictness = int; + + /// Construct a null node. + RLP() {} + + /// Construct a node of value given in the bytes. + explicit RLP(bytesConstRef _d, Strictness _s = VeryStrict); + + /// Construct a node of value given in the bytes. + explicit RLP(bytes const& _d, Strictness _s = VeryStrict): RLP(&_d, _s) {} + + /// Construct a node to read RLP data in the bytes given. + RLP(byte const* _b, unsigned _s, Strictness _st = VeryStrict): RLP(bytesConstRef(_b, _s), _st) {} + + /// Construct a node to read RLP data in the string. + explicit RLP(std::string const& _s, Strictness _st = VeryStrict): RLP(bytesConstRef((byte const*)_s.data(), _s.size()), _st) {} + + /// The bare data of the RLP. + bytesConstRef data() const { return m_data; } + + /// @returns true if the RLP is non-null. + explicit operator bool() const { return !isNull(); } + + /// No value. + bool isNull() const { return m_data.size() == 0; } + + /// Contains a zero-length string or zero-length list. + bool isEmpty() const { return !isNull() && (m_data[0] == c_rlpDataImmLenStart || m_data[0] == c_rlpListStart); } + + /// String value. + bool isData() const { return !isNull() && m_data[0] < c_rlpListStart; } + + /// List value. + bool isList() const { return !isNull() && m_data[0] >= c_rlpListStart; } + + /// Integer value. Must not have a leading zero. + bool isInt() const; + + /// @returns the number of items in the list, or zero if it isn't a list. + size_t itemCount() const { return isList() ? items() : 0; } + size_t itemCountStrict() const { if (!isList()) BOOST_THROW_EXCEPTION(BadCast()); return items(); } + + /// @returns the number of bytes in the data, or zero if it isn't data. + size_t size() const { return isData() ? length() : 0; } + size_t sizeStrict() const { if (!isData()) BOOST_THROW_EXCEPTION(BadCast()); return length(); } + + /// Equality operators; does best-effort conversion and checks for equality. + bool operator==(char const* _s) const { return isData() && toString() == _s; } + bool operator!=(char const* _s) const { return isData() && toString() != _s; } + bool operator==(std::string const& _s) const { return isData() && toString() == _s; } + bool operator!=(std::string const& _s) const { return isData() && toString() != _s; } + template bool operator==(FixedHash<_N> const& _h) const { return isData() && toHash<_N>() == _h; } + template bool operator!=(FixedHash<_N> const& _s) const { return isData() && toHash<_N>() != _s; } + bool operator==(unsigned const& _i) const { return isInt() && toInt() == _i; } + bool operator!=(unsigned const& _i) const { return isInt() && toInt() != _i; } + bool operator==(u256 const& _i) const { return isInt() && toInt() == _i; } + bool operator!=(u256 const& _i) const { return isInt() && toInt() != _i; } + bool operator==(bigint const& _i) const { return isInt() && toInt() == _i; } + bool operator!=(bigint const& _i) const { return isInt() && toInt() != _i; } + + /// Subscript operator. + /// @returns the list item @a _i if isList() and @a _i < listItems(), or RLP() otherwise. + /// @note if used to access items in ascending order, this is efficient. + RLP operator[](size_t _i) const; + + using element_type = RLP; + + /// @brief Iterator class for iterating through items of RLP list. + class iterator + { + friend class RLP; + + public: + using value_type = RLP; + using element_type = RLP; + + iterator& operator++(); + iterator operator++(int) { auto ret = *this; operator++(); return ret; } + RLP operator*() const { return RLP(m_currentItem); } + bool operator==(iterator const& _cmp) const { return m_currentItem == _cmp.m_currentItem; } + bool operator!=(iterator const& _cmp) const { return !operator==(_cmp); } + + private: + iterator() {} + iterator(RLP const& _parent, bool _begin); + + size_t m_remaining = 0; + bytesConstRef m_currentItem; + }; + + /// @brief Iterator into beginning of sub-item list (valid only if we are a list). + iterator begin() const { return iterator(*this, true); } + + /// @brief Iterator into end of sub-item list (valid only if we are a list). + iterator end() const { return iterator(*this, false); } + + template inline T convert(int _flags) const; + + /// Best-effort conversion operators. + explicit operator std::string() const { return toString(); } + explicit operator bytes() const { return toBytes(); } + explicit operator RLPs() const { return toList(); } + explicit operator uint8_t() const { return toInt(); } + explicit operator uint16_t() const { return toInt(); } + explicit operator uint32_t() const { return toInt(); } + explicit operator uint64_t() const { return toInt(); } + explicit operator u160() const { return toInt(); } + explicit operator u256() const { return toInt(); } + explicit operator bigint() const { return toInt(); } + template explicit operator FixedHash() const { return toHash>(); } + template explicit operator std::pair() const { return toPair(); } + template explicit operator std::vector() const { return toVector(); } + template explicit operator std::set() const { return toSet(); } + template explicit operator std::array() const { return toArray(); } + + /// Converts to bytearray. @returns the empty byte array if not a string. + bytes toBytes(int _flags = LaissezFaire) const { if (!isData()) { if (_flags & ThrowOnFail) BOOST_THROW_EXCEPTION(BadCast()); else return bytes(); } return bytes(payload().data(), payload().data() + length()); } + /// Converts to bytearray. @returns the empty byte array if not a string. + bytesConstRef toBytesConstRef(int _flags = LaissezFaire) const { if (!isData()) { if (_flags & ThrowOnFail) BOOST_THROW_EXCEPTION(BadCast()); else return bytesConstRef(); } return payload().cropped(0, length()); } + /// Converts to string. @returns the empty string if not a string. + std::string toString(int _flags = LaissezFaire) const { if (!isData()) { if (_flags & ThrowOnFail) BOOST_THROW_EXCEPTION(BadCast()); else return std::string(); } return payload().cropped(0, length()).toString(); } + /// Converts to string. @throws BadCast if not a string. + std::string toStringStrict() const { return toString(Strict); } + + template + std::vector toVector(int _flags = LaissezFaire) const + { + std::vector ret; + if (isList()) + { + ret.reserve(itemCount()); + for (auto const& i: *this) + ret.push_back(i.convert(_flags)); + } + else if (_flags & ThrowOnFail) + BOOST_THROW_EXCEPTION(BadCast()); + return ret; + } + + template + std::set toSet(int _flags = LaissezFaire) const + { + std::set ret; + if (isList()) + for (auto const& i: *this) + ret.insert(i.convert(_flags)); + else if (_flags & ThrowOnFail) + BOOST_THROW_EXCEPTION(BadCast()); + return ret; + } + + template + std::unordered_set toUnorderedSet(int _flags = LaissezFaire) const + { + std::unordered_set ret; + if (isList()) + for (auto const& i: *this) + ret.insert(i.convert(_flags)); + else if (_flags & ThrowOnFail) + BOOST_THROW_EXCEPTION(BadCast()); + return ret; + } + + template + std::pair toPair(int _flags = Strict) const + { + std::pair ret; + if (itemCountStrict() != 2) + { + if (_flags & ThrowOnFail) + BOOST_THROW_EXCEPTION(BadCast()); + else + return ret; + } + ret.first = (*this)[0].convert(_flags); + ret.second = (*this)[1].convert(_flags); + return ret; + } + + template + std::array toArray(int _flags = LaissezFaire) const + { + if (itemCountStrict() != N) + { + if (_flags & ThrowOnFail) + BOOST_THROW_EXCEPTION(BadCast()); + else + return std::array(); + } + std::array ret; + for (size_t i = 0; i < N; ++i) + ret[i] = operator[](i).convert(_flags); + return ret; + } + + /// Converts to int of type given; if isString(), decodes as big-endian bytestream. @returns 0 if not an int or string. + template _T toInt(int _flags = Strict) const + { + requireGood(); + if ((!isInt() && !(_flags & AllowNonCanon)) || isList() || isNull()) + { + if (_flags & ThrowOnFail) + BOOST_THROW_EXCEPTION(BadCast()); + else + return 0; + } + + auto p = payload(); + if (p.size() > intTraits<_T>::maxSize && (_flags & FailIfTooBig)) + { + if (_flags & ThrowOnFail) + BOOST_THROW_EXCEPTION(BadCast()); + else + return 0; + } + + return fromBigEndian<_T>(p); + } + + template _N toHash(int _flags = Strict) const + { + requireGood(); + auto p = payload(); + auto l = p.size(); + if (!isData() || (l > _N::size && (_flags & FailIfTooBig)) || (l < _N::size && (_flags & FailIfTooSmall))) + { + if (_flags & ThrowOnFail) + BOOST_THROW_EXCEPTION(BadCast()); + else + return _N(); + } + + _N ret; + size_t s = std::min(_N::size, l); + memcpy(ret.data() + _N::size - s, p.data(), s); + return ret; + } + + /// Converts to RLPs collection object. Useful if you need random access to sub items or will iterate over multiple times. + RLPs toList(int _flags = Strict) const; + + /// @returns the data payload. Valid for all types. + bytesConstRef payload() const { auto l = length(); if (l > m_data.size()) BOOST_THROW_EXCEPTION(BadRLP()); return m_data.cropped(payloadOffset(), l); } + + /// @returns the theoretical size of this item as encoded in the data. + /// @note Under normal circumstances, is equivalent to m_data.size() - use that unless you know it won't work. + size_t actualSize() const; + +private: + /// Disable construction from rvalue + explicit RLP(bytes const&&) {} + + /// Throws if is non-canonical data (i.e. single byte done in two bytes that could be done in one). + void requireGood() const; + + /// Single-byte data payload. + bool isSingleByte() const { return !isNull() && m_data[0] < c_rlpDataImmLenStart; } + + /// @returns the amount of bytes used to encode the length of the data. Valid for all types. + unsigned lengthSize() const { if (isData() && m_data[0] > c_rlpDataIndLenZero) return m_data[0] - c_rlpDataIndLenZero; if (isList() && m_data[0] > c_rlpListIndLenZero) return m_data[0] - c_rlpListIndLenZero; return 0; } + + /// @returns the size in bytes of the payload, as given by the RLP as opposed to as inferred from m_data. + size_t length() const; + + /// @returns the number of bytes into the data that the payload starts. + size_t payloadOffset() const { return isSingleByte() ? 0 : (1 + lengthSize()); } + + /// @returns the number of data items. + size_t items() const; + + /// @returns the size encoded into the RLP in @a _data and throws if _data is too short. + static size_t sizeAsEncoded(bytesConstRef _data) { return RLP(_data, ThrowOnFail | FailIfTooSmall).actualSize(); } + + /// Our byte data. + bytesConstRef m_data; + + /// The list-indexing cache. + mutable size_t m_lastIndex = (size_t)-1; + mutable size_t m_lastEnd = 0; + mutable bytesConstRef m_lastItem; +}; + +template <> struct Converter { static std::string convert(RLP const& _r, int _flags) { return _r.toString(_flags); } }; +template <> struct Converter { static bytes convert(RLP const& _r, int _flags) { return _r.toBytes(_flags); } }; +template <> struct Converter { static RLPs convert(RLP const& _r, int _flags) { return _r.toList(_flags); } }; +template <> struct Converter { static uint8_t convert(RLP const& _r, int _flags) { return _r.toInt(_flags); } }; +template <> struct Converter { static uint16_t convert(RLP const& _r, int _flags) { return _r.toInt(_flags); } }; +template <> struct Converter { static uint32_t convert(RLP const& _r, int _flags) { return _r.toInt(_flags); } }; +template <> struct Converter { static uint64_t convert(RLP const& _r, int _flags) { return _r.toInt(_flags); } }; +template <> struct Converter { static u160 convert(RLP const& _r, int _flags) { return _r.toInt(_flags); } }; +template <> struct Converter { static u256 convert(RLP const& _r, int _flags) { return _r.toInt(_flags); } }; +template <> struct Converter { static bigint convert(RLP const& _r, int _flags) { return _r.toInt(_flags); } }; +template struct Converter> { static FixedHash convert(RLP const& _r, int _flags) { return _r.toHash>(_flags); } }; +template struct Converter> { static std::pair convert(RLP const& _r, int _flags) { return _r.toPair(_flags); } }; +template struct Converter> { static std::vector convert(RLP const& _r, int _flags) { return _r.toVector(_flags); } }; +template struct Converter> { static std::set convert(RLP const& _r, int _flags) { return _r.toSet(_flags); } }; +template struct Converter> { static std::unordered_set convert(RLP const& _r, int _flags) { return _r.toUnorderedSet(_flags); } }; +template struct Converter> { static std::array convert(RLP const& _r, int _flags) { return _r.toArray(_flags); } }; + +template inline T RLP::convert(int _flags) const { return Converter::convert(*this, _flags); } + +/** + * @brief Class for writing to an RLP bytestream. + */ +class RLPStream +{ +public: + /// Initializes empty RLPStream. + RLPStream() {} + + /// Initializes the RLPStream as a list of @a _listItems items. + explicit RLPStream(size_t _listItems) { appendList(_listItems); } + + ~RLPStream() {} + + /// Append given datum to the byte stream. + RLPStream& append(unsigned _s) { return append(bigint(_s)); } + RLPStream& append(u160 _s) { return append(bigint(_s)); } + RLPStream& append(u256 _s) { return append(bigint(_s)); } + RLPStream& append(bigint _s); + RLPStream& append(bytesConstRef _s, bool _compact = false); + RLPStream& append(bytes const& _s) { return append(bytesConstRef(&_s)); } + RLPStream& append(std::string const& _s) { return append(bytesConstRef(_s)); } + RLPStream& append(char const* _s) { return append(std::string(_s)); } + template RLPStream& append(FixedHash _s, bool _compact = false, bool _allOrNothing = false) { return _allOrNothing && !_s ? append(bytesConstRef()) : append(_s.ref(), _compact); } + + /// Appends an arbitrary RLP fragment - this *must* be a single item unless @a _itemCount is given. + RLPStream& append(RLP const& _rlp, size_t _itemCount = 1) { return appendRaw(_rlp.data(), _itemCount); } + + /// Appends a sequence of data to the stream as a list. + template RLPStream& append(std::vector<_T> const& _s) { return appendVector(_s); } + template RLPStream& appendVector(std::vector<_T> const& _s) { appendList(_s.size()); for (auto const& i: _s) append(i); return *this; } + template RLPStream& append(std::array<_T, S> const& _s) { appendList(_s.size()); for (auto const& i: _s) append(i); return *this; } + template RLPStream& append(std::set<_T> const& _s) { appendList(_s.size()); for (auto const& i: _s) append(i); return *this; } + template RLPStream& append(std::unordered_set<_T> const& _s) { appendList(_s.size()); for (auto const& i: _s) append(i); return *this; } + template RLPStream& append(std::pair const& _s) { appendList(2); append(_s.first); append(_s.second); return *this; } + + /// Appends a list. + RLPStream& appendList(size_t _items); + RLPStream& appendList(bytesConstRef _rlp); + RLPStream& appendList(bytes const& _rlp) { return appendList(&_rlp); } + RLPStream& appendList(RLPStream const& _s) { return appendList(&_s.out()); } + + /// Appends raw (pre-serialised) RLP data. Use with caution. + RLPStream& appendRaw(bytesConstRef _rlp, size_t _itemCount = 1); + RLPStream& appendRaw(bytes const& _rlp, size_t _itemCount = 1) { return appendRaw(&_rlp, _itemCount); } + + /// Shift operators for appending data items. + template RLPStream& operator<<(T _data) { return append(_data); } + + /// Clear the output stream so far. + void clear() { m_out.clear(); m_listStack.clear(); } + + /// Read the byte stream. + bytes const& out() const { if(!m_listStack.empty()) BOOST_THROW_EXCEPTION(RLPException() << errinfo_comment("listStack is not empty")); return m_out; } + + /// Invalidate the object and steal the output byte stream. + bytes&& invalidate() { if(!m_listStack.empty()) BOOST_THROW_EXCEPTION(RLPException() << errinfo_comment("listStack is not empty")); return std::move(m_out); } + + /// Swap the contents of the output stream out for some other byte array. + void swapOut(bytes& _dest) { if(!m_listStack.empty()) BOOST_THROW_EXCEPTION(RLPException() << errinfo_comment("listStack is not empty")); swap(m_out, _dest); } + +private: + void noteAppended(size_t _itemCount = 1); + + /// Push the node-type byte (using @a _base) along with the item count @a _count. + /// @arg _count is number of characters for strings, data-bytes for ints, or items for lists. + void pushCount(size_t _count, byte _offset); + + /// Push an integer as a raw big-endian byte-stream. + template void pushInt(_T _i, size_t _br) + { + m_out.resize(m_out.size() + _br); + byte* b = &m_out.back(); + for (; _i; _i >>= 8) + *(b--) = (byte)_i; + } + + /// Our output byte stream. + bytes m_out; + + std::vector> m_listStack; +}; + +template void rlpListAux(RLPStream& _out, _T _t) { _out << _t; } +template void rlpListAux(RLPStream& _out, _T _t, _Ts ... _ts) { rlpListAux(_out << _t, _ts...); } + +/// Export a single item in RLP format, returning a byte array. +template bytes rlp(_T _t) { return (RLPStream() << _t).out(); } + +/// Export a list of items in RLP format, returning a byte array. +inline bytes rlpList() { return RLPStream(0).out(); } +template bytes rlpList(_Ts ... _ts) +{ + RLPStream out(sizeof ...(_Ts)); + rlpListAux(out, _ts...); + return out.out(); +} + +/// The empty string in RLP format. +extern bytes RLPNull; + +/// The empty list in RLP format. +extern bytes RLPEmptyList; + +/// Human readable version of RLP. +std::ostream& operator<<(std::ostream& _out, dev::RLP const& _d); + +} diff --git a/libdevcore/RangeMask.cpp b/libdevcore/RangeMask.cpp new file mode 100644 index 0000000000..ad22f2c74f --- /dev/null +++ b/libdevcore/RangeMask.cpp @@ -0,0 +1,22 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file RangeMask.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "RangeMask.h" diff --git a/libdevcore/RangeMask.h b/libdevcore/RangeMask.h new file mode 100644 index 0000000000..21c599f381 --- /dev/null +++ b/libdevcore/RangeMask.h @@ -0,0 +1,294 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file RangeMask.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace dev +{ + +class RLPStream; + +using UnsignedRange = std::pair; +using UnsignedRanges = std::vector; + +/** + * Set of elements of a certain "ground range" representable by unions of ranges inside this + * ground range. + * Ranges are given as pairs (begin, end), denoting the interval [begin, end), i.e. end is excluded. + * Supports set-theoretic operators, size and iteration. + */ +template +class RangeMask +{ + template friend std::ostream& operator<<(std::ostream& _out, RangeMask const& _r); + +public: + using Range = std::pair; + using Ranges = std::vector; + + /// Constructs an empty range mask with empty ground range. + RangeMask(): m_all(0, 0) {} + /// Constructs an empty range mask with ground range [_begin, _end). + RangeMask(T _begin, T _end): m_all(_begin, _end) {} + /// Constructs an empty range mask with ground range _c. + RangeMask(Range const& _c): m_all(_c) {} + + /// @returns the union with the range mask _m, taking also the union of the ground ranges. + RangeMask unionedWith(RangeMask const& _m) const { return operator+(_m); } + RangeMask operator+(RangeMask const& _m) const { return RangeMask(*this) += _m; } + + /// @returns a new range mask containing the smallest _items elements (not ranges). + RangeMask lowest(decltype(T{} - T{}) _items) const + { + RangeMask ret(m_all); + for (auto i = m_ranges.begin(); i != m_ranges.end() && _items; ++i) + _items -= (ret.m_ranges[i->first] = std::min(i->first + _items, i->second)) - i->first; + return ret; + } + + /// @returns the complement of the range mask relative to the ground range. + RangeMask operator~() const { return inverted(); } + + /// @returns a copy of this range mask representing the complement relative to the ground range. + RangeMask inverted() const + { + RangeMask ret(m_all); + T last = m_all.first; + for (auto i: m_ranges) + { + if (i.first != last) + ret.m_ranges[last] = i.first; + last = i.second; + } + if (last != m_all.second) + ret.m_ranges[last] = m_all.second; + return ret; + } + + /// Changes the range mask to its complement relative to the ground range and returns a + /// reference to itself. + RangeMask& invert() { return *this = inverted(); } + + template RangeMask operator-(S const& _m) const { auto ret = *this; return ret -= _m; } + template RangeMask& operator-=(S const& _m) { return invert().unionWith(_m).invert(); } + + RangeMask& operator+=(RangeMask const& _m) { return unionWith(_m); } + + RangeMask& unionWith(RangeMask const& _m) + { + m_all.first = std::min(_m.m_all.first, m_all.first); + m_all.second = std::max(_m.m_all.second, m_all.second); + for (auto const& i: _m.m_ranges) + unionWith(i); + return *this; + } + RangeMask& operator+=(Range const& _m) { return unionWith(_m); } + /// Modifies this range mask to also include the range _m, which has to be a subset of + /// the ground range. + RangeMask& unionWith(Range const& _m); + + /// Adds the single element _i to the range mask. + RangeMask& operator+=(T _m) { return unionWith(_m); } + /// Adds the single element _i to the range mask. + RangeMask& unionWith(T _i) + { + return operator+=(Range(_i, _i + 1)); + } + + bool contains(T _i) const + { + auto it = m_ranges.upper_bound(_i); + if (it == m_ranges.begin()) + return false; + return (--it)->second > _i; + } + + bool empty() const + { + return m_ranges.empty(); + } + + bool full() const + { + return m_all.first == m_all.second || (m_ranges.size() == 1 && m_ranges.begin()->first == m_all.first && m_ranges.begin()->second == m_all.second); + } + + void clear() + { + m_ranges.clear(); + } + + void reset() + { + m_ranges.clear(); + m_all = std::make_pair(0, 0); + } + + /// @returns the ground range. + std::pair const& all() const { return m_all; } + /// Extends the ground range to include _i. + void extendAll(T _i) { m_all = std::make_pair(std::min(m_all.first, _i), std::max(m_all.second, _i + 1)); } + + class const_iterator: public std::iterator + { + friend class RangeMask; + + public: + const_iterator() {} + + T operator*() const { return m_value; } + const_iterator& operator++() { if (m_owner) m_value = m_owner->next(m_value); return *this; } + const_iterator operator++(int) { auto ret = *this; if (m_owner) m_value = m_owner->next(m_value); return ret; } + + bool operator==(const_iterator const& _i) const { return m_owner == _i.m_owner && m_value == _i.m_value; } + bool operator!=(const_iterator const& _i) const { return !operator==(_i); } + bool operator<(const_iterator const& _i) const { return m_value < _i.m_value; } + + private: + const_iterator(RangeMask const& _m, bool _end): m_owner(&_m), m_value(_m.m_ranges.empty() || _end ? _m.m_all.second : _m.m_ranges.begin()->first) {} + + RangeMask const* m_owner = nullptr; + T m_value = 0; + }; + + const_iterator begin() const { return const_iterator(*this, false); } + const_iterator end() const { return const_iterator(*this, true); } + /// @returns the smallest element in the range mask that is larger than _t or the end of the + /// base range if such an element does not exist. + T next(T _t) const + { + _t++; + // find next item in range at least _t + auto uit = m_ranges.upper_bound(_t); // > _t + auto it = uit == m_ranges.begin() ? m_ranges.end() : std::prev(uit); + if (it != m_ranges.end() && it->first <= _t && it->second > _t) + return _t; + return uit == m_ranges.end() ? m_all.second : uit->first; + } + + /// @returns the number of elements (not ranges) in the range mask. + size_t size() const + { + size_t c = 0; + for (auto const& r: this->m_ranges) + c += r.second - r.first; + return c; + } + + size_t firstOut() const + { + if (m_ranges.empty() || !m_ranges.count(m_all.first)) + return m_all.first; + return m_ranges.at(m_all.first); + } + + size_t lastIn() const + { + if (m_ranges.empty()) + return m_all.first; + return m_ranges.rbegin()->second - 1; + } + +private: + /// The ground range. + UnsignedRange m_all; + /// Mapping begin -> end containing the ranges. + std::map m_ranges; +}; + +template inline std::ostream& operator<<(std::ostream& _out, RangeMask const& _r) +{ + _out << _r.m_all.first << "{ "; + for (auto const& i: _r.m_ranges) + _out << "[" << i.first << ", " << i.second << ") "; + _out << "}" << _r.m_all.second; + return _out; +} + +template +RangeMask& RangeMask::unionWith(typename RangeMask::Range const& _m) +{ + for (auto i = _m.first; i < _m.second;) + { + assert(i >= m_all.first); + assert(i < m_all.second); + // For each number, we find the element equal or next lower. this, if any, must contain the value. + // First range that starts after i. + auto rangeAfter = m_ranges.upper_bound(i); + // Range before rangeAfter or "end" if the rangeAfter is the first ever... + auto it = rangeAfter == m_ranges.begin() ? m_ranges.end() : std::prev(rangeAfter); + if (it == m_ranges.end() || it->second < i) + { + // i is either before the first range or between two ranges (with some distance + // so that we cannot merge it onto "it"). + // lower range is too low to merge. + // if the next higher range is too high. + if (rangeAfter == m_ranges.end() || rangeAfter->first > _m.second) + { + // just create a new range + m_ranges[i] = _m.second; + break; + } + else + { + if (rangeAfter->first == i) + // move i to end of range + i = rangeAfter->second; + else + { + // merge with the next higher range + // move i to end of range + i = m_ranges[i] = rangeAfter->second; + m_ranges.erase(rangeAfter); + } + } + } + else if (it->second == i) + { + // The range before i ends with i. + // if the next higher range is too high. + if (rangeAfter == m_ranges.end() || rangeAfter->first > _m.second) + { + // merge with the next lower range + m_ranges[it->first] = _m.second; + break; + } + else + { + // merge with both next lower & next higher. + i = m_ranges[it->first] = rangeAfter->second; + m_ranges.erase(rangeAfter); + } + } + else + i = it->second; + } + return *this; +} + +} diff --git a/libdevcore/SHA3.cpp b/libdevcore/SHA3.cpp new file mode 100644 index 0000000000..d3182d4156 --- /dev/null +++ b/libdevcore/SHA3.cpp @@ -0,0 +1,224 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file SHA3.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "SHA3.h" +#include +#include +#include +#include +#include "RLP.h" +#include "picosha2.h" +using namespace std; +using namespace dev; + +namespace dev +{ + +h256 EmptySHA3 = sha3(bytesConstRef()); +h256 EmptyListSHA3 = sha3(rlpList()); + +namespace keccak +{ + +/** libkeccak-tiny + * + * A single-file implementation of SHA-3 and SHAKE. + * + * Implementor: David Leon Gil + * License: CC0, attribution kindly requested. Blame taken too, + * but not liability. + */ + +#define decshake(bits) \ + int shake##bits(uint8_t*, size_t, const uint8_t*, size_t); + +#define decsha3(bits) \ + int sha3_##bits(uint8_t*, size_t, const uint8_t*, size_t); + +decshake(128) +decshake(256) +decsha3(224) +decsha3(256) +decsha3(384) +decsha3(512) + +/******** The Keccak-f[1600] permutation ********/ + +/*** Constants. ***/ +static const uint8_t rho[24] = \ + { 1, 3, 6, 10, 15, 21, + 28, 36, 45, 55, 2, 14, + 27, 41, 56, 8, 25, 43, + 62, 18, 39, 61, 20, 44}; +static const uint8_t pi[24] = \ + {10, 7, 11, 17, 18, 3, + 5, 16, 8, 21, 24, 4, + 15, 23, 19, 13, 12, 2, + 20, 14, 22, 9, 6, 1}; +static const uint64_t RC[24] = \ + {1ULL, 0x8082ULL, 0x800000000000808aULL, 0x8000000080008000ULL, + 0x808bULL, 0x80000001ULL, 0x8000000080008081ULL, 0x8000000000008009ULL, + 0x8aULL, 0x88ULL, 0x80008009ULL, 0x8000000aULL, + 0x8000808bULL, 0x800000000000008bULL, 0x8000000000008089ULL, 0x8000000000008003ULL, + 0x8000000000008002ULL, 0x8000000000000080ULL, 0x800aULL, 0x800000008000000aULL, + 0x8000000080008081ULL, 0x8000000000008080ULL, 0x80000001ULL, 0x8000000080008008ULL}; + +/*** Helper macros to unroll the permutation. ***/ +#define rol(x, s) (((x) << s) | ((x) >> (64 - s))) +#define REPEAT6(e) e e e e e e +#define REPEAT24(e) REPEAT6(e e e e) +#define REPEAT5(e) e e e e e +#define FOR5(v, s, e) \ + v = 0; \ + REPEAT5(e; v += s;) + +/*** Keccak-f[1600] ***/ +static inline void keccakf(void* state) { + uint64_t* a = (uint64_t*)state; + uint64_t b[5] = {0}; + uint64_t t = 0; + uint8_t x, y; + + for (int i = 0; i < 24; i++) { + // Theta + FOR5(x, 1, + b[x] = 0; + FOR5(y, 5, + b[x] ^= a[x + y]; )) + FOR5(x, 1, + FOR5(y, 5, + a[y + x] ^= b[(x + 4) % 5] ^ rol(b[(x + 1) % 5], 1); )) + // Rho and pi + t = a[1]; + x = 0; + REPEAT24(b[0] = a[pi[x]]; + a[pi[x]] = rol(t, rho[x]); + t = b[0]; + x++; ) + // Chi + FOR5(y, + 5, + FOR5(x, 1, + b[x] = a[y + x];) + FOR5(x, 1, + a[y + x] = b[x] ^ ((~b[(x + 1) % 5]) & b[(x + 2) % 5]); )) + // Iota + a[0] ^= RC[i]; + } +} + +/******** The FIPS202-defined functions. ********/ + +/*** Some helper macros. ***/ + +#define _(S) do { S } while (0) +#define FOR(i, ST, L, S) \ + _(for (size_t i = 0; i < L; i += ST) { S; }) +#define mkapply_ds(NAME, S) \ + static inline void NAME(uint8_t* dst, \ + const uint8_t* src, \ + size_t len) { \ + FOR(i, 1, len, S); \ + } +#define mkapply_sd(NAME, S) \ + static inline void NAME(const uint8_t* src, \ + uint8_t* dst, \ + size_t len) { \ + FOR(i, 1, len, S); \ + } + +mkapply_ds(xorin, dst[i] ^= src[i]) // xorin +mkapply_sd(setout, dst[i] = src[i]) // setout + +#define P keccakf +#define Plen 200 + +// Fold P*F over the full blocks of an input. +#define foldP(I, L, F) \ + while (L >= rate) { \ + F(a, I, rate); \ + P(a); \ + I += rate; \ + L -= rate; \ + } + +/** The sponge-based hash construction. **/ +static inline int hash(uint8_t* out, size_t outlen, + const uint8_t* in, size_t inlen, + size_t rate, uint8_t delim) { + if ((out == NULL) || ((in == NULL) && inlen != 0) || (rate >= Plen)) { + return -1; + } + uint8_t a[Plen] = {0}; + // Absorb input. + foldP(in, inlen, xorin); + // Xor in the DS and pad frame. + a[inlen] ^= delim; + a[rate - 1] ^= 0x80; + // Xor in the last block. + xorin(a, in, inlen); + // Apply P + P(a); + // Squeeze output. + foldP(out, outlen, setout); + setout(a, out, outlen); + memset(a, 0, 200); + return 0; +} + +/*** Helper macros to define SHA3 and SHAKE instances. ***/ +#define defshake(bits) \ + int shake##bits(uint8_t* out, size_t outlen, \ + const uint8_t* in, size_t inlen) { \ + return hash(out, outlen, in, inlen, 200 - (bits / 4), 0x1f); \ + } +#define defsha3(bits) \ + int sha3_##bits(uint8_t* out, size_t outlen, \ + const uint8_t* in, size_t inlen) { \ + if (outlen > (bits/8)) { \ + return -1; \ + } \ + return hash(out, outlen, in, inlen, 200 - (bits / 4), 0x01); \ + } + +/*** FIPS202 SHAKE VOFs ***/ +defshake(128) +defshake(256) + +/*** FIPS202 SHA3 FOFs ***/ +defsha3(224) +defsha3(256) +defsha3(384) +defsha3(512) + +} + +bool sha3(bytesConstRef _input, bytesRef o_output) +{ + // FIXME: What with unaligned memory? + if (o_output.size() != 32) + return false; + keccak::sha3_256(o_output.data(), 32, _input.data(), _input.size()); +// keccak::keccak(ret.data(), 32, (uint64_t const*)_input.data(), _input.size()); + return true; +} + +} diff --git a/libdevcore/SHA3.h b/libdevcore/SHA3.h new file mode 100644 index 0000000000..958e9b24d8 --- /dev/null +++ b/libdevcore/SHA3.h @@ -0,0 +1,71 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file SHA3.h + * @author Gav Wood + * @date 2014 + * + * The FixedHash fixed-size "hash" container type. + */ + +#pragma once + +#include +#include "FixedHash.h" +#include "vector_ref.h" + +namespace dev +{ + +// SHA-3 convenience routines. + +/// Calculate SHA3-256 hash of the given input and load it into the given output. +/// @returns false if o_output.size() != 32. +bool sha3(bytesConstRef _input, bytesRef o_output); + +/// Calculate SHA3-256 hash of the given input, returning as a 256-bit hash. +inline h256 sha3(bytesConstRef _input) { h256 ret; sha3(_input, ret.ref()); return ret; } +inline SecureFixedHash<32> sha3Secure(bytesConstRef _input) { SecureFixedHash<32> ret; sha3(_input, ret.writable().ref()); return ret; } + +/// Calculate SHA3-256 hash of the given input, returning as a 256-bit hash. +inline h256 sha3(bytes const& _input) { return sha3(bytesConstRef(&_input)); } +inline SecureFixedHash<32> sha3Secure(bytes const& _input) { return sha3Secure(bytesConstRef(&_input)); } + +/// Calculate SHA3-256 hash of the given input (presented as a binary-filled string), returning as a 256-bit hash. +inline h256 sha3(std::string const& _input) { return sha3(bytesConstRef(_input)); } +inline SecureFixedHash<32> sha3Secure(std::string const& _input) { return sha3Secure(bytesConstRef(_input)); } + +/// Calculate SHA3-256 hash of the given input (presented as a FixedHash), returns a 256-bit hash. +template inline h256 sha3(FixedHash const& _input) { return sha3(_input.ref()); } +template inline SecureFixedHash<32> sha3Secure(FixedHash const& _input) { return sha3Secure(_input.ref()); } + +/// Fully secure variants are equivalent for sha3 and sha3Secure. +inline SecureFixedHash<32> sha3(bytesSec const& _input) { return sha3Secure(_input.ref()); } +inline SecureFixedHash<32> sha3Secure(bytesSec const& _input) { return sha3Secure(_input.ref()); } +template inline SecureFixedHash<32> sha3(SecureFixedHash const& _input) { return sha3Secure(_input.ref()); } +template inline SecureFixedHash<32> sha3Secure(SecureFixedHash const& _input) { return sha3Secure(_input.ref()); } + +/// Calculate SHA3-256 hash of the given input, possibly interpreting it as nibbles, and return the hash as a string filled with binary data. +inline std::string sha3(std::string const& _input, bool _isNibbles) { return asString((_isNibbles ? sha3(fromHex(_input)) : sha3(bytesConstRef(&_input))).asBytes()); } + +/// Calculate SHA3-256 MAC +inline void sha3mac(bytesConstRef _secret, bytesConstRef _plain, bytesRef _output) { sha3(_secret.toBytes() + _plain.toBytes()).ref().populate(_output); } + +extern h256 EmptySHA3; + +extern h256 EmptyListSHA3; + +} diff --git a/libdevcore/Terminal.h b/libdevcore/Terminal.h new file mode 100644 index 0000000000..582e96b0ce --- /dev/null +++ b/libdevcore/Terminal.h @@ -0,0 +1,217 @@ +#pragma once + +namespace dev +{ +namespace con +{ + +#if defined(_WIN32) + +#define EthReset "" // Text Reset + +#define EthReset "" // Text Reset + + // Regular Colors +#define EthBlack "" // Black +#define EthCoal "" // Black +#define EthGray "" // White +#define EthWhite "" // White +#define EthMaroon "" // Red +#define EthRed "" // Red +#define EthGreen "" // Green +#define EthLime "" // Green +#define EthOrange "" // Yellow +#define EthYellow "" // Yellow +#define EthNavy "" // Blue +#define EthBlue "" // Blue +#define EthViolet "" // Purple +#define EthPurple "" // Purple +#define EthTeal "" // Cyan +#define EthCyan "" // Cyan + +#define EthBlackBold "" // Black +#define EthCoalBold "" // Black +#define EthGrayBold "" // White +#define EthWhiteBold "" // White +#define EthMaroonBold "" // Red +#define EthRedBold "" // Red +#define EthGreenBold "" // Green +#define EthLimeBold "" // Green +#define EthOrangeBold "" // Yellow +#define EthYellowBold "" // Yellow +#define EthNavyBold "" // Blue +#define EthBlueBold "" // Blue +#define EthVioletBold "" // Purple +#define EthPurpleBold "" // Purple +#define EthTealBold "" // Cyan +#define EthCyanBold "" // Cyan + + // Background +#define EthOnBlack "" // Black +#define EthOnCoal "" // Black +#define EthOnGray "" // White +#define EthOnWhite "" // White +#define EthOnMaroon "" // Red +#define EthOnRed "" // Red +#define EthOnGreen "" // Green +#define EthOnLime "" // Green +#define EthOnOrange "" // Yellow +#define EthOnYellow "" // Yellow +#define EthOnNavy "" // Blue +#define EthOnBlue "" // Blue +#define EthOnViolet "" // Purple +#define EthOnPurple "" // Purple +#define EthOnTeal "" // Cyan +#define EthOnCyan "" // Cyan + + // Underline +#define EthBlackUnder "" // Black +#define EthGrayUnder "" // White +#define EthMaroonUnder "" // Red +#define EthGreenUnder "" // Green +#define EthOrangeUnder "" // Yellow +#define EthNavyUnder "" // Blue +#define EthVioletUnder "" // Purple +#define EthTealUnder "" // Cyan + +#else + +#define EthReset "" // Text Reset + +#define EthReset "" // Text Reset + + // Regular Colors +#define EthBlack "" // Black +#define EthCoal "" // Black +#define EthGray "" // White +#define EthWhite "" // White +#define EthMaroon "" // Red +#define EthRed "" // Red +#define EthGreen "" // Green +#define EthLime "" // Green +#define EthOrange "" // Yellow +#define EthYellow "" // Yellow +#define EthNavy "" // Blue +#define EthBlue "" // Blue +#define EthViolet "" // Purple +#define EthPurple "" // Purple +#define EthTeal "" // Cyan +#define EthCyan "" // Cyan + +#define EthBlackBold "" // Black +#define EthCoalBold "" // Black +#define EthGrayBold "" // White +#define EthWhiteBold "" // White +#define EthMaroonBold "" // Red +#define EthRedBold "" // Red +#define EthGreenBold "" // Green +#define EthLimeBold "" // Green +#define EthOrangeBold "" // Yellow +#define EthYellowBold "" // Yellow +#define EthNavyBold "" // Blue +#define EthBlueBold "" // Blue +#define EthVioletBold "" // Purple +#define EthPurpleBold "" // Purple +#define EthTealBold "" // Cyan +#define EthCyanBold "" // Cyan + + // Background +#define EthOnBlack "" // Black +#define EthOnCoal "" // Black +#define EthOnGray "" // White +#define EthOnWhite "" // White +#define EthOnMaroon "" // Red +#define EthOnRed "" // Red +#define EthOnGreen "" // Green +#define EthOnLime "" // Green +#define EthOnOrange "" // Yellow +#define EthOnYellow "" // Yellow +#define EthOnNavy "" // Blue +#define EthOnBlue "" // Blue +#define EthOnViolet "" // Purple +#define EthOnPurple "" // Purple +#define EthOnTeal "" // Cyan +#define EthOnCyan "" // Cyan + + // Underline +#define EthBlackUnder "" // Black +#define EthGrayUnder "" // White +#define EthMaroonUnder "" // Red +#define EthGreenUnder "" // Green +#define EthOrangeUnder "" // Yellow +#define EthNavyUnder "" // Blue +#define EthVioletUnder "" // Purple +#define EthTealUnder "" // Cyan + +/* +#define EthReset "\x1b[0m" // Text Reset + +// Regular Colors +#define EthBlack "\x1b[30m" // Black +#define EthCoal "\x1b[90m" // Black +#define EthGray "\x1b[37m" // White +#define EthWhite "\x1b[97m" // White +#define EthMaroon "\x1b[31m" // Red +#define EthRed "\x1b[91m" // Red +#define EthGreen "\x1b[32m" // Green +#define EthLime "\x1b[92m" // Green +#define EthOrange "\x1b[33m" // Yellow +#define EthYellow "\x1b[93m" // Yellow +#define EthNavy "\x1b[34m" // Blue +#define EthBlue "\x1b[94m" // Blue +#define EthViolet "\x1b[35m" // Purple +#define EthPurple "\x1b[95m" // Purple +#define EthTeal "\x1b[36m" // Cyan +#define EthCyan "\x1b[96m" // Cyan + +#define EthBlackBold "\x1b[1;30m" // Black +#define EthCoalBold "\x1b[1;90m" // Black +#define EthGrayBold "\x1b[1;37m" // White +#define EthWhiteBold "\x1b[1;97m" // White +#define EthMaroonBold "\x1b[1;31m" // Red +#define EthRedBold "\x1b[1;91m" // Red +#define EthGreenBold "\x1b[1;32m" // Green +#define EthLimeBold "\x1b[1;92m" // Green +#define EthOrangeBold "\x1b[1;33m" // Yellow +#define EthYellowBold "\x1b[1;93m" // Yellow +#define EthNavyBold "\x1b[1;34m" // Blue +#define EthBlueBold "\x1b[1;94m" // Blue +#define EthVioletBold "\x1b[1;35m" // Purple +#define EthPurpleBold "\x1b[1;95m" // Purple +#define EthTealBold "\x1b[1;36m" // Cyan +#define EthCyanBold "\x1b[1;96m" // Cyan + +// Background +#define EthOnBlack "\x1b[40m" // Black +#define EthOnCoal "\x1b[100m" // Black +#define EthOnGray "\x1b[47m" // White +#define EthOnWhite "\x1b[107m" // White +#define EthOnMaroon "\x1b[41m" // Red +#define EthOnRed "\x1b[101m" // Red +#define EthOnGreen "\x1b[42m" // Green +#define EthOnLime "\x1b[102m" // Green +#define EthOnOrange "\x1b[43m" // Yellow +#define EthOnYellow "\x1b[103m" // Yellow +#define EthOnNavy "\x1b[44m" // Blue +#define EthOnBlue "\x1b[104m" // Blue +#define EthOnViolet "\x1b[45m" // Purple +#define EthOnPurple "\x1b[105m" // Purple +#define EthOnTeal "\x1b[46m" // Cyan +#define EthOnCyan "\x1b[106m" // Cyan + +// Underline +#define EthBlackUnder "\x1b[4;30m" // Black +#define EthGrayUnder "\x1b[4;37m" // White +#define EthMaroonUnder "\x1b[4;31m" // Red +#define EthGreenUnder "\x1b[4;32m" // Green +#define EthOrangeUnder "\x1b[4;33m" // Yellow +#define EthNavyUnder "\x1b[4;34m" // Blue +#define EthVioletUnder "\x1b[4;35m" // Purple +#define EthTealUnder "\x1b[4;36m" // Cyan +*/ + +#endif + +} + +} diff --git a/libdevcore/TransientDirectory.cpp b/libdevcore/TransientDirectory.cpp new file mode 100644 index 0000000000..4add820aeb --- /dev/null +++ b/libdevcore/TransientDirectory.cpp @@ -0,0 +1,67 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . + */ +/** @file TransientDirectory.cpp + * @author Marek Kotewicz + * @date 2015 + */ + +#include +#include +#include "Exceptions.h" +#include "TransientDirectory.h" +#include "CommonIO.h" +#include "Log.h" +using namespace std; +using namespace dev; +namespace fs = boost::filesystem; + +TransientDirectory::TransientDirectory(): + TransientDirectory((boost::filesystem::temp_directory_path() / "eth_transient" / toString(FixedHash<4>::random())).string()) +{} + +TransientDirectory::TransientDirectory(std::string const& _path): + m_path(_path) +{ + // we never ever want to delete a directory (including all its contents) that we did not create ourselves. + if (boost::filesystem::exists(m_path)) + BOOST_THROW_EXCEPTION(FileError()); + + if (!fs::create_directories(m_path)) + BOOST_THROW_EXCEPTION(FileError()); + DEV_IGNORE_EXCEPTIONS(fs::permissions(m_path, fs::owner_all)); +} + +TransientDirectory::~TransientDirectory() +{ + boost::system::error_code ec; + fs::remove_all(m_path, ec); + if (!ec) + return; + + // In some cases, antivirus runnig on Windows will scan all the newly created directories. + // As a consequence, directory is locked and can not be deleted immediately. + // Retry after 10 milliseconds usually is successful. + // This will help our tests run smoothly in such environment. + this_thread::sleep_for(chrono::milliseconds(10)); + + ec.clear(); + fs::remove_all(m_path, ec); + if (!ec) + { + LOG(WARNING) << "Failed to delete directory '" << m_path << "': " << ec.message(); + } +} diff --git a/libdevcore/TransientDirectory.h b/libdevcore/TransientDirectory.h new file mode 100644 index 0000000000..466bd8a053 --- /dev/null +++ b/libdevcore/TransientDirectory.h @@ -0,0 +1,47 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . + */ +/** @file TransientDirectory.h + * @author Marek Kotewicz + * @date 2015 + */ + +#pragma once + +#include + +namespace dev +{ + +/** + * @brief temporary directory implementation + * It creates temporary directory in the given path. On dealloc it removes the directory + * @throws if the given path already exists, throws an exception + */ +class TransientDirectory +{ +public: + TransientDirectory(); + TransientDirectory(std::string const& _path); + ~TransientDirectory(); + + std::string const& path() const { return m_path; } + +private: + std::string m_path; +}; + +} diff --git a/libdevcore/TrieCommon.cpp b/libdevcore/TrieCommon.cpp new file mode 100644 index 0000000000..b90c9d8def --- /dev/null +++ b/libdevcore/TrieCommon.cpp @@ -0,0 +1,127 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file TrieCommon.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "TrieCommon.h" + +namespace dev +{ + +/* + * Hex-prefix Notation. First nibble has flags: oddness = 2^0 & termination = 2^1 + * NOTE: the "termination marker" and "leaf-node" specifier are completely equivalent. + * [0,0,1,2,3,4,5] 0x10012345 + * [0,1,2,3,4,5] 0x00012345 + * [1,2,3,4,5] 0x112345 + * [0,0,1,2,3,4] 0x00001234 + * [0,1,2,3,4] 0x101234 + * [1,2,3,4] 0x001234 + * [0,0,1,2,3,4,5,T] 0x30012345 + * [0,0,1,2,3,4,T] 0x20001234 + * [0,1,2,3,4,5,T] 0x20012345 + * [1,2,3,4,5,T] 0x312345 + * [1,2,3,4,T] 0x201234 + */ + +std::string hexPrefixEncode(bytes const& _hexVector, bool _leaf, int _begin, int _end) +{ + unsigned begin = _begin; + unsigned end = _end < 0 ? _hexVector.size() + 1 + _end : _end; + bool odd = ((end - begin) % 2) != 0; + + std::string ret(1, ((_leaf ? 2 : 0) | (odd ? 1 : 0)) * 16); + if (odd) + { + ret[0] |= _hexVector[begin]; + ++begin; + } + for (unsigned i = begin; i < end; i += 2) + ret += _hexVector[i] * 16 + _hexVector[i + 1]; + return ret; +} + +std::string hexPrefixEncode(bytesConstRef _data, bool _leaf, int _beginNibble, int _endNibble, unsigned _offset) +{ + unsigned begin = _beginNibble + _offset; + unsigned end = (_endNibble < 0 ? ((int)(_data.size() * 2 - _offset) + 1) + _endNibble : _endNibble) + _offset; + bool odd = (end - begin) & 1; + + std::string ret(1, ((_leaf ? 2 : 0) | (odd ? 1 : 0)) * 16); + ret.reserve((end - begin) / 2 + 1); + + unsigned d = odd ? 1 : 2; + for (auto i = begin; i < end; ++i, ++d) + { + byte n = nibble(_data, i); + if (d & 1) // odd + ret.back() |= n; // or the nibble onto the back + else + ret.push_back(n << 4); // push the nibble on to the back << 4 + } + return ret; +} + +std::string hexPrefixEncode(bytesConstRef _d1, unsigned _o1, bytesConstRef _d2, unsigned _o2, bool _leaf) +{ + unsigned begin1 = _o1; + unsigned end1 = _d1.size() * 2; + unsigned begin2 = _o2; + unsigned end2 = _d2.size() * 2; + + bool odd = (end1 - begin1 + end2 - begin2) & 1; + + std::string ret(1, ((_leaf ? 2 : 0) | (odd ? 1 : 0)) * 16); + ret.reserve((end1 - begin1 + end2 - begin2) / 2 + 1); + + unsigned d = odd ? 1 : 2; + for (auto i = begin1; i < end1; ++i, ++d) + { + byte n = nibble(_d1, i); + if (d & 1) // odd + ret.back() |= n; // or the nibble onto the back + else + ret.push_back(n << 4); // push the nibble on to the back << 4 + } + for (auto i = begin2; i < end2; ++i, ++d) + { + byte n = nibble(_d2, i); + if (d & 1) // odd + ret.back() |= n; // or the nibble onto the back + else + ret.push_back(n << 4); // push the nibble on to the back << 4 + } + return ret; +} + +byte uniqueInUse(RLP const& _orig, byte except) +{ + byte used = 255; + for (unsigned i = 0; i < 17; ++i) + if (i != except && !_orig[i].isEmpty()) + { + if (used == 255) + used = (byte)i; + else + return 255; + } + return used; +} + +} diff --git a/libdevcore/TrieCommon.h b/libdevcore/TrieCommon.h new file mode 100644 index 0000000000..8053e62c98 --- /dev/null +++ b/libdevcore/TrieCommon.h @@ -0,0 +1,133 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file TrieCommon.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include "Common.h" +#include "RLP.h" + +namespace dev +{ + +inline byte nibble(bytesConstRef _data, unsigned _i) +{ + return (_i & 1) ? (_data[_i / 2] & 15) : (_data[_i / 2] >> 4); +} + +/// Interprets @a _first and @a _second as vectors of nibbles and returns the length of the longest common +/// prefix of _first[_beginFirst..._endFirst] and _second[_beginSecond..._endSecond]. +inline unsigned sharedNibbles(bytesConstRef _first, unsigned _beginFirst, unsigned _endFirst, bytesConstRef _second, unsigned _beginSecond, unsigned _endSecond) +{ + unsigned ret = 0; + while (_beginFirst < _endFirst && _beginSecond < _endSecond && nibble(_first, _beginFirst) == nibble(_second, _beginSecond)) + { + ++_beginFirst; + ++_beginSecond; + ++ret; + } + return ret; +} + +/** + * Nibble-based view on a bytesConstRef. + */ +struct NibbleSlice +{ + bytesConstRef data; + unsigned offset; + + NibbleSlice(bytesConstRef _data = bytesConstRef(), unsigned _offset = 0): data(_data), offset(_offset) {} + byte operator[](unsigned _index) const { return nibble(data, offset + _index); } + unsigned size() const { return data.size() * 2 - offset; } + bool empty() const { return !size(); } + NibbleSlice mid(unsigned _index) const { return NibbleSlice(data, offset + _index); } + void clear() { data.reset(); offset = 0; } + + /// @returns true iff _k is a prefix of this. + bool contains(NibbleSlice _k) const { return shared(_k) == _k.size(); } + /// @returns the number of shared nibbles at the beginning of this and _k. + unsigned shared(NibbleSlice _k) const { return sharedNibbles(data, offset, offset + size(), _k.data, _k.offset, _k.offset + _k.size()); } + /** + * @brief Determine if we, a full key, are situated prior to a particular key-prefix. + * @param _k The prefix. + * @return true if we are strictly prior to the prefix. + */ + bool isEarlierThan(NibbleSlice _k) const + { + unsigned i = 0; + for (; i < _k.size() && i < size(); ++i) + if (operator[](i) < _k[i]) // Byte is lower - we're earlier.. + return true; + else if (operator[](i) > _k[i]) // Byte is higher - we're not earlier. + return false; + if (i >= _k.size()) // Ran past the end of the prefix - we're == for the entire prefix - we're not earlier. + return false; + return true; // Ran out before the prefix had finished - we're earlier. + } + bool operator==(NibbleSlice _k) const { return _k.size() == size() && shared(_k) == _k.size(); } + bool operator!=(NibbleSlice _s) const { return !operator==(_s); } +}; + +inline std::ostream& operator<<(std::ostream& _out, NibbleSlice const& _m) +{ + for (unsigned i = 0; i < _m.size(); ++i) + _out << std::hex << (int)_m[i] << std::dec; + return _out; +} + +inline bool isLeaf(RLP const& _twoItem) +{ + assert(_twoItem.isList() && _twoItem.itemCount() == 2); + auto pl = _twoItem[0].payload(); + return (pl[0] & 0x20) != 0; +} + +inline NibbleSlice keyOf(bytesConstRef _hpe) +{ + if (!_hpe.size()) + return NibbleSlice(_hpe, 0); + if (_hpe[0] & 0x10) + return NibbleSlice(_hpe, 1); + else + return NibbleSlice(_hpe, 2); +} + +inline NibbleSlice keyOf(RLP const& _twoItem) +{ + return keyOf(_twoItem[0].payload()); +} + +byte uniqueInUse(RLP const& _orig, byte except); +std::string hexPrefixEncode(bytes const& _hexVector, bool _leaf = false, int _begin = 0, int _end = -1); +std::string hexPrefixEncode(bytesConstRef _data, bool _leaf, int _beginNibble, int _endNibble, unsigned _offset); +std::string hexPrefixEncode(bytesConstRef _d1, unsigned _o1, bytesConstRef _d2, unsigned _o2, bool _leaf); + +inline std::string hexPrefixEncode(NibbleSlice _s, bool _leaf, int _begin = 0, int _end = -1) +{ + return hexPrefixEncode(_s.data, _leaf, _begin, _end, _s.offset); +} + +inline std::string hexPrefixEncode(NibbleSlice _s1, NibbleSlice _s2, bool _leaf) +{ + return hexPrefixEncode(_s1.data, _s1.offset, _s2.data, _s2.offset, _leaf); +} + +} diff --git a/libdevcore/TrieDB.cpp b/libdevcore/TrieDB.cpp new file mode 100644 index 0000000000..e1b4828368 --- /dev/null +++ b/libdevcore/TrieDB.cpp @@ -0,0 +1,33 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file TrieDB.cpp + * @author Gav Wood + * @date 2014 + */ +#if !defined(ETH_EMSCRIPTEN) + +#include "Common.h" +#include "TrieDB.h" +using namespace std; +using namespace dev; + +h256 const dev::c_shaNull = sha3(rlp("")); +h256 const dev::EmptyTrie = sha3(rlp("")); + +const char* TrieDBChannel::name() { return "-T-"; } + +#endif // ETH_EMSCRIPTEN diff --git a/libdevcore/TrieDB.h b/libdevcore/TrieDB.h new file mode 100644 index 0000000000..45e99cfd99 --- /dev/null +++ b/libdevcore/TrieDB.h @@ -0,0 +1,1242 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file TrieDB.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include "db.h" +#include "Common.h" +#include "Log.h" +#include "Exceptions.h" +#include "SHA3.h" +#include "MemoryDB.h" +#include "TrieCommon.h" + +namespace dev +{ + +struct TrieDBChannel: public LogChannel { static const char* name(); static const int verbosity = 17; }; +#define tdebug clog(TrieDBChannel) + +struct InvalidTrie: virtual dev::Exception {}; +extern const h256 c_shaNull; +extern const h256 EmptyTrie; + +enum class Verification { + Skip, + Normal +}; + +/** + * @brief Merkle Patricia Tree "Trie": a modifed base-16 Radix tree. + * This version uses a database backend. + * Usage: + * @code + * GenericTrieDB t(&myDB); + * assert(t.isNull()); + * t.init(); + * assert(t.isEmpty()); + * t.insert(x, y); + * assert(t.at(x) == y.toString()); + * t.remove(x); + * assert(t.isEmpty()); + * @endcode + */ +template +class GenericTrieDB +{ +public: + using DB = _DB; + + explicit GenericTrieDB(DB* _db = nullptr): m_db(_db) {} + GenericTrieDB(DB* _db, h256 const& _root, Verification _v = Verification::Normal) { open(_db, _root, _v); } + ~GenericTrieDB() {} + + void open(DB* _db) { m_db = _db; } + void open(DB* _db, h256 const& _root, Verification _v = Verification::Normal) { m_db = _db; setRoot(_root, _v); } + + void init() { setRoot(forceInsertNode(&RLPNull)); assert(node(m_root).size()); } + + void setRoot(h256 const& _root, Verification _v = Verification::Normal) + { + m_root = _root; + if (_v == Verification::Normal) + { + if (m_root == c_shaNull && !m_db->exists(m_root)) + init(); + } + /*std::cout << "Setting root to " << _root << " (patched to " << m_root << ")" << std::endl;*/ +#if ETH_DEBUG + if (_v == Verification::Normal) +#endif + if (!node(m_root).size()) + BOOST_THROW_EXCEPTION(RootNotFound()); + } + + /// True if the trie is uninitialised (i.e. that the DB doesn't contain the root node). + bool isNull() const { return !node(m_root).size(); } + /// True if the trie is initialised but empty (i.e. that the DB contains the root node which is empty). + bool isEmpty() const { return m_root == c_shaNull && node(m_root).size(); } + + h256 const& root() const { if (node(m_root).empty()) BOOST_THROW_EXCEPTION(BadRoot(m_root)); /*std::cout << "Returning root as " << ret << " (really " << m_root << ")" << std::endl;*/ return m_root; } // patch the root in the case of the empty trie. TODO: handle this properly. + + std::string at(bytes const& _key) const { return at(&_key); } + std::string at(bytesConstRef _key) const; + void insert(bytes const& _key, bytes const& _value) { insert(&_key, &_value); } + void insert(bytesConstRef _key, bytes const& _value) { insert(_key, &_value); } + void insert(bytes const& _key, bytesConstRef _value) { insert(&_key, _value); } + void insert(bytesConstRef _key, bytesConstRef _value); + void remove(bytes const& _key) { remove(&_key); } + void remove(bytesConstRef _key); + bool contains(bytes const& _key) { return contains(&_key); } + bool contains(bytesConstRef _key) { return !at(_key).empty(); } + + class iterator + { + public: + using value_type = std::pair; + + iterator() {} + explicit iterator(GenericTrieDB const* _db); + iterator(GenericTrieDB const* _db, bytesConstRef _key); + + iterator& operator++() { next(); return *this; } + + value_type operator*() const { return at(); } + value_type operator->() const { return at(); } + + bool operator==(iterator const& _c) const { return _c.m_trail == m_trail; } + bool operator!=(iterator const& _c) const { return _c.m_trail != m_trail; } + + value_type at() const; + + private: + void next(); + void next(NibbleSlice _key); + + struct Node + { + std::string rlp; + std::string key; // as hexPrefixEncoding. + byte child; // 255 -> entering, 16 -> actually at the node, 17 -> exiting, 0-15 -> actual children. + + // 255 -> 16 -> 0 -> 1 -> ... -> 15 -> 17 + + void setChild(unsigned _i) { child = _i; } + void setFirstChild() { child = 16; } + void incrementChild() { child = child == 16 ? 0 : child == 15 ? 17 : (child + 1); } + + bool operator==(Node const& _c) const { return rlp == _c.rlp && key == _c.key && child == _c.child; } + bool operator!=(Node const& _c) const { return !operator==(_c); } + }; + + protected: + std::vector m_trail; + GenericTrieDB const* m_that; + }; + + iterator begin() const { return iterator(this); } + iterator end() const { return iterator(); } + + iterator lower_bound(bytesConstRef _key) const { return iterator(this, _key); } + + /// Used for debugging, scans the whole trie. + void descendKey(h256 const& _k, h256Hash& _keyMask, bool _wasExt, std::ostream* _out, int _indent = 0) const + { + _keyMask.erase(_k); + if (_k == m_root && _k == c_shaNull) // root allowed to be empty + return; + descendList(RLP(node(_k)), _keyMask, _wasExt, _out, _indent); // if not, it must be a list + } + + /// Used for debugging, scans the whole trie. + void descendEntry(RLP const& _r, h256Hash& _keyMask, bool _wasExt, std::ostream* _out, int _indent) const + { + if (_r.isData() && _r.size() == 32) + descendKey(_r.toHash(), _keyMask, _wasExt, _out, _indent); + else if (_r.isList()) + descendList(_r, _keyMask, _wasExt, _out, _indent); + else + BOOST_THROW_EXCEPTION(InvalidTrie()); + } + + /// Used for debugging, scans the whole trie. + void descendList(RLP const& _r, h256Hash& _keyMask, bool _wasExt, std::ostream* _out, int _indent) const + { + if (_r.isList() && _r.itemCount() == 2 && (!_wasExt || _out)) + { + if (_out) + (*_out) << std::string(_indent * 2, ' ') << (_wasExt ? "!2 " : "2 ") << sha3(_r.data()) << ": " << _r << "\n"; + if (!isLeaf(_r)) // don't go down leaves + descendEntry(_r[1], _keyMask, true, _out, _indent + 1); + } + else if (_r.isList() && _r.itemCount() == 17) + { + if (_out) + (*_out) << std::string(_indent * 2, ' ') << "17 " << sha3(_r.data()) << ": " << _r << "\n"; + for (unsigned i = 0; i < 16; ++i) + if (!_r[i].isEmpty()) // 16 branches are allowed to be empty + descendEntry(_r[i], _keyMask, false, _out, _indent + 1); + } + else + BOOST_THROW_EXCEPTION(InvalidTrie()); + } + + /// Used for debugging, scans the whole trie. + h256Hash leftOvers(std::ostream* _out = nullptr) const + { + h256Hash k = m_db->keys(); + descendKey(m_root, k, false, _out); + return k; + } + + /// Used for debugging, scans the whole trie. + void debugStructure(std::ostream& _out) const + { + leftOvers(&_out); + } + + /// Used for debugging, scans the whole trie. + /// @param _requireNoLeftOvers if true, requires that all keys are reachable. + bool check(bool _requireNoLeftOvers) const + { + try + { + return leftOvers().empty() || !_requireNoLeftOvers; + } + catch (...) + { + cwarn << boost::current_exception_diagnostic_information(); + return false; + } + } + + /// Get the underlying database. + /// @warning This can be used to bypass the trie code. Don't use these unless you *really* + /// know what you're doing. + DB const* db() const { return m_db; } + DB* db() { return m_db; } + +private: + RLPStream& streamNode(RLPStream& _s, bytes const& _b); + + std::string atAux(RLP const& _here, NibbleSlice _key) const; + + void mergeAtAux(RLPStream& _out, RLP const& _replace, NibbleSlice _key, bytesConstRef _value); + bytes mergeAt(RLP const& _replace, NibbleSlice _k, bytesConstRef _v, bool _inLine = false); + bytes mergeAt(RLP const& _replace, h256 const& _replaceHash, NibbleSlice _k, bytesConstRef _v, bool _inLine = false); + + bool deleteAtAux(RLPStream& _out, RLP const& _replace, NibbleSlice _key); + bytes deleteAt(RLP const& _replace, NibbleSlice _k); + + // in: null (DEL) -- OR -- [_k, V] (DEL) + // out: [_k, _s] + // -- OR -- + // in: [V0, ..., V15, S16] (DEL) AND _k == {} + // out: [V0, ..., V15, _s] + bytes place(RLP const& _orig, NibbleSlice _k, bytesConstRef _s); + + // in: [K, S] (DEL) + // out: null + // -- OR -- + // in: [V0, ..., V15, S] (DEL) + // out: [V0, ..., V15, null] + bytes remove(RLP const& _orig); + + // in: [K1 & K2, V] (DEL) : nibbles(K1) == _s, 0 < _s <= nibbles(K1 & K2) + // out: [K1, H] ; [K2, V] => H (INS) (being [K1, [K2, V]] if necessary) + bytes cleve(RLP const& _orig, unsigned _s); + + // in: [K1, H] (DEL) ; H <= [K2, V] (DEL) (being [K1, [K2, V]] (DEL) if necessary) + // out: [K1 & K2, V] + bytes graft(RLP const& _orig); + + // in: [V0, ... V15, S] (DEL) + // out1: [k{i}, Vi] where i < 16 + // out2: [k{}, S] where i == 16 + bytes merge(RLP const& _orig, byte _i); + + // in: [k{}, S] (DEL) + // out: [null ** 16, S] + // -- OR -- + // in: [k{i}, N] (DEL) + // out: [null ** i, N, null ** (16 - i)] + // -- OR -- + // in: [k{i}K, V] (DEL) + // out: [null ** i, H, null ** (16 - i)] ; [K, V] => H (INS) (being [null ** i, [K, V], null ** (16 - i)] if necessary) + bytes branch(RLP const& _orig); + + bool isTwoItemNode(RLP const& _n) const; + std::string deref(RLP const& _n) const; + + std::string node(h256 const& _h) const { return m_db->lookup(_h); } + + // These are low-level node insertion functions that just go straight through into the DB. + h256 forceInsertNode(bytesConstRef _v) { auto h = sha3(_v); forceInsertNode(h, _v); return h; } + void forceInsertNode(h256 const& _h, bytesConstRef _v) { m_db->insert(_h, _v); } + void forceKillNode(h256 const& _h) { m_db->kill(_h); } + + // This are semantically-aware node insertion functions that only kills when the node's + // data is < 32 bytes. It can safely be used when pruning the trie but won't work correctly + // for the special case of the root (which is always looked up via a hash). In that case, + // use forceKillNode(). + void killNode(RLP const& _d) { if (_d.data().size() >= 32) forceKillNode(sha3(_d.data())); } + void killNode(RLP const& _d, h256 const& _h) { if (_d.data().size() >= 32) forceKillNode(_h); } + + h256 m_root; + DB* m_db = nullptr; +}; + +template +std::ostream& operator<<(std::ostream& _out, GenericTrieDB const& _db) +{ + for (auto const& i: _db) + _out << escaped(i.first.toString(), false) << ": " << escaped(i.second.toString(), false) << std::endl; + return _out; +} + +/** + * Different view on a GenericTrieDB that can use different key types. + */ +template +class SpecificTrieDB: public Generic +{ +public: + using DB = typename Generic::DB; + using KeyType = _KeyType; + + SpecificTrieDB(DB* _db = nullptr): Generic(_db) {} + SpecificTrieDB(DB* _db, h256 _root, Verification _v = Verification::Normal): Generic(_db, _root, _v) {} + + std::string operator[](KeyType _k) const { return at(_k); } + + bool contains(KeyType _k) const { return Generic::contains(bytesConstRef((byte const*)&_k, sizeof(KeyType))); } + std::string at(KeyType _k) const { return Generic::at(bytesConstRef((byte const*)&_k, sizeof(KeyType))); } + void insert(KeyType _k, bytesConstRef _value) { Generic::insert(bytesConstRef((byte const*)&_k, sizeof(KeyType)), _value); } + void insert(KeyType _k, bytes const& _value) { insert(_k, bytesConstRef(&_value)); } + void remove(KeyType _k) { Generic::remove(bytesConstRef((byte const*)&_k, sizeof(KeyType))); } + + class iterator: public Generic::iterator + { + public: + using Super = typename Generic::iterator; + using value_type = std::pair; + + iterator() {} + iterator(Generic const* _db): Super(_db) {} + iterator(Generic const* _db, bytesConstRef _k): Super(_db, _k) {} + + value_type operator*() const { return at(); } + value_type operator->() const { return at(); } + + value_type at() const; + }; + + iterator begin() const { return this; } + iterator end() const { return iterator(); } + iterator lower_bound(KeyType _k) const { return iterator(this, bytesConstRef((byte const*)&_k, sizeof(KeyType))); } +}; + +template +std::ostream& operator<<(std::ostream& _out, SpecificTrieDB const& _db) +{ + for (auto const& i: _db) + _out << i.first << ": " << escaped(i.second.toString(), false) << std::endl; + return _out; +} + +template +class HashedGenericTrieDB: private SpecificTrieDB, h256> +{ + using Super = SpecificTrieDB, h256>; + +public: + using DB = _DB; + + HashedGenericTrieDB(DB* _db = nullptr): Super(_db) {} + HashedGenericTrieDB(DB* _db, h256 _root, Verification _v = Verification::Normal): Super(_db, _root, _v) {} + + using Super::open; + using Super::init; + using Super::setRoot; + + /// True if the trie is uninitialised (i.e. that the DB doesn't contain the root node). + using Super::isNull; + /// True if the trie is initialised but empty (i.e. that the DB contains the root node which is empty). + using Super::isEmpty; + + using Super::root; + using Super::db; + + using Super::leftOvers; + using Super::check; + using Super::debugStructure; + + std::string at(bytesConstRef _key) const { return Super::at(sha3(_key)); } + bool contains(bytesConstRef _key) { return Super::contains(sha3(_key)); } + void insert(bytesConstRef _key, bytesConstRef _value) { Super::insert(sha3(_key), _value); } + void remove(bytesConstRef _key) { Super::remove(sha3(_key)); } + + // empty from the PoV of the iterator interface; still need a basic iterator impl though. + class iterator + { + public: + using value_type = std::pair; + + iterator() {} + iterator(HashedGenericTrieDB const*) {} + iterator(HashedGenericTrieDB const*, bytesConstRef) {} + + iterator& operator++() { return *this; } + value_type operator*() const { return value_type(); } + value_type operator->() const { return value_type(); } + + bool operator==(iterator const&) const { return true; } + bool operator!=(iterator const&) const { return false; } + + value_type at() const { return value_type(); } + }; + iterator begin() const { return iterator(); } + iterator end() const { return iterator(); } + iterator lower_bound(bytesConstRef) const { return iterator(); } +}; + +// Hashed & Hash-key mapping +template +class FatGenericTrieDB: private SpecificTrieDB, h256> +{ + using Super = SpecificTrieDB, h256>; + +public: + using DB = _DB; + FatGenericTrieDB(DB* _db = nullptr): Super(_db) {} + FatGenericTrieDB(DB* _db, h256 _root, Verification _v = Verification::Normal): Super(_db, _root, _v) {} + + using Super::init; + using Super::isNull; + using Super::isEmpty; + using Super::root; + using Super::leftOvers; + using Super::check; + using Super::open; + using Super::setRoot; + using Super::db; + using Super::debugStructure; + + std::string at(bytesConstRef _key) const { return Super::at(sha3(_key)); } + bool contains(bytesConstRef _key) { return Super::contains(sha3(_key)); } + void insert(bytesConstRef _key, bytesConstRef _value) + { + h256 hash = sha3(_key); + Super::insert(hash, _value); + Super::db()->insertAux(hash, _key); + } + + void remove(bytesConstRef _key) { Super::remove(sha3(_key)); } + + // iterates over pairs + class iterator: public GenericTrieDB<_DB>::iterator + { + public: + using Super = typename GenericTrieDB<_DB>::iterator; + + iterator() { } + iterator(FatGenericTrieDB const* _trie) : Super(_trie) { } + + typename Super::value_type at() const + { + auto hashed = Super::at(); + m_key = static_cast(Super::m_that)->db()->lookupAux(h256(hashed.first)); + return std::make_pair(&m_key, std::move(hashed.second)); + } + + private: + mutable bytes m_key; + }; + + iterator begin() const { return iterator(); } + iterator end() const { return iterator(); } + + // iterates over pairs + class HashedIterator: public GenericTrieDB<_DB>::iterator + { + public: + using Super = typename GenericTrieDB<_DB>::iterator; + + HashedIterator() {} + HashedIterator(FatGenericTrieDB const* _trie) : Super(_trie) {} + + bytes key() const + { + auto hashed = Super::at(); + return static_cast(Super::m_that)->db()->lookupAux(h256(hashed.first)); + } + }; + + HashedIterator hashedBegin() const { return HashedIterator(this); } + HashedIterator hashedEnd() const { return HashedIterator(); } +}; + +template using TrieDB = SpecificTrieDB, KeyType>; + +} + +// Template implementations... +namespace dev +{ + +template GenericTrieDB::iterator::iterator(GenericTrieDB const* _db) +{ + m_that = _db; + m_trail.push_back({_db->node(_db->m_root), std::string(1, '\0'), 255}); // one null byte is the HPE for the empty key. + next(); +} + +template GenericTrieDB::iterator::iterator(GenericTrieDB const* _db, bytesConstRef _fullKey) +{ + m_that = _db; + m_trail.push_back({_db->node(_db->m_root), std::string(1, '\0'), 255}); // one null byte is the HPE for the empty key. + next(_fullKey); +} + +template typename GenericTrieDB::iterator::value_type GenericTrieDB::iterator::at() const +{ + assert(m_trail.size()); + Node const& b = m_trail.back(); + assert(b.key.size()); + assert(!(b.key[0] & 0x10)); // should be an integer number of bytes (i.e. not an odd number of nibbles). + + RLP rlp(b.rlp); + return std::make_pair(bytesConstRef(b.key).cropped(1), rlp[rlp.itemCount() == 2 ? 1 : 16].payload()); +} + +template void GenericTrieDB::iterator::next(NibbleSlice _key) +{ + NibbleSlice k = _key; + while (true) + { + if (m_trail.empty()) + { + m_that = nullptr; + return; + } + + Node const& b = m_trail.back(); + RLP rlp(b.rlp); + + if (m_trail.back().child == 255) + { + // Entering. Look for first... + if (rlp.isEmpty()) + { + // Kill our search as soon as we hit an empty node. + k.clear(); + m_trail.pop_back(); + continue; + } + if (!rlp.isList() || (rlp.itemCount() != 2 && rlp.itemCount() != 17)) + { +#if ETH_PARANOIA + cwarn << "BIG FAT ERROR. STATE TRIE CORRUPTED!!!!!"; + cwarn << b.rlp.size() << toHex(b.rlp); + cwarn << rlp; + auto c = rlp.itemCount(); + cwarn << c; + BOOST_THROW_EXCEPTION(InvalidTrie()); +#else + m_that = nullptr; + return; +#endif + } + if (rlp.itemCount() == 2) + { + // Just turn it into a valid Branch + auto keyOfRLP = keyOf(rlp); + + // TODO: do something different depending on how keyOfRLP compares to k.mid(0, std::min(k.size(), keyOfRLP.size())); + // if == all is good - continue descent. + // if > discard key and continue descent. + // if < discard key and skip node. + + if (!k.contains(keyOfRLP)) + { + if (!k.isEarlierThan(keyOfRLP)) + { + k.clear(); + m_trail.pop_back(); + continue; + } + k.clear(); + } + + k = k.mid(std::min(k.size(), keyOfRLP.size())); + m_trail.back().key = hexPrefixEncode(keyOf(m_trail.back().key), keyOfRLP, false); + if (isLeaf(rlp)) + { + // leaf - exit now. + if (k.empty()) + { + m_trail.back().child = 0; + return; + } + // Still data in key we're supposed to be looking for when we're at a leaf. Go for next one. + k.clear(); + m_trail.pop_back(); + continue; + } + + // enter child. + m_trail.back().rlp = m_that->deref(rlp[1]); + // no need to set .child as 255 - it's already done. + continue; + } + else + { + // Already a branch - look for first valid. + if (k.size()) + { + m_trail.back().setChild(k[0]); + k = k.mid(1); + } + else + m_trail.back().setChild(16); + // run through to... + } + } + else + { + // Continuing/exiting. Look for next... + if (!(rlp.isList() && rlp.itemCount() == 17)) + { + k.clear(); + m_trail.pop_back(); + continue; + } + // else run through to... + m_trail.back().incrementChild(); + } + + // ...here. should only get here if we're a list. + assert(rlp.isList() && rlp.itemCount() == 17); + for (;; m_trail.back().incrementChild()) + if (m_trail.back().child == 17) + { + // finished here. + k.clear(); + m_trail.pop_back(); + break; + } + else if (!rlp[m_trail.back().child].isEmpty()) + { + if (m_trail.back().child == 16) + return; // have a value at this node - exit now. + else + { + // lead-on to another node - enter child. + // fixed so that Node passed into push_back is constructed *before* m_trail is potentially resized (which invalidates back and rlp) + Node const& back = m_trail.back(); + m_trail.push_back(Node{ + m_that->deref(rlp[back.child]), + hexPrefixEncode(keyOf(back.key), NibbleSlice(bytesConstRef(&back.child, 1), 1), false), + 255 + }); + break; + } + } + else + k.clear(); + } +} + +template void GenericTrieDB::iterator::next() +{ + while (true) + { + if (m_trail.empty()) + { + m_that = nullptr; + return; + } + + Node const& b = m_trail.back(); + RLP rlp(b.rlp); + + if (m_trail.back().child == 255) + { + // Entering. Look for first... + if (rlp.isEmpty()) + { + m_trail.pop_back(); + continue; + } + if (!(rlp.isList() && (rlp.itemCount() == 2 || rlp.itemCount() == 17))) + { +#if ETH_PARANOIA + cwarn << "BIG FAT ERROR. STATE TRIE CORRUPTED!!!!!"; + cwarn << b.rlp.size() << toHex(b.rlp); + cwarn << rlp; + auto c = rlp.itemCount(); + cwarn << c; + BOOST_THROW_EXCEPTION(InvalidTrie()); +#else + m_that = nullptr; + return; +#endif + } + if (rlp.itemCount() == 2) + { + // Just turn it into a valid Branch + m_trail.back().key = hexPrefixEncode(keyOf(m_trail.back().key), keyOf(rlp), false); + if (isLeaf(rlp)) + { + // leaf - exit now. + m_trail.back().child = 0; + return; + } + + // enter child. + m_trail.back().rlp = m_that->deref(rlp[1]); + // no need to set .child as 255 - it's already done. + continue; + } + else + { + // Already a branch - look for first valid. + m_trail.back().setFirstChild(); + // run through to... + } + } + else + { + // Continuing/exiting. Look for next... + if (!(rlp.isList() && rlp.itemCount() == 17)) + { + m_trail.pop_back(); + continue; + } + // else run through to... + m_trail.back().incrementChild(); + } + + // ...here. should only get here if we're a list. + assert(rlp.isList() && rlp.itemCount() == 17); + for (;; m_trail.back().incrementChild()) + if (m_trail.back().child == 17) + { + // finished here. + m_trail.pop_back(); + break; + } + else if (!rlp[m_trail.back().child].isEmpty()) + { + if (m_trail.back().child == 16) + return; // have a value at this node - exit now. + else + { + // lead-on to another node - enter child. + // fixed so that Node passed into push_back is constructed *before* m_trail is potentially resized (which invalidates back and rlp) + Node const& back = m_trail.back(); + m_trail.push_back(Node{ + m_that->deref(rlp[back.child]), + hexPrefixEncode(keyOf(back.key), NibbleSlice(bytesConstRef(&back.child, 1), 1), false), + 255 + }); + break; + } + } + } +} + +template typename SpecificTrieDB::iterator::value_type SpecificTrieDB::iterator::at() const +{ + auto p = Super::at(); + value_type ret; + assert(p.first.size() == sizeof(KeyType)); + memcpy(&ret.first, p.first.data(), sizeof(KeyType)); + ret.second = p.second; + return ret; +} + +template void GenericTrieDB::insert(bytesConstRef _key, bytesConstRef _value) +{ +#if ETH_PARANOIA + tdebug << "Insert" << toHex(_key.cropped(0, 4)) << "=>" << toHex(_value); +#endif + + std::string rootValue = node(m_root); + assert(rootValue.size()); + bytes b = mergeAt(RLP(rootValue), m_root, NibbleSlice(_key), _value); + + // mergeAt won't attempt to delete the node if it's less than 32 bytes + // However, we know it's the root node and thus always hashed. + // So, if it's less than 32 (and thus should have been deleted but wasn't) then we delete it here. + if (rootValue.size() < 32) + forceKillNode(m_root); + m_root = forceInsertNode(&b); +} + +template std::string GenericTrieDB::at(bytesConstRef _key) const +{ + return atAux(RLP(node(m_root)), _key); +} + +template std::string GenericTrieDB::atAux(RLP const& _here, NibbleSlice _key) const +{ + if (_here.isEmpty() || _here.isNull()) + // not found. + return std::string(); + unsigned itemCount = _here.itemCount(); + assert(_here.isList() && (itemCount == 2 || itemCount == 17)); + if (itemCount == 2) + { + auto k = keyOf(_here); + if (_key == k && isLeaf(_here)) + // reached leaf and it's us + return _here[1].toString(); + else if (_key.contains(k) && !isLeaf(_here)) + // not yet at leaf and it might yet be us. onwards... + return atAux(_here[1].isList() ? _here[1] : RLP(node(_here[1].toHash())), _key.mid(k.size())); + else + // not us. + return std::string(); + } + else + { + if (_key.size() == 0) + return _here[16].toString(); + auto n = _here[_key[0]]; + if (n.isEmpty()) + return std::string(); + else + return atAux(n.isList() ? n : RLP(node(n.toHash())), _key.mid(1)); + } +} + +template bytes GenericTrieDB::mergeAt(RLP const& _orig, NibbleSlice _k, bytesConstRef _v, bool _inLine) +{ + return mergeAt(_orig, sha3(_orig.data()), _k, _v, _inLine); +} + +template bytes GenericTrieDB::mergeAt(RLP const& _orig, h256 const& _origHash, NibbleSlice _k, bytesConstRef _v, bool _inLine) +{ +#if ETH_PARANOIA + tdebug << "mergeAt " << _orig << _k << sha3(_orig.data()); +#endif + + // The caller will make sure that the bytes are inserted properly. + // - This might mean inserting an entry into m_over + // We will take care to ensure that (our reference to) _orig is killed. + + // Empty - just insert here + if (_orig.isEmpty()) + return place(_orig, _k, _v); + + unsigned itemCount = _orig.itemCount(); + assert(_orig.isList() && (itemCount == 2 || itemCount == 17)); + if (itemCount == 2) + { + // pair... + NibbleSlice k = keyOf(_orig); + + // exactly our node - place value in directly. + if (k == _k && isLeaf(_orig)) + return place(_orig, _k, _v); + + // partial key is our key - move down. + if (_k.contains(k) && !isLeaf(_orig)) + { + if (!_inLine) + killNode(_orig, _origHash); + RLPStream s(2); + s.append(_orig[0]); + mergeAtAux(s, _orig[1], _k.mid(k.size()), _v); + return s.out(); + } + + auto sh = _k.shared(k); +// std::cout << _k << " sh " << k << " = " << sh << std::endl; + if (sh) + { + // shared stuff - cleve at disagreement. + auto cleved = cleve(_orig, sh); + return mergeAt(RLP(cleved), _k, _v, true); + } + else + { + // nothing shared - branch + auto branched = branch(_orig); + return mergeAt(RLP(branched), _k, _v, true); + } + } + else + { + // branch... + + // exactly our node - place value. + if (_k.size() == 0) + return place(_orig, _k, _v); + + // Kill the node. + if (!_inLine) + killNode(_orig, _origHash); + + // not exactly our node - delve to next level at the correct index. + byte n = _k[0]; + RLPStream r(17); + for (byte i = 0; i < 17; ++i) + if (i == n) + mergeAtAux(r, _orig[i], _k.mid(1), _v); + else + r.append(_orig[i]); + return r.out(); + } + +} + +template void GenericTrieDB::mergeAtAux(RLPStream& _out, RLP const& _orig, NibbleSlice _k, bytesConstRef _v) +{ +#if ETH_PARANOIA || !ETH_TRUE + tdebug << "mergeAtAux " << _orig << _k << sha3(_orig.data()) << ((_orig.isData() && _orig.size() <= 32) ? _orig.toHash().abridged() : std::string()); +#endif + + RLP r = _orig; + std::string s; + // _orig is always a segment of a node's RLP - removing it alone is pointless. However, if may be a hash, in which case we deref and we know it is removable. + bool isRemovable = false; + if (!r.isList() && !r.isEmpty()) + { + s = node(_orig.toHash()); + r = RLP(s); + assert(!r.isNull()); + isRemovable = true; + } + bytes b = mergeAt(r, _k, _v, !isRemovable); + streamNode(_out, b); +} + +template void GenericTrieDB::remove(bytesConstRef _key) +{ +#if ETH_PARANOIA + tdebug << "Remove" << toHex(_key.cropped(0, 4).toBytes()); +#endif + + std::string rv = node(m_root); + bytes b = deleteAt(RLP(rv), NibbleSlice(_key)); + if (b.size()) + { + if (rv.size() < 32) + forceKillNode(m_root); + m_root = forceInsertNode(&b); + } +} + +template bool GenericTrieDB::isTwoItemNode(RLP const& _n) const +{ + return (_n.isData() && RLP(node(_n.toHash())).itemCount() == 2) + || (_n.isList() && _n.itemCount() == 2); +} + +template std::string GenericTrieDB::deref(RLP const& _n) const +{ + return _n.isList() ? _n.data().toString() : node(_n.toHash()); +} + +template bytes GenericTrieDB::deleteAt(RLP const& _orig, NibbleSlice _k) +{ +#if ETH_PARANOIA + tdebug << "deleteAt " << _orig << _k << sha3(_orig.data()); +#endif + + // The caller will make sure that the bytes are inserted properly. + // - This might mean inserting an entry into m_over + // We will take care to ensure that (our reference to) _orig is killed. + + // Empty - not found - no change. + if (_orig.isEmpty()) + return bytes(); + + assert(_orig.isList() && (_orig.itemCount() == 2 || _orig.itemCount() == 17)); + if (_orig.itemCount() == 2) + { + // pair... + NibbleSlice k = keyOf(_orig); + + // exactly our node - return null. + if (k == _k && isLeaf(_orig)) + { + killNode(_orig); + return RLPNull; + } + + // partial key is our key - move down. + if (_k.contains(k)) + { + RLPStream s; + s.appendList(2) << _orig[0]; + if (!deleteAtAux(s, _orig[1], _k.mid(k.size()))) + return bytes(); + killNode(_orig); + RLP r(s.out()); + if (isTwoItemNode(r[1])) + return graft(r); + return s.out(); + } + else + // not found - no change. + return bytes(); + } + else + { + // branch... + + // exactly our node - remove and rejig. + if (_k.size() == 0 && !_orig[16].isEmpty()) + { + // Kill the node. + killNode(_orig); + + byte used = uniqueInUse(_orig, 16); + if (used != 255) + if (isTwoItemNode(_orig[used])) + { + auto merged = merge(_orig, used); + return graft(RLP(merged)); + } + else + return merge(_orig, used); + else + { + RLPStream r(17); + for (byte i = 0; i < 16; ++i) + r << _orig[i]; + r << ""; + return r.out(); + } + } + else + { + // not exactly our node - delve to next level at the correct index. + RLPStream r(17); + byte n = _k[0]; + for (byte i = 0; i < 17; ++i) + if (i == n) + if (!deleteAtAux(r, _orig[i], _k.mid(1))) // bomb out if the key didn't turn up. + return bytes(); + else {} + else + r << _orig[i]; + + // Kill the node. + killNode(_orig); + + // check if we ended up leaving the node invalid. + RLP rlp(r.out()); + byte used = uniqueInUse(rlp, 255); + if (used == 255) // no - all ok. + return r.out(); + + // yes; merge + if (isTwoItemNode(rlp[used])) + { + auto merged = merge(rlp, used); + return graft(RLP(merged)); + } + else + return merge(rlp, used); + } + } + +} + +template bool GenericTrieDB::deleteAtAux(RLPStream& _out, RLP const& _orig, NibbleSlice _k) +{ +#if ETH_PARANOIA || !ETH_TRUE + tdebug << "deleteAtAux " << _orig << _k << sha3(_orig.data()) << ((_orig.isData() && _orig.size() <= 32) ? _orig.toHash().abridged() : std::string()); +#endif + + bytes b = _orig.isEmpty() ? bytes() : deleteAt(_orig.isList() ? _orig : RLP(node(_orig.toHash())), _k); + + if (!b.size()) // not found - no change. + return false; + +/* if (_orig.isList()) + killNode(_orig); + else + killNode(_orig.toHash());*/ + + streamNode(_out, b); + return true; +} + +template bytes GenericTrieDB::place(RLP const& _orig, NibbleSlice _k, bytesConstRef _s) +{ +#if ETH_PARANOIA + tdebug << "place " << _orig << _k; +#endif + + killNode(_orig); + if (_orig.isEmpty()) + return rlpList(hexPrefixEncode(_k, true), _s); + + assert(_orig.isList() && (_orig.itemCount() == 2 || _orig.itemCount() == 17)); + if (_orig.itemCount() == 2) + return rlpList(_orig[0], _s); + + auto s = RLPStream(17); + for (unsigned i = 0; i < 16; ++i) + s << _orig[i]; + s << _s; + return s.out(); +} + +// in1: [K, S] (DEL) +// out1: null +// in2: [V0, ..., V15, S] (DEL) +// out2: [V0, ..., V15, null] iff exists i: !!Vi -- OR -- null otherwise +template bytes GenericTrieDB::remove(RLP const& _orig) +{ +#if ETH_PARANOIA + tdebug << "kill " << _orig; +#endif + + killNode(_orig); + + assert(_orig.isList() && (_orig.itemCount() == 2 || _orig.itemCount() == 17)); + if (_orig.itemCount() == 2) + return RLPNull; + RLPStream r(17); + for (unsigned i = 0; i < 16; ++i) + r << _orig[i]; + r << ""; + return r.out(); +} + +template RLPStream& GenericTrieDB::streamNode(RLPStream& _s, bytes const& _b) +{ + if (_b.size() < 32) + _s.appendRaw(_b); + else + _s.append(forceInsertNode(&_b)); + return _s; +} + +template bytes GenericTrieDB::cleve(RLP const& _orig, unsigned _s) +{ +#if ETH_PARANOIA + tdebug << "cleve " << _orig << _s; +#endif + + killNode(_orig); + assert(_orig.isList() && _orig.itemCount() == 2); + auto k = keyOf(_orig); + assert(_s && _s <= k.size()); + + RLPStream bottom(2); + bottom << hexPrefixEncode(k, isLeaf(_orig), /*ugh*/(int)_s) << _orig[1]; + + RLPStream top(2); + top << hexPrefixEncode(k, false, 0, /*ugh*/(int)_s); + streamNode(top, bottom.out()); + + return top.out(); +} + +template bytes GenericTrieDB::graft(RLP const& _orig) +{ +#if ETH_PARANOIA + tdebug << "graft " << _orig; +#endif + + assert(_orig.isList() && _orig.itemCount() == 2); + std::string s; + RLP n; + if (_orig[1].isList()) + n = _orig[1]; + else + { + // remove second item from the trie after derefrencing it into s & n. + auto lh = _orig[1].toHash(); + s = node(lh); + forceKillNode(lh); + n = RLP(s); + } + assert(n.itemCount() == 2); + + return rlpList(hexPrefixEncode(keyOf(_orig), keyOf(n), isLeaf(n)), n[1]); +// auto ret = +// std::cout << keyOf(_orig) << " ++ " << keyOf(n) << " == " << keyOf(RLP(ret)) << std::endl; +// return ret; +} + +template bytes GenericTrieDB::merge(RLP const& _orig, byte _i) +{ +#if ETH_PARANOIA + tdebug << "merge " << _orig << (int)_i; +#endif + + assert(_orig.isList() && _orig.itemCount() == 17); + RLPStream s(2); + if (_i != 16) + { + assert(!_orig[_i].isEmpty()); + s << hexPrefixEncode(bytesConstRef(&_i, 1), false, 1, 2, 0); + } + else + s << hexPrefixEncode(bytes(), true); + s << _orig[_i]; + return s.out(); +} + +template bytes GenericTrieDB::branch(RLP const& _orig) +{ +#if ETH_PARANOIA + tdebug << "branch " << _orig; +#endif + + assert(_orig.isList() && _orig.itemCount() == 2); + killNode(_orig); + + auto k = keyOf(_orig); + RLPStream r(17); + if (k.size() == 0) + { + assert(isLeaf(_orig)); + for (unsigned i = 0; i < 16; ++i) + r << ""; + r << _orig[1]; + } + else + { + byte b = k[0]; + for (unsigned i = 0; i < 16; ++i) + if (i == b) + if (isLeaf(_orig) || k.size() > 1) + streamNode(r, rlpList(hexPrefixEncode(k.mid(1), isLeaf(_orig)), _orig[1])); + else + r << _orig[1]; + else + r << ""; + r << ""; + } + return r.out(); +} + +} diff --git a/libdevcore/TrieHash.cpp b/libdevcore/TrieHash.cpp new file mode 100644 index 0000000000..f611a57a61 --- /dev/null +++ b/libdevcore/TrieHash.cpp @@ -0,0 +1,199 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file TrieHash.cpp + * @author Gav Wood + * @date 2014 + */ + +#if !defined(ETH_EMSCRIPTEN) + +#include "TrieHash.h" +#include "TrieCommon.h" +#include "TrieDB.h" // @TODO replace ASAP! +#include "SHA3.h" +using namespace std; +using namespace dev; + +namespace dev +{ + +/*/ +#define APPEND_CHILD appendData +/*/ +#define APPEND_CHILD appendRaw +/**/ + +#define ENABLE_DEBUG_PRINT 0 + +#if ENABLE_DEBUG_PRINT +bool g_hashDebug = false; +#endif + +void hash256aux(HexMap const& _s, HexMap::const_iterator _begin, HexMap::const_iterator _end, unsigned _preLen, RLPStream& _rlp); + +void hash256rlp(HexMap const& _s, HexMap::const_iterator _begin, HexMap::const_iterator _end, unsigned _preLen, RLPStream& _rlp) +{ +#if ENABLE_DEBUG_PRINT + static std::string s_indent; + if (_preLen) + s_indent += " "; +#endif + + if (_begin == _end) + _rlp << ""; // NULL + else if (std::next(_begin) == _end) + { + // only one left - terminate with the pair. + _rlp.appendList(2) << hexPrefixEncode(_begin->first, true, _preLen) << _begin->second; +#if ENABLE_DEBUG_PRINT + if (g_hashDebug) + LOG(ERROR) << s_indent << toHex(bytesConstRef(_begin->first.data() + _preLen, _begin->first.size() - _preLen), 1) << ": " << _begin->second << " = " << sha3(_rlp.out()) << std::endl; +#endif + } + else + { + // find the number of common prefix nibbles shared + // i.e. the minimum number of nibbles shared at the beginning between the first hex string and each successive. + unsigned sharedPre = (unsigned)-1; + unsigned c = 0; + for (auto i = std::next(_begin); i != _end && sharedPre; ++i, ++c) + { + unsigned x = std::min(sharedPre, std::min((unsigned)_begin->first.size(), (unsigned)i->first.size())); + unsigned shared = _preLen; + for (; shared < x && _begin->first[shared] == i->first[shared]; ++shared) {} + sharedPre = std::min(shared, sharedPre); + } + if (sharedPre > _preLen) + { + // if they all have the same next nibble, we also want a pair. +#if ENABLE_DEBUG_PRINT + if (g_hashDebug) + LOG(ERROR) << s_indent << toHex(bytesConstRef(_begin->first.data() + _preLen, sharedPre), 1) << ": " << std::endl; +#endif + _rlp.appendList(2) << hexPrefixEncode(_begin->first, false, _preLen, (int)sharedPre); + hash256aux(_s, _begin, _end, (unsigned)sharedPre, _rlp); +#if ENABLE_DEBUG_PRINT + if (g_hashDebug) + LOG(ERROR) << s_indent << "= " << hex << sha3(_rlp.out()) << dec << std::endl; +#endif + } + else + { + // otherwise enumerate all 16+1 entries. + _rlp.appendList(17); + auto b = _begin; + if (_preLen == b->first.size()) + { +#if ENABLE_DEBUG_PRINT + if (g_hashDebug) + LOG(ERROR) << s_indent << "@: " << b->second << std::endl; +#endif + ++b; + } + for (auto i = 0; i < 16; ++i) + { + auto n = b; + for (; n != _end && n->first[_preLen] == i; ++n) {} + if (b == n) + _rlp << ""; + else + { +#if ENABLE_DEBUG_PRINT + if (g_hashDebug) + LOG(ERROR) << s_indent << std::hex << i << ": " << std::dec << std::endl; +#endif + hash256aux(_s, b, n, _preLen + 1, _rlp); + } + b = n; + } + if (_preLen == _begin->first.size()) + _rlp << _begin->second; + else + _rlp << ""; + +#if ENABLE_DEBUG_PRINT + if (g_hashDebug) + LOG(ERROR) << s_indent << "= " << hex << sha3(_rlp.out()) << dec << std::endl; +#endif + } + } +#if ENABLE_DEBUG_PRINT + if (_preLen) + s_indent.resize(s_indent.size() - 2); +#endif +} + +void hash256aux(HexMap const& _s, HexMap::const_iterator _begin, HexMap::const_iterator _end, unsigned _preLen, RLPStream& _rlp) +{ + RLPStream rlp; + hash256rlp(_s, _begin, _end, _preLen, rlp); + if (rlp.out().size() < 32) + { + // RECURSIVE RLP +#if ENABLE_DEBUG_PRINT + LOG(ERROR) << "[INLINE: " << dec << rlp.out().size() << " < 32]" << endl; +#endif + _rlp.APPEND_CHILD(rlp.out()); + } + else + { +#if ENABLE_DEBUG_PRINT + LOG(ERROR) << "[HASH: " << dec << rlp.out().size() << " >= 32]" << endl; +#endif + _rlp << sha3(rlp.out()); + } +} + +bytes rlp256(BytesMap const& _s) +{ + // build patricia tree. + if (_s.empty()) + return rlp(""); + HexMap hexMap; + for (auto i = _s.rbegin(); i != _s.rend(); ++i) + hexMap[asNibbles(bytesConstRef(&i->first))] = i->second; + RLPStream s; + hash256rlp(hexMap, hexMap.cbegin(), hexMap.cend(), 0, s); + return s.out(); +} + +h256 hash256(BytesMap const& _s) +{ + return sha3(rlp256(_s)); +} + +h256 orderedTrieRoot(std::vector const& _data) +{ + BytesMap m; + unsigned j = 0; + for (auto i: _data) + m[rlp(j++)] = i; + return hash256(m); +} + +h256 orderedTrieRoot(std::vector const& _data) +{ + BytesMap m; + unsigned j = 0; + for (auto i: _data) + m[rlp(j++)] = i.toBytes(); + return hash256(m); +} + +} + +#endif // ETH_EMSCRIPTEN diff --git a/libdevcore/TrieHash.h b/libdevcore/TrieHash.h new file mode 100644 index 0000000000..bf22a9024d --- /dev/null +++ b/libdevcore/TrieHash.h @@ -0,0 +1,46 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file TrieHash.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include "Common.h" +#include "FixedHash.h" + +namespace dev +{ + +bytes rlp256(BytesMap const& _s); +h256 hash256(BytesMap const& _s); + +h256 orderedTrieRoot(std::vector const& _data); + +template inline h256 trieRootOver(unsigned _itemCount, T const& _getKey, U const& _getValue) +{ + BytesMap m; + for (unsigned i = 0; i < _itemCount; ++i) + m[_getKey(i)] = _getValue(i); + return hash256(m); +} + +h256 orderedTrieRoot(std::vector const& _data); +h256 orderedTrieRoot(std::vector const& _data); + +} diff --git a/libdevcore/UndefMacros.h b/libdevcore/UndefMacros.h new file mode 100644 index 0000000000..7ab4408cbd --- /dev/null +++ b/libdevcore/UndefMacros.h @@ -0,0 +1,46 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file UndefMacros.h + * @author Lefteris + * @date 2015 + * + * This header should be used to #undef some really evil macros defined by + * windows.h which result in conflict with our libsolidity/Token.h + */ +#pragma once + +#if defined(_MSC_VER) || defined(__MINGW32__) + +#undef DELETE +#undef IN +#undef VOID +#undef THIS +#undef CONST + +// Conflicting define on MinGW in windows.h +// windows.h(19): #define interface struct +#ifdef interface +#undef interface +#endif + +#elif defined(DELETE) || defined(IN) || defined(VOID) || defined(THIS) || defined(CONST) || defined(interface) + +#error "The preceding macros in this header file are reserved for V8's "\ +"TOKEN_LIST. Please add a platform specific define above to undefine "\ +"overlapping macros." + +#endif diff --git a/libdevcore/Worker.cpp b/libdevcore/Worker.cpp new file mode 100644 index 0000000000..1fb3c5d62c --- /dev/null +++ b/libdevcore/Worker.cpp @@ -0,0 +1,127 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Worker.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "Worker.h" + +#include +#include +#include "Log.h" +using namespace std; +using namespace dev; + +void Worker::startWorking() +{ +// cnote << "startWorking for thread" << m_name; + Guard l(x_work); + if (m_work) + { + WorkerState ex = WorkerState::Stopped; + m_state.compare_exchange_strong(ex, WorkerState::Starting); + //如果m_state==ex 就把WorkerState::Starting赋给m_state + } + else + { + m_state = WorkerState::Starting; + //新起线程异步执行 + m_work.reset(new thread([&]() + { + setThreadName(m_name.c_str()); +// cnote << "Thread begins"; + while (m_state != WorkerState::Killing) + { + WorkerState ex = WorkerState::Starting; + //不确定这段代码执行有什么用, 为了下面的日志? 还有一个强制转换也不确定 + bool ok = m_state.compare_exchange_strong(ex, WorkerState::Started); +// cnote << "Trying to set Started: Thread was" << (unsigned)ex << "; " << ok; + (void)ok; + + try + { + //host继承worker 这里调用host里面的继承方法 + //client继承worker + startedWorking(); + workLoop(); + doneWorking(); + } + catch (std::exception const& _e) + { + clog(WarnChannel) << "Exception thrown in Worker thread: " << _e.what(); + } + +// ex = WorkerState::Stopping; +// m_state.compare_exchange_strong(ex, WorkerState::Stopped); + + ex = m_state.exchange(WorkerState::Stopped); +// cnote << "State: Stopped: Thread was" << (unsigned)ex; + if (ex == WorkerState::Killing || ex == WorkerState::Starting) + m_state.exchange(ex); + +// cnote << "Waiting until not Stopped..."; + DEV_TIMED_ABOVE("Worker stopping", 100) + while (m_state == WorkerState::Stopped) + this_thread::sleep_for(chrono::milliseconds(20)); + } + })); +// cnote << "Spawning" << m_name; + } + DEV_TIMED_ABOVE("Start worker", 100) + while (m_state == WorkerState::Starting) + this_thread::sleep_for(chrono::microseconds(20)); +} + +void Worker::stopWorking() +{ + DEV_GUARDED(x_work) + if (m_work) + { + WorkerState ex = WorkerState::Started; + m_state.compare_exchange_strong(ex, WorkerState::Stopping); + + DEV_TIMED_ABOVE("Stop worker", 100) + while (m_state != WorkerState::Stopped) + this_thread::sleep_for(chrono::microseconds(20)); + } +} + +void Worker::terminate() +{ +// cnote << "stopWorking for thread" << m_name; + DEV_GUARDED(x_work) + if (m_work) + { + m_state.exchange(WorkerState::Killing); + + DEV_TIMED_ABOVE("Terminate worker", 100) + m_work->join(); + + m_work.reset(); + } +} + +void Worker::workLoop() +{ + while (m_state == WorkerState::Started) + { + if (m_idleWaitMs) + this_thread::sleep_for(chrono::milliseconds(m_idleWaitMs)); + doWork(); + } +} diff --git a/libdevcore/Worker.h b/libdevcore/Worker.h new file mode 100644 index 0000000000..78dcea345a --- /dev/null +++ b/libdevcore/Worker.h @@ -0,0 +1,107 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Worker.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include +#include +#include "Guards.h" + +namespace dev +{ + +enum class IfRunning +{ + Fail, + Join, + Detach +}; + +enum class WorkerState +{ + Starting, + Started, + Stopping, + Stopped, + Killing +}; + +class Worker +{ +protected: + Worker(std::string const& _name = "anon", unsigned _idleWaitMs = 30): m_name(_name), m_idleWaitMs(_idleWaitMs) {} + + /// Move-constructor. + Worker(Worker&& _m) { std::swap(m_name, _m.m_name); } + + /// Move-assignment. + Worker& operator=(Worker&& _m) + { + assert(&_m != this); + std::swap(m_name, _m.m_name); + return *this; + } + + virtual ~Worker() { terminate(); } + + /// Allows changing worker name if work is stopped. + void setName(std::string _n) { if (!isWorking()) m_name = _n; } + + /// Starts worker thread; causes startedWorking() to be called. + void startWorking(); + + /// Stop worker thread; causes call to stopWorking(). + void stopWorking(); + + /// Returns if worker thread is present. + bool isWorking() const { Guard l(x_work); return m_state == WorkerState::Started; } + + /// Called after thread is started from startWorking(). + virtual void startedWorking() {} + + /// Called continuously following sleep for m_idleWaitMs. + virtual void doWork() {} + + /// Overrides doWork(); should call shouldStop() often and exit when true. + virtual void workLoop(); + bool shouldStop() const { return m_state != WorkerState::Started; } + + /// Called when is to be stopped, just prior to thread being joined. + virtual void doneWorking() {} + + /// Blocks caller into worker thread has finished. +// void join() const { Guard l(x_work); try { if (m_work) m_work->join(); } catch (...) {} } + +private: + /// Stop and never start again. + void terminate(); + + std::string m_name; + + unsigned m_idleWaitMs = 0; + + mutable Mutex x_work; ///< Lock for the network existance. + std::unique_ptr m_work; ///< The network thread. + std::atomic m_state = {WorkerState::Starting}; +}; + +} diff --git a/libdevcore/boost_multiprecision_number_compare_bug_workaround.hpp b/libdevcore/boost_multiprecision_number_compare_bug_workaround.hpp new file mode 100644 index 0000000000..0fd6461eed --- /dev/null +++ b/libdevcore/boost_multiprecision_number_compare_bug_workaround.hpp @@ -0,0 +1,520 @@ + +// This is a copy of boost/multiprecision/detail/number_compare.hpp from boost 1.59 to replace buggy version from 1.58. + +#ifdef BOOST_MP_COMPARE_HPP +#error This bug workaround header must be included before original boost/multiprecision/detail/number_compare.hpp +#endif + +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2012 John Maddock. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_MP_COMPARE_HPP +#define BOOST_MP_COMPARE_HPP + +// A copy of boost/multiprecision/traits/is_backend.hpp +#ifndef BOOST_MP_IS_BACKEND_HPP +#define BOOST_MP_IS_BACKEND_HPP + +#include +#include +#include +#include +#include + +namespace boost{ namespace multiprecision{ namespace detail{ + + BOOST_MPL_HAS_XXX_TRAIT_DEF(signed_types) + BOOST_MPL_HAS_XXX_TRAIT_DEF(unsigned_types) + BOOST_MPL_HAS_XXX_TRAIT_DEF(float_types) + + template + struct is_backend + { + static const bool value = has_signed_types::value && has_unsigned_types::value && has_float_types::value; + }; + + template + struct other_backend + { + typedef typename boost::conditional< + boost::is_same, number >::value, + number, number >::type type; + }; + + template + struct number_from_backend + { + typedef typename boost::conditional < + boost::is_convertible >::value, + number, + typename other_backend::type > ::type type; + }; + + template + struct is_first_backend_imp{ static const bool value = false; }; + template + struct is_first_backend_imp{ static const bool value = is_convertible >::value || is_convertible >::value; }; + + template + struct is_first_backend : is_first_backend_imp::value, T, U> {}; + + template + struct is_second_backend_imp{ static const bool value = false; }; + template + struct is_second_backend_imp{ static const bool value = is_convertible >::value || is_convertible >::value; }; + + template + struct is_second_backend : is_second_backend_imp::value, T, U> {}; + +} +} +} + +#endif // BOOST_MP_IS_BACKEND_HPP + +// +// Comparison operators for number. +// + +namespace boost{ namespace multiprecision{ + +namespace default_ops{ + +template +inline bool eval_eq(const B& a, const B& b) +{ + return a.compare(b) == 0; +} +template +inline typename enable_if_c::value, bool>::type eval_eq(const T& a, const U& b) +{ + typename boost::multiprecision::detail::number_from_backend::type t(b); + return eval_eq(a, t.backend()); +} +template +inline typename enable_if_c::value, bool>::type eval_eq(const T& a, const U& b) +{ + typename boost::multiprecision::detail::number_from_backend::type t(a); + return eval_eq(t.backend(), b); +} + +template +inline bool eval_lt(const B& a, const B& b) +{ + return a.compare(b) < 0; +} +template +inline typename enable_if_c::value, bool>::type eval_lt(const T& a, const U& b) +{ + typename boost::multiprecision::detail::number_from_backend::type t(b); + return eval_lt(a, t.backend()); +} +template +inline typename enable_if_c::value, bool>::type eval_lt(const T& a, const U& b) +{ + typename boost::multiprecision::detail::number_from_backend::type t(a); + return eval_lt(t.backend(), b); +} + +template +inline bool eval_gt(const B& a, const B& b) +{ + return a.compare(b) > 0; +} +template +inline typename enable_if_c::value, bool>::type eval_gt(const T& a, const U& b) +{ + typename boost::multiprecision::detail::number_from_backend::type t(b); + return eval_gt(a, t.backend()); +} +template +inline typename enable_if_c::value, bool>::type eval_gt(const T& a, const U& b) +{ + typename boost::multiprecision::detail::number_from_backend::type t(a); + return eval_gt(t.backend(), b); +} + +} // namespace default_ops + +namespace detail{ + +template +struct is_valid_mixed_compare : public mpl::false_ {}; + +template +struct is_valid_mixed_compare, Val> : public is_convertible > {}; + +template +struct is_valid_mixed_compare, number > : public mpl::false_ {}; + +template +struct is_valid_mixed_compare, expression > + : public mpl::bool_, number >::value> {}; + +template +struct is_valid_mixed_compare, number > + : public mpl::bool_, number >::value> {}; + +template +inline BOOST_CONSTEXPR typename boost::enable_if_c::value != number_kind_floating_point, bool>::type is_unordered_value(const number&) +{ + return false; +} +template +inline BOOST_CONSTEXPR typename boost::enable_if_c::value == number_kind_floating_point, bool>::type is_unordered_value(const number& a) +{ + using default_ops::eval_fpclassify; + return eval_fpclassify(a.backend()) == FP_NAN; +} + +template +inline BOOST_CONSTEXPR typename boost::enable_if_c::value != number_kind_floating_point, bool>::type is_unordered_value(const Arithmetic&) +{ + return false; +} +template +inline BOOST_CONSTEXPR typename boost::enable_if_c::value == number_kind_floating_point, bool>::type is_unordered_value(const Arithmetic& a) +{ + return (boost::math::isnan)(a); +} + +template +inline BOOST_CONSTEXPR bool is_unordered_comparison(const T& a, const U& b) +{ + return is_unordered_value(a) || is_unordered_value(b); +} + +} + +template +inline bool operator == (const number& a, const number& b) +{ + using default_ops::eval_eq; + if(detail::is_unordered_comparison(a, b)) return false; + return eval_eq(a.backend(), b.backend()); +} +template +inline typename enable_if_c, Arithmetic>::value, bool>::type + operator == (const number& a, const Arithmetic& b) +{ + using default_ops::eval_eq; + if(detail::is_unordered_comparison(a, b)) return false; + return eval_eq(a.backend(), number::canonical_value(b)); +} +template +inline typename enable_if_c, Arithmetic>::value, bool>::type + operator == (const Arithmetic& a, const number& b) +{ + using default_ops::eval_eq; + if(detail::is_unordered_comparison(a, b)) return false; + return eval_eq(b.backend(), number::canonical_value(a)); +} +template +inline typename enable_if_c::result_type, Arithmetic>::value, bool>::type + operator == (const Arithmetic& a, const detail::expression& b) +{ + typedef typename detail::expression::result_type result_type; + using default_ops::eval_eq; + result_type t(b); + if(detail::is_unordered_comparison(a, t)) return false; + return eval_eq(t.backend(), result_type::canonical_value(a)); +} +template +inline typename enable_if_c::result_type, Arithmetic>::value, bool>::type + operator == (const detail::expression& a, const Arithmetic& b) +{ + typedef typename detail::expression::result_type result_type; + using default_ops::eval_eq; + result_type t(a); + if(detail::is_unordered_comparison(t, b)) return false; + return eval_eq(t.backend(), result_type::canonical_value(b)); +} +template +inline typename enable_if::result_type, typename detail::expression::result_type>, bool>::type + operator == (const detail::expression& a, const detail::expression& b) +{ + using default_ops::eval_eq; + typename detail::expression::result_type t(a); + typename detail::expression::result_type t2(b); + if(detail::is_unordered_comparison(t, t2)) return false; + return eval_eq(t.backend(), t2.backend()); +} + +template +inline bool operator != (const number& a, const number& b) +{ + using default_ops::eval_eq; + if(detail::is_unordered_comparison(a, b)) return true; + return !eval_eq(a.backend(), b.backend()); +} +template +inline typename enable_if_c, Arithmetic>::value, bool>::type + operator != (const number& a, const Arithmetic& b) +{ + using default_ops::eval_eq; + if(detail::is_unordered_comparison(a, b)) return true; + return !eval_eq(a.backend(), number::canonical_value(b)); +} +template +inline typename enable_if_c, Arithmetic>::value, bool>::type + operator != (const Arithmetic& a, const number& b) +{ + using default_ops::eval_eq; + if(detail::is_unordered_comparison(a, b)) return true; + return !eval_eq(b.backend(), number::canonical_value(a)); +} +template +inline typename enable_if_c::result_type, Arithmetic>::value, bool>::type + operator != (const Arithmetic& a, const detail::expression& b) +{ + typedef typename detail::expression::result_type result_type; + using default_ops::eval_eq; + result_type t(b); + if(detail::is_unordered_comparison(a, t)) return true; + return !eval_eq(t.backend(), result_type::canonical_value(a)); +} +template +inline typename enable_if_c::result_type, Arithmetic>::value, bool>::type + operator != (const detail::expression& a, const Arithmetic& b) +{ + typedef typename detail::expression::result_type result_type; + using default_ops::eval_eq; + result_type t(a); + if(detail::is_unordered_comparison(t, b)) return true; + return !eval_eq(t.backend(), result_type::canonical_value(b)); +} +template +inline typename enable_if::result_type, typename detail::expression::result_type>, bool>::type + operator != (const detail::expression& a, const detail::expression& b) +{ + using default_ops::eval_eq; + typename detail::expression::result_type t(a); + typename detail::expression::result_type t2(b); + if(detail::is_unordered_comparison(t, t2)) return true; + return !eval_eq(t.backend(), t2.backend()); +} + +template +inline bool operator < (const number& a, const number& b) +{ + using default_ops::eval_lt; + if(detail::is_unordered_comparison(a, b)) return false; + return eval_lt(a.backend(), b.backend()); +} +template +inline typename enable_if_c, Arithmetic>::value, bool>::type + operator < (const number& a, const Arithmetic& b) +{ + using default_ops::eval_lt; + if(detail::is_unordered_comparison(a, b)) return false; + return eval_lt(a.backend(), number::canonical_value(b)); +} +template +inline typename enable_if_c, Arithmetic>::value, bool>::type + operator < (const Arithmetic& a, const number& b) +{ + using default_ops::eval_gt; + if(detail::is_unordered_comparison(a, b)) return false; + return eval_gt(b.backend(), number::canonical_value(a)); +} +template +inline typename enable_if_c::result_type, Arithmetic>::value, bool>::type + operator < (const Arithmetic& a, const detail::expression& b) +{ + typedef typename detail::expression::result_type result_type; + using default_ops::eval_gt; + result_type t(b); + if(detail::is_unordered_comparison(a, t)) return false; + return eval_gt(t.backend(), result_type::canonical_value(a)); +} +template +inline typename enable_if_c::result_type, Arithmetic>::value, bool>::type + operator < (const detail::expression& a, const Arithmetic& b) +{ + typedef typename detail::expression::result_type result_type; + using default_ops::eval_lt; + result_type t(a); + if(detail::is_unordered_comparison(t, b)) return false; + return eval_lt(t.backend(), result_type::canonical_value(b)); +} +template +inline typename enable_if::result_type, typename detail::expression::result_type>, bool>::type + operator < (const detail::expression& a, const detail::expression& b) +{ + using default_ops::eval_lt; + typename detail::expression::result_type t(a); + typename detail::expression::result_type t2(b); + if(detail::is_unordered_comparison(t, t2)) return false; + return eval_lt(t.backend(), t2.backend()); +} + +template +inline bool operator > (const number& a, const number& b) +{ + using default_ops::eval_gt; + if(detail::is_unordered_comparison(a, b)) return false; + return eval_gt(a.backend(), b.backend()); +} +template +inline typename enable_if_c, Arithmetic>::value, bool>::type + operator > (const number& a, const Arithmetic& b) +{ + using default_ops::eval_gt; + if(detail::is_unordered_comparison(a, b)) return false; + return eval_gt(a.backend(), number::canonical_value(b)); +} +template +inline typename enable_if_c, Arithmetic>::value, bool>::type + operator > (const Arithmetic& a, const number& b) +{ + using default_ops::eval_lt; + if(detail::is_unordered_comparison(a, b)) return false; + return eval_lt(b.backend(), number::canonical_value(a)); +} +template +inline typename enable_if_c::result_type, Arithmetic>::value, bool>::type + operator > (const Arithmetic& a, const detail::expression& b) +{ + typedef typename detail::expression::result_type result_type; + using default_ops::eval_lt; + result_type t(b); + if(detail::is_unordered_comparison(a, t)) return false; + return a > t; +} +template +inline typename enable_if_c::result_type, Arithmetic>::value, bool>::type + operator > (const detail::expression& a, const Arithmetic& b) +{ + typedef typename detail::expression::result_type result_type; + using default_ops::eval_gt; + result_type t(a); + if(detail::is_unordered_comparison(t, b)) return false; + return t > b; +} +template +inline typename enable_if::result_type, typename detail::expression::result_type>, bool>::type + operator > (const detail::expression& a, const detail::expression& b) +{ + using default_ops::eval_gt; + typename detail::expression::result_type t(a); + typename detail::expression::result_type t2(b); + if(detail::is_unordered_comparison(t, t2)) return false; + return t > t2; +} + +template +inline bool operator <= (const number& a, const number& b) +{ + using default_ops::eval_gt; + if(detail::is_unordered_comparison(a, b)) return false; + return !eval_gt(a.backend(), b.backend()); +} +template +inline typename enable_if_c, Arithmetic>::value, bool>::type + operator <= (const number& a, const Arithmetic& b) +{ + using default_ops::eval_gt; + if(detail::is_unordered_comparison(a, b)) return false; + return !eval_gt(a.backend(), number::canonical_value(b)); +} +template +inline typename enable_if_c, Arithmetic>::value, bool>::type + operator <= (const Arithmetic& a, const number& b) +{ + using default_ops::eval_lt; + if(detail::is_unordered_comparison(a, b)) return false; + return !eval_lt(b.backend(), number::canonical_value(a)); +} +template +inline typename enable_if_c::result_type, Arithmetic>::value, bool>::type + operator <= (const Arithmetic& a, const detail::expression& b) +{ + typedef typename detail::expression::result_type result_type; + using default_ops::eval_lt; + if(detail::is_unordered_value(a) || detail::is_unordered_value(b)) + return false; + result_type t(b); + if(detail::is_unordered_comparison(a, t)) return false; + return !eval_lt(t.backend(), result_type::canonical_value(a)); +} +template +inline typename enable_if_c::result_type, Arithmetic>::value, bool>::type + operator <= (const detail::expression& a, const Arithmetic& b) +{ + typedef typename detail::expression::result_type result_type; + using default_ops::eval_gt; + result_type t(a); + if(detail::is_unordered_comparison(t, b)) return false; + return !eval_gt(t.backend(), result_type::canonical_value(b)); +} +template +inline typename enable_if::result_type, typename detail::expression::result_type>, bool>::type + operator <= (const detail::expression& a, const detail::expression& b) +{ + using default_ops::eval_gt; + typename detail::expression::result_type t(a); + typename detail::expression::result_type t2(b); + if(detail::is_unordered_comparison(t, t2)) return false; + return !eval_gt(t.backend(), t2.backend()); +} + +template +inline bool operator >= (const number& a, const number& b) +{ + using default_ops::eval_lt; + if(detail::is_unordered_comparison(a, b)) return false; + return !eval_lt(a.backend(), b.backend()); +} +template +inline typename enable_if_c, Arithmetic>::value, bool>::type + operator >= (const number& a, const Arithmetic& b) +{ + using default_ops::eval_lt; + if(detail::is_unordered_comparison(a, b)) return false; + return !eval_lt(a.backend(), number::canonical_value(b)); +} +template +inline typename enable_if_c, Arithmetic>::value, bool>::type + operator >= (const Arithmetic& a, const number& b) +{ + using default_ops::eval_gt; + if(detail::is_unordered_comparison(a, b)) return false; + return !eval_gt(b.backend(), number::canonical_value(a)); +} +template +inline typename enable_if_c::result_type, Arithmetic>::value, bool>::type + operator >= (const Arithmetic& a, const detail::expression& b) +{ + typedef typename detail::expression::result_type result_type; + using default_ops::eval_gt; + result_type t(b); + if(detail::is_unordered_comparison(a, t)) return false; + return !eval_gt(t.backend(), result_type::canonical_value(a)); +} +template +inline typename enable_if_c::result_type, Arithmetic>::value, bool>::type + operator >= (const detail::expression& a, const Arithmetic& b) +{ + typedef typename detail::expression::result_type result_type; + using default_ops::eval_lt; + result_type t(a); + if(detail::is_unordered_comparison(t, b)) return false; + return !eval_lt(t.backend(), result_type::canonical_value(b)); +} +template +inline typename enable_if::result_type, typename detail::expression::result_type>, bool>::type + operator >= (const detail::expression& a, const detail::expression& b) +{ + using default_ops::eval_lt; + typename detail::expression::result_type t(a); + typename detail::expression::result_type t2(b); + if(detail::is_unordered_comparison(t, t2)) return false; + return !eval_lt(t.backend(), t2.backend()); +} + + +}} // namespaces + +#endif // BOOST_MP_COMPARE_HPP diff --git a/libdevcore/concurrent_queue.h b/libdevcore/concurrent_queue.h new file mode 100644 index 0000000000..eb431f9d0c --- /dev/null +++ b/libdevcore/concurrent_queue.h @@ -0,0 +1,71 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +#pragma once +#include +#include +#include +#include + + +namespace dev +{ + +/// Concurrent queue. +/// You can push and pop elements to/from the queue. Pop will block until the queue is not empty. +/// The default backend (_QueueT) is std::queue. It can be changed to any type that has +/// proper push(), pop(), empty() and front() methods. +template> +class concurrent_queue +{ +public: + template + void push(_U&& _elem) + { + { + std::lock_guard guard{x_mutex}; + m_queue.push(std::forward<_U>(_elem)); + } + m_cv.notify_one(); + } + + _T pop() + { + std::unique_lock lock{x_mutex}; + m_cv.wait(lock, [this]{ return !m_queue.empty(); }); + auto item = std::move(m_queue.front()); + m_queue.pop(); + return item; + } + + std::pair tryPop(int milliseconds) { + std::unique_lock lock{x_mutex}; + auto ret = m_cv.wait_for(lock, std::chrono::milliseconds(milliseconds), [this] { return !m_queue.empty(); }); + if (!ret) { + return std::make_pair(ret, _T()); + } + auto item = std::move(m_queue.front()); + m_queue.pop(); + return std::make_pair(ret, item); + } + +private: + _QueueT m_queue; + std::mutex x_mutex; + std::condition_variable m_cv; +}; + +} diff --git a/libdevcore/db.h b/libdevcore/db.h new file mode 100644 index 0000000000..e09ae3da69 --- /dev/null +++ b/libdevcore/db.h @@ -0,0 +1,41 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file DB.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#pragma warning(push) +#pragma warning(disable: 4100 4267) +#if ETH_ROCKSDB +#include +#include +namespace ldb = rocksdb; +#elif ETH_ODBC +#include +#include +#include +namespace ldb = leveldb; +#else +#include +#include +namespace ldb = leveldb; +#endif +#pragma warning(pop) +#define DEV_LDB 1 diff --git a/libdevcore/debugbreak.h b/libdevcore/debugbreak.h new file mode 100644 index 0000000000..bc84930ce8 --- /dev/null +++ b/libdevcore/debugbreak.h @@ -0,0 +1,125 @@ +/* Copyright (c) 2013, Scott Tsai + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef DEBUG_BREAK_H +#define DEBUG_BREAK_H + +#if defined(_MSC_VER) || defined(__MINGW32__) + +#define debug_break __debugbreak + +#else + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + /* gcc optimizers consider code after __builtin_trap() dead. + * Making __builtin_trap() unsuitable for breaking into the debugger */ + DEBUG_BREAK_PREFER_BUILTIN_TRAP_TO_SIGTRAP = 0, +}; + +#if defined(__i386__) || defined(__x86_64__) +enum { HAVE_TRAP_INSTRUCTION = 1, }; +__attribute__((gnu_inline, always_inline)) +static void __inline__ trap_instruction(void) +{ + __asm__ volatile("int $0x03"); +} +#elif defined(__thumb__) +enum { HAVE_TRAP_INSTRUCTION = 1, }; +/* FIXME: handle __THUMB_INTERWORK__ */ +__attribute__((gnu_inline, always_inline)) +static void __inline__ trap_instruction(void) +{ + /* See 'arm-linux-tdep.c' in GDB source. + * Both instruction sequences below works. */ +#if 1 + /* 'eabi_linux_thumb_le_breakpoint' */ + __asm__ volatile(".inst 0xde01"); +#else + /* 'eabi_linux_thumb2_le_breakpoint' */ + __asm__ volatile(".inst.w 0xf7f0a000"); +#endif + + /* Known problem: + * After a breakpoint hit, can't stepi, step, or continue in GDB. + * 'step' stuck on the same instruction. + * + * Workaround: a new GDB command, + * 'debugbreak-step' is defined in debugbreak-gdb.py + * that does: + * (gdb) set $instruction_len = 2 + * (gdb) tbreak *($pc + $instruction_len) + * (gdb) jump *($pc + $instruction_len) + */ +} +#elif defined(__arm__) && !defined(__thumb__) +enum { HAVE_TRAP_INSTRUCTION = 1, }; +__attribute__((gnu_inline, always_inline)) +static void __inline__ trap_instruction(void) +{ + /* See 'arm-linux-tdep.c' in GDB source, + * 'eabi_linux_arm_le_breakpoint' */ + __asm__ volatile(".inst 0xe7f001f0"); + /* Has same known problem and workaround + * as Thumb mode */ +} +#else +enum { HAVE_TRAP_INSTRUCTION = 0, }; +#endif + +__attribute__((gnu_inline, always_inline)) +static void __inline__ debug_break(void) +{ + if (HAVE_TRAP_INSTRUCTION) { +#if defined(ETH_EMSCRIPTEN) + asm("debugger"); +#else + trap_instruction(); +#endif + } else if (DEBUG_BREAK_PREFER_BUILTIN_TRAP_TO_SIGTRAP) { + /* raises SIGILL on Linux x86{,-64}, to continue in gdb: + * (gdb) handle SIGILL stop nopass + * */ + __builtin_trap(); + } else { + raise(SIGTRAP); + } +} + +#ifdef __cplusplus +} +#endif + +#endif + +#endif diff --git a/libdevcore/easylog.h b/libdevcore/easylog.h new file mode 100644 index 0000000000..b1d44e4e6a --- /dev/null +++ b/libdevcore/easylog.h @@ -0,0 +1,36 @@ +#ifndef EASYLOG_H +#define EASYLOG_H + +#include "easylogging++.h" +#include +#include +using namespace std; + +enum EWarningType +{ + GasUsedWarning=0, + ConvergenceWarning=1, + OnChainTimeWarning, + PackageTimeWarning, + ChangeViewWarning, +}; + +const map WarningMap = { + {GasUsedWarning, "GasUsedWarning"}, + {ConvergenceWarning, "ConvergenceWarning"}, + {OnChainTimeWarning, "OnChainTimeWarning"}, + {PackageTimeWarning, "PackageTimeWarning"}, + {ChangeViewWarning, "ChangeViewWarning"}, +}; + +const int COnChainTimeLimit = 1000; //上链耗时超1000ms告警 +const int CGasUsedLimit = 90; //gas 超过阈值的90%告警 +const int CConvergenceLimit = 1000; //共识耗时超过1000ms告警 +const int CPackageTimeLimit = 2000; //打包耗时超过2000ms告警 + + +#define MY_CUSTOM_LOGGER(LEVEL) CLOG(LEVEL, "default", "fileLogger") +#undef LOG +#define LOG(LEVEL) CLOG(LEVEL, "default", "fileLogger") +#define LOGCOMWARNING LOG(WARNING)<<"common|" +#endif \ No newline at end of file diff --git a/libdevcore/easylogging++.cpp b/libdevcore/easylogging++.cpp new file mode 100644 index 0000000000..bb4b488d4d --- /dev/null +++ b/libdevcore/easylogging++.cpp @@ -0,0 +1,2982 @@ +// +// Bismillah ar-Rahmaan ar-Raheem +// +// Easylogging++ v9.94.2 +// Cross-platform logging library for C++ applications +// +// Copyright (c) 2017 muflihun.com +// +// This library is released under the MIT Licence. +// http://labs.muflihun.com/easyloggingpp/licence.php +// +// https://github.com/muflihun/easyloggingpp +// https://muflihun.github.io/easyloggingpp +// http://muflihun.com +// + +#include "easylogging++.h" + +#if defined(AUTO_INITIALIZE_EASYLOGGINGPP) +INITIALIZE_EASYLOGGINGPP +#endif + +namespace el { + +// el::base::utils +namespace base { +namespace utils { + +/// @brief Aborts application due with user-defined status +static void abort(int status, const std::string& reason) { + // Both status and reason params are there for debugging with tools like gdb etc + ELPP_UNUSED(status); + ELPP_UNUSED(reason); +#if defined(ELPP_COMPILER_MSVC) && defined(_M_IX86) && defined(_DEBUG) + // Ignore msvc critical error dialog - break instead (on debug mode) + _asm int 3 +#else + ::abort(); +#endif // defined(ELPP_COMPILER_MSVC) && defined(_M_IX86) && defined(_DEBUG) +} + +} // namespace utils +} // namespace base + +// el + +// LevelHelper + +const char* LevelHelper::convertToString(Level level) { + // Do not use switch over strongly typed enums because Intel C++ compilers dont support them yet. + if (level == Level::Global) return "GLOBAL"; + if (level == Level::Debug) return "DEBUG"; + if (level == Level::Info) return "INFO"; + if (level == Level::Warning) return "WARNING"; + if (level == Level::Error) return "ERROR"; + if (level == Level::Fatal) return "FATAL"; + if (level == Level::Verbose) return "VERBOSE"; + if (level == Level::Trace) return "TRACE"; + return "UNKNOWN"; +} + +struct StringToLevelItem { + const char* levelString; + Level level; +}; + +static struct StringToLevelItem stringToLevelMap[] = { + { "global", Level::Global }, + { "debug", Level::Debug }, + { "info", Level::Info }, + { "warning", Level::Warning }, + { "error", Level::Error }, + { "fatal", Level::Fatal }, + { "verbose", Level::Verbose }, + { "trace", Level::Trace } +}; + +Level LevelHelper::convertFromString(const char* levelStr) { + for (auto& item : stringToLevelMap) { + if (base::utils::Str::cStringCaseEq(levelStr, item.levelString)) { + return item.level; + } + } + return Level::Unknown; +} + +void LevelHelper::forEachLevel(base::type::EnumType* startIndex, const std::function& fn) { + base::type::EnumType lIndexMax = LevelHelper::kMaxValid; + do { + if (fn()) { + break; + } + *startIndex = static_cast(*startIndex << 1); + } while (*startIndex <= lIndexMax); +} + +// ConfigurationTypeHelper + +const char* ConfigurationTypeHelper::convertToString(ConfigurationType configurationType) { + // Do not use switch over strongly typed enums because Intel C++ compilers dont support them yet. + if (configurationType == ConfigurationType::Enabled) return "ENABLED"; + if (configurationType == ConfigurationType::Filename) return "FILENAME"; + if (configurationType == ConfigurationType::Format) return "FORMAT"; + if (configurationType == ConfigurationType::ToFile) return "TO_FILE"; + if (configurationType == ConfigurationType::ToStandardOutput) return "TO_STANDARD_OUTPUT"; + if (configurationType == ConfigurationType::SubsecondPrecision) return "SUBSECOND_PRECISION"; + if (configurationType == ConfigurationType::PerformanceTracking) return "PERFORMANCE_TRACKING"; + if (configurationType == ConfigurationType::MaxLogFileSize) return "MAX_LOG_FILE_SIZE"; + if (configurationType == ConfigurationType::LogFlushThreshold) return "LOG_FLUSH_THRESHOLD"; + return "UNKNOWN"; +} + +struct ConfigurationStringToTypeItem { + const char* configString; + ConfigurationType configType; +}; + +static struct ConfigurationStringToTypeItem configStringToTypeMap[] = { + { "enabled", ConfigurationType::Enabled }, + { "to_file", ConfigurationType::ToFile }, + { "to_standard_output", ConfigurationType::ToStandardOutput }, + { "format", ConfigurationType::Format }, + { "filename", ConfigurationType::Filename }, + { "subsecond_precision", ConfigurationType::SubsecondPrecision }, + { "milliseconds_width", ConfigurationType::MillisecondsWidth }, + { "performance_tracking", ConfigurationType::PerformanceTracking }, + { "max_log_file_size", ConfigurationType::MaxLogFileSize }, + { "log_flush_threshold", ConfigurationType::LogFlushThreshold }, +}; + +ConfigurationType ConfigurationTypeHelper::convertFromString(const char* configStr) { + for (auto& item : configStringToTypeMap) { + if (base::utils::Str::cStringCaseEq(configStr, item.configString)) { + return item.configType; + } + } + return ConfigurationType::Unknown; +} + +void ConfigurationTypeHelper::forEachConfigType(base::type::EnumType* startIndex, const std::function& fn) { + base::type::EnumType cIndexMax = ConfigurationTypeHelper::kMaxValid; + do { + if (fn()) { + break; + } + *startIndex = static_cast(*startIndex << 1); + } while (*startIndex <= cIndexMax); +} + +// Configuration + +Configuration::Configuration(const Configuration& c) : + m_level(c.m_level), + m_configurationType(c.m_configurationType), + m_value(c.m_value) { +} + +Configuration& Configuration::operator=(const Configuration& c) { + if (&c != this) { + m_level = c.m_level; + m_configurationType = c.m_configurationType; + m_value = c.m_value; + } + return *this; +} + +/// @brief Full constructor used to sets value of configuration +Configuration::Configuration(Level level, ConfigurationType configurationType, const std::string& value) : + m_level(level), + m_configurationType(configurationType), + m_value(value) { +} + +void Configuration::log(el::base::type::ostream_t& os) const { + os << LevelHelper::convertToString(m_level) + << ELPP_LITERAL(" ") << ConfigurationTypeHelper::convertToString(m_configurationType) + << ELPP_LITERAL(" = ") << m_value.c_str(); +} + +/// @brief Used to find configuration from configuration (pointers) repository. Avoid using it. +Configuration::Predicate::Predicate(Level level, ConfigurationType configurationType) : + m_level(level), + m_configurationType(configurationType) { +} + +bool Configuration::Predicate::operator()(const Configuration* conf) const { + return ((conf != nullptr) && (conf->level() == m_level) && (conf->configurationType() == m_configurationType)); +} + +// Configurations + +Configurations::Configurations(void) : + m_configurationFile(std::string()), + m_isFromFile(false) { +} + +Configurations::Configurations(const std::string& configurationFile, bool useDefaultsForRemaining, + Configurations* base) : + m_configurationFile(configurationFile), + m_isFromFile(false) { + parseFromFile(configurationFile, base); + if (useDefaultsForRemaining) { + setRemainingToDefault(); + } +} + +bool Configurations::parseFromFile(const std::string& configurationFile, Configurations* base) { + // We initial assertion with true because if we have assertion diabled, we want to pass this + // check and if assertion is enabled we will have values re-assigned any way. + bool assertionPassed = true; + ELPP_ASSERT((assertionPassed = base::utils::File::pathExists(configurationFile.c_str(), true)) == true, + "Configuration file [" << configurationFile << "] does not exist!"); + if (!assertionPassed) { + return false; + } + bool success = Parser::parseFromFile(configurationFile, this, base); + m_isFromFile = success; + return success; +} + +bool Configurations::parseFromText(const std::string& configurationsString, Configurations* base) { + bool success = Parser::parseFromText(configurationsString, this, base); + if (success) { + m_isFromFile = false; + } + return success; +} + +void Configurations::setFromBase(Configurations* base) { + if (base == nullptr || base == this) { + return; + } + base::threading::ScopedLock scopedLock(base->lock()); + for (Configuration*& conf : base->list()) { + set(conf); + } +} + +bool Configurations::hasConfiguration(ConfigurationType configurationType) { + base::type::EnumType lIndex = LevelHelper::kMinValid; + bool result = false; + LevelHelper::forEachLevel(&lIndex, [&](void) -> bool { + if (hasConfiguration(LevelHelper::castFromInt(lIndex), configurationType)) { + result = true; + } + return result; + }); + return result; +} + +bool Configurations::hasConfiguration(Level level, ConfigurationType configurationType) { + base::threading::ScopedLock scopedLock(lock()); +#if ELPP_COMPILER_INTEL + // We cant specify template types here, Intel C++ throws compilation error + // "error: type name is not allowed" + return RegistryWithPred::get(level, configurationType) != nullptr; +#else + return RegistryWithPred::get(level, configurationType) != nullptr; +#endif // ELPP_COMPILER_INTEL +} + +void Configurations::set(Level level, ConfigurationType configurationType, const std::string& value) { + base::threading::ScopedLock scopedLock(lock()); + unsafeSet(level, configurationType, value); // This is not unsafe anymore as we have locked mutex + if (level == Level::Global) { + unsafeSetGlobally(configurationType, value, false); // Again this is not unsafe either + } +} + +void Configurations::set(Configuration* conf) { + if (conf == nullptr) { + return; + } + set(conf->level(), conf->configurationType(), conf->value()); +} + +void Configurations::setToDefault(void) { + setGlobally(ConfigurationType::Enabled, std::string("true"), true); +#if !defined(ELPP_NO_DEFAULT_LOG_FILE) + setGlobally(ConfigurationType::Filename, std::string(base::consts::kDefaultLogFile), true); +#else + ELPP_UNUSED(base::consts::kDefaultLogFile); +#endif // !defined(ELPP_NO_DEFAULT_LOG_FILE) +#if defined(ELPP_NO_LOG_TO_FILE) + setGlobally(ConfigurationType::ToFile, std::string("false"), true); +#else + setGlobally(ConfigurationType::ToFile, std::string("true"), true); +#endif // defined(ELPP_NO_LOG_TO_FILE) + setGlobally(ConfigurationType::ToStandardOutput, std::string("true"), true); + setGlobally(ConfigurationType::SubsecondPrecision, std::string("3"), true); + setGlobally(ConfigurationType::PerformanceTracking, std::string("true"), true); + setGlobally(ConfigurationType::MaxLogFileSize, std::string("0"), true); + setGlobally(ConfigurationType::LogFlushThreshold, std::string("0"), true); + + setGlobally(ConfigurationType::Format, std::string("%datetime %level [%logger] %msg"), true); + set(Level::Debug, ConfigurationType::Format, + std::string("%datetime %level [%logger] [%user@%host] [%func] [%loc] %msg")); + // INFO and WARNING are set to default by Level::Global + set(Level::Error, ConfigurationType::Format, std::string("%datetime %level [%logger] %msg")); + set(Level::Fatal, ConfigurationType::Format, std::string("%datetime %level [%logger] %msg")); + set(Level::Verbose, ConfigurationType::Format, std::string("%datetime %level-%vlevel [%logger] %msg")); + set(Level::Trace, ConfigurationType::Format, std::string("%datetime %level [%logger] [%func] [%loc] %msg")); +} + +void Configurations::setRemainingToDefault(void) { + base::threading::ScopedLock scopedLock(lock()); +#if defined(ELPP_NO_LOG_TO_FILE) + unsafeSetIfNotExist(Level::Global, ConfigurationType::Enabled, std::string("false")); +#else + unsafeSetIfNotExist(Level::Global, ConfigurationType::Enabled, std::string("true")); +#endif // defined(ELPP_NO_LOG_TO_FILE) +#if !defined(ELPP_NO_DEFAULT_LOG_FILE) + unsafeSetIfNotExist(Level::Global, ConfigurationType::Filename, std::string(base::consts::kDefaultLogFile)); +#endif // !defined(ELPP_NO_DEFAULT_LOG_FILE) + unsafeSetIfNotExist(Level::Global, ConfigurationType::ToStandardOutput, std::string("true")); + unsafeSetIfNotExist(Level::Global, ConfigurationType::SubsecondPrecision, std::string("3")); + unsafeSetIfNotExist(Level::Global, ConfigurationType::PerformanceTracking, std::string("true")); + unsafeSetIfNotExist(Level::Global, ConfigurationType::MaxLogFileSize, std::string("0")); + unsafeSetIfNotExist(Level::Global, ConfigurationType::Format, std::string("%datetime %level [%logger] %msg")); + unsafeSetIfNotExist(Level::Debug, ConfigurationType::Format, + std::string("%datetime %level [%logger] [%user@%host] [%func] [%loc] %msg")); + // INFO and WARNING are set to default by Level::Global + unsafeSetIfNotExist(Level::Error, ConfigurationType::Format, std::string("%datetime %level [%logger] %msg")); + unsafeSetIfNotExist(Level::Fatal, ConfigurationType::Format, std::string("%datetime %level [%logger] %msg")); + unsafeSetIfNotExist(Level::Verbose, ConfigurationType::Format, std::string("%datetime %level-%vlevel [%logger] %msg")); + unsafeSetIfNotExist(Level::Trace, ConfigurationType::Format, + std::string("%datetime %level [%logger] [%func] [%loc] %msg")); +} + +bool Configurations::Parser::parseFromFile(const std::string& configurationFile, Configurations* sender, + Configurations* base) { + sender->setFromBase(base); + std::ifstream fileStream_(configurationFile.c_str(), std::ifstream::in); + ELPP_ASSERT(fileStream_.is_open(), "Unable to open configuration file [" << configurationFile << "] for parsing."); + bool parsedSuccessfully = false; + std::string line = std::string(); + Level currLevel = Level::Unknown; + std::string currConfigStr = std::string(); + std::string currLevelStr = std::string(); + while (fileStream_.good()) { + std::getline(fileStream_, line); + parsedSuccessfully = parseLine(&line, &currConfigStr, &currLevelStr, &currLevel, sender); + ELPP_ASSERT(parsedSuccessfully, "Unable to parse configuration line: " << line); + } + return parsedSuccessfully; +} + +bool Configurations::Parser::parseFromText(const std::string& configurationsString, Configurations* sender, + Configurations* base) { + sender->setFromBase(base); + bool parsedSuccessfully = false; + std::stringstream ss(configurationsString); + std::string line = std::string(); + Level currLevel = Level::Unknown; + std::string currConfigStr = std::string(); + std::string currLevelStr = std::string(); + while (std::getline(ss, line)) { + parsedSuccessfully = parseLine(&line, &currConfigStr, &currLevelStr, &currLevel, sender); + ELPP_ASSERT(parsedSuccessfully, "Unable to parse configuration line: " << line); + } + return parsedSuccessfully; +} + +void Configurations::Parser::ignoreComments(std::string* line) { + std::size_t foundAt = 0; + std::size_t quotesStart = line->find("\""); + std::size_t quotesEnd = std::string::npos; + if (quotesStart != std::string::npos) { + quotesEnd = line->find("\"", quotesStart + 1); + while (quotesEnd != std::string::npos && line->at(quotesEnd - 1) == '\\') { + // Do not erase slash yet - we will erase it in parseLine(..) while loop + quotesEnd = line->find("\"", quotesEnd + 2); + } + } + if ((foundAt = line->find(base::consts::kConfigurationComment)) != std::string::npos) { + if (foundAt < quotesEnd) { + foundAt = line->find(base::consts::kConfigurationComment, quotesEnd + 1); + } + *line = line->substr(0, foundAt); + } +} + +bool Configurations::Parser::isLevel(const std::string& line) { + return base::utils::Str::startsWith(line, std::string(base::consts::kConfigurationLevel)); +} + +bool Configurations::Parser::isComment(const std::string& line) { + return base::utils::Str::startsWith(line, std::string(base::consts::kConfigurationComment)); +} + +bool Configurations::Parser::isConfig(const std::string& line) { + std::size_t assignment = line.find('='); + return line != "" && + ((line[0] >= 'A' && line[0] <= 'Z') || (line[0] >= 'a' && line[0] <= 'z')) && + (assignment != std::string::npos) && + (line.size() > assignment); +} + +bool Configurations::Parser::parseLine(std::string* line, std::string* currConfigStr, std::string* currLevelStr, + Level* currLevel, + Configurations* conf) { + ConfigurationType currConfig = ConfigurationType::Unknown; + std::string currValue = std::string(); + *line = base::utils::Str::trim(*line); + if (isComment(*line)) return true; + ignoreComments(line); + *line = base::utils::Str::trim(*line); + if (line->empty()) { + // Comment ignored + return true; + } + if (isLevel(*line)) { + if (line->size() <= 2) { + return true; + } + *currLevelStr = line->substr(1, line->size() - 2); + *currLevelStr = base::utils::Str::toUpper(*currLevelStr); + *currLevelStr = base::utils::Str::trim(*currLevelStr); + *currLevel = LevelHelper::convertFromString(currLevelStr->c_str()); + return true; + } + if (isConfig(*line)) { + std::size_t assignment = line->find('='); + *currConfigStr = line->substr(0, assignment); + *currConfigStr = base::utils::Str::toUpper(*currConfigStr); + *currConfigStr = base::utils::Str::trim(*currConfigStr); + currConfig = ConfigurationTypeHelper::convertFromString(currConfigStr->c_str()); + currValue = line->substr(assignment + 1); + currValue = base::utils::Str::trim(currValue); + std::size_t quotesStart = currValue.find("\"", 0); + std::size_t quotesEnd = std::string::npos; + if (quotesStart != std::string::npos) { + quotesEnd = currValue.find("\"", quotesStart + 1); + while (quotesEnd != std::string::npos && currValue.at(quotesEnd - 1) == '\\') { + currValue = currValue.erase(quotesEnd - 1, 1); + quotesEnd = currValue.find("\"", quotesEnd + 2); + } + } + if (quotesStart != std::string::npos && quotesEnd != std::string::npos) { + // Quote provided - check and strip if valid + ELPP_ASSERT((quotesStart < quotesEnd), "Configuration error - No ending quote found in [" + << currConfigStr << "]"); + ELPP_ASSERT((quotesStart + 1 != quotesEnd), "Empty configuration value for [" << currConfigStr << "]"); + if ((quotesStart != quotesEnd) && (quotesStart + 1 != quotesEnd)) { + // Explicit check in case if assertion is disabled + currValue = currValue.substr(quotesStart + 1, quotesEnd - 1); + } + } + } + ELPP_ASSERT(*currLevel != Level::Unknown, "Unrecognized severity level [" << *currLevelStr << "]"); + ELPP_ASSERT(currConfig != ConfigurationType::Unknown, "Unrecognized configuration [" << *currConfigStr << "]"); + if (*currLevel == Level::Unknown || currConfig == ConfigurationType::Unknown) { + return false; // unrecognizable level or config + } + conf->set(*currLevel, currConfig, currValue); + return true; +} + +void Configurations::unsafeSetIfNotExist(Level level, ConfigurationType configurationType, const std::string& value) { + Configuration* conf = RegistryWithPred::get(level, configurationType); + if (conf == nullptr) { + unsafeSet(level, configurationType, value); + } +} + +void Configurations::unsafeSet(Level level, ConfigurationType configurationType, const std::string& value) { + Configuration* conf = RegistryWithPred::get(level, configurationType); + if (conf == nullptr) { + registerNew(new Configuration(level, configurationType, value)); + } else { + conf->setValue(value); + } + if (level == Level::Global) { + unsafeSetGlobally(configurationType, value, false); + } +} + +void Configurations::setGlobally(ConfigurationType configurationType, const std::string& value, + bool includeGlobalLevel) { + if (includeGlobalLevel) { + set(Level::Global, configurationType, value); + } + base::type::EnumType lIndex = LevelHelper::kMinValid; + LevelHelper::forEachLevel(&lIndex, [&](void) -> bool { + set(LevelHelper::castFromInt(lIndex), configurationType, value); + return false; // Do not break lambda function yet as we need to set all levels regardless + }); +} + +void Configurations::unsafeSetGlobally(ConfigurationType configurationType, const std::string& value, + bool includeGlobalLevel) { + if (includeGlobalLevel) { + unsafeSet(Level::Global, configurationType, value); + } + base::type::EnumType lIndex = LevelHelper::kMinValid; + LevelHelper::forEachLevel(&lIndex, [&](void) -> bool { + unsafeSet(LevelHelper::castFromInt(lIndex), configurationType, value); + return false; // Do not break lambda function yet as we need to set all levels regardless + }); +} + +// LogBuilder + +void LogBuilder::convertToColoredOutput(base::type::string_t* logLine, Level level) { + if (!m_termSupportsColor) return; + const base::type::char_t* resetColor = ELPP_LITERAL("\x1b[0m"); + if (level == Level::Error || level == Level::Fatal) + *logLine = ELPP_LITERAL("\x1b[31m") + *logLine + resetColor; + else if (level == Level::Warning) + *logLine = ELPP_LITERAL("\x1b[33m") + *logLine + resetColor; + else if (level == Level::Debug) + *logLine = ELPP_LITERAL("\x1b[32m") + *logLine + resetColor; + else if (level == Level::Info) + *logLine = ELPP_LITERAL("\x1b[36m") + *logLine + resetColor; + else if (level == Level::Trace) + *logLine = ELPP_LITERAL("\x1b[35m") + *logLine + resetColor; +} + +// Logger + +Logger::Logger(const std::string& id, base::LogStreamsReferenceMap* logStreamsReference) : + m_id(id), + m_typedConfigurations(nullptr), + m_parentApplicationName(std::string()), + m_isConfigured(false), + m_logStreamsReference(logStreamsReference) { + initUnflushedCount(); +} + +Logger::Logger(const std::string& id, const Configurations& configurations, + base::LogStreamsReferenceMap* logStreamsReference) : + m_id(id), + m_typedConfigurations(nullptr), + m_parentApplicationName(std::string()), + m_isConfigured(false), + m_logStreamsReference(logStreamsReference) { + initUnflushedCount(); + configure(configurations); +} + +Logger::Logger(const Logger& logger) { + base::utils::safeDelete(m_typedConfigurations); + m_id = logger.m_id; + m_typedConfigurations = logger.m_typedConfigurations; + m_parentApplicationName = logger.m_parentApplicationName; + m_isConfigured = logger.m_isConfigured; + m_configurations = logger.m_configurations; + m_unflushedCount = logger.m_unflushedCount; + m_logStreamsReference = logger.m_logStreamsReference; +} + +Logger& Logger::operator=(const Logger& logger) { + if (&logger != this) { + base::utils::safeDelete(m_typedConfigurations); + m_id = logger.m_id; + m_typedConfigurations = logger.m_typedConfigurations; + m_parentApplicationName = logger.m_parentApplicationName; + m_isConfigured = logger.m_isConfigured; + m_configurations = logger.m_configurations; + m_unflushedCount = logger.m_unflushedCount; + m_logStreamsReference = logger.m_logStreamsReference; + } + return *this; +} + +void Logger::configure(const Configurations& configurations) { + m_isConfigured = false; // we set it to false in case if we fail + initUnflushedCount(); + if (m_typedConfigurations != nullptr) { + Configurations* c = const_cast(m_typedConfigurations->configurations()); + if (c->hasConfiguration(Level::Global, ConfigurationType::Filename)) { + // This check is definitely needed for cases like ELPP_NO_DEFAULT_LOG_FILE + flush(); + } + } + base::threading::ScopedLock scopedLock(lock()); + if (m_configurations != configurations) { + m_configurations.setFromBase(const_cast(&configurations)); + } + base::utils::safeDelete(m_typedConfigurations); + m_typedConfigurations = new base::TypedConfigurations(&m_configurations, m_logStreamsReference); + resolveLoggerFormatSpec(); + m_isConfigured = true; +} + +void Logger::reconfigure(void) { + ELPP_INTERNAL_INFO(1, "Reconfiguring logger [" << m_id << "]"); + configure(m_configurations); +} + +bool Logger::isValidId(const std::string& id) { + for (std::string::const_iterator it = id.begin(); it != id.end(); ++it) { + if (!base::utils::Str::contains(base::consts::kValidLoggerIdSymbols, *it)) { + return false; + } + } + return true; +} + +void Logger::flush(void) { + ELPP_INTERNAL_INFO(3, "Flushing logger [" << m_id << "] all levels"); + base::threading::ScopedLock scopedLock(lock()); + base::type::EnumType lIndex = LevelHelper::kMinValid; + LevelHelper::forEachLevel(&lIndex, [&](void) -> bool { + flush(LevelHelper::castFromInt(lIndex), nullptr); + return false; + }); +} + +void Logger::flush(Level level, base::type::fstream_t* fs) { + if (fs == nullptr && m_typedConfigurations->toFile(level)) { + fs = m_typedConfigurations->fileStream(level); + } + if (fs != nullptr) { + fs->flush(); + m_unflushedCount.find(level)->second = 0; + } +} + +void Logger::initUnflushedCount(void) { + m_unflushedCount.clear(); + base::type::EnumType lIndex = LevelHelper::kMinValid; + LevelHelper::forEachLevel(&lIndex, [&](void) -> bool { + m_unflushedCount.insert(std::make_pair(LevelHelper::castFromInt(lIndex), 0)); + return false; + }); +} + +void Logger::resolveLoggerFormatSpec(void) const { + base::type::EnumType lIndex = LevelHelper::kMinValid; + LevelHelper::forEachLevel(&lIndex, [&](void) -> bool { + base::LogFormat* logFormat = + const_cast(&m_typedConfigurations->logFormat(LevelHelper::castFromInt(lIndex))); + base::utils::Str::replaceFirstWithEscape(logFormat->m_format, base::consts::kLoggerIdFormatSpecifier, m_id); + return false; + }); +} + +// el::base +namespace base { + +// el::base::utils +namespace utils { + +// File + +base::type::fstream_t* File::newFileStream(const std::string& filename) { + base::type::fstream_t *fs = new base::type::fstream_t(filename.c_str(), + base::type::fstream_t::out +#if !defined(ELPP_FRESH_LOG_FILE) + | base::type::fstream_t::app +#endif + ); +#if defined(ELPP_UNICODE) + std::locale elppUnicodeLocale(""); +# if ELPP_OS_WINDOWS + std::locale elppUnicodeLocaleWindows(elppUnicodeLocale, new std::codecvt_utf8_utf16); + elppUnicodeLocale = elppUnicodeLocaleWindows; +# endif // ELPP_OS_WINDOWS + fs->imbue(elppUnicodeLocale); +#endif // defined(ELPP_UNICODE) + if (fs->is_open()) { + fs->flush(); + } else { + base::utils::safeDelete(fs); + ELPP_INTERNAL_ERROR("Bad file [" << filename << "]", true); + } + return fs; +} + +std::size_t File::getSizeOfFile(base::type::fstream_t* fs) { + if (fs == nullptr) { + return 0; + } + std::streampos currPos = fs->tellg(); + fs->seekg(0, fs->end); + std::size_t size = static_cast(fs->tellg()); + fs->seekg(currPos); + return size; +} + +bool File::pathExists(const char* path, bool considerFile) { + if (path == nullptr) { + return false; + } +#if ELPP_OS_UNIX + ELPP_UNUSED(considerFile); + struct stat st; + return (stat(path, &st) == 0); +#elif ELPP_OS_WINDOWS + DWORD fileType = GetFileAttributesA(path); + if (fileType == INVALID_FILE_ATTRIBUTES) { + return false; + } + return considerFile ? true : ((fileType & FILE_ATTRIBUTE_DIRECTORY) == 0 ? false : true); +#endif // ELPP_OS_UNIX +} + +bool File::createPath(const std::string& path) { + if (path.empty()) { + return false; + } + if (base::utils::File::pathExists(path.c_str())) { + return true; + } + int status = -1; + + char* currPath = const_cast(path.c_str()); + std::string builtPath = std::string(); +#if ELPP_OS_UNIX + if (path[0] == '/') { + builtPath = "/"; + } + currPath = STRTOK(currPath, base::consts::kFilePathSeperator, 0); +#elif ELPP_OS_WINDOWS + // Use secure functions API + char* nextTok_ = nullptr; + currPath = STRTOK(currPath, base::consts::kFilePathSeperator, &nextTok_); + ELPP_UNUSED(nextTok_); +#endif // ELPP_OS_UNIX + while (currPath != nullptr) { + builtPath.append(currPath); + builtPath.append(base::consts::kFilePathSeperator); +#if ELPP_OS_UNIX + status = mkdir(builtPath.c_str(), ELPP_LOG_PERMS); + currPath = STRTOK(nullptr, base::consts::kFilePathSeperator, 0); +#elif ELPP_OS_WINDOWS + status = _mkdir(builtPath.c_str()); + currPath = STRTOK(nullptr, base::consts::kFilePathSeperator, &nextTok_); +#endif // ELPP_OS_UNIX + } + if (status == -1) { + ELPP_INTERNAL_ERROR("Error while creating path [" << path << "]", true); + return false; + } + return true; +} + +std::string File::extractPathFromFilename(const std::string& fullPath, const char* separator) { + if ((fullPath == "") || (fullPath.find(separator) == std::string::npos)) { + return fullPath; + } + std::size_t lastSlashAt = fullPath.find_last_of(separator); + if (lastSlashAt == 0) { + return std::string(separator); + } + return fullPath.substr(0, lastSlashAt + 1); +} + +void File::buildStrippedFilename(const char* filename, char buff[], std::size_t limit) { + std::size_t sizeOfFilename = strlen(filename); + if (sizeOfFilename >= limit) { + filename += (sizeOfFilename - limit); + if (filename[0] != '.' && filename[1] != '.') { // prepend if not already + filename += 3; // 3 = '..' + STRCAT(buff, "..", limit); + } + } + STRCAT(buff, filename, limit); +} + +void File::buildBaseFilename(const std::string& fullPath, char buff[], std::size_t limit, const char* separator) { + const char *filename = fullPath.c_str(); + std::size_t lastSlashAt = fullPath.find_last_of(separator); + filename += lastSlashAt ? lastSlashAt+1 : 0; + std::size_t sizeOfFilename = strlen(filename); + if (sizeOfFilename >= limit) { + filename += (sizeOfFilename - limit); + if (filename[0] != '.' && filename[1] != '.') { // prepend if not already + filename += 3; // 3 = '..' + STRCAT(buff, "..", limit); + } + } + STRCAT(buff, filename, limit); +} + +// Str + +bool Str::wildCardMatch(const char* str, const char* pattern) { + while (*pattern) { + switch (*pattern) { + case '?': + if (!*str) + return false; + ++str; + ++pattern; + break; + case '*': + if (wildCardMatch(str, pattern + 1)) + return true; + if (*str && wildCardMatch(str + 1, pattern)) + return true; + return false; + default: + if (*str++ != *pattern++) + return false; + break; + } + } + return !*str && !*pattern; +} + +std::string& Str::ltrim(std::string& str) { + str.erase(str.begin(), std::find_if(str.begin(), str.end(), [](char c) { + return !std::isspace(c); + } )); + return str; +} + +std::string& Str::rtrim(std::string& str) { + str.erase(std::find_if(str.rbegin(), str.rend(), [](char c) { + return !std::isspace(c); + }).base(), str.end()); + return str; +} + +std::string& Str::trim(std::string& str) { + return ltrim(rtrim(str)); +} + +bool Str::startsWith(const std::string& str, const std::string& start) { + return (str.length() >= start.length()) && (str.compare(0, start.length(), start) == 0); +} + +bool Str::endsWith(const std::string& str, const std::string& end) { + return (str.length() >= end.length()) && (str.compare(str.length() - end.length(), end.length(), end) == 0); +} + +std::string& Str::replaceAll(std::string& str, char replaceWhat, char replaceWith) { + std::replace(str.begin(), str.end(), replaceWhat, replaceWith); + return str; +} + +std::string& Str::replaceAll(std::string& str, const std::string& replaceWhat, + const std::string& replaceWith) { + if (replaceWhat == replaceWith) + return str; + std::size_t foundAt = std::string::npos; + while ((foundAt = str.find(replaceWhat, foundAt + 1)) != std::string::npos) { + str.replace(foundAt, replaceWhat.length(), replaceWith); + } + return str; +} + +void Str::replaceFirstWithEscape(base::type::string_t& str, const base::type::string_t& replaceWhat, + const base::type::string_t& replaceWith) { + std::size_t foundAt = base::type::string_t::npos; + while ((foundAt = str.find(replaceWhat, foundAt + 1)) != base::type::string_t::npos) { + if (foundAt > 0 && str[foundAt - 1] == base::consts::kFormatSpecifierChar) { + str.erase(foundAt > 0 ? foundAt - 1 : 0, 1); + ++foundAt; + } else { + str.replace(foundAt, replaceWhat.length(), replaceWith); + return; + } + } +} +#if defined(ELPP_UNICODE) +void Str::replaceFirstWithEscape(base::type::string_t& str, const base::type::string_t& replaceWhat, + const std::string& replaceWith) { + replaceFirstWithEscape(str, replaceWhat, base::type::string_t(replaceWith.begin(), replaceWith.end())); +} +#endif // defined(ELPP_UNICODE) + +std::string& Str::toUpper(std::string& str) { + std::transform(str.begin(), str.end(), str.begin(), + [](char c) { + return static_cast(::toupper(c)); + }); + return str; +} + +bool Str::cStringEq(const char* s1, const char* s2) { + if (s1 == nullptr && s2 == nullptr) return true; + if (s1 == nullptr || s2 == nullptr) return false; + return strcmp(s1, s2) == 0; +} + +bool Str::cStringCaseEq(const char* s1, const char* s2) { + if (s1 == nullptr && s2 == nullptr) return true; + if (s1 == nullptr || s2 == nullptr) return false; + + // With thanks to cygwin for this code + int d = 0; + + while (true) { + const int c1 = toupper(*s1++); + const int c2 = toupper(*s2++); + + if (((d = c1 - c2) != 0) || (c2 == '\0')) { + break; + } + } + + return d == 0; +} + +bool Str::contains(const char* str, char c) { + for (; *str; ++str) { + if (*str == c) + return true; + } + return false; +} + +char* Str::convertAndAddToBuff(std::size_t n, int len, char* buf, const char* bufLim, bool zeroPadded) { + char localBuff[10] = ""; + char* p = localBuff + sizeof(localBuff) - 2; + if (n > 0) { + for (; n > 0 && p > localBuff && len > 0; n /= 10, --len) + *--p = static_cast(n % 10 + '0'); + } else { + *--p = '0'; + --len; + } + if (zeroPadded) + while (p > localBuff && len-- > 0) *--p = static_cast('0'); + return addToBuff(p, buf, bufLim); +} + +char* Str::addToBuff(const char* str, char* buf, const char* bufLim) { + while ((buf < bufLim) && ((*buf = *str++) != '\0')) + ++buf; + return buf; +} + +char* Str::clearBuff(char buff[], std::size_t lim) { + STRCPY(buff, "", lim); + ELPP_UNUSED(lim); // For *nix we dont have anything using lim in above STRCPY macro + return buff; +} + +/// @brief Converst wchar* to char* +/// NOTE: Need to free return value after use! +char* Str::wcharPtrToCharPtr(const wchar_t* line) { + std::size_t len_ = wcslen(line) + 1; + char* buff_ = static_cast(malloc(len_ + 1)); +# if ELPP_OS_UNIX || (ELPP_OS_WINDOWS && !ELPP_CRT_DBG_WARNINGS) + std::wcstombs(buff_, line, len_); +# elif ELPP_OS_WINDOWS + std::size_t convCount_ = 0; + mbstate_t mbState_; + ::memset(static_cast(&mbState_), 0, sizeof(mbState_)); + wcsrtombs_s(&convCount_, buff_, len_, &line, len_, &mbState_); +# endif // ELPP_OS_UNIX || (ELPP_OS_WINDOWS && !ELPP_CRT_DBG_WARNINGS) + return buff_; +} + +// OS + +#if ELPP_OS_WINDOWS +/// @brief Gets environment variables for Windows based OS. +/// We are not using getenv(const char*) because of CRT deprecation +/// @param varname Variable name to get environment variable value for +/// @return If variable exist the value of it otherwise nullptr +const char* OS::getWindowsEnvironmentVariable(const char* varname) { + const DWORD bufferLen = 50; + static char buffer[bufferLen]; + if (GetEnvironmentVariableA(varname, buffer, bufferLen)) { + return buffer; + } + return nullptr; +} +#endif // ELPP_OS_WINDOWS +#if ELPP_OS_ANDROID +std::string OS::getProperty(const char* prop) { + char propVal[PROP_VALUE_MAX + 1]; + int ret = __system_property_get(prop, propVal); + return ret == 0 ? std::string() : std::string(propVal); +} + +std::string OS::getDeviceName(void) { + std::stringstream ss; + std::string manufacturer = getProperty("ro.product.manufacturer"); + std::string model = getProperty("ro.product.model"); + if (manufacturer.empty() || model.empty()) { + return std::string(); + } + ss << manufacturer << "-" << model; + return ss.str(); +} +#endif // ELPP_OS_ANDROID + +const std::string OS::getBashOutput(const char* command) { +#if (ELPP_OS_UNIX && !ELPP_OS_ANDROID && !ELPP_CYGWIN) + if (command == nullptr) { + return std::string(); + } + FILE* proc = nullptr; + if ((proc = popen(command, "r")) == nullptr) { + ELPP_INTERNAL_ERROR("\nUnable to run command [" << command << "]", true); + return std::string(); + } + char hBuff[4096]; + if (fgets(hBuff, sizeof(hBuff), proc) != nullptr) { + pclose(proc); + if (hBuff[strlen(hBuff) - 1] == '\n') { + hBuff[strlen(hBuff) - 1] = '\0'; + } + return std::string(hBuff); + } + return std::string(); +#else + ELPP_UNUSED(command); + return std::string(); +#endif // (ELPP_OS_UNIX && !ELPP_OS_ANDROID && !ELPP_CYGWIN) +} + +std::string OS::getEnvironmentVariable(const char* variableName, const char* defaultVal, + const char* alternativeBashCommand) { +#if ELPP_OS_UNIX + const char* val = getenv(variableName); +#elif ELPP_OS_WINDOWS + const char* val = getWindowsEnvironmentVariable(variableName); +#endif // ELPP_OS_UNIX + if ((val == nullptr) || ((strcmp(val, "") == 0))) { +#if ELPP_OS_UNIX && defined(ELPP_FORCE_ENV_VAR_FROM_BASH) + // Try harder on unix-based systems + std::string valBash = base::utils::OS::getBashOutput(alternativeBashCommand); + if (valBash.empty()) { + return std::string(defaultVal); + } else { + return valBash; + } +#elif ELPP_OS_WINDOWS || ELPP_OS_UNIX + ELPP_UNUSED(alternativeBashCommand); + return std::string(defaultVal); +#endif // ELPP_OS_UNIX && defined(ELPP_FORCE_ENV_VAR_FROM_BASH) + } + return std::string(val); +} + +std::string OS::currentUser(void) { +#if ELPP_OS_UNIX && !ELPP_OS_ANDROID + return getEnvironmentVariable("USER", base::consts::kUnknownUser, "whoami"); +#elif ELPP_OS_WINDOWS + return getEnvironmentVariable("USERNAME", base::consts::kUnknownUser); +#elif ELPP_OS_ANDROID + ELPP_UNUSED(base::consts::kUnknownUser); + return std::string("android"); +#else + return std::string(); +#endif // ELPP_OS_UNIX && !ELPP_OS_ANDROID +} + +std::string OS::currentHost(void) { +#if ELPP_OS_UNIX && !ELPP_OS_ANDROID + return getEnvironmentVariable("HOSTNAME", base::consts::kUnknownHost, "hostname"); +#elif ELPP_OS_WINDOWS + return getEnvironmentVariable("COMPUTERNAME", base::consts::kUnknownHost); +#elif ELPP_OS_ANDROID + ELPP_UNUSED(base::consts::kUnknownHost); + return getDeviceName(); +#else + return std::string(); +#endif // ELPP_OS_UNIX && !ELPP_OS_ANDROID +} + +bool OS::termSupportsColor(void) { + std::string term = getEnvironmentVariable("TERM", ""); + return term == "xterm" || term == "xterm-color" || term == "xterm-256color" + || term == "screen" || term == "linux" || term == "cygwin" + || term == "screen-256color"; +} + +// DateTime + +void DateTime::gettimeofday(struct timeval* tv) { +#if ELPP_OS_WINDOWS + if (tv != nullptr) { +# if ELPP_COMPILER_MSVC || defined(_MSC_EXTENSIONS) + const unsigned __int64 delta_ = 11644473600000000Ui64; +# else + const unsigned __int64 delta_ = 11644473600000000ULL; +# endif // ELPP_COMPILER_MSVC || defined(_MSC_EXTENSIONS) + const double secOffSet = 0.000001; + const unsigned long usecOffSet = 1000000; + FILETIME fileTime; + GetSystemTimeAsFileTime(&fileTime); + unsigned __int64 present = 0; + present |= fileTime.dwHighDateTime; + present = present << 32; + present |= fileTime.dwLowDateTime; + present /= 10; // mic-sec + // Subtract the difference + present -= delta_; + tv->tv_sec = static_cast(present * secOffSet); + tv->tv_usec = static_cast(present % usecOffSet); + } +#else + ::gettimeofday(tv, nullptr); +#endif // ELPP_OS_WINDOWS +} + +std::string DateTime::getDateTime(const char* format, const base::SubsecondPrecision* ssPrec) { + struct timeval currTime; + gettimeofday(&currTime); + return timevalToString(currTime, format, ssPrec); +} + +std::string DateTime::timevalToString(struct timeval tval, const char* format, + const el::base::SubsecondPrecision* ssPrec) { + struct ::tm timeInfo; + buildTimeInfo(&tval, &timeInfo); + const int kBuffSize = 30; + char buff_[kBuffSize] = ""; + parseFormat(buff_, kBuffSize, format, &timeInfo, static_cast(tval.tv_usec / ssPrec->m_offset), + ssPrec); + return std::string(buff_); +} + +base::type::string_t DateTime::formatTime(unsigned long long time, base::TimestampUnit timestampUnit) { + base::type::EnumType start = static_cast(timestampUnit); + const base::type::char_t* unit = base::consts::kTimeFormats[start].unit; + for (base::type::EnumType i = start; i < base::consts::kTimeFormatsCount - 1; ++i) { + if (time <= base::consts::kTimeFormats[i].value) { + break; + } + if (base::consts::kTimeFormats[i].value == 1000.0f && time / 1000.0f < 1.9f) { + break; + } + time /= static_cast(base::consts::kTimeFormats[i].value); + unit = base::consts::kTimeFormats[i + 1].unit; + } + base::type::stringstream_t ss; + ss << time << " " << unit; + return ss.str(); +} + +unsigned long long DateTime::getTimeDifference(const struct timeval& endTime, const struct timeval& startTime, + base::TimestampUnit timestampUnit) { + if (timestampUnit == base::TimestampUnit::Microsecond) { + return static_cast(static_cast(1000000 * endTime.tv_sec + endTime.tv_usec) - + static_cast(1000000 * startTime.tv_sec + startTime.tv_usec)); + } + // milliseconds + auto conv = [](const struct timeval& tim) { + return static_cast((tim.tv_sec * 1000) + (tim.tv_usec / 1000)); + }; + return static_cast(conv(endTime) - conv(startTime)); +} + +struct ::tm* DateTime::buildTimeInfo(struct timeval* currTime, struct ::tm* timeInfo) { +#if ELPP_OS_UNIX + time_t rawTime = currTime->tv_sec; + ::elpptime_r(&rawTime, timeInfo); + return timeInfo; +#else +# if ELPP_COMPILER_MSVC + ELPP_UNUSED(currTime); + time_t t; + _time64(&t); + elpptime_s(timeInfo, &t); + return timeInfo; +# else + // For any other compilers that don't have CRT warnings issue e.g, MinGW or TDM GCC- we use different method + time_t rawTime = currTime->tv_sec; + struct tm* tmInf = elpptime(&rawTime); + *timeInfo = *tmInf; + return timeInfo; +# endif // ELPP_COMPILER_MSVC +#endif // ELPP_OS_UNIX +} + +char* DateTime::parseFormat(char* buf, std::size_t bufSz, const char* format, const struct tm* tInfo, + std::size_t msec, const base::SubsecondPrecision* ssPrec) { + const char* bufLim = buf + bufSz; + for (; *format; ++format) { + if (*format == base::consts::kFormatSpecifierChar) { + switch (*++format) { + case base::consts::kFormatSpecifierChar: // Escape + break; + case '\0': // End + --format; + break; + case 'd': // Day + buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_mday, 2, buf, bufLim); + continue; + case 'a': // Day of week (short) + buf = base::utils::Str::addToBuff(base::consts::kDaysAbbrev[tInfo->tm_wday], buf, bufLim); + continue; + case 'A': // Day of week (long) + buf = base::utils::Str::addToBuff(base::consts::kDays[tInfo->tm_wday], buf, bufLim); + continue; + case 'M': // month + buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_mon + 1, 2, buf, bufLim); + continue; + case 'b': // month (short) + buf = base::utils::Str::addToBuff(base::consts::kMonthsAbbrev[tInfo->tm_mon], buf, bufLim); + continue; + case 'B': // month (long) + buf = base::utils::Str::addToBuff(base::consts::kMonths[tInfo->tm_mon], buf, bufLim); + continue; + case 'y': // year (two digits) + buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_year + base::consts::kYearBase, 2, buf, bufLim); + continue; + case 'Y': // year (four digits) + buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_year + base::consts::kYearBase, 4, buf, bufLim); + continue; + case 'h': // hour (12-hour) + buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_hour % 12, 2, buf, bufLim); + continue; + case 'H': // hour (24-hour) + buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_hour, 2, buf, bufLim); + continue; + case 'm': // minute + buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_min, 2, buf, bufLim); + continue; + case 's': // second + buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_sec, 2, buf, bufLim); + continue; + case 'z': // subsecond part + case 'g': + buf = base::utils::Str::convertAndAddToBuff(msec, ssPrec->m_width, buf, bufLim); + continue; + case 'F': // AM/PM + buf = base::utils::Str::addToBuff((tInfo->tm_hour >= 12) ? base::consts::kPm : base::consts::kAm, buf, bufLim); + continue; + default: + continue; + } + } + if (buf == bufLim) break; + *buf++ = *format; + } + return buf; +} + +// CommandLineArgs + +void CommandLineArgs::setArgs(int argc, char** argv) { + m_params.clear(); + m_paramsWithValue.clear(); + if (argc == 0 || argv == nullptr) { + return; + } + m_argc = argc; + m_argv = argv; + for (int i = 1; i < m_argc; ++i) { + const char* v = (strstr(m_argv[i], "=")); + if (v != nullptr && strlen(v) > 0) { + std::string key = std::string(m_argv[i]); + key = key.substr(0, key.find_first_of('=')); + if (hasParamWithValue(key.c_str())) { + ELPP_INTERNAL_INFO(1, "Skipping [" << key << "] arg since it already has value [" + << getParamValue(key.c_str()) << "]"); + } else { + m_paramsWithValue.insert(std::make_pair(key, std::string(v + 1))); + } + } + if (v == nullptr) { + if (hasParam(m_argv[i])) { + ELPP_INTERNAL_INFO(1, "Skipping [" << m_argv[i] << "] arg since it already exists"); + } else { + m_params.push_back(std::string(m_argv[i])); + } + } + } +} + +bool CommandLineArgs::hasParamWithValue(const char* paramKey) const { + return m_paramsWithValue.find(std::string(paramKey)) != m_paramsWithValue.end(); +} + +const char* CommandLineArgs::getParamValue(const char* paramKey) const { + return m_paramsWithValue.find(std::string(paramKey))->second.c_str(); +} + +bool CommandLineArgs::hasParam(const char* paramKey) const { + return std::find(m_params.begin(), m_params.end(), std::string(paramKey)) != m_params.end(); +} + +bool CommandLineArgs::empty(void) const { + return m_params.empty() && m_paramsWithValue.empty(); +} + +std::size_t CommandLineArgs::size(void) const { + return m_params.size() + m_paramsWithValue.size(); +} + +base::type::ostream_t& operator<<(base::type::ostream_t& os, const CommandLineArgs& c) { + for (int i = 1; i < c.m_argc; ++i) { + os << ELPP_LITERAL("[") << c.m_argv[i] << ELPP_LITERAL("]"); + if (i < c.m_argc - 1) { + os << ELPP_LITERAL(" "); + } + } + return os; +} + +} // namespace utils + +// el::base::threading +namespace threading { + +#if ELPP_THREADING_ENABLED +# if ELPP_USE_STD_THREADING +# if ELPP_ASYNC_LOGGING +static void msleep(int ms) { + // Only when async logging enabled - this is because async is strict on compiler +# if defined(ELPP_NO_SLEEP_FOR) + usleep(ms * 1000); +# else + std::this_thread::sleep_for(std::chrono::milliseconds(ms)); +# endif // defined(ELPP_NO_SLEEP_FOR) +} +# endif // ELPP_ASYNC_LOGGING +# endif // !ELPP_USE_STD_THREADING +#endif // ELPP_THREADING_ENABLED + +} // namespace threading + +// el::base + +// SubsecondPrecision + +void SubsecondPrecision::init(int width) { + if (width < 1 || width > 6) { + width = base::consts::kDefaultSubsecondPrecision; + } + m_width = width; + switch (m_width) { + case 3: + m_offset = 1000; + break; + case 4: + m_offset = 100; + break; + case 5: + m_offset = 10; + break; + case 6: + m_offset = 1; + break; + default: + m_offset = 1000; + break; + } +} + +// LogFormat + +LogFormat::LogFormat(void) : + m_level(Level::Unknown), + m_userFormat(base::type::string_t()), + m_format(base::type::string_t()), + m_dateTimeFormat(std::string()), + m_flags(0x0), + m_currentUser(base::utils::OS::currentUser()), + m_currentHost(base::utils::OS::currentHost()) { +} + +LogFormat::LogFormat(Level level, const base::type::string_t& format) + : m_level(level), m_userFormat(format), m_currentUser(base::utils::OS::currentUser()), + m_currentHost(base::utils::OS::currentHost()) { + parseFromFormat(m_userFormat); +} + +LogFormat::LogFormat(const LogFormat& logFormat): + m_level(logFormat.m_level), + m_userFormat(logFormat.m_userFormat), + m_format(logFormat.m_format), + m_dateTimeFormat(logFormat.m_dateTimeFormat), + m_flags(logFormat.m_flags), + m_currentUser(logFormat.m_currentUser), + m_currentHost(logFormat.m_currentHost) { +} + +LogFormat::LogFormat(LogFormat&& logFormat) { + m_level = std::move(logFormat.m_level); + m_userFormat = std::move(logFormat.m_userFormat); + m_format = std::move(logFormat.m_format); + m_dateTimeFormat = std::move(logFormat.m_dateTimeFormat); + m_flags = std::move(logFormat.m_flags); + m_currentUser = std::move(logFormat.m_currentUser); + m_currentHost = std::move(logFormat.m_currentHost); +} + +LogFormat& LogFormat::operator=(const LogFormat& logFormat) { + if (&logFormat != this) { + m_level = logFormat.m_level; + m_userFormat = logFormat.m_userFormat; + m_dateTimeFormat = logFormat.m_dateTimeFormat; + m_flags = logFormat.m_flags; + m_currentUser = logFormat.m_currentUser; + m_currentHost = logFormat.m_currentHost; + } + return *this; +} + +bool LogFormat::operator==(const LogFormat& other) { + return m_level == other.m_level && m_userFormat == other.m_userFormat && m_format == other.m_format && + m_dateTimeFormat == other.m_dateTimeFormat && m_flags == other.m_flags; +} + +/// @brief Updates format to be used while logging. +/// @param userFormat User provided format +void LogFormat::parseFromFormat(const base::type::string_t& userFormat) { + // We make copy because we will be changing the format + // i.e, removing user provided date format from original format + // and then storing it. + base::type::string_t formatCopy = userFormat; + m_flags = 0x0; + auto conditionalAddFlag = [&](const base::type::char_t* specifier, base::FormatFlags flag) { + std::size_t foundAt = base::type::string_t::npos; + while ((foundAt = formatCopy.find(specifier, foundAt + 1)) != base::type::string_t::npos) { + if (foundAt > 0 && formatCopy[foundAt - 1] == base::consts::kFormatSpecifierChar) { + if (hasFlag(flag)) { + // If we already have flag we remove the escape chars so that '%%' is turned to '%' + // even after specifier resolution - this is because we only replaceFirst specifier + formatCopy.erase(foundAt > 0 ? foundAt - 1 : 0, 1); + ++foundAt; + } + } else { + if (!hasFlag(flag)) addFlag(flag); + } + } + }; + conditionalAddFlag(base::consts::kAppNameFormatSpecifier, base::FormatFlags::AppName); + conditionalAddFlag(base::consts::kSeverityLevelFormatSpecifier, base::FormatFlags::Level); + conditionalAddFlag(base::consts::kSeverityLevelShortFormatSpecifier, base::FormatFlags::LevelShort); + conditionalAddFlag(base::consts::kLoggerIdFormatSpecifier, base::FormatFlags::LoggerId); + conditionalAddFlag(base::consts::kThreadIdFormatSpecifier, base::FormatFlags::ThreadId); + conditionalAddFlag(base::consts::kLogFileFormatSpecifier, base::FormatFlags::File); + conditionalAddFlag(base::consts::kLogFileBaseFormatSpecifier, base::FormatFlags::FileBase); + conditionalAddFlag(base::consts::kLogLineFormatSpecifier, base::FormatFlags::Line); + conditionalAddFlag(base::consts::kLogLocationFormatSpecifier, base::FormatFlags::Location); + conditionalAddFlag(base::consts::kLogFunctionFormatSpecifier, base::FormatFlags::Function); + conditionalAddFlag(base::consts::kCurrentUserFormatSpecifier, base::FormatFlags::User); + conditionalAddFlag(base::consts::kCurrentHostFormatSpecifier, base::FormatFlags::Host); + conditionalAddFlag(base::consts::kMessageFormatSpecifier, base::FormatFlags::LogMessage); + conditionalAddFlag(base::consts::kVerboseLevelFormatSpecifier, base::FormatFlags::VerboseLevel); + // For date/time we need to extract user's date format first + std::size_t dateIndex = std::string::npos; + if ((dateIndex = formatCopy.find(base::consts::kDateTimeFormatSpecifier)) != std::string::npos) { + while (dateIndex > 0 && formatCopy[dateIndex - 1] == base::consts::kFormatSpecifierChar) { + dateIndex = formatCopy.find(base::consts::kDateTimeFormatSpecifier, dateIndex + 1); + } + if (dateIndex != std::string::npos) { + addFlag(base::FormatFlags::DateTime); + updateDateFormat(dateIndex, formatCopy); + } + } + m_format = formatCopy; + updateFormatSpec(); +} + +void LogFormat::updateDateFormat(std::size_t index, base::type::string_t& currFormat) { + if (hasFlag(base::FormatFlags::DateTime)) { + index += ELPP_STRLEN(base::consts::kDateTimeFormatSpecifier); + } + const base::type::char_t* ptr = currFormat.c_str() + index; + if ((currFormat.size() > index) && (ptr[0] == '{')) { + // User has provided format for date/time + ++ptr; + int count = 1; // Start by 1 in order to remove starting brace + std::stringstream ss; + for (; *ptr; ++ptr, ++count) { + if (*ptr == '}') { + ++count; // In order to remove ending brace + break; + } + ss << static_cast(*ptr); + } + currFormat.erase(index, count); + m_dateTimeFormat = ss.str(); + } else { + // No format provided, use default + if (hasFlag(base::FormatFlags::DateTime)) { + m_dateTimeFormat = std::string(base::consts::kDefaultDateTimeFormat); + } + } +} + +void LogFormat::updateFormatSpec(void) { + // Do not use switch over strongly typed enums because Intel C++ compilers dont support them yet. + if (m_level == Level::Debug) { + base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelFormatSpecifier, + base::consts::kDebugLevelLogValue); + base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelShortFormatSpecifier, + base::consts::kDebugLevelShortLogValue); + } else if (m_level == Level::Info) { + base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelFormatSpecifier, + base::consts::kInfoLevelLogValue); + base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelShortFormatSpecifier, + base::consts::kInfoLevelShortLogValue); + } else if (m_level == Level::Warning) { + base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelFormatSpecifier, + base::consts::kWarningLevelLogValue); + base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelShortFormatSpecifier, + base::consts::kWarningLevelShortLogValue); + } else if (m_level == Level::Error) { + base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelFormatSpecifier, + base::consts::kErrorLevelLogValue); + base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelShortFormatSpecifier, + base::consts::kErrorLevelShortLogValue); + } else if (m_level == Level::Fatal) { + base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelFormatSpecifier, + base::consts::kFatalLevelLogValue); + base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelShortFormatSpecifier, + base::consts::kFatalLevelShortLogValue); + } else if (m_level == Level::Verbose) { + base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelFormatSpecifier, + base::consts::kVerboseLevelLogValue); + base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelShortFormatSpecifier, + base::consts::kVerboseLevelShortLogValue); + } else if (m_level == Level::Trace) { + base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelFormatSpecifier, + base::consts::kTraceLevelLogValue); + base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelShortFormatSpecifier, + base::consts::kTraceLevelShortLogValue); + } + if (hasFlag(base::FormatFlags::User)) { + base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kCurrentUserFormatSpecifier, + m_currentUser); + } + if (hasFlag(base::FormatFlags::Host)) { + base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kCurrentHostFormatSpecifier, + m_currentHost); + } + // Ignore Level::Global and Level::Unknown +} + +// TypedConfigurations + +TypedConfigurations::TypedConfigurations(Configurations* configurations, + base::LogStreamsReferenceMap* logStreamsReference) { + m_configurations = configurations; + m_logStreamsReference = logStreamsReference; + build(m_configurations); +} + +TypedConfigurations::TypedConfigurations(const TypedConfigurations& other) { + this->m_configurations = other.m_configurations; + this->m_logStreamsReference = other.m_logStreamsReference; + build(m_configurations); +} + +bool TypedConfigurations::enabled(Level level) { + return getConfigByVal(level, &m_enabledMap, "enabled"); +} + +bool TypedConfigurations::toFile(Level level) { + return getConfigByVal(level, &m_toFileMap, "toFile"); +} + +const std::string& TypedConfigurations::filename(Level level) { + return getConfigByRef(level, &m_filenameMap, "filename"); +} + +bool TypedConfigurations::toStandardOutput(Level level) { + return getConfigByVal(level, &m_toStandardOutputMap, "toStandardOutput"); +} + +const base::LogFormat& TypedConfigurations::logFormat(Level level) { + return getConfigByRef(level, &m_logFormatMap, "logFormat"); +} + +const base::SubsecondPrecision& TypedConfigurations::subsecondPrecision(Level level) { + return getConfigByRef(level, &m_subsecondPrecisionMap, "subsecondPrecision"); +} + +const base::MillisecondsWidth& TypedConfigurations::millisecondsWidth(Level level) { + return getConfigByRef(level, &m_subsecondPrecisionMap, "millisecondsWidth"); +} + +bool TypedConfigurations::performanceTracking(Level level) { + return getConfigByVal(level, &m_performanceTrackingMap, "performanceTracking"); +} + +base::type::fstream_t* TypedConfigurations::fileStream(Level level) { + return getConfigByRef(level, &m_fileStreamMap, "fileStream").get(); +} + +std::size_t TypedConfigurations::maxLogFileSize(Level level) { + return getConfigByVal(level, &m_maxLogFileSizeMap, "maxLogFileSize"); +} + +std::size_t TypedConfigurations::logFlushThreshold(Level level) { + return getConfigByVal(level, &m_logFlushThresholdMap, "logFlushThreshold"); +} + +void TypedConfigurations::build(Configurations* configurations) { + base::threading::ScopedLock scopedLock(lock()); + auto getBool = [] (std::string boolStr) -> bool { // Pass by value for trimming + base::utils::Str::trim(boolStr); + return (boolStr == "TRUE" || boolStr == "true" || boolStr == "1"); + }; + std::vector withFileSizeLimit; + for (Configurations::const_iterator it = configurations->begin(); it != configurations->end(); ++it) { + Configuration* conf = *it; + // We cannot use switch on strong enums because Intel C++ dont support them yet + if (conf->configurationType() == ConfigurationType::Enabled) { + setValue(conf->level(), getBool(conf->value()), &m_enabledMap); + } else if (conf->configurationType() == ConfigurationType::ToFile) { + setValue(conf->level(), getBool(conf->value()), &m_toFileMap); + } else if (conf->configurationType() == ConfigurationType::ToStandardOutput) { + setValue(conf->level(), getBool(conf->value()), &m_toStandardOutputMap); + } else if (conf->configurationType() == ConfigurationType::Filename) { + // We do not yet configure filename but we will configure in another + // loop. This is because if file cannot be created, we will force ToFile + // to be false. Because configuring logger is not necessarily performance + // sensative operation, we can live with another loop; (by the way this loop + // is not very heavy either) + } else if (conf->configurationType() == ConfigurationType::Format) { + setValue(conf->level(), base::LogFormat(conf->level(), + base::type::string_t(conf->value().begin(), conf->value().end())), &m_logFormatMap); + } else if (conf->configurationType() == ConfigurationType::SubsecondPrecision) { + setValue(Level::Global, + base::SubsecondPrecision(static_cast(getULong(conf->value()))), &m_subsecondPrecisionMap); + } else if (conf->configurationType() == ConfigurationType::PerformanceTracking) { + setValue(Level::Global, getBool(conf->value()), &m_performanceTrackingMap); + } else if (conf->configurationType() == ConfigurationType::MaxLogFileSize) { + setValue(conf->level(), static_cast(getULong(conf->value())), &m_maxLogFileSizeMap); +#if !defined(ELPP_NO_DEFAULT_LOG_FILE) + withFileSizeLimit.push_back(conf); +#endif // !defined(ELPP_NO_DEFAULT_LOG_FILE) + } else if (conf->configurationType() == ConfigurationType::LogFlushThreshold) { + setValue(conf->level(), static_cast(getULong(conf->value())), &m_logFlushThresholdMap); + } + } + // As mentioned earlier, we will now set filename configuration in separate loop to deal with non-existent files + for (Configurations::const_iterator it = configurations->begin(); it != configurations->end(); ++it) { + Configuration* conf = *it; + if (conf->configurationType() == ConfigurationType::Filename) { + insertFile(conf->level(), conf->value()); + } + } + for (std::vector::iterator conf = withFileSizeLimit.begin(); + conf != withFileSizeLimit.end(); ++conf) { + // This is not unsafe as mutex is locked in currect scope + unsafeValidateFileRolling((*conf)->level(), base::defaultPreRollOutCallback); + } +} + +unsigned long TypedConfigurations::getULong(std::string confVal) { + bool valid = true; + base::utils::Str::trim(confVal); + valid = !confVal.empty() && std::find_if(confVal.begin(), confVal.end(), + [](char c) { + return !base::utils::Str::isDigit(c); + }) == confVal.end(); + if (!valid) { + valid = false; + ELPP_ASSERT(valid, "Configuration value not a valid integer [" << confVal << "]"); + return 0; + } + return atol(confVal.c_str()); +} + +std::string TypedConfigurations::resolveFilename(const std::string& filename) { + std::string resultingFilename = filename; + std::size_t dateIndex = std::string::npos; + std::string dateTimeFormatSpecifierStr = std::string(base::consts::kDateTimeFormatSpecifierForFilename); + if ((dateIndex = resultingFilename.find(dateTimeFormatSpecifierStr.c_str())) != std::string::npos) { + while (dateIndex > 0 && resultingFilename[dateIndex - 1] == base::consts::kFormatSpecifierChar) { + dateIndex = resultingFilename.find(dateTimeFormatSpecifierStr.c_str(), dateIndex + 1); + } + if (dateIndex != std::string::npos) { + const char* ptr = resultingFilename.c_str() + dateIndex; + // Goto end of specifier + ptr += dateTimeFormatSpecifierStr.size(); + std::string fmt; + if ((resultingFilename.size() > dateIndex) && (ptr[0] == '{')) { + // User has provided format for date/time + ++ptr; + int count = 1; // Start by 1 in order to remove starting brace + std::stringstream ss; + for (; *ptr; ++ptr, ++count) { + if (*ptr == '}') { + ++count; // In order to remove ending brace + break; + } + ss << *ptr; + } + resultingFilename.erase(dateIndex + dateTimeFormatSpecifierStr.size(), count); + fmt = ss.str(); + } else { + fmt = std::string(base::consts::kDefaultDateTimeFormatInFilename); + } + base::SubsecondPrecision ssPrec(3); + std::string now = base::utils::DateTime::getDateTime(fmt.c_str(), &ssPrec); + base::utils::Str::replaceAll(now, '/', '-'); // Replace path element since we are dealing with filename + base::utils::Str::replaceAll(resultingFilename, dateTimeFormatSpecifierStr, now); + } + } + return resultingFilename; +} + +void TypedConfigurations::insertFile(Level level, const std::string& fullFilename) { +#if defined(ELPP_NO_LOG_TO_FILE) + setValue(level, false, &m_toFileMap); + ELPP_UNUSED(fullFilename); + m_fileStreamMap.insert(std::make_pair(level, base::FileStreamPtr(nullptr))); + return; +#endif + std::string resolvedFilename = resolveFilename(fullFilename); + if (resolvedFilename.empty()) { + std::cerr << "Could not load empty file for logging, please re-check your configurations for level [" + << LevelHelper::convertToString(level) << "]"; + } + std::string filePath = base::utils::File::extractPathFromFilename(resolvedFilename, base::consts::kFilePathSeperator); + if (filePath.size() < resolvedFilename.size()) { + base::utils::File::createPath(filePath); + } + auto create = [&](Level level) { + base::LogStreamsReferenceMap::iterator filestreamIter = m_logStreamsReference->find(resolvedFilename); + base::type::fstream_t* fs = nullptr; + if (filestreamIter == m_logStreamsReference->end()) { + // We need a completely new stream, nothing to share with + fs = base::utils::File::newFileStream(resolvedFilename); + m_filenameMap.insert(std::make_pair(level, resolvedFilename)); + m_fileStreamMap.insert(std::make_pair(level, base::FileStreamPtr(fs))); + m_logStreamsReference->insert(std::make_pair(resolvedFilename, base::FileStreamPtr(m_fileStreamMap.at(level)))); + } else { + // Woops! we have an existing one, share it! + m_filenameMap.insert(std::make_pair(level, filestreamIter->first)); + m_fileStreamMap.insert(std::make_pair(level, base::FileStreamPtr(filestreamIter->second))); + fs = filestreamIter->second.get(); + } + if (fs == nullptr) { + // We display bad file error from newFileStream() + ELPP_INTERNAL_ERROR("Setting [TO_FILE] of [" + << LevelHelper::convertToString(level) << "] to FALSE", false); + setValue(level, false, &m_toFileMap); + } + }; + // If we dont have file conf for any level, create it for Level::Global first + // otherwise create for specified level + create(m_filenameMap.empty() && m_fileStreamMap.empty() ? Level::Global : level); +} + +bool TypedConfigurations::unsafeValidateFileRolling(Level level, const PreRollOutCallback& preRollOutCallback) { + base::type::fstream_t* fs = unsafeGetConfigByRef(level, &m_fileStreamMap, "fileStream").get(); + if (fs == nullptr) { + return true; + } + std::size_t maxLogFileSize = unsafeGetConfigByVal(level, &m_maxLogFileSizeMap, "maxLogFileSize"); + std::size_t currFileSize = base::utils::File::getSizeOfFile(fs); + if (maxLogFileSize != 0 && currFileSize >= maxLogFileSize) { + std::string fname = unsafeGetConfigByRef(level, &m_filenameMap, "filename"); + ELPP_INTERNAL_INFO(1, "Truncating log file [" << fname << "] as a result of configurations for level [" + << LevelHelper::convertToString(level) << "]"); + fs->close(); + preRollOutCallback(fname.c_str(), currFileSize); + fs->open(fname, std::fstream::out | std::fstream::trunc); + return true; + } + return false; +} + +// RegisteredHitCounters + +bool RegisteredHitCounters::validateEveryN(const char* filename, base::type::LineNumber lineNumber, std::size_t n) { + base::threading::ScopedLock scopedLock(lock()); + base::HitCounter* counter = get(filename, lineNumber); + if (counter == nullptr) { + registerNew(counter = new base::HitCounter(filename, lineNumber)); + } + counter->validateHitCounts(n); + bool result = (n >= 1 && counter->hitCounts() != 0 && counter->hitCounts() % n == 0); + return result; +} + +/// @brief Validates counter for hits >= N, i.e, registers new if does not exist otherwise updates original one +/// @return True if validation resulted in triggering hit. Meaning logs should be written everytime true is returned +bool RegisteredHitCounters::validateAfterN(const char* filename, base::type::LineNumber lineNumber, std::size_t n) { + base::threading::ScopedLock scopedLock(lock()); + base::HitCounter* counter = get(filename, lineNumber); + if (counter == nullptr) { + registerNew(counter = new base::HitCounter(filename, lineNumber)); + } + // Do not use validateHitCounts here since we do not want to reset counter here + // Note the >= instead of > because we are incrementing + // after this check + if (counter->hitCounts() >= n) + return true; + counter->increment(); + return false; +} + +/// @brief Validates counter for hits are <= n, i.e, registers new if does not exist otherwise updates original one +/// @return True if validation resulted in triggering hit. Meaning logs should be written everytime true is returned +bool RegisteredHitCounters::validateNTimes(const char* filename, base::type::LineNumber lineNumber, std::size_t n) { + base::threading::ScopedLock scopedLock(lock()); + base::HitCounter* counter = get(filename, lineNumber); + if (counter == nullptr) { + registerNew(counter = new base::HitCounter(filename, lineNumber)); + } + counter->increment(); + // Do not use validateHitCounts here since we do not want to reset counter here + if (counter->hitCounts() <= n) + return true; + return false; +} + +// RegisteredLoggers + +RegisteredLoggers::RegisteredLoggers(const LogBuilderPtr& defaultLogBuilder) : + m_defaultLogBuilder(defaultLogBuilder) { + m_defaultConfigurations.setToDefault(); +} + +Logger* RegisteredLoggers::get(const std::string& id, bool forceCreation) { + base::threading::ScopedLock scopedLock(lock()); + Logger* logger_ = base::utils::Registry::get(id); + if (logger_ == nullptr && forceCreation) { + bool validId = Logger::isValidId(id); + if (!validId) { + ELPP_ASSERT(validId, "Invalid logger ID [" << id << "]. Not registering this logger."); + return nullptr; + } + logger_ = new Logger(id, m_defaultConfigurations, &m_logStreamsReference); + logger_->m_logBuilder = m_defaultLogBuilder; + registerNew(id, logger_); + LoggerRegistrationCallback* callback = nullptr; + for (const std::pair& h + : m_loggerRegistrationCallbacks) { + callback = h.second.get(); + if (callback != nullptr && callback->enabled()) { + callback->handle(logger_); + } + } + } + return logger_; +} + +bool RegisteredLoggers::remove(const std::string& id) { + if (id == base::consts::kDefaultLoggerId) { + return false; + } + Logger* logger = base::utils::Registry::get(id); + if (logger != nullptr) { + unregister(logger); + } + return true; +} + +void RegisteredLoggers::unsafeFlushAll(void) { + ELPP_INTERNAL_INFO(1, "Flushing all log files"); + for (base::LogStreamsReferenceMap::iterator it = m_logStreamsReference.begin(); + it != m_logStreamsReference.end(); ++it) { + if (it->second.get() == nullptr) continue; + it->second->flush(); + } +} + +// VRegistry + +VRegistry::VRegistry(base::type::VerboseLevel level, base::type::EnumType* pFlags) : m_level(level), m_pFlags(pFlags) { +} + +/// @brief Sets verbose level. Accepted range is 0-9 +void VRegistry::setLevel(base::type::VerboseLevel level) { + base::threading::ScopedLock scopedLock(lock()); + if (level > 9) + m_level = base::consts::kMaxVerboseLevel; + else + m_level = level; +} + +void VRegistry::setModules(const char* modules) { + base::threading::ScopedLock scopedLock(lock()); + auto addSuffix = [](std::stringstream& ss, const char* sfx, const char* prev) { + if (prev != nullptr && base::utils::Str::endsWith(ss.str(), std::string(prev))) { + std::string chr(ss.str().substr(0, ss.str().size() - strlen(prev))); + ss.str(std::string("")); + ss << chr; + } + if (base::utils::Str::endsWith(ss.str(), std::string(sfx))) { + std::string chr(ss.str().substr(0, ss.str().size() - strlen(sfx))); + ss.str(std::string("")); + ss << chr; + } + ss << sfx; + }; + auto insert = [&](std::stringstream& ss, base::type::VerboseLevel level) { + if (!base::utils::hasFlag(LoggingFlag::DisableVModulesExtensions, *m_pFlags)) { + addSuffix(ss, ".h", nullptr); + m_modules.insert(std::make_pair(ss.str(), level)); + addSuffix(ss, ".c", ".h"); + m_modules.insert(std::make_pair(ss.str(), level)); + addSuffix(ss, ".cpp", ".c"); + m_modules.insert(std::make_pair(ss.str(), level)); + addSuffix(ss, ".cc", ".cpp"); + m_modules.insert(std::make_pair(ss.str(), level)); + addSuffix(ss, ".cxx", ".cc"); + m_modules.insert(std::make_pair(ss.str(), level)); + addSuffix(ss, ".-inl.h", ".cxx"); + m_modules.insert(std::make_pair(ss.str(), level)); + addSuffix(ss, ".hxx", ".-inl.h"); + m_modules.insert(std::make_pair(ss.str(), level)); + addSuffix(ss, ".hpp", ".hxx"); + m_modules.insert(std::make_pair(ss.str(), level)); + addSuffix(ss, ".hh", ".hpp"); + } + m_modules.insert(std::make_pair(ss.str(), level)); + }; + bool isMod = true; + bool isLevel = false; + std::stringstream ss; + int level = -1; + for (; *modules; ++modules) { + switch (*modules) { + case '=': + isLevel = true; + isMod = false; + break; + case ',': + isLevel = false; + isMod = true; + if (!ss.str().empty() && level != -1) { + insert(ss, static_cast(level)); + ss.str(std::string("")); + level = -1; + } + break; + default: + if (isMod) { + ss << *modules; + } else if (isLevel) { + if (isdigit(*modules)) { + level = static_cast(*modules) - 48; + } + } + break; + } + } + if (!ss.str().empty() && level != -1) { + insert(ss, static_cast(level)); + } +} + +bool VRegistry::allowed(base::type::VerboseLevel vlevel, const char* file) { + base::threading::ScopedLock scopedLock(lock()); + if (m_modules.empty() || file == nullptr) { + return vlevel <= m_level; + } else { + std::map::iterator it = m_modules.begin(); + for (; it != m_modules.end(); ++it) { + if (base::utils::Str::wildCardMatch(file, it->first.c_str())) { + return vlevel <= it->second; + } + } + if (base::utils::hasFlag(LoggingFlag::AllowVerboseIfModuleNotSpecified, *m_pFlags)) { + return true; + } + return false; + } +} + +void VRegistry::setFromArgs(const base::utils::CommandLineArgs* commandLineArgs) { + if (commandLineArgs->hasParam("-v") || commandLineArgs->hasParam("--verbose") || + commandLineArgs->hasParam("-V") || commandLineArgs->hasParam("--VERBOSE")) { + setLevel(base::consts::kMaxVerboseLevel); + } else if (commandLineArgs->hasParamWithValue("--v")) { + setLevel(static_cast(atoi(commandLineArgs->getParamValue("--v")))); + } else if (commandLineArgs->hasParamWithValue("--V")) { + setLevel(static_cast(atoi(commandLineArgs->getParamValue("--V")))); + } else if ((commandLineArgs->hasParamWithValue("-vmodule")) && vModulesEnabled()) { + setModules(commandLineArgs->getParamValue("-vmodule")); + } else if (commandLineArgs->hasParamWithValue("-VMODULE") && vModulesEnabled()) { + setModules(commandLineArgs->getParamValue("-VMODULE")); + } +} + +#if !defined(ELPP_DEFAULT_LOGGING_FLAGS) +# define ELPP_DEFAULT_LOGGING_FLAGS 0x0 +#endif // !defined(ELPP_DEFAULT_LOGGING_FLAGS) +// Storage +#if ELPP_ASYNC_LOGGING +Storage::Storage(const LogBuilderPtr& defaultLogBuilder, base::IWorker* asyncDispatchWorker) : +#else +Storage::Storage(const LogBuilderPtr& defaultLogBuilder) : +#endif // ELPP_ASYNC_LOGGING + m_registeredHitCounters(new base::RegisteredHitCounters()), + m_registeredLoggers(new base::RegisteredLoggers(defaultLogBuilder)), + m_flags(ELPP_DEFAULT_LOGGING_FLAGS), + m_vRegistry(new base::VRegistry(0, &m_flags)), +#if ELPP_ASYNC_LOGGING + m_asyncLogQueue(new base::AsyncLogQueue()), + m_asyncDispatchWorker(asyncDispatchWorker), +#endif // ELPP_ASYNC_LOGGING + m_preRollOutCallback(base::defaultPreRollOutCallback) { + // Register default logger + m_registeredLoggers->get(std::string(base::consts::kDefaultLoggerId)); + // We register default logger anyway (worse case it's not going to register) just in case + m_registeredLoggers->get("default"); + // Register performance logger and reconfigure format + Logger* performanceLogger = m_registeredLoggers->get(std::string(base::consts::kPerformanceLoggerId)); + m_registeredLoggers->get("performance"); + performanceLogger->configurations()->setGlobally(ConfigurationType::Format, std::string("%datetime %level %msg")); + performanceLogger->reconfigure(); +#if defined(ELPP_SYSLOG) + // Register syslog logger and reconfigure format + Logger* sysLogLogger = m_registeredLoggers->get(std::string(base::consts::kSysLogLoggerId)); + sysLogLogger->configurations()->setGlobally(ConfigurationType::Format, std::string("%level: %msg")); + sysLogLogger->reconfigure(); +#endif // defined(ELPP_SYSLOG) + addFlag(LoggingFlag::AllowVerboseIfModuleNotSpecified); +#if ELPP_ASYNC_LOGGING + installLogDispatchCallback(std::string("AsyncLogDispatchCallback")); +#else + installLogDispatchCallback(std::string("DefaultLogDispatchCallback")); +#endif // ELPP_ASYNC_LOGGING +#if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING) + installPerformanceTrackingCallback + (std::string("DefaultPerformanceTrackingCallback")); +#endif // defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING) + ELPP_INTERNAL_INFO(1, "Easylogging++ has been initialized"); +#if ELPP_ASYNC_LOGGING + m_asyncDispatchWorker->start(); +#endif // ELPP_ASYNC_LOGGING +} + +Storage::~Storage(void) { + ELPP_INTERNAL_INFO(4, "Destroying storage"); +#if ELPP_ASYNC_LOGGING + ELPP_INTERNAL_INFO(5, "Replacing log dispatch callback to synchronous"); + uninstallLogDispatchCallback(std::string("AsyncLogDispatchCallback")); + installLogDispatchCallback(std::string("DefaultLogDispatchCallback")); + ELPP_INTERNAL_INFO(5, "Destroying asyncDispatchWorker"); + base::utils::safeDelete(m_asyncDispatchWorker); + ELPP_INTERNAL_INFO(5, "Destroying asyncLogQueue"); + base::utils::safeDelete(m_asyncLogQueue); +#endif // ELPP_ASYNC_LOGGING + ELPP_INTERNAL_INFO(5, "Destroying registeredHitCounters"); + base::utils::safeDelete(m_registeredHitCounters); + ELPP_INTERNAL_INFO(5, "Destroying registeredLoggers"); + base::utils::safeDelete(m_registeredLoggers); + ELPP_INTERNAL_INFO(5, "Destroying vRegistry"); + base::utils::safeDelete(m_vRegistry); +} + +bool Storage::hasCustomFormatSpecifier(const char* formatSpecifier) { + base::threading::ScopedLock scopedLock(lock()); + return std::find(m_customFormatSpecifiers.begin(), m_customFormatSpecifiers.end(), + formatSpecifier) != m_customFormatSpecifiers.end(); +} + +void Storage::installCustomFormatSpecifier(const CustomFormatSpecifier& customFormatSpecifier) { + if (hasCustomFormatSpecifier(customFormatSpecifier.formatSpecifier())) { + return; + } + base::threading::ScopedLock scopedLock(lock()); + m_customFormatSpecifiers.push_back(customFormatSpecifier); +} + +bool Storage::uninstallCustomFormatSpecifier(const char* formatSpecifier) { + base::threading::ScopedLock scopedLock(lock()); + std::vector::iterator it = std::find(m_customFormatSpecifiers.begin(), + m_customFormatSpecifiers.end(), formatSpecifier); + if (it != m_customFormatSpecifiers.end() && strcmp(formatSpecifier, it->formatSpecifier()) == 0) { + m_customFormatSpecifiers.erase(it); + return true; + } + return false; +} + +void Storage::setApplicationArguments(int argc, char** argv) { + m_commandLineArgs.setArgs(argc, argv); + m_vRegistry->setFromArgs(commandLineArgs()); + // default log file +#if !defined(ELPP_DISABLE_LOG_FILE_FROM_ARG) + if (m_commandLineArgs.hasParamWithValue(base::consts::kDefaultLogFileParam)) { + Configurations c; + c.setGlobally(ConfigurationType::Filename, + std::string(m_commandLineArgs.getParamValue(base::consts::kDefaultLogFileParam))); + registeredLoggers()->setDefaultConfigurations(c); + for (base::RegisteredLoggers::iterator it = registeredLoggers()->begin(); + it != registeredLoggers()->end(); ++it) { + it->second->configure(c); + } + } +#endif // !defined(ELPP_DISABLE_LOG_FILE_FROM_ARG) +#if defined(ELPP_LOGGING_FLAGS_FROM_ARG) + if (m_commandLineArgs.hasParamWithValue(base::consts::kLoggingFlagsParam)) { + int userInput = atoi(m_commandLineArgs.getParamValue(base::consts::kLoggingFlagsParam)); + if (ELPP_DEFAULT_LOGGING_FLAGS == 0x0) { + m_flags = userInput; + } else { + base::utils::addFlag(userInput, &m_flags); + } + } +#endif // defined(ELPP_LOGGING_FLAGS_FROM_ARG) +} + +// DefaultLogDispatchCallback + +void DefaultLogDispatchCallback::handle(const LogDispatchData* data) { + m_data = data; + dispatch(m_data->logMessage()->logger()->logBuilder()->build(m_data->logMessage(), + m_data->dispatchAction() == base::DispatchAction::NormalLog)); +} + +void DefaultLogDispatchCallback::dispatch(base::type::string_t&& logLine) { + if (m_data->dispatchAction() == base::DispatchAction::NormalLog) { + if (m_data->logMessage()->logger()->m_typedConfigurations->toFile(m_data->logMessage()->level())) { + base::type::fstream_t* fs = m_data->logMessage()->logger()->m_typedConfigurations->fileStream( + m_data->logMessage()->level()); + if (fs != nullptr) { + fs->write(logLine.c_str(), logLine.size()); + if (fs->fail()) { + ELPP_INTERNAL_ERROR("Unable to write log to file [" + << m_data->logMessage()->logger()->m_typedConfigurations->filename(m_data->logMessage()->level()) << "].\n" + << "Few possible reasons (could be something else):\n" << " * Permission denied\n" + << " * Disk full\n" << " * Disk is not writable", true); + } else { + if (ELPP->hasFlag(LoggingFlag::ImmediateFlush) + || (m_data->logMessage()->logger()->isFlushNeeded(m_data->logMessage()->level()))) { + m_data->logMessage()->logger()->flush(m_data->logMessage()->level(), fs); + } + } + } else { + ELPP_INTERNAL_ERROR("Log file for [" << LevelHelper::convertToString(m_data->logMessage()->level()) << "] " + << "has not been configured but [TO_FILE] is configured to TRUE. [Logger ID: " + << m_data->logMessage()->logger()->id() << "]", false); + } + } + if (m_data->logMessage()->logger()->m_typedConfigurations->toStandardOutput(m_data->logMessage()->level())) { + if (ELPP->hasFlag(LoggingFlag::ColoredTerminalOutput)) + m_data->logMessage()->logger()->logBuilder()->convertToColoredOutput(&logLine, m_data->logMessage()->level()); + ELPP_COUT << ELPP_COUT_LINE(logLine); + } + } +#if defined(ELPP_SYSLOG) + else if (m_data->dispatchAction() == base::DispatchAction::SysLog) { + // Determine syslog priority + int sysLogPriority = 0; + if (m_data->logMessage()->level() == Level::Fatal) + sysLogPriority = LOG_EMERG; + else if (m_data->logMessage()->level() == Level::Error) + sysLogPriority = LOG_ERR; + else if (m_data->logMessage()->level() == Level::Warning) + sysLogPriority = LOG_WARNING; + else if (m_data->logMessage()->level() == Level::Info) + sysLogPriority = LOG_INFO; + else if (m_data->logMessage()->level() == Level::Debug) + sysLogPriority = LOG_DEBUG; + else + sysLogPriority = LOG_NOTICE; +# if defined(ELPP_UNICODE) + char* line = base::utils::Str::wcharPtrToCharPtr(logLine.c_str()); + syslog(sysLogPriority, "%s", line); + free(line); +# else + syslog(sysLogPriority, "%s", logLine.c_str()); +# endif + } +#endif // defined(ELPP_SYSLOG) +} + +#if ELPP_ASYNC_LOGGING + +// AsyncLogDispatchCallback + +void AsyncLogDispatchCallback::handle(const LogDispatchData* data) { + base::type::string_t logLine = data->logMessage()->logger()->logBuilder()->build(data->logMessage(), + data->dispatchAction() == base::DispatchAction::NormalLog); + if (data->dispatchAction() == base::DispatchAction::NormalLog + && data->logMessage()->logger()->typedConfigurations()->toStandardOutput(data->logMessage()->level())) { + if (ELPP->hasFlag(LoggingFlag::ColoredTerminalOutput)) + data->logMessage()->logger()->logBuilder()->convertToColoredOutput(&logLine, data->logMessage()->level()); + ELPP_COUT << ELPP_COUT_LINE(logLine); + } + // Save resources and only queue if we want to write to file otherwise just ignore handler + if (data->logMessage()->logger()->typedConfigurations()->toFile(data->logMessage()->level())) { + ELPP->asyncLogQueue()->push(AsyncLogItem(*(data->logMessage()), *data, logLine)); + } +} + +// AsyncDispatchWorker +AsyncDispatchWorker::AsyncDispatchWorker() { + setContinueRunning(false); +} + +AsyncDispatchWorker::~AsyncDispatchWorker() { + setContinueRunning(false); + ELPP_INTERNAL_INFO(6, "Stopping dispatch worker - Cleaning log queue"); + clean(); + ELPP_INTERNAL_INFO(6, "Log queue cleaned"); +} + +bool AsyncDispatchWorker::clean(void) { + std::mutex m; + std::unique_lock lk(m); + cv.wait(lk, [] { return !ELPP->asyncLogQueue()->empty(); }); + emptyQueue(); + lk.unlock(); + cv.notify_one(); + return ELPP->asyncLogQueue()->empty(); +} + +void AsyncDispatchWorker::emptyQueue(void) { + while (!ELPP->asyncLogQueue()->empty()) { + AsyncLogItem data = ELPP->asyncLogQueue()->next(); + handle(&data); + base::threading::msleep(100); + } +} + +void AsyncDispatchWorker::start(void) { + base::threading::msleep(5000); // 5s (why?) + setContinueRunning(true); + std::thread t1(&AsyncDispatchWorker::run, this); + t1.join(); +} + +void AsyncDispatchWorker::handle(AsyncLogItem* logItem) { + LogDispatchData* data = logItem->data(); + LogMessage* logMessage = logItem->logMessage(); + Logger* logger = logMessage->logger(); + base::TypedConfigurations* conf = logger->typedConfigurations(); + base::type::string_t logLine = logItem->logLine(); + if (data->dispatchAction() == base::DispatchAction::NormalLog) { + if (conf->toFile(logMessage->level())) { + base::type::fstream_t* fs = conf->fileStream(logMessage->level()); + if (fs != nullptr) { + fs->write(logLine.c_str(), logLine.size()); + if (fs->fail()) { + ELPP_INTERNAL_ERROR("Unable to write log to file [" + << conf->filename(logMessage->level()) << "].\n" + << "Few possible reasons (could be something else):\n" << " * Permission denied\n" + << " * Disk full\n" << " * Disk is not writable", true); + } else { + if (ELPP->hasFlag(LoggingFlag::ImmediateFlush) || (logger->isFlushNeeded(logMessage->level()))) { + logger->flush(logMessage->level(), fs); + } + } + } else { + ELPP_INTERNAL_ERROR("Log file for [" << LevelHelper::convertToString(logMessage->level()) << "] " + << "has not been configured but [TO_FILE] is configured to TRUE. [Logger ID: " << logger->id() << "]", false); + } + } + } +# if defined(ELPP_SYSLOG) + else if (data->dispatchAction() == base::DispatchAction::SysLog) { + // Determine syslog priority + int sysLogPriority = 0; + if (logMessage->level() == Level::Fatal) + sysLogPriority = LOG_EMERG; + else if (logMessage->level() == Level::Error) + sysLogPriority = LOG_ERR; + else if (logMessage->level() == Level::Warning) + sysLogPriority = LOG_WARNING; + else if (logMessage->level() == Level::Info) + sysLogPriority = LOG_INFO; + else if (logMessage->level() == Level::Debug) + sysLogPriority = LOG_DEBUG; + else + sysLogPriority = LOG_NOTICE; +# if defined(ELPP_UNICODE) + char* line = base::utils::Str::wcharPtrToCharPtr(logLine.c_str()); + syslog(sysLogPriority, "%s", line); + free(line); +# else + syslog(sysLogPriority, "%s", logLine.c_str()); +# endif + } +# endif // defined(ELPP_SYSLOG) +} + +void AsyncDispatchWorker::run(void) { + while (continueRunning()) { + emptyQueue(); + base::threading::msleep(10); // 10ms + } +} +#endif // ELPP_ASYNC_LOGGING + +// DefaultLogBuilder + +base::type::string_t DefaultLogBuilder::build(const LogMessage* logMessage, bool appendNewLine) const { + base::TypedConfigurations* tc = logMessage->logger()->typedConfigurations(); + const base::LogFormat* logFormat = &tc->logFormat(logMessage->level()); + base::type::string_t logLine = logFormat->format(); + char buff[base::consts::kSourceFilenameMaxLength + base::consts::kSourceLineMaxLength] = ""; + const char* bufLim = buff + sizeof(buff); + if (logFormat->hasFlag(base::FormatFlags::AppName)) { + // App name + base::utils::Str::replaceFirstWithEscape(logLine, base::consts::kAppNameFormatSpecifier, + logMessage->logger()->parentApplicationName()); + } + if (logFormat->hasFlag(base::FormatFlags::ThreadId)) { + // Thread ID + base::utils::Str::replaceFirstWithEscape(logLine, base::consts::kThreadIdFormatSpecifier, + ELPP->getThreadName(base::threading::getCurrentThreadId())); + } + if (logFormat->hasFlag(base::FormatFlags::DateTime)) { + // DateTime + base::utils::Str::replaceFirstWithEscape(logLine, base::consts::kDateTimeFormatSpecifier, + base::utils::DateTime::getDateTime(logFormat->dateTimeFormat().c_str(), + &tc->subsecondPrecision(logMessage->level()))); + } + if (logFormat->hasFlag(base::FormatFlags::Function)) { + // Function + base::utils::Str::replaceFirstWithEscape(logLine, base::consts::kLogFunctionFormatSpecifier, logMessage->func()); + } + if (logFormat->hasFlag(base::FormatFlags::File)) { + // File + base::utils::Str::clearBuff(buff, base::consts::kSourceFilenameMaxLength); + base::utils::File::buildStrippedFilename(logMessage->file().c_str(), buff); + base::utils::Str::replaceFirstWithEscape(logLine, base::consts::kLogFileFormatSpecifier, std::string(buff)); + } + if (logFormat->hasFlag(base::FormatFlags::FileBase)) { + // FileBase + base::utils::Str::clearBuff(buff, base::consts::kSourceFilenameMaxLength); + base::utils::File::buildBaseFilename(logMessage->file(), buff); + base::utils::Str::replaceFirstWithEscape(logLine, base::consts::kLogFileBaseFormatSpecifier, std::string(buff)); + } + if (logFormat->hasFlag(base::FormatFlags::Line)) { + // Line + char* buf = base::utils::Str::clearBuff(buff, base::consts::kSourceLineMaxLength); + buf = base::utils::Str::convertAndAddToBuff(logMessage->line(), base::consts::kSourceLineMaxLength, buf, bufLim, false); + base::utils::Str::replaceFirstWithEscape(logLine, base::consts::kLogLineFormatSpecifier, std::string(buff)); + } + if (logFormat->hasFlag(base::FormatFlags::Location)) { + // Location + char* buf = base::utils::Str::clearBuff(buff, + base::consts::kSourceFilenameMaxLength + base::consts::kSourceLineMaxLength); + base::utils::File::buildStrippedFilename(logMessage->file().c_str(), buff); + buf = base::utils::Str::addToBuff(buff, buf, bufLim); + buf = base::utils::Str::addToBuff(":", buf, bufLim); + buf = base::utils::Str::convertAndAddToBuff(logMessage->line(), base::consts::kSourceLineMaxLength, buf, bufLim, + false); + base::utils::Str::replaceFirstWithEscape(logLine, base::consts::kLogLocationFormatSpecifier, std::string(buff)); + } + if (logMessage->level() == Level::Verbose && logFormat->hasFlag(base::FormatFlags::VerboseLevel)) { + // Verbose level + char* buf = base::utils::Str::clearBuff(buff, 1); + buf = base::utils::Str::convertAndAddToBuff(logMessage->verboseLevel(), 1, buf, bufLim, false); + base::utils::Str::replaceFirstWithEscape(logLine, base::consts::kVerboseLevelFormatSpecifier, std::string(buff)); + } + if (logFormat->hasFlag(base::FormatFlags::LogMessage)) { + // Log message + base::utils::Str::replaceFirstWithEscape(logLine, base::consts::kMessageFormatSpecifier, logMessage->message()); + } +#if !defined(ELPP_DISABLE_CUSTOM_FORMAT_SPECIFIERS) + for (std::vector::const_iterator it = ELPP->customFormatSpecifiers()->begin(); + it != ELPP->customFormatSpecifiers()->end(); ++it) { + std::string fs(it->formatSpecifier()); + base::type::string_t wcsFormatSpecifier(fs.begin(), fs.end()); + base::utils::Str::replaceFirstWithEscape(logLine, wcsFormatSpecifier, it->resolver()(logMessage)); + } +#endif // !defined(ELPP_DISABLE_CUSTOM_FORMAT_SPECIFIERS) + if (appendNewLine) logLine += ELPP_LITERAL("\n"); + return logLine; +} + +// LogDispatcher + +void LogDispatcher::dispatch(void) { + if (m_proceed && m_dispatchAction == base::DispatchAction::None) { + m_proceed = false; + } + if (!m_proceed) { + return; + } + base::threading::ScopedLock scopedLock(ELPP->lock()); + base::TypedConfigurations* tc = m_logMessage.logger()->m_typedConfigurations; + if (ELPP->hasFlag(LoggingFlag::StrictLogFileSizeCheck)) { + tc->validateFileRolling(m_logMessage.level(), ELPP->preRollOutCallback()); + } + LogDispatchCallback* callback = nullptr; + LogDispatchData data; + for (const std::pair& h + : ELPP->m_logDispatchCallbacks) { + callback = h.second.get(); + if (callback != nullptr && callback->enabled()) { + data.setLogMessage(&m_logMessage); + data.setDispatchAction(m_dispatchAction); + callback->handle(&data); + } + } +} + +// MessageBuilder + +void MessageBuilder::initialize(Logger* logger) { + m_logger = logger; + m_containerLogSeperator = ELPP->hasFlag(LoggingFlag::NewLineForContainer) ? + ELPP_LITERAL("\n ") : ELPP_LITERAL(", "); +} + +MessageBuilder& MessageBuilder::operator<<(const wchar_t* msg) { + if (msg == nullptr) { + m_logger->stream() << base::consts::kNullPointer; + return *this; + } +# if defined(ELPP_UNICODE) + m_logger->stream() << msg; +# else + char* buff_ = base::utils::Str::wcharPtrToCharPtr(msg); + m_logger->stream() << buff_; + free(buff_); +# endif + if (ELPP->hasFlag(LoggingFlag::AutoSpacing)) { + m_logger->stream() << " "; + } + return *this; +} + +// Writer + +Writer& Writer::construct(Logger* logger, bool needLock) { + m_logger = logger; + initializeLogger(logger->id(), false, needLock); + m_messageBuilder.initialize(m_logger); + return *this; +} + +Writer& Writer::construct(int count, const char* loggerIds, ...) { + if (ELPP->hasFlag(LoggingFlag::MultiLoggerSupport)) { + va_list loggersList; + va_start(loggersList, loggerIds); + const char* id = loggerIds; + for (int i = 0; i < count; ++i) { + m_loggerIds.push_back(std::string(id)); + id = va_arg(loggersList, const char*); + } + va_end(loggersList); + initializeLogger(m_loggerIds.at(0)); + } else { + initializeLogger(std::string(loggerIds)); + } + m_messageBuilder.initialize(m_logger); + return *this; +} + +void Writer::initializeLogger(const std::string& loggerId, bool lookup, bool needLock) { + if (lookup) { + m_logger = ELPP->registeredLoggers()->get(loggerId, ELPP->hasFlag(LoggingFlag::CreateLoggerAutomatically)); + } + if (m_logger == nullptr) { + ELPP->acquireLock(); + if (!ELPP->registeredLoggers()->has(std::string(base::consts::kDefaultLoggerId))) { + // Somehow default logger has been unregistered. Not good! Register again + ELPP->registeredLoggers()->get(std::string(base::consts::kDefaultLoggerId)); + } + ELPP->releaseLock(); // Need to unlock it for next writer + Writer(Level::Debug, m_file, m_line, m_func).construct(1, base::consts::kDefaultLoggerId) + << "Logger [" << loggerId << "] is not registered yet!"; + m_proceed = false; + } else { + if (needLock) { + m_logger->acquireLock(); // This should not be unlocked by checking m_proceed because + // m_proceed can be changed by lines below + } + if (ELPP->hasFlag(LoggingFlag::HierarchicalLogging)) { + m_proceed = m_level == Level::Verbose ? m_logger->enabled(m_level) : + LevelHelper::castToInt(m_level) >= LevelHelper::castToInt(ELPP->m_loggingLevel); + } else { + m_proceed = m_logger->enabled(m_level); + } + } +} + +void Writer::processDispatch() { +#if ELPP_LOGGING_ENABLED + if (ELPP->hasFlag(LoggingFlag::MultiLoggerSupport)) { + bool firstDispatched = false; + base::type::string_t logMessage; + std::size_t i = 0; + do { + if (m_proceed) { + if (firstDispatched) { + m_logger->stream() << logMessage; + } else { + firstDispatched = true; + if (m_loggerIds.size() > 1) { + logMessage = m_logger->stream().str(); + } + } + triggerDispatch(); + } else if (m_logger != nullptr) { + m_logger->stream().str(ELPP_LITERAL("")); + m_logger->releaseLock(); + } + if (i + 1 < m_loggerIds.size()) { + initializeLogger(m_loggerIds.at(i + 1)); + } + } while (++i < m_loggerIds.size()); + } else { + if (m_proceed) { + triggerDispatch(); + } else if (m_logger != nullptr) { + m_logger->stream().str(ELPP_LITERAL("")); + m_logger->releaseLock(); + } + } +#else + if (m_logger != nullptr) { + m_logger->stream().str(ELPP_LITERAL("")); + m_logger->releaseLock(); + } +#endif // ELPP_LOGGING_ENABLED +} + +void Writer::triggerDispatch(void) { + if (m_proceed) { + base::LogDispatcher(m_proceed, LogMessage(m_level, m_file, m_line, m_func, m_verboseLevel, + m_logger), m_dispatchAction).dispatch(); + } + if (m_logger != nullptr) { + m_logger->stream().str(ELPP_LITERAL("")); + m_logger->releaseLock(); + } + if (m_proceed && m_level == Level::Fatal + && !ELPP->hasFlag(LoggingFlag::DisableApplicationAbortOnFatalLog)) { + base::Writer(Level::Warning, m_file, m_line, m_func).construct(1, base::consts::kDefaultLoggerId) + << "Aborting application. Reason: Fatal log at [" << m_file << ":" << m_line << "]"; + std::stringstream reasonStream; + reasonStream << "Fatal log at [" << m_file << ":" << m_line << "]" + << " If you wish to disable 'abort on fatal log' please use " + << "el::Helpers::addFlag(el::LoggingFlag::DisableApplicationAbortOnFatalLog)"; + base::utils::abort(1, reasonStream.str()); + } + m_proceed = false; +} + +// PErrorWriter + +PErrorWriter::~PErrorWriter(void) { + if (m_proceed) { +#if ELPP_COMPILER_MSVC + char buff[256]; + strerror_s(buff, 256, errno); + m_logger->stream() << ": " << buff << " [" << errno << "]"; +#else + m_logger->stream() << ": " << strerror(errno) << " [" << errno << "]"; +#endif + } +} + +// PerformanceTracker + +#if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING) + +PerformanceTracker::PerformanceTracker(const std::string& blockName, + base::TimestampUnit timestampUnit, + const std::string& loggerId, + bool scopedLog, Level level) : + m_blockName(blockName), m_timestampUnit(timestampUnit), m_loggerId(loggerId), m_scopedLog(scopedLog), + m_level(level), m_hasChecked(false), m_lastCheckpointId(std::string()), m_enabled(false) { +#if !defined(ELPP_DISABLE_PERFORMANCE_TRACKING) && ELPP_LOGGING_ENABLED + // We store it locally so that if user happen to change configuration by the end of scope + // or before calling checkpoint, we still depend on state of configuraton at time of construction + el::Logger* loggerPtr = ELPP->registeredLoggers()->get(loggerId, false); + m_enabled = loggerPtr != nullptr && loggerPtr->m_typedConfigurations->performanceTracking(m_level); + if (m_enabled) { + base::utils::DateTime::gettimeofday(&m_startTime); + } +#endif // !defined(ELPP_DISABLE_PERFORMANCE_TRACKING) && ELPP_LOGGING_ENABLED +} + +PerformanceTracker::~PerformanceTracker(void) { +#if !defined(ELPP_DISABLE_PERFORMANCE_TRACKING) && ELPP_LOGGING_ENABLED + if (m_enabled) { + base::threading::ScopedLock scopedLock(lock()); + if (m_scopedLog) { + base::utils::DateTime::gettimeofday(&m_endTime); + base::type::string_t formattedTime = getFormattedTimeTaken(); + PerformanceTrackingData data(PerformanceTrackingData::DataType::Complete); + data.init(this); + data.m_formattedTimeTaken = formattedTime; + PerformanceTrackingCallback* callback = nullptr; + for (const std::pair& h + : ELPP->m_performanceTrackingCallbacks) { + callback = h.second.get(); + if (callback != nullptr && callback->enabled()) { + callback->handle(&data); + } + } + } + } +#endif // !defined(ELPP_DISABLE_PERFORMANCE_TRACKING) +} + +void PerformanceTracker::checkpoint(const std::string& id, const char* file, base::type::LineNumber line, + const char* func) { +#if !defined(ELPP_DISABLE_PERFORMANCE_TRACKING) && ELPP_LOGGING_ENABLED + if (m_enabled) { + base::threading::ScopedLock scopedLock(lock()); + base::utils::DateTime::gettimeofday(&m_endTime); + base::type::string_t formattedTime = m_hasChecked ? getFormattedTimeTaken(m_lastCheckpointTime) : ELPP_LITERAL(""); + PerformanceTrackingData data(PerformanceTrackingData::DataType::Checkpoint); + data.init(this); + data.m_checkpointId = id; + data.m_file = file; + data.m_line = line; + data.m_func = func; + data.m_formattedTimeTaken = formattedTime; + PerformanceTrackingCallback* callback = nullptr; + for (const std::pair& h + : ELPP->m_performanceTrackingCallbacks) { + callback = h.second.get(); + if (callback != nullptr && callback->enabled()) { + callback->handle(&data); + } + } + base::utils::DateTime::gettimeofday(&m_lastCheckpointTime); + m_hasChecked = true; + m_lastCheckpointId = id; + } +#endif // !defined(ELPP_DISABLE_PERFORMANCE_TRACKING) && ELPP_LOGGING_ENABLED + ELPP_UNUSED(id); + ELPP_UNUSED(file); + ELPP_UNUSED(line); + ELPP_UNUSED(func); +} + +const base::type::string_t PerformanceTracker::getFormattedTimeTaken(struct timeval startTime) const { + if (ELPP->hasFlag(LoggingFlag::FixedTimeFormat)) { + base::type::stringstream_t ss; + ss << base::utils::DateTime::getTimeDifference(m_endTime, + startTime, m_timestampUnit) << " " << base::consts::kTimeFormats[static_cast + (m_timestampUnit)].unit; + return ss.str(); + } + return base::utils::DateTime::formatTime(base::utils::DateTime::getTimeDifference(m_endTime, + startTime, m_timestampUnit), m_timestampUnit); +} + +#endif // defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING) + +namespace debug { +#if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_CRASH_LOG) + +// StackTrace + +StackTrace::StackTraceEntry::StackTraceEntry(std::size_t index, const char* loc, const char* demang, const char* hex, + const char* addr) { + m_index = index; + m_location = std::string(loc); + m_demangled = std::string(demang); + m_hex = std::string(hex); + m_addr = std::string(addr); +} + +std::ostream& operator<<(std::ostream& ss, const StackTrace::StackTraceEntry& si) { + ss << "[" << si.m_index << "] " << si.m_location << (si.m_demangled.empty() ? "" : ":") << si.m_demangled + << (si.m_hex.empty() ? "" : "+") << si.m_hex << si.m_addr; + return ss; +} + +std::ostream& operator<<(std::ostream& os, const StackTrace& st) { + std::vector::const_iterator it = st.m_stack.begin(); + while (it != st.m_stack.end()) { + os << " " << *it++ << "\n"; + } + return os; +} + +void StackTrace::generateNew(void) { +#if ELPP_STACKTRACE + m_stack.clear(); + void* stack[kMaxStack]; + unsigned int size = backtrace(stack, kMaxStack); + char** strings = backtrace_symbols(stack, size); + if (size > kStackStart) { // Skip StackTrace c'tor and generateNew + for (std::size_t i = kStackStart; i < size; ++i) { + char* mangName = nullptr; + char* hex = nullptr; + char* addr = nullptr; + for (char* c = strings[i]; *c; ++c) { + switch (*c) { + case '(': + mangName = c; + break; + case '+': + hex = c; + break; + case ')': + addr = c; + break; + default: + break; + } + } + // Perform demangling if parsed properly + if (mangName != nullptr && hex != nullptr && addr != nullptr && mangName < hex) { + *mangName++ = '\0'; + *hex++ = '\0'; + *addr++ = '\0'; + int status = 0; + char* demangName = abi::__cxa_demangle(mangName, 0, 0, &status); + // if demangling is successful, output the demangled function name + if (status == 0) { + // Success (see http://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-html-USERS-4.3/a01696.html) + StackTraceEntry entry(i - 1, strings[i], demangName, hex, addr); + m_stack.push_back(entry); + } else { + // Not successful - we will use mangled name + StackTraceEntry entry(i - 1, strings[i], mangName, hex, addr); + m_stack.push_back(entry); + } + free(demangName); + } else { + StackTraceEntry entry(i - 1, strings[i]); + m_stack.push_back(entry); + } + } + } + free(strings); +#else + ELPP_INTERNAL_INFO(1, "Stacktrace generation not supported for selected compiler"); +#endif // ELPP_STACKTRACE +} + +// Static helper functions + +static std::string crashReason(int sig) { + std::stringstream ss; + bool foundReason = false; + for (int i = 0; i < base::consts::kCrashSignalsCount; ++i) { + if (base::consts::kCrashSignals[i].numb == sig) { + ss << "Application has crashed due to [" << base::consts::kCrashSignals[i].name << "] signal"; + if (ELPP->hasFlag(el::LoggingFlag::LogDetailedCrashReason)) { + ss << std::endl << + " " << base::consts::kCrashSignals[i].brief << std::endl << + " " << base::consts::kCrashSignals[i].detail; + } + foundReason = true; + } + } + if (!foundReason) { + ss << "Application has crashed due to unknown signal [" << sig << "]"; + } + return ss.str(); +} +/// @brief Logs reason of crash from sig +static void logCrashReason(int sig, bool stackTraceIfAvailable, Level level, const char* logger) { + std::stringstream ss; + ss << "CRASH HANDLED; "; + ss << crashReason(sig); +#if ELPP_STACKTRACE + if (stackTraceIfAvailable) { + ss << std::endl << " ======= Backtrace: =========" << std::endl << base::debug::StackTrace(); + } +#else + ELPP_UNUSED(stackTraceIfAvailable); +#endif // ELPP_STACKTRACE + ELPP_WRITE_LOG(el::base::Writer, level, base::DispatchAction::NormalLog, logger) << ss.str(); +} + +static inline void crashAbort(int sig) { + base::utils::abort(sig, std::string()); +} + +/// @brief Default application crash handler +/// +/// @detail This function writes log using 'default' logger, prints stack trace for GCC based compilers and aborts program. +static inline void defaultCrashHandler(int sig) { + base::debug::logCrashReason(sig, true, Level::Fatal, base::consts::kDefaultLoggerId); + base::debug::crashAbort(sig); +} + +// CrashHandler + +CrashHandler::CrashHandler(bool useDefault) { + if (useDefault) { + setHandler(defaultCrashHandler); + } +} + +void CrashHandler::setHandler(const Handler& cHandler) { + m_handler = cHandler; +#if defined(ELPP_HANDLE_SIGABRT) + int i = 0; // SIGABRT is at base::consts::kCrashSignals[0] +#else + int i = 1; +#endif // defined(ELPP_HANDLE_SIGABRT) + for (; i < base::consts::kCrashSignalsCount; ++i) { + m_handler = signal(base::consts::kCrashSignals[i].numb, cHandler); + } +} + +#endif // defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_CRASH_LOG) +} // namespace debug +} // namespace base + +// el + +// Helpers + +#if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_CRASH_LOG) + +void Helpers::crashAbort(int sig, const char* sourceFile, unsigned int long line) { + std::stringstream ss; + ss << base::debug::crashReason(sig).c_str(); + ss << " - [Called el::Helpers::crashAbort(" << sig << ")]"; + if (sourceFile != nullptr && strlen(sourceFile) > 0) { + ss << " - Source: " << sourceFile; + if (line > 0) + ss << ":" << line; + else + ss << " (line number not specified)"; + } + base::utils::abort(sig, ss.str()); +} + +void Helpers::logCrashReason(int sig, bool stackTraceIfAvailable, Level level, const char* logger) { + el::base::debug::logCrashReason(sig, stackTraceIfAvailable, level, logger); +} + +#endif // defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_CRASH_LOG) + +// Loggers + +Logger* Loggers::getLogger(const std::string& identity, bool registerIfNotAvailable) { + base::threading::ScopedLock scopedLock(ELPP->lock()); + return ELPP->registeredLoggers()->get(identity, registerIfNotAvailable); +} + +void Loggers::setDefaultLogBuilder(el::LogBuilderPtr& logBuilderPtr) { + ELPP->registeredLoggers()->setDefaultLogBuilder(logBuilderPtr); +} + +bool Loggers::unregisterLogger(const std::string& identity) { + base::threading::ScopedLock scopedLock(ELPP->lock()); + return ELPP->registeredLoggers()->remove(identity); +} + +bool Loggers::hasLogger(const std::string& identity) { + base::threading::ScopedLock scopedLock(ELPP->lock()); + return ELPP->registeredLoggers()->has(identity); +} + +Logger* Loggers::reconfigureLogger(Logger* logger, const Configurations& configurations) { + if (!logger) return nullptr; + logger->configure(configurations); + return logger; +} + +Logger* Loggers::reconfigureLogger(const std::string& identity, const Configurations& configurations) { + return Loggers::reconfigureLogger(Loggers::getLogger(identity), configurations); +} + +Logger* Loggers::reconfigureLogger(const std::string& identity, ConfigurationType configurationType, + const std::string& value) { + Logger* logger = Loggers::getLogger(identity); + if (logger == nullptr) { + return nullptr; + } + logger->configurations()->set(Level::Global, configurationType, value); + logger->reconfigure(); + return logger; +} + +void Loggers::reconfigureAllLoggers(const Configurations& configurations) { + for (base::RegisteredLoggers::iterator it = ELPP->registeredLoggers()->begin(); + it != ELPP->registeredLoggers()->end(); ++it) { + Loggers::reconfigureLogger(it->second, configurations); + } +} + +void Loggers::reconfigureAllLoggers(Level level, ConfigurationType configurationType, + const std::string& value) { + for (base::RegisteredLoggers::iterator it = ELPP->registeredLoggers()->begin(); + it != ELPP->registeredLoggers()->end(); ++it) { + Logger* logger = it->second; + logger->configurations()->set(level, configurationType, value); + logger->reconfigure(); + } +} + +void Loggers::setDefaultConfigurations(const Configurations& configurations, bool reconfigureExistingLoggers) { + ELPP->registeredLoggers()->setDefaultConfigurations(configurations); + if (reconfigureExistingLoggers) { + Loggers::reconfigureAllLoggers(configurations); + } +} + +const Configurations* Loggers::defaultConfigurations(void) { + return ELPP->registeredLoggers()->defaultConfigurations(); +} + +const base::LogStreamsReferenceMap* Loggers::logStreamsReference(void) { + return ELPP->registeredLoggers()->logStreamsReference(); +} + +base::TypedConfigurations Loggers::defaultTypedConfigurations(void) { + return base::TypedConfigurations( + ELPP->registeredLoggers()->defaultConfigurations(), + ELPP->registeredLoggers()->logStreamsReference()); +} + +std::vector* Loggers::populateAllLoggerIds(std::vector* targetList) { + targetList->clear(); + for (base::RegisteredLoggers::iterator it = ELPP->registeredLoggers()->list().begin(); + it != ELPP->registeredLoggers()->list().end(); ++it) { + targetList->push_back(it->first); + } + return targetList; +} + +void Loggers::configureFromGlobal(const char* globalConfigurationFilePath) { + std::ifstream gcfStream(globalConfigurationFilePath, std::ifstream::in); + ELPP_ASSERT(gcfStream.is_open(), "Unable to open global configuration file [" << globalConfigurationFilePath + << "] for parsing."); + std::string line = std::string(); + std::stringstream ss; + Logger* logger = nullptr; + auto configure = [&](void) { + ELPP_INTERNAL_INFO(8, "Configuring logger: '" << logger->id() << "' with configurations \n" << ss.str() + << "\n--------------"); + Configurations c; + c.parseFromText(ss.str()); + logger->configure(c); + }; + while (gcfStream.good()) { + std::getline(gcfStream, line); + ELPP_INTERNAL_INFO(1, "Parsing line: " << line); + base::utils::Str::trim(line); + if (Configurations::Parser::isComment(line)) continue; + Configurations::Parser::ignoreComments(&line); + base::utils::Str::trim(line); + if (line.size() > 2 && base::utils::Str::startsWith(line, std::string(base::consts::kConfigurationLoggerId))) { + if (!ss.str().empty() && logger != nullptr) { + configure(); + } + ss.str(std::string("")); + line = line.substr(2); + base::utils::Str::trim(line); + if (line.size() > 1) { + ELPP_INTERNAL_INFO(1, "Getting logger: '" << line << "'"); + logger = getLogger(line); + } + } else { + ss << line << "\n"; + } + } + if (!ss.str().empty() && logger != nullptr) { + configure(); + } +} + +bool Loggers::configureFromArg(const char* argKey) { +#if defined(ELPP_DISABLE_CONFIGURATION_FROM_PROGRAM_ARGS) + ELPP_UNUSED(argKey); +#else + if (!Helpers::commandLineArgs()->hasParamWithValue(argKey)) { + return false; + } + configureFromGlobal(Helpers::commandLineArgs()->getParamValue(argKey)); +#endif // defined(ELPP_DISABLE_CONFIGURATION_FROM_PROGRAM_ARGS) + return true; +} + +void Loggers::flushAll(void) { + ELPP->registeredLoggers()->flushAll(); +} + +void Loggers::setVerboseLevel(base::type::VerboseLevel level) { + ELPP->vRegistry()->setLevel(level); +} + +base::type::VerboseLevel Loggers::verboseLevel(void) { + return ELPP->vRegistry()->level(); +} + +void Loggers::setVModules(const char* modules) { + if (ELPP->vRegistry()->vModulesEnabled()) { + ELPP->vRegistry()->setModules(modules); + } +} + +void Loggers::clearVModules(void) { + ELPP->vRegistry()->clearModules(); +} + +// VersionInfo + +const std::string VersionInfo::version(void) { + return std::string("9.94.2"); +} +/// @brief Release date of current version +const std::string VersionInfo::releaseDate(void) { + return std::string("12-04-2017 1621hrs"); +} + +} // namespace el diff --git a/libdevcore/easylogging++.h b/libdevcore/easylogging++.h new file mode 100644 index 0000000000..fafcc356d6 --- /dev/null +++ b/libdevcore/easylogging++.h @@ -0,0 +1,4594 @@ +// +// Bismillah ar-Rahmaan ar-Raheem +// +// Easylogging++ v9.94.2 +// Single-header only, cross-platform logging library for C++ applications +// +// Copyright (c) 2017 muflihun.com +// +// This library is released under the MIT Licence. +// http://labs.muflihun.com/easyloggingpp/licence.php +// +// https://github.com/muflihun/easyloggingpp +// https://muflihun.github.io/easyloggingpp +// http://muflihun.com +// +#ifndef EASYLOGGINGPP_H +#define EASYLOGGINGPP_H +// Compilers and C++0x/C++11 Evaluation +#if __cplusplus >= 201103L +# define ELPP_CXX11 1 +#endif // __cplusplus >= 201103L +#if (defined(__GNUC__)) +# define ELPP_COMPILER_GCC 1 +#else +# define ELPP_COMPILER_GCC 0 +#endif +#if ELPP_COMPILER_GCC +# define ELPP_GCC_VERSION (__GNUC__ * 10000 \ ++ __GNUC_MINOR__ * 100 \ ++ __GNUC_PATCHLEVEL__) +# if defined(__GXX_EXPERIMENTAL_CXX0X__) +# define ELPP_CXX0X 1 +# endif +#endif +// Visual C++ +#if defined(_MSC_VER) +# define ELPP_COMPILER_MSVC 1 +#else +# define ELPP_COMPILER_MSVC 0 +#endif +#define ELPP_CRT_DBG_WARNINGS ELPP_COMPILER_MSVC +#if ELPP_COMPILER_MSVC +# if (_MSC_VER == 1600) +# define ELPP_CXX0X 1 +# elif(_MSC_VER >= 1700) +# define ELPP_CXX11 1 +# endif +#endif +// Clang++ +#if (defined(__clang__) && (__clang__ == 1)) +# define ELPP_COMPILER_CLANG 1 +#else +# define ELPP_COMPILER_CLANG 0 +#endif +#if ELPP_COMPILER_CLANG +# if __has_include() +# include // Make __GLIBCXX__ defined when using libstdc++ +# if !defined(__GLIBCXX__) || __GLIBCXX__ >= 20150426 +# define ELPP_CLANG_SUPPORTS_THREAD +# endif // !defined(__GLIBCXX__) || __GLIBCXX__ >= 20150426 +# endif // __has_include() +#endif +#if (defined(__MINGW32__) || defined(__MINGW64__)) +# define ELPP_MINGW 1 +#else +# define ELPP_MINGW 0 +#endif +#if (defined(__CYGWIN__) && (__CYGWIN__ == 1)) +# define ELPP_CYGWIN 1 +#else +# define ELPP_CYGWIN 0 +#endif +#if (defined(__INTEL_COMPILER)) +# define ELPP_COMPILER_INTEL 1 +#else +# define ELPP_COMPILER_INTEL 0 +#endif +// Operating System Evaluation +// Windows +#if (defined(_WIN32) || defined(_WIN64)) +# define ELPP_OS_WINDOWS 1 +#else +# define ELPP_OS_WINDOWS 0 +#endif +// Linux +#if (defined(__linux) || defined(__linux__)) +# define ELPP_OS_LINUX 1 +#else +# define ELPP_OS_LINUX 0 +#endif +#if (defined(__APPLE__)) +# define ELPP_OS_MAC 1 +#else +# define ELPP_OS_MAC 0 +#endif +#if (defined(__FreeBSD__)) +# define ELPP_OS_FREEBSD 1 +#else +# define ELPP_OS_FREEBSD 0 +#endif +#if (defined(__sun)) +# define ELPP_OS_SOLARIS 1 +#else +# define ELPP_OS_SOLARIS 0 +#endif +// Unix +#if ((ELPP_OS_LINUX || ELPP_OS_MAC || ELPP_OS_FREEBSD || ELPP_OS_SOLARIS) && (!ELPP_OS_WINDOWS)) +# define ELPP_OS_UNIX 1 +#else +# define ELPP_OS_UNIX 0 +#endif +#if (defined(__ANDROID__)) +# define ELPP_OS_ANDROID 1 +#else +# define ELPP_OS_ANDROID 0 +#endif +// Evaluating Cygwin as *nix OS +#if !ELPP_OS_UNIX && !ELPP_OS_WINDOWS && ELPP_CYGWIN +# undef ELPP_OS_UNIX +# undef ELPP_OS_LINUX +# define ELPP_OS_UNIX 1 +# define ELPP_OS_LINUX 1 +#endif // !ELPP_OS_UNIX && !ELPP_OS_WINDOWS && ELPP_CYGWIN +#if !defined(ELPP_INTERNAL_DEBUGGING_OUT_INFO) +# define ELPP_INTERNAL_DEBUGGING_OUT_INFO std::cout +#endif // !defined(ELPP_INTERNAL_DEBUGGING_OUT) +#if !defined(ELPP_INTERNAL_DEBUGGING_OUT_ERROR) +# define ELPP_INTERNAL_DEBUGGING_OUT_ERROR std::cerr +#endif // !defined(ELPP_INTERNAL_DEBUGGING_OUT) +#if !defined(ELPP_INTERNAL_DEBUGGING_ENDL) +# define ELPP_INTERNAL_DEBUGGING_ENDL std::endl +#endif // !defined(ELPP_INTERNAL_DEBUGGING_OUT) +#if !defined(ELPP_INTERNAL_DEBUGGING_MSG) +# define ELPP_INTERNAL_DEBUGGING_MSG(msg) msg +#endif // !defined(ELPP_INTERNAL_DEBUGGING_OUT) +// Internal Assertions and errors +#if !defined(ELPP_DISABLE_ASSERT) +# if (defined(ELPP_DEBUG_ASSERT_FAILURE)) +# define ELPP_ASSERT(expr, msg) if (!(expr)) { \ +std::stringstream internalInfoStream; internalInfoStream << msg; \ +ELPP_INTERNAL_DEBUGGING_OUT_ERROR \ +<< "EASYLOGGING++ ASSERTION FAILED (LINE: " << __LINE__ << ") [" #expr << "] WITH MESSAGE \"" \ +<< ELPP_INTERNAL_DEBUGGING_MSG(internalInfoStream.str()) << "\"" << ELPP_INTERNAL_DEBUGGING_ENDL; base::utils::abort(1, \ +"ELPP Assertion failure, please define ELPP_DEBUG_ASSERT_FAILURE"); } +# else +# define ELPP_ASSERT(expr, msg) if (!(expr)) { \ +std::stringstream internalInfoStream; internalInfoStream << msg; \ +ELPP_INTERNAL_DEBUGGING_OUT_ERROR\ +<< "ASSERTION FAILURE FROM EASYLOGGING++ (LINE: " \ +<< __LINE__ << ") [" #expr << "] WITH MESSAGE \"" << ELPP_INTERNAL_DEBUGGING_MSG(internalInfoStream.str()) << "\"" \ +<< ELPP_INTERNAL_DEBUGGING_ENDL; } +# endif // (defined(ELPP_DEBUG_ASSERT_FAILURE)) +#else +# define ELPP_ASSERT(x, y) +#endif //(!defined(ELPP_DISABLE_ASSERT) +#if ELPP_COMPILER_MSVC +# define ELPP_INTERNAL_DEBUGGING_WRITE_PERROR \ +{ char buff[256]; strerror_s(buff, 256, errno); \ +ELPP_INTERNAL_DEBUGGING_OUT_ERROR << ": " << buff << " [" << errno << "]";} (void)0 +#else +# define ELPP_INTERNAL_DEBUGGING_WRITE_PERROR \ +ELPP_INTERNAL_DEBUGGING_OUT_ERROR << ": " << strerror(errno) << " [" << errno << "]"; (void)0 +#endif // ELPP_COMPILER_MSVC +#if defined(ELPP_DEBUG_ERRORS) +# if !defined(ELPP_INTERNAL_ERROR) +# define ELPP_INTERNAL_ERROR(msg, pe) { \ +std::stringstream internalInfoStream; internalInfoStream << " " << msg; \ +ELPP_INTERNAL_DEBUGGING_OUT_ERROR \ +<< "ERROR FROM EASYLOGGING++ (LINE: " << __LINE__ << ") " \ +<< ELPP_INTERNAL_DEBUGGING_MSG(internalInfoStream.str()) << ELPP_INTERNAL_DEBUGGING_ENDL; \ +if (pe) { ELPP_INTERNAL_DEBUGGING_OUT_ERROR << " "; ELPP_INTERNAL_DEBUGGING_WRITE_PERROR; }} (void)0 +# endif +#else +# undef ELPP_INTERNAL_INFO +# define ELPP_INTERNAL_ERROR(msg, pe) +#endif // defined(ELPP_DEBUG_ERRORS) +#if (defined(ELPP_DEBUG_INFO)) +# if !(defined(ELPP_INTERNAL_INFO_LEVEL)) +# define ELPP_INTERNAL_INFO_LEVEL 9 +# endif // !(defined(ELPP_INTERNAL_INFO_LEVEL)) +# if !defined(ELPP_INTERNAL_INFO) +# define ELPP_INTERNAL_INFO(lvl, msg) { if (lvl <= ELPP_INTERNAL_INFO_LEVEL) { \ +std::stringstream internalInfoStream; internalInfoStream << " " << msg; \ +ELPP_INTERNAL_DEBUGGING_OUT_INFO << ELPP_INTERNAL_DEBUGGING_MSG(internalInfoStream.str()) \ +<< ELPP_INTERNAL_DEBUGGING_ENDL; }} +# endif +#else +# undef ELPP_INTERNAL_INFO +# define ELPP_INTERNAL_INFO(lvl, msg) +#endif // (defined(ELPP_DEBUG_INFO)) +#if (defined(ELPP_FEATURE_ALL)) || (defined(ELPP_FEATURE_CRASH_LOG)) +# if (ELPP_COMPILER_GCC && !ELPP_MINGW && !ELPP_OS_ANDROID) +# define ELPP_STACKTRACE 1 +# else +# if ELPP_COMPILER_MSVC +# pragma message("Stack trace not available for this compiler") +# else +# warning "Stack trace not available for this compiler"; +# endif // ELPP_COMPILER_MSVC +# define ELPP_STACKTRACE 0 +# endif // ELPP_COMPILER_GCC +#else +# define ELPP_STACKTRACE 0 +#endif // (defined(ELPP_FEATURE_ALL)) || (defined(ELPP_FEATURE_CRASH_LOG)) +// Miscellaneous macros +#define ELPP_UNUSED(x) (void)x +#if ELPP_OS_UNIX +// Log file permissions for unix-based systems +# define ELPP_LOG_PERMS S_IRUSR | S_IWUSR | S_IXUSR | S_IWGRP | S_IRGRP | S_IXGRP | S_IWOTH | S_IXOTH +#endif // ELPP_OS_UNIX +#if defined(ELPP_AS_DLL) && ELPP_COMPILER_MSVC +# if defined(ELPP_EXPORT_SYMBOLS) +# define ELPP_EXPORT __declspec(dllexport) +# else +# define ELPP_EXPORT __declspec(dllimport) +# endif // defined(ELPP_EXPORT_SYMBOLS) +#else +# define ELPP_EXPORT +#endif // defined(ELPP_AS_DLL) && ELPP_COMPILER_MSVC +// Some special functions that are VC++ specific +#undef STRTOK +#undef STRERROR +#undef STRCAT +#undef STRCPY +#if ELPP_CRT_DBG_WARNINGS +# define STRTOK(a, b, c) strtok_s(a, b, c) +# define STRERROR(a, b, c) strerror_s(a, b, c) +# define STRCAT(a, b, len) strcat_s(a, len, b) +# define STRCPY(a, b, len) strcpy_s(a, len, b) +#else +# define STRTOK(a, b, c) strtok(a, b) +# define STRERROR(a, b, c) strerror(c) +# define STRCAT(a, b, len) strcat(a, b) +# define STRCPY(a, b, len) strcpy(a, b) +#endif +// Compiler specific support evaluations +#if (ELPP_MINGW && !defined(ELPP_FORCE_USE_STD_THREAD)) +# define ELPP_USE_STD_THREADING 0 +#else +# if ((ELPP_COMPILER_CLANG && defined(ELPP_CLANG_SUPPORTS_THREAD)) || \ + (!ELPP_COMPILER_CLANG && defined(ELPP_CXX11)) || \ + defined(ELPP_FORCE_USE_STD_THREAD)) +# define ELPP_USE_STD_THREADING 1 +# else +# define ELPP_USE_STD_THREADING 0 +# endif +#endif +#undef ELPP_FINAL +#if ELPP_COMPILER_INTEL || (ELPP_GCC_VERSION < 40702) +# define ELPP_FINAL +#else +# define ELPP_FINAL final +#endif // ELPP_COMPILER_INTEL || (ELPP_GCC_VERSION < 40702) +#if defined(ELPP_EXPERIMENTAL_ASYNC) +# define ELPP_ASYNC_LOGGING 1 +#else +# define ELPP_ASYNC_LOGGING 0 +#endif // defined(ELPP_EXPERIMENTAL_ASYNC) +#if defined(ELPP_THREAD_SAFE) || ELPP_ASYNC_LOGGING +# define ELPP_THREADING_ENABLED 1 +#else +# define ELPP_THREADING_ENABLED 0 +#endif // defined(ELPP_THREAD_SAFE) || ELPP_ASYNC_LOGGING +// Function macro ELPP_FUNC +#undef ELPP_FUNC +#if ELPP_COMPILER_MSVC // Visual C++ +# define ELPP_FUNC __FUNCSIG__ +#elif ELPP_COMPILER_GCC // GCC +# define ELPP_FUNC __PRETTY_FUNCTION__ +#elif ELPP_COMPILER_INTEL // Intel C++ +# define ELPP_FUNC __PRETTY_FUNCTION__ +#elif ELPP_COMPILER_CLANG // Clang++ +# define ELPP_FUNC __PRETTY_FUNCTION__ +#else +# if defined(__func__) +# define ELPP_FUNC __func__ +# else +# define ELPP_FUNC "" +# endif // defined(__func__) +#endif // defined(_MSC_VER) +#undef ELPP_VARIADIC_TEMPLATES_SUPPORTED +// Keep following line commented until features are fixed +#define ELPP_VARIADIC_TEMPLATES_SUPPORTED \ +(ELPP_COMPILER_GCC || ELPP_COMPILER_CLANG || ELPP_COMPILER_INTEL || (ELPP_COMPILER_MSVC && _MSC_VER >= 1800)) +// Logging Enable/Disable macros +#if defined(ELPP_DISABLE_LOGS) +#define ELPP_LOGGING_ENABLED 0 +#else +#define ELPP_LOGGING_ENABLED 1 +#endif +#if (!defined(ELPP_DISABLE_DEBUG_LOGS) && (ELPP_LOGGING_ENABLED) && ((defined(_DEBUG)) || (!defined(NDEBUG)))) +# define ELPP_DEBUG_LOG 1 +#else +# define ELPP_DEBUG_LOG 0 +#endif // (!defined(ELPP_DISABLE_DEBUG_LOGS) && (ELPP_LOGGING_ENABLED) && ((defined(_DEBUG)) || (!defined(NDEBUG)))) +#if (!defined(ELPP_DISABLE_INFO_LOGS) && (ELPP_LOGGING_ENABLED)) +# define ELPP_INFO_LOG 1 +#else +# define ELPP_INFO_LOG 0 +#endif // (!defined(ELPP_DISABLE_INFO_LOGS) && (ELPP_LOGGING_ENABLED)) +#if (!defined(ELPP_DISABLE_WARNING_LOGS) && (ELPP_LOGGING_ENABLED)) +# define ELPP_WARNING_LOG 1 +#else +# define ELPP_WARNING_LOG 0 +#endif // (!defined(ELPP_DISABLE_WARNING_LOGS) && (ELPP_LOGGING_ENABLED)) +#if (!defined(ELPP_DISABLE_ERROR_LOGS) && (ELPP_LOGGING_ENABLED)) +# define ELPP_ERROR_LOG 1 +#else +# define ELPP_ERROR_LOG 0 +#endif // (!defined(ELPP_DISABLE_ERROR_LOGS) && (ELPP_LOGGING_ENABLED)) +#if (!defined(ELPP_DISABLE_FATAL_LOGS) && (ELPP_LOGGING_ENABLED)) +# define ELPP_FATAL_LOG 1 +#else +# define ELPP_FATAL_LOG 0 +#endif // (!defined(ELPP_DISABLE_FATAL_LOGS) && (ELPP_LOGGING_ENABLED)) +#if (!defined(ELPP_DISABLE_TRACE_LOGS) && (ELPP_LOGGING_ENABLED)) +# define ELPP_TRACE_LOG 1 +#else +# define ELPP_TRACE_LOG 0 +#endif // (!defined(ELPP_DISABLE_TRACE_LOGS) && (ELPP_LOGGING_ENABLED)) +#if (!defined(ELPP_DISABLE_VERBOSE_LOGS) && (ELPP_LOGGING_ENABLED)) +# define ELPP_VERBOSE_LOG 1 +#else +# define ELPP_VERBOSE_LOG 0 +#endif // (!defined(ELPP_DISABLE_VERBOSE_LOGS) && (ELPP_LOGGING_ENABLED)) +#if (!(ELPP_CXX0X || ELPP_CXX11)) +# error "C++0x (or higher) support not detected! (Is `-std=c++11' missing?)" +#endif // (!(ELPP_CXX0X || ELPP_CXX11)) +// Headers +#if defined(ELPP_SYSLOG) +# include +#endif // defined(ELPP_SYSLOG) +#include +#include +#include +#include +#include +#include +#include +#include +#if defined(ELPP_UNICODE) +# include +# if ELPP_OS_WINDOWS +# include +# endif // ELPP_OS_WINDOWS +#endif // defined(ELPP_UNICODE) +#if ELPP_STACKTRACE +# include +# include +#endif // ELPP_STACKTRACE +#if ELPP_OS_ANDROID +# include +#endif // ELPP_OS_ANDROID +#if ELPP_OS_UNIX +# include +# include +#elif ELPP_OS_WINDOWS +# include +# include +# if defined(WIN32_LEAN_AND_MEAN) +# if defined(ELPP_WINSOCK2) +# include +# else +# include +# endif // defined(ELPP_WINSOCK2) +# endif // defined(WIN32_LEAN_AND_MEAN) +#endif // ELPP_OS_UNIX +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if ELPP_THREADING_ENABLED +# if ELPP_USE_STD_THREADING +# include +# include +# else +# if ELPP_OS_UNIX +# include +# endif // ELPP_OS_UNIX +# endif // ELPP_USE_STD_THREADING +#endif // ELPP_THREADING_ENABLED +#if ELPP_ASYNC_LOGGING +# if defined(ELPP_NO_SLEEP_FOR) +# include +# endif // defined(ELPP_NO_SLEEP_FOR) +# include +# include +# include +#endif // ELPP_ASYNC_LOGGING +#if defined(ELPP_STL_LOGGING) +// For logging STL based templates +# include +# include +# include +# include +# include +# include +# if defined(ELPP_LOG_STD_ARRAY) +# include +# endif // defined(ELPP_LOG_STD_ARRAY) +# if defined(ELPP_LOG_UNORDERED_MAP) +# include +# endif // defined(ELPP_LOG_UNORDERED_MAP) +# if defined(ELPP_LOG_UNORDERED_SET) +# include +# endif // defined(ELPP_UNORDERED_SET) +#endif // defined(ELPP_STL_LOGGING) +#if defined(ELPP_QT_LOGGING) +// For logging Qt based classes & templates +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +#endif // defined(ELPP_QT_LOGGING) +#if defined(ELPP_BOOST_LOGGING) +// For logging boost based classes & templates +# include +# include +# include +# include +# include +# include +# include +# include +#endif // defined(ELPP_BOOST_LOGGING) +#if defined(ELPP_WXWIDGETS_LOGGING) +// For logging wxWidgets based classes & templates +# include +#endif // defined(ELPP_WXWIDGETS_LOGGING) +#if defined(ELPP_UTC_DATETIME) +# define elpptime_r gmtime_r +# define elpptime_s gmtime_s +# define elpptime gmtime +#else +# define elpptime_r localtime_r +# define elpptime_s localtime_s +# define elpptime localtime +#endif // defined(ELPP_UTC_DATETIME) +// Forward declarations +namespace el { +class Logger; +class LogMessage; +class PerformanceTrackingData; +class Loggers; +class Helpers; +template class Callback; +class LogDispatchCallback; +class PerformanceTrackingCallback; +class LoggerRegistrationCallback; +class LogDispatchData; +namespace base { +class Storage; +class RegisteredLoggers; +class PerformanceTracker; +class MessageBuilder; +class Writer; +class PErrorWriter; +class LogDispatcher; +class DefaultLogBuilder; +class DefaultLogDispatchCallback; +#if ELPP_ASYNC_LOGGING +class AsyncLogDispatchCallback; +class AsyncDispatchWorker; +#endif // ELPP_ASYNC_LOGGING +class DefaultPerformanceTrackingCallback; +} // namespace base +} // namespace el +/// @brief Easylogging++ entry namespace +namespace el { +/// @brief Namespace containing base/internal functionality used by Easylogging++ +namespace base { +/// @brief Data types used by Easylogging++ +namespace type { +#undef ELPP_LITERAL +#undef ELPP_STRLEN +#undef ELPP_COUT +#if defined(ELPP_UNICODE) +# define ELPP_LITERAL(txt) L##txt +# define ELPP_STRLEN wcslen +# if defined ELPP_CUSTOM_COUT +# define ELPP_COUT ELPP_CUSTOM_COUT +# else +# define ELPP_COUT std::wcout +# endif // defined ELPP_CUSTOM_COUT +typedef wchar_t char_t; +typedef std::wstring string_t; +typedef std::wstringstream stringstream_t; +typedef std::wfstream fstream_t; +typedef std::wostream ostream_t; +#else +# define ELPP_LITERAL(txt) txt +# define ELPP_STRLEN strlen +# if defined ELPP_CUSTOM_COUT +# define ELPP_COUT ELPP_CUSTOM_COUT +# else +# define ELPP_COUT std::cout +# endif // defined ELPP_CUSTOM_COUT +typedef char char_t; +typedef std::string string_t; +typedef std::stringstream stringstream_t; +typedef std::fstream fstream_t; +typedef std::ostream ostream_t; +#endif // defined(ELPP_UNICODE) +#if defined(ELPP_CUSTOM_COUT_LINE) +# define ELPP_COUT_LINE(logLine) ELPP_CUSTOM_COUT_LINE(logLine) +#else +# define ELPP_COUT_LINE(logLine) logLine << std::flush +#endif // defined(ELPP_CUSTOM_COUT_LINE) +typedef unsigned int EnumType; +typedef unsigned short VerboseLevel; +typedef unsigned long int LineNumber; +typedef std::shared_ptr StoragePointer; +typedef std::shared_ptr LogDispatchCallbackPtr; +typedef std::shared_ptr PerformanceTrackingCallbackPtr; +typedef std::shared_ptr LoggerRegistrationCallbackPtr; +typedef std::unique_ptr PerformanceTrackerPtr; +} // namespace type +/// @brief Internal helper class that prevent copy constructor for class +/// +/// @detail When using this class simply inherit it privately +class NoCopy { + protected: + NoCopy(void) {} + private: + NoCopy(const NoCopy&); + NoCopy& operator=(const NoCopy&); +}; +/// @brief Internal helper class that makes all default constructors private. +/// +/// @detail This prevents initializing class making it static unless an explicit constructor is declared. +/// When using this class simply inherit it privately +class StaticClass { + private: + StaticClass(void); + StaticClass(const StaticClass&); + StaticClass& operator=(const StaticClass&); +}; +} // namespace base +/// @brief Represents enumeration for severity level used to determine level of logging +/// +/// @detail With Easylogging++, developers may disable or enable any level regardless of +/// what the severity is. Or they can choose to log using hierarchical logging flag +enum class Level : base::type::EnumType { + /// @brief Generic level that represents all the levels. Useful when setting global configuration for all levels + Global = 1, + /// @brief Information that can be useful to back-trace certain events - mostly useful than debug logs. + Trace = 2, + /// @brief Informational events most useful for developers to debug application + Debug = 4, + /// @brief Severe error information that will presumably abort application + Fatal = 8, + /// @brief Information representing errors in application but application will keep running + Error = 16, + /// @brief Useful when application has potentially harmful situtaions + Warning = 32, + /// @brief Information that can be highly useful and vary with verbose logging level. + Verbose = 64, + /// @brief Mainly useful to represent current progress of application + Info = 128, + /// @brief Represents unknown level + Unknown = 1010 +}; +/// @brief Static class that contains helper functions for el::Level +class LevelHelper : base::StaticClass { + public: + /// @brief Represents minimum valid level. Useful when iterating through enum. + static const base::type::EnumType kMinValid = static_cast(Level::Trace); + /// @brief Represents maximum valid level. This is used internally and you should not need it. + static const base::type::EnumType kMaxValid = static_cast(Level::Info); + /// @brief Casts level to int, useful for iterating through enum. + static base::type::EnumType castToInt(Level level) { + return static_cast(level); + } + /// @brief Casts int(ushort) to level, useful for iterating through enum. + static Level castFromInt(base::type::EnumType l) { + return static_cast(l); + } + /// @brief Converts level to associated const char* + /// @return Upper case string based level. + static const char* convertToString(Level level); + /// @brief Converts from levelStr to Level + /// @param levelStr Upper case string based level. + /// Lower case is also valid but providing upper case is recommended. + static Level convertFromString(const char* levelStr); + /// @brief Applies specified function to each level starting from startIndex + /// @param startIndex initial value to start the iteration from. This is passed as pointer and + /// is left-shifted so this can be used inside function (fn) to represent current level. + /// @param fn function to apply with each level. This bool represent whether or not to stop iterating through levels. + static void forEachLevel(base::type::EnumType* startIndex, const std::function& fn); +}; +/// @brief Represents enumeration of ConfigurationType used to configure or access certain aspect +/// of logging +enum class ConfigurationType : base::type::EnumType { + /// @brief Determines whether or not corresponding level and logger of logging is enabled + /// You may disable all logs by using el::Level::Global + Enabled = 1, + /// @brief Whether or not to write corresponding log to log file + ToFile = 2, + /// @brief Whether or not to write corresponding level and logger log to standard output. + /// By standard output meaning termnal, command prompt etc + ToStandardOutput = 4, + /// @brief Determines format of logging corresponding level and logger. + Format = 8, + /// @brief Determines log file (full path) to write logs to for correponding level and logger + Filename = 16, + /// @brief Specifies precision of the subsecond part. It should be within range (1-6). + SubsecondPrecision = 32, + /// @brief Alias of SubsecondPrecision (for backward compatibility) + MillisecondsWidth = SubsecondPrecision, + /// @brief Determines whether or not performance tracking is enabled. + /// + /// @detail This does not depend on logger or level. Performance tracking always uses 'performance' logger + PerformanceTracking = 64, + /// @brief Specifies log file max size. + /// + /// @detail If file size of corresponding log file (for corresponding level) is >= specified size, log file will + /// be truncated and re-initiated. + MaxLogFileSize = 128, + /// @brief Specifies number of log entries to hold until we flush pending log data + LogFlushThreshold = 256, + /// @brief Represents unknown configuration + Unknown = 1010 +}; +/// @brief Static class that contains helper functions for el::ConfigurationType +class ConfigurationTypeHelper : base::StaticClass { + public: + /// @brief Represents minimum valid configuration type. Useful when iterating through enum. + static const base::type::EnumType kMinValid = static_cast(ConfigurationType::Enabled); + /// @brief Represents maximum valid configuration type. This is used internally and you should not need it. + static const base::type::EnumType kMaxValid = static_cast(ConfigurationType::MaxLogFileSize); + /// @brief Casts configuration type to int, useful for iterating through enum. + static base::type::EnumType castToInt(ConfigurationType configurationType) { + return static_cast(configurationType); + } + /// @brief Casts int(ushort) to configurationt type, useful for iterating through enum. + static ConfigurationType castFromInt(base::type::EnumType c) { + return static_cast(c); + } + /// @brief Converts configuration type to associated const char* + /// @returns Upper case string based configuration type. + static const char* convertToString(ConfigurationType configurationType); + /// @brief Converts from configStr to ConfigurationType + /// @param configStr Upper case string based configuration type. + /// Lower case is also valid but providing upper case is recommended. + static ConfigurationType convertFromString(const char* configStr); + /// @brief Applies specified function to each configuration type starting from startIndex + /// @param startIndex initial value to start the iteration from. This is passed by pointer and is left-shifted + /// so this can be used inside function (fn) to represent current configuration type. + /// @param fn function to apply with each configuration type. + /// This bool represent whether or not to stop iterating through configurations. + static inline void forEachConfigType(base::type::EnumType* startIndex, const std::function& fn); +}; +/// @brief Flags used while writing logs. This flags are set by user +enum class LoggingFlag : base::type::EnumType { + /// @brief Makes sure we have new line for each container log entry + NewLineForContainer = 1, + /// @brief Makes sure if -vmodule is used and does not specifies a module, then verbose + /// logging is allowed via that module. + AllowVerboseIfModuleNotSpecified = 2, + /// @brief When handling crashes by default, detailed crash reason will be logged as well + LogDetailedCrashReason = 4, + /// @brief Allows to disable application abortion when logged using FATAL level + DisableApplicationAbortOnFatalLog = 8, + /// @brief Flushes log with every log-entry (performance sensative) - Disabled by default + ImmediateFlush = 16, + /// @brief Enables strict file rolling + StrictLogFileSizeCheck = 32, + /// @brief Make terminal output colorful for supported terminals + ColoredTerminalOutput = 64, + /// @brief Supports use of multiple logging in same macro, e.g, CLOG(INFO, "default", "network") + MultiLoggerSupport = 128, + /// @brief Disables comparing performance tracker's checkpoints + DisablePerformanceTrackingCheckpointComparison = 256, + /// @brief Disable VModules + DisableVModules = 512, + /// @brief Disable VModules extensions + DisableVModulesExtensions = 1024, + /// @brief Enables hierarchical logging + HierarchicalLogging = 2048, + /// @brief Creates logger automatically when not available + CreateLoggerAutomatically = 4096, + /// @brief Adds spaces b/w logs that separated by left-shift operator + AutoSpacing = 8192, + /// @brief Preserves time format and does not convert it to sec, hour etc (performance tracking only) + FixedTimeFormat = 16384 +}; +namespace base { +/// @brief Namespace containing constants used internally. +namespace consts { +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-variable" +#endif +// Level log values - These are values that are replaced in place of %level format specifier +// Extra spaces after format specifiers are only for readability purposes in log files +static const base::type::char_t* kInfoLevelLogValue = ELPP_LITERAL("INFO"); +static const base::type::char_t* kDebugLevelLogValue = ELPP_LITERAL("DEBUG"); +static const base::type::char_t* kWarningLevelLogValue = ELPP_LITERAL("WARNING"); +static const base::type::char_t* kErrorLevelLogValue = ELPP_LITERAL("ERROR"); +static const base::type::char_t* kFatalLevelLogValue = ELPP_LITERAL("FATAL"); +static const base::type::char_t* kVerboseLevelLogValue = + ELPP_LITERAL("VERBOSE"); // will become VERBOSE-x where x = verbose level +static const base::type::char_t* kTraceLevelLogValue = ELPP_LITERAL("TRACE"); +static const base::type::char_t* kInfoLevelShortLogValue = ELPP_LITERAL("I"); +static const base::type::char_t* kDebugLevelShortLogValue = ELPP_LITERAL("D"); +static const base::type::char_t* kWarningLevelShortLogValue = ELPP_LITERAL("W"); +static const base::type::char_t* kErrorLevelShortLogValue = ELPP_LITERAL("E"); +static const base::type::char_t* kFatalLevelShortLogValue = ELPP_LITERAL("F"); +static const base::type::char_t* kVerboseLevelShortLogValue = ELPP_LITERAL("V"); +static const base::type::char_t* kTraceLevelShortLogValue = ELPP_LITERAL("T"); +// Format specifiers - These are used to define log format +static const base::type::char_t* kAppNameFormatSpecifier = ELPP_LITERAL("%app"); +static const base::type::char_t* kLoggerIdFormatSpecifier = ELPP_LITERAL("%logger"); +static const base::type::char_t* kThreadIdFormatSpecifier = ELPP_LITERAL("%thread"); +static const base::type::char_t* kSeverityLevelFormatSpecifier = ELPP_LITERAL("%level"); +static const base::type::char_t* kSeverityLevelShortFormatSpecifier = ELPP_LITERAL("%levshort"); +static const base::type::char_t* kDateTimeFormatSpecifier = ELPP_LITERAL("%datetime"); +static const base::type::char_t* kLogFileFormatSpecifier = ELPP_LITERAL("%file"); +static const base::type::char_t* kLogFileBaseFormatSpecifier = ELPP_LITERAL("%fbase"); +static const base::type::char_t* kLogLineFormatSpecifier = ELPP_LITERAL("%line"); +static const base::type::char_t* kLogLocationFormatSpecifier = ELPP_LITERAL("%loc"); +static const base::type::char_t* kLogFunctionFormatSpecifier = ELPP_LITERAL("%func"); +static const base::type::char_t* kCurrentUserFormatSpecifier = ELPP_LITERAL("%user"); +static const base::type::char_t* kCurrentHostFormatSpecifier = ELPP_LITERAL("%host"); +static const base::type::char_t* kMessageFormatSpecifier = ELPP_LITERAL("%msg"); +static const base::type::char_t* kVerboseLevelFormatSpecifier = ELPP_LITERAL("%vlevel"); +static const char* kDateTimeFormatSpecifierForFilename = "%datetime"; +// Date/time +static const char* kDays[7] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }; +static const char* kDaysAbbrev[7] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; +static const char* kMonths[12] = { "January", "February", "March", "Apri", "May", "June", "July", "August", + "September", "October", "November", "December" + }; +static const char* kMonthsAbbrev[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; +static const char* kDefaultDateTimeFormat = "%Y-%M-%d %H:%m:%s,%g"; +static const char* kDefaultDateTimeFormatInFilename = "%Y-%M-%d_%H-%m"; +static const int kYearBase = 1900; +static const char* kAm = "AM"; +static const char* kPm = "PM"; +// Miscellaneous constants +#ifdef ELPP_DEFAULT_LOGGER +static const char* kDefaultLoggerId = ELPP_DEFAULT_LOGGER; +#else +static const char* kDefaultLoggerId = "default"; +#endif +#ifdef ELPP_DEFAULT_PERFORMANCE_LOGGER +static const char* kPerformanceLoggerId = ELPP_DEFAULT_PERFORMANCE_LOGGER; +#else +static const char* kPerformanceLoggerId = "performance"; +#endif +#if defined(ELPP_SYSLOG) +static const char* kSysLogLoggerId = "syslog"; +#endif // defined(ELPP_SYSLOG) +static const char* kNullPointer = "nullptr"; +static const char kFormatSpecifierChar = '%'; +#if ELPP_VARIADIC_TEMPLATES_SUPPORTED +static const char kFormatSpecifierCharValue = 'v'; +#endif // ELPP_VARIADIC_TEMPLATES_SUPPORTED +static const unsigned int kMaxLogPerContainer = 100; +static const unsigned int kMaxLogPerCounter = 100000; +static const unsigned int kDefaultSubsecondPrecision = 3; +static const base::type::VerboseLevel kMaxVerboseLevel = 9; +static const char* kUnknownUser = "user"; +static const char* kUnknownHost = "unknown-host"; +#if defined(ELPP_DEFAULT_LOG_FILE) +static const char* kDefaultLogFile = ELPP_DEFAULT_LOG_FILE; +#else +# if ELPP_OS_UNIX +# if ELPP_OS_ANDROID +static const char* kDefaultLogFile = "logs/myeasylog.log"; +# else +static const char* kDefaultLogFile = "logs/myeasylog.log"; +# endif // ELPP_OS_ANDROID +# elif ELPP_OS_WINDOWS +static const char* kDefaultLogFile = "logs\\myeasylog.log"; +# endif // ELPP_OS_UNIX +#endif // defined(ELPP_DEFAULT_LOG_FILE) +#if !defined(ELPP_DISABLE_LOG_FILE_FROM_ARG) +static const char* kDefaultLogFileParam = "--default-log-file"; +#endif // !defined(ELPP_DISABLE_LOG_FILE_FROM_ARG) +#if defined(ELPP_LOGGING_FLAGS_FROM_ARG) +static const char* kLoggingFlagsParam = "--logging-flags"; +#endif // defined(ELPP_LOGGING_FLAGS_FROM_ARG) +#if ELPP_OS_WINDOWS +static const char* kFilePathSeperator = "\\"; +#else +static const char* kFilePathSeperator = "/"; +#endif // ELPP_OS_WINDOWS +static const char* kValidLoggerIdSymbols = + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._"; +static const char* kConfigurationComment = "##"; +static const char* kConfigurationLevel = "*"; +static const char* kConfigurationLoggerId = "--"; +static const std::size_t kSourceFilenameMaxLength = 100; +static const std::size_t kSourceLineMaxLength = 10; +static const Level kPerformanceTrackerDefaultLevel = Level::Info; +const struct { + double value; + const base::type::char_t* unit; +} kTimeFormats[] = { + { 1000.0f, ELPP_LITERAL("us") }, + { 1000.0f, ELPP_LITERAL("ms") }, + { 60.0f, ELPP_LITERAL("seconds") }, + { 60.0f, ELPP_LITERAL("minutes") }, + { 24.0f, ELPP_LITERAL("hours") }, + { 7.0f, ELPP_LITERAL("days") } +}; +static const int kTimeFormatsCount = sizeof(kTimeFormats) / sizeof(kTimeFormats[0]); +const struct { + int numb; + const char* name; + const char* brief; + const char* detail; +} kCrashSignals[] = { + // NOTE: Do not re-order, if you do please check CrashHandler(bool) constructor and CrashHandler::setHandler(..) + { + SIGABRT, "SIGABRT", "Abnormal termination", + "Program was abnormally terminated." + }, + { + SIGFPE, "SIGFPE", "Erroneous arithmetic operation", + "Arithemetic operation issue such as division by zero or operation resulting in overflow." + }, + { + SIGILL, "SIGILL", "Illegal instruction", + "Generally due to a corruption in the code or to an attempt to execute data." + }, + { + SIGSEGV, "SIGSEGV", "Invalid access to memory", + "Program is trying to read an invalid (unallocated, deleted or corrupted) or inaccessible memory." + }, + { + SIGINT, "SIGINT", "Interactive attention signal", + "Interruption generated (generally) by user or operating system." + }, +}; +static const int kCrashSignalsCount = sizeof(kCrashSignals) / sizeof(kCrashSignals[0]); +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic pop +#endif +} // namespace consts +} // namespace base +typedef std::function PreRollOutCallback; +namespace base { +static inline void defaultPreRollOutCallback(const char*, std::size_t) {} +/// @brief Enum to represent timestamp unit +enum class TimestampUnit : base::type::EnumType { + Microsecond = 0, Millisecond = 1, Second = 2, Minute = 3, Hour = 4, Day = 5 +}; +/// @brief Format flags used to determine specifiers that are active for performance improvements. +enum class FormatFlags : base::type::EnumType { + DateTime = 1 << 1, + LoggerId = 1 << 2, + File = 1 << 3, + Line = 1 << 4, + Location = 1 << 5, + Function = 1 << 6, + User = 1 << 7, + Host = 1 << 8, + LogMessage = 1 << 9, + VerboseLevel = 1 << 10, + AppName = 1 << 11, + ThreadId = 1 << 12, + Level = 1 << 13, + FileBase = 1 << 14, + LevelShort = 1 << 15 +}; +/// @brief A subsecond precision class containing actual width and offset of the subsecond part +class SubsecondPrecision { + public: + SubsecondPrecision(void) { + init(base::consts::kDefaultSubsecondPrecision); + } + explicit SubsecondPrecision(int width) { + init(width); + } + bool operator==(const SubsecondPrecision& ssPrec) { + return m_width == ssPrec.m_width && m_offset == ssPrec.m_offset; + } + int m_width; + unsigned int m_offset; + private: + void init(int width); +}; +/// @brief Type alias of SubsecondPrecision +typedef SubsecondPrecision MillisecondsWidth; +/// @brief Namespace containing utility functions/static classes used internally +namespace utils { +/// @brief Deletes memory safely and points to null +template +static +typename std::enable_if::value, void>::type +safeDelete(T*& pointer) { + if (pointer == nullptr) + return; + delete pointer; + pointer = nullptr; +} +/// @brief Bitwise operations for C++11 strong enum class. This casts e into Flag_T and returns value after bitwise operation +/// Use these function as
flag = bitwise::Or(MyEnum::val1, flag);
+namespace bitwise { +template +static inline base::type::EnumType And(Enum e, base::type::EnumType flag) { + return static_cast(flag) & static_cast(e); +} +template +static inline base::type::EnumType Not(Enum e, base::type::EnumType flag) { + return static_cast(flag) & ~(static_cast(e)); +} +template +static inline base::type::EnumType Or(Enum e, base::type::EnumType flag) { + return static_cast(flag) | static_cast(e); +} +} // namespace bitwise +template +static inline void addFlag(Enum e, base::type::EnumType* flag) { + *flag = base::utils::bitwise::Or(e, *flag); +} +template +static inline void removeFlag(Enum e, base::type::EnumType* flag) { + *flag = base::utils::bitwise::Not(e, *flag); +} +template +static inline bool hasFlag(Enum e, base::type::EnumType flag) { + return base::utils::bitwise::And(e, flag) > 0x0; +} +} // namespace utils +namespace threading { +#if ELPP_THREADING_ENABLED +# if !ELPP_USE_STD_THREADING +namespace internal { +/// @brief A mutex wrapper for compiler that dont yet support std::recursive_mutex +class Mutex : base::NoCopy { + public: + Mutex(void) { +# if ELPP_OS_UNIX + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&m_underlyingMutex, &attr); + pthread_mutexattr_destroy(&attr); +# elif ELPP_OS_WINDOWS + InitializeCriticalSection(&m_underlyingMutex); +# endif // ELPP_OS_UNIX + } + + virtual ~Mutex(void) { +# if ELPP_OS_UNIX + pthread_mutex_destroy(&m_underlyingMutex); +# elif ELPP_OS_WINDOWS + DeleteCriticalSection(&m_underlyingMutex); +# endif // ELPP_OS_UNIX + } + + inline void lock(void) { +# if ELPP_OS_UNIX + pthread_mutex_lock(&m_underlyingMutex); +# elif ELPP_OS_WINDOWS + EnterCriticalSection(&m_underlyingMutex); +# endif // ELPP_OS_UNIX + } + + inline bool try_lock(void) { +# if ELPP_OS_UNIX + return (pthread_mutex_trylock(&m_underlyingMutex) == 0); +# elif ELPP_OS_WINDOWS + return TryEnterCriticalSection(&m_underlyingMutex); +# endif // ELPP_OS_UNIX + } + + inline void unlock(void) { +# if ELPP_OS_UNIX + pthread_mutex_unlock(&m_underlyingMutex); +# elif ELPP_OS_WINDOWS + LeaveCriticalSection(&m_underlyingMutex); +# endif // ELPP_OS_UNIX + } + + private: +# if ELPP_OS_UNIX + pthread_mutex_t m_underlyingMutex; +# elif ELPP_OS_WINDOWS + CRITICAL_SECTION m_underlyingMutex; +# endif // ELPP_OS_UNIX +}; +/// @brief Scoped lock for compiler that dont yet support std::lock_guard +template +class ScopedLock : base::NoCopy { + public: + explicit ScopedLock(M& mutex) { + m_mutex = &mutex; + m_mutex->lock(); + } + + virtual ~ScopedLock(void) { + m_mutex->unlock(); + } + private: + M* m_mutex; + ScopedLock(void); +}; +} // namespace internal +typedef base::threading::internal::Mutex Mutex; +typedef base::threading::internal::ScopedLock ScopedLock; +# else +typedef std::recursive_mutex Mutex; +typedef std::lock_guard ScopedLock; +# endif // !ELPP_USE_STD_THREADING +#else +namespace internal { +/// @brief Mutex wrapper used when multi-threading is disabled. +class NoMutex : base::NoCopy { + public: + NoMutex(void) {} + inline void lock(void) {} + inline bool try_lock(void) { + return true; + } + inline void unlock(void) {} +}; +/// @brief Lock guard wrapper used when multi-threading is disabled. +template +class NoScopedLock : base::NoCopy { + public: + explicit NoScopedLock(Mutex&) { + } + virtual ~NoScopedLock(void) { + } + private: + NoScopedLock(void); +}; +} // namespace internal +typedef base::threading::internal::NoMutex Mutex; +typedef base::threading::internal::NoScopedLock ScopedLock; +#endif // ELPP_THREADING_ENABLED +/// @brief Base of thread safe class, this class is inheritable-only +class ThreadSafe { + public: + virtual inline void acquireLock(void) ELPP_FINAL { m_mutex.lock(); } + virtual inline void releaseLock(void) ELPP_FINAL { m_mutex.unlock(); } + virtual inline base::threading::Mutex& lock(void) ELPP_FINAL { return m_mutex; } + protected: + ThreadSafe(void) {} + virtual ~ThreadSafe(void) {} + private: + base::threading::Mutex m_mutex; +}; + +#if ELPP_THREADING_ENABLED +# if !ELPP_USE_STD_THREADING +/// @brief Gets ID of currently running threading in windows systems. On unix, nothing is returned. +static std::string getCurrentThreadId(void) { + std::stringstream ss; +# if (ELPP_OS_WINDOWS) + ss << GetCurrentThreadId(); +# endif // (ELPP_OS_WINDOWS) + return ss.str(); +} +# else +/// @brief Gets ID of currently running threading using std::this_thread::get_id() +static std::string getCurrentThreadId(void) { + std::stringstream ss; + ss << std::this_thread::get_id(); + return ss.str(); +} +# endif // !ELPP_USE_STD_THREADING +#else +static inline std::string getCurrentThreadId(void) { + return std::string(); +} +#endif // ELPP_THREADING_ENABLED +} // namespace threading +namespace utils { +class File : base::StaticClass { + public: + /// @brief Creates new out file stream for specified filename. + /// @return Pointer to newly created fstream or nullptr + static base::type::fstream_t* newFileStream(const std::string& filename); + + /// @brief Gets size of file provided in stream + static std::size_t getSizeOfFile(base::type::fstream_t* fs); + + /// @brief Determines whether or not provided path exist in current file system + static bool pathExists(const char* path, bool considerFile = false); + + /// @brief Creates specified path on file system + /// @param path Path to create. + static bool createPath(const std::string& path); + /// @brief Extracts path of filename with leading slash + static std::string extractPathFromFilename(const std::string& fullPath, + const char* seperator = base::consts::kFilePathSeperator); + /// @brief builds stripped filename and puts it in buff + static void buildStrippedFilename(const char* filename, char buff[], + std::size_t limit = base::consts::kSourceFilenameMaxLength); + /// @brief builds base filename and puts it in buff + static void buildBaseFilename(const std::string& fullPath, char buff[], + std::size_t limit = base::consts::kSourceFilenameMaxLength, + const char* seperator = base::consts::kFilePathSeperator); +}; +/// @brief String utilities helper class used internally. You should not use it. +class Str : base::StaticClass { + public: + /// @brief Checks if character is digit. Dont use libc implementation of it to prevent locale issues. + static inline bool isDigit(char c) { + return c >= '0' && c <= '9'; + } + + /// @brief Matches wildcards, '*' and '?' only supported. + static bool wildCardMatch(const char* str, const char* pattern); + + static std::string& ltrim(std::string& str); + static std::string& rtrim(std::string& str); + static std::string& trim(std::string& str); + + /// @brief Determines whether or not str starts with specified string + /// @param str String to check + /// @param start String to check against + /// @return Returns true if starts with specified string, false otherwise + static bool startsWith(const std::string& str, const std::string& start); + + /// @brief Determines whether or not str ends with specified string + /// @param str String to check + /// @param end String to check against + /// @return Returns true if ends with specified string, false otherwise + static bool endsWith(const std::string& str, const std::string& end); + + /// @brief Replaces all instances of replaceWhat with 'replaceWith'. Original variable is changed for performance. + /// @param [in,out] str String to replace from + /// @param replaceWhat Character to replace + /// @param replaceWith Character to replace with + /// @return Modified version of str + static std::string& replaceAll(std::string& str, char replaceWhat, char replaceWith); + + /// @brief Replaces all instances of 'replaceWhat' with 'replaceWith'. (String version) Replaces in place + /// @param str String to replace from + /// @param replaceWhat Character to replace + /// @param replaceWith Character to replace with + /// @return Modified (original) str + static std::string& replaceAll(std::string& str, const std::string& replaceWhat, + const std::string& replaceWith); + + static void replaceFirstWithEscape(base::type::string_t& str, const base::type::string_t& replaceWhat, + const base::type::string_t& replaceWith); +#if defined(ELPP_UNICODE) + static void replaceFirstWithEscape(base::type::string_t& str, const base::type::string_t& replaceWhat, + const std::string& replaceWith); +#endif // defined(ELPP_UNICODE) + /// @brief Converts string to uppercase + /// @param str String to convert + /// @return Uppercase string + static std::string& toUpper(std::string& str); + + /// @brief Compares cstring equality - uses strcmp + static bool cStringEq(const char* s1, const char* s2); + + /// @brief Compares cstring equality (case-insensitive) - uses toupper(char) + /// Dont use strcasecmp because of CRT (VC++) + static bool cStringCaseEq(const char* s1, const char* s2); + + /// @brief Returns true if c exist in str + static bool contains(const char* str, char c); + + static char* convertAndAddToBuff(std::size_t n, int len, char* buf, const char* bufLim, bool zeroPadded = true); + static char* addToBuff(const char* str, char* buf, const char* bufLim); + static char* clearBuff(char buff[], std::size_t lim); + + /// @brief Converst wchar* to char* + /// NOTE: Need to free return value after use! + static char* wcharPtrToCharPtr(const wchar_t* line); +}; +/// @brief Operating System helper static class used internally. You should not use it. +class OS : base::StaticClass { + public: +#if ELPP_OS_WINDOWS + /// @brief Gets environment variables for Windows based OS. + /// We are not using getenv(const char*) because of CRT deprecation + /// @param varname Variable name to get environment variable value for + /// @return If variable exist the value of it otherwise nullptr + static const char* getWindowsEnvironmentVariable(const char* varname); +#endif // ELPP_OS_WINDOWS +#if ELPP_OS_ANDROID + /// @brief Reads android property value + static std::string getProperty(const char* prop); + + /// @brief Reads android device name + static std::string getDeviceName(void); +#endif // ELPP_OS_ANDROID + + /// @brief Runs command on terminal and returns the output. + /// + /// @detail This is applicable only on unix based systems, for all other OS, an empty string is returned. + /// @param command Bash command + /// @return Result of bash output or empty string if no result found. + static const std::string getBashOutput(const char* command); + + /// @brief Gets environment variable. This is cross-platform and CRT safe (for VC++) + /// @param variableName Environment variable name + /// @param defaultVal If no environment variable or value found the value to return by default + /// @param alternativeBashCommand If environment variable not found what would be alternative bash command + /// in order to look for value user is looking for. E.g, for 'user' alternative command will 'whoami' + static std::string getEnvironmentVariable(const char* variableName, const char* defaultVal, + const char* alternativeBashCommand = nullptr); + /// @brief Gets current username. + static std::string currentUser(void); + + /// @brief Gets current host name or computer name. + /// + /// @detail For android systems this is device name with its manufacturer and model seperated by hyphen + static std::string currentHost(void); + /// @brief Whether or not terminal supports colors + static bool termSupportsColor(void); +}; +/// @brief Contains utilities for cross-platform date/time. This class make use of el::base::utils::Str +class DateTime : base::StaticClass { + public: + /// @brief Cross platform gettimeofday for Windows and unix platform. This can be used to determine current microsecond. + /// + /// @detail For unix system it uses gettimeofday(timeval*, timezone*) and for Windows, a seperate implementation is provided + /// @param [in,out] tv Pointer that gets updated + static void gettimeofday(struct timeval* tv); + + /// @brief Gets current date and time with a subsecond part. + /// @param format User provided date/time format + /// @param ssPrec A pointer to base::SubsecondPrecision from configuration (non-null) + /// @returns string based date time in specified format. + static std::string getDateTime(const char* format, const base::SubsecondPrecision* ssPrec); + + /// @brief Converts timeval (struct from ctime) to string using specified format and subsecond precision + static std::string timevalToString(struct timeval tval, const char* format, + const el::base::SubsecondPrecision* ssPrec); + + /// @brief Formats time to get unit accordingly, units like second if > 1000 or minutes if > 60000 etc + static base::type::string_t formatTime(unsigned long long time, base::TimestampUnit timestampUnit); + + /// @brief Gets time difference in milli/micro second depending on timestampUnit + static unsigned long long getTimeDifference(const struct timeval& endTime, const struct timeval& startTime, + base::TimestampUnit timestampUnit); + + + private: + static struct ::tm* buildTimeInfo(struct timeval* currTime, struct ::tm* timeInfo); + static char* parseFormat(char* buf, std::size_t bufSz, const char* format, const struct tm* tInfo, + std::size_t msec, const base::SubsecondPrecision* ssPrec); +}; +/// @brief Command line arguments for application if specified using el::Helpers::setArgs(..) or START_EASYLOGGINGPP(..) +class CommandLineArgs { + public: + CommandLineArgs(void) { + setArgs(0, static_cast(nullptr)); + } + CommandLineArgs(int argc, const char** argv) { + setArgs(argc, argv); + } + CommandLineArgs(int argc, char** argv) { + setArgs(argc, argv); + } + virtual ~CommandLineArgs(void) {} + /// @brief Sets arguments and parses them + inline void setArgs(int argc, const char** argv) { + setArgs(argc, const_cast(argv)); + } + /// @brief Sets arguments and parses them + void setArgs(int argc, char** argv); + /// @brief Returns true if arguments contain paramKey with a value (seperated by '=') + bool hasParamWithValue(const char* paramKey) const; + /// @brief Returns value of arguments + /// @see hasParamWithValue(const char*) + const char* getParamValue(const char* paramKey) const; + /// @brief Return true if arguments has a param (not having a value) i,e without '=' + bool hasParam(const char* paramKey) const; + /// @brief Returns true if no params available. This exclude argv[0] + bool empty(void) const; + /// @brief Returns total number of arguments. This exclude argv[0] + std::size_t size(void) const; + friend base::type::ostream_t& operator<<(base::type::ostream_t& os, const CommandLineArgs& c); + + private: + int m_argc; + char** m_argv; + std::map m_paramsWithValue; + std::vector m_params; +}; +/// @brief Abstract registry (aka repository) that provides basic interface for pointer repository specified by T_Ptr type. +/// +/// @detail Most of the functions are virtual final methods but anything implementing this abstract class should implement +/// unregisterAll() and deepCopy(const AbstractRegistry&) and write registerNew() method according to container +/// and few more methods; get() to find element, unregister() to unregister single entry. +/// Please note that this is thread-unsafe and should also implement thread-safety mechanisms in implementation. +template +class AbstractRegistry : public base::threading::ThreadSafe { + public: + typedef typename Container::iterator iterator; + typedef typename Container::const_iterator const_iterator; + + /// @brief Default constructor + AbstractRegistry(void) {} + + /// @brief Move constructor that is useful for base classes + AbstractRegistry(AbstractRegistry&& sr) { + if (this == &sr) { + return; + } + unregisterAll(); + m_list = std::move(sr.m_list); + } + + bool operator==(const AbstractRegistry& other) { + if (size() != other.size()) { + return false; + } + for (std::size_t i = 0; i < m_list.size(); ++i) { + if (m_list.at(i) != other.m_list.at(i)) { + return false; + } + } + return true; + } + + bool operator!=(const AbstractRegistry& other) { + if (size() != other.size()) { + return true; + } + for (std::size_t i = 0; i < m_list.size(); ++i) { + if (m_list.at(i) != other.m_list.at(i)) { + return true; + } + } + return false; + } + + /// @brief Assignment move operator + AbstractRegistry& operator=(AbstractRegistry&& sr) { + if (this == &sr) { + return *this; + } + unregisterAll(); + m_list = std::move(sr.m_list); + return *this; + } + + virtual ~AbstractRegistry(void) { + } + + /// @return Iterator pointer from start of repository + virtual inline iterator begin(void) ELPP_FINAL { + return m_list.begin(); + } + + /// @return Iterator pointer from end of repository + virtual inline iterator end(void) ELPP_FINAL { + return m_list.end(); + } + + + /// @return Constant iterator pointer from start of repository + virtual inline const_iterator cbegin(void) const ELPP_FINAL { + return m_list.cbegin(); + } + + /// @return End of repository + virtual inline const_iterator cend(void) const ELPP_FINAL { + return m_list.cend(); + } + + /// @return Whether or not repository is empty + virtual inline bool empty(void) const ELPP_FINAL { + return m_list.empty(); + } + + /// @return Size of repository + virtual inline std::size_t size(void) const ELPP_FINAL { + return m_list.size(); + } + + /// @brief Returns underlying container by reference + virtual inline Container& list(void) ELPP_FINAL { + return m_list; + } + + /// @brief Returns underlying container by constant reference. + virtual inline const Container& list(void) const ELPP_FINAL { + return m_list; + } + + /// @brief Unregisters all the pointers from current repository. + virtual void unregisterAll(void) = 0; + + protected: + virtual void deepCopy(const AbstractRegistry&) = 0; + void reinitDeepCopy(const AbstractRegistry& sr) { + unregisterAll(); + deepCopy(sr); + } + + private: + Container m_list; +}; + +/// @brief A pointer registry mechanism to manage memory and provide search functionalities. (non-predicate version) +/// +/// @detail NOTE: This is thread-unsafe implementation (although it contains lock function, it does not use these functions) +/// of AbstractRegistry. Any implementation of this class should be +/// explicitly (by using lock functions) +template +class Registry : public AbstractRegistry> { + public: + typedef typename Registry::iterator iterator; + typedef typename Registry::const_iterator const_iterator; + + Registry(void) {} + + /// @brief Copy constructor that is useful for base classes. Try to avoid this constructor, use move constructor. + Registry(const Registry& sr) : AbstractRegistry>() { + if (this == &sr) { + return; + } + this->reinitDeepCopy(sr); + } + + /// @brief Assignment operator that unregisters all the existing registeries and deeply copies each of repo element + /// @see unregisterAll() + /// @see deepCopy(const AbstractRegistry&) + Registry& operator=(const Registry& sr) { + if (this == &sr) { + return *this; + } + this->reinitDeepCopy(sr); + return *this; + } + + virtual ~Registry(void) { + unregisterAll(); + } + + protected: + virtual void unregisterAll(void) ELPP_FINAL { + if (!this->empty()) { + for (auto&& curr : this->list()) { + base::utils::safeDelete(curr.second); + } + this->list().clear(); + } + } + +/// @brief Registers new registry to repository. + virtual void registerNew(const T_Key& uniqKey, T_Ptr* ptr) ELPP_FINAL { + unregister(uniqKey); + this->list().insert(std::make_pair(uniqKey, ptr)); + } + +/// @brief Unregisters single entry mapped to specified unique key + void unregister(const T_Key& uniqKey) { + T_Ptr* existing = get(uniqKey); + if (existing != nullptr) { + base::utils::safeDelete(existing); + this->list().erase(uniqKey); + } + } + +/// @brief Gets pointer from repository. If none found, nullptr is returned. + T_Ptr* get(const T_Key& uniqKey) { + iterator it = this->list().find(uniqKey); + return it == this->list().end() + ? nullptr + : it->second; + } + + private: + virtual void deepCopy(const AbstractRegistry>& sr) ELPP_FINAL { + for (const_iterator it = sr.cbegin(); it != sr.cend(); ++it) { + registerNew(it->first, new T_Ptr(*it->second)); + } + } +}; + +/// @brief A pointer registry mechanism to manage memory and provide search functionalities. (predicate version) +/// +/// @detail NOTE: This is thread-unsafe implementation of AbstractRegistry. Any implementation of this class +/// should be made thread-safe explicitly +template +class RegistryWithPred : public AbstractRegistry> { + public: + typedef typename RegistryWithPred::iterator iterator; + typedef typename RegistryWithPred::const_iterator const_iterator; + + RegistryWithPred(void) { + } + + virtual ~RegistryWithPred(void) { + unregisterAll(); + } + + /// @brief Copy constructor that is useful for base classes. Try to avoid this constructor, use move constructor. + RegistryWithPred(const RegistryWithPred& sr) : AbstractRegistry>() { + if (this == &sr) { + return; + } + this->reinitDeepCopy(sr); + } + + /// @brief Assignment operator that unregisters all the existing registeries and deeply copies each of repo element + /// @see unregisterAll() + /// @see deepCopy(const AbstractRegistry&) + RegistryWithPred& operator=(const RegistryWithPred& sr) { + if (this == &sr) { + return *this; + } + this->reinitDeepCopy(sr); + return *this; + } + + friend base::type::ostream_t& operator<<(base::type::ostream_t& os, const RegistryWithPred& sr) { + for (const_iterator it = sr.list().begin(); it != sr.list().end(); ++it) { + os << ELPP_LITERAL(" ") << **it << ELPP_LITERAL("\n"); + } + return os; + } + + protected: + virtual void unregisterAll(void) ELPP_FINAL { + if (!this->empty()) { + for (auto&& curr : this->list()) { + base::utils::safeDelete(curr); + } + this->list().clear(); + } + } + + virtual void unregister(T_Ptr*& ptr) ELPP_FINAL { + if (ptr) { + iterator iter = this->begin(); + for (; iter != this->end(); ++iter) { + if (ptr == *iter) { + break; + } + } + if (iter != this->end() && *iter != nullptr) { + this->list().erase(iter); + base::utils::safeDelete(*iter); + } + } + } + + virtual inline void registerNew(T_Ptr* ptr) ELPP_FINAL { + this->list().push_back(ptr); + } + +/// @brief Gets pointer from repository with speicifed arguments. Arguments are passed to predicate +/// in order to validate pointer. + template + T_Ptr* get(const T& arg1, const T2 arg2) { + iterator iter = std::find_if(this->list().begin(), this->list().end(), Pred(arg1, arg2)); + if (iter != this->list().end() && *iter != nullptr) { + return *iter; + } + return nullptr; + } + + private: + virtual void deepCopy(const AbstractRegistry>& sr) { + for (const_iterator it = sr.list().begin(); it != sr.list().end(); ++it) { + registerNew(new T_Ptr(**it)); + } + } +}; +class Utils { + public: + template + static bool installCallback(const std::string& id, std::map* mapT) { + if (mapT->find(id) == mapT->end()) { + mapT->insert(std::make_pair(id, TPtr(new T()))); + return true; + } + return false; + } + + template + static void uninstallCallback(const std::string& id, std::map* mapT) { + if (mapT->find(id) != mapT->end()) { + mapT->erase(id); + } + } + + template + static T* callback(const std::string& id, std::map* mapT) { + typename std::map::iterator iter = mapT->find(id); + if (iter != mapT->end()) { + return static_cast(iter->second.get()); + } + return nullptr; + } +}; +} // namespace utils +} // namespace base +/// @brief Base of Easylogging++ friendly class +/// +/// @detail After inheriting this class publicly, implement pure-virtual function `void log(std::ostream&) const` +class Loggable { + public: + virtual ~Loggable(void) {} + virtual void log(el::base::type::ostream_t&) const = 0; + private: + friend inline el::base::type::ostream_t& operator<<(el::base::type::ostream_t& os, const Loggable& loggable) { + loggable.log(os); + return os; + } +}; +namespace base { +/// @brief Represents log format containing flags and date format. This is used internally to start initial log +class LogFormat : public Loggable { + public: + LogFormat(void); + LogFormat(Level level, const base::type::string_t& format); + LogFormat(const LogFormat& logFormat); + LogFormat(LogFormat&& logFormat); + LogFormat& operator=(const LogFormat& logFormat); + virtual ~LogFormat(void) {} + bool operator==(const LogFormat& other); + + /// @brief Updates format to be used while logging. + /// @param userFormat User provided format + void parseFromFormat(const base::type::string_t& userFormat); + + inline Level level(void) const { + return m_level; + } + + inline const base::type::string_t& userFormat(void) const { + return m_userFormat; + } + + inline const base::type::string_t& format(void) const { + return m_format; + } + + inline const std::string& dateTimeFormat(void) const { + return m_dateTimeFormat; + } + + inline base::type::EnumType flags(void) const { + return m_flags; + } + + inline bool hasFlag(base::FormatFlags flag) const { + return base::utils::hasFlag(flag, m_flags); + } + + virtual void log(el::base::type::ostream_t& os) const { + os << m_format; + } + + protected: + /// @brief Updates date time format if available in currFormat. + /// @param index Index where %datetime, %date or %time was found + /// @param [in,out] currFormat current format that is being used to format + virtual void updateDateFormat(std::size_t index, base::type::string_t& currFormat) ELPP_FINAL; + + /// @brief Updates %level from format. This is so that we dont have to do it at log-writing-time. It uses m_format and m_level + virtual void updateFormatSpec(void) ELPP_FINAL; + + inline void addFlag(base::FormatFlags flag) { + base::utils::addFlag(flag, &m_flags); + } + + private: + Level m_level; + base::type::string_t m_userFormat; + base::type::string_t m_format; + std::string m_dateTimeFormat; + base::type::EnumType m_flags; + std::string m_currentUser; + std::string m_currentHost; + friend class el::Logger; // To resolve loggerId format specifier easily +}; +} // namespace base +/// @brief Resolving function for format specifier +typedef std::function FormatSpecifierValueResolver; +/// @brief User-provided custom format specifier +/// @see el::Helpers::installCustomFormatSpecifier +/// @see FormatSpecifierValueResolver +class CustomFormatSpecifier { + public: + CustomFormatSpecifier(const char* formatSpecifier, const FormatSpecifierValueResolver& resolver) : + m_formatSpecifier(formatSpecifier), m_resolver(resolver) {} + inline const char* formatSpecifier(void) const { + return m_formatSpecifier; + } + inline const FormatSpecifierValueResolver& resolver(void) const { + return m_resolver; + } + inline bool operator==(const char* formatSpecifier) { + return strcmp(m_formatSpecifier, formatSpecifier) == 0; + } + + private: + const char* m_formatSpecifier; + FormatSpecifierValueResolver m_resolver; +}; +/// @brief Represents single configuration that has representing level, configuration type and a string based value. +/// +/// @detail String based value means any value either its boolean, integer or string itself, it will be embedded inside quotes +/// and will be parsed later. +/// +/// Consider some examples below: +/// * el::Configuration confEnabledInfo(el::Level::Info, el::ConfigurationType::Enabled, "true"); +/// * el::Configuration confMaxLogFileSizeInfo(el::Level::Info, el::ConfigurationType::MaxLogFileSize, "2048"); +/// * el::Configuration confFilenameInfo(el::Level::Info, el::ConfigurationType::Filename, "/var/log/my.log"); +class Configuration : public Loggable { + public: + Configuration(const Configuration& c); + Configuration& operator=(const Configuration& c); + + virtual ~Configuration(void) { + } + + /// @brief Full constructor used to sets value of configuration + Configuration(Level level, ConfigurationType configurationType, const std::string& value); + + /// @brief Gets level of current configuration + inline Level level(void) const { + return m_level; + } + + /// @brief Gets configuration type of current configuration + inline ConfigurationType configurationType(void) const { + return m_configurationType; + } + + /// @brief Gets string based configuration value + inline const std::string& value(void) const { + return m_value; + } + + /// @brief Set string based configuration value + /// @param value Value to set. Values have to be std::string; For boolean values use "true", "false", for any integral values + /// use them in quotes. They will be parsed when configuring + inline void setValue(const std::string& value) { + m_value = value; + } + + virtual void log(el::base::type::ostream_t& os) const; + + /// @brief Used to find configuration from configuration (pointers) repository. Avoid using it. + class Predicate { + public: + Predicate(Level level, ConfigurationType configurationType); + + bool operator()(const Configuration* conf) const; + + private: + Level m_level; + ConfigurationType m_configurationType; + }; + + private: + Level m_level; + ConfigurationType m_configurationType; + std::string m_value; +}; + +/// @brief Thread-safe Configuration repository +/// +/// @detail This repository represents configurations for all the levels and configuration type mapped to a value. +class Configurations : public base::utils::RegistryWithPred { + public: + /// @brief Default constructor with empty repository + Configurations(void); + + /// @brief Constructor used to set configurations using configuration file. + /// @param configurationFile Full path to configuration file + /// @param useDefaultsForRemaining Lets you set the remaining configurations to default. + /// @param base If provided, this configuration will be based off existing repository that this argument is pointing to. + /// @see parseFromFile(const std::string&, Configurations* base) + /// @see setRemainingToDefault() + Configurations(const std::string& configurationFile, bool useDefaultsForRemaining = true, + Configurations* base = nullptr); + + virtual ~Configurations(void) { + } + + /// @brief Parses configuration from file. + /// @param configurationFile Full path to configuration file + /// @param base Configurations to base new configuration repository off. This value is used when you want to use + /// existing Configurations to base all the values and then set rest of configuration via configuration file. + /// @return True if successfully parsed, false otherwise. You may define 'ELPP_DEBUG_ASSERT_FAILURE' to make sure you + /// do not proceed without successful parse. + bool parseFromFile(const std::string& configurationFile, Configurations* base = nullptr); + + /// @brief Parse configurations from configuration string. + /// + /// @detail This configuration string has same syntax as configuration file contents. Make sure all the necessary + /// new line characters are provided. + /// @param base Configurations to base new configuration repository off. This value is used when you want to use + /// existing Configurations to base all the values and then set rest of configuration via configuration text. + /// @return True if successfully parsed, false otherwise. You may define 'ELPP_DEBUG_ASSERT_FAILURE' to make sure you + /// do not proceed without successful parse. + bool parseFromText(const std::string& configurationsString, Configurations* base = nullptr); + + /// @brief Sets configuration based-off an existing configurations. + /// @param base Pointer to existing configurations. + void setFromBase(Configurations* base); + + /// @brief Determines whether or not specified configuration type exists in the repository. + /// + /// @detail Returns as soon as first level is found. + /// @param configurationType Type of configuration to check existence for. + bool hasConfiguration(ConfigurationType configurationType); + + /// @brief Determines whether or not specified configuration type exists for specified level + /// @param level Level to check + /// @param configurationType Type of configuration to check existence for. + bool hasConfiguration(Level level, ConfigurationType configurationType); + + /// @brief Sets value of configuration for specified level. + /// + /// @detail Any existing configuration for specified level will be replaced. Also note that configuration types + /// ConfigurationType::SubsecondPrecision and ConfigurationType::PerformanceTracking will be ignored if not set for + /// Level::Global because these configurations are not dependant on level. + /// @param level Level to set configuration for (el::Level). + /// @param configurationType Type of configuration (el::ConfigurationType) + /// @param value A string based value. Regardless of what the data type of configuration is, it will always be string + /// from users' point of view. This is then parsed later to be used internally. + /// @see Configuration::setValue(const std::string& value) + /// @see el::Level + /// @see el::ConfigurationType + void set(Level level, ConfigurationType configurationType, const std::string& value); + + /// @brief Sets single configuration based on other single configuration. + /// @see set(Level level, ConfigurationType configurationType, const std::string& value) + void set(Configuration* conf); + + inline Configuration* get(Level level, ConfigurationType configurationType) { + base::threading::ScopedLock scopedLock(lock()); + return RegistryWithPred::get(level, configurationType); + } + + /// @brief Sets configuration for all levels. + /// @param configurationType Type of configuration + /// @param value String based value + /// @see Configurations::set(Level level, ConfigurationType configurationType, const std::string& value) + inline void setGlobally(ConfigurationType configurationType, const std::string& value) { + setGlobally(configurationType, value, false); + } + + /// @brief Clears repository so that all the configurations are unset + inline void clear(void) { + base::threading::ScopedLock scopedLock(lock()); + unregisterAll(); + } + + /// @brief Gets configuration file used in parsing this configurations. + /// + /// @detail If this repository was set manually or by text this returns empty string. + inline const std::string& configurationFile(void) const { + return m_configurationFile; + } + + /// @brief Sets configurations to "factory based" configurations. + void setToDefault(void); + + /// @brief Lets you set the remaining configurations to default. + /// + /// @detail By remaining, it means that the level/type a configuration does not exist for. + /// This function is useful when you want to minimize chances of failures, e.g, if you have a configuration file that sets + /// configuration for all the configurations except for Enabled or not, we use this so that ENABLED is set to default i.e, + /// true. If you dont do this explicitly (either by calling this function or by using second param in Constructor + /// and try to access a value, an error is thrown + void setRemainingToDefault(void); + + /// @brief Parser used internally to parse configurations from file or text. + /// + /// @detail This class makes use of base::utils::Str. + /// You should not need this unless you are working on some tool for Easylogging++ + class Parser : base::StaticClass { + public: + /// @brief Parses configuration from file. + /// @param configurationFile Full path to configuration file + /// @param sender Sender configurations pointer. Usually 'this' is used from calling class + /// @param base Configurations to base new configuration repository off. This value is used when you want to use + /// existing Configurations to base all the values and then set rest of configuration via configuration file. + /// @return True if successfully parsed, false otherwise. You may define '_STOP_ON_FIRSTELPP_ASSERTION' to make sure you + /// do not proceed without successful parse. + static bool parseFromFile(const std::string& configurationFile, Configurations* sender, + Configurations* base = nullptr); + + /// @brief Parse configurations from configuration string. + /// + /// @detail This configuration string has same syntax as configuration file contents. Make sure all the necessary + /// new line characters are provided. You may define '_STOP_ON_FIRSTELPP_ASSERTION' to make sure you + /// do not proceed without successful parse (This is recommended) + /// @param configurationsString the configuration in plain text format + /// @param sender Sender configurations pointer. Usually 'this' is used from calling class + /// @param base Configurations to base new configuration repository off. This value is used when you want to use + /// existing Configurations to base all the values and then set rest of configuration via configuration text. + /// @return True if successfully parsed, false otherwise. + static bool parseFromText(const std::string& configurationsString, Configurations* sender, + Configurations* base = nullptr); + + private: + friend class el::Loggers; + static void ignoreComments(std::string* line); + static bool isLevel(const std::string& line); + static bool isComment(const std::string& line); + static inline bool isConfig(const std::string& line); + static bool parseLine(std::string* line, std::string* currConfigStr, std::string* currLevelStr, Level* currLevel, + Configurations* conf); + }; + + private: + std::string m_configurationFile; + bool m_isFromFile; + friend class el::Loggers; + + /// @brief Unsafely sets configuration if does not already exist + void unsafeSetIfNotExist(Level level, ConfigurationType configurationType, const std::string& value); + + /// @brief Thread unsafe set + void unsafeSet(Level level, ConfigurationType configurationType, const std::string& value); + + /// @brief Sets configurations for all levels including Level::Global if includeGlobalLevel is true + /// @see Configurations::setGlobally(ConfigurationType configurationType, const std::string& value) + void setGlobally(ConfigurationType configurationType, const std::string& value, bool includeGlobalLevel); + + /// @brief Sets configurations (Unsafely) for all levels including Level::Global if includeGlobalLevel is true + /// @see Configurations::setGlobally(ConfigurationType configurationType, const std::string& value) + void unsafeSetGlobally(ConfigurationType configurationType, const std::string& value, bool includeGlobalLevel); +}; + +namespace base { +typedef std::shared_ptr FileStreamPtr; +typedef std::map LogStreamsReferenceMap; +/// @brief Configurations with data types. +/// +/// @detail el::Configurations have string based values. This is whats used internally in order to read correct configurations. +/// This is to perform faster while writing logs using correct configurations. +/// +/// This is thread safe and final class containing non-virtual destructor (means nothing should inherit this class) +class TypedConfigurations : public base::threading::ThreadSafe { + public: + /// @brief Constructor to initialize (construct) the object off el::Configurations + /// @param configurations Configurations pointer/reference to base this typed configurations off. + /// @param logStreamsReference Use ELPP->registeredLoggers()->logStreamsReference() + TypedConfigurations(Configurations* configurations, base::LogStreamsReferenceMap* logStreamsReference); + + TypedConfigurations(const TypedConfigurations& other); + + virtual ~TypedConfigurations(void) { + } + + const Configurations* configurations(void) const { + return m_configurations; + } + + bool enabled(Level level); + bool toFile(Level level); + const std::string& filename(Level level); + bool toStandardOutput(Level level); + const base::LogFormat& logFormat(Level level); + const base::SubsecondPrecision& subsecondPrecision(Level level = Level::Global); + const base::MillisecondsWidth& millisecondsWidth(Level level = Level::Global); + bool performanceTracking(Level level = Level::Global); + base::type::fstream_t* fileStream(Level level); + std::size_t maxLogFileSize(Level level); + std::size_t logFlushThreshold(Level level); + + private: + Configurations* m_configurations; + std::map m_enabledMap; + std::map m_toFileMap; + std::map m_filenameMap; + std::map m_toStandardOutputMap; + std::map m_logFormatMap; + std::map m_subsecondPrecisionMap; + std::map m_performanceTrackingMap; + std::map m_fileStreamMap; + std::map m_maxLogFileSizeMap; + std::map m_logFlushThresholdMap; + base::LogStreamsReferenceMap* m_logStreamsReference; + + friend class el::Helpers; + friend class el::base::MessageBuilder; + friend class el::base::Writer; + friend class el::base::DefaultLogDispatchCallback; + friend class el::base::LogDispatcher; + + template + inline Conf_T getConfigByVal(Level level, const std::map* confMap, const char* confName) { + base::threading::ScopedLock scopedLock(lock()); + return unsafeGetConfigByVal(level, confMap, confName); // This is not unsafe anymore - mutex locked in scope + } + + template + inline Conf_T& getConfigByRef(Level level, std::map* confMap, const char* confName) { + base::threading::ScopedLock scopedLock(lock()); + return unsafeGetConfigByRef(level, confMap, confName); // This is not unsafe anymore - mutex locked in scope + } + + template + Conf_T unsafeGetConfigByVal(Level level, const std::map* confMap, const char* confName) { + ELPP_UNUSED(confName); + typename std::map::const_iterator it = confMap->find(level); + if (it == confMap->end()) { + try { + return confMap->at(Level::Global); + } catch (...) { + ELPP_INTERNAL_ERROR("Unable to get configuration [" << confName << "] for level [" + << LevelHelper::convertToString(level) << "]" + << std::endl << "Please ensure you have properly configured logger.", false); + return Conf_T(); + } + } + return it->second; + } + + template + Conf_T& unsafeGetConfigByRef(Level level, std::map* confMap, const char* confName) { + ELPP_UNUSED(confName); + typename std::map::iterator it = confMap->find(level); + if (it == confMap->end()) { + try { + return confMap->at(Level::Global); + } catch (...) { + ELPP_INTERNAL_ERROR("Unable to get configuration [" << confName << "] for level [" + << LevelHelper::convertToString(level) << "]" + << std::endl << "Please ensure you have properly configured logger.", false); + } + } + return it->second; + } + + template + void setValue(Level level, const Conf_T& value, std::map* confMap, bool includeGlobalLevel = true) { + // If map is empty and we are allowed to add into generic level (Level::Global), do it! + if (confMap->empty() && includeGlobalLevel) { + confMap->insert(std::make_pair(Level::Global, value)); + return; + } + // If same value exist in generic level already, dont add it to explicit level + typename std::map::iterator it = confMap->find(Level::Global); + if (it != confMap->end() && it->second == value) { + return; + } + // Now make sure we dont double up values if we really need to add it to explicit level + it = confMap->find(level); + if (it == confMap->end()) { + // Value not found for level, add new + confMap->insert(std::make_pair(level, value)); + } else { + // Value found, just update value + confMap->at(level) = value; + } + } + + void build(Configurations* configurations); + unsigned long getULong(std::string confVal); + std::string resolveFilename(const std::string& filename); + void insertFile(Level level, const std::string& fullFilename); + bool unsafeValidateFileRolling(Level level, const PreRollOutCallback& preRollOutCallback); + + inline bool validateFileRolling(Level level, const PreRollOutCallback& preRollOutCallback) { + base::threading::ScopedLock scopedLock(lock()); + return unsafeValidateFileRolling(level, preRollOutCallback); + } +}; +/// @brief Class that keeps record of current line hit for occasional logging +class HitCounter { + public: + HitCounter(void) : + m_filename(""), + m_lineNumber(0), + m_hitCounts(0) { + } + + HitCounter(const char* filename, base::type::LineNumber lineNumber) : + m_filename(filename), + m_lineNumber(lineNumber), + m_hitCounts(0) { + } + + HitCounter(const HitCounter& hitCounter) : + m_filename(hitCounter.m_filename), + m_lineNumber(hitCounter.m_lineNumber), + m_hitCounts(hitCounter.m_hitCounts) { + } + + HitCounter& operator=(const HitCounter& hitCounter) { + if (&hitCounter != this) { + m_filename = hitCounter.m_filename; + m_lineNumber = hitCounter.m_lineNumber; + m_hitCounts = hitCounter.m_hitCounts; + } + return *this; + } + + virtual ~HitCounter(void) { + } + + /// @brief Resets location of current hit counter + inline void resetLocation(const char* filename, base::type::LineNumber lineNumber) { + m_filename = filename; + m_lineNumber = lineNumber; + } + + /// @brief Validates hit counts and resets it if necessary + inline void validateHitCounts(std::size_t n) { + if (m_hitCounts >= base::consts::kMaxLogPerCounter) { + m_hitCounts = (n >= 1 ? base::consts::kMaxLogPerCounter % n : 0); + } + ++m_hitCounts; + } + + inline const char* filename(void) const { + return m_filename; + } + + inline base::type::LineNumber lineNumber(void) const { + return m_lineNumber; + } + + inline std::size_t hitCounts(void) const { + return m_hitCounts; + } + + inline void increment(void) { + ++m_hitCounts; + } + + class Predicate { + public: + Predicate(const char* filename, base::type::LineNumber lineNumber) + : m_filename(filename), + m_lineNumber(lineNumber) { + } + inline bool operator()(const HitCounter* counter) { + return ((counter != nullptr) && + (strcmp(counter->m_filename, m_filename) == 0) && + (counter->m_lineNumber == m_lineNumber)); + } + + private: + const char* m_filename; + base::type::LineNumber m_lineNumber; + }; + + private: + const char* m_filename; + base::type::LineNumber m_lineNumber; + std::size_t m_hitCounts; +}; +/// @brief Repository for hit counters used across the application +class RegisteredHitCounters : public base::utils::RegistryWithPred { + public: + /// @brief Validates counter for every N, i.e, registers new if does not exist otherwise updates original one + /// @return True if validation resulted in triggering hit. Meaning logs should be written everytime true is returned + bool validateEveryN(const char* filename, base::type::LineNumber lineNumber, std::size_t n); + + /// @brief Validates counter for hits >= N, i.e, registers new if does not exist otherwise updates original one + /// @return True if validation resulted in triggering hit. Meaning logs should be written everytime true is returned + bool validateAfterN(const char* filename, base::type::LineNumber lineNumber, std::size_t n); + + /// @brief Validates counter for hits are <= n, i.e, registers new if does not exist otherwise updates original one + /// @return True if validation resulted in triggering hit. Meaning logs should be written everytime true is returned + bool validateNTimes(const char* filename, base::type::LineNumber lineNumber, std::size_t n); + + /// @brief Gets hit counter registered at specified position + inline const base::HitCounter* getCounter(const char* filename, base::type::LineNumber lineNumber) { + base::threading::ScopedLock scopedLock(lock()); + return get(filename, lineNumber); + } +}; +/// @brief Action to be taken for dispatching +enum class DispatchAction : base::type::EnumType { + None = 1, NormalLog = 2, SysLog = 4 +}; +} // namespace base +template +class Callback : protected base::threading::ThreadSafe { + public: + Callback(void) : m_enabled(true) {} + inline bool enabled(void) const { + return m_enabled; + } + inline void setEnabled(bool enabled) { + base::threading::ScopedLock scopedLock(lock()); + m_enabled = enabled; + } + protected: + virtual void handle(const T* handlePtr) = 0; + private: + bool m_enabled; +}; +class LogDispatchData { + public: + LogDispatchData() : m_logMessage(nullptr), m_dispatchAction(base::DispatchAction::None) {} + inline const LogMessage* logMessage(void) const { + return m_logMessage; + } + inline base::DispatchAction dispatchAction(void) const { + return m_dispatchAction; + } + private: + LogMessage* m_logMessage; + base::DispatchAction m_dispatchAction; + friend class base::LogDispatcher; + + inline void setLogMessage(LogMessage* logMessage) { + m_logMessage = logMessage; + } + inline void setDispatchAction(base::DispatchAction dispatchAction) { + m_dispatchAction = dispatchAction; + } +}; +class LogDispatchCallback : public Callback { + private: + friend class base::LogDispatcher; +}; +class PerformanceTrackingCallback : public Callback { + private: + friend class base::PerformanceTracker; +}; +class LoggerRegistrationCallback : public Callback { + private: + friend class base::RegisteredLoggers; +}; +class LogBuilder : base::NoCopy { + public: + LogBuilder() : m_termSupportsColor(base::utils::OS::termSupportsColor()) {} + virtual ~LogBuilder(void) { + ELPP_INTERNAL_INFO(3, "Destroying log builder...") + } + virtual base::type::string_t build(const LogMessage* logMessage, bool appendNewLine) const = 0; + void convertToColoredOutput(base::type::string_t* logLine, Level level); + private: + bool m_termSupportsColor; + friend class el::base::DefaultLogDispatchCallback; +}; +typedef std::shared_ptr LogBuilderPtr; +/// @brief Represents a logger holding ID and configurations we need to write logs +/// +/// @detail This class does not write logs itself instead its used by writer to read configuations from. +class Logger : public base::threading::ThreadSafe, public Loggable { + public: + Logger(const std::string& id, base::LogStreamsReferenceMap* logStreamsReference); + Logger(const std::string& id, const Configurations& configurations, base::LogStreamsReferenceMap* logStreamsReference); + Logger(const Logger& logger); + Logger& operator=(const Logger& logger); + + virtual ~Logger(void) { + base::utils::safeDelete(m_typedConfigurations); + } + + virtual inline void log(el::base::type::ostream_t& os) const { + os << m_id.c_str(); + } + + /// @brief Configures the logger using specified configurations. + void configure(const Configurations& configurations); + + /// @brief Reconfigures logger using existing configurations + void reconfigure(void); + + inline const std::string& id(void) const { + return m_id; + } + + inline const std::string& parentApplicationName(void) const { + return m_parentApplicationName; + } + + inline void setParentApplicationName(const std::string& parentApplicationName) { + m_parentApplicationName = parentApplicationName; + } + + inline Configurations* configurations(void) { + return &m_configurations; + } + + inline base::TypedConfigurations* typedConfigurations(void) { + return m_typedConfigurations; + } + + static bool isValidId(const std::string& id); + + /// @brief Flushes logger to sync all log files for all levels + void flush(void); + + void flush(Level level, base::type::fstream_t* fs); + + inline bool isFlushNeeded(Level level) { + return ++m_unflushedCount.find(level)->second >= m_typedConfigurations->logFlushThreshold(level); + } + + inline LogBuilder* logBuilder(void) const { + return m_logBuilder.get(); + } + + inline void setLogBuilder(const LogBuilderPtr& logBuilder) { + m_logBuilder = logBuilder; + } + + inline bool enabled(Level level) const { + return m_typedConfigurations->enabled(level); + } + +#if ELPP_VARIADIC_TEMPLATES_SUPPORTED +# define LOGGER_LEVEL_WRITERS_SIGNATURES(FUNCTION_NAME)\ +template \ +inline void FUNCTION_NAME(const char*, const T&, const Args&...);\ +template \ +inline void FUNCTION_NAME(const T&); + + template + inline void verbose(int, const char*, const T&, const Args&...); + + template + inline void verbose(int, const T&); + + LOGGER_LEVEL_WRITERS_SIGNATURES(info) + LOGGER_LEVEL_WRITERS_SIGNATURES(debug) + LOGGER_LEVEL_WRITERS_SIGNATURES(warn) + LOGGER_LEVEL_WRITERS_SIGNATURES(error) + LOGGER_LEVEL_WRITERS_SIGNATURES(fatal) + LOGGER_LEVEL_WRITERS_SIGNATURES(trace) +# undef LOGGER_LEVEL_WRITERS_SIGNATURES +#endif // ELPP_VARIADIC_TEMPLATES_SUPPORTED + private: + std::string m_id; + base::TypedConfigurations* m_typedConfigurations; + base::type::stringstream_t m_stream; + std::string m_parentApplicationName; + bool m_isConfigured; + Configurations m_configurations; + std::map m_unflushedCount; + base::LogStreamsReferenceMap* m_logStreamsReference; + LogBuilderPtr m_logBuilder; + + friend class el::LogMessage; + friend class el::Loggers; + friend class el::Helpers; + friend class el::base::RegisteredLoggers; + friend class el::base::DefaultLogDispatchCallback; + friend class el::base::MessageBuilder; + friend class el::base::Writer; + friend class el::base::PErrorWriter; + friend class el::base::Storage; + friend class el::base::PerformanceTracker; + friend class el::base::LogDispatcher; + + Logger(void); + +#if ELPP_VARIADIC_TEMPLATES_SUPPORTED + template + void log_(Level, int, const char*, const T&, const Args&...); + + template + inline void log_(Level, int, const T&); + + template + void log(Level, const char*, const T&, const Args&...); + + template + inline void log(Level, const T&); +#endif // ELPP_VARIADIC_TEMPLATES_SUPPORTED + + void initUnflushedCount(void); + + inline base::type::stringstream_t& stream(void) { + return m_stream; + } + + void resolveLoggerFormatSpec(void) const; +}; +namespace base { +/// @brief Loggers repository +class RegisteredLoggers : public base::utils::Registry { + public: + explicit RegisteredLoggers(const LogBuilderPtr& defaultLogBuilder); + + virtual ~RegisteredLoggers(void) { + unsafeFlushAll(); + } + + inline void setDefaultConfigurations(const Configurations& configurations) { + base::threading::ScopedLock scopedLock(lock()); + m_defaultConfigurations.setFromBase(const_cast(&configurations)); + } + + inline Configurations* defaultConfigurations(void) { + return &m_defaultConfigurations; + } + + Logger* get(const std::string& id, bool forceCreation = true); + + template + inline bool installLoggerRegistrationCallback(const std::string& id) { + return base::utils::Utils::installCallback(id, + &m_loggerRegistrationCallbacks); + } + + template + inline void uninstallLoggerRegistrationCallback(const std::string& id) { + base::utils::Utils::uninstallCallback(id, &m_loggerRegistrationCallbacks); + } + + template + inline T* loggerRegistrationCallback(const std::string& id) { + return base::utils::Utils::callback(id, &m_loggerRegistrationCallbacks); + } + + bool remove(const std::string& id); + + inline bool has(const std::string& id) { + return get(id, false) != nullptr; + } + + inline void unregister(Logger*& logger) { + base::threading::ScopedLock scopedLock(lock()); + base::utils::Registry::unregister(logger->id()); + } + + inline base::LogStreamsReferenceMap* logStreamsReference(void) { + return &m_logStreamsReference; + } + + inline void flushAll(void) { + base::threading::ScopedLock scopedLock(lock()); + unsafeFlushAll(); + } + + inline void setDefaultLogBuilder(LogBuilderPtr& logBuilderPtr) { + base::threading::ScopedLock scopedLock(lock()); + m_defaultLogBuilder = logBuilderPtr; + } + + private: + LogBuilderPtr m_defaultLogBuilder; + Configurations m_defaultConfigurations; + base::LogStreamsReferenceMap m_logStreamsReference; + std::map m_loggerRegistrationCallbacks; + friend class el::base::Storage; + + void unsafeFlushAll(void); +}; +/// @brief Represents registries for verbose logging +class VRegistry : base::NoCopy, public base::threading::ThreadSafe { + public: + explicit VRegistry(base::type::VerboseLevel level, base::type::EnumType* pFlags); + + /// @brief Sets verbose level. Accepted range is 0-9 + void setLevel(base::type::VerboseLevel level); + + inline base::type::VerboseLevel level(void) const { + return m_level; + } + + inline void clearModules(void) { + base::threading::ScopedLock scopedLock(lock()); + m_modules.clear(); + } + + void setModules(const char* modules); + + bool allowed(base::type::VerboseLevel vlevel, const char* file); + + inline const std::map& modules(void) const { + return m_modules; + } + + void setFromArgs(const base::utils::CommandLineArgs* commandLineArgs); + + /// @brief Whether or not vModules enabled + inline bool vModulesEnabled(void) { + return !base::utils::hasFlag(LoggingFlag::DisableVModules, *m_pFlags); + } + + private: + base::type::VerboseLevel m_level; + base::type::EnumType* m_pFlags; + std::map m_modules; +}; +} // namespace base +class LogMessage { + public: + LogMessage(Level level, const std::string& file, base::type::LineNumber line, const std::string& func, + base::type::VerboseLevel verboseLevel, Logger* logger) : + m_level(level), m_file(file), m_line(line), m_func(func), + m_verboseLevel(verboseLevel), m_logger(logger), m_message(logger->stream().str()) { + } + inline Level level(void) const { + return m_level; + } + inline const std::string& file(void) const { + return m_file; + } + inline base::type::LineNumber line(void) const { + return m_line; + } + inline const std::string& func(void) const { + return m_func; + } + inline base::type::VerboseLevel verboseLevel(void) const { + return m_verboseLevel; + } + inline Logger* logger(void) const { + return m_logger; + } + inline const base::type::string_t& message(void) const { + return m_message; + } + private: + Level m_level; + std::string m_file; + base::type::LineNumber m_line; + std::string m_func; + base::type::VerboseLevel m_verboseLevel; + Logger* m_logger; + base::type::string_t m_message; +}; +namespace base { +#if ELPP_ASYNC_LOGGING +class AsyncLogItem { + public: + explicit AsyncLogItem(const LogMessage& logMessage, const LogDispatchData& data, const base::type::string_t& logLine) + : m_logMessage(logMessage), m_dispatchData(data), m_logLine(logLine) {} + virtual ~AsyncLogItem() {} + inline LogMessage* logMessage(void) { + return &m_logMessage; + } + inline LogDispatchData* data(void) { + return &m_dispatchData; + } + inline base::type::string_t logLine(void) { + return m_logLine; + } + private: + LogMessage m_logMessage; + LogDispatchData m_dispatchData; + base::type::string_t m_logLine; +}; +class AsyncLogQueue : public base::threading::ThreadSafe { + public: + virtual ~AsyncLogQueue() { + ELPP_INTERNAL_INFO(6, "~AsyncLogQueue"); + } + + inline AsyncLogItem next(void) { + base::threading::ScopedLock scopedLock(lock()); + AsyncLogItem result = m_queue.front(); + m_queue.pop(); + return result; + } + + inline void push(const AsyncLogItem& item) { + base::threading::ScopedLock scopedLock(lock()); + m_queue.push(item); + } + inline void pop(void) { + base::threading::ScopedLock scopedLock(lock()); + m_queue.pop(); + } + inline AsyncLogItem front(void) { + base::threading::ScopedLock scopedLock(lock()); + return m_queue.front(); + } + inline bool empty(void) { + base::threading::ScopedLock scopedLock(lock()); + return m_queue.empty(); + } + private: + std::queue m_queue; +}; +class IWorker { + public: + virtual ~IWorker() {} + virtual void start() = 0; +}; +#endif // ELPP_ASYNC_LOGGING +/// @brief Easylogging++ management storage +class Storage : base::NoCopy, public base::threading::ThreadSafe { + public: +#if ELPP_ASYNC_LOGGING + Storage(const LogBuilderPtr& defaultLogBuilder, base::IWorker* asyncDispatchWorker); +#else + explicit Storage(const LogBuilderPtr& defaultLogBuilder); +#endif // ELPP_ASYNC_LOGGING + + virtual ~Storage(void); + + inline bool validateEveryNCounter(const char* filename, base::type::LineNumber lineNumber, std::size_t occasion) { + return hitCounters()->validateEveryN(filename, lineNumber, occasion); + } + + inline bool validateAfterNCounter(const char* filename, base::type::LineNumber lineNumber, std::size_t n) { + return hitCounters()->validateAfterN(filename, lineNumber, n); + } + + inline bool validateNTimesCounter(const char* filename, base::type::LineNumber lineNumber, std::size_t n) { + return hitCounters()->validateNTimes(filename, lineNumber, n); + } + + inline base::RegisteredHitCounters* hitCounters(void) const { + return m_registeredHitCounters; + } + + inline base::RegisteredLoggers* registeredLoggers(void) const { + return m_registeredLoggers; + } + + inline base::VRegistry* vRegistry(void) const { + return m_vRegistry; + } + +#if ELPP_ASYNC_LOGGING + inline base::AsyncLogQueue* asyncLogQueue(void) const { + return m_asyncLogQueue; + } +#endif // ELPP_ASYNC_LOGGING + + inline const base::utils::CommandLineArgs* commandLineArgs(void) const { + return &m_commandLineArgs; + } + + inline void addFlag(LoggingFlag flag) { + base::utils::addFlag(flag, &m_flags); + } + + inline void removeFlag(LoggingFlag flag) { + base::utils::removeFlag(flag, &m_flags); + } + + inline bool hasFlag(LoggingFlag flag) const { + return base::utils::hasFlag(flag, m_flags); + } + + inline base::type::EnumType flags(void) const { + return m_flags; + } + + inline void setFlags(base::type::EnumType flags) { + m_flags = flags; + } + + inline void setPreRollOutCallback(const PreRollOutCallback& callback) { + m_preRollOutCallback = callback; + } + + inline void unsetPreRollOutCallback(void) { + m_preRollOutCallback = base::defaultPreRollOutCallback; + } + + inline PreRollOutCallback& preRollOutCallback(void) { + return m_preRollOutCallback; + } + + bool hasCustomFormatSpecifier(const char* formatSpecifier); + void installCustomFormatSpecifier(const CustomFormatSpecifier& customFormatSpecifier); + bool uninstallCustomFormatSpecifier(const char* formatSpecifier); + + const std::vector* customFormatSpecifiers(void) const { + return &m_customFormatSpecifiers; + } + + inline void setLoggingLevel(Level level) { + m_loggingLevel = level; + } + + template + inline bool installLogDispatchCallback(const std::string& id) { + return base::utils::Utils::installCallback(id, &m_logDispatchCallbacks); + } + + template + inline void uninstallLogDispatchCallback(const std::string& id) { + base::utils::Utils::uninstallCallback(id, &m_logDispatchCallbacks); + } + template + inline T* logDispatchCallback(const std::string& id) { + return base::utils::Utils::callback(id, &m_logDispatchCallbacks); + } + +#if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING) + template + inline bool installPerformanceTrackingCallback(const std::string& id) { + return base::utils::Utils::installCallback(id, + &m_performanceTrackingCallbacks); + } + + template + inline void uninstallPerformanceTrackingCallback(const std::string& id) { + base::utils::Utils::uninstallCallback(id, + &m_performanceTrackingCallbacks); + } + + template + inline T* performanceTrackingCallback(const std::string& id) { + return base::utils::Utils::callback(id, &m_performanceTrackingCallbacks); + } +#endif // defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING) + + /// @brief Sets thread name for current thread. Requires std::thread + inline void setThreadName(const std::string& name) { + if (name.empty()) return; + base::threading::ScopedLock scopedLock(lock()); + m_threadNames[base::threading::getCurrentThreadId()] = name; + } + + inline std::string getThreadName(const std::string& threadId) { + std::map::const_iterator it = m_threadNames.find(threadId); + if (it == m_threadNames.end()) { + return threadId; + } + return it->second; + } + private: + base::RegisteredHitCounters* m_registeredHitCounters; + base::RegisteredLoggers* m_registeredLoggers; + base::type::EnumType m_flags; + base::VRegistry* m_vRegistry; +#if ELPP_ASYNC_LOGGING + base::AsyncLogQueue* m_asyncLogQueue; + base::IWorker* m_asyncDispatchWorker; +#endif // ELPP_ASYNC_LOGGING + base::utils::CommandLineArgs m_commandLineArgs; + PreRollOutCallback m_preRollOutCallback; + std::map m_logDispatchCallbacks; + std::map m_performanceTrackingCallbacks; + std::map m_threadNames; + std::vector m_customFormatSpecifiers; + Level m_loggingLevel; + + friend class el::Helpers; + friend class el::base::DefaultLogDispatchCallback; + friend class el::LogBuilder; + friend class el::base::MessageBuilder; + friend class el::base::Writer; + friend class el::base::PerformanceTracker; + friend class el::base::LogDispatcher; + + void setApplicationArguments(int argc, char** argv); + + inline void setApplicationArguments(int argc, const char** argv) { + setApplicationArguments(argc, const_cast(argv)); + } +}; +extern ELPP_EXPORT base::type::StoragePointer elStorage; +#define ELPP el::base::elStorage +class DefaultLogDispatchCallback : public LogDispatchCallback { + protected: + void handle(const LogDispatchData* data); + private: + const LogDispatchData* m_data; + void dispatch(base::type::string_t&& logLine); +}; +#if ELPP_ASYNC_LOGGING +class AsyncLogDispatchCallback : public LogDispatchCallback { + protected: + void handle(const LogDispatchData* data); +}; +class AsyncDispatchWorker : public base::IWorker, public base::threading::ThreadSafe { + public: + AsyncDispatchWorker(); + virtual ~AsyncDispatchWorker(); + + bool clean(void); + void emptyQueue(void); + virtual void start(void); + void handle(AsyncLogItem* logItem); + void run(void); + + void setContinueRunning(bool value) { + base::threading::ScopedLock scopedLock(m_continueRunningMutex); + m_continueRunning = value; + } + + bool continueRunning(void) const { + return m_continueRunning; + } + private: + std::condition_variable cv; + bool m_continueRunning; + base::threading::Mutex m_continueRunningMutex; +}; +#endif // ELPP_ASYNC_LOGGING +} // namespace base +namespace base { +class DefaultLogBuilder : public LogBuilder { + public: + base::type::string_t build(const LogMessage* logMessage, bool appendNewLine) const; +}; +/// @brief Dispatches log messages +class LogDispatcher : base::NoCopy { + public: + LogDispatcher(bool proceed, LogMessage&& logMessage, base::DispatchAction dispatchAction) : + m_proceed(proceed), + m_logMessage(std::move(logMessage)), + m_dispatchAction(std::move(dispatchAction)) { + } + + void dispatch(void); + + private: + bool m_proceed; + LogMessage m_logMessage; + base::DispatchAction m_dispatchAction; +}; +#if defined(ELPP_STL_LOGGING) +/// @brief Workarounds to write some STL logs +/// +/// @detail There is workaround needed to loop through some stl containers. In order to do that, we need iterable containers +/// of same type and provide iterator interface and pass it on to writeIterator(). +/// Remember, this is passed by value in constructor so that we dont change original containers. +/// This operation is as expensive as Big-O(std::min(class_.size(), base::consts::kMaxLogPerContainer)) +namespace workarounds { +/// @brief Abstract IterableContainer template that provides interface for iterable classes of type T +template +class IterableContainer { + public: + typedef typename Container::iterator iterator; + typedef typename Container::const_iterator const_iterator; + IterableContainer(void) {} + virtual ~IterableContainer(void) {} + iterator begin(void) { + return getContainer().begin(); + } + iterator end(void) { + return getContainer().end(); + } + private: + virtual Container& getContainer(void) = 0; +}; +/// @brief Implements IterableContainer and provides iterable std::priority_queue class +template, typename Comparator = std::less> +class IterablePriorityQueue : public IterableContainer, + public std::priority_queue { + public: + IterablePriorityQueue(std::priority_queue queue_) { + std::size_t count_ = 0; + while (++count_ < base::consts::kMaxLogPerContainer && !queue_.empty()) { + this->push(queue_.top()); + queue_.pop(); + } + } + private: + inline Container& getContainer(void) { + return this->c; + } +}; +/// @brief Implements IterableContainer and provides iterable std::queue class +template> +class IterableQueue : public IterableContainer, public std::queue { + public: + IterableQueue(std::queue queue_) { + std::size_t count_ = 0; + while (++count_ < base::consts::kMaxLogPerContainer && !queue_.empty()) { + this->push(queue_.front()); + queue_.pop(); + } + } + private: + inline Container& getContainer(void) { + return this->c; + } +}; +/// @brief Implements IterableContainer and provides iterable std::stack class +template> +class IterableStack : public IterableContainer, public std::stack { + public: + IterableStack(std::stack stack_) { + std::size_t count_ = 0; + while (++count_ < base::consts::kMaxLogPerContainer && !stack_.empty()) { + this->push(stack_.top()); + stack_.pop(); + } + } + private: + inline Container& getContainer(void) { + return this->c; + } +}; +} // namespace workarounds +#endif // defined(ELPP_STL_LOGGING) +// Log message builder +class MessageBuilder { + public: + MessageBuilder(void) : m_logger(nullptr), m_containerLogSeperator(ELPP_LITERAL("")) {} + void initialize(Logger* logger); + +# define ELPP_SIMPLE_LOG(LOG_TYPE)\ +MessageBuilder& operator<<(LOG_TYPE msg) {\ +m_logger->stream() << msg;\ +if (ELPP->hasFlag(LoggingFlag::AutoSpacing)) {\ +m_logger->stream() << " ";\ +}\ +return *this;\ +} + + inline MessageBuilder& operator<<(const std::string& msg) { + return operator<<(msg.c_str()); + } + ELPP_SIMPLE_LOG(char) + ELPP_SIMPLE_LOG(bool) + ELPP_SIMPLE_LOG(signed short) + ELPP_SIMPLE_LOG(unsigned short) + ELPP_SIMPLE_LOG(signed int) + ELPP_SIMPLE_LOG(unsigned int) + ELPP_SIMPLE_LOG(signed long) + ELPP_SIMPLE_LOG(unsigned long) + ELPP_SIMPLE_LOG(float) + ELPP_SIMPLE_LOG(double) + ELPP_SIMPLE_LOG(char*) + ELPP_SIMPLE_LOG(const char*) + ELPP_SIMPLE_LOG(const void*) + ELPP_SIMPLE_LOG(long double) + inline MessageBuilder& operator<<(const std::wstring& msg) { + return operator<<(msg.c_str()); + } + MessageBuilder& operator<<(const wchar_t* msg); + // ostream manipulators + inline MessageBuilder& operator<<(std::ostream& (*OStreamMani)(std::ostream&)) { + m_logger->stream() << OStreamMani; + return *this; + } +#define ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(temp) \ +template \ +inline MessageBuilder& operator<<(const temp& template_inst) { \ +return writeIterator(template_inst.begin(), template_inst.end(), template_inst.size()); \ +} +#define ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(temp) \ +template \ +inline MessageBuilder& operator<<(const temp& template_inst) { \ +return writeIterator(template_inst.begin(), template_inst.end(), template_inst.size()); \ +} +#define ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG(temp) \ +template \ +inline MessageBuilder& operator<<(const temp& template_inst) { \ +return writeIterator(template_inst.begin(), template_inst.end(), template_inst.size()); \ +} +#define ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(temp) \ +template \ +inline MessageBuilder& operator<<(const temp& template_inst) { \ +return writeIterator(template_inst.begin(), template_inst.end(), template_inst.size()); \ +} +#define ELPP_ITERATOR_CONTAINER_LOG_FIVE_ARG(temp) \ +template \ +inline MessageBuilder& operator<<(const temp& template_inst) { \ +return writeIterator(template_inst.begin(), template_inst.end(), template_inst.size()); \ +} + +#if defined(ELPP_STL_LOGGING) + ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(std::vector) + ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(std::list) + ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(std::deque) + ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG(std::set) + ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG(std::multiset) + ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(std::map) + ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(std::multimap) + template + inline MessageBuilder& operator<<(const std::queue& queue_) { + base::workarounds::IterableQueue iterableQueue_ = + static_cast >(queue_); + return writeIterator(iterableQueue_.begin(), iterableQueue_.end(), iterableQueue_.size()); + } + template + inline MessageBuilder& operator<<(const std::stack& stack_) { + base::workarounds::IterableStack iterableStack_ = + static_cast >(stack_); + return writeIterator(iterableStack_.begin(), iterableStack_.end(), iterableStack_.size()); + } + template + inline MessageBuilder& operator<<(const std::priority_queue& priorityQueue_) { + base::workarounds::IterablePriorityQueue iterablePriorityQueue_ = + static_cast >(priorityQueue_); + return writeIterator(iterablePriorityQueue_.begin(), iterablePriorityQueue_.end(), iterablePriorityQueue_.size()); + } + template + MessageBuilder& operator<<(const std::pair& pair_) { + m_logger->stream() << ELPP_LITERAL("("); + operator << (static_cast(pair_.first)); + m_logger->stream() << ELPP_LITERAL(", "); + operator << (static_cast(pair_.second)); + m_logger->stream() << ELPP_LITERAL(")"); + return *this; + } + template + MessageBuilder& operator<<(const std::bitset& bitset_) { + m_logger->stream() << ELPP_LITERAL("["); + operator << (bitset_.to_string()); + m_logger->stream() << ELPP_LITERAL("]"); + return *this; + } +# if defined(ELPP_LOG_STD_ARRAY) + template + inline MessageBuilder& operator<<(const std::array& array) { + return writeIterator(array.begin(), array.end(), array.size()); + } +# endif // defined(ELPP_LOG_STD_ARRAY) +# if defined(ELPP_LOG_UNORDERED_MAP) + ELPP_ITERATOR_CONTAINER_LOG_FIVE_ARG(std::unordered_map) + ELPP_ITERATOR_CONTAINER_LOG_FIVE_ARG(std::unordered_multimap) +# endif // defined(ELPP_LOG_UNORDERED_MAP) +# if defined(ELPP_LOG_UNORDERED_SET) + ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(std::unordered_set) + ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(std::unordered_multiset) +# endif // defined(ELPP_LOG_UNORDERED_SET) +#endif // defined(ELPP_STL_LOGGING) +#if defined(ELPP_QT_LOGGING) + inline MessageBuilder& operator<<(const QString& msg) { +# if defined(ELPP_UNICODE) + m_logger->stream() << msg.toStdWString(); +# else + m_logger->stream() << msg.toStdString(); +# endif // defined(ELPP_UNICODE) + return *this; + } + inline MessageBuilder& operator<<(const QByteArray& msg) { + return operator << (QString(msg)); + } + inline MessageBuilder& operator<<(const QStringRef& msg) { + return operator<<(msg.toString()); + } + inline MessageBuilder& operator<<(qint64 msg) { +# if defined(ELPP_UNICODE) + m_logger->stream() << QString::number(msg).toStdWString(); +# else + m_logger->stream() << QString::number(msg).toStdString(); +# endif // defined(ELPP_UNICODE) + return *this; + } + inline MessageBuilder& operator<<(quint64 msg) { +# if defined(ELPP_UNICODE) + m_logger->stream() << QString::number(msg).toStdWString(); +# else + m_logger->stream() << QString::number(msg).toStdString(); +# endif // defined(ELPP_UNICODE) + return *this; + } + inline MessageBuilder& operator<<(QChar msg) { + m_logger->stream() << msg.toLatin1(); + return *this; + } + inline MessageBuilder& operator<<(const QLatin1String& msg) { + m_logger->stream() << msg.latin1(); + return *this; + } + ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(QList) + ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(QVector) + ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(QQueue) + ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(QSet) + ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(QLinkedList) + ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(QStack) + template + MessageBuilder& operator<<(const QPair& pair_) { + m_logger->stream() << ELPP_LITERAL("("); + operator << (static_cast(pair_.first)); + m_logger->stream() << ELPP_LITERAL(", "); + operator << (static_cast(pair_.second)); + m_logger->stream() << ELPP_LITERAL(")"); + return *this; + } + template + MessageBuilder& operator<<(const QMap& map_) { + m_logger->stream() << ELPP_LITERAL("["); + QList keys = map_.keys(); + typename QList::const_iterator begin = keys.begin(); + typename QList::const_iterator end = keys.end(); + int max_ = static_cast(base::consts::kMaxLogPerContainer); // to prevent warning + for (int index_ = 0; begin != end && index_ < max_; ++index_, ++begin) { + m_logger->stream() << ELPP_LITERAL("("); + operator << (static_cast(*begin)); + m_logger->stream() << ELPP_LITERAL(", "); + operator << (static_cast(map_.value(*begin))); + m_logger->stream() << ELPP_LITERAL(")"); + m_logger->stream() << ((index_ < keys.size() -1) ? m_containerLogSeperator : ELPP_LITERAL("")); + } + if (begin != end) { + m_logger->stream() << ELPP_LITERAL("..."); + } + m_logger->stream() << ELPP_LITERAL("]"); + return *this; + } + template + inline MessageBuilder& operator<<(const QMultiMap& map_) { + operator << (static_cast>(map_)); + return *this; + } + template + MessageBuilder& operator<<(const QHash& hash_) { + m_logger->stream() << ELPP_LITERAL("["); + QList keys = hash_.keys(); + typename QList::const_iterator begin = keys.begin(); + typename QList::const_iterator end = keys.end(); + int max_ = static_cast(base::consts::kMaxLogPerContainer); // prevent type warning + for (int index_ = 0; begin != end && index_ < max_; ++index_, ++begin) { + m_logger->stream() << ELPP_LITERAL("("); + operator << (static_cast(*begin)); + m_logger->stream() << ELPP_LITERAL(", "); + operator << (static_cast(hash_.value(*begin))); + m_logger->stream() << ELPP_LITERAL(")"); + m_logger->stream() << ((index_ < keys.size() -1) ? m_containerLogSeperator : ELPP_LITERAL("")); + } + if (begin != end) { + m_logger->stream() << ELPP_LITERAL("..."); + } + m_logger->stream() << ELPP_LITERAL("]"); + return *this; + } + template + inline MessageBuilder& operator<<(const QMultiHash& multiHash_) { + operator << (static_cast>(multiHash_)); + return *this; + } +#endif // defined(ELPP_QT_LOGGING) +#if defined(ELPP_BOOST_LOGGING) + ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(boost::container::vector) + ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(boost::container::stable_vector) + ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(boost::container::list) + ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(boost::container::deque) + ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(boost::container::map) + ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(boost::container::flat_map) + ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG(boost::container::set) + ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG(boost::container::flat_set) +#endif // defined(ELPP_BOOST_LOGGING) + + /// @brief Macro used internally that can be used externally to make containers easylogging++ friendly + /// + /// @detail This macro expands to write an ostream& operator<< for container. This container is expected to + /// have begin() and end() methods that return respective iterators + /// @param ContainerType Type of container e.g, MyList from WX_DECLARE_LIST(int, MyList); in wxwidgets + /// @param SizeMethod Method used to get size of container. + /// @param ElementInstance Instance of element to be fed out. Insance name is "elem". See WXELPP_ENABLED macro + /// for an example usage +#define MAKE_CONTAINERELPP_FRIENDLY(ContainerType, SizeMethod, ElementInstance) \ +el::base::type::ostream_t& operator<<(el::base::type::ostream_t& ss, const ContainerType& container) {\ +const el::base::type::char_t* sep = ELPP->hasFlag(el::LoggingFlag::NewLineForContainer) ? \ +ELPP_LITERAL("\n ") : ELPP_LITERAL(", ");\ +ContainerType::const_iterator elem = container.begin();\ +ContainerType::const_iterator endElem = container.end();\ +std::size_t size_ = container.SizeMethod; \ +ss << ELPP_LITERAL("[");\ +for (std::size_t i = 0; elem != endElem && i < el::base::consts::kMaxLogPerContainer; ++i, ++elem) { \ +ss << ElementInstance;\ +ss << ((i < size_ - 1) ? sep : ELPP_LITERAL(""));\ +}\ +if (elem != endElem) {\ +ss << ELPP_LITERAL("...");\ +}\ +ss << ELPP_LITERAL("]");\ +return ss;\ +} +#if defined(ELPP_WXWIDGETS_LOGGING) + ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(wxVector) +# define ELPP_WX_PTR_ENABLED(ContainerType) MAKE_CONTAINERELPP_FRIENDLY(ContainerType, size(), *(*elem)) +# define ELPP_WX_ENABLED(ContainerType) MAKE_CONTAINERELPP_FRIENDLY(ContainerType, size(), (*elem)) +# define ELPP_WX_HASH_MAP_ENABLED(ContainerType) MAKE_CONTAINERELPP_FRIENDLY(ContainerType, size(), \ +ELPP_LITERAL("(") << elem->first << ELPP_LITERAL(", ") << elem->second << ELPP_LITERAL(")") +#else +# define ELPP_WX_PTR_ENABLED(ContainerType) +# define ELPP_WX_ENABLED(ContainerType) +# define ELPP_WX_HASH_MAP_ENABLED(ContainerType) +#endif // defined(ELPP_WXWIDGETS_LOGGING) + // Other classes + template + ELPP_SIMPLE_LOG(const Class&) +#undef ELPP_SIMPLE_LOG +#undef ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG +#undef ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG +#undef ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG +#undef ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG +#undef ELPP_ITERATOR_CONTAINER_LOG_FIVE_ARG + private: + Logger* m_logger; + const base::type::char_t* m_containerLogSeperator; + + template + MessageBuilder& writeIterator(Iterator begin_, Iterator end_, std::size_t size_) { + m_logger->stream() << ELPP_LITERAL("["); + for (std::size_t i = 0; begin_ != end_ && i < base::consts::kMaxLogPerContainer; ++i, ++begin_) { + operator << (*begin_); + m_logger->stream() << ((i < size_ - 1) ? m_containerLogSeperator : ELPP_LITERAL("")); + } + if (begin_ != end_) { + m_logger->stream() << ELPP_LITERAL("..."); + } + m_logger->stream() << ELPP_LITERAL("]"); + if (ELPP->hasFlag(LoggingFlag::AutoSpacing)) { + m_logger->stream() << " "; + } + return *this; + } +}; +/// @brief Writes nothing - Used when certain log is disabled +class NullWriter : base::NoCopy { + public: + NullWriter(void) {} + + // Null manipulator + inline NullWriter& operator<<(std::ostream& (*)(std::ostream&)) { + return *this; + } + + template + inline NullWriter& operator<<(const T&) { + return *this; + } + + inline operator bool() { + return true; + } +}; +/// @brief Main entry point of each logging +class Writer : base::NoCopy { + public: + Writer(Level level, const char* file, base::type::LineNumber line, + const char* func, base::DispatchAction dispatchAction = base::DispatchAction::NormalLog, + base::type::VerboseLevel verboseLevel = 0) : + m_level(level), m_file(file), m_line(line), m_func(func), m_verboseLevel(verboseLevel), + m_logger(nullptr), m_proceed(false), m_dispatchAction(dispatchAction) { + } + + virtual ~Writer(void) { + processDispatch(); + } + + template + inline Writer& operator<<(const T& log) { +#if ELPP_LOGGING_ENABLED + if (m_proceed) { + m_messageBuilder << log; + } +#endif // ELPP_LOGGING_ENABLED + return *this; + } + + inline Writer& operator<<(std::ostream& (*log)(std::ostream&)) { +#if ELPP_LOGGING_ENABLED + if (m_proceed) { + m_messageBuilder << log; + } +#endif // ELPP_LOGGING_ENABLED + return *this; + } + + inline operator bool() { + return true; + } + + Writer& construct(Logger* logger, bool needLock = true); + Writer& construct(int count, const char* loggerIds, ...); + protected: + Level m_level; + const char* m_file; + const base::type::LineNumber m_line; + const char* m_func; + base::type::VerboseLevel m_verboseLevel; + Logger* m_logger; + bool m_proceed; + base::MessageBuilder m_messageBuilder; + base::DispatchAction m_dispatchAction; + std::vector m_loggerIds; + friend class el::Helpers; + + void initializeLogger(const std::string& loggerId, bool lookup = true, bool needLock = true); + void processDispatch(); + void triggerDispatch(void); +}; +class PErrorWriter : public base::Writer { + public: + PErrorWriter(Level level, const char* file, base::type::LineNumber line, + const char* func, base::DispatchAction dispatchAction = base::DispatchAction::NormalLog, + base::type::VerboseLevel verboseLevel = 0) : + base::Writer(level, file, line, func, dispatchAction, verboseLevel) { + } + + virtual ~PErrorWriter(void); +}; +} // namespace base +// Logging from Logger class. Why this is here? Because we have Storage and Writer class available +#if ELPP_VARIADIC_TEMPLATES_SUPPORTED +template +void Logger::log_(Level level, int vlevel, const char* s, const T& value, const Args&... args) { + base::MessageBuilder b; + b.initialize(this); + while (*s) { + if (*s == base::consts::kFormatSpecifierChar) { + if (*(s + 1) == base::consts::kFormatSpecifierChar) { + ++s; + } else { + if (*(s + 1) == base::consts::kFormatSpecifierCharValue) { + ++s; + b << value; + log_(level, vlevel, ++s, args...); + return; + } + } + } + b << *s++; + } + ELPP_INTERNAL_ERROR("Too many arguments provided. Unable to handle. Please provide more format specifiers", false); +} +template +void Logger::log_(Level level, int vlevel, const T& log) { + if (level == Level::Verbose) { + if (ELPP->vRegistry()->allowed(vlevel, __FILE__)) { + base::Writer(Level::Verbose, "FILE", 0, "FUNCTION", + base::DispatchAction::NormalLog, vlevel).construct(this, false) << log; + } else { + stream().str(ELPP_LITERAL("")); + } + } else { + base::Writer(level, "FILE", 0, "FUNCTION").construct(this, false) << log; + } +} +template +inline void Logger::log(Level level, const char* s, const T& value, const Args&... args) { + base::threading::ScopedLock scopedLock(lock()); + log_(level, 0, s, value, args...); +} +template +inline void Logger::log(Level level, const T& log) { + base::threading::ScopedLock scopedLock(lock()); + log_(level, 0, log); +} +# if ELPP_VERBOSE_LOG +template +inline void Logger::verbose(int vlevel, const char* s, const T& value, const Args&... args) { + base::threading::ScopedLock scopedLock(lock()); + log_(el::Level::Verbose, vlevel, s, value, args...); +} +template +inline void Logger::verbose(int vlevel, const T& log) { + base::threading::ScopedLock scopedLock(lock()); + log_(el::Level::Verbose, vlevel, log); +} +# else +template +inline void Logger::verbose(int, const char*, const T&, const Args&...) { + return; +} +template +inline void Logger::verbose(int, const T&) { + return; +} +# endif // ELPP_VERBOSE_LOG +# define LOGGER_LEVEL_WRITERS(FUNCTION_NAME, LOG_LEVEL)\ +template \ +inline void Logger::FUNCTION_NAME(const char* s, const T& value, const Args&... args) {\ +log(LOG_LEVEL, s, value, args...);\ +}\ +template \ +inline void Logger::FUNCTION_NAME(const T& value) {\ +log(LOG_LEVEL, value);\ +} +# define LOGGER_LEVEL_WRITERS_DISABLED(FUNCTION_NAME, LOG_LEVEL)\ +template \ +inline void Logger::FUNCTION_NAME(const char*, const T&, const Args&...) {\ +return;\ +}\ +template \ +inline void Logger::FUNCTION_NAME(const T&) {\ +return;\ +} + +# if ELPP_INFO_LOG +LOGGER_LEVEL_WRITERS(info, Level::Info) +# else +LOGGER_LEVEL_WRITERS_DISABLED(info, Level::Info) +# endif // ELPP_INFO_LOG +# if ELPP_DEBUG_LOG +LOGGER_LEVEL_WRITERS(debug, Level::Debug) +# else +LOGGER_LEVEL_WRITERS_DISABLED(debug, Level::Debug) +# endif // ELPP_DEBUG_LOG +# if ELPP_WARNING_LOG +LOGGER_LEVEL_WRITERS(warn, Level::Warning) +# else +LOGGER_LEVEL_WRITERS_DISABLED(warn, Level::Warning) +# endif // ELPP_WARNING_LOG +# if ELPP_ERROR_LOG +LOGGER_LEVEL_WRITERS(error, Level::Error) +# else +LOGGER_LEVEL_WRITERS_DISABLED(error, Level::Error) +# endif // ELPP_ERROR_LOG +# if ELPP_FATAL_LOG +LOGGER_LEVEL_WRITERS(fatal, Level::Fatal) +# else +LOGGER_LEVEL_WRITERS_DISABLED(fatal, Level::Fatal) +# endif // ELPP_FATAL_LOG +# if ELPP_TRACE_LOG +LOGGER_LEVEL_WRITERS(trace, Level::Trace) +# else +LOGGER_LEVEL_WRITERS_DISABLED(trace, Level::Trace) +# endif // ELPP_TRACE_LOG +# undef LOGGER_LEVEL_WRITERS +# undef LOGGER_LEVEL_WRITERS_DISABLED +#endif // ELPP_VARIADIC_TEMPLATES_SUPPORTED +#if ELPP_COMPILER_MSVC +# define ELPP_VARIADIC_FUNC_MSVC(variadicFunction, variadicArgs) variadicFunction variadicArgs +# define ELPP_VARIADIC_FUNC_MSVC_RUN(variadicFunction, ...) ELPP_VARIADIC_FUNC_MSVC(variadicFunction, (__VA_ARGS__)) +# define el_getVALength(...) ELPP_VARIADIC_FUNC_MSVC_RUN(el_resolveVALength, 0, ## __VA_ARGS__,\ +10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) +#else +# if ELPP_COMPILER_CLANG +# define el_getVALength(...) el_resolveVALength(0, __VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) +# else +# define el_getVALength(...) el_resolveVALength(0, ## __VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) +# endif // ELPP_COMPILER_CLANG +#endif // ELPP_COMPILER_MSVC +#define el_resolveVALength(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N +#define ELPP_WRITE_LOG(writer, level, dispatchAction, ...) \ +writer(level, __FILE__, __LINE__, ELPP_FUNC, dispatchAction).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__) +#define ELPP_WRITE_LOG_IF(writer, condition, level, dispatchAction, ...) if (condition) \ +writer(level, __FILE__, __LINE__, ELPP_FUNC, dispatchAction).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__) +#define ELPP_WRITE_LOG_EVERY_N(writer, occasion, level, dispatchAction, ...) \ +ELPP->validateEveryNCounter(__FILE__, __LINE__, occasion) && \ +writer(level, __FILE__, __LINE__, ELPP_FUNC, dispatchAction).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__) +#define ELPP_WRITE_LOG_AFTER_N(writer, n, level, dispatchAction, ...) \ +ELPP->validateAfterNCounter(__FILE__, __LINE__, n) && \ +writer(level, __FILE__, __LINE__, ELPP_FUNC, dispatchAction).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__) +#define ELPP_WRITE_LOG_N_TIMES(writer, n, level, dispatchAction, ...) \ +ELPP->validateNTimesCounter(__FILE__, __LINE__, n) && \ +writer(level, __FILE__, __LINE__, ELPP_FUNC, dispatchAction).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__) +#if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING) +class PerformanceTrackingData { + public: + enum class DataType : base::type::EnumType { + Checkpoint = 1, Complete = 2 + }; + // Do not use constructor, will run into multiple definition error, use init(PerformanceTracker*) + explicit PerformanceTrackingData(DataType dataType) : m_performanceTracker(nullptr), + m_dataType(dataType), m_firstCheckpoint(false), m_file(""), m_line(0), m_func("") {} + inline const std::string* blockName(void) const; + inline const struct timeval* startTime(void) const; + inline const struct timeval* endTime(void) const; + inline const struct timeval* lastCheckpointTime(void) const; + inline const base::PerformanceTracker* performanceTracker(void) const { + return m_performanceTracker; + } + inline PerformanceTrackingData::DataType dataType(void) const { + return m_dataType; + } + inline bool firstCheckpoint(void) const { + return m_firstCheckpoint; + } + inline std::string checkpointId(void) const { + return m_checkpointId; + } + inline const char* file(void) const { + return m_file; + } + inline base::type::LineNumber line(void) const { + return m_line; + } + inline const char* func(void) const { + return m_func; + } + inline const base::type::string_t* formattedTimeTaken() const { + return &m_formattedTimeTaken; + } + inline const std::string& loggerId(void) const; + private: + base::PerformanceTracker* m_performanceTracker; + base::type::string_t m_formattedTimeTaken; + PerformanceTrackingData::DataType m_dataType; + bool m_firstCheckpoint; + std::string m_checkpointId; + const char* m_file; + base::type::LineNumber m_line; + const char* m_func; + inline void init(base::PerformanceTracker* performanceTracker, bool firstCheckpoint = false) { + m_performanceTracker = performanceTracker; + m_firstCheckpoint = firstCheckpoint; + } + + friend class el::base::PerformanceTracker; +}; +namespace base { +/// @brief Represents performanceTracker block of code that conditionally adds performance status to log +/// either when goes outside the scope of when checkpoint() is called +class PerformanceTracker : public base::threading::ThreadSafe, public Loggable { + public: + PerformanceTracker(const std::string& blockName, + base::TimestampUnit timestampUnit = base::TimestampUnit::Millisecond, + const std::string& loggerId = std::string(el::base::consts::kPerformanceLoggerId), + bool scopedLog = true, Level level = base::consts::kPerformanceTrackerDefaultLevel); + /// @brief Copy constructor + PerformanceTracker(const PerformanceTracker& t) : + m_blockName(t.m_blockName), m_timestampUnit(t.m_timestampUnit), m_loggerId(t.m_loggerId), m_scopedLog(t.m_scopedLog), + m_level(t.m_level), m_hasChecked(t.m_hasChecked), m_lastCheckpointId(t.m_lastCheckpointId), m_enabled(t.m_enabled), + m_startTime(t.m_startTime), m_endTime(t.m_endTime), m_lastCheckpointTime(t.m_lastCheckpointTime) { + } + virtual ~PerformanceTracker(void); + /// @brief A checkpoint for current performanceTracker block. + void checkpoint(const std::string& id = std::string(), const char* file = __FILE__, + base::type::LineNumber line = __LINE__, + const char* func = ""); + inline Level level(void) const { + return m_level; + } + private: + std::string m_blockName; + base::TimestampUnit m_timestampUnit; + std::string m_loggerId; + bool m_scopedLog; + Level m_level; + bool m_hasChecked; + std::string m_lastCheckpointId; + bool m_enabled; + struct timeval m_startTime, m_endTime, m_lastCheckpointTime; + + PerformanceTracker(void); + + friend class el::PerformanceTrackingData; + friend class base::DefaultPerformanceTrackingCallback; + + const inline base::type::string_t getFormattedTimeTaken() const { + return getFormattedTimeTaken(m_startTime); + } + + const base::type::string_t getFormattedTimeTaken(struct timeval startTime) const; + + virtual inline void log(el::base::type::ostream_t& os) const { + os << getFormattedTimeTaken(); + } +}; +class DefaultPerformanceTrackingCallback : public PerformanceTrackingCallback { + protected: + void handle(const PerformanceTrackingData* data) { + m_data = data; + base::type::stringstream_t ss; + if (m_data->dataType() == PerformanceTrackingData::DataType::Complete) { + ss << ELPP_LITERAL("Executed [") << m_data->blockName()->c_str() << ELPP_LITERAL("] in [") << + *m_data->formattedTimeTaken() << ELPP_LITERAL("]"); + } else { + ss << ELPP_LITERAL("Performance checkpoint"); + if (!m_data->checkpointId().empty()) { + ss << ELPP_LITERAL(" [") << m_data->checkpointId().c_str() << ELPP_LITERAL("]"); + } + ss << ELPP_LITERAL(" for block [") << m_data->blockName()->c_str() << ELPP_LITERAL("] : [") << + *m_data->performanceTracker(); + if (!ELPP->hasFlag(LoggingFlag::DisablePerformanceTrackingCheckpointComparison) + && m_data->performanceTracker()->m_hasChecked) { + ss << ELPP_LITERAL(" ([") << *m_data->formattedTimeTaken() << ELPP_LITERAL("] from "); + if (m_data->performanceTracker()->m_lastCheckpointId.empty()) { + ss << ELPP_LITERAL("last checkpoint"); + } else { + ss << ELPP_LITERAL("checkpoint '") << m_data->performanceTracker()->m_lastCheckpointId.c_str() << ELPP_LITERAL("'"); + } + ss << ELPP_LITERAL(")]"); + } else { + ss << ELPP_LITERAL("]"); + } + } + el::base::Writer(m_data->performanceTracker()->level(), m_data->file(), m_data->line(), m_data->func()).construct(1, + m_data->loggerId().c_str()) << ss.str(); + } + private: + const PerformanceTrackingData* m_data; +}; +} // namespace base +inline const std::string* PerformanceTrackingData::blockName() const { + return const_cast(&m_performanceTracker->m_blockName); +} +inline const struct timeval* PerformanceTrackingData::startTime() const { + return const_cast(&m_performanceTracker->m_startTime); +} +inline const struct timeval* PerformanceTrackingData::endTime() const { + return const_cast(&m_performanceTracker->m_endTime); +} +inline const struct timeval* PerformanceTrackingData::lastCheckpointTime() const { + return const_cast(&m_performanceTracker->m_lastCheckpointTime); +} +inline const std::string& PerformanceTrackingData::loggerId(void) const { + return m_performanceTracker->m_loggerId; +} +#endif // defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING) +namespace base { +/// @brief Contains some internal debugging tools like crash handler and stack tracer +namespace debug { +#if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_CRASH_LOG) +class StackTrace : base::NoCopy { + public: + static const unsigned int kMaxStack = 64; + static const unsigned int kStackStart = 2; // We want to skip c'tor and StackTrace::generateNew() + class StackTraceEntry { + public: + StackTraceEntry(std::size_t index, const char* loc, const char* demang, const char* hex, const char* addr); + StackTraceEntry(std::size_t index, char* loc) : + m_index(index), + m_location(loc) { + } + std::size_t m_index; + std::string m_location; + std::string m_demangled; + std::string m_hex; + std::string m_addr; + friend std::ostream& operator<<(std::ostream& ss, const StackTraceEntry& si); + + private: + StackTraceEntry(void); + }; + + StackTrace(void) { + generateNew(); + } + + virtual ~StackTrace(void) { + } + + inline std::vector& getLatestStack(void) { + return m_stack; + } + + friend std::ostream& operator<<(std::ostream& os, const StackTrace& st); + + private: + std::vector m_stack; + + void generateNew(void); +}; +/// @brief Handles unexpected crashes +class CrashHandler : base::NoCopy { + public: + typedef void (*Handler)(int); + + explicit CrashHandler(bool useDefault); + explicit CrashHandler(const Handler& cHandler) { + setHandler(cHandler); + } + void setHandler(const Handler& cHandler); + + private: + Handler m_handler; +}; +#else +class CrashHandler { + public: + explicit CrashHandler(bool) {} +}; +#endif // defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_CRASH_LOG) +} // namespace debug +} // namespace base +extern base::debug::CrashHandler elCrashHandler; +#define MAKE_LOGGABLE(ClassType, ClassInstance, OutputStreamInstance) \ +el::base::type::ostream_t& operator<<(el::base::type::ostream_t& OutputStreamInstance, const ClassType& ClassInstance) +/// @brief Initializes syslog with process ID, options and facility. calls closelog() on d'tor +class SysLogInitializer { + public: + SysLogInitializer(const char* processIdent, int options = 0, int facility = 0) { +#if defined(ELPP_SYSLOG) + openlog(processIdent, options, facility); +#else + ELPP_UNUSED(processIdent); + ELPP_UNUSED(options); + ELPP_UNUSED(facility); +#endif // defined(ELPP_SYSLOG) + } + virtual ~SysLogInitializer(void) { +#if defined(ELPP_SYSLOG) + closelog(); +#endif // defined(ELPP_SYSLOG) + } +}; +#define ELPP_INITIALIZE_SYSLOG(id, opt, fac) el::SysLogInitializer elSyslogInit(id, opt, fac) +/// @brief Static helpers for developers +class Helpers : base::StaticClass { + public: + /// @brief Shares logging repository (base::Storage) + static inline void setStorage(base::type::StoragePointer storage) { + ELPP = storage; + } + /// @return Main storage repository + static inline base::type::StoragePointer storage() { + return ELPP; + } + /// @brief Sets application arguments and figures out whats active for logging and whats not. + static inline void setArgs(int argc, char** argv) { + ELPP->setApplicationArguments(argc, argv); + } + /// @copydoc setArgs(int argc, char** argv) + static inline void setArgs(int argc, const char** argv) { + ELPP->setApplicationArguments(argc, const_cast(argv)); + } + /// @brief Sets thread name for current thread. Requires std::thread + static inline void setThreadName(const std::string& name) { + ELPP->setThreadName(name); + } + static inline std::string getThreadName() { + return ELPP->getThreadName(base::threading::getCurrentThreadId()); + } +#if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_CRASH_LOG) + /// @brief Overrides default crash handler and installs custom handler. + /// @param crashHandler A functor with no return type that takes single int argument. + /// Handler is a typedef with specification: void (*Handler)(int) + static inline void setCrashHandler(const el::base::debug::CrashHandler::Handler& crashHandler) { + el::elCrashHandler.setHandler(crashHandler); + } + /// @brief Abort due to crash with signal in parameter + /// @param sig Crash signal + static void crashAbort(int sig, const char* sourceFile = "", unsigned int long line = 0); + /// @brief Logs reason of crash as per sig + /// @param sig Crash signal + /// @param stackTraceIfAvailable Includes stack trace if available + /// @param level Logging level + /// @param logger Logger to use for logging + static void logCrashReason(int sig, bool stackTraceIfAvailable = false, + Level level = Level::Fatal, const char* logger = base::consts::kDefaultLoggerId); +#endif // defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_CRASH_LOG) + /// @brief Installs pre rollout callback, this callback is triggered when log file is about to be rolled out + /// (can be useful for backing up) + static inline void installPreRollOutCallback(const PreRollOutCallback& callback) { + ELPP->setPreRollOutCallback(callback); + } + /// @brief Uninstalls pre rollout callback + static inline void uninstallPreRollOutCallback(void) { + ELPP->unsetPreRollOutCallback(); + } + /// @brief Installs post log dispatch callback, this callback is triggered when log is dispatched + template + static inline bool installLogDispatchCallback(const std::string& id) { + return ELPP->installLogDispatchCallback(id); + } + /// @brief Uninstalls log dispatch callback + template + static inline void uninstallLogDispatchCallback(const std::string& id) { + ELPP->uninstallLogDispatchCallback(id); + } + template + static inline T* logDispatchCallback(const std::string& id) { + return ELPP->logDispatchCallback(id); + } +#if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING) + /// @brief Installs post performance tracking callback, this callback is triggered when performance tracking is finished + template + static inline bool installPerformanceTrackingCallback(const std::string& id) { + return ELPP->installPerformanceTrackingCallback(id); + } + /// @brief Uninstalls post performance tracking handler + template + static inline void uninstallPerformanceTrackingCallback(const std::string& id) { + ELPP->uninstallPerformanceTrackingCallback(id); + } + template + static inline T* performanceTrackingCallback(const std::string& id) { + return ELPP->performanceTrackingCallback(id); + } +#endif // defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING) + /// @brief Converts template to std::string - useful for loggable classes to log containers within log(std::ostream&) const + template + static std::string convertTemplateToStdString(const T& templ) { + el::Logger* logger = + ELPP->registeredLoggers()->get(el::base::consts::kDefaultLoggerId); + if (logger == nullptr) { + return std::string(); + } + base::MessageBuilder b; + b.initialize(logger); + logger->acquireLock(); + b << templ; +#if defined(ELPP_UNICODE) + std::string s = std::string(logger->stream().str().begin(), logger->stream().str().end()); +#else + std::string s = logger->stream().str(); +#endif // defined(ELPP_UNICODE) + logger->stream().str(ELPP_LITERAL("")); + logger->releaseLock(); + return s; + } + /// @brief Returns command line arguments (pointer) provided to easylogging++ + static inline const el::base::utils::CommandLineArgs* commandLineArgs(void) { + return ELPP->commandLineArgs(); + } + /// @brief Installs user defined format specifier and handler + static inline void installCustomFormatSpecifier(const CustomFormatSpecifier& customFormatSpecifier) { + ELPP->installCustomFormatSpecifier(customFormatSpecifier); + } + /// @brief Uninstalls user defined format specifier and handler + static inline bool uninstallCustomFormatSpecifier(const char* formatSpecifier) { + return ELPP->uninstallCustomFormatSpecifier(formatSpecifier); + } + /// @brief Returns true if custom format specifier is installed + static inline bool hasCustomFormatSpecifier(const char* formatSpecifier) { + return ELPP->hasCustomFormatSpecifier(formatSpecifier); + } + static inline void validateFileRolling(Logger* logger, Level level) { + if (logger == nullptr) return; + logger->m_typedConfigurations->validateFileRolling(level, ELPP->preRollOutCallback()); + } +}; +/// @brief Static helpers to deal with loggers and their configurations +class Loggers : base::StaticClass { + public: + /// @brief Gets existing or registers new logger + static Logger* getLogger(const std::string& identity, bool registerIfNotAvailable = true); + /// @brief Changes default log builder for future loggers + static void setDefaultLogBuilder(el::LogBuilderPtr& logBuilderPtr); + /// @brief Installs logger registration callback, this callback is triggered when new logger is registered + template + static inline bool installLoggerRegistrationCallback(const std::string& id) { + return ELPP->registeredLoggers()->installLoggerRegistrationCallback(id); + } + /// @brief Uninstalls log dispatch callback + template + static inline void uninstallLoggerRegistrationCallback(const std::string& id) { + ELPP->registeredLoggers()->uninstallLoggerRegistrationCallback(id); + } + template + static inline T* loggerRegistrationCallback(const std::string& id) { + return ELPP->registeredLoggers()->loggerRegistrationCallback(id); + } + /// @brief Unregisters logger - use it only when you know what you are doing, you may unregister + /// loggers initialized / used by third-party libs. + static bool unregisterLogger(const std::string& identity); + /// @brief Whether or not logger with id is registered + static bool hasLogger(const std::string& identity); + /// @brief Reconfigures specified logger with new configurations + static Logger* reconfigureLogger(Logger* logger, const Configurations& configurations); + /// @brief Reconfigures logger with new configurations after looking it up using identity + static Logger* reconfigureLogger(const std::string& identity, const Configurations& configurations); + /// @brief Reconfigures logger's single configuration + static Logger* reconfigureLogger(const std::string& identity, ConfigurationType configurationType, + const std::string& value); + /// @brief Reconfigures all the existing loggers with new configurations + static void reconfigureAllLoggers(const Configurations& configurations); + /// @brief Reconfigures single configuration for all the loggers + static inline void reconfigureAllLoggers(ConfigurationType configurationType, const std::string& value) { + reconfigureAllLoggers(Level::Global, configurationType, value); + } + /// @brief Reconfigures single configuration for all the loggers for specified level + static void reconfigureAllLoggers(Level level, ConfigurationType configurationType, + const std::string& value); + /// @brief Sets default configurations. This configuration is used for future (and conditionally for existing) loggers + static void setDefaultConfigurations(const Configurations& configurations, + bool reconfigureExistingLoggers = false); + /// @brief Returns current default + static const Configurations* defaultConfigurations(void); + /// @brief Returns log stream reference pointer if needed by user + static const base::LogStreamsReferenceMap* logStreamsReference(void); + /// @brief Default typed configuration based on existing defaultConf + static base::TypedConfigurations defaultTypedConfigurations(void); + /// @brief Populates all logger IDs in current repository. + /// @param [out] targetList List of fill up. + static std::vector* populateAllLoggerIds(std::vector* targetList); + /// @brief Sets configurations from global configuration file. + static void configureFromGlobal(const char* globalConfigurationFilePath); + /// @brief Configures loggers using command line arg. Ensure you have already set command line args, + /// @return False if invalid argument or argument with no value provided, true if attempted to configure logger. + /// If true is returned that does not mean it has been configured successfully, it only means that it + /// has attempeted to configure logger using configuration file provided in argument + static bool configureFromArg(const char* argKey); + /// @brief Flushes all loggers for all levels - Be careful if you dont know how many loggers are registered + static void flushAll(void); + /// @brief Adds logging flag used internally. + static inline void addFlag(LoggingFlag flag) { + ELPP->addFlag(flag); + } + /// @brief Removes logging flag used internally. + static inline void removeFlag(LoggingFlag flag) { + ELPP->removeFlag(flag); + } + /// @brief Determines whether or not certain flag is active + static inline bool hasFlag(LoggingFlag flag) { + return ELPP->hasFlag(flag); + } + /// @brief Adds flag and removes it when scope goes out + class ScopedAddFlag { + public: + ScopedAddFlag(LoggingFlag flag) : m_flag(flag) { + Loggers::addFlag(m_flag); + } + ~ScopedAddFlag(void) { + Loggers::removeFlag(m_flag); + } + private: + LoggingFlag m_flag; + }; + /// @brief Removes flag and add it when scope goes out + class ScopedRemoveFlag { + public: + ScopedRemoveFlag(LoggingFlag flag) : m_flag(flag) { + Loggers::removeFlag(m_flag); + } + ~ScopedRemoveFlag(void) { + Loggers::addFlag(m_flag); + } + private: + LoggingFlag m_flag; + }; + /// @brief Sets hierarchy for logging. Needs to enable logging flag (HierarchicalLogging) + static void setLoggingLevel(Level level) { + ELPP->setLoggingLevel(level); + } + /// @brief Sets verbose level on the fly + static void setVerboseLevel(base::type::VerboseLevel level); + /// @brief Gets current verbose level + static base::type::VerboseLevel verboseLevel(void); + /// @brief Sets vmodules as specified (on the fly) + static void setVModules(const char* modules); + /// @brief Clears vmodules + static void clearVModules(void); +}; +class VersionInfo : base::StaticClass { + public: + /// @brief Current version number + static const std::string version(void); + + /// @brief Release date of current version + static const std::string releaseDate(void); +}; +} // namespace el +#undef VLOG_IS_ON +/// @brief Determines whether verbose logging is on for specified level current file. +#define VLOG_IS_ON(verboseLevel) (ELPP->vRegistry()->allowed(verboseLevel, __FILE__)) +#undef TIMED_BLOCK +#undef TIMED_SCOPE +#undef TIMED_SCOPE_IF +#undef TIMED_FUNC +#undef TIMED_FUNC_IF +#undef ELPP_MIN_UNIT +#if defined(ELPP_PERFORMANCE_MICROSECONDS) +# define ELPP_MIN_UNIT el::base::TimestampUnit::Microsecond +#else +# define ELPP_MIN_UNIT el::base::TimestampUnit::Millisecond +#endif // (defined(ELPP_PERFORMANCE_MICROSECONDS)) +/// @brief Performance tracked scope. Performance gets written when goes out of scope using +/// 'performance' logger. +/// +/// @detail Please note in order to check the performance at a certain time you can use obj->checkpoint(); +/// @see el::base::PerformanceTracker +/// @see el::base::PerformanceTracker::checkpoint +// Note: Do not surround this definition with null macro because of obj instance +#define TIMED_SCOPE_IF(obj, blockname, condition) el::base::type::PerformanceTrackerPtr obj( condition ? \ + new el::base::PerformanceTracker(blockname, ELPP_MIN_UNIT) : nullptr ) +#define TIMED_SCOPE(obj, blockname) TIMED_SCOPE_IF(obj, blockname, true) +#define TIMED_BLOCK(obj, blockName) for (struct { int i; el::base::type::PerformanceTrackerPtr timer; } obj = { 0, \ + el::base::type::PerformanceTrackerPtr(new el::base::PerformanceTracker(blockName, ELPP_MIN_UNIT)) }; obj.i < 1; ++obj.i) +/// @brief Performance tracked function. Performance gets written when goes out of scope using +/// 'performance' logger. +/// +/// @detail Please note in order to check the performance at a certain time you can use obj->checkpoint(); +/// @see el::base::PerformanceTracker +/// @see el::base::PerformanceTracker::checkpoint +#define TIMED_FUNC_IF(obj,condition) TIMED_SCOPE_IF(obj, ELPP_FUNC, condition) +#define TIMED_FUNC(obj) TIMED_SCOPE(obj, ELPP_FUNC) +#undef PERFORMANCE_CHECKPOINT +#undef PERFORMANCE_CHECKPOINT_WITH_ID +#define PERFORMANCE_CHECKPOINT(obj) obj->checkpoint(std::string(), __FILE__, __LINE__, ELPP_FUNC) +#define PERFORMANCE_CHECKPOINT_WITH_ID(obj, id) obj->checkpoint(id, __FILE__, __LINE__, ELPP_FUNC) +#undef ELPP_COUNTER +#undef ELPP_COUNTER_POS +/// @brief Gets hit counter for file/line +#define ELPP_COUNTER (ELPP->hitCounters()->getCounter(__FILE__, __LINE__)) +/// @brief Gets hit counter position for file/line, -1 if not registered yet +#define ELPP_COUNTER_POS (ELPP_COUNTER == nullptr ? -1 : ELPP_COUNTER->hitCounts()) +// Undef levels to support LOG(LEVEL) +#undef INFO +#undef WARNING +#undef DEBUG +#undef ERROR +#undef FATAL +#undef TRACE +#undef VERBOSE +// Undef existing +#undef CINFO +#undef CWARNING +#undef CDEBUG +#undef CFATAL +#undef CERROR +#undef CTRACE +#undef CVERBOSE +#undef CINFO_IF +#undef CWARNING_IF +#undef CDEBUG_IF +#undef CERROR_IF +#undef CFATAL_IF +#undef CTRACE_IF +#undef CVERBOSE_IF +#undef CINFO_EVERY_N +#undef CWARNING_EVERY_N +#undef CDEBUG_EVERY_N +#undef CERROR_EVERY_N +#undef CFATAL_EVERY_N +#undef CTRACE_EVERY_N +#undef CVERBOSE_EVERY_N +#undef CINFO_AFTER_N +#undef CWARNING_AFTER_N +#undef CDEBUG_AFTER_N +#undef CERROR_AFTER_N +#undef CFATAL_AFTER_N +#undef CTRACE_AFTER_N +#undef CVERBOSE_AFTER_N +#undef CINFO_N_TIMES +#undef CWARNING_N_TIMES +#undef CDEBUG_N_TIMES +#undef CERROR_N_TIMES +#undef CFATAL_N_TIMES +#undef CTRACE_N_TIMES +#undef CVERBOSE_N_TIMES +// Normal logs +#if ELPP_INFO_LOG +# define CINFO(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Info, dispatchAction, __VA_ARGS__) +#else +# define CINFO(writer, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_INFO_LOG +#if ELPP_WARNING_LOG +# define CWARNING(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Warning, dispatchAction, __VA_ARGS__) +#else +# define CWARNING(writer, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_WARNING_LOG +#if ELPP_DEBUG_LOG +# define CDEBUG(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Debug, dispatchAction, __VA_ARGS__) +#else +# define CDEBUG(writer, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_DEBUG_LOG +#if ELPP_ERROR_LOG +# define CERROR(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Error, dispatchAction, __VA_ARGS__) +#else +# define CERROR(writer, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_ERROR_LOG +#if ELPP_FATAL_LOG +# define CFATAL(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Fatal, dispatchAction, __VA_ARGS__) +#else +# define CFATAL(writer, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_FATAL_LOG +#if ELPP_TRACE_LOG +# define CTRACE(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Trace, dispatchAction, __VA_ARGS__) +#else +# define CTRACE(writer, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_TRACE_LOG +#if ELPP_VERBOSE_LOG +# define CVERBOSE(writer, vlevel, dispatchAction, ...) if (VLOG_IS_ON(vlevel)) writer(\ +el::Level::Verbose, __FILE__, __LINE__, ELPP_FUNC, dispatchAction, vlevel).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__) +#else +# define CVERBOSE(writer, vlevel, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_VERBOSE_LOG +// Conditional logs +#if ELPP_INFO_LOG +# define CINFO_IF(writer, condition_, dispatchAction, ...) \ +ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Info, dispatchAction, __VA_ARGS__) +#else +# define CINFO_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_INFO_LOG +#if ELPP_WARNING_LOG +# define CWARNING_IF(writer, condition_, dispatchAction, ...)\ +ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Warning, dispatchAction, __VA_ARGS__) +#else +# define CWARNING_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_WARNING_LOG +#if ELPP_DEBUG_LOG +# define CDEBUG_IF(writer, condition_, dispatchAction, ...)\ +ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Debug, dispatchAction, __VA_ARGS__) +#else +# define CDEBUG_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_DEBUG_LOG +#if ELPP_ERROR_LOG +# define CERROR_IF(writer, condition_, dispatchAction, ...)\ +ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Error, dispatchAction, __VA_ARGS__) +#else +# define CERROR_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_ERROR_LOG +#if ELPP_FATAL_LOG +# define CFATAL_IF(writer, condition_, dispatchAction, ...)\ +ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Fatal, dispatchAction, __VA_ARGS__) +#else +# define CFATAL_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_FATAL_LOG +#if ELPP_TRACE_LOG +# define CTRACE_IF(writer, condition_, dispatchAction, ...)\ +ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Trace, dispatchAction, __VA_ARGS__) +#else +# define CTRACE_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_TRACE_LOG +#if ELPP_VERBOSE_LOG +# define CVERBOSE_IF(writer, condition_, vlevel, dispatchAction, ...) if (VLOG_IS_ON(vlevel) && (condition_)) writer( \ +el::Level::Verbose, __FILE__, __LINE__, ELPP_FUNC, dispatchAction, vlevel).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__) +#else +# define CVERBOSE_IF(writer, condition_, vlevel, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_VERBOSE_LOG +// Occasional logs +#if ELPP_INFO_LOG +# define CINFO_EVERY_N(writer, occasion, dispatchAction, ...)\ +ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Info, dispatchAction, __VA_ARGS__) +#else +# define CINFO_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_INFO_LOG +#if ELPP_WARNING_LOG +# define CWARNING_EVERY_N(writer, occasion, dispatchAction, ...)\ +ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Warning, dispatchAction, __VA_ARGS__) +#else +# define CWARNING_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_WARNING_LOG +#if ELPP_DEBUG_LOG +# define CDEBUG_EVERY_N(writer, occasion, dispatchAction, ...)\ +ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Debug, dispatchAction, __VA_ARGS__) +#else +# define CDEBUG_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_DEBUG_LOG +#if ELPP_ERROR_LOG +# define CERROR_EVERY_N(writer, occasion, dispatchAction, ...)\ +ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Error, dispatchAction, __VA_ARGS__) +#else +# define CERROR_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_ERROR_LOG +#if ELPP_FATAL_LOG +# define CFATAL_EVERY_N(writer, occasion, dispatchAction, ...)\ +ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Fatal, dispatchAction, __VA_ARGS__) +#else +# define CFATAL_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_FATAL_LOG +#if ELPP_TRACE_LOG +# define CTRACE_EVERY_N(writer, occasion, dispatchAction, ...)\ +ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Trace, dispatchAction, __VA_ARGS__) +#else +# define CTRACE_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_TRACE_LOG +#if ELPP_VERBOSE_LOG +# define CVERBOSE_EVERY_N(writer, occasion, vlevel, dispatchAction, ...)\ +CVERBOSE_IF(writer, ELPP->validateEveryNCounter(__FILE__, __LINE__, occasion), vlevel, dispatchAction, __VA_ARGS__) +#else +# define CVERBOSE_EVERY_N(writer, occasion, vlevel, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_VERBOSE_LOG +// After N logs +#if ELPP_INFO_LOG +# define CINFO_AFTER_N(writer, n, dispatchAction, ...)\ +ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Info, dispatchAction, __VA_ARGS__) +#else +# define CINFO_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_INFO_LOG +#if ELPP_WARNING_LOG +# define CWARNING_AFTER_N(writer, n, dispatchAction, ...)\ +ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Warning, dispatchAction, __VA_ARGS__) +#else +# define CWARNING_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_WARNING_LOG +#if ELPP_DEBUG_LOG +# define CDEBUG_AFTER_N(writer, n, dispatchAction, ...)\ +ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Debug, dispatchAction, __VA_ARGS__) +#else +# define CDEBUG_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_DEBUG_LOG +#if ELPP_ERROR_LOG +# define CERROR_AFTER_N(writer, n, dispatchAction, ...)\ +ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Error, dispatchAction, __VA_ARGS__) +#else +# define CERROR_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_ERROR_LOG +#if ELPP_FATAL_LOG +# define CFATAL_AFTER_N(writer, n, dispatchAction, ...)\ +ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Fatal, dispatchAction, __VA_ARGS__) +#else +# define CFATAL_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_FATAL_LOG +#if ELPP_TRACE_LOG +# define CTRACE_AFTER_N(writer, n, dispatchAction, ...)\ +ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Trace, dispatchAction, __VA_ARGS__) +#else +# define CTRACE_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_TRACE_LOG +#if ELPP_VERBOSE_LOG +# define CVERBOSE_AFTER_N(writer, n, vlevel, dispatchAction, ...)\ +CVERBOSE_IF(writer, ELPP->validateAfterNCounter(__FILE__, __LINE__, n), vlevel, dispatchAction, __VA_ARGS__) +#else +# define CVERBOSE_AFTER_N(writer, n, vlevel, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_VERBOSE_LOG +// N Times logs +#if ELPP_INFO_LOG +# define CINFO_N_TIMES(writer, n, dispatchAction, ...)\ +ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Info, dispatchAction, __VA_ARGS__) +#else +# define CINFO_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_INFO_LOG +#if ELPP_WARNING_LOG +# define CWARNING_N_TIMES(writer, n, dispatchAction, ...)\ +ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Warning, dispatchAction, __VA_ARGS__) +#else +# define CWARNING_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_WARNING_LOG +#if ELPP_DEBUG_LOG +# define CDEBUG_N_TIMES(writer, n, dispatchAction, ...)\ +ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Debug, dispatchAction, __VA_ARGS__) +#else +# define CDEBUG_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_DEBUG_LOG +#if ELPP_ERROR_LOG +# define CERROR_N_TIMES(writer, n, dispatchAction, ...)\ +ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Error, dispatchAction, __VA_ARGS__) +#else +# define CERROR_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_ERROR_LOG +#if ELPP_FATAL_LOG +# define CFATAL_N_TIMES(writer, n, dispatchAction, ...)\ +ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Fatal, dispatchAction, __VA_ARGS__) +#else +# define CFATAL_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_FATAL_LOG +#if ELPP_TRACE_LOG +# define CTRACE_N_TIMES(writer, n, dispatchAction, ...)\ +ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Trace, dispatchAction, __VA_ARGS__) +#else +# define CTRACE_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_TRACE_LOG +#if ELPP_VERBOSE_LOG +# define CVERBOSE_N_TIMES(writer, n, vlevel, dispatchAction, ...)\ +CVERBOSE_IF(writer, ELPP->validateNTimesCounter(__FILE__, __LINE__, n), vlevel, dispatchAction, __VA_ARGS__) +#else +# define CVERBOSE_N_TIMES(writer, n, vlevel, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_VERBOSE_LOG +// +// Custom Loggers - Requires (level, dispatchAction, loggerId/s) +// +// undef existing +#undef CLOG +#undef CLOG_VERBOSE +#undef CVLOG +#undef CLOG_IF +#undef CLOG_VERBOSE_IF +#undef CVLOG_IF +#undef CLOG_EVERY_N +#undef CVLOG_EVERY_N +#undef CLOG_AFTER_N +#undef CVLOG_AFTER_N +#undef CLOG_N_TIMES +#undef CVLOG_N_TIMES +// Normal logs +#define CLOG(LEVEL, ...)\ +C##LEVEL(el::base::Writer, el::base::DispatchAction::NormalLog, __VA_ARGS__) +#define CVLOG(vlevel, ...) CVERBOSE(el::base::Writer, vlevel, el::base::DispatchAction::NormalLog, __VA_ARGS__) +// Conditional logs +#define CLOG_IF(condition, LEVEL, ...)\ +C##LEVEL##_IF(el::base::Writer, condition, el::base::DispatchAction::NormalLog, __VA_ARGS__) +#define CVLOG_IF(condition, vlevel, ...)\ +CVERBOSE_IF(el::base::Writer, condition, vlevel, el::base::DispatchAction::NormalLog, __VA_ARGS__) +// Hit counts based logs +#define CLOG_EVERY_N(n, LEVEL, ...)\ +C##LEVEL##_EVERY_N(el::base::Writer, n, el::base::DispatchAction::NormalLog, __VA_ARGS__) +#define CVLOG_EVERY_N(n, vlevel, ...)\ +CVERBOSE_EVERY_N(el::base::Writer, n, vlevel, el::base::DispatchAction::NormalLog, __VA_ARGS__) +#define CLOG_AFTER_N(n, LEVEL, ...)\ +C##LEVEL##_AFTER_N(el::base::Writer, n, el::base::DispatchAction::NormalLog, __VA_ARGS__) +#define CVLOG_AFTER_N(n, vlevel, ...)\ +CVERBOSE_AFTER_N(el::base::Writer, n, vlevel, el::base::DispatchAction::NormalLog, __VA_ARGS__) +#define CLOG_N_TIMES(n, LEVEL, ...)\ +C##LEVEL##_N_TIMES(el::base::Writer, n, el::base::DispatchAction::NormalLog, __VA_ARGS__) +#define CVLOG_N_TIMES(n, vlevel, ...)\ +CVERBOSE_N_TIMES(el::base::Writer, n, vlevel, el::base::DispatchAction::NormalLog, __VA_ARGS__) +// +// Default Loggers macro using CLOG(), CLOG_VERBOSE() and CVLOG() macros +// +// undef existing +#undef LOG +#undef VLOG +#undef LOG_IF +#undef VLOG_IF +#undef LOG_EVERY_N +#undef VLOG_EVERY_N +#undef LOG_AFTER_N +#undef VLOG_AFTER_N +#undef LOG_N_TIMES +#undef VLOG_N_TIMES +#undef ELPP_CURR_FILE_LOGGER_ID +#if defined(ELPP_DEFAULT_LOGGER) +# define ELPP_CURR_FILE_LOGGER_ID ELPP_DEFAULT_LOGGER +#else +# define ELPP_CURR_FILE_LOGGER_ID el::base::consts::kDefaultLoggerId +#endif +#undef ELPP_TRACE +#define ELPP_TRACE CLOG(TRACE, ELPP_CURR_FILE_LOGGER_ID) +// Normal logs +#define LOG(LEVEL) CLOG(LEVEL, ELPP_CURR_FILE_LOGGER_ID) +#define VLOG(vlevel) CVLOG(vlevel, ELPP_CURR_FILE_LOGGER_ID) +// Conditional logs +#define LOG_IF(condition, LEVEL) CLOG_IF(condition, LEVEL, ELPP_CURR_FILE_LOGGER_ID) +#define VLOG_IF(condition, vlevel) CVLOG_IF(condition, vlevel, ELPP_CURR_FILE_LOGGER_ID) +// Hit counts based logs +#define LOG_EVERY_N(n, LEVEL) CLOG_EVERY_N(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID) +#define VLOG_EVERY_N(n, vlevel) CVLOG_EVERY_N(n, vlevel, ELPP_CURR_FILE_LOGGER_ID) +#define LOG_AFTER_N(n, LEVEL) CLOG_AFTER_N(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID) +#define VLOG_AFTER_N(n, vlevel) CVLOG_AFTER_N(n, vlevel, ELPP_CURR_FILE_LOGGER_ID) +#define LOG_N_TIMES(n, LEVEL) CLOG_N_TIMES(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID) +#define VLOG_N_TIMES(n, vlevel) CVLOG_N_TIMES(n, vlevel, ELPP_CURR_FILE_LOGGER_ID) +// Generic PLOG() +#undef CPLOG +#undef CPLOG_IF +#undef PLOG +#undef PLOG_IF +#undef DCPLOG +#undef DCPLOG_IF +#undef DPLOG +#undef DPLOG_IF +#define CPLOG(LEVEL, ...)\ +C##LEVEL(el::base::PErrorWriter, el::base::DispatchAction::NormalLog, __VA_ARGS__) +#define CPLOG_IF(condition, LEVEL, ...)\ +C##LEVEL##_IF(el::base::PErrorWriter, condition, el::base::DispatchAction::NormalLog, __VA_ARGS__) +#define DCPLOG(LEVEL, ...)\ +if (ELPP_DEBUG_LOG) C##LEVEL(el::base::PErrorWriter, el::base::DispatchAction::NormalLog, __VA_ARGS__) +#define DCPLOG_IF(condition, LEVEL, ...)\ +C##LEVEL##_IF(el::base::PErrorWriter, (ELPP_DEBUG_LOG) && (condition), el::base::DispatchAction::NormalLog, __VA_ARGS__) +#define PLOG(LEVEL) CPLOG(LEVEL, ELPP_CURR_FILE_LOGGER_ID) +#define PLOG_IF(condition, LEVEL) CPLOG_IF(condition, LEVEL, ELPP_CURR_FILE_LOGGER_ID) +#define DPLOG(LEVEL) DCPLOG(LEVEL, ELPP_CURR_FILE_LOGGER_ID) +#define DPLOG_IF(condition, LEVEL) DCPLOG_IF(condition, LEVEL, ELPP_CURR_FILE_LOGGER_ID) +// Generic SYSLOG() +#undef CSYSLOG +#undef CSYSLOG_IF +#undef CSYSLOG_EVERY_N +#undef CSYSLOG_AFTER_N +#undef CSYSLOG_N_TIMES +#undef SYSLOG +#undef SYSLOG_IF +#undef SYSLOG_EVERY_N +#undef SYSLOG_AFTER_N +#undef SYSLOG_N_TIMES +#undef DCSYSLOG +#undef DCSYSLOG_IF +#undef DCSYSLOG_EVERY_N +#undef DCSYSLOG_AFTER_N +#undef DCSYSLOG_N_TIMES +#undef DSYSLOG +#undef DSYSLOG_IF +#undef DSYSLOG_EVERY_N +#undef DSYSLOG_AFTER_N +#undef DSYSLOG_N_TIMES +#if defined(ELPP_SYSLOG) +# define CSYSLOG(LEVEL, ...)\ +C##LEVEL(el::base::Writer, el::base::DispatchAction::SysLog, __VA_ARGS__) +# define CSYSLOG_IF(condition, LEVEL, ...)\ +C##LEVEL##_IF(el::base::Writer, condition, el::base::DispatchAction::SysLog, __VA_ARGS__) +# define CSYSLOG_EVERY_N(n, LEVEL, ...) C##LEVEL##_EVERY_N(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__) +# define CSYSLOG_AFTER_N(n, LEVEL, ...) C##LEVEL##_AFTER_N(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__) +# define CSYSLOG_N_TIMES(n, LEVEL, ...) C##LEVEL##_N_TIMES(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__) +# define SYSLOG(LEVEL) CSYSLOG(LEVEL, el::base::consts::kSysLogLoggerId) +# define SYSLOG_IF(condition, LEVEL) CSYSLOG_IF(condition, LEVEL, el::base::consts::kSysLogLoggerId) +# define SYSLOG_EVERY_N(n, LEVEL) CSYSLOG_EVERY_N(n, LEVEL, el::base::consts::kSysLogLoggerId) +# define SYSLOG_AFTER_N(n, LEVEL) CSYSLOG_AFTER_N(n, LEVEL, el::base::consts::kSysLogLoggerId) +# define SYSLOG_N_TIMES(n, LEVEL) CSYSLOG_N_TIMES(n, LEVEL, el::base::consts::kSysLogLoggerId) +# define DCSYSLOG(LEVEL, ...) if (ELPP_DEBUG_LOG) C##LEVEL(el::base::Writer, el::base::DispatchAction::SysLog, __VA_ARGS__) +# define DCSYSLOG_IF(condition, LEVEL, ...)\ +C##LEVEL##_IF(el::base::Writer, (ELPP_DEBUG_LOG) && (condition), el::base::DispatchAction::SysLog, __VA_ARGS__) +# define DCSYSLOG_EVERY_N(n, LEVEL, ...)\ +if (ELPP_DEBUG_LOG) C##LEVEL##_EVERY_N(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__) +# define DCSYSLOG_AFTER_N(n, LEVEL, ...)\ +if (ELPP_DEBUG_LOG) C##LEVEL##_AFTER_N(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__) +# define DCSYSLOG_N_TIMES(n, LEVEL, ...)\ +if (ELPP_DEBUG_LOG) C##LEVEL##_EVERY_N(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__) +# define DSYSLOG(LEVEL) DCSYSLOG(LEVEL, el::base::consts::kSysLogLoggerId) +# define DSYSLOG_IF(condition, LEVEL) DCSYSLOG_IF(condition, LEVEL, el::base::consts::kSysLogLoggerId) +# define DSYSLOG_EVERY_N(n, LEVEL) DCSYSLOG_EVERY_N(n, LEVEL, el::base::consts::kSysLogLoggerId) +# define DSYSLOG_AFTER_N(n, LEVEL) DCSYSLOG_AFTER_N(n, LEVEL, el::base::consts::kSysLogLoggerId) +# define DSYSLOG_N_TIMES(n, LEVEL) DCSYSLOG_N_TIMES(n, LEVEL, el::base::consts::kSysLogLoggerId) +#else +# define CSYSLOG(LEVEL, ...) el::base::NullWriter() +# define CSYSLOG_IF(condition, LEVEL, ...) el::base::NullWriter() +# define CSYSLOG_EVERY_N(n, LEVEL, ...) el::base::NullWriter() +# define CSYSLOG_AFTER_N(n, LEVEL, ...) el::base::NullWriter() +# define CSYSLOG_N_TIMES(n, LEVEL, ...) el::base::NullWriter() +# define SYSLOG(LEVEL) el::base::NullWriter() +# define SYSLOG_IF(condition, LEVEL) el::base::NullWriter() +# define SYSLOG_EVERY_N(n, LEVEL) el::base::NullWriter() +# define SYSLOG_AFTER_N(n, LEVEL) el::base::NullWriter() +# define SYSLOG_N_TIMES(n, LEVEL) el::base::NullWriter() +# define DCSYSLOG(LEVEL, ...) el::base::NullWriter() +# define DCSYSLOG_IF(condition, LEVEL, ...) el::base::NullWriter() +# define DCSYSLOG_EVERY_N(n, LEVEL, ...) el::base::NullWriter() +# define DCSYSLOG_AFTER_N(n, LEVEL, ...) el::base::NullWriter() +# define DCSYSLOG_N_TIMES(n, LEVEL, ...) el::base::NullWriter() +# define DSYSLOG(LEVEL) el::base::NullWriter() +# define DSYSLOG_IF(condition, LEVEL) el::base::NullWriter() +# define DSYSLOG_EVERY_N(n, LEVEL) el::base::NullWriter() +# define DSYSLOG_AFTER_N(n, LEVEL) el::base::NullWriter() +# define DSYSLOG_N_TIMES(n, LEVEL) el::base::NullWriter() +#endif // defined(ELPP_SYSLOG) +// +// Custom Debug Only Loggers - Requires (level, loggerId/s) +// +// undef existing +#undef DCLOG +#undef DCVLOG +#undef DCLOG_IF +#undef DCVLOG_IF +#undef DCLOG_EVERY_N +#undef DCVLOG_EVERY_N +#undef DCLOG_AFTER_N +#undef DCVLOG_AFTER_N +#undef DCLOG_N_TIMES +#undef DCVLOG_N_TIMES +// Normal logs +#define DCLOG(LEVEL, ...) if (ELPP_DEBUG_LOG) CLOG(LEVEL, __VA_ARGS__) +#define DCLOG_VERBOSE(vlevel, ...) if (ELPP_DEBUG_LOG) CLOG_VERBOSE(vlevel, __VA_ARGS__) +#define DCVLOG(vlevel, ...) if (ELPP_DEBUG_LOG) CVLOG(vlevel, __VA_ARGS__) +// Conditional logs +#define DCLOG_IF(condition, LEVEL, ...) if (ELPP_DEBUG_LOG) CLOG_IF(condition, LEVEL, __VA_ARGS__) +#define DCVLOG_IF(condition, vlevel, ...) if (ELPP_DEBUG_LOG) CVLOG_IF(condition, vlevel, __VA_ARGS__) +// Hit counts based logs +#define DCLOG_EVERY_N(n, LEVEL, ...) if (ELPP_DEBUG_LOG) CLOG_EVERY_N(n, LEVEL, __VA_ARGS__) +#define DCVLOG_EVERY_N(n, vlevel, ...) if (ELPP_DEBUG_LOG) CVLOG_EVERY_N(n, vlevel, __VA_ARGS__) +#define DCLOG_AFTER_N(n, LEVEL, ...) if (ELPP_DEBUG_LOG) CLOG_AFTER_N(n, LEVEL, __VA_ARGS__) +#define DCVLOG_AFTER_N(n, vlevel, ...) if (ELPP_DEBUG_LOG) CVLOG_AFTER_N(n, vlevel, __VA_ARGS__) +#define DCLOG_N_TIMES(n, LEVEL, ...) if (ELPP_DEBUG_LOG) CLOG_N_TIMES(n, LEVEL, __VA_ARGS__) +#define DCVLOG_N_TIMES(n, vlevel, ...) if (ELPP_DEBUG_LOG) CVLOG_N_TIMES(n, vlevel, __VA_ARGS__) +// +// Default Debug Only Loggers macro using CLOG(), CLOG_VERBOSE() and CVLOG() macros +// +#if !defined(ELPP_NO_DEBUG_MACROS) +// undef existing +#undef DLOG +#undef DVLOG +#undef DLOG_IF +#undef DVLOG_IF +#undef DLOG_EVERY_N +#undef DVLOG_EVERY_N +#undef DLOG_AFTER_N +#undef DVLOG_AFTER_N +#undef DLOG_N_TIMES +#undef DVLOG_N_TIMES +// Normal logs +#define DLOG(LEVEL) DCLOG(LEVEL, ELPP_CURR_FILE_LOGGER_ID) +#define DVLOG(vlevel) DCVLOG(vlevel, ELPP_CURR_FILE_LOGGER_ID) +// Conditional logs +#define DLOG_IF(condition, LEVEL) DCLOG_IF(condition, LEVEL, ELPP_CURR_FILE_LOGGER_ID) +#define DVLOG_IF(condition, vlevel) DCVLOG_IF(condition, vlevel, ELPP_CURR_FILE_LOGGER_ID) +// Hit counts based logs +#define DLOG_EVERY_N(n, LEVEL) DCLOG_EVERY_N(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID) +#define DVLOG_EVERY_N(n, vlevel) DCVLOG_EVERY_N(n, vlevel, ELPP_CURR_FILE_LOGGER_ID) +#define DLOG_AFTER_N(n, LEVEL) DCLOG_AFTER_N(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID) +#define DVLOG_AFTER_N(n, vlevel) DCVLOG_AFTER_N(n, vlevel, ELPP_CURR_FILE_LOGGER_ID) +#define DLOG_N_TIMES(n, LEVEL) DCLOG_N_TIMES(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID) +#define DVLOG_N_TIMES(n, vlevel) DCVLOG_N_TIMES(n, vlevel, ELPP_CURR_FILE_LOGGER_ID) +#endif // defined(ELPP_NO_DEBUG_MACROS) +#if !defined(ELPP_NO_CHECK_MACROS) +// Check macros +#undef CCHECK +#undef CPCHECK +#undef CCHECK_EQ +#undef CCHECK_NE +#undef CCHECK_LT +#undef CCHECK_GT +#undef CCHECK_LE +#undef CCHECK_GE +#undef CCHECK_BOUNDS +#undef CCHECK_NOTNULL +#undef CCHECK_STRCASEEQ +#undef CCHECK_STRCASENE +#undef CHECK +#undef PCHECK +#undef CHECK_EQ +#undef CHECK_NE +#undef CHECK_LT +#undef CHECK_GT +#undef CHECK_LE +#undef CHECK_GE +#undef CHECK_BOUNDS +#undef CHECK_NOTNULL +#undef CHECK_STRCASEEQ +#undef CHECK_STRCASENE +#define CCHECK(condition, ...) CLOG_IF(!(condition), FATAL, __VA_ARGS__) << "Check failed: [" << #condition << "] " +#define CPCHECK(condition, ...) CPLOG_IF(!(condition), FATAL, __VA_ARGS__) << "Check failed: [" << #condition << "] " +#define CHECK(condition) CCHECK(condition, ELPP_CURR_FILE_LOGGER_ID) +#define PCHECK(condition) CPCHECK(condition, ELPP_CURR_FILE_LOGGER_ID) +#define CCHECK_EQ(a, b, ...) CCHECK(a == b, __VA_ARGS__) +#define CCHECK_NE(a, b, ...) CCHECK(a != b, __VA_ARGS__) +#define CCHECK_LT(a, b, ...) CCHECK(a < b, __VA_ARGS__) +#define CCHECK_GT(a, b, ...) CCHECK(a > b, __VA_ARGS__) +#define CCHECK_LE(a, b, ...) CCHECK(a <= b, __VA_ARGS__) +#define CCHECK_GE(a, b, ...) CCHECK(a >= b, __VA_ARGS__) +#define CCHECK_BOUNDS(val, min, max, ...) CCHECK(val >= min && val <= max, __VA_ARGS__) +#define CHECK_EQ(a, b) CCHECK_EQ(a, b, ELPP_CURR_FILE_LOGGER_ID) +#define CHECK_NE(a, b) CCHECK_NE(a, b, ELPP_CURR_FILE_LOGGER_ID) +#define CHECK_LT(a, b) CCHECK_LT(a, b, ELPP_CURR_FILE_LOGGER_ID) +#define CHECK_GT(a, b) CCHECK_GT(a, b, ELPP_CURR_FILE_LOGGER_ID) +#define CHECK_LE(a, b) CCHECK_LE(a, b, ELPP_CURR_FILE_LOGGER_ID) +#define CHECK_GE(a, b) CCHECK_GE(a, b, ELPP_CURR_FILE_LOGGER_ID) +#define CHECK_BOUNDS(val, min, max) CCHECK_BOUNDS(val, min, max, ELPP_CURR_FILE_LOGGER_ID) +#define CCHECK_NOTNULL(ptr, ...) CCHECK((ptr) != nullptr, __VA_ARGS__) +#define CCHECK_STREQ(str1, str2, ...) CLOG_IF(!el::base::utils::Str::cStringEq(str1, str2), FATAL, __VA_ARGS__) \ +<< "Check failed: [" << #str1 << " == " << #str2 << "] " +#define CCHECK_STRNE(str1, str2, ...) CLOG_IF(el::base::utils::Str::cStringEq(str1, str2), FATAL, __VA_ARGS__) \ +<< "Check failed: [" << #str1 << " != " << #str2 << "] " +#define CCHECK_STRCASEEQ(str1, str2, ...) CLOG_IF(!el::base::utils::Str::cStringCaseEq(str1, str2), FATAL, __VA_ARGS__) \ +<< "Check failed: [" << #str1 << " == " << #str2 << "] " +#define CCHECK_STRCASENE(str1, str2, ...) CLOG_IF(el::base::utils::Str::cStringCaseEq(str1, str2), FATAL, __VA_ARGS__) \ +<< "Check failed: [" << #str1 << " != " << #str2 << "] " +#define CHECK_NOTNULL(ptr) CCHECK_NOTNULL((ptr), ELPP_CURR_FILE_LOGGER_ID) +#define CHECK_STREQ(str1, str2) CCHECK_STREQ(str1, str2, ELPP_CURR_FILE_LOGGER_ID) +#define CHECK_STRNE(str1, str2) CCHECK_STRNE(str1, str2, ELPP_CURR_FILE_LOGGER_ID) +#define CHECK_STRCASEEQ(str1, str2) CCHECK_STRCASEEQ(str1, str2, ELPP_CURR_FILE_LOGGER_ID) +#define CHECK_STRCASENE(str1, str2) CCHECK_STRCASENE(str1, str2, ELPP_CURR_FILE_LOGGER_ID) +#undef DCCHECK +#undef DCCHECK_EQ +#undef DCCHECK_NE +#undef DCCHECK_LT +#undef DCCHECK_GT +#undef DCCHECK_LE +#undef DCCHECK_GE +#undef DCCHECK_BOUNDS +#undef DCCHECK_NOTNULL +#undef DCCHECK_STRCASEEQ +#undef DCCHECK_STRCASENE +#undef DCPCHECK +#undef DCHECK +#undef DCHECK_EQ +#undef DCHECK_NE +#undef DCHECK_LT +#undef DCHECK_GT +#undef DCHECK_LE +#undef DCHECK_GE +#undef DCHECK_BOUNDS_ +#undef DCHECK_NOTNULL +#undef DCHECK_STRCASEEQ +#undef DCHECK_STRCASENE +#undef DPCHECK +#define DCCHECK(condition, ...) if (ELPP_DEBUG_LOG) CCHECK(condition, __VA_ARGS__) +#define DCCHECK_EQ(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_EQ(a, b, __VA_ARGS__) +#define DCCHECK_NE(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_NE(a, b, __VA_ARGS__) +#define DCCHECK_LT(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_LT(a, b, __VA_ARGS__) +#define DCCHECK_GT(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_GT(a, b, __VA_ARGS__) +#define DCCHECK_LE(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_LE(a, b, __VA_ARGS__) +#define DCCHECK_GE(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_GE(a, b, __VA_ARGS__) +#define DCCHECK_BOUNDS(val, min, max, ...) if (ELPP_DEBUG_LOG) CCHECK_BOUNDS(val, min, max, __VA_ARGS__) +#define DCCHECK_NOTNULL(ptr, ...) if (ELPP_DEBUG_LOG) CCHECK_NOTNULL((ptr), __VA_ARGS__) +#define DCCHECK_STREQ(str1, str2, ...) if (ELPP_DEBUG_LOG) CCHECK_STREQ(str1, str2, __VA_ARGS__) +#define DCCHECK_STRNE(str1, str2, ...) if (ELPP_DEBUG_LOG) CCHECK_STRNE(str1, str2, __VA_ARGS__) +#define DCCHECK_STRCASEEQ(str1, str2, ...) if (ELPP_DEBUG_LOG) CCHECK_STRCASEEQ(str1, str2, __VA_ARGS__) +#define DCCHECK_STRCASENE(str1, str2, ...) if (ELPP_DEBUG_LOG) CCHECK_STRCASENE(str1, str2, __VA_ARGS__) +#define DCPCHECK(condition, ...) if (ELPP_DEBUG_LOG) CPCHECK(condition, __VA_ARGS__) +#define DCHECK(condition) DCCHECK(condition, ELPP_CURR_FILE_LOGGER_ID) +#define DCHECK_EQ(a, b) DCCHECK_EQ(a, b, ELPP_CURR_FILE_LOGGER_ID) +#define DCHECK_NE(a, b) DCCHECK_NE(a, b, ELPP_CURR_FILE_LOGGER_ID) +#define DCHECK_LT(a, b) DCCHECK_LT(a, b, ELPP_CURR_FILE_LOGGER_ID) +#define DCHECK_GT(a, b) DCCHECK_GT(a, b, ELPP_CURR_FILE_LOGGER_ID) +#define DCHECK_LE(a, b) DCCHECK_LE(a, b, ELPP_CURR_FILE_LOGGER_ID) +#define DCHECK_GE(a, b) DCCHECK_GE(a, b, ELPP_CURR_FILE_LOGGER_ID) +#define DCHECK_BOUNDS(val, min, max) DCCHECK_BOUNDS(val, min, max, ELPP_CURR_FILE_LOGGER_ID) +#define DCHECK_NOTNULL(ptr) DCCHECK_NOTNULL((ptr), ELPP_CURR_FILE_LOGGER_ID) +#define DCHECK_STREQ(str1, str2) DCCHECK_STREQ(str1, str2, ELPP_CURR_FILE_LOGGER_ID) +#define DCHECK_STRNE(str1, str2) DCCHECK_STRNE(str1, str2, ELPP_CURR_FILE_LOGGER_ID) +#define DCHECK_STRCASEEQ(str1, str2) DCCHECK_STRCASEEQ(str1, str2, ELPP_CURR_FILE_LOGGER_ID) +#define DCHECK_STRCASENE(str1, str2) DCCHECK_STRCASENE(str1, str2, ELPP_CURR_FILE_LOGGER_ID) +#define DPCHECK(condition) DCPCHECK(condition, ELPP_CURR_FILE_LOGGER_ID) +#endif // defined(ELPP_NO_CHECK_MACROS) +#if defined(ELPP_DISABLE_DEFAULT_CRASH_HANDLING) +# define ELPP_USE_DEF_CRASH_HANDLER false +#else +# define ELPP_USE_DEF_CRASH_HANDLER true +#endif // defined(ELPP_DISABLE_DEFAULT_CRASH_HANDLING) +#define ELPP_CRASH_HANDLER_INIT +#define ELPP_INIT_EASYLOGGINGPP(val) \ +namespace el { \ +namespace base { \ +el::base::type::StoragePointer elStorage(val); \ +} \ +el::base::debug::CrashHandler elCrashHandler(ELPP_USE_DEF_CRASH_HANDLER); \ +} + +#if ELPP_ASYNC_LOGGING +# define INITIALIZE_EASYLOGGINGPP ELPP_INIT_EASYLOGGINGPP(new el::base::Storage(el::LogBuilderPtr(new el::base::DefaultLogBuilder()),\ +new el::base::AsyncDispatchWorker())) +#else +# define INITIALIZE_EASYLOGGINGPP ELPP_INIT_EASYLOGGINGPP(new el::base::Storage(el::LogBuilderPtr(new el::base::DefaultLogBuilder()))) +#endif // ELPP_ASYNC_LOGGING +#define INITIALIZE_NULL_EASYLOGGINGPP \ +namespace el {\ +namespace base {\ +el::base::type::StoragePointer elStorage;\ +}\ +el::base::debug::CrashHandler elCrashHandler(ELPP_USE_DEF_CRASH_HANDLER);\ +} +#define SHARE_EASYLOGGINGPP(initializedStorage)\ +namespace el {\ +namespace base {\ +el::base::type::StoragePointer elStorage(initializedStorage);\ +}\ +el::base::debug::CrashHandler elCrashHandler(ELPP_USE_DEF_CRASH_HANDLER);\ +} + +#if defined(ELPP_UNICODE) +# define START_EASYLOGGINGPP(argc, argv) el::Helpers::setArgs(argc, argv); std::locale::global(std::locale("")) +#else +# define START_EASYLOGGINGPP(argc, argv) el::Helpers::setArgs(argc, argv) +#endif // defined(ELPP_UNICODE) +#endif // EASYLOGGINGPP_H diff --git a/libdevcore/picosha2.h b/libdevcore/picosha2.h new file mode 100644 index 0000000000..bbdcf67daa --- /dev/null +++ b/libdevcore/picosha2.h @@ -0,0 +1,360 @@ +/* +The MIT License (MIT) + +Copyright (C) 2014 okdshin + +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. +*/ +#ifndef PICOSHA2_H +#define PICOSHA2_H +//picosha2:20140213 +#include +#include +#include +#include +#include +#include +#include + +namespace picosha2 +{ + +namespace detail +{ + +inline uint8_t mask_8bit(uint8_t x){ + return x&0xff; +} + +inline uint32_t mask_32bit(uint32_t x){ + return x&0xffffffff; +} + +static const uint32_t add_constant[64] = { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, + 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, + 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, + 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, + 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, + 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +}; + +static const uint32_t initial_message_digest[8] = { + 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, + 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 +}; + +inline uint32_t ch(uint32_t x, uint32_t y, uint32_t z){ + return (x&y)^((~x)&z); +} + +inline uint32_t maj(uint32_t x, uint32_t y, uint32_t z){ + return (x&y)^(x&z)^(y&z); +} + +inline uint32_t rotr(uint32_t x, std::size_t n){ + assert(n < 32); + return mask_32bit((x>>n)|(x<<(32-n))); +} + +inline uint32_t bsig0(uint32_t x){ + return rotr(x, 2)^rotr(x, 13)^rotr(x, 22); +} + +inline uint32_t bsig1(uint32_t x){ + return rotr(x, 6)^rotr(x, 11)^rotr(x, 25); +} + +inline uint32_t shr(uint32_t x, std::size_t n){ + assert(n < 32); + return x >> n; +} + +inline uint32_t ssig0(uint32_t x){ + return rotr(x, 7)^rotr(x, 18)^shr(x, 3); +} + +inline uint32_t ssig1(uint32_t x){ + return rotr(x, 17)^rotr(x, 19)^shr(x, 10); +} + +template +void hash256_block(RaIter1 message_digest, RaIter2 first, RaIter2 last){ + (void)last; // FIXME: check this is valid + uint32_t w[64]; + std::fill(w, w+64, 0); + for(std::size_t i = 0; i < 16; ++i){ + w[i] = (static_cast(mask_8bit(*(first+i*4)))<<24) + |(static_cast(mask_8bit(*(first+i*4+1)))<<16) + |(static_cast(mask_8bit(*(first+i*4+2)))<<8) + |(static_cast(mask_8bit(*(first+i*4+3)))); + } + for(std::size_t i = 16; i < 64; ++i){ + w[i] = mask_32bit(ssig1(w[i-2])+w[i-7]+ssig0(w[i-15])+w[i-16]); + } + + uint32_t a = *message_digest; + uint32_t b = *(message_digest+1); + uint32_t c = *(message_digest+2); + uint32_t d = *(message_digest+3); + uint32_t e = *(message_digest+4); + uint32_t f = *(message_digest+5); + uint32_t g = *(message_digest+6); + uint32_t h = *(message_digest+7); + + for(std::size_t i = 0; i < 64; ++i){ + uint32_t temp1 = h+bsig1(e)+ch(e,f,g)+add_constant[i]+w[i]; + uint32_t temp2 = bsig0(a)+maj(a,b,c); + h = g; + g = f; + f = e; + e = mask_32bit(d+temp1); + d = c; + c = b; + b = a; + a = mask_32bit(temp1+temp2); + } + *message_digest += a; + *(message_digest+1) += b; + *(message_digest+2) += c; + *(message_digest+3) += d; + *(message_digest+4) += e; + *(message_digest+5) += f; + *(message_digest+6) += g; + *(message_digest+7) += h; + for(std::size_t i = 0; i < 8; ++i){ + *(message_digest+i) = mask_32bit(*(message_digest+i)); + } +} + +}//namespace detail + +template +void output_hex(InIter first, InIter last, std::ostream& os){ + os.setf(std::ios::hex, std::ios::basefield); + while(first != last){ + os.width(2); + os.fill('0'); + os << static_cast(*first); + ++first; + } + os.setf(std::ios::dec, std::ios::basefield); +} + +template +void bytes_to_hex_string(InIter first, InIter last, std::string& hex_str){ + std::ostringstream oss; + output_hex(first, last, oss); + hex_str.assign(oss.str()); +} + +template +void bytes_to_hex_string(const InContainer& bytes, std::string& hex_str){ + bytes_to_hex_string(bytes.begin(), bytes.end(), hex_str); +} + +template +std::string bytes_to_hex_string(InIter first, InIter last){ + std::string hex_str; + bytes_to_hex_string(first, last, hex_str); + return hex_str; +} + +template +std::string bytes_to_hex_string(const InContainer& bytes){ + std::string hex_str; + bytes_to_hex_string(bytes, hex_str); + return hex_str; +} + +class hash256_one_by_one { +public: + hash256_one_by_one(){ + init(); + } + + void init(){ + buffer_.clear(); + std::fill(data_length_digits_, data_length_digits_+4, 0); + std::copy(detail::initial_message_digest, detail::initial_message_digest+8, h_); + } + + template + void process(RaIter first, RaIter last){ + add_to_data_length(std::distance(first, last)); + std::copy(first, last, std::back_inserter(buffer_)); + std::size_t i = 0; + for(;i+64 <= buffer_.size(); i+=64){ + detail::hash256_block(h_, buffer_.begin()+i, buffer_.begin()+i+64); + } + buffer_.erase(buffer_.begin(), buffer_.begin()+i); + } + + void finish(){ + uint8_t temp[64]; + std::fill(temp, temp+64, 0); + std::size_t remains = buffer_.size(); + std::copy(buffer_.begin(), buffer_.end(), temp); + temp[remains] = 0x80; + + if(remains > 55){ + std::fill(temp+remains+1, temp+64, 0); + detail::hash256_block(h_, temp, temp+64); + std::fill(temp, temp+64-4, 0); + } + else { + std::fill(temp+remains+1, temp+64-4, 0); + } + + write_data_bit_length(&(temp[56])); + detail::hash256_block(h_, temp, temp+64); + } + + template + void get_hash_bytes(OutIter first, OutIter last)const{ + for(const uint32_t* iter = h_; iter != h_+8; ++iter){ + for(std::size_t i = 0; i < 4 && first != last; ++i){ + *(first++) = detail::mask_8bit(static_cast((*iter >> (24-8*i)))); + } + } + } + +private: + void add_to_data_length(uint32_t n) { + uint32_t carry = 0; + data_length_digits_[0] += n; + for(std::size_t i = 0; i < 4; ++i) { + data_length_digits_[i] += carry; + if(data_length_digits_[i] >= 65536u) { + data_length_digits_[i] -= 65536u; + carry = 1; + } + else { + break; + } + } + } + void write_data_bit_length(uint8_t* begin) { + uint32_t data_bit_length_digits[4]; + std::copy( + data_length_digits_, data_length_digits_+4, + data_bit_length_digits + ); + + // convert byte length to bit length (multiply 8 or shift 3 times left) + uint32_t carry = 0; + for(std::size_t i = 0; i < 4; ++i) { + uint32_t before_val = data_bit_length_digits[i]; + data_bit_length_digits[i] <<= 3; + data_bit_length_digits[i] |= carry; + data_bit_length_digits[i] &= 65535u; + carry = (before_val >> (16-3)) & 65535u; + } + + // write data_bit_length + for(int i = 3; i >= 0; --i) { + (*begin++) = static_cast(data_bit_length_digits[i] >> 8); + (*begin++) = static_cast(data_bit_length_digits[i]); + } + } + std::vector buffer_; + uint32_t data_length_digits_[4]; //as 64bit integer (16bit x 4 integer) + uint32_t h_[8]; +}; + +inline void get_hash_hex_string(const hash256_one_by_one& hasher, std::string& hex_str){ + uint8_t hash[32]; + hasher.get_hash_bytes(hash, hash+32); + return bytes_to_hex_string(hash, hash+32, hex_str); +} + +inline std::string get_hash_hex_string(const hash256_one_by_one& hasher){ + std::string hex_str; + get_hash_hex_string(hasher, hex_str); + return hex_str; +} + +template +void hash256(RaIter first, RaIter last, OutIter first2, OutIter last2){ + hash256_one_by_one hasher; + //hasher.init(); + hasher.process(first, last); + hasher.finish(); + hasher.get_hash_bytes(first2, last2); +} + +template +void hash256(RaIter first, RaIter last, OutContainer& dst){ + hash256(first, last, dst.begin(), dst.end()); +} + +template +void hash256(const RaContainer& src, OutIter first, OutIter last){ + hash256(src.begin(), src.end(), first, last); +} + +template +void hash256(const RaContainer& src, OutContainer& dst){ + hash256(src.begin(), src.end(), dst.begin(), dst.end()); +} + + +template +void hash256_hex_string(RaIter first, RaIter last, std::string& hex_str){ + uint8_t hashed[32]; + hash256(first, last, hashed, hashed+32); + std::ostringstream oss; + output_hex(hashed, hashed+32, oss); + hex_str.assign(oss.str()); +} + +template +std::string hash256_hex_string(RaIter first, RaIter last){ + std::string hex_str; + hash256_hex_string(first, last, hex_str); + return hex_str; +} + +inline void hash256_hex_string(const std::string& src, std::string& hex_str){ + hash256_hex_string(src.begin(), src.end(), hex_str); +} + +template +void hash256_hex_string(const RaContainer& src, std::string& hex_str){ + hash256_hex_string(src.begin(), src.end(), hex_str); +} + +template +std::string hash256_hex_string(const RaContainer& src){ + return hash256_hex_string(src.begin(), src.end()); +} + +}//namespace picosha2 + +#endif //PICOSHA2_H diff --git a/libdevcore/vector_ref.h b/libdevcore/vector_ref.h new file mode 100644 index 0000000000..23d0933339 --- /dev/null +++ b/libdevcore/vector_ref.h @@ -0,0 +1,120 @@ +#pragma once + +#include +#include +#include +#include +#include + +#ifdef __INTEL_COMPILER +#pragma warning(disable:597) //will not be called for implicit or explicit conversions +#endif + +namespace dev +{ + +/** + * A modifiable reference to an existing object or vector in memory. + */ +template +class vector_ref +{ +public: + using value_type = _T; + using element_type = _T; + using mutable_value_type = typename std::conditional::value, typename std::remove_const<_T>::type, _T>::type; + + static_assert(std::is_pod::value, "vector_ref can only be used with PODs due to its low-level treatment of data."); + + vector_ref(): m_data(nullptr), m_count(0) {} + /// Creates a new vector_ref to point to @a _count elements starting at @a _data. + vector_ref(_T* _data, size_t _count): m_data(_data), m_count(_count) {} + /// Creates a new vector_ref pointing to the data part of a string (given as pointer). + vector_ref(typename std::conditional::value, std::string const*, std::string*>::type _data): m_data(reinterpret_cast<_T*>(_data->data())), m_count(_data->size() / sizeof(_T)) {} + /// Creates a new vector_ref pointing to the data part of a vector (given as pointer). + vector_ref(typename std::conditional::value, std::vector::type> const*, std::vector<_T>*>::type _data): m_data(_data->data()), m_count(_data->size()) {} + /// Creates a new vector_ref pointing to the data part of a string (given as reference). + vector_ref(typename std::conditional::value, std::string const&, std::string&>::type _data): m_data(reinterpret_cast<_T*>(_data.data())), m_count(_data.size() / sizeof(_T)) {} +#if DEV_LDB + vector_ref(ldb::Slice const& _s): m_data(reinterpret_cast<_T*>(_s.data())), m_count(_s.size() / sizeof(_T)) {} +#endif + explicit operator bool() const { return m_data && m_count; } + + bool contentsEqual(std::vector const& _c) const { if (!m_data || m_count == 0) return _c.empty(); else return _c.size() == m_count && !memcmp(_c.data(), m_data, m_count * sizeof(_T)); } + std::vector toVector() const { return std::vector(m_data, m_data + m_count); } + std::vector toBytes() const { return std::vector(reinterpret_cast(m_data), reinterpret_cast(m_data) + m_count * sizeof(_T)); } + std::string toString() const { return std::string((char const*)m_data, ((char const*)m_data) + m_count * sizeof(_T)); } + + template explicit operator vector_ref<_T2>() const { assert(m_count * sizeof(_T) / sizeof(_T2) * sizeof(_T2) / sizeof(_T) == m_count); return vector_ref<_T2>(reinterpret_cast<_T2*>(m_data), m_count * sizeof(_T) / sizeof(_T2)); } + operator vector_ref<_T const>() const { return vector_ref<_T const>(m_data, m_count); } + + _T* data() const { return m_data; } + /// @returns the number of elements referenced (not necessarily number of bytes). + size_t count() const { return m_count; } + /// @returns the number of elements referenced (not necessarily number of bytes). + size_t size() const { return m_count; } + bool empty() const { return !m_count; } + /// @returns a new vector_ref pointing at the next chunk of @a size() elements. + vector_ref<_T> next() const { if (!m_data) return *this; else return vector_ref<_T>(m_data + m_count, m_count); } + /// @returns a new vector_ref which is a shifted and shortened view of the original data. + /// If this goes out of bounds in any way, returns an empty vector_ref. + /// If @a _count is ~size_t(0), extends the view to the end of the data. + vector_ref<_T> cropped(size_t _begin, size_t _count) const { if (m_data && _begin <= m_count && _count <= m_count && _begin + _count <= m_count) return vector_ref<_T>(m_data + _begin, _count == ~size_t(0) ? m_count - _begin : _count); else return vector_ref<_T>(); } + /// @returns a new vector_ref which is a shifted view of the original data (not going beyond it). + vector_ref<_T> cropped(size_t _begin) const { if (m_data && _begin <= m_count) return vector_ref<_T>(m_data + _begin, m_count - _begin); else return vector_ref<_T>(); } + void retarget(_T* _d, size_t _s) { m_data = _d; m_count = _s; } + void retarget(std::vector<_T> const& _t) { m_data = _t.data(); m_count = _t.size(); } + template bool overlapsWith(vector_ref _t) const { void const* f1 = data(); void const* t1 = data() + size(); void const* f2 = _t.data(); void const* t2 = _t.data() + _t.size(); return f1 < t2 && t1 > f2; } + /// Copies the contents of this vector_ref to the contents of @a _t, up to the max size of @a _t. + void copyTo(vector_ref::type> _t) const { if (overlapsWith(_t)) memmove(_t.data(), m_data, std::min(_t.size(), m_count) * sizeof(_T)); else memcpy(_t.data(), m_data, std::min(_t.size(), m_count) * sizeof(_T)); } + /// Copies the contents of this vector_ref to the contents of @a _t, and zeros further trailing elements in @a _t. + void populate(vector_ref::type> _t) const { copyTo(_t); memset(_t.data() + m_count, 0, std::max(_t.size(), m_count) - m_count); } + /// Securely overwrite the memory. + /// @note adapted from OpenSSL's implementation. + void cleanse() + { + static unsigned char s_cleanseCounter = 0; + uint8_t* p = (uint8_t*)begin(); + size_t const len = (uint8_t*)end() - p; + size_t loop = len; + size_t count = s_cleanseCounter; + while (loop--) + { + *(p++) = (uint8_t)count; + count += (17 + ((size_t)p & 0xf)); + } + p = (uint8_t*)memchr((uint8_t*)begin(), (uint8_t)count, len); + if (p) + count += (63 + (size_t)p); + s_cleanseCounter = (uint8_t)count; + memset((uint8_t*)begin(), 0, len); + } + + _T* begin() { return m_data; } + _T* end() { return m_data + m_count; } + _T const* begin() const { return m_data; } + _T const* end() const { return m_data + m_count; } + + _T& operator[](size_t _i) { assert(m_data); assert(_i < m_count); return m_data[_i]; } + _T const& operator[](size_t _i) const { assert(m_data); assert(_i < m_count); return m_data[_i]; } + + bool operator==(vector_ref<_T> const& _cmp) const { return m_data == _cmp.m_data && m_count == _cmp.m_count; } + bool operator!=(vector_ref<_T> const& _cmp) const { return !operator==(_cmp); } + +#if DEV_LDB + operator ldb::Slice() const { return ldb::Slice((char const*)m_data, m_count * sizeof(_T)); } +#endif + + void reset() { m_data = nullptr; m_count = 0; } + +private: + _T* m_data; + size_t m_count; +}; + +template vector_ref<_T const> ref(_T const& _t) { return vector_ref<_T const>(&_t, 1); } +template vector_ref<_T> ref(_T& _t) { return vector_ref<_T>(&_t, 1); } +template vector_ref<_T const> ref(std::vector<_T> const& _t) { return vector_ref<_T const>(&_t); } +template vector_ref<_T> ref(std::vector<_T>& _t) { return vector_ref<_T>(&_t); } + +} diff --git a/libdevcrypto/AES.cpp b/libdevcrypto/AES.cpp new file mode 100644 index 0000000000..f06c91b148 --- /dev/null +++ b/libdevcrypto/AES.cpp @@ -0,0 +1,62 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . + */ +/** @file AES.cpp + * @author Alex Leverington + * @date 2014 + */ + +#include "AES.h" +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace dev; +using namespace dev::crypto; +using namespace CryptoPP; + +bytes dev::aesDecrypt(bytesConstRef _ivCipher, std::string const& _password, unsigned _rounds, bytesConstRef _salt) +{ + bytes pw = asBytes(_password); + + if (!_salt.size()) + _salt = &pw; + + bytes target(64); + CryptoPP::PKCS5_PBKDF2_HMAC().DeriveKey(target.data(), target.size(), 0, pw.data(), pw.size(), _salt.data(), _salt.size(), _rounds); + + try + { + CryptoPP::AES::Decryption aesDecryption(target.data(), 16); + auto cipher = _ivCipher.cropped(16); + auto iv = _ivCipher.cropped(0, 16); + CryptoPP::CBC_Mode_ExternalCipher::Decryption cbcDecryption(aesDecryption, iv.data()); + std::string decrypted; + CryptoPP::StreamTransformationFilter stfDecryptor(cbcDecryption, new CryptoPP::StringSink(decrypted)); + stfDecryptor.Put(cipher.data(), cipher.size()); + stfDecryptor.MessageEnd(); + return asBytes(decrypted); + } + catch (exception const& e) + { + LOG(ERROR) << e.what() << endl; + return bytes(); + } +} diff --git a/libdevcrypto/AES.h b/libdevcrypto/AES.h new file mode 100644 index 0000000000..d94754f3d8 --- /dev/null +++ b/libdevcrypto/AES.h @@ -0,0 +1,34 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . + */ +/** @file AES.h + * @author Alex Leverington + * @date 2014 + * + * AES + * todo: use openssl + */ + +#pragma once + +#include "Common.h" + +namespace dev +{ + +bytes aesDecrypt(bytesConstRef _cipher, std::string const& _password, unsigned _rounds = 2000, bytesConstRef _salt = bytesConstRef()); + +} diff --git a/libdevcrypto/CMakeLists.txt b/libdevcrypto/CMakeLists.txt new file mode 100644 index 0000000000..0d84119185 --- /dev/null +++ b/libdevcrypto/CMakeLists.txt @@ -0,0 +1,13 @@ +aux_source_directory(. SRC_LIST) + +file(GLOB HEADERS "*.h") + +add_library(devcrypto ${SRC_LIST} ${HEADERS}) +add_definitions(-D_GLIBCXX_USE_CXX11_ABI=1) + +find_package(Dev) +find_package(Utils) + +target_include_directories(devcrypto PRIVATE ..) +target_include_directories(devcrypto PRIVATE ../utils) +target_link_libraries(devcrypto Secp256k1 Cryptopp crypto ${Utils_SCRYPT_LIBRARIES} devcore) \ No newline at end of file diff --git a/libdevcrypto/Common.cpp b/libdevcrypto/Common.cpp new file mode 100644 index 0000000000..14d2ec367f --- /dev/null +++ b/libdevcrypto/Common.cpp @@ -0,0 +1,360 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Common.cpp + * @author Alex Leverington + * @author Gav Wood + * @date 2014 + */ + +#include // conflicts with +#include "Common.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "AES.h" +#include "CryptoPP.h" +#include "Exceptions.h" +using namespace std; +using namespace dev; +using namespace dev::crypto; +using namespace CryptoPP; + +class Secp256k1Context +{ +public: + static secp256k1_context const* get() + { + static Secp256k1Context s_ctx; + return s_ctx.m_ctx; + } + +private: + Secp256k1Context(): + m_ctx(secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY)) {} + ~Secp256k1Context() { secp256k1_context_destroy(m_ctx); } + + secp256k1_context* const m_ctx = nullptr; +}; + + +bool dev::SignatureStruct::isValid() const noexcept +{ + if (v > 1 || + r >= h256("0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141") || + s >= h256("0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141") || + s < h256(1) || + r < h256(1)) + return false; + return true; +} + +Public SignatureStruct::recover(h256 const& _hash) const +{ + return dev::recover((Signature)*this, _hash); +} + +Address dev::ZeroAddress = Address(); + +Public dev::toPublic(Secret const& _secret) +{ + auto* ctx = Secp256k1Context::get(); + secp256k1_pubkey rawPubkey; + // Creation will fail if the secret key is invalid. + if (!secp256k1_ec_pubkey_create(ctx, &rawPubkey, _secret.data())) + return {}; + std::array serializedPubkey; + size_t serializedPubkeySize = serializedPubkey.size(); + secp256k1_ec_pubkey_serialize( + ctx, serializedPubkey.data(), &serializedPubkeySize, + &rawPubkey, SECP256K1_EC_UNCOMPRESSED + ); + assert(serializedPubkeySize == serializedPubkey.size()); + // Expect single byte header of value 0x04 -- uncompressed public key. + assert(serializedPubkey[0] == 0x04); + // Create the Public skipping the header. + return Public{&serializedPubkey[1], Public::ConstructFromPointer}; +} + +Address dev::toAddress(Public const& _public) +{ + return right160(sha3(_public.ref())); +} + +Address dev::toAddress(Secret const& _secret) +{ + return toAddress(toPublic(_secret)); +} + +Address dev::toAddress(Address const& _from, u256 const& _nonce) +{ + return right160(sha3(rlpList(_from, _nonce))); +} + +void dev::encrypt(Public const& _k, bytesConstRef _plain, bytes& o_cipher) +{ + bytes io = _plain.toBytes(); + Secp256k1PP::get()->encrypt(_k, io); + o_cipher = std::move(io); +} + +bool dev::decrypt(Secret const& _k, bytesConstRef _cipher, bytes& o_plaintext) +{ + bytes io = _cipher.toBytes(); + Secp256k1PP::get()->decrypt(_k, io); + if (io.empty()) + return false; + o_plaintext = std::move(io); + return true; +} + +void dev::encryptECIES(Public const& _k, bytesConstRef _plain, bytes& o_cipher) +{ + encryptECIES(_k, bytesConstRef(), _plain, o_cipher); +} + +void dev::encryptECIES(Public const& _k, bytesConstRef _sharedMacData, bytesConstRef _plain, bytes& o_cipher) +{ + bytes io = _plain.toBytes(); + Secp256k1PP::get()->encryptECIES(_k, _sharedMacData, io); + o_cipher = std::move(io); +} + +bool dev::decryptECIES(Secret const& _k, bytesConstRef _cipher, bytes& o_plaintext) +{ + return decryptECIES(_k, bytesConstRef(), _cipher, o_plaintext); +} + +bool dev::decryptECIES(Secret const& _k, bytesConstRef _sharedMacData, bytesConstRef _cipher, bytes& o_plaintext) +{ + bytes io = _cipher.toBytes(); + if (!Secp256k1PP::get()->decryptECIES(_k, _sharedMacData, io)) + return false; + o_plaintext = std::move(io); + return true; +} + +void dev::encryptSym(Secret const& _k, bytesConstRef _plain, bytes& o_cipher) +{ + // TOOD: @alex @subtly do this properly. + encrypt(KeyPair(_k).pub(), _plain, o_cipher); +} + +bool dev::decryptSym(Secret const& _k, bytesConstRef _cipher, bytes& o_plain) +{ + // TODO: @alex @subtly do this properly. + return decrypt(_k, _cipher, o_plain); +} + +std::pair dev::encryptSymNoAuth(SecureFixedHash<16> const& _k, bytesConstRef _plain) +{ + h128 iv(Nonce::get().makeInsecure()); + return make_pair(encryptSymNoAuth(_k, iv, _plain), iv); +} + +bytes dev::encryptAES128CTR(bytesConstRef _k, h128 const& _iv, bytesConstRef _plain) +{ + if (_k.size() != 16 && _k.size() != 24 && _k.size() != 32) + return bytes(); + SecByteBlock key(_k.data(), _k.size()); + try + { + CTR_Mode::Encryption e; + e.SetKeyWithIV(key, key.size(), _iv.data()); + bytes ret(_plain.size()); + e.ProcessData(ret.data(), _plain.data(), _plain.size()); + return ret; + } + catch (CryptoPP::Exception& _e) + { + LOG(ERROR) << _e.what() << endl; + return bytes(); + } +} + +bytesSec dev::decryptAES128CTR(bytesConstRef _k, h128 const& _iv, bytesConstRef _cipher) +{ + if (_k.size() != 16 && _k.size() != 24 && _k.size() != 32) + return bytesSec(); + SecByteBlock key(_k.data(), _k.size()); + try + { + CTR_Mode::Decryption d; + d.SetKeyWithIV(key, key.size(), _iv.data()); + bytesSec ret(_cipher.size()); + d.ProcessData(ret.writable().data(), _cipher.data(), _cipher.size()); + return ret; + } + catch (CryptoPP::Exception& _e) + { + LOG(ERROR) << _e.what() << endl; + return bytesSec(); + } +} + +static const Public c_zeroKey("3f17f1962b36e491b30a40b2405849e597ba5fb5"); + +Public dev::recover(Signature const& _sig, h256 const& _message) +{ + int v = _sig[64]; + if (v > 3) + return {}; + + auto* ctx = Secp256k1Context::get(); + secp256k1_ecdsa_recoverable_signature rawSig; + if (!secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rawSig, _sig.data(), v)) + return {}; + + secp256k1_pubkey rawPubkey; + if (!secp256k1_ecdsa_recover(ctx, &rawPubkey, &rawSig, _message.data())) + return {}; + + std::array serializedPubkey; + size_t serializedPubkeySize = serializedPubkey.size(); + secp256k1_ec_pubkey_serialize( + ctx, serializedPubkey.data(), &serializedPubkeySize, + &rawPubkey, SECP256K1_EC_UNCOMPRESSED + ); + assert(serializedPubkeySize == serializedPubkey.size()); + // Expect single byte header of value 0x04 -- uncompressed public key. + assert(serializedPubkey[0] == 0x04); + // Create the Public skipping the header. + return Public{&serializedPubkey[1], Public::ConstructFromPointer}; +} + +static const u256 c_secp256k1n("115792089237316195423570985008687907852837564279074904382605163141518161494337"); + +Signature dev::sign(Secret const& _k, h256 const& _hash) +{ + auto* ctx = Secp256k1Context::get(); + secp256k1_ecdsa_recoverable_signature rawSig; + if (!secp256k1_ecdsa_sign_recoverable(ctx, &rawSig, _hash.data(), _k.data(), nullptr, nullptr)) + return {}; + + Signature s; + int v = 0; + secp256k1_ecdsa_recoverable_signature_serialize_compact(ctx, s.data(), &v, &rawSig); + + SignatureStruct& ss = *reinterpret_cast(&s); + ss.v = static_cast(v); + if (ss.s > c_secp256k1n / 2) + { + ss.v = static_cast(ss.v ^ 1); + ss.s = h256(c_secp256k1n - u256(ss.s)); + } + assert(ss.s <= c_secp256k1n / 2); + return s; +} + +bool dev::verify(Public const& _p, Signature const& _s, h256 const& _hash) +{ + // TODO: Verify w/o recovery (if faster). + if (!_p) + return false; + return _p == recover(_s, _hash); +} + +bytesSec dev::pbkdf2(string const& _pass, bytes const& _salt, unsigned _iterations, unsigned _dkLen) +{ + bytesSec ret(_dkLen); + if (PKCS5_PBKDF2_HMAC().DeriveKey( + ret.writable().data(), + _dkLen, + 0, + reinterpret_cast(_pass.data()), + _pass.size(), + _salt.data(), + _salt.size(), + _iterations + ) != _iterations) + BOOST_THROW_EXCEPTION(CryptoException() << errinfo_comment("Key derivation failed.")); + return ret; +} + +bytesSec dev::scrypt(std::string const& _pass, bytes const& _salt, uint64_t _n, uint32_t _r, uint32_t _p, unsigned _dkLen) +{ + bytesSec ret(_dkLen); + if (libscrypt_scrypt( + reinterpret_cast(_pass.data()), + _pass.size(), + _salt.data(), + _salt.size(), + _n, + _r, + _p, + ret.writable().data(), + _dkLen + ) != 0) + BOOST_THROW_EXCEPTION(CryptoException() << errinfo_comment("Key derivation failed.")); + return ret; +} + +KeyPair::KeyPair(Secret const& _sec): + m_secret(_sec), + m_public(toPublic(_sec)) +{ + // Assign address only if the secret key is valid. + if (m_public) + m_address = toAddress(m_public); +} + +KeyPair KeyPair::create() +{ + while (true) + { + KeyPair keyPair(Secret::random()); + if (keyPair.address()) + return keyPair; + } +} + +KeyPair KeyPair::fromEncryptedSeed(bytesConstRef _seed, std::string const& _password) +{ + return KeyPair(Secret(sha3(aesDecrypt(_seed, _password)))); +} + +h256 crypto::kdf(Secret const& _priv, h256 const& _hash) +{ + // H(H(r||k)^h) + h256 s; + sha3mac(Secret::random().ref(), _priv.ref(), s.ref()); + s ^= _hash; + sha3(s.ref(), s.ref()); + + if (!s || !_hash || !_priv) + BOOST_THROW_EXCEPTION(InvalidState()); + return s; +} + +Secret Nonce::next() +{ + Guard l(x_value); + if (!m_value) + { + m_value = Secret::random(); + if (!m_value) + BOOST_THROW_EXCEPTION(InvalidState()); + } + m_value = sha3Secure(m_value.ref()); + return sha3(~m_value); +} diff --git a/libdevcrypto/Common.h b/libdevcrypto/Common.h new file mode 100644 index 0000000000..d49468da49 --- /dev/null +++ b/libdevcrypto/Common.h @@ -0,0 +1,223 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Common.h + * @author Alex Leverington + * @author Gav Wood + * @date 2014 + * + * Ethereum-specific data structures & algorithms. + */ + +#pragma once + +#include +#include +#include +#include + +namespace dev +{ + +using Secret = SecureFixedHash<32>; + +/// A public key: 64 bytes. +/// @NOTE This is not endian-specific; it's just a bunch of bytes. +using Public = h512; + +/// A signature: 65 bytes: r: [0, 32), s: [32, 64), v: 64. +/// @NOTE This is not endian-specific; it's just a bunch of bytes. +using Signature = h520; + +struct SignatureStruct +{ + SignatureStruct() = default; + SignatureStruct(Signature const& _s) { *(h520*)this = _s; } + SignatureStruct(h256 const& _r, h256 const& _s, byte _v): r(_r), s(_s), v(_v) {} + operator Signature() const { return *(h520 const*)this; } + + /// @returns true if r,s,v values are valid, otherwise false + bool isValid() const noexcept; + + /// @returns the public part of the key that signed @a _hash to give this sig. + Public recover(h256 const& _hash) const; + + h256 r; + h256 s; + byte v = 0; +}; + +/// An Ethereum address: 20 bytes. +/// @NOTE This is not endian-specific; it's just a bunch of bytes. +using Address = h160; + +/// The zero address. +extern Address ZeroAddress; + +/// A vector of Ethereum addresses. +using Addresses = h160s; + +/// A hash set of Ethereum addresses. +using AddressHash = std::unordered_set; + +/// A vector of secrets. +using Secrets = std::vector; + +/// Convert a secret key into the public key equivalent. +Public toPublic(Secret const& _secret); + +/// Convert a public key to address. +Address toAddress(Public const& _public); + +/// Convert a secret key into address of public key equivalent. +/// @returns 0 if it's not a valid secret key. +Address toAddress(Secret const& _secret); + +// Convert transaction from and nonce to address. +Address toAddress(Address const& _from, u256 const& _nonce); + +/// Encrypts plain text using Public key. +void encrypt(Public const& _k, bytesConstRef _plain, bytes& o_cipher); + +/// Decrypts cipher using Secret key. +bool decrypt(Secret const& _k, bytesConstRef _cipher, bytes& o_plaintext); + +/// Symmetric encryption. +void encryptSym(Secret const& _k, bytesConstRef _plain, bytes& o_cipher); + +/// Symmetric decryption. +bool decryptSym(Secret const& _k, bytesConstRef _cipher, bytes& o_plaintext); + +/// Encrypt payload using ECIES standard with AES128-CTR. +void encryptECIES(Public const& _k, bytesConstRef _plain, bytes& o_cipher); + +/// Encrypt payload using ECIES standard with AES128-CTR. +/// @a _sharedMacData is shared authenticated data. +void encryptECIES(Public const& _k, bytesConstRef _sharedMacData, bytesConstRef _plain, bytes& o_cipher); + +/// Decrypt payload using ECIES standard with AES128-CTR. +bool decryptECIES(Secret const& _k, bytesConstRef _cipher, bytes& o_plaintext); + +/// Decrypt payload using ECIES standard with AES128-CTR. +/// @a _sharedMacData is shared authenticated data. +bool decryptECIES(Secret const& _k, bytesConstRef _sharedMacData, bytesConstRef _cipher, bytes& o_plaintext); + +/// Encrypts payload with random IV/ctr using AES128-CTR. +std::pair encryptSymNoAuth(SecureFixedHash<16> const& _k, bytesConstRef _plain); + +/// Encrypts payload with specified IV/ctr using AES128-CTR. +bytes encryptAES128CTR(bytesConstRef _k, h128 const& _iv, bytesConstRef _plain); + +/// Decrypts payload with specified IV/ctr using AES128-CTR. +bytesSec decryptAES128CTR(bytesConstRef _k, h128 const& _iv, bytesConstRef _cipher); + +/// Encrypts payload with specified IV/ctr using AES128-CTR. +inline bytes encryptSymNoAuth(SecureFixedHash<16> const& _k, h128 const& _iv, bytesConstRef _plain) { return encryptAES128CTR(_k.ref(), _iv, _plain); } +inline bytes encryptSymNoAuth(SecureFixedHash<32> const& _k, h128 const& _iv, bytesConstRef _plain) { return encryptAES128CTR(_k.ref(), _iv, _plain); } + +/// Decrypts payload with specified IV/ctr using AES128-CTR. +inline bytesSec decryptSymNoAuth(SecureFixedHash<16> const& _k, h128 const& _iv, bytesConstRef _cipher) { return decryptAES128CTR(_k.ref(), _iv, _cipher); } +inline bytesSec decryptSymNoAuth(SecureFixedHash<32> const& _k, h128 const& _iv, bytesConstRef _cipher) { return decryptAES128CTR(_k.ref(), _iv, _cipher); } + +/// Recovers Public key from signed message hash. +Public recover(Signature const& _sig, h256 const& _hash); + +/// Returns siganture of message hash. +Signature sign(Secret const& _k, h256 const& _hash); + +/// Verify signature. +bool verify(Public const& _k, Signature const& _s, h256 const& _hash); + +/// Derive key via PBKDF2. +bytesSec pbkdf2(std::string const& _pass, bytes const& _salt, unsigned _iterations, unsigned _dkLen = 32); + +/// Derive key via Scrypt. +bytesSec scrypt(std::string const& _pass, bytes const& _salt, uint64_t _n, uint32_t _r, uint32_t _p, unsigned _dkLen); + +/// Simple class that represents a "key pair". +/// All of the data of the class can be regenerated from the secret key (m_secret) alone. +/// Actually stores a tuplet of secret, public and address (the right 160-bits of the public). +class KeyPair +{ +public: + /// Null constructor. + KeyPair() = default; + + /// Normal constructor - populates object from the given secret key. + /// If the secret key is invalid the constructor succeeds, but public key + /// and address stay "null". + KeyPair(Secret const& _sec); + + /// Create a new, randomly generated object. + static KeyPair create(); + + /// Create from an encrypted seed. + static KeyPair fromEncryptedSeed(bytesConstRef _seed, std::string const& _password); + + Secret const& secret() const { return m_secret; } + + Secret const& sec() const { return m_secret; } + /// Retrieve the public key. + Public const& pub() const { return m_public; } + + /// Retrieve the associated address of the public key. + Address const& address() const { return m_address; } + + bool operator==(KeyPair const& _c) const { return m_public == _c.m_public; } + bool operator!=(KeyPair const& _c) const { return m_public != _c.m_public; } + +private: + Secret m_secret; + Public m_public; + Address m_address; +}; + +namespace crypto +{ + +DEV_SIMPLE_EXCEPTION(InvalidState); + +/// Key derivation +h256 kdf(Secret const& _priv, h256 const& _hash); + +/** + * @brief Generator for non-repeating nonce material. + * The Nonce class should only be used when a non-repeating nonce + * is required and, in its current form, not recommended for signatures. + * This is primarily because the key-material for signatures is + * encrypted on disk whereas the seed for Nonce is not. + * Thus, Nonce's primary intended use at this time is for networking + * where the key is also stored in plaintext. + */ +class Nonce +{ +public: + /// Returns the next nonce (might be read from a file). + static Secret get() { static Nonce s; return s.next(); } + +private: + Nonce() = default; + + /// @returns the next nonce. + Secret next(); + + std::mutex x_value; + Secret m_value; +}; + +} + +} diff --git a/libdevcrypto/CryptoPP.cpp b/libdevcrypto/CryptoPP.cpp new file mode 100644 index 0000000000..db7032ccc9 --- /dev/null +++ b/libdevcrypto/CryptoPP.cpp @@ -0,0 +1,281 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . + */ +/** @file CryptoPP.cpp + * @author Alex Leverington + * @date 2014 + */ + +#include // conflicts with +#include "CryptoPP.h" +#include +#include +#include +#include +#include +#include "ECDHE.h" + +static_assert(CRYPTOPP_VERSION == 570, "Wrong Crypto++ version"); + +using namespace std; +using namespace dev; +using namespace dev::crypto; +using namespace CryptoPP; + +static_assert(dev::Secret::size == 32, "Secret key must be 32 bytes."); +static_assert(dev::Public::size == 64, "Public key must be 64 bytes."); +static_assert(dev::Signature::size == 65, "Signature must be 65 bytes."); + +namespace +{ +class Secp256k1PPCtx +{ +public: + OID m_oid; + + std::mutex x_rng; + AutoSeededRandomPool m_rng; + + std::mutex x_params; + DL_GroupParameters_EC m_params; + + DL_GroupParameters_EC::EllipticCurve m_curve; + + Integer m_q; + Integer m_qs; + + static Secp256k1PPCtx& get() + { + static Secp256k1PPCtx ctx; + return ctx; + } + +private: + Secp256k1PPCtx(): + m_oid(ASN1::secp256k1()), m_params(m_oid), m_curve(m_params.GetCurve()), + m_q(m_params.GetGroupOrder()), m_qs(m_params.GetSubgroupOrder()) + {} +}; + +inline ECP::Point publicToPoint(Public const& _p) { Integer x(_p.data(), 32); Integer y(_p.data() + 32, 32); return ECP::Point(x,y); } + +inline Integer secretToExponent(Secret const& _s) { return Integer(_s.data(), Secret::size); } + +} + +Secp256k1PP* Secp256k1PP::get() +{ + static Secp256k1PP s_this; + return &s_this; +} + +bytes Secp256k1PP::eciesKDF(Secret const& _z, bytes _s1, unsigned kdByteLen) +{ + auto reps = ((kdByteLen + 7) * 8) / (CryptoPP::SHA256::BLOCKSIZE * 8); + // SEC/ISO/Shoup specify counter size SHOULD be equivalent + // to size of hash output, however, it also notes that + // the 4 bytes is okay. NIST specifies 4 bytes. + bytes ctr({0, 0, 0, 1}); + bytes k; + CryptoPP::SHA256 ctx; + for (unsigned i = 0; i <= reps; i++) + { + ctx.Update(ctr.data(), ctr.size()); + ctx.Update(_z.data(), Secret::size); + ctx.Update(_s1.data(), _s1.size()); + // append hash to k + bytes digest(32); + ctx.Final(digest.data()); + ctx.Restart(); + + k.reserve(k.size() + h256::size); + move(digest.begin(), digest.end(), back_inserter(k)); + + if (++ctr[3] || ++ctr[2] || ++ctr[1] || ++ctr[0]) + continue; + } + + k.resize(kdByteLen); + return k; +} + +void Secp256k1PP::encryptECIES(Public const& _k, bytes& io_cipher) +{ + encryptECIES(_k, bytesConstRef(), io_cipher); +} + +void Secp256k1PP::encryptECIES(Public const& _k, bytesConstRef _sharedMacData, bytes& io_cipher) +{ + // interop w/go ecies implementation + auto r = KeyPair::create(); + Secret z; + ecdh::agree(r.secret(), _k, z); + auto key = eciesKDF(z, bytes(), 32); + bytesConstRef eKey = bytesConstRef(&key).cropped(0, 16); + bytesRef mKeyMaterial = bytesRef(&key).cropped(16, 16); + CryptoPP::SHA256 ctx; + ctx.Update(mKeyMaterial.data(), mKeyMaterial.size()); + bytes mKey(32); + ctx.Final(mKey.data()); + + auto iv = h128::random(); + bytes cipherText = encryptSymNoAuth(SecureFixedHash<16>(eKey), iv, bytesConstRef(&io_cipher)); + if (cipherText.empty()) + return; + + bytes msg(1 + Public::size + h128::size + cipherText.size() + 32); + msg[0] = 0x04; + r.pub().ref().copyTo(bytesRef(&msg).cropped(1, Public::size)); + iv.ref().copyTo(bytesRef(&msg).cropped(1 + Public::size, h128::size)); + bytesRef msgCipherRef = bytesRef(&msg).cropped(1 + Public::size + h128::size, cipherText.size()); + bytesConstRef(&cipherText).copyTo(msgCipherRef); + + // tag message + CryptoPP::HMAC hmacctx(mKey.data(), mKey.size()); + bytesConstRef cipherWithIV = bytesRef(&msg).cropped(1 + Public::size, h128::size + cipherText.size()); + hmacctx.Update(cipherWithIV.data(), cipherWithIV.size()); + hmacctx.Update(_sharedMacData.data(), _sharedMacData.size()); + hmacctx.Final(msg.data() + 1 + Public::size + cipherWithIV.size()); + + io_cipher.resize(msg.size()); + io_cipher.swap(msg); +} + +bool Secp256k1PP::decryptECIES(Secret const& _k, bytes& io_text) +{ + return decryptECIES(_k, bytesConstRef(), io_text); +} + +bool Secp256k1PP::decryptECIES(Secret const& _k, bytesConstRef _sharedMacData, bytes& io_text) +{ + + // interop w/go ecies implementation + + // io_cipher[0] must be 2, 3, or 4, else invalidpublickey + if (io_text.empty() || io_text[0] < 2 || io_text[0] > 4) + // invalid message: publickey + return false; + + if (io_text.size() < (1 + Public::size + h128::size + 1 + h256::size)) + // invalid message: length + return false; + + Secret z; + ecdh::agree(_k, *(Public*)(io_text.data() + 1), z); + auto key = eciesKDF(z, bytes(), 64); + bytesConstRef eKey = bytesConstRef(&key).cropped(0, 16); + bytesRef mKeyMaterial = bytesRef(&key).cropped(16, 16); + bytes mKey(32); + CryptoPP::SHA256 ctx; + ctx.Update(mKeyMaterial.data(), mKeyMaterial.size()); + ctx.Final(mKey.data()); + + bytes plain; + size_t cipherLen = io_text.size() - 1 - Public::size - h128::size - h256::size; + bytesConstRef cipherWithIV(io_text.data() + 1 + Public::size, h128::size + cipherLen); + bytesConstRef cipherIV = cipherWithIV.cropped(0, h128::size); + bytesConstRef cipherNoIV = cipherWithIV.cropped(h128::size, cipherLen); + bytesConstRef msgMac(cipherNoIV.data() + cipherLen, h256::size); + h128 iv(cipherIV.toBytes()); + + // verify tag + CryptoPP::HMAC hmacctx(mKey.data(), mKey.size()); + hmacctx.Update(cipherWithIV.data(), cipherWithIV.size()); + hmacctx.Update(_sharedMacData.data(), _sharedMacData.size()); + h256 mac; + hmacctx.Final(mac.data()); + for (unsigned i = 0; i < h256::size; i++) + if (mac[i] != msgMac[i]) + return false; + + plain = decryptSymNoAuth(SecureFixedHash<16>(eKey), iv, cipherNoIV).makeInsecure(); + io_text.resize(plain.size()); + io_text.swap(plain); + + return true; +} + +void Secp256k1PP::encrypt(Public const& _k, bytes& io_cipher) +{ + auto& ctx = Secp256k1PPCtx::get(); + ECIES::Encryptor e; + { + Guard l(ctx.x_params); + e.AccessKey().Initialize(ctx.m_params, publicToPoint(_k)); + } + + size_t plen = io_cipher.size(); + bytes ciphertext; + ciphertext.resize(e.CiphertextLength(plen)); + + { + Guard l(ctx.x_rng); + e.Encrypt(ctx.m_rng, io_cipher.data(), plen, ciphertext.data()); + } + + memset(io_cipher.data(), 0, io_cipher.size()); + io_cipher = std::move(ciphertext); +} + +void Secp256k1PP::decrypt(Secret const& _k, bytes& io_text) +{ + auto& ctx = Secp256k1PPCtx::get(); + CryptoPP::ECIES::Decryptor d; + { + Guard l(ctx.x_params); + d.AccessKey().Initialize(ctx.m_params, secretToExponent(_k)); + } + + if (!io_text.size()) + { + io_text.resize(1); + io_text[0] = 0; + } + + size_t clen = io_text.size(); + bytes plain; + plain.resize(d.MaxPlaintextLength(io_text.size())); + + DecodingResult r; + { + Guard l(ctx.x_rng); + r = d.Decrypt(ctx.m_rng, io_text.data(), clen, plain.data()); + } + + if (!r.isValidCoding) + { + io_text.clear(); + return; + } + + io_text.resize(r.messageLength); + io_text = std::move(plain); +} + +void Secp256k1PP::agree(Secret const& _s, Public const& _r, Secret& o_s) +{ + // TODO: mutex ASN1::secp256k1() singleton + // Creating Domain is non-const for m_oid and m_oid is not thread-safe + ECDH::Domain d(ASN1::secp256k1()); + assert(d.AgreedValueLength() == sizeof(o_s)); + byte remote[65] = {0x04}; + memcpy(&remote[1], _r.data(), 64); + d.Agree(o_s.writable().data(), _s.data(), remote); +} + +#if defined(__GNUC__) + #pragma GCC diagnostic pop +#endif // defined(__GNUC__) diff --git a/libdevcrypto/CryptoPP.h b/libdevcrypto/CryptoPP.h new file mode 100644 index 0000000000..edb05080fa --- /dev/null +++ b/libdevcrypto/CryptoPP.h @@ -0,0 +1,73 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . + */ +/** @file CryptoPP.h + * @author Alex Leverington + * @date 2014 + * + * CryptoPP headers and primitive helper methods + */ + +#pragma once + +#include "Common.h" + +namespace dev +{ +namespace crypto +{ +/// Amount of bytes added when encrypting with encryptECIES. +static const unsigned c_eciesOverhead = 113; + +/** + * CryptoPP secp256k1 algorithms. + * @todo Collect ECIES methods into class. + */ +class Secp256k1PP +{ +public: + static Secp256k1PP* get(); + + /// Encrypts text (replace input). (ECIES w/XOR-SHA1) + void encrypt(Public const& _k, bytes& io_cipher); + + /// Decrypts text (replace input). (ECIES w/XOR-SHA1) + void decrypt(Secret const& _k, bytes& io_text); + + /// Encrypts text (replace input). (ECIES w/AES128-CTR-SHA256) + void encryptECIES(Public const& _k, bytes& io_cipher); + + /// Encrypts text (replace input). (ECIES w/AES128-CTR-SHA256) + void encryptECIES(Public const& _k, bytesConstRef _sharedMacData, bytes& io_cipher); + + /// Decrypts text (replace input). (ECIES w/AES128-CTR-SHA256) + bool decryptECIES(Secret const& _k, bytes& io_text); + + /// Decrypts text (replace input). (ECIES w/AES128-CTR-SHA256) + bool decryptECIES(Secret const& _k, bytesConstRef _sharedMacData, bytes& io_text); + + /// Key derivation function used by encryptECIES and decryptECIES. + bytes eciesKDF(Secret const& _z, bytes _s1, unsigned kdBitLen = 256); + + void agree(Secret const& _s, Public const& _r, Secret& o_s); + +private: + Secp256k1PP() = default; +}; + +} +} + diff --git a/libdevcrypto/ECDHE.cpp b/libdevcrypto/ECDHE.cpp new file mode 100644 index 0000000000..1ca3448cff --- /dev/null +++ b/libdevcrypto/ECDHE.cpp @@ -0,0 +1,44 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . + */ +/** @file ECDHE.cpp + * @author Alex Leverington + * @date 2014 + */ + +#include "ECDHE.h" +#include +#include "CryptoPP.h" + +using namespace std; +using namespace dev; +using namespace dev::crypto; + +void dev::crypto::ecdh::agree(Secret const& _s, Public const& _r, Secret& o_s) +{ + Secp256k1PP::get()->agree(_s, _r, o_s); +} + +void ECDHE::agree(Public const& _remote, Secret& o_sharedSecret) const +{ + if (m_remoteEphemeral) + // agreement can only occur once + BOOST_THROW_EXCEPTION(InvalidState()); + + m_remoteEphemeral = _remote; + Secp256k1PP::get()->agree(m_ephemeral.secret(), m_remoteEphemeral, o_sharedSecret); +} + diff --git a/libdevcrypto/ECDHE.h b/libdevcrypto/ECDHE.h new file mode 100644 index 0000000000..5e0ece1ca0 --- /dev/null +++ b/libdevcrypto/ECDHE.h @@ -0,0 +1,62 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . + */ +/** @file ECDHE.h + * @author Alex Leverington + * @date 2014 + * + * Elliptic curve Diffie-Hellman ephemeral key exchange + */ + +#pragma once + +#include "Common.h" + +namespace dev +{ +namespace crypto +{ +namespace ecdh +{ +void agree(Secret const& _s, Public const& _r, Secret& o_s); +} + +/** + * @brief Derive DH shared secret from EC keypairs. + * As ephemeral keys are single-use, agreement is limited to a single occurrence. + */ +class ECDHE +{ +public: + /// Constructor (pass public key for ingress exchange). + ECDHE(): m_ephemeral(KeyPair::create()) {}; + + /// Public key sent to remote. + Public pubkey() { return m_ephemeral.pub(); } + + Secret seckey() { return m_ephemeral.secret(); } + + /// Input public key for dh agreement, output generated shared secret. + void agree(Public const& _remoteEphemeral, Secret& o_sharedSecret) const; + +protected: + KeyPair m_ephemeral; ///< Ephemeral keypair; generated. + mutable Public m_remoteEphemeral; ///< Public key of remote; parameter. Set once when agree is called, otherwise immutable. +}; + +} +} + diff --git a/libdevcrypto/Exceptions.h b/libdevcrypto/Exceptions.h new file mode 100644 index 0000000000..6a61376231 --- /dev/null +++ b/libdevcrypto/Exceptions.h @@ -0,0 +1,35 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Exceptions.h + * @author Christian + * @date 2016 + */ + +#pragma once + +#include + +namespace dev +{ +namespace crypto +{ + +/// Rare malfunction of cryptographic functions. +DEV_SIMPLE_EXCEPTION(CryptoException); + +} +} diff --git a/libdevcrypto/Rsa.cpp b/libdevcrypto/Rsa.cpp new file mode 100644 index 0000000000..89c31d4382 --- /dev/null +++ b/libdevcrypto/Rsa.cpp @@ -0,0 +1,82 @@ +#include +#include +#include + +#include +#include +#include + +#include "Rsa.h" +using namespace std; + +std::string dev::crypto::RSAKeyVerify(const std::string& pubStr, const std::string& strData ) +{ + if (pubStr.empty() || strData.empty()) + { + return ""; + } + + BIO *bio = NULL; + if ((bio = BIO_new_mem_buf(const_cast(pubStr.c_str()), -1)) == NULL) + { + std::cout << "BIO_new_mem_buf failed!" << std::endl; + return ""; + } + + std::string strRet; + RSA* pRSAPublicKey = RSA_new(); + if(PEM_read_bio_RSA_PUBKEY(bio, &pRSAPublicKey, 0, 0) == NULL) + { + std::cout << "PEM_read_bio_RSA_PUBKEY failed!" << std::endl; + return ""; + } + + int nLen = RSA_size(pRSAPublicKey); + char* pEncode = new char[nLen + 1]; + int ret = RSA_public_decrypt(strData.length(), (const unsigned char*)strData.c_str(), (unsigned char*)pEncode, pRSAPublicKey, RSA_PKCS1_PADDING); + if (ret >= 0) + { + strRet = std::string(pEncode, ret); + } + delete[] pEncode; + RSA_free(pRSAPublicKey); + CRYPTO_cleanup_all_ex_data(); + return strRet; +} + +std::string dev::crypto::RSAKeySign( const std::string& strPemFileName, const std::string& strData ) +{ + if (strPemFileName.empty() || strData.empty()) + { + std::cout << "strPemFileName or strData is empty" << std::endl; + return ""; + } + + FILE* hPriKeyFile = fopen(strPemFileName.c_str(),"rb"); + if (hPriKeyFile == NULL) + { + std::cout << "open file:" << strPemFileName << " faied!" << std::endl; + return ""; + } + + std::string strRet; + RSA* pRSAPriKey = RSA_new(); + if(PEM_read_RSAPrivateKey(hPriKeyFile, &pRSAPriKey, 0, 0) == NULL) + { + std::cout << "PEM_read_RSAPrivateKey faied!" << std::endl; + return ""; + } + int nLen = RSA_size(pRSAPriKey); + char* pDecode = new char[nLen+1]; + + int ret = RSA_private_encrypt(strData.length(), (const unsigned char*)strData.c_str(), (unsigned char*)pDecode, pRSAPriKey, RSA_PKCS1_PADDING); + if(ret >= 0) + { + strRet = std::string((char*)pDecode, ret); + } + delete [] pDecode; + RSA_free(pRSAPriKey); + fclose(hPriKeyFile); + CRYPTO_cleanup_all_ex_data(); + return strRet; +} diff --git a/libdevcrypto/Rsa.h b/libdevcrypto/Rsa.h new file mode 100644 index 0000000000..f4b79784b2 --- /dev/null +++ b/libdevcrypto/Rsa.h @@ -0,0 +1,12 @@ +#pragma once + +#include + +using namespace std; + +namespace dev { + namespace crypto { + std::string RSAKeyVerify(const std::string& pubStr, const std::string& strData); + std::string RSAKeySign(const std::string& strPemFileName, const std::string& strData); + } +} diff --git a/libdevcrypto/SecretStore.cpp b/libdevcrypto/SecretStore.cpp new file mode 100644 index 0000000000..a2e8733dc7 --- /dev/null +++ b/libdevcrypto/SecretStore.cpp @@ -0,0 +1,456 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file SecretStore.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "SecretStore.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +using namespace std; +using namespace dev; +namespace js = json_spirit; +namespace fs = boost::filesystem; + +static const int c_keyFileVersion = 3; +std::string SecretStore::defaultpath=getDataDir("keystore"); + +/// Upgrade the json-format to the current version. +static js::mValue upgraded(string const& _s) +{ + js::mValue v; + js::read_string(_s, v); + if (v.type() != js::obj_type) + return js::mValue(); + js::mObject ret = v.get_obj(); + unsigned version = ret.count("Version") ? stoi(ret["Version"].get_str()) : ret.count("version") ? ret["version"].get_int() : 0; + if (version == 1) + { + // upgrade to version 2 + js::mObject old; + swap(old, ret); + + ret["id"] = old["Id"]; + js::mObject c; + c["ciphertext"] = old["Crypto"].get_obj()["CipherText"]; + c["cipher"] = "aes-128-cbc"; + { + js::mObject cp; + cp["iv"] = old["Crypto"].get_obj()["IV"]; + c["cipherparams"] = cp; + } + c["kdf"] = old["Crypto"].get_obj()["KeyHeader"].get_obj()["Kdf"]; + { + js::mObject kp; + kp["salt"] = old["Crypto"].get_obj()["Salt"]; + for (auto const& i: old["Crypto"].get_obj()["KeyHeader"].get_obj()["KdfParams"].get_obj()) + if (i.first != "SaltLen") + kp[boost::to_lower_copy(i.first)] = i.second; + c["kdfparams"] = kp; + } + c["sillymac"] = old["Crypto"].get_obj()["MAC"]; + c["sillymacjson"] = _s; + ret["crypto"] = c; + version = 2; + } + if (ret.count("Crypto") && !ret.count("crypto")) + { + ret["crypto"] = ret["Crypto"]; + ret.erase("Crypto"); + } + if (version == 2) + { + ret["crypto"].get_obj()["cipher"] = "aes-128-ctr"; + ret["crypto"].get_obj()["compat"] = "2"; + version = 3; + } + if (version == c_keyFileVersion) + return ret; + return js::mValue(); +} + +SecretStore::SecretStore(string const& _path): m_path(_path) +{ + load(); +} + +void SecretStore::setPath(string const& _path) +{ + m_path = _path; + load(); +} + +bytesSec SecretStore::secret(h128 const& _uuid, function const& _pass, bool _useCache) const +{ + auto rit = m_cached.find(_uuid); + if (_useCache && rit != m_cached.end()) + return rit->second; + auto it = m_keys.find(_uuid); + bytesSec key; + if (it != m_keys.end()) + { + key = bytesSec(decrypt(it->second.encryptedKey, _pass())); + if (!key.empty()) + m_cached[_uuid] = key; + } + return key; +} + +bytesSec SecretStore::secret(Address const& _address, function const& _pass) const +{ + bytesSec ret; + if (auto k = key(_address)) + ret = bytesSec(decrypt(k->second.encryptedKey, _pass())); + return ret; +} + +bytesSec SecretStore::secret(string const& _content, string const& _pass) +{ + try + { + js::mValue u = upgraded(_content); + if (u.type() != js::obj_type) + return bytesSec(); + return decrypt(js::write_string(u.get_obj()["crypto"], false), _pass); + } + catch (...) + { + return bytesSec(); + } +} + +h128 SecretStore::importSecret(bytesSec const& _s, string const& _pass) +{ + h128 r = h128::random(); + EncryptedKey key{encrypt(_s.ref(), _pass), toUUID(r), KeyPair(Secret(_s)).address()}; + m_cached[r] = _s; + m_keys[r] = move(key); + save(); + return r; +} + +h128 SecretStore::importSecret(bytesConstRef _s, string const& _pass) +{ + h128 r = h128::random(); + EncryptedKey key{encrypt(_s, _pass), toUUID(r), KeyPair(Secret(_s)).address()}; + m_cached[r] = bytesSec(_s); + m_keys[r] = move(key); + save(); + return r; +} + +void SecretStore::kill(h128 const& _uuid) +{ + m_cached.erase(_uuid); + if (m_keys.count(_uuid)) + { + fs::remove(m_keys[_uuid].filename); + m_keys.erase(_uuid); + } +} + +void SecretStore::clearCache() const +{ + m_cached.clear(); +} + +void SecretStore::save(string const& _keysPath) +{ + fs::path p(_keysPath); + fs::create_directories(p); + DEV_IGNORE_EXCEPTIONS(fs::permissions(p, fs::owner_all)); + for (auto& k: m_keys) + { + string uuid = toUUID(k.first); + string filename = (p / uuid).string() + ".json"; + js::mObject v; + js::mValue crypto; + js::read_string(k.second.encryptedKey, crypto); + v["address"] = k.second.address.hex(); + v["crypto"] = crypto; + v["id"] = uuid; + v["version"] = c_keyFileVersion; + writeFile(filename, js::write_string(js::mValue(v), true)); + swap(k.second.filename, filename); + if (!filename.empty() && !fs::equivalent(filename, k.second.filename)) + fs::remove(filename); + } +} + +bool SecretStore::noteAddress(h128 const& _uuid, Address const& _address) +{ + if (m_keys.find(_uuid) != m_keys.end() && m_keys[_uuid].address == ZeroAddress) + { + m_keys[_uuid].address = _address; + return true; + } + return false; +} + +void SecretStore::load(string const& _keysPath) +{ + fs::path p(_keysPath); + try + { + for (fs::directory_iterator it(p); it != fs::directory_iterator(); ++it) + if (fs::is_regular_file(it->path())) + readKey(it->path().string(), true); + } + catch (...) {} +} + +h128 SecretStore::readKey(string const& _file, bool _takeFileOwnership) +{ + LOG(TRACE) << "Reading" << _file; + return readKeyContent(contentsString(_file), _takeFileOwnership ? _file : string()); +} + +h128 SecretStore::readKeyContent(string const& _content, string const& _file) +{ + try + { + js::mValue u = upgraded(_content); + if (u.type() == js::obj_type) + { + js::mObject& o = u.get_obj(); + auto uuid = fromUUID(o["id"].get_str()); + Address address = ZeroAddress; + if (o.find("address") != o.end() && isHex(o["address"].get_str())) + address = Address(o["address"].get_str()); + else + LOG(WARNING) << "Account address is either not defined or not in hex format" << _file; + m_keys[uuid] = EncryptedKey{js::write_string(o["crypto"], false), _file, address}; + return uuid; + } + else + LOG(WARNING) << "Invalid JSON in key file" << _file; + return h128(); + } + catch (...) + { + return h128(); + } +} + +bool SecretStore::recode(Address const& _address, string const& _newPass, function const& _pass, KDF _kdf) +{ + if (auto k = key(_address)) + { + bytesSec s = secret(_address, _pass); + if (s.empty()) + return false; + else + { + k->second.encryptedKey = encrypt(s.ref(), _newPass, _kdf); + save(); + return true; + } + } + return false; +} + +pair const* SecretStore::key(Address const& _address) const +{ + for (auto const& k: m_keys) + if (k.second.address == _address) + return &k; + return nullptr; +} + +pair* SecretStore::key(Address const& _address) +{ + for (auto& k: m_keys) + if (k.second.address == _address) + return &k; + return nullptr; +} + +bool SecretStore::recode(h128 const& _uuid, string const& _newPass, function const& _pass, KDF _kdf) +{ + bytesSec s = secret(_uuid, _pass, true); + if (s.empty()) + return false; + m_cached.erase(_uuid); + m_keys[_uuid].encryptedKey = encrypt(s.ref(), _newPass, _kdf); + save(); + return true; +} + +static bytesSec deriveNewKey(string const& _pass, KDF _kdf, js::mObject& o_ret) +{ + unsigned dklen = 32; + unsigned iterations = 1 << 18; + bytes salt = h256::random().asBytes(); + if (_kdf == KDF::Scrypt) + { + unsigned p = 1; + unsigned r = 8; + o_ret["kdf"] = "scrypt"; + { + js::mObject params; + params["n"] = int64_t(iterations); + params["r"] = int(r); + params["p"] = int(p); + params["dklen"] = int(dklen); + params["salt"] = toHex(salt); + o_ret["kdfparams"] = params; + } + return scrypt(_pass, salt, iterations, r, p, dklen); + } + else + { + o_ret["kdf"] = "pbkdf2"; + { + js::mObject params; + params["prf"] = "hmac-sha256"; + params["c"] = int(iterations); + params["salt"] = toHex(salt); + params["dklen"] = int(dklen); + o_ret["kdfparams"] = params; + } + return pbkdf2(_pass, salt, iterations, dklen); + } +} + +string SecretStore::encrypt(bytesConstRef _v, string const& _pass, KDF _kdf) +{ + js::mObject ret; + + bytesSec derivedKey = deriveNewKey(_pass, _kdf, ret); + if (derivedKey.empty()) + BOOST_THROW_EXCEPTION(crypto::CryptoException() << errinfo_comment("Key derivation failed.")); + + ret["cipher"] = "aes-128-ctr"; + SecureFixedHash<16> key(derivedKey, h128::AlignLeft); + h128 iv = h128::random(); + { + js::mObject params; + params["iv"] = toHex(iv.ref()); + ret["cipherparams"] = params; + } + + // cipher text + bytes cipherText = encryptSymNoAuth(key, iv, _v); + if (cipherText.empty()) + BOOST_THROW_EXCEPTION(crypto::CryptoException() << errinfo_comment("Key encryption failed.")); + ret["ciphertext"] = toHex(cipherText); + + // and mac. + h256 mac = sha3(derivedKey.ref().cropped(16, 16).toBytes() + cipherText); + ret["mac"] = toHex(mac.ref()); + + return js::write_string(js::mValue(ret), true); +} + +bytesSec SecretStore::decrypt(string const& _v, string const& _pass) +{ + js::mObject o; + { + js::mValue ov; + js::read_string(_v, ov); + o = ov.get_obj(); + } + + // derive key + bytesSec derivedKey; + if (o["kdf"].get_str() == "pbkdf2") + { + auto params = o["kdfparams"].get_obj(); + if (params["prf"].get_str() != "hmac-sha256") + { + LOG(WARNING) << "Unknown PRF for PBKDF2" << params["prf"].get_str() << "not supported."; + return bytesSec(); + } + unsigned iterations = params["c"].get_int(); + bytes salt = fromHex(params["salt"].get_str()); + derivedKey = pbkdf2(_pass, salt, iterations, params["dklen"].get_int()); + } + else if (o["kdf"].get_str() == "scrypt") + { + auto p = o["kdfparams"].get_obj(); + derivedKey = scrypt(_pass, fromHex(p["salt"].get_str()), p["n"].get_int(), p["r"].get_int(), p["p"].get_int(), p["dklen"].get_int()); + } + else + { + LOG(WARNING) << "Unknown KDF" << o["kdf"].get_str() << "not supported."; + return bytesSec(); + } + + if (derivedKey.size() < 32 && !(o.count("compat") && o["compat"].get_str() == "2")) + { + LOG(WARNING) << "Derived key's length too short (<32 bytes)"; + return bytesSec(); + } + + bytes cipherText = fromHex(o["ciphertext"].get_str()); + + // check MAC + if (o.count("mac")) + { + h256 mac(o["mac"].get_str()); + h256 macExp; + if (o.count("compat") && o["compat"].get_str() == "2") + macExp = sha3(derivedKey.ref().cropped(derivedKey.size() - 16).toBytes() + cipherText); + else + macExp = sha3(derivedKey.ref().cropped(16, 16).toBytes() + cipherText); + if (mac != macExp) + { + LOG(WARNING) << "Invalid key - MAC mismatch; expected" << toString(macExp) << ", got" << toString(mac); + return bytesSec(); + } + } + else if (o.count("sillymac")) + { + h256 mac(o["sillymac"].get_str()); + h256 macExp = sha3(asBytes(o["sillymacjson"].get_str()) + derivedKey.ref().cropped(derivedKey.size() - 16).toBytes() + cipherText); + if (mac != macExp) + { + LOG(WARNING) << "Invalid key - MAC mismatch; expected" << toString(macExp) << ", got" << toString(mac); + return bytesSec(); + } + } + else + LOG(WARNING) << "No MAC. Proceeding anyway."; + + // decrypt + if (o["cipher"].get_str() == "aes-128-ctr") + { + auto params = o["cipherparams"].get_obj(); + h128 iv(params["iv"].get_str()); + if (o.count("compat") && o["compat"].get_str() == "2") + { + SecureFixedHash<16> key(sha3Secure(derivedKey.ref().cropped(derivedKey.size() - 16)), h128::AlignRight); + return decryptSymNoAuth(key, iv, &cipherText); + } + else + return decryptSymNoAuth(SecureFixedHash<16>(derivedKey, h128::AlignLeft), iv, &cipherText); + } + else + { + LOG(WARNING) << "Unknown cipher" << o["cipher"].get_str() << "not supported."; + return bytesSec(); + } +} diff --git a/libdevcrypto/SecretStore.h b/libdevcrypto/SecretStore.h new file mode 100644 index 0000000000..ee6e4cd90a --- /dev/null +++ b/libdevcrypto/SecretStore.h @@ -0,0 +1,147 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . + */ +/** @file SecretStore.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include +#include +#include +#include "Common.h" + +namespace dev +{ + +enum class KDF { + PBKDF2_SHA256, + Scrypt, +}; + +/** + * Manages encrypted keys stored in a certain directory on disk. The keys are read into memory + * and changes to the keys are automatically synced to the directory. + * Each file stores exactly one key in a specific JSON format whose file name is derived from the + * UUID of the key. + * @note that most of the functions here affect the filesystem and throw exceptions on failure, + * and they also throw exceptions upon rare malfunction in the cryptographic functions. + */ +class SecretStore +{ +public: + struct EncryptedKey + { + std::string encryptedKey; + std::string filename; + Address address; + }; + + /// Construct a new SecretStore but don't read any keys yet. + /// Call setPath in + SecretStore() = default; + + /// Construct a new SecretStore and read all keys in the given directory. + SecretStore(std::string const& _path); + + /// Set a path for finding secrets. + void setPath(std::string const& _path); + + /// @returns the secret key stored by the given @a _uuid. + /// @param _pass function that returns the password for the key. + /// @param _useCache if true, allow previously decrypted keys to be returned directly. + bytesSec secret(h128 const& _uuid, std::function const& _pass, bool _useCache = true) const; + /// @returns the secret key stored by the given @a _uuid. + /// @param _pass function that returns the password for the key. + static bytesSec secret(std::string const& _content, std::string const& _pass); + /// @returns the secret key stored by the given @a _address. + /// @param _pass function that returns the password for the key. + bytesSec secret(Address const& _address, std::function const& _pass) const; + /// Imports the (encrypted) key stored in the file @a _file and copies it to the managed directory. + h128 importKey(std::string const& _file) { auto ret = readKey(_file, false); if (ret) save(); return ret; } + /// Imports the (encrypted) key contained in the json formatted @a _content and stores it in + /// the managed directory. + h128 importKeyContent(std::string const& _content) { auto ret = readKeyContent(_content, std::string()); if (ret) save(); return ret; } + /// Imports the decrypted key given by @a _s and stores it, encrypted with + /// (a key derived from) the password @a _pass. + h128 importSecret(bytesSec const& _s, std::string const& _pass); + h128 importSecret(bytesConstRef _s, std::string const& _pass); + /// Decrypts and re-encrypts the key identified by @a _uuid. + bool recode(h128 const& _uuid, std::string const& _newPass, std::function const& _pass, KDF _kdf = KDF::Scrypt); + /// Decrypts and re-encrypts the key identified by @a _address. + bool recode(Address const& _address, std::string const& _newPass, std::function const& _pass, KDF _kdf = KDF::Scrypt); + /// Removes the key specified by @a _uuid from both memory and disk. + void kill(h128 const& _uuid); + + /// Returns the uuids of all stored keys. + std::vector keys() const { return keysOf(m_keys); } + + /// @returns true iff we have the given key stored. + bool contains(h128 const& _k) const { return m_keys.count(_k); } + + /// Clears all cached decrypted keys. The passwords have to be supplied in order to retrieve + /// secrets again after calling this function. + void clearCache() const; + + /// Import the key from the file @a _file, but do not copy it to the managed directory yet. + /// @param _takeFileOwnership if true, deletes the file if it is not the canonical file for the + /// key (derived from its uuid). + h128 readKey(std::string const& _file, bool _takeFileOwnership); + /// Import the key contained in the json-encoded @a _content, but do not store it in the + /// managed directory. + /// @param _file if given, assume this file contains @a _content and delete it later, if it is + /// not the canonical file for the key (derived from the uuid). + h128 readKeyContent(std::string const& _content, std::string const& _file = std::string()); + + /// Store all keys in the directory @a _keysPath. + void save(std::string const& _keysPath); + /// Store all keys in the managed directory. + void save() { save(m_path); } + /// @returns true if the current file @arg _uuid contains an empty address. m_keys will be updated with the given @arg _address. + bool noteAddress(h128 const& _uuid, Address const& _address); + /// @returns the address of the given key or the zero address if it is unknown. + Address address(h128 const& _uuid) const { return m_keys.at(_uuid).address; } + + /// @returns the default path for the managed directory. + //static std::string defaultPath() { return getDataDir("web3") + "/keys"; } + + static std::string defaultPath() { return SecretStore::defaultpath ; } + static std::string defaultpath; + +private: + /// Loads all keys in the given directory. + void load(std::string const& _keysPath); + void load() { load(m_path); } + /// Encrypts @a _v with a key derived from @a _pass or the empty string on error. + static std::string encrypt(bytesConstRef _v, std::string const& _pass, KDF _kdf = KDF::Scrypt); + /// Decrypts @a _v with a key derived from @a _pass or the empty byte array on error. + static bytesSec decrypt(std::string const& _v, std::string const& _pass); + /// @returns the key given the @a _address. + std::pair const* key(Address const& _address) const; + std::pair* key(Address const& _address); + /// Stores decrypted keys by uuid. + mutable std::unordered_map m_cached; + /// Stores encrypted keys together with the file they were loaded from by uuid. + std::unordered_map m_keys; + + std::string m_path; +}; + +} + diff --git a/libdevcrypto/WordList.cpp b/libdevcrypto/WordList.cpp new file mode 100644 index 0000000000..3a2a0194ee --- /dev/null +++ b/libdevcrypto/WordList.cpp @@ -0,0 +1,5036 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file WordList.cpp + * @author Gav Wood + * @date 2015 + */ + +#include "WordList.h" + +namespace dev +{ + +std::vector const WordList = +{ + "be", + "and", + "of", + "a", + "in", + "to", + "have", + "to", + "it", + "i", + "that", + "for", + "you", + "he", + "with", + "on", + "do", + "say", + "this", + "they", + "at", + "but", + "we", + "his", + "from", + "that", + "not", + "she", + "or", + "as", + "what", + "go", + "their", + "can", + "who", + "get", + "if", + "would", + "her", + "all", + "my", + "make", + "about", + "know", + "will", + "as", + "up", + "one", + "time", + "there", + "year", + "so", + "think", + "when", + "which", + "them", + "some", + "me", + "people", + "take", + "out", + "into", + "just", + "see", + "him", + "your", + "come", + "could", + "now", + "than", + "like", + "other", + "how", + "then", + "its", + "our", + "two", + "more", + "these", + "want", + "way", + "look", + "first", + "also", + "new", + "because", + "day", + "more", + "use", + "no", + "man", + "find", + "here", + "thing", + "give", + "many", + "well", + "only", + "those", + "tell", + "one", + "very", + "her", + "even", + "back", + "any", + "good", + "woman", + "through", + "us", + "life", + "child", + "there", + "work", + "down", + "may", + "after", + "should", + "call", + "world", + "over", + "school", + "still", + "try", + "in", + "as", + "last", + "ask", + "need", + "too", + "feel", + "three", + "when", + "state", + "never", + "become", + "between", + "high", + "really", + "something", + "most", + "another", + "much", + "family", + "own", + "out", + "leave", + "put", + "old", + "while", + "mean", + "on", + "keep", + "student", + "why", + "let", + "great", + "same", + "big", + "group", + "begin", + "seem", + "country", + "help", + "talk", + "where", + "turn", + "problem", + "every", + "start", + "hand", + "might", + "american", + "show", + "part", + "about", + "against", + "place", + "over", + "such", + "again", + "few", + "case", + "most", + "week", + "company", + "where", + "system", + "each", + "right", + "program", + "hear", + "so", + "question", + "during", + "work", + "play", + "government", + "run", + "small", + "number", + "off", + "always", + "move", + "like", + "night", + "live", + "mr", + "point", + "believe", + "hold", + "today", + "bring", + "happen", + "next", + "without", + "before", + "large", + "all", + "million", + "must", + "home", + "under", + "water", + "room", + "write", + "mother", + "area", + "national", + "money", + "story", + "young", + "fact", + "month", + "different", + "lot", + "right", + "study", + "book", + "eye", + "job", + "word", + "though", + "business", + "issue", + "side", + "kind", + "four", + "head", + "far", + "black", + "long", + "both", + "little", + "house", + "yes", + "after", + "since", + "long", + "provide", + "service", + "around", + "friend", + "important", + "father", + "sit", + "away", + "until", + "power", + "hour", + "game", + "often", + "yet", + "line", + "political", + "end", + "among", + "ever", + "stand", + "bad", + "lose", + "however", + "member", + "pay", + "law", + "meet", + "car", + "city", + "almost", + "include", + "continue", + "set", + "later", + "community", + "much", + "name", + "five", + "once", + "white", + "least", + "president", + "learn", + "real", + "change", + "team", + "minute", + "best", + "several", + "idea", + "kid", + "body", + "information", + "nothing", + "ago", + "right", + "lead", + "social", + "understand", + "whether", + "back", + "watch", + "together", + "follow", + "around", + "parent", + "only", + "stop", + "face", + "anything", + "create", + "public", + "already", + "speak", + "others", + "read", + "level", + "allow", + "add", + "office", + "spend", + "door", + "health", + "person", + "art", + "sure", + "such", + "war", + "history", + "party", + "within", + "grow", + "result", + "open", + "change", + "morning", + "walk", + "reason", + "low", + "win", + "research", + "girl", + "guy", + "early", + "food", + "before", + "moment", + "himself", + "air", + "teacher", + "force", + "offer", + "enough", + "both", + "education", + "across", + "although", + "remember", + "foot", + "second", + "boy", + "maybe", + "toward", + "able", + "age", + "off", + "policy", + "everything", + "love", + "process", + "music", + "including", + "consider", + "appear", + "actually", + "buy", + "probably", + "human", + "wait", + "serve", + "market", + "die", + "send", + "expect", + "home", + "sense", + "build", + "stay", + "fall", + "oh", + "nation", + "plan", + "cut", + "college", + "interest", + "death", + "course", + "someone", + "experience", + "behind", + "reach", + "local", + "kill", + "six", + "remain", + "effect", + "use", + "yeah", + "suggest", + "class", + "control", + "raise", + "care", + "perhaps", + "little", + "late", + "hard", + "field", + "else", + "pass", + "former", + "sell", + "major", + "sometimes", + "require", + "along", + "development", + "themselves", + "report", + "role", + "better", + "economic", + "effort", + "up", + "decide", + "rate", + "strong", + "possible", + "heart", + "drug", + "show", + "leader", + "light", + "voice", + "wife", + "whole", + "police", + "mind", + "finally", + "pull", + "return", + "free", + "military", + "price", + "report", + "less", + "according", + "decision", + "explain", + "son", + "hope", + "even", + "develop", + "view", + "relationship", + "carry", + "town", + "road", + "drive", + "arm", + "true", + "federal", + "break", + "better", + "difference", + "thank", + "receive", + "value", + "international", + "building", + "action", + "full", + "model", + "join", + "season", + "society", + "because", + "tax", + "director", + "early", + "position", + "player", + "agree", + "especially", + "record", + "pick", + "wear", + "paper", + "special", + "space", + "ground", + "form", + "support", + "event", + "official", + "whose", + "matter", + "everyone", + "center", + "couple", + "site", + "end", + "project", + "hit", + "base", + "activity", + "star", + "table", + "need", + "court", + "produce", + "eat", + "american", + "teach", + "oil", + "half", + "situation", + "easy", + "cost", + "industry", + "figure", + "face", + "street", + "image", + "itself", + "phone", + "either", + "data", + "cover", + "quite", + "picture", + "clear", + "practice", + "piece", + "land", + "recent", + "describe", + "product", + "doctor", + "wall", + "patient", + "worker", + "news", + "test", + "movie", + "certain", + "north", + "love", + "personal", + "open", + "support", + "simply", + "third", + "technology", + "catch", + "step", + "baby", + "computer", + "type", + "attention", + "draw", + "film", + "republican", + "tree", + "source", + "red", + "nearly", + "organization", + "choose", + "cause", + "hair", + "look", + "point", + "century", + "evidence", + "window", + "difficult", + "listen", + "soon", + "culture", + "billion", + "chance", + "brother", + "energy", + "period", + "course", + "summer", + "less", + "realize", + "hundred", + "available", + "plant", + "likely", + "opportunity", + "term", + "short", + "letter", + "condition", + "choice", + "place", + "single", + "rule", + "daughter", + "administration", + "south", + "husband", + "congress", + "floor", + "campaign", + "material", + "population", + "well", + "call", + "economy", + "medical", + "hospital", + "church", + "close", + "thousand", + "risk", + "current", + "fire", + "future", + "wrong", + "involve", + "defense", + "anyone", + "increase", + "security", + "bank", + "myself", + "certainly", + "west", + "sport", + "board", + "seek", + "per", + "subject", + "officer", + "private", + "rest", + "behavior", + "deal", + "performance", + "fight", + "throw", + "top", + "quickly", + "past", + "goal", + "second", + "bed", + "order", + "author", + "fill", + "represent", + "focus", + "foreign", + "drop", + "plan", + "blood", + "upon", + "agency", + "push", + "nature", + "color", + "no", + "recently", + "store", + "reduce", + "sound", + "note", + "fine", + "before", + "near", + "movement", + "page", + "enter", + "share", + "than", + "common", + "poor", + "other", + "natural", + "race", + "concern", + "series", + "significant", + "similar", + "hot", + "language", + "each", + "usually", + "response", + "dead", + "rise", + "animal", + "factor", + "decade", + "article", + "shoot", + "east", + "save", + "seven", + "artist", + "away", + "scene", + "stock", + "career", + "despite", + "central", + "eight", + "thus", + "treatment", + "beyond", + "happy", + "exactly", + "protect", + "approach", + "lie", + "size", + "dog", + "fund", + "serious", + "occur", + "media", + "ready", + "sign", + "thought", + "list", + "individual", + "simple", + "quality", + "pressure", + "accept", + "answer", + "hard", + "resource", + "identify", + "left", + "meeting", + "determine", + "prepare", + "disease", + "whatever", + "success", + "argue", + "cup", + "particularly", + "amount", + "ability", + "staff", + "recognize", + "indicate", + "character", + "growth", + "loss", + "degree", + "wonder", + "attack", + "herself", + "region", + "television", + "box", + "tv", + "training", + "pretty", + "trade", + "deal", + "election", + "everybody", + "physical", + "lay", + "general", + "feeling", + "standard", + "bill", + "message", + "fail", + "outside", + "arrive", + "analysis", + "benefit", + "name", + "sex", + "forward", + "lawyer", + "present", + "section", + "environmental", + "glass", + "answer", + "skill", + "sister", + "pm", + "professor", + "operation", + "financial", + "crime", + "stage", + "ok", + "compare", + "authority", + "miss", + "design", + "sort", + "one", + "act", + "ten", + "knowledge", + "gun", + "station", + "blue", + "state", + "strategy", + "little", + "clearly", + "discuss", + "indeed", + "force", + "truth", + "song", + "example", + "democratic", + "check", + "environment", + "leg", + "dark", + "public", + "various", + "rather", + "laugh", + "guess", + "executive", + "set", + "study", + "prove", + "hang", + "entire", + "rock", + "design", + "enough", + "forget", + "since", + "claim", + "note", + "remove", + "manager", + "help", + "close", + "sound", + "enjoy", + "network", + "legal", + "religious", + "cold", + "form", + "final", + "main", + "science", + "green", + "memory", + "card", + "above", + "seat", + "cell", + "establish", + "nice", + "trial", + "expert", + "that", + "spring", + "firm", + "democrat", + "radio", + "visit", + "management", + "care", + "avoid", + "imagine", + "tonight", + "huge", + "ball", + "no", + "close", + "finish", + "yourself", + "talk", + "theory", + "impact", + "respond", + "statement", + "maintain", + "charge", + "popular", + "traditional", + "onto", + "reveal", + "direction", + "weapon", + "employee", + "cultural", + "contain", + "peace", + "head", + "control", + "base", + "pain", + "apply", + "play", + "measure", + "wide", + "shake", + "fly", + "interview", + "manage", + "chair", + "fish", + "particular", + "camera", + "structure", + "politics", + "perform", + "bit", + "weight", + "suddenly", + "discover", + "candidate", + "top", + "production", + "treat", + "trip", + "evening", + "affect", + "inside", + "conference", + "unit", + "best", + "style", + "adult", + "worry", + "range", + "mention", + "rather", + "far", + "deep", + "past", + "edge", + "individual", + "specific", + "writer", + "trouble", + "necessary", + "throughout", + "challenge", + "fear", + "shoulder", + "institution", + "middle", + "sea", + "dream", + "bar", + "beautiful", + "property", + "instead", + "improve", + "stuff", + "detail", + "method", + "sign", + "somebody", + "magazine", + "hotel", + "soldier", + "reflect", + "heavy", + "sexual", + "cause", + "bag", + "heat", + "fall", + "marriage", + "tough", + "sing", + "surface", + "purpose", + "exist", + "pattern", + "whom", + "skin", + "agent", + "owner", + "machine", + "gas", + "down", + "ahead", + "generation", + "commercial", + "address", + "cancer", + "test", + "item", + "reality", + "coach", + "step", + "mrs", + "yard", + "beat", + "violence", + "total", + "tend", + "investment", + "discussion", + "finger", + "garden", + "notice", + "collection", + "modern", + "task", + "partner", + "positive", + "civil", + "kitchen", + "consumer", + "shot", + "budget", + "wish", + "painting", + "scientist", + "safe", + "agreement", + "capital", + "mouth", + "nor", + "victim", + "newspaper", + "instead", + "threat", + "responsibility", + "smile", + "attorney", + "score", + "account", + "interesting", + "break", + "audience", + "rich", + "dinner", + "figure", + "vote", + "western", + "relate", + "travel", + "debate", + "prevent", + "citizen", + "majority", + "none", + "front", + "born", + "admit", + "senior", + "assume", + "wind", + "key", + "professional", + "mission", + "fast", + "alone", + "customer", + "suffer", + "speech", + "successful", + "option", + "participant", + "southern", + "fresh", + "eventually", + "no", + "forest", + "video", + "global", + "senate", + "reform", + "access", + "restaurant", + "judge", + "publish", + "cost", + "relation", + "like", + "release", + "own", + "bird", + "opinion", + "credit", + "critical", + "corner", + "concerned", + "recall", + "version", + "stare", + "safety", + "effective", + "neighborhood", + "original", + "act", + "troop", + "income", + "directly", + "hurt", + "species", + "immediately", + "track", + "basic", + "strike", + "hope", + "sky", + "freedom", + "absolutely", + "plane", + "nobody", + "achieve", + "object", + "attitude", + "labor", + "refer", + "concept", + "client", + "powerful", + "perfect", + "nine", + "therefore", + "conduct", + "announce", + "conversation", + "examine", + "touch", + "please", + "attend", + "completely", + "vote", + "variety", + "sleep", + "turn", + "involved", + "investigation", + "nuclear", + "researcher", + "press", + "conflict", + "spirit", + "experience", + "replace", + "british", + "encourage", + "lot", + "lot", + "lot", + "lot", + "argument", + "by", + "once", + "camp", + "brain", + "feature", + "afternoon", + "am", + "weekend", + "dozen", + "possibility", + "along", + "insurance", + "department", + "battle", + "beginning", + "date", + "generally", + "african", + "very", + "sorry", + "crisis", + "complete", + "fan", + "stick", + "define", + "easily", + "through", + "hole", + "element", + "vision", + "status", + "normal", + "chinese", + "ship", + "solution", + "stone", + "slowly", + "scale", + "bit", + "university", + "introduce", + "driver", + "attempt", + "park", + "spot", + "lack", + "ice", + "boat", + "drink", + "sun", + "front", + "distance", + "wood", + "handle", + "truck", + "return", + "mountain", + "survey", + "supposed", + "tradition", + "winter", + "village", + "soviet", + "refuse", + "sales", + "roll", + "communication", + "run", + "screen", + "gain", + "resident", + "hide", + "gold", + "club", + "future", + "farm", + "potential", + "increase", + "middle", + "european", + "presence", + "independent", + "district", + "shape", + "reader", + "ms", + "contract", + "crowd", + "christian", + "express", + "apartment", + "willing", + "strength", + "previous", + "band", + "obviously", + "horse", + "interested", + "target", + "prison", + "ride", + "guard", + "terms", + "demand", + "reporter", + "deliver", + "text", + "share", + "tool", + "wild", + "vehicle", + "observe", + "flight", + "inside", + "facility", + "understanding", + "average", + "emerge", + "advantage", + "quick", + "light", + "leadership", + "earn", + "pound", + "basis", + "bright", + "operate", + "guest", + "sample", + "contribute", + "tiny", + "block", + "protection", + "settle", + "feed", + "collect", + "additional", + "while", + "highly", + "identity", + "title", + "mostly", + "lesson", + "faith", + "river", + "promote", + "living", + "present", + "count", + "unless", + "marry", + "tomorrow", + "technique", + "path", + "ear", + "shop", + "folk", + "order", + "principle", + "survive", + "lift", + "border", + "competition", + "jump", + "gather", + "limit", + "fit", + "claim", + "cry", + "equipment", + "worth", + "associate", + "critic", + "warm", + "aspect", + "result", + "insist", + "failure", + "annual", + "french", + "christmas", + "comment", + "responsible", + "affair", + "approach", + "until", + "procedure", + "regular", + "spread", + "chairman", + "baseball", + "soft", + "ignore", + "egg", + "measure", + "belief", + "demonstrate", + "anybody", + "murder", + "gift", + "religion", + "review", + "editor", + "past", + "engage", + "coffee", + "document", + "speed", + "cross", + "influence", + "anyway", + "threaten", + "commit", + "female", + "youth", + "wave", + "move", + "afraid", + "quarter", + "background", + "native", + "broad", + "wonderful", + "deny", + "apparently", + "slightly", + "reaction", + "twice", + "suit", + "perspective", + "growing", + "blow", + "construction", + "kind", + "intelligence", + "destroy", + "cook", + "connection", + "charge", + "burn", + "shoe", + "view", + "grade", + "context", + "committee", + "hey", + "mistake", + "focus", + "smile", + "location", + "clothes", + "indian", + "quiet", + "dress", + "promise", + "aware", + "neighbor", + "complete", + "drive", + "function", + "bone", + "active", + "extend", + "chief", + "average", + "combine", + "wine", + "below", + "cool", + "voter", + "mean", + "demand", + "learning", + "bus", + "hell", + "dangerous", + "remind", + "moral", + "united", + "category", + "relatively", + "victory", + "key", + "academic", + "visit", + "internet", + "healthy", + "fire", + "negative", + "following", + "historical", + "medicine", + "tour", + "depend", + "photo", + "finding", + "grab", + "direct", + "classroom", + "contact", + "justice", + "participate", + "daily", + "fair", + "pair", + "famous", + "exercise", + "knee", + "flower", + "tape", + "hire", + "familiar", + "appropriate", + "supply", + "fully", + "cut", + "will", + "actor", + "birth", + "search", + "tie", + "democracy", + "eastern", + "primary", + "yesterday", + "circle", + "device", + "progress", + "next", + "front", + "bottom", + "island", + "exchange", + "clean", + "studio", + "train", + "lady", + "colleague", + "application", + "neck", + "lean", + "damage", + "plastic", + "tall", + "plate", + "hate", + "otherwise", + "writing", + "press", + "male", + "start", + "alive", + "expression", + "football", + "intend", + "attack", + "chicken", + "army", + "abuse", + "theater", + "shut", + "map", + "extra", + "session", + "danger", + "welcome", + "domestic", + "lots", + "literature", + "rain", + "desire", + "assessment", + "injury", + "respect", + "northern", + "nod", + "paint", + "fuel", + "leaf", + "direct", + "dry", + "russian", + "instruction", + "fight", + "pool", + "climb", + "sweet", + "lead", + "engine", + "fourth", + "salt", + "expand", + "importance", + "metal", + "fat", + "ticket", + "software", + "disappear", + "corporate", + "strange", + "lip", + "reading", + "urban", + "mental", + "increasingly", + "lunch", + "educational", + "somewhere", + "farmer", + "above", + "sugar", + "planet", + "favorite", + "explore", + "obtain", + "enemy", + "greatest", + "complex", + "surround", + "athlete", + "invite", + "repeat", + "carefully", + "soul", + "scientific", + "impossible", + "panel", + "meaning", + "mom", + "married", + "alone", + "instrument", + "predict", + "weather", + "presidential", + "emotional", + "commitment", + "supreme", + "bear", + "pocket", + "thin", + "temperature", + "surprise", + "poll", + "proposal", + "consequence", + "half", + "breath", + "sight", + "cover", + "balance", + "adopt", + "minority", + "straight", + "attempt", + "connect", + "works", + "teaching", + "belong", + "aid", + "advice", + "okay", + "photograph", + "empty", + "regional", + "trail", + "novel", + "code", + "somehow", + "organize", + "jury", + "breast", + "iraqi", + "human", + "acknowledge", + "theme", + "storm", + "union", + "record", + "desk", + "fear", + "thanks", + "fruit", + "under", + "expensive", + "yellow", + "conclusion", + "prime", + "shadow", + "struggle", + "conclude", + "analyst", + "dance", + "limit", + "like", + "regulation", + "being", + "last", + "ring", + "largely", + "shift", + "revenue", + "mark", + "locate", + "county", + "appearance", + "package", + "difficulty", + "bridge", + "recommend", + "obvious", + "train", + "basically", + "e-mail", + "generate", + "anymore", + "propose", + "thinking", + "possibly", + "trend", + "visitor", + "loan", + "currently", + "comfortable", + "investor", + "but", + "profit", + "angry", + "crew", + "deep", + "accident", + "male", + "meal", + "hearing", + "traffic", + "muscle", + "notion", + "capture", + "prefer", + "truly", + "earth", + "japanese", + "chest", + "search", + "thick", + "cash", + "museum", + "beauty", + "emergency", + "unique", + "feature", + "internal", + "ethnic", + "link", + "stress", + "content", + "select", + "root", + "nose", + "declare", + "outside", + "appreciate", + "actual", + "bottle", + "hardly", + "setting", + "launch", + "dress", + "file", + "sick", + "outcome", + "ad", + "defend", + "matter", + "judge", + "duty", + "sheet", + "ought", + "ensure", + "catholic", + "extremely", + "extent", + "component", + "mix", + "long-term", + "slow", + "contrast", + "zone", + "wake", + "challenge", + "airport", + "chief", + "brown", + "standard", + "shirt", + "pilot", + "warn", + "ultimately", + "cat", + "contribution", + "capacity", + "ourselves", + "estate", + "guide", + "circumstance", + "snow", + "english", + "politician", + "steal", + "pursue", + "slip", + "percentage", + "meat", + "funny", + "neither", + "soil", + "influence", + "surgery", + "correct", + "jewish", + "blame", + "estimate", + "due", + "basketball", + "late", + "golf", + "investigate", + "crazy", + "significantly", + "chain", + "address", + "branch", + "combination", + "just", + "frequently", + "governor", + "relief", + "user", + "dad", + "kick", + "part", + "manner", + "ancient", + "silence", + "rating", + "golden", + "motion", + "german", + "gender", + "solve", + "fee", + "landscape", + "used", + "bowl", + "equal", + "long", + "official", + "forth", + "frame", + "typical", + "except", + "conservative", + "eliminate", + "host", + "hall", + "trust", + "ocean", + "score", + "row", + "producer", + "afford", + "meanwhile", + "regime", + "division", + "confirm", + "fix", + "appeal", + "mirror", + "tooth", + "smart", + "length", + "entirely", + "rely", + "topic", + "complain", + "issue", + "variable", + "back", + "range", + "telephone", + "perception", + "attract", + "confidence", + "bedroom", + "secret", + "debt", + "rare", + "his", + "tank", + "nurse", + "coverage", + "opposition", + "aside", + "anywhere", + "bond", + "file", + "pleasure", + "master", + "era", + "requirement", + "check", + "stand", + "fun", + "expectation", + "wing", + "separate", + "now", + "clear", + "struggle", + "mean", + "somewhat", + "pour", + "stir", + "judgment", + "clean", + "except", + "beer", + "english", + "reference", + "tear", + "doubt", + "grant", + "seriously", + "account", + "minister", + "totally", + "hero", + "industrial", + "cloud", + "stretch", + "winner", + "volume", + "travel", + "seed", + "surprised", + "rest", + "fashion", + "pepper", + "separate", + "busy", + "intervention", + "copy", + "tip", + "below", + "cheap", + "aim", + "cite", + "welfare", + "vegetable", + "gray", + "dish", + "beach", + "improvement", + "everywhere", + "opening", + "overall", + "divide", + "initial", + "terrible", + "oppose", + "contemporary", + "route", + "multiple", + "essential", + "question", + "league", + "criminal", + "careful", + "core", + "upper", + "rush", + "necessarily", + "specifically", + "tired", + "rise", + "tie", + "employ", + "holiday", + "dance", + "vast", + "resolution", + "household", + "fewer", + "abortion", + "apart", + "witness", + "match", + "barely", + "sector", + "representative", + "lack", + "beneath", + "beside", + "black", + "incident", + "limited", + "proud", + "flow", + "faculty", + "increased", + "waste", + "merely", + "mass", + "emphasize", + "experiment", + "definitely", + "bomb", + "enormous", + "tone", + "liberal", + "massive", + "engineer", + "wheel", + "female", + "decline", + "invest", + "promise", + "cable", + "towards", + "expose", + "rural", + "aids", + "jew", + "narrow", + "cream", + "secretary", + "gate", + "solid", + "hill", + "typically", + "noise", + "grass", + "unfortunately", + "hat", + "legislation", + "succeed", + "either", + "celebrate", + "achievement", + "fishing", + "drink", + "accuse", + "hand", + "useful", + "land", + "secret", + "reject", + "talent", + "taste", + "characteristic", + "milk", + "escape", + "cast", + "sentence", + "unusual", + "closely", + "convince", + "height", + "physician", + "assess", + "sleep", + "plenty", + "ride", + "virtually", + "first", + "addition", + "sharp", + "creative", + "lower", + "behind", + "approve", + "explanation", + "outside", + "gay", + "campus", + "proper", + "live", + "guilty", + "living", + "acquire", + "compete", + "technical", + "plus", + "mind", + "potential", + "immigrant", + "weak", + "illegal", + "hi", + "alternative", + "interaction", + "column", + "personality", + "signal", + "curriculum", + "list", + "honor", + "passenger", + "assistance", + "forever", + "fun", + "regard", + "israeli", + "association", + "twenty", + "knock", + "review", + "wrap", + "lab", + "offer", + "display", + "criticism", + "asset", + "depression", + "spiritual", + "musical", + "journalist", + "prayer", + "suspect", + "scholar", + "warning", + "climate", + "cheese", + "observation", + "childhood", + "payment", + "sir", + "permit", + "cigarette", + "definition", + "priority", + "bread", + "creation", + "graduate", + "request", + "emotion", + "scream", + "dramatic", + "universe", + "gap", + "excellent", + "deeply", + "prosecutor", + "mark", + "green", + "lucky", + "drag", + "airline", + "library", + "agenda", + "recover", + "factory", + "selection", + "primarily", + "roof", + "unable", + "expense", + "initiative", + "diet", + "arrest", + "funding", + "therapy", + "wash", + "schedule", + "sad", + "brief", + "housing", + "post", + "purchase", + "existing", + "dark", + "steel", + "regarding", + "shout", + "remaining", + "visual", + "fairly", + "chip", + "violent", + "silent", + "suppose", + "self", + "bike", + "tea", + "perceive", + "comparison", + "settlement", + "layer", + "planning", + "far", + "description", + "later", + "slow", + "slide", + "widely", + "wedding", + "inform", + "portion", + "territory", + "immediate", + "opponent", + "abandon", + "link", + "mass", + "lake", + "transform", + "tension", + "display", + "leading", + "bother", + "consist", + "alcohol", + "enable", + "bend", + "saving", + "gain", + "desert", + "shall", + "error", + "release", + "cop", + "arab", + "double", + "walk", + "sand", + "spanish", + "rule", + "hit", + "print", + "preserve", + "passage", + "formal", + "transition", + "existence", + "album", + "participation", + "arrange", + "atmosphere", + "joint", + "reply", + "cycle", + "opposite", + "lock", + "whole", + "deserve", + "consistent", + "resistance", + "discovery", + "tear", + "exposure", + "pose", + "stream", + "sale", + "trust", + "benefit", + "pot", + "grand", + "mine", + "hello", + "coalition", + "tale", + "knife", + "resolve", + "racial", + "phase", + "present", + "joke", + "coat", + "mexican", + "symptom", + "contact", + "manufacturer", + "philosophy", + "potato", + "interview", + "foundation", + "quote", + "online", + "pass", + "negotiation", + "good", + "urge", + "occasion", + "dust", + "breathe", + "elect", + "investigator", + "jacket", + "glad", + "ordinary", + "reduction", + "rarely", + "shift", + "pack", + "suicide", + "numerous", + "touch", + "substance", + "discipline", + "elsewhere", + "iron", + "practical", + "moreover", + "passion", + "volunteer", + "implement", + "essentially", + "gene", + "enforcement", + "vs", + "sauce", + "independence", + "marketing", + "priest", + "amazing", + "intense", + "advance", + "employer", + "shock", + "inspire", + "adjust", + "retire", + "sure", + "visible", + "kiss", + "illness", + "cap", + "habit", + "competitive", + "juice", + "congressional", + "involvement", + "dominate", + "previously", + "whenever", + "transfer", + "analyze", + "another", + "attach", + "for", + "indian", + "disaster", + "parking", + "prospect", + "boss", + "complaint", + "championship", + "coach", + "exercise", + "fundamental", + "severe", + "enhance", + "mystery", + "impose", + "poverty", + "other", + "entry", + "fat", + "spending", + "king", + "evaluate", + "symbol", + "still", + "trade", + "maker", + "mood", + "accomplish", + "emphasis", + "illustrate", + "boot", + "monitor", + "asian", + "entertainment", + "bean", + "evaluation", + "creature", + "commander", + "digital", + "arrangement", + "concentrate", + "total", + "usual", + "anger", + "psychological", + "heavily", + "peak", + "approximately", + "increasing", + "disorder", + "missile", + "equally", + "vary", + "wire", + "round", + "distribution", + "transportation", + "holy", + "ring", + "twin", + "command", + "commission", + "interpretation", + "breakfast", + "stop", + "strongly", + "engineering", + "luck", + "so-called", + "constant", + "race", + "clinic", + "veteran", + "smell", + "tablespoon", + "capable", + "nervous", + "tourist", + "light", + "toss", + "crucial", + "bury", + "pray", + "tomato", + "exception", + "butter", + "deficit", + "bathroom", + "objective", + "block", + "electronic", + "ally", + "journey", + "reputation", + "mixture", + "surely", + "tower", + "smoke", + "confront", + "pure", + "glance", + "dimension", + "toy", + "prisoner", + "fellow", + "smooth", + "nearby", + "peer", + "designer", + "personnel", + "shape", + "educator", + "relative", + "immigration", + "belt", + "teaspoon", + "birthday", + "implication", + "perfectly", + "coast", + "supporter", + "accompany", + "silver", + "teenager", + "recognition", + "retirement", + "flag", + "recovery", + "whisper", + "watch", + "gentleman", + "corn", + "moon", + "inner", + "junior", + "rather", + "throat", + "salary", + "swing", + "observer", + "due", + "straight", + "publication", + "pretty", + "crop", + "dig", + "strike", + "permanent", + "plant", + "phenomenon", + "anxiety", + "unlike", + "wet", + "literally", + "resist", + "convention", + "embrace", + "supply", + "assist", + "exhibition", + "construct", + "viewer", + "pan", + "consultant", + "soon", + "line", + "administrator", + "date", + "occasionally", + "mayor", + "consideration", + "ceo", + "secure", + "pink", + "smoke", + "estimate", + "buck", + "historic", + "poem", + "grandmother", + "bind", + "fifth", + "constantly", + "enterprise", + "favor", + "testing", + "stomach", + "apparent", + "weigh", + "install", + "sensitive", + "suggestion", + "mail", + "recipe", + "reasonable", + "preparation", + "wooden", + "elementary", + "concert", + "aggressive", + "false", + "intention", + "channel", + "extreme", + "tube", + "drawing", + "protein", + "quit", + "absence", + "roll", + "latin", + "rapidly", + "jail", + "comment", + "diversity", + "honest", + "palestinian", + "pace", + "employment", + "speaker", + "impression", + "essay", + "respondent", + "giant", + "cake", + "historian", + "negotiate", + "restore", + "substantial", + "pop", + "particular", + "specialist", + "origin", + "approval", + "mine", + "quietly", + "advise", + "conventional", + "drop", + "count", + "depth", + "wealth", + "disability", + "shell", + "general", + "criticize", + "fast", + "professional", + "effectively", + "biological", + "pack", + "onion", + "deputy", + "flat", + "brand", + "assure", + "mad", + "award", + "criteria", + "dealer", + "via", + "alternative", + "utility", + "precisely", + "arise", + "armed", + "nevertheless", + "highway", + "clinical", + "routine", + "schedule", + "wage", + "normally", + "phrase", + "ingredient", + "stake", + "muslim", + "dream", + "fiber", + "activist", + "islamic", + "snap", + "terrorism", + "refugee", + "incorporate", + "hip", + "ultimate", + "switch", + "corporation", + "valuable", + "assumption", + "gear", + "graduate", + "barrier", + "minor", + "provision", + "killer", + "assign", + "gang", + "developing", + "classic", + "chemical", + "wave", + "label", + "teen", + "index", + "vacation", + "advocate", + "draft", + "extraordinary", + "heaven", + "rough", + "yell", + "pregnant", + "distant", + "drama", + "satellite", + "personally", + "wonder", + "clock", + "chocolate", + "italian", + "canadian", + "ceiling", + "sweep", + "advertising", + "universal", + "spin", + "house", + "button", + "bell", + "rank", + "darkness", + "ahead", + "clothing", + "super", + "yield", + "fence", + "portrait", + "paint", + "survival", + "roughly", + "lawsuit", + "bottom", + "testimony", + "bunch", + "beat", + "wind", + "found", + "burden", + "react", + "chamber", + "furniture", + "cooperation", + "string", + "ceremony", + "communicate", + "taste", + "cheek", + "lost", + "profile", + "mechanism", + "disagree", + "like", + "penalty", + "match", + "ie", + "advance", + "resort", + "destruction", + "bear", + "unlikely", + "tissue", + "constitutional", + "pant", + "stranger", + "infection", + "cabinet", + "broken", + "apple", + "electric", + "proceed", + "track", + "bet", + "literary", + "virus", + "stupid", + "dispute", + "fortune", + "strategic", + "assistant", + "overcome", + "remarkable", + "occupy", + "statistics", + "shopping", + "cousin", + "encounter", + "wipe", + "initially", + "blind", + "white", + "port", + "honor", + "electricity", + "genetic", + "adviser", + "pay", + "spokesman", + "retain", + "latter", + "incentive", + "slave", + "chemical", + "translate", + "accurate", + "whereas", + "terror", + "though", + "expansion", + "elite", + "olympic", + "dirt", + "odd", + "rice", + "bullet", + "tight", + "bible", + "chart", + "solar", + "decline", + "conservative", + "process", + "square", + "stick", + "concentration", + "complicated", + "gently", + "champion", + "scenario", + "telescope", + "reflection", + "revolution", + "strip", + "interpret", + "friendly", + "tournament", + "fiction", + "detect", + "balance", + "likely", + "tremendous", + "lifetime", + "recommendation", + "flow", + "senator", + "market", + "hunting", + "salad", + "guarantee", + "innocent", + "boundary", + "pause", + "remote", + "satisfaction", + "journal", + "bench", + "lover", + "raw", + "awareness", + "surprising", + "withdraw", + "general", + "deck", + "similarly", + "newly", + "pole", + "testify", + "mode", + "dialogue", + "imply", + "naturally", + "mutual", + "founder", + "top", + "advanced", + "pride", + "dismiss", + "aircraft", + "delivery", + "mainly", + "bake", + "freeze", + "platform", + "finance", + "sink", + "attractive", + "respect", + "diverse", + "relevant", + "ideal", + "joy", + "worth", + "regularly", + "working", + "singer", + "evolve", + "shooting", + "partly", + "unknown", + "assistant", + "offense", + "counter", + "dna", + "smell", + "potentially", + "transfer", + "thirty", + "justify", + "protest", + "crash", + "craft", + "treaty", + "terrorist", + "insight", + "possess", + "politically", + "tap", + "lie", + "extensive", + "episode", + "double", + "swim", + "tire", + "fault", + "loose", + "free", + "shortly", + "originally", + "considerable", + "prior", + "intellectual", + "mix", + "assault", + "relax", + "stair", + "adventure", + "external", + "proof", + "confident", + "headquarters", + "sudden", + "dirty", + "violation", + "tongue", + "license", + "hold", + "shelter", + "rub", + "controversy", + "entrance", + "favorite", + "practice", + "properly", + "fade", + "defensive", + "tragedy", + "net", + "characterize", + "funeral", + "profession", + "alter", + "spot", + "constitute", + "establishment", + "squeeze", + "imagination", + "target", + "mask", + "convert", + "comprehensive", + "prominent", + "presentation", + "regardless", + "easy", + "load", + "stable", + "introduction", + "appeal", + "pretend", + "not", + "elderly", + "representation", + "deer", + "split", + "violate", + "partnership", + "pollution", + "emission", + "steady", + "vital", + "neither", + "fate", + "earnings", + "oven", + "distinction", + "segment", + "nowhere", + "poet", + "mere", + "exciting", + "variation", + "comfort", + "radical", + "stress", + "adapt", + "irish", + "honey", + "correspondent", + "pale", + "musician", + "significance", + "load", + "round", + "vessel", + "storage", + "flee", + "mm-hmm", + "leather", + "distribute", + "evolution", + "ill", + "tribe", + "shelf", + "can", + "grandfather", + "lawn", + "buyer", + "dining", + "wisdom", + "council", + "vulnerable", + "instance", + "garlic", + "capability", + "poetry", + "celebrity", + "gradually", + "stability", + "doubt", + "fantasy", + "scared", + "guide", + "plot", + "framework", + "gesture", + "depending", + "ongoing", + "psychology", + "since", + "counselor", + "witness", + "chapter", + "fellow", + "divorce", + "owe", + "pipe", + "athletic", + "slight", + "math", + "shade", + "tail", + "sustain", + "mount", + "obligation", + "angle", + "palm", + "differ", + "custom", + "store", + "economist", + "fifteen", + "soup", + "celebration", + "efficient", + "damage", + "composition", + "satisfy", + "pile", + "briefly", + "carbon", + "closer", + "consume", + "scheme", + "crack", + "frequency", + "tobacco", + "survivor", + "besides", + "in", + "psychologist", + "wealthy", + "galaxy", + "given", + "fund", + "ski", + "limitation", + "ok", + "trace", + "appointment", + "preference", + "meter", + "explosion", + "arrest", + "publicly", + "incredible", + "fighter", + "rapid", + "admission", + "hunter", + "educate", + "painful", + "friendship", + "aide", + "infant", + "calculate", + "fifty", + "rid", + "porch", + "tendency", + "uniform", + "formation", + "scholarship", + "reservation", + "efficiency", + "waste", + "qualify", + "mall", + "derive", + "scandal", + "pc", + "helpful", + "impress", + "heel", + "resemble", + "privacy", + "fabric", + "surprise", + "contest", + "proportion", + "guideline", + "rifle", + "maintenance", + "conviction", + "trick", + "organic", + "tent", + "examination", + "publisher", + "strengthen", + "french", + "proposed", + "myth", + "sophisticated", + "cow", + "etc", + "standing", + "asleep", + "tennis", + "nerve", + "barrel", + "bombing", + "membership", + "ratio", + "menu", + "purchase", + "controversial", + "desperate", + "rate", + "lifestyle", + "humor", + "loud", + "glove", + "suspect", + "sufficient", + "narrative", + "photographer", + "helicopter", + "catholic", + "modest", + "provider", + "delay", + "agricultural", + "explode", + "stroke", + "scope", + "punishment", + "handful", + "badly", + "horizon", + "curious", + "downtown", + "girlfriend", + "prompt", + "request", + "cholesterol", + "absorb", + "adjustment", + "taxpayer", + "eager", + "principal", + "detailed", + "motivation", + "assignment", + "restriction", + "across", + "palestinian", + "laboratory", + "workshop", + "differently", + "auto", + "romantic", + "cotton", + "motor", + "sue", + "flavor", + "overlook", + "float", + "undergo", + "sequence", + "demonstration", + "jet", + "orange", + "consumption", + "assert", + "blade", + "temporary", + "medication", + "print", + "cabin", + "bite", + "relative", + "edition", + "valley", + "yours", + "pitch", + "pine", + "brilliant", + "versus", + "manufacturing", + "risk", + "christian", + "complex", + "absolute", + "chef", + "discrimination", + "offensive", + "german", + "suit", + "boom", + "register", + "appoint", + "heritage", + "god", + "terrorist", + "dominant", + "successfully", + "shit", + "lemon", + "hungry", + "sense", + "dry", + "wander", + "submit", + "economics", + "naked", + "anticipate", + "nut", + "legacy", + "extension", + "shrug", + "fly", + "battery", + "arrival", + "legitimate", + "orientation", + "inflation", + "cope", + "flame", + "cluster", + "host", + "wound", + "dependent", + "shower", + "institutional", + "depict", + "operating", + "flesh", + "garage", + "operator", + "instructor", + "collapse", + "borrow", + "furthermore", + "comedy", + "mortgage", + "sanction", + "civilian", + "twelve", + "weekly", + "habitat", + "grain", + "brush", + "consciousness", + "devote", + "crack", + "measurement", + "province", + "ease", + "seize", + "ethics", + "nomination", + "permission", + "wise", + "actress", + "summit", + "acid", + "odds", + "gifted", + "frustration", + "medium", + "function", + "physically", + "grant", + "distinguish", + "shore", + "repeatedly", + "lung", + "firm", + "running", + "correct", + "distinct", + "artistic", + "discourse", + "basket", + "ah", + "fighting", + "impressive", + "competitor", + "ugly", + "worried", + "portray", + "powder", + "ghost", + "persuade", + "moderate", + "subsequent", + "continued", + "cookie", + "carrier", + "cooking", + "frequent", + "ban", + "swing", + "orange", + "awful", + "admire", + "pet", + "miracle", + "exceed", + "rhythm", + "widespread", + "killing", + "lovely", + "sin", + "charity", + "script", + "tactic", + "identification", + "transformation", + "everyday", + "headline", + "crash", + "venture", + "invasion", + "military", + "nonetheless", + "adequate", + "piano", + "grocery", + "intensity", + "exhibit", + "high", + "blanket", + "margin", + "principal", + "quarterback", + "mouse", + "rope", + "concrete", + "prescription", + "african-american", + "chase", + "document", + "brick", + "recruit", + "patch", + "consensus", + "horror", + "recording", + "changing", + "painter", + "colonial", + "pie", + "sake", + "gaze", + "courage", + "pregnancy", + "swear", + "defeat", + "clue", + "reinforce", + "win", + "confusion", + "slice", + "occupation", + "dear", + "coal", + "sacred", + "criminal", + "formula", + "cognitive", + "collective", + "exact", + "uncle", + "square", + "captain", + "sigh", + "attribute", + "dare", + "okay", + "homeless", + "cool", + "gallery", + "soccer", + "defendant", + "tunnel", + "fitness", + "lap", + "grave", + "toe", + "container", + "virtue", + "abroad", + "architect", + "dramatically", + "makeup", + "inquiry", + "rose", + "surprisingly", + "highlight", + "decrease", + "indication", + "rail", + "anniversary", + "couch", + "alliance", + "hypothesis", + "boyfriend", + "compose", + "peer", + "mess", + "rank", + "legend", + "regulate", + "adolescent", + "shine", + "norm", + "upset", + "remark", + "resign", + "reward", + "gentle", + "related", + "organ", + "lightly", + "concerning", + "invent", + "laughter", + "fit", + "northwest", + "counseling", + "tight", + "receiver", + "ritual", + "insect", + "interrupt", + "salmon", + "favor", + "trading", + "concern", + "magic", + "superior", + "combat", + "stem", + "surgeon", + "acceptable", + "physics", + "rape", + "counsel", + "brush", + "jeans", + "hunt", + "continuous", + "log", + "echo", + "pill", + "excited", + "sculpture", + "compound", + "integrate", + "flour", + "bitter", + "bare", + "slope", + "rent", + "presidency", + "serving", + "subtle", + "greatly", + "bishop", + "drinking", + "delay", + "cry", + "acceptance", + "collapse", + "shop", + "pump", + "candy", + "evil", + "final", + "finance", + "pleased", + "medal", + "beg", + "sponsor", + "ethical", + "secondary", + "slam", + "export", + "experimental", + "melt", + "midnight", + "net", + "curve", + "integrity", + "entitle", + "evident", + "logic", + "essence", + "park", + "exclude", + "harsh", + "closet", + "suburban", + "greet", + "favor", + "interior", + "corridor", + "murder", + "retail", + "pitcher", + "march", + "snake", + "pitch", + "excuse", + "cross", + "weakness", + "pig", + "cold", + "classical", + "estimated", + "t-shirt", + "online", + "unemployment", + "civilization", + "fold", + "patient", + "pop", + "daily", + "reverse", + "missing", + "correlation", + "humanity", + "flash", + "developer", + "reliable", + "excitement", + "beef", + "islam", + "roman", + "stretch", + "architecture", + "occasional", + "administrative", + "elbow", + "deadly", + "muslim", + "hispanic", + "allegation", + "tip", + "confuse", + "airplane", + "monthly", + "duck", + "dose", + "korean", + "plead", + "initiate", + "lecture", + "van", + "sixth", + "bay", + "mainstream", + "suburb", + "sandwich", + "unlike", + "trunk", + "rumor", + "implementation", + "swallow", + "motivate", + "render", + "longtime", + "trap", + "restrict", + "cloth", + "seemingly", + "legislative", + "effectiveness", + "enforce", + "lens", + "reach", + "inspector", + "lend", + "plain", + "fraud", + "companion", + "contend", + "nail", + "array", + "strict", + "assemble", + "frankly", + "rat", + "burst", + "hallway", + "cave", + "inevitable", + "southwest", + "monster", + "speed", + "protest", + "unexpected", + "obstacle", + "facilitate", + "encounter", + "rip", + "herb", + "overwhelming", + "integration", + "crystal", + "recession", + "wish", + "top", + "written", + "motive", + "label", + "flood", + "pen", + "ownership", + "nightmare", + "notice", + "inspection", + "supervisor", + "consult", + "arena", + "laugh", + "diagnosis", + "possession", + "forgive", + "warm", + "consistently", + "basement", + "project", + "drift", + "drain", + "last", + "prosecution", + "maximum", + "announcement", + "warrior", + "prediction", + "bacteria", + "questionnaire", + "mud", + "infrastructure", + "hurry", + "privilege", + "temple", + "medium", + "outdoor", + "suck", + "and/or", + "broadcast", + "re", + "leap", + "random", + "past", + "wrist", + "curtain", + "monitor", + "pond", + "domain", + "guilt", + "cattle", + "subject", + "walking", + "playoff", + "minimum", + "fiscal", + "skirt", + "dump", + "hence", + "database", + "uncomfortable", + "aim", + "execute", + "limb", + "ideology", + "average", + "welcome", + "tune", + "continuing", + "harm", + "railroad", + "endure", + "radiation", + "horn", + "chronic", + "peaceful", + "innovation", + "strain", + "guitar", + "replacement", + "behave", + "administer", + "simultaneously", + "dancer", + "amendment", + "guard", + "pad", + "transmission", + "await", + "retired", + "trigger", + "spill", + "grateful", + "grace", + "virtual", + "response", + "colony", + "adoption", + "slide", + "indigenous", + "closed", + "convict", + "civilian", + "towel", + "modify", + "particle", + "award", + "glance", + "prize", + "landing", + "conduct", + "blue", + "boost", + "bat", + "alarm", + "festival", + "grip", + "weird", + "undermine", + "freshman", + "sweat", + "outer", + "european", + "drunk", + "survey", + "research", + "separation", + "traditionally", + "stuff", + "govern", + "southeast", + "intelligent", + "wherever", + "ballot", + "rhetoric", + "convinced", + "driving", + "vitamin", + "enthusiasm", + "accommodate", + "praise", + "injure", + "wilderness", + "nearby", + "endless", + "mandate", + "pause", + "excuse", + "respectively", + "uncertainty", + "chaos", + "short", + "mechanical", + "canvas", + "forty", + "matter", + "lobby", + "profound", + "format", + "trait", + "currency", + "turkey", + "reserve", + "beam", + "abuse", + "astronomer", + "corruption", + "contractor", + "apologize", + "doctrine", + "genuine", + "thumb", + "unity", + "compromise", + "horrible", + "behavioral", + "exclusive", + "scatter", + "commonly", + "convey", + "rush", + "twist", + "complexity", + "fork", + "disk", + "relieve", + "suspicion", + "lock", + "finish", + "health-care", + "health-care", + "health-care", + "health-care", + "residence", + "shame", + "meaningful", + "sidewalk", + "olympics", + "technological", + "signature", + "pleasant", + "wow", + "suspend", + "rebel", + "frozen", + "desire", + "spouse", + "fluid", + "pension", + "resume", + "theoretical", + "sodium", + "blow", + "promotion", + "delicate", + "forehead", + "rebuild", + "bounce", + "electrical", + "hook", + "detective", + "traveler", + "click", + "compensation", + "signal", + "exit", + "attraction", + "dedicate", + "altogether", + "pickup", + "carve", + "needle", + "belly", + "ship", + "scare", + "portfolio", + "shuttle", + "invisible", + "timing", + "engagement", + "ankle", + "transaction", + "rescue", + "counterpart", + "historically", + "firmly", + "mild", + "rider", + "doll", + "noon", + "exhibit", + "amid", + "identical", + "precise", + "anxious", + "structural", + "residential", + "loud", + "diagnose", + "carbohydrate", + "liberty", + "poster", + "theology", + "nonprofit", + "crawl", + "oxygen", + "handsome", + "magic", + "sum", + "provided", + "businessman", + "promising", + "conscious", + "determination", + "donor", + "hers", + "pastor", + "jazz", + "opera", + "japanese", + "bite", + "frame", + "evil", + "acquisition", + "pit", + "hug", + "wildlife", + "punish", + "giant", + "primary", + "equity", + "wrong", + "doorway", + "departure", + "elevator", + "teenage", + "guidance", + "happiness", + "statue", + "pursuit", + "repair", + "decent", + "gym", + "oral", + "clerk", + "israeli", + "envelope", + "reporting", + "destination", + "fist", + "endorse", + "exploration", + "generous", + "bath", + "rescue", + "thereby", + "overall", + "indicator", + "sunlight", + "feedback", + "spectrum", + "purple", + "laser", + "bold", + "reluctant", + "starting", + "expertise", + "practically", + "program", + "picture", + "tune", + "eating", + "age", + "volunteer", + "hint", + "sharply", + "parade", + "advocate", + "realm", + "ban", + "strip", + "cancel", + "blend", + "therapist", + "slice", + "peel", + "pizza", + "recipient", + "hesitate", + "flip", + "accounting", + "debate", + "bias", + "huh", + "metaphor", + "candle", + "handle", + "worry", + "judicial", + "entity", + "suffering", + "full-time", + "feel", + "lamp", + "garbage", + "servant", + "addition", + "regulatory", + "diplomatic", + "elegant", + "inside", + "reception", + "vanish", + "automatically", + "chin", + "trail", + "necessity", + "confess", + "racism", + "starter", + "interior", + "banking", + "casual", + "gravity", + "enroll", + "diminish", + "prevention", + "arab", + "value", + "minimize", + "chop", + "performer", + "intent", + "isolate", + "pump", + "inventory", + "productive", + "assembly", + "civic", + "silk", + "magnitude", + "steep", + "hostage", + "collector", + "popularity", + "kiss", + "alien", + "dynamic", + "scary", + "equation", + "angel", + "switch", + "offering", + "rage", + "photography", + "repair", + "toilet", + "disappointed", + "precious", + "prohibit", + "representative", + "content", + "realistic", + "russian", + "hidden", + "command", + "tender", + "wake", + "gathering", + "outstanding", + "stumble", + "lonely", + "automobile", + "artificial", + "dawn", + "abstract", + "descend", + "silly", + "hook", + "tide", + "shared", + "hopefully", + "readily", + "cooperate", + "revolutionary", + "romance", + "hardware", + "pillow", + "kit", + "cook", + "spread", + "continent", + "seal", + "circuit", + "sink", + "ruling", + "shortage", + "annually", + "lately", + "trap", + "scan", + "fool", + "deadline", + "rear", + "processing", + "ranch", + "coastal", + "undertake", + "softly", + "reserve", + "burning", + "verbal", + "tribal", + "ridiculous", + "automatic", + "diamond", + "credibility", + "import", + "sexually", + "spring", + "way", + "divine", + "sentiment", + "cart", + "oversee", + "stem", + "elder", + "pro", + "inspiration", + "dutch", + "quantity", + "trailer", + "mate", + "o'clock", + "greek", + "genius", + "monument", + "bid", + "quest", + "sacrifice", + "invitation", + "accuracy", + "juror", + "officially", + "broker", + "treasure", + "loyalty", + "credit", + "shock", + "talented", + "gasoline", + "stiff", + "output", + "nominee", + "extended", + "please", + "diabetes", + "slap", + "toxic", + "alleged", + "jaw", + "grief", + "mysterious", + "rocket", + "donate", + "inmate", + "tackle", + "dynamics", + "bow", + "ours", + "senior", + "dignity", + "carpet", + "parental", + "bubble", + "heat", + "buddy", + "barn", + "sword", + "flash", + "seventh", + "glory", + "tightly", + "protective", + "tuck", + "drum", + "faint", + "post", + "queen", + "dilemma", + "input", + "specialize", + "northeast", + "shallow", + "liability", + "sail", + "merchant", + "stadium", + "improved", + "bloody", + "defeat", + "associated", + "withdrawal", + "refrigerator", + "nest", + "near", + "thoroughly", + "lane", + "ancestor", + "condemn", + "steam", + "accent", + "escape", + "optimistic", + "unite", + "cage", + "equip", + "shrimp", + "homeland", + "exchange", + "rack", + "costume", + "wolf", + "courtroom", + "statute", + "cartoon", + "besides", + "productivity", + "grin", + "symbolic", + "seal", + "bug", + "bless", + "aunt", + "agriculture", + "rock", + "hostile", + "root", + "hay", + "combined", + "instantly", + "bankruptcy", + "vaccine", + "bonus", + "collaboration", + "mixed", + "opposed", + "orbit", + "grasp", + "patience", + "spite", + "tropical", + "voting", + "patrol", + "willingness", + "position", + "revelation", + "rent", + "calm", + "jewelry", + "cuban", + "haul", + "concede", + "trace", + "wagon", + "afterward", + "spectacular", + "ruin", + "sheer", + "prior", + "immune", + "reliability", + "ass", + "alongside", + "bush", + "exotic", + "fascinating", + "secure", + "clip", + "thigh", + "bull", + "drawer", + "regard", + "sheep", + "discourage", + "coordinator", + "ideological", + "runner", + "secular", + "intimate", + "empire", + "cab", + "divorce", + "exam", + "documentary", + "neutral", + "biology", + "flexible", + "progressive", + "web", + "conspiracy", + "catch", + "casualty", + "republic", + "execution", + "terrific", + "whale", + "functional", + "star", + "draft", + "instinct", + "teammate", + "aluminum", + "whoever", + "ministry", + "verdict", + "instruct", + "skull", + "self-esteem", + "ease", + "cooperative", + "manipulate", + "bee", + "practitioner", + "loop", + "edit", + "whip", + "puzzle", + "mushroom", + "subsidy", + "boil", + "tragic", + "mathematics", + "mechanic", + "jar", + "respect", + "earthquake", + "pork", + "creativity", + "safely", + "underlying", + "dessert", + "sympathy", + "fisherman", + "incredibly", + "isolation", + "sock", + "near", + "jump", + "eleven", + "sexy", + "entrepreneur", + "syndrome", + "bureau", + "seat", + "workplace", + "ambition", + "touchdown", + "utilize", + "breeze", + "costly", + "ambitious", + "christianity", + "presumably", + "influential", + "translation", + "uncertain", + "dissolve", + "object", + "statistical", + "gut", + "metropolitan", + "rolling", + "aesthetic", + "spell", + "insert", + "booth", + "helmet", + "waist", + "expected", + "lion", + "accomplishment", + "royal", + "panic", + "cast", + "crush", + "actively", + "cliff", + "minimal", + "cord", + "fortunately", + "cocaine", + "illusion", + "anonymous", + "tolerate", + "appreciation", + "commissioner", + "harm", + "flexibility", + "instructional", + "scramble", + "casino", + "tumor", + "decorate", + "sort", + "charge", + "pulse", + "equivalent", + "fixed", + "experienced", + "donation", + "diary", + "sibling", + "irony", + "spoon", + "midst", + "alley", + "upset", + "interact", + "soap", + "cute", + "rival", + "short-term", + "punch", + "pin", + "hockey", + "passing", + "persist", + "supplier", + "known", + "momentum", + "purse", + "shed", + "liquid", + "icon", + "elephant", + "consequently", + "legislature", + "associate", + "franchise", + "correctly", + "mentally", + "foster", + "bicycle", + "encouraging", + "cheat", + "access", + "heal", + "fever", + "filter", + "rabbit", + "coin", + "exploit", + "accessible", + "organism", + "sensation", + "partially", + "stay", + "upstairs", + "dried", + "minimum", + "pro", + "conservation", + "shove", + "backyard", + "charter", + "stove", + "consent", + "comprise", + "reminder", + "alike", + "placement", + "dough", + "grandchild", + "dam", + "reportedly", + "well-known", + "surrounding", + "ecological", + "outfit", + "unprecedented", + "columnist", + "workout", + "preliminary", + "patent", + "shy", + "quote", + "trash", + "disabled", + "gross", + "damn", + "hormone", + "texture", + "counter", + "pencil", + "associate", + "frontier", + "spray", + "bet", + "disclose", + "custody", + "banker", + "beast", + "interfere", + "oak", + "case", + "eighth", + "notebook", + "outline", + "gaze", + "attendance", + "speculation", + "uncover", + "behalf", + "innovative", + "shark", + "reward", + "mill", + "installation", + "stimulate", + "tag", + "vertical", + "swimming", + "fleet", + "catalog", + "outsider", + "sacrifice", + "desperately", + "stance", + "compel", + "sensitivity", + "someday", + "instant", + "debut", + "proclaim", + "worldwide", + "hike", + "required", + "confrontation", + "colorful", + "ideal", + "constitution", + "trainer", + "thanksgiving", + "scent", + "stack", + "eyebrow", + "sack", + "cease", + "inherit", + "tray", + "pioneer", + "organizational", + "textbook", + "uh", + "nasty", + "shrink", + "model", + "emerging", + "dot", + "wheat", + "fierce", + "envision", + "rational", + "kingdom", + "aisle", + "weaken", + "protocol", + "exclusively", + "vocal", + "marketplace", + "openly", + "unfair", + "terrain", + "deploy", + "risky", + "pasta", + "genre", + "distract", + "merit", + "planner", + "depressed", + "chunk", + "closest", + "discount", + "no", + "ladder", + "jungle", + "migration", + "breathing", + "invade", + "hurricane", + "retailer", + "classify", + "wound", + "coup", + "aid", + "ambassador", + "density", + "supportive", + "curiosity", + "skip", + "aggression", + "stimulus", + "journalism", + "robot", + "flood", + "dip", + "likewise", + "informal", + "persian", + "feather", + "sphere", + "tighten", + "boast", + "pat", + "perceived", + "sole", + "publicity", + "major", + "unfold", + "joke", + "well-being", + "validity", + "ecosystem", + "strictly", + "partial", + "collar", + "weed", + "compliance", + "streak", + "supposedly", + "added", + "builder", + "glimpse", + "premise", + "specialty", + "deem", + "artifact", + "sneak", + "monkey", + "mentor", + "two-thirds", + "listener", + "lightning", + "legally", + "sleeve", + "disappointment", + "disturb", + "rib", + "excessive", + "high-tech", + "debris", + "pile", + "rod", + "logical", + "liberal", + "ash", + "socially", + "parish", + "slavery", + "blank", + "commodity", + "cure", + "mineral", + "hunger", + "dying", + "developmental", + "faster", + "spare", + "halfway", + "cure", + "equality", + "cemetery", + "harassment", + "deliberately", + "fame", + "regret", + "striking", + "likelihood", + "carrot", + "atop", + "toll", + "rim", + "embarrassed", + "cling", + "isolated", + "blink", + "suspicious", + "wheelchair", + "squad", + "eligible", + "processor", + "plunge", + "this", + "sponsor", + "grin", + "color", + "demographic", + "rain", + "chill", + "refuge", + "steer", + "legislator", + "rally", + "programming", + "cheer", + "outlet", + "intact", + "vendor", + "thrive", + "peanut", + "chew", + "elaborate", + "intellectual", + "conception", + "auction", + "steak", + "comply", + "triumph", + "shareholder", + "comparable", + "transport", + "conscience", + "calculation", + "considerably", + "interval", + "scratch", + "awake", + "jurisdiction", + "inevitably", + "feminist", + "constraint", + "emotionally", + "expedition", + "allegedly", + "compromise", + "strain", + "similarity", + "butt", + "lid", + "dumb", + "bulk", + "sprinkle", + "mortality", + "philosophical", + "conversion", + "patron", + "municipal", + "any", + "liver", + "harmony", + "solely", + "tolerance", + "instant", + "goat", + "arm", + "blessing", + "banana", + "running", + "palace", + "formerly", + "peasant", + "neat", + "grandparent", + "lawmaker", + "supermarket", + "cruise", + "mobile", + "plain", + "part", + "calendar", + "widow", + "deposit", + "beard", + "brake", + "downtown", + "screening", + "impulse", + "forbid", + "fur", + "brutal", + "predator", + "poke", + "opt", + "voluntary", + "trouble", + "valid", + "forum", + "dancing", + "happily", + "soar", + "removal", + "autonomy", + "enact", + "round", + "thread", + "light", + "landmark", + "unhappy", + "offender", + "coming", + "privately", + "fraction", + "distinctive", + "tourism", + "threshold", + "calm", + "routinely", + "suite", + "remark", + "regulator", + "straw", + "theological", + "apart", + "exhaust", + "globe", + "fragile", + "objection", + "chemistry", + "old-fashioned", + "crowded", + "circle", + "blast", + "prevail", + "overnight", + "denial", + "rental", + "fantastic", + "fragment", + "level", + "screw", + "warmth", + "undergraduate", + "liquid", + "headache", + "policeman", + "yield", + "projection", + "battle", + "suitable", + "mention", + "graduation", + "drill", + "cruel", + "mansion", + "regard", + "grape", + "authorize", + "cottage", + "driveway", + "charm", + "sexuality", + "loyal", + "clay", + "pound", + "balloon", + "invention", + "ego", + "fare", + "homework", + "disc", + "sofa", + "guarantee", + "availability", + "radar", + "frown", + "regain", + "leave", + "permit", + "sweater", + "rehabilitation", + "rubber", + "retreat", + "molecule", + "freely", + "favorable", + "steadily", + "veteran", + "integrated", + "ha", + "youngster", + "broadcast", + "premium", + "accountability", + "overwhelm", + "one-third", + "contemplate", + "update", + "spark", + "ironically", + "fatigue", + "beyond", + "speculate", + "marker", + "low", + "preach", + "bucket", + "bomb", + "blond", + "confession", + "provoke", + "marble", + "substantially", + "twist", + "defender", + "fish", + "explicit", + "transport", + "disturbing", + "surveillance", + "magnetic", + "technician", + "mutter", + "devastating", + "depart", + "arrow", + "trauma", + "neighboring", + "soak", + "ribbon", + "meantime", + "transmit", + "screen", + "harvest", + "consecutive", + "republican", + "coordinate", + "worldwide", + "within", + "spy", + "slot", + "riot", + "nutrient", + "citizenship", + "severely", + "sovereignty", + "ridge", + "brave", + "lighting", + "specify", + "contributor", + "frustrate", + "crowd", + "articulate", + "importantly", + "transit", + "dense", + "seminar", + "electronics", + "sunny", + "shorts", + "swell", + "accusation", + "soften", + "photograph", + "straighten", + "terribly", + "cue", + "sudden", + "bride", + "biography", + "hazard", + "compelling", + "seldom", + "tile", + "economically", + "honestly", + "troubled", + "bow", + "twentieth", + "balanced", + "foreigner", + "launch", + "convenience", + "delight", + "weave", + "timber", + "till", + "accurately", + "plea", + "bulb", + "copy", + "flying", + "sustainable", + "devil", + "bolt", + "cargo", + "spine", + "seller", + "skilled", + "managing", + "public", + "marine", + "dock", + "organized", + "fog", + "diplomat", + "boring", + "sometime", + "summary", + "missionary", + "epidemic", + "fatal", + "trim", + "warehouse", + "accelerate", + "butterfly", + "bronze", + "drown", + "inherent", + "praise", + "nationwide", + "spit", + "harvest", + "kneel", + "vacuum", + "selected", + "dictate", + "stereotype", + "sensor", + "laundry", + "manual", + "pistol", + "naval", + "plaintiff", + "immigrant", + "kid", + "middle-class", + "apology", + "till", +}; + +} diff --git a/libdevcrypto/WordList.h b/libdevcrypto/WordList.h new file mode 100644 index 0000000000..39d5a1429a --- /dev/null +++ b/libdevcrypto/WordList.h @@ -0,0 +1,31 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file WordList.h + * @author Gav Wood + * @date 2015 + */ + +#pragma once + +#include "Common.h" + +namespace dev +{ + +extern std::vector const WordList; + +} diff --git a/libethcore/ABI.cpp b/libethcore/ABI.cpp new file mode 100644 index 0000000000..fb44f51c5a --- /dev/null +++ b/libethcore/ABI.cpp @@ -0,0 +1,27 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file ABI.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "ABI.h" + +using namespace std; +using namespace dev; +using namespace dev::eth; + diff --git a/libethcore/ABI.h b/libethcore/ABI.h new file mode 100644 index 0000000000..6c6f91e33d --- /dev/null +++ b/libethcore/ABI.h @@ -0,0 +1,263 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file ABI.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include +#include +#include + + + +namespace dev +{ +namespace eth +{ + +class ContractABI { +public: + /* + template + void serialise(FixedHash const& _t) { + static_assert(N <= 32, "Cannot serialise hash > 32 bytes."); + static_assert(N > 0, "Cannot serialise zero-length hash."); + + fixedItems.push_back(bytes(32 - N, 0) + _t.asBytes()); + } + */ + + void serialise(u256 const& _t) { + fixedItems.push_back(h256(_t).asBytes()); + } + + void serialise(byte const& _t){ + fixedItems.push_back(bytes(31, 0) + bytes(_t)); + } + + void serialise(u160 const& _t) { + fixedItems.push_back(bytes(12, 0) + h160(_t).asBytes()); + } + + void serialise(string32 const& _t) { + bytes ret; + bytesConstRef((byte const*) _t.data(), 32).populate(bytesRef(&ret)); + + fixedItems.push_back(ret); + } + + void serialise(std::string const& _t) { + bytes ret = h256(u256(_t.size())).asBytes(); + ret.resize(ret.size() + (_t.size() + 31) / 32 * 32); + bytesConstRef(&_t).populate(bytesRef(&ret).cropped(32)); + + DynamicItem item; + item.data = ret; + item.offset = fixedItems.size(); + + serialise(u256(0)); + + dynamicItems.push_back(item); + } + + inline void abiInAux() { + return; + } + + template void abiInAux(T const& _t, U const& ... _u) { + serialise(_t); + abiInAux(_u ...); + } + + template bytes abiIn(std::string _id, T const& ... _t) { + fixedItems.clear(); + dynamicItems.clear(); + + abiInAux(_t ...); + + size_t offset = fixedItems.size() * 32; + + for(auto it = dynamicItems.begin(); it != dynamicItems.end(); ++it) { + fixedItems[it->offset] = h256(offset).asBytes(); + + offset += it->data.size(); + } + + bytes fixed; + for(auto it = fixedItems.begin(); it != fixedItems.end(); ++it) fixed += *it; + + bytes dynamic; + for(auto it = dynamicItems.begin(); it != dynamicItems.end(); ++it) dynamic += it->data; + + return sha3(_id).ref().cropped(0, 4).toBytes() + fixed + dynamic; + } + + template + void deserialise(FixedHash& out) { + static_assert(N <= 32, "Parameter sizes must be at most 32 bytes."); + data.cropped(getOffset() + 32 - N, N).populate(out.ref()); + } + + void deserialise(u256& out) { + + out = fromBigEndian(data.cropped(getOffset(), 32)); + } + + void deserialise(u160& out) { + out = fromBigEndian(data.cropped(getOffset() + 12, 20)); + } + + void deserialise(byte& out) { + out = fromBigEndian(data.cropped(getOffset() + 31, 1)); + } + + void deserialise(string32& out) { + data.cropped(0, 32).populate(bytesRef((byte*) out.data(), 32)); + } + + void deserialise(bool& out) { + u256 ret = fromBigEndian(data.cropped(0, 32)); + out = ret > 0 ? true : false; + } + + void deserialise(std::string& out) { + u256 offset = fromBigEndian(data.cropped(getOffset(), 32)); + u256 len = fromBigEndian(data.cropped(static_cast(offset), 32)); + + auto stringData = data.cropped(static_cast(offset) + 32, static_cast(len)); + + out.assign((const char*)stringData.data(), stringData.size()); + + + } + + inline void abiOutAux() { + return; + } + + template void abiOutAux(T& _t, U& ... _u) { + deserialise(_t); + ++decodeOffset; + + abiOutAux(_u ...); + } + + template void abiOut(bytesConstRef _data, T& ... _t) { + data = _data; + decodeOffset = 0; + + abiOutAux(_t ...); + } + +private: + struct DynamicItem { + bytes data; + size_t offset; + }; + + std::vector fixedItems; + std::vector dynamicItems; + + size_t getOffset() { + return decodeOffset * 32; + } + + bytesConstRef data; + size_t decodeOffset = 0; +}; + + +inline string32 toString32(std::string const& _s) +{ + string32 ret; + for (unsigned i = 0; i < 32; ++i) + ret[i] = i < _s.size() ? _s[i] : 0; + return ret; +} + +template struct ABISerialiser {}; +template struct ABISerialiser> { static bytes serialise(FixedHash const& _t) { static_assert(N <= 32, "Cannot serialise hash > 32 bytes."); static_assert(N > 0, "Cannot serialise zero-length hash."); return bytes(32 - N, 0) + _t.asBytes(); } }; +template <> struct ABISerialiser { static bytes serialise(u256 const& _t) { return h256(_t).asBytes(); } }; +template <> struct ABISerialiser { static bytes serialise(u160 const& _t) { return bytes(12, 0) + h160(_t).asBytes(); } }; +template <> struct ABISerialiser { static bytes serialise(string32 const& _t) { bytes ret; bytesConstRef((byte const*)_t.data(), 32).populate(bytesRef(&ret)); return ret; } }; +template <> struct ABISerialiser +{ + static bytes serialise(std::string const& _t) + { + bytes ret = h256(u256(32)).asBytes() + h256(u256(_t.size())).asBytes(); + ret.resize(ret.size() + (_t.size() + 31) / 32 * 32); + bytesConstRef(&_t).populate(bytesRef(&ret).cropped(64)); + return ret; + } +}; +inline bytes abiInAux() { return {}; } +template bytes abiInAux(T const& _t, U const& ... _u) +{ + return ABISerialiser::serialise(_t) + abiInAux(_u ...); +} + +template bytes abiIn(std::string _id, T const& ... _t) +{ + return sha3(_id).ref().cropped(0, 4).toBytes() + abiInAux(_t ...); +} + +template struct ABIDeserialiser {}; +template struct ABIDeserialiser> { static FixedHash deserialise(bytesConstRef& io_t) { static_assert(N <= 32, "Parameter sizes must be at most 32 bytes."); FixedHash ret; io_t.cropped(32 - N, N).populate(ret.ref()); io_t = io_t.cropped(32); return ret; } }; +template <> struct ABIDeserialiser { static u256 deserialise(bytesConstRef& io_t) { u256 ret = fromBigEndian(io_t.cropped(0, 32)); io_t = io_t.cropped(32); return ret; } }; +template <> struct ABIDeserialiser { static u160 deserialise(bytesConstRef& io_t) { u160 ret = fromBigEndian(io_t.cropped(12, 20)); io_t = io_t.cropped(32); return ret; } }; +template <> struct ABIDeserialiser { static string32 deserialise(bytesConstRef& io_t) { string32 ret; io_t.cropped(0, 32).populate(bytesRef((byte*)ret.data(), 32)); io_t = io_t.cropped(32); return ret; } }; + +template <> struct ABIDeserialiser { + static bool deserialise(bytesConstRef& io_t) + { + u256 ret = fromBigEndian(io_t.cropped(0, 32)); + io_t = io_t.cropped(32); + return ret>0?true:false; + } +}; + +template <> struct ABIDeserialiser +{ + static std::string deserialise(bytesConstRef& io_t) + { + unsigned o = (uint16_t)u256(h256(io_t.cropped(0, 32))); + unsigned s = (uint16_t)u256(h256(io_t.cropped(o, 32))); + std::string ret; + ret.resize(s); + io_t.cropped(o + 32, s).populate(bytesRef((byte*)ret.data(), s)); + io_t = io_t.cropped(32); + return ret; + } +}; + +template T abiOut(bytes const& _data) +{ + bytesConstRef o(&_data); + return ABIDeserialiser::deserialise(o); +} + +template T abiOut(bytesConstRef& _data) +{ + return ABIDeserialiser::deserialise(_data); +} + +} +} diff --git a/libethcore/BasicAuthority.cpp b/libethcore/BasicAuthority.cpp new file mode 100644 index 0000000000..067845754a --- /dev/null +++ b/libethcore/BasicAuthority.cpp @@ -0,0 +1,96 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file BasicAuthority.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "BasicAuthority.h" +#include + +#include +#include "Exceptions.h" +#include "BlockHeader.h" +using namespace std; +using namespace dev; +using namespace eth; + + +void BasicAuthority::init() +{ + ETH_REGISTER_SEAL_ENGINE(BasicAuthority); +} + +StringHashMap BasicAuthority::jsInfo(BlockHeader const& _bi) const +{ + return { { "sig", toJS(sig(_bi)) } }; +} + +bool BasicAuthority::shouldSeal(Interface* _i) +{ +// LOG(DEBUG) << "Comparing: " << _i->pendingInfo().timestamp() << " to " << utcTime(); + return _i->pendingInfo().timestamp() + 5 <= utcTime() || (_i->pendingInfo().timestamp() <= utcTime() && !_i->pending().empty()); +} + +void BasicAuthority::generateSeal(BlockHeader const& _bi, bytes const& _block_data) +{ + BlockHeader bi = _bi; + h256 h = bi.hash(WithoutSeal); + Signature s = sign(m_secret, h); + setSig(bi, s); + SealEngineBase::generateSeal(bi, _block_data); +} + +bool BasicAuthority::onOptionChanging(std::string const& _name, bytes const& _value) +{ + RLP rlp(_value); + if (_name == "authorities") + m_authorities = rlp.toUnorderedSet
(); + else if (_name == "authority") + m_secret = Secret(rlp.toHash()); + else + return false; + return true; +} + +void BasicAuthority::populateFromParent(BlockHeader& _bi, BlockHeader const& _parent) const +{ + SealEngineFace::populateFromParent(_bi, _parent); + // pseudo-random difficulty to facilitate fork reduction. + _bi.setDifficulty(fromBigEndian(sha3(sha3(m_secret) ^ _bi.parentHash()).ref().cropped(0, 4))); +} + +void BasicAuthority::verify(Strictness _s, BlockHeader const& _bi, BlockHeader const& _parent, bytesConstRef _block) const +{ + SealEngineFace::verify(_s, _bi, _parent, _block); + // check it hashes according to proof of work or that it's the genesis block. + Signature s = sig(_bi); + h256 h = _bi.hash(WithoutSeal); + Address a = toAddress(recover(s, h)); + if (_s == CheckEverything && _bi.parentHash() && !m_authorities.count(a)) + { + InvalidBlockNonce ex; + ex << errinfo_hash256(_bi.hash(WithoutSeal)); + BOOST_THROW_EXCEPTION(ex); + } + else if (_s == QuickNonce && _bi.parentHash() && !SignatureStruct(sig(_bi)).isValid()) + { + InvalidBlockNonce ex; + ex << errinfo_hash256(_bi.hash(WithoutSeal)); + BOOST_THROW_EXCEPTION(ex); + } +} diff --git a/libethcore/BasicAuthority.h b/libethcore/BasicAuthority.h new file mode 100644 index 0000000000..35b86e6d82 --- /dev/null +++ b/libethcore/BasicAuthority.h @@ -0,0 +1,60 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file BasicAuthority.h + * @author Gav Wood + * @date 2014 + * + * Determines the PoW algorithm. + */ + +#pragma once + +#include "SealEngine.h" + +namespace dev +{ +namespace eth +{ + +class BasicAuthority: public SealEngineBase +{ +public: + std::string name() const override { return "BasicAuthority"; } + unsigned revision() const override { return 0; } + unsigned sealFields() const override { return 1; } + bytes sealRLP() const override { return rlp(Signature()); } + + void populateFromParent(BlockHeader&, BlockHeader const&) const override; + StringHashMap jsInfo(BlockHeader const& _bi) const override; + void verify(Strictness _s, BlockHeader const& _bi, BlockHeader const& _parent, bytesConstRef _block) const override; + bool shouldSeal(Interface*) override; + void generateSeal(BlockHeader const& _bi, bytes const& _block_data = bytes()) override; + + static Signature sig(BlockHeader const& _bi) { return _bi.seal(); } + static BlockHeader& setSig(BlockHeader& _bi, Signature const& _sig) { _bi.setSeal(_sig); return _bi; } + void setSecret(Secret const& _s) { m_secret = _s; } + static void init(); + +private: + bool onOptionChanging(std::string const& _name, bytes const& _value) override; + + Secret m_secret; + AddressHash m_authorities; +}; + +} +} diff --git a/libethcore/BlockHeader.cpp b/libethcore/BlockHeader.cpp new file mode 100644 index 0000000000..7ce767aad6 --- /dev/null +++ b/libethcore/BlockHeader.cpp @@ -0,0 +1,225 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file BlockHeader.cpp + * @author Gav Wood + * @date 2014 + */ + +#include + +#include +#include +#include +#include +#include "Exceptions.h" +#include "BlockHeader.h" +using namespace std; +using namespace dev; +using namespace dev::eth; + +BlockHeader::BlockHeader() +{ +} + +BlockHeader::BlockHeader(bytesConstRef _block, BlockDataType _bdt, h256 const& _hashWith) +{ + RLP header = _bdt == BlockData ? extractHeader(_block) : RLP(_block); + m_hash = _hashWith ? _hashWith : sha3(header.data()); + populate(header); +} + +u256 BlockHeader::maxBlockHeadGas = 200000000; //默认两个亿 + +void BlockHeader::clear() +{ + m_parentHash = h256(); + m_sha3Uncles = EmptyListSHA3; + m_author = Address(); + m_stateRoot = EmptyTrie; + m_transactionsRoot = EmptyTrie; + m_receiptsRoot = EmptyTrie; + m_logBloom = LogBloom(); + m_difficulty = 0; + m_number = Invalid256; + m_gasLimit = 0; + m_gasUsed = 0; + m_timestamp = Invalid256; + m_extraData.clear(); + m_seal.clear(); + m_gen_idx = Invalid256; + m_node_list.clear(); + noteDirty(); +} + +h256 BlockHeader::hash(IncludeSeal _i) const +{ + h256 dummy; + h256& memo = _i == WithSeal ? m_hash : _i == WithoutSeal ? m_hashWithout : dummy; + if (!memo) + { + RLPStream s; + streamRLP(s, _i); + memo = sha3(s.out()); + } + return memo; +} + +void BlockHeader::streamRLPFields(RLPStream& _s) const +{ + _s << m_parentHash << m_sha3Uncles << m_author << m_stateRoot << m_transactionsRoot << m_receiptsRoot << m_logBloom + << m_difficulty << m_number << m_gasLimit << m_gasUsed << m_timestamp << m_extraData << m_gen_idx; + // 公钥列表 + _s.appendVector(m_node_list); +} + +void BlockHeader::streamRLP(RLPStream& _s, IncludeSeal _i) const +{ + if (_i != OnlySeal) + { + _s.appendList(BlockHeader::BasicFields + (_i == WithoutSeal ? 0 : m_seal.size())); + BlockHeader::streamRLPFields(_s); + } + if (_i != WithoutSeal) + for (unsigned i = 0; i < m_seal.size(); ++i) + _s.appendRaw(m_seal[i]); +} + +h256 BlockHeader::headerHashFromBlock(bytesConstRef _block) +{ + return sha3(RLP(_block)[0].data()); +} + +RLP BlockHeader::extractHeader(bytesConstRef _block) +{ + RLP root(_block); + if (!root.isList()) + BOOST_THROW_EXCEPTION(InvalidBlockFormat() << errinfo_comment("Block must be a list") << BadFieldError(0, _block.toString())); + RLP header = root[0]; + if (!header.isList()) + BOOST_THROW_EXCEPTION(InvalidBlockFormat() << errinfo_comment("Block header must be a list") << BadFieldError(0, header.data().toString())); + if (!root[1].isList()) + BOOST_THROW_EXCEPTION(InvalidBlockFormat() << errinfo_comment("Block transactions must be a list") << BadFieldError(1, root[1].data().toString())); + if (!root[2].isList()) + BOOST_THROW_EXCEPTION(InvalidBlockFormat() << errinfo_comment("Block uncles must be a list") << BadFieldError(2, root[2].data().toString())); + return header; +} + +void BlockHeader::populate(RLP const& _header) +{ + int field = 0; + try + { + m_parentHash = _header[field = 0].toHash(RLP::VeryStrict); + m_sha3Uncles = _header[field = 1].toHash(RLP::VeryStrict); + m_author = _header[field = 2].toHash
(RLP::VeryStrict); + m_stateRoot = _header[field = 3].toHash(RLP::VeryStrict); + m_transactionsRoot = _header[field = 4].toHash(RLP::VeryStrict); + m_receiptsRoot = _header[field = 5].toHash(RLP::VeryStrict); + m_logBloom = _header[field = 6].toHash(RLP::VeryStrict); + m_difficulty = _header[field = 7].toInt(); + m_number = _header[field = 8].toInt(); + m_gasLimit = _header[field = 9].toInt(); + m_gasUsed = _header[field = 10].toInt(); + m_timestamp = _header[field = 11].toInt(); + m_extraData = _header[field = 12].toBytes(); + + m_gen_idx = _header[field = 13].toInt(); + m_node_list = _header[field = 14].toVector(); + + m_seal.clear(); + for (unsigned i = 15; i < _header.itemCount(); ++i) + m_seal.push_back(_header[i].data().toBytes()); + } + catch (Exception const& _e) + { + _e << errinfo_name("invalid block header format") << BadFieldError(field, toHex(_header[field].data().toBytes())); + throw; + } +} + +struct BlockInfoDiagnosticsChannel: public LogChannel { static const char* name() { return EthBlue "▧" EthWhite " ◌"; } static const int verbosity = 9; }; + +void BlockHeader::populateFromParent(BlockHeader const& _parent) +{ + m_stateRoot = _parent.stateRoot(); + m_number = _parent.m_number + 1; + m_parentHash = _parent.m_hash; + m_gasLimit = BlockHeader::maxBlockHeadGas; + m_difficulty = 1; + m_gasUsed = 0; +} + +void BlockHeader::verify(Strictness _s, BlockHeader const& _parent, bytesConstRef _block) const +{ + if (m_number > ~(unsigned)0) + BOOST_THROW_EXCEPTION(InvalidNumber()); + + if (_s != CheckNothingNew && m_gasUsed > m_gasLimit) + BOOST_THROW_EXCEPTION(TooMuchGasUsed() << RequirementError(bigint(m_gasLimit), bigint(m_gasUsed))); + + if (_parent) + { + if (m_parentHash && _parent.hash() != m_parentHash) + BOOST_THROW_EXCEPTION(InvalidParentHash()); + + if (m_timestamp <= _parent.m_timestamp) + BOOST_THROW_EXCEPTION(InvalidTimestamp()); + + if (m_number != _parent.m_number + 1) + BOOST_THROW_EXCEPTION(InvalidNumber()); + } + + if (_block) + { + RLP root(_block); + + auto txList = root[1]; + auto expectedRoot = trieRootOver(txList.itemCount(), [&](unsigned i) { return rlp(i); }, [&](unsigned i) { return txList[i].data().toBytes(); }); + + clog(BlockInfoDiagnosticsChannel) << "Expected trie root:" << toString(expectedRoot); + if (m_transactionsRoot != expectedRoot) + { + MemoryDB tm; + GenericTrieDB transactionsTrie(&tm); + transactionsTrie.init(); + + vector txs; + + for (unsigned i = 0; i < txList.itemCount(); ++i) + { + RLPStream k; + k << i; + + transactionsTrie.insert(&k.out(), txList[i].data()); + + txs.push_back(txList[i].data()); + LOG(DEBUG) << toHex(k.out()) << toHex(txList[i].data()); + } + LOG(DEBUG) << "trieRootOver" << expectedRoot; + LOG(DEBUG) << "orderedTrieRoot" << orderedTrieRoot(txs); + LOG(DEBUG) << "TrieDB" << transactionsTrie.root(); + LOG(DEBUG) << "Contents:"; + for (auto const& t : txs) + LOG(DEBUG) << toHex(t); + + BOOST_THROW_EXCEPTION(InvalidTransactionsRoot() << Hash256RequirementError(expectedRoot, m_transactionsRoot)); + } + clog(BlockInfoDiagnosticsChannel) << "Expected uncle hash:" << toString(sha3(root[2].data())); + if (m_sha3Uncles != sha3(root[2].data())) + BOOST_THROW_EXCEPTION(InvalidUnclesHash() << Hash256RequirementError(sha3(root[2].data()), m_sha3Uncles)); + } +} diff --git a/libethcore/BlockHeader.h b/libethcore/BlockHeader.h new file mode 100644 index 0000000000..326f9e3c08 --- /dev/null +++ b/libethcore/BlockHeader.h @@ -0,0 +1,213 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file BlockHeader.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include +#include +#include +#include "Common.h" +#include "ChainOperationParams.h" +#include "Exceptions.h" + +namespace dev +{ +namespace eth +{ + +enum IncludeSeal +{ + WithoutSeal = 0, + WithSeal = 1, + OnlySeal = 2 +}; + +enum Strictness +{ + CheckEverything, + JustSeal, + QuickNonce, + IgnoreSeal, + CheckNothingNew +}; + +// TODO: for implementing soon. +/*enum Check +{ + CheckBasic, + CheckExtended, + CheckBlock, + CheckParent, + CheckSeal, + CheckSealQuickly, + CheckAll = CheckBasic | CheckExtended | CheckBlock | CheckParent | CheckSeal, +}; +using Checks = FlagSet;*/ + +enum BlockDataType +{ + HeaderData, + BlockData +}; + +DEV_SIMPLE_EXCEPTION(NoHashRecorded); +DEV_SIMPLE_EXCEPTION(GenesisBlockCannotBeCalculated); + +/** @brief Encapsulation of a block header. + * Class to contain all of a block header's data. It is able to parse a block header and populate + * from some given RLP block serialisation with the static fromHeader(), through the method + * populate(). This will not conduct any verification above basic formating. In this case extra + * verification can be performed through verify(). + * + * The object may also be populated from an entire block through the explicit + * constructor BlockHeader(bytesConstRef) and manually with the populate() method. These will + * conduct verification of the header against the other information in the block. + * + * The object may be populated with a template given a parent BlockHeader object with the + * populateFromParent() method. The genesis block info may be retrieved with genesis() and the + * corresponding RLP block created with createGenesisBlock(). + * + * To determine the header hash without the nonce (for sealing), the method hash(WithoutNonce) is + * provided. + * + * The default constructor creates an empty object, which can be tested against with the boolean + * conversion operator. + */ +class BlockHeader +{ + friend class BlockChain; +public: + static const unsigned BasicFields = 15; + static u256 maxBlockHeadGas;//块最大gas + + BlockHeader(); + explicit BlockHeader(bytesConstRef _data, BlockDataType _bdt = BlockData, h256 const& _hashWith = h256()); + explicit BlockHeader(bytes const& _data, BlockDataType _bdt = BlockData, h256 const& _hashWith = h256()): BlockHeader(&_data, _bdt, _hashWith) {} + + static h256 headerHashFromBlock(bytes const& _block) { return headerHashFromBlock(&_block); } + static h256 headerHashFromBlock(bytesConstRef _block); + static RLP extractHeader(bytesConstRef _block); + + explicit operator bool() const { return m_timestamp != Invalid256; } + + bool operator==(BlockHeader const& _cmp) const + { + return m_parentHash == _cmp.parentHash() && + m_sha3Uncles == _cmp.sha3Uncles() && + m_author == _cmp.author() && + m_stateRoot == _cmp.stateRoot() && + m_transactionsRoot == _cmp.transactionsRoot() && + m_receiptsRoot == _cmp.receiptsRoot() && + m_logBloom == _cmp.logBloom() && + m_difficulty == _cmp.difficulty() && + m_number == _cmp.number() && + m_gasLimit == _cmp.gasLimit() && + m_gasUsed == _cmp.gasUsed() && + m_timestamp == _cmp.timestamp() && + m_extraData == _cmp.extraData() && + m_gen_idx == _cmp.genIndex() && + m_node_list == _cmp.nodeList(); + } + bool operator!=(BlockHeader const& _cmp) const { return !operator==(_cmp); } + + void clear(); + void noteDirty() const { m_hashWithout = m_hash = h256(); } + void populateFromParent(BlockHeader const& parent); + + // TODO: pull out into abstract class Verifier. + void verify(Strictness _s = CheckEverything, BlockHeader const& _parent = BlockHeader(), bytesConstRef _block = bytesConstRef()) const; + void verify(Strictness _s, bytesConstRef _block) const { verify(_s, BlockHeader(), _block); } + + h256 hash(IncludeSeal _i = WithSeal) const; + void streamRLP(RLPStream& _s, IncludeSeal _i = WithSeal) const; + + void setParentHash(h256 const& _v) { m_parentHash = _v; noteDirty(); } + void setSha3Uncles(h256 const& _v) { m_sha3Uncles = _v; noteDirty(); } + void setTimestamp(u256 const& _v) { m_timestamp = _v; noteDirty(); } + void setAuthor(Address const& _v) { m_author = _v; noteDirty(); } + void setRoots(h256 const& _t, h256 const& _r, h256 const& _u, h256 const& _s) { m_transactionsRoot = _t; m_receiptsRoot = _r; m_stateRoot = _s; m_sha3Uncles = _u; noteDirty(); } + void setGasUsed(u256 const& _v) { m_gasUsed = _v; noteDirty(); } + void setNumber(u256 const& _v) { m_number = _v; noteDirty(); } + void setGasLimit(u256 const& _v) { m_gasLimit = _v; noteDirty(); } + void setExtraData(bytes const& _v) { m_extraData = _v; noteDirty(); } + void setLogBloom(LogBloom const& _v) { m_logBloom = _v; noteDirty(); } + void setDifficulty(u256 const& _v) { m_difficulty = _v; noteDirty(); } + template void setSeal(unsigned _offset, T const& _value) { if (m_seal.size() <= _offset) m_seal.resize(_offset + 1); m_seal[_offset] = rlp(_value); noteDirty(); } + template void setSeal(T const& _value) { setSeal(0, _value); } + void setIndex(u256 const& _idx) { m_gen_idx = _idx; noteDirty(); } + void setNodeList(h512s const& _list) { m_node_list = _list; noteDirty(); } + + h256 const& parentHash() const { return m_parentHash; } + h256 const& sha3Uncles() const { return m_sha3Uncles; } + u256 const& timestamp() const { return m_timestamp; } + Address const& author() const { return m_author; } + h256 const& stateRoot() const { return m_stateRoot; } + h256 const& transactionsRoot() const { return m_transactionsRoot; } + h256 const& receiptsRoot() const { return m_receiptsRoot; } + u256 const& gasUsed() const { return m_gasUsed; } + u256 const& number() const { return m_number; } + u256 const& gasLimit() const { return m_gasLimit; } + bytes const& extraData() const { return m_extraData; } + LogBloom const& logBloom() const { return m_logBloom; } + u256 const& difficulty() const { return m_difficulty; } + template T seal(unsigned _offset = 0) const { T ret; if (_offset < m_seal.size()) ret = RLP(m_seal[_offset]).convert(RLP::VeryStrict); return ret; } + u256 const& genIndex() const { return m_gen_idx; } + h512s const& nodeList() const { return m_node_list; } + +private: + void populate(RLP const& _header); + void streamRLPFields(RLPStream& _s) const; + + h256 m_parentHash; + h256 m_sha3Uncles; + h256 m_stateRoot; + h256 m_transactionsRoot; + h256 m_receiptsRoot; + LogBloom m_logBloom; + u256 m_number = Invalid256; + u256 m_gasLimit; + u256 m_gasUsed; + bytes m_extraData; + u256 m_timestamp = Invalid256; + + Address m_author; + u256 m_difficulty; + + u256 m_gen_idx; /// 挖矿者的索引 + h512s m_node_list; /// 参与共识的公钥列表 + + std::vector m_seal; ///< Additional (RLP-encoded) header fields. + + mutable h256 m_hash; ///< (Memoised) SHA3 hash of the block header with seal. + mutable h256 m_hashWithout; ///< (Memoised) SHA3 hash of the block header without seal. +}; + +inline std::ostream& operator<<(std::ostream& _out, BlockHeader const& _bi) +{ + _out << _bi.hash(WithoutSeal) << " " << _bi.parentHash() << " " << _bi.sha3Uncles() << " " << _bi.author() << " " << _bi.stateRoot() << " " << _bi.transactionsRoot() << " " << + _bi.receiptsRoot() << " " << _bi.logBloom() << " " << _bi.difficulty() << " " << _bi.number() << " " << _bi.gasLimit() << " " << + _bi.gasUsed() << " " << _bi.timestamp(); + return _out; +} + +} +} diff --git a/libethcore/CMakeLists.txt b/libethcore/CMakeLists.txt new file mode 100644 index 0000000000..e18b6003a6 --- /dev/null +++ b/libethcore/CMakeLists.txt @@ -0,0 +1,28 @@ +aux_source_directory(. SRC_LIST) + +file(GLOB HEADERS "*.h") + +add_library(ethcore ${SRC_LIST} ${HEADERS}) + +find_package(Dev) + +include_directories(../libodbc/include + ../libodbc/include/db2_linux + ../libodbc/include/ibase + ../libodbc/include/infomix + ../libodbc/include/mysql + ../libodbc/include/odbc_linux + ../libodbc/include/pgsql + ../libodbc/include/sqlbase + ../libodbc/include/sqllite + ../libodbc/include/ss_linux + ../libodbc/include/sybase) + + +target_include_directories(ethcore PRIVATE ..) +target_include_directories(ethcore PRIVATE ../utils) +target_link_libraries(ethcore ${Dev_DEVCORE_LIBRARIES}) +target_link_libraries(ethcore ${Dev_DEVCRYPTO_LIBRARIES}) + +install(TARGETS ethcore RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib) + diff --git a/libethcore/ChainOperationParams.cpp b/libethcore/ChainOperationParams.cpp new file mode 100644 index 0000000000..5c701e0bf2 --- /dev/null +++ b/libethcore/ChainOperationParams.cpp @@ -0,0 +1,75 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file ChainOperationParams.cpp + * @author Gav Wood + * @date 2015 + */ + +#include "ChainOperationParams.h" + +#include +using namespace std; +using namespace dev; +using namespace eth; + +PrecompiledContract::PrecompiledContract(unsigned _base, unsigned _word, std::function const& _exec): + PrecompiledContract([=](unsigned size) -> bigint + { + bigint s = size; + bigint b = _base; + bigint w = _word; + return b + (s + 31) / 32 * w; + }, _exec) +{} + +ChainOperationParams::ChainOperationParams() +{ + otherParams = std::unordered_map{ + {"minGasLimit", "0x1388"}, + {"maxGasLimit", "0x7fffffffffffffff"}, + {"gasLimitBoundDivisor", "0x0400"}, + {"minimumDifficulty", "0x020000"}, + {"difficultyBoundDivisor", "0x0800"}, + {"durationLimit", "0x0d"}, + {"registrar", "5e70c0bbcd5636e0f9f9316e9f8633feb64d4050"}, + {"networkID", "0x0"} + }; + blockReward = u256("0x4563918244F40000"); +} + +u256 ChainOperationParams::u256Param(string const& _name) const +{ + std::string at(""); + + auto it = otherParams.find(_name); + if (it != otherParams.end()) + at = it->second; + + return u256(fromBigEndian(fromHex(at))); +} + +string ChainOperationParams::param(string const& _name) const +{ + std::string at(""); + + auto it = otherParams.find(_name); + if (it != otherParams.end()) + at = it->second; + + return at; +} + diff --git a/libethcore/ChainOperationParams.h b/libethcore/ChainOperationParams.h new file mode 100644 index 0000000000..392d3293cb --- /dev/null +++ b/libethcore/ChainOperationParams.h @@ -0,0 +1,120 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file ChainOperationsParams.h + * @author Gav Wood + * @date 2015 + */ + +#pragma once + +#include +#include "Common.h" +#include +#include + +namespace dev +{ +namespace eth +{ + +class PrecompiledContract +{ +public: + PrecompiledContract() = default; + PrecompiledContract(std::function const& _cost, std::function const& _exec): + m_cost(_cost), + m_execute(_exec) + {} + PrecompiledContract(unsigned _base, unsigned _word, std::function const& _exec); + + bigint cost(bytesConstRef _in) const { return m_cost(_in.size()); } + void execute(bytesConstRef _in, bytesRef _out) const { m_execute(_in, _out); } + +private: + std::function m_cost; + std::function m_execute; +}; + +struct ChainOperationParams +{ + ChainOperationParams(); + + explicit operator bool() const { return accountStartNonce != Invalid256; } + + /// The chain sealer name: e.g. Ethash, NoProof, BasicAuthority + std::string sealEngineName = "NoProof"; + + /// General chain params. + u256 blockReward = 0; + u256 maximumExtraDataSize = 1024; + u256 accountStartNonce = 0; + bool tieBreakingGas = true; + + /// Precompiled contracts as specified in the chain params. + std::unordered_map precompiled; + + /** + * @brief Additional parameters. + * + * e.g. Ethash specific: + * - minGasLimit + * - maxGasLimit + * - gasLimitBoundDivisor + * - minimumDifficulty + * - difficultyBoundDivisor + * - durationLimit + */ + std::unordered_map otherParams; + + /// Convenience method to get an otherParam as a u256 int. + u256 u256Param(std::string const& _name) const; + std::string param(std::string const& _name) const; + + bool evmEventLog = false; //是否打印event log + bool evmCoverLog = false; //是否打印覆盖率统计日志 + Address sysytemProxyAddress;//系统代理合约地址 + Address god;//上帝帐号 + + std::string listenIp; + int rpcPort = 6789; + int p2pPort = 16789; + std::string wallet; + std::string keystoreDir; + std::string dataDir; + std::string logFileConf; + + //dfs related parameters + string nodeId; + string groupId; + string storagePath; + + std::string vmKind; + unsigned networkId; + int logVerbosity = 4; + + u256 intervalBlockTime = 3000; + + bool broadcastToNormalNode = false; // 是否在PBFT共识阶段广播信息给非记账者 + + u256 godMinerStart=0; + u256 godMinerEnd=0; + std::map godMinerList; + +}; + +} +} diff --git a/libethcore/Common.cpp b/libethcore/Common.cpp new file mode 100644 index 0000000000..1cea6541fc --- /dev/null +++ b/libethcore/Common.cpp @@ -0,0 +1,199 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Common.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "Common.h" +#include +#include +#include +#include +#include + +#include +#include "ICAP.h" +#include "Exceptions.h" +#include "BlockHeader.h" + +using namespace std; +using namespace dev; +using namespace dev::eth; + +namespace dev +{ +namespace eth +{ + +const unsigned c_protocolVersion = 63; +#if ETH_FATDB +const unsigned c_minorProtocolVersion = 3; +const unsigned c_databaseBaseVersion = 9; +const unsigned c_databaseVersionModifier = 1; +#else +const unsigned c_minorProtocolVersion = 2; +const unsigned c_databaseBaseVersion = 9; +const unsigned c_databaseVersionModifier = 0; +#endif + +const unsigned c_databaseVersion = c_databaseBaseVersion + (c_databaseVersionModifier << 8) + (23 << 9); + +Address toAddress(std::string const& _s) +{ + try + { + eth::ICAP i = eth::ICAP::decoded(_s); + return i.direct(); + } + catch (eth::InvalidICAP&) {} + try + { + auto b = fromHex(_s.substr(0, 2) == "0x" ? _s.substr(2) : _s, WhenError::Throw); + if (b.size() == 20) + return Address(b); + } + catch (BadHexCharacter&) {} + BOOST_THROW_EXCEPTION(InvalidAddress()); +} + +vector> const& units() +{ + static const vector> s_units = + { + {exp10<54>(), "Uether"}, + {exp10<51>(), "Vether"}, + {exp10<48>(), "Dether"}, + {exp10<45>(), "Nether"}, + {exp10<42>(), "Yether"}, + {exp10<39>(), "Zether"}, + {exp10<36>(), "Eether"}, + {exp10<33>(), "Pether"}, + {exp10<30>(), "Tether"}, + {exp10<27>(), "Gether"}, + {exp10<24>(), "Mether"}, + {exp10<21>(), "grand"}, + {exp10<18>(), "ether"}, + {exp10<15>(), "finney"}, + {exp10<12>(), "szabo"}, + {exp10<9>(), "Gwei"}, + {exp10<6>(), "Mwei"}, + {exp10<3>(), "Kwei"}, + {exp10<0>(), "wei"} + }; + + return s_units; +} + +std::string formatBalance(bigint const& _b) +{ + ostringstream ret; + u256 b; + if (_b < 0) + { + ret << "-"; + b = (u256)-_b; + } + else + b = (u256)_b; + + if (b > units()[0].first * 1000) + { + ret << (b / units()[0].first) << " " << units()[0].second; + return ret.str(); + } + ret << setprecision(5); + for (auto const& i: units()) + if (i.first != 1 && b >= i.first) + { + ret << (double(b / (i.first / 1000)) / 1000.0) << " " << i.second; + return ret.str(); + } + ret << b << " wei"; + return ret.str(); +} + +static void badBlockInfo(BlockHeader const& _bi, string const& _err) +{ + string const c_line = EthReset EthOnMaroon + string(80, ' ') + EthReset; + string const c_border = EthReset EthOnMaroon + string(2, ' ') + EthReset EthMaroonBold; + string const c_space = c_border + string(76, ' ') + c_border + EthReset; + stringstream ss; + ss << c_line << endl; + ss << c_space << endl; + ss << c_border + " Import Failure " + _err + string(max(0, 53 - _err.size()), ' ') + " " + c_border << endl; + ss << c_space << endl; + string bin = toString(_bi.number()); + ss << c_border + (" Guru Meditation #" + string(max(0, 8 - bin.size()), '0') + bin + "." + _bi.hash().abridged() + " ") + c_border << endl; + ss << c_space << endl; + ss << c_line; + LOG(WARNING) << "\n" + ss.str(); +} + +void badBlock(bytesConstRef _block, string const& _err) +{ + BlockHeader bi; + DEV_IGNORE_EXCEPTIONS(bi = BlockHeader(_block)); + badBlockInfo(bi, _err); +} + +string TransactionSkeleton::userReadable(bool _toProxy, function(TransactionSkeleton const&)> const& _getNatSpec, function const& _formatAddress) const +{ + if (creation) + { + // show notice concerning the creation code. TODO: this needs entering into natspec. + return string("ÐApp is attempting to create a contract; ") + (_toProxy ? "(this transaction is not executed directly, but forwarded to another ÐApp) " : "") + "to be endowed with " + formatBalance(value) + ", with additional network fees of up to " + formatBalance(gas * gasPrice) + ".\n\nMaximum total cost is " + formatBalance(value + gas * gasPrice) + "."; + } + + bool isContract; + std::string natSpec; + tie(isContract, natSpec) = _getNatSpec(*this); + if (!isContract) + { + // recipient has no code - nothing special about this transaction, show basic value transfer info + return "ÐApp is attempting to send " + formatBalance(value) + " to a recipient " + _formatAddress(to) + (_toProxy ? " (this transaction is not executed directly, but forwarded to another ÐApp)" : "") + ", with additional network fees of up to " + formatBalance(gas * gasPrice) + ".\n\nMaximum total cost is " + formatBalance(value + gas * gasPrice) + "."; + } + + if (natSpec.empty()) + return "ÐApp is attempting to call into an unknown contract at address " + + _formatAddress(to) + ".\n\n" + + (_toProxy ? "This transaction is not executed directly, but forwarded to another ÐApp.\n\n" : "") + + "Call involves sending " + + formatBalance(value) + " to the recipient, with additional network fees of up to " + + formatBalance(gas * gasPrice) + + "However, this also does other stuff which we don't understand, and does so in your name.\n\n" + + "WARNING: This is probably going to cost you at least " + + formatBalance(value + gas * gasPrice) + + ", however this doesn't include any side-effects, which could be of far greater importance.\n\n" + + "REJECT UNLESS YOU REALLY KNOW WHAT YOU ARE DOING!"; + + return "ÐApp attempting to conduct contract interaction with " + + _formatAddress(to) + + ": " + natSpec + ".\n\n" + + (_toProxy ? "This transaction is not executed directly, but forwarded to another ÐApp.\n\n" : "") + + (value > 0 ? + "In addition, ÐApp is attempting to send " + + formatBalance(value) + " to said recipient, with additional network fees of up to " + + formatBalance(gas * gasPrice) + " = " + + formatBalance(value + gas * gasPrice) + "." + : + "Additional network fees are at most" + + formatBalance(gas * gasPrice) + "."); +} + +} +} diff --git a/libethcore/Common.h b/libethcore/Common.h new file mode 100644 index 0000000000..466e50bf52 --- /dev/null +++ b/libethcore/Common.h @@ -0,0 +1,280 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Common.h + * @author Gav Wood + * @date 2014 + * + * Ethereum-specific data structures & algorithms. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +namespace dev +{ +namespace eth +{ + +/// Current protocol version. +extern const unsigned c_protocolVersion; + +/// Current minor protocol version. +extern const unsigned c_minorProtocolVersion; + +/// Current database version. +extern const unsigned c_databaseVersion; + +/// User-friendly string representation of the amount _b in wei. +std::string formatBalance(bigint const& _b); + +DEV_SIMPLE_EXCEPTION(InvalidAddress); + +/// Convert the given string into an address. +Address toAddress(std::string const& _s); + +/// Get information concerning the currency denominations. +std::vector> const& units(); + +/// The log bloom's size (2048-bit). +using LogBloom = h2048; + +/// Many log blooms. +using LogBlooms = std::vector; + +// The various denominations; here for ease of use where needed within code. +static const u256 ether = exp10<18>(); +static const u256 finney = exp10<15>(); +static const u256 szabo = exp10<12>(); +static const u256 shannon = exp10<9>(); +static const u256 wei = exp10<0>(); + +using Nonce = h64; + +using BlockNumber = unsigned; + +static const BlockNumber LatestBlock = (BlockNumber) - 2; +static const BlockNumber PendingBlock = (BlockNumber) - 1; +static const h256 LatestBlockHash = h256(2); +static const h256 EarliestBlockHash = h256(1); +static const h256 PendingBlockHash = h256(0); + +static const u256 DefaultBlockGasLimit = 100000000; + +enum class RelativeBlock : BlockNumber +{ + Latest = LatestBlock, + Pending = PendingBlock +}; + +class Transaction; + +struct ImportRoute +{ + h256s deadBlocks; + h256s liveBlocks; + std::vector goodTranactions; +}; + +enum class FilterCheckScene { + None, + CheckDeploy, + CheckTx, + CheckCall, + CheckDeployAndTxAndCall, + PackTranscation,//打包交易场景 要校验 accountfilter、干预filter 要处理 + ImportBlock, //bc import 新块 要校验 accountfilter、干预filter 要处理 + BlockExecuteTransation// Block::execute 执行交易 通用入口 +}; + +enum class ImportResult +{ + Success = 0, + UnknownParent, + FutureTimeKnown, + FutureTimeUnknown, + AlreadyInChain, + AlreadyKnown, + Malformed, + OverbidGasPrice, + BadChain, + UnexpectedError, + NonceCheckFail, + BlockLimitCheckFail, + NoDeployPermission, + NoTxPermission, + NoCallPermission +}; + +struct ImportRequirements +{ + using value = unsigned; + enum + { + ValidSeal = 1, ///< Validate seal + UncleBasic = 4, ///< Check the basic structure of the uncles. + TransactionBasic = 8, ///< Check the basic structure of the transactions. + UncleSeals = 16, ///< Check the basic structure of the uncles. + TransactionSignatures = 32, ///< Check the basic structure of the transactions. + Parent = 64, ///< Check parent block header. + UncleParent = 128, ///< Check uncle parent block header. + PostGenesis = 256, ///< Require block to be non-genesis. + CheckMinerSignatures = 512, /// 检查签名,只有在落地块的地方才会需要 + CheckUncles = UncleBasic | UncleSeals, ///< Check uncle seals. + CheckTransactions = TransactionBasic | TransactionSignatures, ///< Check transaction signatures. + OutOfOrderChecks = ValidSeal | CheckUncles | CheckTransactions, ///< Do all checks that can be done independently of prior blocks having been imported. + InOrderChecks = Parent | UncleParent, ///< Do all checks that cannot be done independently of prior blocks having been imported. + Everything = ValidSeal | CheckUncles | CheckTransactions | Parent | UncleParent, + None = 0 + }; +}; + +/// Super-duper signal mechanism. TODO: replace with somthing a bit heavier weight. +template class Signal +{ +public: + using Callback = std::function; + + class HandlerAux + { + friend class Signal; + + public: + ~HandlerAux() { if (m_s) m_s->m_fire.erase(m_i); } + void reset() { m_s = nullptr; } + void fire(Args const&... _args) { m_h(_args...); } + + private: + HandlerAux(unsigned _i, Signal* _s, Callback const& _h): m_i(_i), m_s(_s), m_h(_h) {} + + unsigned m_i = 0; + Signal* m_s = nullptr; + Callback m_h; + }; + + ~Signal() + { + for (auto const& h : m_fire) + if (auto l = h.second.lock()) + l->reset(); + } + + std::shared_ptr add(Callback const& _h) + { + auto n = m_fire.empty() ? 0 : (m_fire.rbegin()->first + 1); + auto h = std::shared_ptr(new HandlerAux(n, this, _h)); + m_fire[n] = h; + return h; + } + + void operator()(Args const&... _args) + { + for (auto const& f : valuesOf(m_fire)) + if (auto h = f.lock()) + h->fire(_args...); + } + +private: + std::map> m_fire; +}; + +template using Handler = std::shared_ptr::HandlerAux>; + +struct TransactionSkeleton +{ + bool creation = false; + Address from; + Address to; + u256 value; + bytes data; + u256 randomid = Invalid256; + u256 gas = Invalid256; + u256 gasPrice = Invalid256; + u256 blockLimit = Invalid256; + + std::string userReadable(bool _toProxy, std::function(TransactionSkeleton const&)> const& _getNatSpec, std::function const& _formatAddress) const; +}; + +/** +* 节点配置信息的结构 +*/ +class NodeConnParams { +public: + std::string _sNodeId = ""; //节点的nodeid + std::string _sAgencyInfo = ""; //节点的机构信息 + std::string _sIP = ""; //节点ip + int _iPort = 0; //节点端口 + int _iIdentityType = -1; //节点类型 0-参与者,1-记账者 + std::string _sAgencyDesc; //节点描述 + std::string _sCAhash; //cahash + u256 _iIdx; //节点索引 + std::string toString()const { + std::ostringstream os; + os << _sNodeId << "|" << _sIP << "|" << _iPort << "|" << _iIdentityType << "|" << _sAgencyInfo << "|" << _sAgencyDesc << "|" << _sCAhash << "|" << _iIdx; + return os.str(); + } + //判断节点是否正确初始化 + bool Valid() const { + return _sNodeId != "" && _sIP != "" && _iPort != 0 && _iIdentityType != -1; + } + NodeConnParams() {}; + NodeConnParams(const std::string & json); + //转换为enode 信息 enode://${nodeid}@${ip}:${port} + std::string toEnodeInfo()const { + std::ostringstream os; + os << "enode://" << _sNodeId << "@" << _sIP << ":" << _iPort; + std::cout << "NodeConnParams toEnodeInfo is: " << os.str() << std::endl; + return os.str(); + } + bool operator==(const NodeConnParams &p1)const { + return (_sNodeId == p1._sNodeId + && _sAgencyInfo == p1._sAgencyInfo + && _sIP == p1._sIP + && _iPort == p1._iPort + && _iIdentityType == p1._iIdentityType + && _sAgencyDesc == p1._sAgencyDesc); + } +}; + +void badBlock(bytesConstRef _header, std::string const& _err); +inline void badBlock(bytes const& _header, std::string const& _err) { badBlock(&_header, _err); } + +// TODO: move back into a mining subsystem and have it be accessible from Sealant only via a dynamic_cast. +/** + * @brief Describes the progress of a mining operation. + */ +struct WorkingProgress +{ +// MiningProgress& operator+=(MiningProgress const& _mp) { hashes += _mp.hashes; ms = std::max(ms, _mp.ms); return *this; } + uint64_t hashes = 0; ///< Total number of hashes computed. + uint64_t ms = 0; ///< Total number of milliseconds of mining thus far. + u256 rate() const { return ms == 0 ? 0 : hashes * 1000 / ms; } +}; + +/// Import transaction policy +enum class IfDropped +{ + Ignore, ///< Don't import transaction that was previously dropped. + Retry ///< Import transaction even if it was dropped before. +}; + +} +} diff --git a/libethcore/CommonJS.cpp b/libethcore/CommonJS.cpp new file mode 100644 index 0000000000..71585bb3e6 --- /dev/null +++ b/libethcore/CommonJS.cpp @@ -0,0 +1,77 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file CommonJS.cpp + * @authors: + * Gav Wood + * Marek Kotewicz + * @date 2014 + */ + +#include "CommonJS.h" + +namespace dev +{ + +std::string prettyU256(u256 _n, bool _abridged) +{ + std::string raw; + std::ostringstream s; + if (!(_n >> 64)) + s << " " << (uint64_t)_n << " (0x" << std::hex << (uint64_t)_n << ")"; + else if (!~(_n >> 64)) + s << " " << (int64_t)_n << " (0x" << std::hex << (int64_t)_n << ")"; + else if ((_n >> 160) == 0) + { + Address a = right160(_n); + + std::string n; + if (_abridged) + n = a.abridged(); + else + n = toHex(a.ref()); + + if (n.empty()) + s << "0"; + else + s << _n << "(0x" << n << ")"; + } + else if (!(raw = fromRaw((h256)_n)).empty()) + return "\"" + raw + "\""; + else + s << "" << (h256)_n; + return s.str(); +} + +namespace eth +{ + +BlockNumber jsToBlockNumber(std::string const& _js) +{ + if (_js == "latest") + return LatestBlock; + else if (_js == "earliest") + return 0; + else if (_js == "pending") + return PendingBlock; + else + return (unsigned)jsToInt(_js); +} + +} + +} + diff --git a/libethcore/CommonJS.h b/libethcore/CommonJS.h new file mode 100644 index 0000000000..05fa96d611 --- /dev/null +++ b/libethcore/CommonJS.h @@ -0,0 +1,61 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file CommonJS.h + * @authors: + * Gav Wood + * Marek Kotewicz + * @date 2014 + */ + +#pragma once + +#include +#include +#include +#include "Common.h" + +// devcrypto + +namespace dev +{ + +/// Leniently convert string to Public (h512). Accepts integers, "0x" prefixing, non-exact length. +inline Public jsToPublic(std::string const& _s) { return jsToFixed(_s); } + +/// Leniently convert string to Secret (h256). Accepts integers, "0x" prefixing, non-exact length. +inline Secret jsToSecret(std::string const& _s) { h256 d = jsToFixed(_s); Secret ret(d); d.ref().cleanse(); return ret; } + +/// Leniently convert string to Address (h160). Accepts integers, "0x" prefixing, non-exact length. +inline Address jsToAddress(std::string const& _s) { return eth::toAddress(_s); } + +/// Convert u256 into user-readable string. Returns int/hex value of 64 bits int, hex of 160 bits FixedHash. As a fallback try to handle input as h256. +std::string prettyU256(u256 _n, bool _abridged = true); + +} + + +// ethcore +namespace dev +{ +namespace eth +{ + +/// Convert to a block number, a bit like jsToInt, except that it correctly recognises "pending" and "latest". +BlockNumber jsToBlockNumber(std::string const& _js); + +} +} diff --git a/libethcore/Exceptions.h b/libethcore/Exceptions.h new file mode 100644 index 0000000000..26c080ff4b --- /dev/null +++ b/libethcore/Exceptions.h @@ -0,0 +1,91 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Exceptions.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include "Common.h" + +namespace dev +{ +namespace eth +{ + +// information to add to exceptions +using errinfo_name = boost::error_info; +using errinfo_field = boost::error_info; +using errinfo_data = boost::error_info; +using errinfo_nonce = boost::error_info; +using errinfo_difficulty = boost::error_info; +using errinfo_target = boost::error_info; +using errinfo_seedHash = boost::error_info; +using errinfo_mixHash = boost::error_info; +using errinfo_ethashResult = boost::error_info>; +using BadFieldError = boost::tuple; + +DEV_SIMPLE_EXCEPTION(OutOfGasBase); +DEV_SIMPLE_EXCEPTION(OutOfGasIntrinsic); +DEV_SIMPLE_EXCEPTION(NotEnoughAvailableSpace); +DEV_SIMPLE_EXCEPTION(NotEnoughCash); +DEV_SIMPLE_EXCEPTION(GasPriceTooLow); +DEV_SIMPLE_EXCEPTION(BlockGasLimitReached); +DEV_SIMPLE_EXCEPTION(FeeTooSmall); +DEV_SIMPLE_EXCEPTION(TooMuchGasUsed); +DEV_SIMPLE_EXCEPTION(ExtraDataTooBig); +DEV_SIMPLE_EXCEPTION(ExtraDataIncorrect); +DEV_SIMPLE_EXCEPTION(InvalidSignature); +DEV_SIMPLE_EXCEPTION(InvalidTransactionFormat); +DEV_SIMPLE_EXCEPTION(InvalidBlockFormat); +DEV_SIMPLE_EXCEPTION(InvalidUnclesHash); +DEV_SIMPLE_EXCEPTION(TooManyUncles); +DEV_SIMPLE_EXCEPTION(UncleTooOld); +DEV_SIMPLE_EXCEPTION(UncleIsBrother); +DEV_SIMPLE_EXCEPTION(UncleInChain); +DEV_SIMPLE_EXCEPTION(UncleParentNotInChain); +DEV_SIMPLE_EXCEPTION(InvalidStateRoot); +DEV_SIMPLE_EXCEPTION(InvalidGasUsed); +DEV_SIMPLE_EXCEPTION(InvalidTransactionsRoot); +DEV_SIMPLE_EXCEPTION(InvalidDifficulty); +DEV_SIMPLE_EXCEPTION(InvalidGasLimit); +DEV_SIMPLE_EXCEPTION(InvalidReceiptsStateRoot); +DEV_SIMPLE_EXCEPTION(InvalidTimestamp); +DEV_SIMPLE_EXCEPTION(InvalidLogBloom); +DEV_SIMPLE_EXCEPTION(InvalidNonce); +DEV_SIMPLE_EXCEPTION(InvalidBlockHeaderItemCount); +DEV_SIMPLE_EXCEPTION(InvalidBlockNonce); +DEV_SIMPLE_EXCEPTION(InvalidParentHash); +DEV_SIMPLE_EXCEPTION(InvalidUncleParentHash); +DEV_SIMPLE_EXCEPTION(InvalidNumber); +DEV_SIMPLE_EXCEPTION(BlockNotFound); +DEV_SIMPLE_EXCEPTION(UnknownParent); +DEV_SIMPLE_EXCEPTION(NonceCheckFail); +DEV_SIMPLE_EXCEPTION(BlockLimitCheckFail); +DEV_SIMPLE_EXCEPTION(FilterCheckFail); +DEV_SIMPLE_EXCEPTION(NoDeployPermission); +DEV_SIMPLE_EXCEPTION(NoCallPermission); +DEV_SIMPLE_EXCEPTION(NoTxPermission); + +DEV_SIMPLE_EXCEPTION(DatabaseAlreadyOpen); +DEV_SIMPLE_EXCEPTION(DAGCreationFailure); +DEV_SIMPLE_EXCEPTION(DAGComputeFailure); + +} +} diff --git a/libethcore/ICAP.cpp b/libethcore/ICAP.cpp new file mode 100644 index 0000000000..5a74f187fa --- /dev/null +++ b/libethcore/ICAP.cpp @@ -0,0 +1,167 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file ICAP.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "ICAP.h" +#include +#include +#include +#include +#include "Exceptions.h" +#include "ABI.h" +using namespace std; +using namespace dev; +using namespace dev::eth; + +namespace dev +{ +namespace eth +{ + +string ICAP::iban(std::string _c, std::string _d) +{ + boost::to_upper(_c); + boost::to_upper(_d); + auto totStr = _d + _c + "00"; + bigint tot = 0; + for (char x: totStr) + if (x >= 'A') + tot = tot * 100 + x - 'A' + 10; + else + tot = tot * 10 + x - '0'; + unsigned check = (unsigned)(u256)(98 - tot % 97); + ostringstream out; + out << _c << setfill('0') << setw(2) << check << _d; + return out.str(); +} + +std::pair ICAP::fromIBAN(std::string _iban) +{ + if (_iban.size() < 4) + return std::make_pair(string(), string()); + boost::to_upper(_iban); + std::string c = _iban.substr(0, 2); + std::string d = _iban.substr(4); + if (iban(c, d) != _iban) + return std::make_pair(string(), string()); + return make_pair(c, d); +} + +Secret ICAP::createDirect() +{ + Secret ret; + while (true) + { + ret = Secret::random(); + if (!toAddress(ret)[0]) + return ret; + } +} + +ICAP ICAP::decoded(std::string const& _encoded) +{ + ICAP ret; + std::string country; + std::string data; + std::tie(country, data) = fromIBAN(_encoded); + if (country != "XE") + BOOST_THROW_EXCEPTION(InvalidICAP()); + if (data.size() == 30 || data.size() == 31) + { + ret.m_type = Direct; + // Direct ICAP + ret.m_direct = fromBase36(data); + } + else if (data.size() == 16) + { + ret.m_type = Indirect; + ret.m_asset = data.substr(0, 3); + if (ret.m_asset == "XET" || ret.m_asset == "ETH") + { + ret.m_institution = data.substr(3, 4); + ret.m_client = data.substr(7); + } + else + BOOST_THROW_EXCEPTION(InvalidICAP()); + } + else + BOOST_THROW_EXCEPTION(InvalidICAP()); + + return ret; +} + +std::string ICAP::encoded() const +{ + if (m_type == Direct) + { + std::string d = toBase36(m_direct); + while (d.size() < 30) // always 34, sometimes 35. + d = "0" + d; + return iban("XE", d); + } + else if (m_type == Indirect) + { + if ( + m_asset.find_first_not_of("qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890") != string::npos || + m_institution.find_first_not_of("qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890") != string::npos || + m_client.find_first_not_of("qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890") != string::npos || + m_asset.size() != 3 || + (boost::to_upper_copy(m_asset) != "XET" && boost::to_upper_copy(m_asset) != "ETH") || + m_institution.size() != 4 || + m_client.size() != 9 + ) + BOOST_THROW_EXCEPTION(InvalidICAP()); + return iban("XE", m_asset + m_institution + m_client); + } + else + BOOST_THROW_EXCEPTION(InvalidICAP()); +} + +pair ICAP::lookup(std::function const& _call, Address const& _reg) const +{ + auto resolve = [&](string const& s) + { +/* vector ss; + boost::algorithm::split(ss, s, boost::is_any_of("/")); + Address r = _reg; + for (unsigned i = 0; i < ss.size() - 1; ++i) + r = abiOut
(_call(r, abiIn("subRegistrar(bytes32)", ss[i])));*/ + return abiOut
(_call(_reg, abiIn("addr(string)", s))); + }; + if (m_asset == "XET") + { + Address a = resolve(m_institution); + bytes d = abiIn("deposit(uint64)", fromBase36<8>(m_client)); + return make_pair(a, d); + } +/* else if (m_asset == "ETH") + { + if (m_institution[0] != 'X') + return make_pair(resolve(m_institution + "/" + m_client), bytes()); + else if (m_institution == "XREG") + return make_pair(resolve(m_client), bytes()); + else + BOOST_THROW_EXCEPTION(InterfaceNotSupported("ICAP::lookup(), bad institution")); + }*/ + BOOST_THROW_EXCEPTION(InterfaceNotSupported("ICAP::lookup(), bad asset")); +} + +} +} diff --git a/libethcore/ICAP.h b/libethcore/ICAP.h new file mode 100644 index 0000000000..7e18f74270 --- /dev/null +++ b/libethcore/ICAP.h @@ -0,0 +1,106 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file ICAP.h + * @author Gav Wood + * @date 2014 + * + * Ethereum-specific data structures & algorithms. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include "Common.h" + +namespace dev +{ +namespace eth +{ + +DEV_SIMPLE_EXCEPTION(InvalidICAP); + +/** + * @brief Encapsulation of an ICAP address. + * Can be encoded, decoded, looked-up and inspected. + */ +class ICAP +{ +public: + /// Construct null ICAP object. + ICAP() = default; + /// Construct a direct ICAP object for given target address. Must have a zero first byte. + ICAP(Address const& _target): m_type(Direct), m_direct(_target) {} + /// Construct an indirect ICAP object for given client and institution names. + ICAP(std::string const& _client, std::string const& _inst): m_type(Indirect), m_client(boost::algorithm::to_upper_copy(_client)), m_institution(boost::algorithm::to_upper_copy(_inst)), m_asset("XET") {} + /// Construct an indirect ICAP object for given client, institution and asset names. You generally don't want to use this. + ICAP(std::string const& _c, std::string const& _i, std::string const& _a): m_type(Indirect), m_client(boost::algorithm::to_upper_copy(_c)), m_institution(boost::algorithm::to_upper_copy(_i)), m_asset(boost::algorithm::to_upper_copy(_a)) {} + + /// Type of ICAP address. + enum Type + { + Invalid, + Direct, + Indirect + }; + + /// Create a direct address for ICAP. + static Secret createDirect(); + + /// @returns IBAN encoding of client and data. + static std::string iban(std::string _c, std::string _d); + /// @returns Client and data from given IBAN address. + static std::pair fromIBAN(std::string _iban); + + /// @returns the ICAP object for the ICAP address given. + static ICAP decoded(std::string const& _encoded); + + /// @returns the encoded ICAP address. + std::string encoded() const; + /// @returns type of ICAP. + Type type() const { return m_type; } + /// @returns target address. Only valid when type() == Direct. + Address const& direct() const { return m_type == Direct ? m_direct : ZeroAddress; } + /// @returns asset. Only valid when type() == Indirect. + std::string const& asset() const { return m_type == Indirect ? m_asset : EmptyString; } + /// @returns target name. Only valid when type() == Indirect and asset() == "ETH". + std::string const& target() const { return m_type == Indirect && m_asset == "ETH" ? m_client : EmptyString; } + /// @returns institution name. Only valid when type() == Indirect and asset() == "XET". + std::string const& institution() const { return m_type == Indirect && m_asset == "XET" ? m_institution : EmptyString; } + /// @returns client name. Only valid when type() == Indirect and asset() == "XET". + std::string const& client() const { return m_type == Indirect && m_asset == "XET" ? m_client : EmptyString; } + /// @returns target address. Always valid, but requires the Registry address and a function to make calls. + std::pair address(std::function const& _call, Address const& _reg) const { return m_type == Direct ? make_pair(direct(), bytes()) : m_type == Indirect ? lookup(_call, _reg) : make_pair(Address(), bytes()); } + + /// @returns target address. Looks up through the given Registry and call function. Only valid when type() == Indirect. + std::pair lookup(std::function const& _call, Address const& _reg) const; + +private: + Type m_type = Invalid; + Address m_direct; + std::string m_client; + std::string m_institution; + std::string m_asset; +}; + + +} +} diff --git a/libethcore/KeyManager.cpp b/libethcore/KeyManager.cpp new file mode 100644 index 0000000000..5d25e048a0 --- /dev/null +++ b/libethcore/KeyManager.cpp @@ -0,0 +1,485 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file KeyManager.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "KeyManager.h" +#include +#include +#include +#include + +#include +#include +#include +using namespace std; +using namespace dev; +using namespace eth; +namespace js = json_spirit; +namespace fs = boost::filesystem; + +std::string KeyManager::defaultpath=getDataDir("ethereum") + "/keys.info"; + +KeyManager::KeyManager(string const& _keysFile, string const& _secretsPath): + m_keysFile(_keysFile), m_store(_secretsPath) +{ + for (auto const& uuid: m_store.keys()) + { + auto addr = m_store.address(uuid); + m_addrLookup[addr] = uuid; + m_uuidLookup[uuid] = addr; + } +} + +KeyManager::~KeyManager() +{} + +bool KeyManager::exists() const +{ + return !contents(m_keysFile + ".salt").empty() && !contents(m_keysFile).empty(); +} + +void KeyManager::create(string const& _pass) +{ + m_defaultPasswordDeprecated = asString(h256::random().asBytes()); + write(_pass, m_keysFile); +} + +bool KeyManager::recode(Address const& _address, string const& _newPass, string const& _hint, function const& _pass, KDF _kdf) +{ + noteHint(_newPass, _hint); + h128 u = uuid(_address); + if (!store().recode(u, _newPass, [&](){ return getPassword(u, _pass); }, _kdf)) + return false; + + m_keyInfo[_address].passHash = hashPassword(_newPass); + write(); + return true; +} + +bool KeyManager::recode(Address const& _address, SemanticPassword _newPass, function const& _pass, KDF _kdf) +{ + h128 u = uuid(_address); + string p; + if (_newPass == SemanticPassword::Existing) + p = getPassword(u, _pass); + else if (_newPass == SemanticPassword::Master) + p = defaultPassword(); + else + return false; + + return recode(_address, p, string(), _pass, _kdf); +} + +bool KeyManager::load(string const& _pass) +{ + try + { + bytes salt = contents(m_keysFile + ".salt"); + bytes encKeys = contents(m_keysFile); + if (encKeys.empty()) + return false; + m_keysFileKey = SecureFixedHash<16>(pbkdf2(_pass, salt, 262144, 16)); + bytesSec bs = decryptSymNoAuth(m_keysFileKey, h128(), &encKeys); + RLP s(bs.ref()); + unsigned version = unsigned(s[0]); + if (version == 1) + { + bool saveRequired = false; + for (auto const& i: s[1]) + { + h128 uuid(i[1]); + Address addr(i[0]); + if (uuid) + { + if (m_store.contains(uuid)) + { + m_addrLookup[addr] = uuid; + m_uuidLookup[uuid] = addr; + m_keyInfo[addr] = KeyInfo(h256(i[2]), string(i[3]), i.itemCount() > 4 ? string(i[4]) : ""); + if (m_store.noteAddress(uuid, addr)) + saveRequired = true; + } + else + LOG(WARNING) << "Missing key:" << uuid << addr; + } + else + { + // TODO: brain wallet. + m_keyInfo[addr] = KeyInfo(h256(i[2]), string(i[3]), i.itemCount() > 4 ? string(i[4]) : ""); + } +// LOG(DEBUG) << toString(addr) << toString(uuid) << toString((h256)i[2]) << (string)i[3]; + } + if (saveRequired) + m_store.save(); + + for (auto const& i: s[2]) + m_passwordHint[h256(i[0])] = string(i[1]); + m_defaultPasswordDeprecated = string(s[3]); + } +// LOG(DEBUG) << hashPassword(m_password) << toHex(m_password); + cachePassword(m_defaultPasswordDeprecated); +// LOG(DEBUG) << hashPassword(asString(m_key.ref())) << m_key.hex(); + cachePassword(asString(m_keysFileKey.ref())); +// LOG(DEBUG) << hashPassword(_pass) << _pass; + m_master = hashPassword(_pass); + cachePassword(_pass); + return true; + } + catch (...) + { + return false; + } +} + +Secret KeyManager::secret(Address const& _address, function const& _pass, bool _usePasswordCache) const +{ + if (m_addrLookup.count(_address)) + return secret(m_addrLookup.at(_address), _pass, _usePasswordCache); + else + return brain(_pass()); +} + +Secret KeyManager::secret(h128 const& _uuid, function const& _pass, bool _usePasswordCache) const +{ + if (_usePasswordCache) + return Secret(m_store.secret(_uuid, [&](){ return getPassword(_uuid, _pass); }, _usePasswordCache)); + else + return Secret(m_store.secret(_uuid, _pass, _usePasswordCache)); +} + +string KeyManager::getPassword(h128 const& _uuid, function const& _pass) const +{ + h256 ph; + auto ait = m_uuidLookup.find(_uuid); + if (ait != m_uuidLookup.end()) + { + auto kit = m_keyInfo.find(ait->second); + if (kit != m_keyInfo.end()) + ph = kit->second.passHash; + } + return getPassword(ph, _pass); +} + +string KeyManager::getPassword(h256 const& _passHash, function const& _pass) const +{ + auto it = m_cachedPasswords.find(_passHash); + if (it != m_cachedPasswords.end()) + return it->second; + for (unsigned i = 0; i < 10; ++i) + { + string p = _pass(); + if (p.empty()) + break; + if (_passHash == UnknownPassword || hashPassword(p) == _passHash) + { + cachePassword(p); + return p; + } + } + return string(); +} + +h128 KeyManager::uuid(Address const& _a) const +{ + auto it = m_addrLookup.find(_a); + if (it == m_addrLookup.end()) + return h128(); + return it->second; +} + +Address KeyManager::address(h128 const& _uuid) const +{ + auto it = m_uuidLookup.find(_uuid); + if (it == m_uuidLookup.end()) + return Address(); + return it->second; +} + +h128 KeyManager::import(Secret const& _s, string const& _accountName, string const& _pass, string const& _passwordHint) +{ + Address addr = KeyPair(_s).address(); + auto passHash = hashPassword(_pass); + cachePassword(_pass); + m_passwordHint[passHash] = _passwordHint; + auto uuid = m_store.importSecret(_s.asBytesSec(), _pass); + m_keyInfo[addr] = KeyInfo{passHash, _accountName, ""}; + m_addrLookup[addr] = uuid; + m_uuidLookup[uuid] = addr; + write(m_keysFile); + return uuid; +} + +Secret KeyManager::brain(string const& _seed) +{ + h256 r = sha3(_seed); + for (auto i = 0; i < 16384; ++i) + r = sha3(r); + Secret ret(r); + r.ref().cleanse(); + while (toAddress(ret)[0]) + ret = sha3(ret); + return ret; +} + +Secret KeyManager::subkey(Secret const& _s, unsigned _index) +{ + RLPStream out(2); + out << _s.ref(); + out << _index; + bytesSec r; + out.swapOut(r.writable()); + return sha3(r); +} + +Address KeyManager::importBrain(string const& _seed, string const& _accountName, string const& _passwordHint) +{ + Address addr = toAddress(brain(_seed)); + m_keyInfo[addr].accountName = _accountName; + m_keyInfo[addr].passwordHint = _passwordHint; + write(); + return addr; +} + +void KeyManager::importExistingBrain(Address const& _a, string const& _accountName, string const& _passwordHint) +{ + m_keyInfo[_a].accountName = _accountName; + m_keyInfo[_a].passwordHint = _passwordHint; + write(); +} + +void KeyManager::importExisting(h128 const& _uuid, string const& _info, string const& _pass, string const& _passwordHint) +{ + bytesSec key = m_store.secret(_uuid, [&](){ return _pass; }); + if (key.empty()) + return; + Address a = KeyPair(Secret(key)).address(); + auto passHash = hashPassword(_pass); + if (!m_cachedPasswords.count(passHash)) + cachePassword(_pass); + importExisting(_uuid, _info, a, passHash, _passwordHint); +} + +void KeyManager::importExisting(h128 const& _uuid, string const& _accountName, Address const& _address, h256 const& _passHash, string const& _passwordHint) +{ + if (!m_passwordHint.count(_passHash)) + m_passwordHint[_passHash] = _passwordHint; + m_uuidLookup[_uuid] = _address; + m_addrLookup[_address] = _uuid; + m_keyInfo[_address].passHash = _passHash; + m_keyInfo[_address].accountName = _accountName; + write(m_keysFile); +} + +void KeyManager::kill(Address const& _a) +{ + auto id = m_addrLookup[_a]; + m_uuidLookup.erase(id); + m_addrLookup.erase(_a); + m_keyInfo.erase(_a); + m_store.kill(id); + write(m_keysFile); +} + +KeyPair KeyManager::presaleSecret(std::string const& _json, function const& _password) +{ + js::mValue val; + json_spirit::read_string(_json, val); + auto obj = val.get_obj(); + string p = _password(true); + if (obj["encseed"].type() == js::str_type) + { + auto encseed = fromHex(obj["encseed"].get_str()); + KeyPair k; + for (bool gotit = false; !gotit;) + { + gotit = true; + k = KeyPair::fromEncryptedSeed(&encseed, p); + if (obj["ethaddr"].type() == js::str_type) + { + Address a(obj["ethaddr"].get_str()); + Address b = k.address(); + if (a != b) + { + if ((p = _password(false)).empty()) + BOOST_THROW_EXCEPTION(PasswordUnknown()); + else + gotit = false; + } + } + } + return k; + } + else + BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("encseed type is not js::str_type")); +} + +Addresses KeyManager::accounts() const +{ + set
addresses; + for (auto const& i: m_keyInfo) + addresses.insert(i.first); + for (auto const& key: m_store.keys()) + addresses.insert(m_store.address(key)); + // Remove the zero address if present + return Addresses{addresses.upper_bound(Address()), addresses.end()}; +} + +bool KeyManager::hasAccount(Address const& _address) const +{ + if (!_address) + return false; + if (m_keyInfo.count(_address)) + return true; + for (auto const& key: m_store.keys()) + if (m_store.address(key) == _address) + return true; + return false; +} + +string const& KeyManager::accountName(Address const& _address) const +{ + try + { + return m_keyInfo.at(_address).accountName; + } + catch (...) + { + return EmptyString; + } +} + +void KeyManager::changeName(Address const& _address, std::string const& _name) +{ + auto it = m_keyInfo.find(_address); + if (it != m_keyInfo.end()) + { + it->second.accountName = _name; + write(m_keysFile); + } +} + +string const& KeyManager::passwordHint(Address const& _address) const +{ + try + { + auto& info = m_keyInfo.at(_address); + if (info.passwordHint.size()) + return info.passwordHint; + return m_passwordHint.at(info.passHash); + } + catch (...) + { + return EmptyString; + } +} + +h256 KeyManager::hashPassword(string const& _pass) const +{ + // TODO SECURITY: store this a bit more securely; Scrypt perhaps? + return h256(pbkdf2(_pass, asBytes(m_defaultPasswordDeprecated), 262144, 32).makeInsecure()); +} + +void KeyManager::cachePassword(string const& _password) const +{ + m_cachedPasswords[hashPassword(_password)] = _password; +} + +bool KeyManager::write(string const& _keysFile) const +{ + if (!m_keysFileKey) + return false; + write(m_keysFileKey, _keysFile); + return true; +} + +void KeyManager::write(string const& _pass, string const& _keysFile) const +{ + bytes salt = h256::random().asBytes(); + writeFile(_keysFile + ".salt", salt, true); + auto key = SecureFixedHash<16>(pbkdf2(_pass, salt, 262144, 16)); + + cachePassword(_pass); + m_master = hashPassword(_pass); + write(key, _keysFile); +} + +void KeyManager::write(SecureFixedHash<16> const& _key, string const& _keysFile) const +{ + RLPStream s(4); + s << 1; // version + + s.appendList(m_keyInfo.size()); + for (auto const& info: m_keyInfo) + { + h128 id = uuid(info.first); + auto const& ki = info.second; + s.appendList(5) << info.first << id << ki.passHash << ki.accountName << ki.passwordHint; + } + + s.appendList(m_passwordHint.size()); + for (auto const& i: m_passwordHint) + s.appendList(2) << i.first << i.second; + s.append(m_defaultPasswordDeprecated); + + writeFile(_keysFile, encryptSymNoAuth(_key, h128(), &s.out()), true); + m_keysFileKey = _key; + cachePassword(defaultPassword()); +} + +KeyPair KeyManager::newKeyPair(KeyManager::NewKeyType _type) +{ + KeyPair p; + bool keepGoing = true; + unsigned done = 0; + function f = [&]() { + KeyPair lp; + while (keepGoing) + { + done++; + if (done % 1000 == 0) + LOG(DEBUG) << "Tried" << done << "keys"; + lp = KeyPair::create(); + auto a = lp.address(); + if (_type == NewKeyType::NoVanity || + (_type == NewKeyType::DirectICAP && !a[0]) || + (_type == NewKeyType::FirstTwo && a[0] == a[1]) || + (_type == NewKeyType::FirstTwoNextTwo && a[0] == a[1] && a[2] == a[3]) || + (_type == NewKeyType::FirstThree && a[0] == a[1] && a[1] == a[2]) || + (_type == NewKeyType::FirstFour && a[0] == a[1] && a[1] == a[2] && a[2] == a[3]) + ) + break; + } + if (keepGoing) + p = lp; + keepGoing = false; + }; + + vector ts; + for (unsigned t = 0; t < std::thread::hardware_concurrency() - 1; ++t) + ts.push_back(new std::thread(f)); + f(); + + for (std::thread* t: ts) + { + t->join(); + delete t; + } + return p; +} diff --git a/libethcore/KeyManager.h b/libethcore/KeyManager.h new file mode 100644 index 0000000000..974842eaca --- /dev/null +++ b/libethcore/KeyManager.h @@ -0,0 +1,200 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . + */ +/** @file KeyManager.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +namespace dev +{ +namespace eth +{ +class PasswordUnknown: public Exception {}; + +struct KeyInfo +{ + KeyInfo() = default; + KeyInfo(h256 const& _passHash, std::string const& _accountName, std::string const& _passwordHint = std::string()): passHash(_passHash), accountName(_accountName), passwordHint(_passwordHint) {} + + /// Hash of the password or h256() / UnknownPassword if unknown. + h256 passHash; + /// Name of the key, or JSON key info if begins with '{'. + std::string accountName; + /// Hint of the password. Alternative place for storage than the hash-based lookup. + std::string passwordHint; +}; + +static h256 const UnknownPassword; +/// Password query function that never returns a password. +static auto const DontKnowThrow = [](){ throw PasswordUnknown(); return std::string(); }; + +enum class SemanticPassword +{ + Existing, + Master +}; + +// TODO: This one is specifically for Ethereum, but we can make it generic in due course. +// TODO: hidden-partition style key-store. +/** + * @brief High-level manager of password-encrypted keys for Ethereum. + * Usage: + * + * Call exists() to check whether there is already a database. If so, get the master password from + * the user and call load() with it. If not, get a new master password from the user (get them to type + * it twice and keep some hint around!) and call create() with it. + * + * Uses a "key file" (and a corresponding .salt file) that contains encrypted information about the keys and + * a directory called "secrets path" that contains a file for each key. + */ +class KeyManager +{ +public: + enum class NewKeyType { DirectICAP = 0, NoVanity, FirstTwo, FirstTwoNextTwo, FirstThree, FirstFour }; + + KeyManager(std::string const& _keysFile = defaultPath(), std::string const& _secretsPath = SecretStore::defaultPath()); + ~KeyManager(); + + void setSecretsPath(std::string const& _secretsPath) { m_store.setPath(_secretsPath); } + void setKeysFile(std::string const& _keysFile) { m_keysFile = _keysFile; } + std::string const& keysFile() const { return m_keysFile; } + + bool exists() const; + void create(std::string const& _pass); + bool load(std::string const& _pass); + void save(std::string const& _pass) const { write(_pass, m_keysFile); } + + void notePassword(std::string const& _pass) { m_cachedPasswords[hashPassword(_pass)] = _pass; } + void noteHint(std::string const& _pass, std::string const& _hint) { if (!_hint.empty()) m_passwordHint[hashPassword(_pass)] = _hint; } + bool haveHint(std::string const& _pass) const { auto h = hashPassword(_pass); return m_cachedPasswords.count(h) && !m_cachedPasswords.at(h).empty(); } + + /// @returns the list of account addresses. + Addresses accounts() const; + /// @returns a hashset of all account addresses. + AddressHash accountsHash() const { return AddressHash() + accounts(); } + bool hasAccount(Address const& _address) const; + /// @returns the human-readable name or json-encoded info of the account for the given address. + std::string const& accountName(Address const& _address) const; + /// @returns the password hint for the account for the given address; + std::string const& passwordHint(Address const& _address) const; + /// Should be called to change password + void changeName(Address const& _address, std::string const& _name); + + /// @returns true if the given address has a key (UUID) associated with it. Equivalent to !!uuid(_a) + /// If the address has no key, it could be a brain wallet. + bool haveKey(Address const& _a) const { return m_addrLookup.count(_a); } + /// @returns the uuid of the key for the address @a _a or the empty hash on error. + h128 uuid(Address const& _a) const; + /// @returns the address corresponding to the key with uuid @a _uuid or the zero address on error. + Address address(h128 const& _uuid) const; + + h128 import(Secret const& _s, std::string const& _accountName, std::string const& _pass, std::string const& _passwordHint); + h128 import(Secret const& _s, std::string const& _accountName) { return import(_s, _accountName, defaultPassword(), std::string()); } + Address importBrain(std::string const& _seed, std::string const& _accountName, std::string const& _seedHint); + void importExistingBrain(Address const& _a, std::string const& _accountName, std::string const& _seedHint); + + SecretStore& store() { return m_store; } + void importExisting(h128 const& _uuid, std::string const& _accountName, std::string const& _pass, std::string const& _passwordHint); + void importExisting(h128 const& _uuid, std::string const& _accountName) { importExisting(_uuid, _accountName, defaultPassword(), std::string()); } + void importExisting(h128 const& _uuid, std::string const& _accountName, Address const& _addr, h256 const& _passHash = h256(), std::string const& _passwordHint = std::string()); + + /// @returns the secret key associated with an address provided the password query + /// function @a _pass or the zero-secret key on error. + Secret secret(Address const& _address, std::function const& _pass = DontKnowThrow, bool _usePasswordCache = true) const; + /// @returns the secret key associated with the uuid of a key provided the password query + /// function @a _pass or the zero-secret key on error. + Secret secret(h128 const& _uuid, std::function const& _pass = DontKnowThrow, bool _usePasswordCache = true) const; + + bool recode(Address const& _address, SemanticPassword _newPass, std::function const& _pass = DontKnowThrow, KDF _kdf = KDF::Scrypt); + bool recode(Address const& _address, std::string const& _newPass, std::string const& _hint, std::function const& _pass = DontKnowThrow, KDF _kdf = KDF::Scrypt); + + void kill(h128 const& _id) { kill(address(_id)); } + void kill(Address const& _a); + + static std::string defaultPath() { return KeyManager::defaultpath ; } + + + + static std::string defaultpath; + //TODO: remove init_priority, use a better way. + + + + /// Extracts the secret key from the presale wallet. + static KeyPair presaleSecret(std::string const& _json, std::function const& _password); + + /// @returns the brainwallet secret for the given seed. + static Secret brain(std::string const& _seed); + + /// @returns the HD subkey for a given key. + static Secret subkey(Secret const& _s, unsigned _index); + + /// @returns new random keypair with given vanity + static KeyPair newKeyPair(NewKeyType _type); +private: + std::string getPassword(h128 const& _uuid, std::function const& _pass = DontKnowThrow) const; + std::string getPassword(h256 const& _passHash, std::function const& _pass = DontKnowThrow) const; + std::string defaultPassword(std::function const& _pass = DontKnowThrow) const { return getPassword(m_master, _pass); } + h256 hashPassword(std::string const& _pass) const; + + /// Stores the password by its hash in the password cache. + void cachePassword(std::string const& _password) const; + + // Only use if previously loaded ok. + // @returns false if wasn't previously loaded ok. + bool write() const { return write(m_keysFile); } + bool write(std::string const& _keysFile) const; + void write(std::string const& _pass, std::string const& _keysFile) const; // TODO: all passwords should be a secure string. + void write(SecureFixedHash<16> const& _key, std::string const& _keysFile) const; + + // Ethereum keys. + + /// Mapping key uuid -> address. + std::unordered_map m_uuidLookup; + /// Mapping address -> key uuid. + std::unordered_map m_addrLookup; + /// Mapping address -> key info. + std::unordered_map m_keyInfo; + /// Mapping password hash -> password hint. + std::unordered_map m_passwordHint; + + // Passwords that we're storing. Mapping password hash -> password. + mutable std::unordered_map m_cachedPasswords; + + // DEPRECATED. + // Used to be the default password for keys in the keystore, stored in the keys file. + // Now the default password is based off the key of the keys file directly, so this is redundant + // except for the fact that people have existing keys stored with it. Leave for now until/unless + // we have an upgrade strategy. + std::string m_defaultPasswordDeprecated; + + mutable std::string m_keysFile; + mutable SecureFixedHash<16> m_keysFileKey; + mutable h256 m_master; + SecretStore m_store; +}; + +} +} diff --git a/libethcore/Precompiled.cpp b/libethcore/Precompiled.cpp new file mode 100644 index 0000000000..1630ec6214 --- /dev/null +++ b/libethcore/Precompiled.cpp @@ -0,0 +1,92 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Precompiled.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "Precompiled.h" + +#include +#include +#include +#include +using namespace std; +using namespace dev; +using namespace dev::eth; + +PrecompiledRegistrar* PrecompiledRegistrar::s_this = nullptr; + +PrecompiledExecutor const& PrecompiledRegistrar::executor(std::string const& _name) +{ + if (!get()->m_execs.count(_name)) + BOOST_THROW_EXCEPTION(ExecutorNotFound()); + return get()->m_execs[_name]; +} + +namespace +{ + +ETH_REGISTER_PRECOMPILED(ecrecover)(bytesConstRef _in, bytesRef _out) +{ + struct inType + { + h256 hash; + h256 v; + h256 r; + h256 s; + } in; + + memcpy(&in, _in.data(), min(_in.size(), sizeof(in))); + + h256 ret; + u256 v = (u256)in.v; + if (v >= 27 && v <= 28) + { + SignatureStruct sig(in.r, in.s, (byte)((int)v - 27)); + if (sig.isValid()) + { + try + { + if (Public rec = recover(sig, in.hash)) + { + ret = dev::sha3(rec); + memset(ret.data(), 0, 12); + ret.ref().copyTo(_out); + } + } + catch (...) {} + } + } +} + +ETH_REGISTER_PRECOMPILED(sha256)(bytesConstRef _in, bytesRef _out) +{ + dev::sha256(_in).ref().copyTo(_out); +} + +ETH_REGISTER_PRECOMPILED(ripemd160)(bytesConstRef _in, bytesRef _out) +{ + h256(dev::ripemd160(_in), h256::AlignRight).ref().copyTo(_out); +} + +ETH_REGISTER_PRECOMPILED(identity)(bytesConstRef _in, bytesRef _out) +{ + _in.copyTo(_out); +} + +} diff --git a/libethcore/Precompiled.h b/libethcore/Precompiled.h new file mode 100644 index 0000000000..a98bb31f30 --- /dev/null +++ b/libethcore/Precompiled.h @@ -0,0 +1,60 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Precompiled.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include +#include +#include + +namespace dev +{ +namespace eth +{ + +using PrecompiledExecutor = std::function; + +DEV_SIMPLE_EXCEPTION(ExecutorNotFound); + +class PrecompiledRegistrar +{ +public: + /// Get the executor object for @a _name function or @throw ExecutorNotFound if not found. + static PrecompiledExecutor const& executor(std::string const& _name); + + /// Register an executor. In general just use ETH_REGISTER_PRECOMPILED. + static PrecompiledExecutor registerPrecompiled(std::string const& _name, PrecompiledExecutor const& _exec) { return (get()->m_execs[_name] = _exec); } + /// Unregister an executor. Shouldn't generally be necessary. + static void unregisterPrecompiled(std::string const& _name) { get()->m_execs.erase(_name); } + +private: + static PrecompiledRegistrar* get() { if (!s_this) s_this = new PrecompiledRegistrar; return s_this; } + + std::unordered_map m_execs; + static PrecompiledRegistrar* s_this; +}; + +// TODO: unregister on unload with a static object. +#define ETH_REGISTER_PRECOMPILED(Name) static void __eth_registerPrecompiledFunction ## Name(bytesConstRef _in, bytesRef _out); static PrecompiledExecutor __eth_registerPrecompiledFactory ## Name = ::dev::eth::PrecompiledRegistrar::registerPrecompiled(#Name, &__eth_registerPrecompiledFunction ## Name); static void __eth_registerPrecompiledFunction ## Name + +} +} diff --git a/libethcore/SealEngine.cpp b/libethcore/SealEngine.cpp new file mode 100644 index 0000000000..ad5a29f48d --- /dev/null +++ b/libethcore/SealEngine.cpp @@ -0,0 +1,71 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file SealEngine.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "SealEngine.h" +#include "Transaction.h" +#include +using namespace std; +using namespace dev; +using namespace eth; + +SealEngineRegistrar* SealEngineRegistrar::s_this = nullptr; + +void NoProof::init() +{ + ETH_REGISTER_SEAL_ENGINE(NoProof); +} + +void SealEngineFace::verify(Strictness _s, BlockHeader const& _bi, BlockHeader const& _parent, bytesConstRef _block) const +{ + _bi.verify(_s, _parent, _block); +} + +void SealEngineFace::populateFromParent(BlockHeader& _bi, BlockHeader const& _parent) const +{ + _bi.populateFromParent(_parent); +} + +void SealEngineFace::verifyTransaction(ImportRequirements::value _ir, TransactionBase const& _t, BlockHeader const&) const +{ + if (_ir & ImportRequirements::TransactionSignatures) + _t.checkLowS(); +} + +SealEngineFace* SealEngineRegistrar::create(ChainOperationParams const& _params) +{ + SealEngineFace* ret = create(_params.sealEngineName); + assert(ret && "Seal engine not found."); + if (ret) + ret->setChainParams(_params); + return ret; +} + +EVMSchedule const& SealEngineBase::evmSchedule(EnvInfo const& _envInfo) const +{ + if (_envInfo.number() >= chainParams().u256Param("EIP158ForkBlock")) + return EIP158Schedule; + else if (_envInfo.number() >= chainParams().u256Param("EIP150ForkBlock")) + return EIP150Schedule; + else if (_envInfo.number() >= chainParams().u256Param("homsteadForkBlock")) + return HomesteadSchedule; + else + return FrontierSchedule; +} diff --git a/libethcore/SealEngine.h b/libethcore/SealEngine.h new file mode 100644 index 0000000000..9b7c4a0218 --- /dev/null +++ b/libethcore/SealEngine.h @@ -0,0 +1,146 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file SealEngine.h + * @author Gav Wood + * @date 2014 + * + * Determines the PoW algorithm. + */ + +#pragma once + +#include +#include +#include +#include +#include "BlockHeader.h" +#include "Common.h" + +namespace dev +{ +namespace eth +{ + +class BlockHeader; +struct ChainOperationParams; +class Interface; +class PrecompiledFace; +class TransactionBase; +class EnvInfo; + +class SealEngineFace +{ +public: + virtual ~SealEngineFace() {} + + virtual std::string name() const = 0; + virtual unsigned revision() const { return 0; } + virtual unsigned sealFields() const { return 0; } + virtual bytes sealRLP() const { return bytes(); } + virtual StringHashMap jsInfo(BlockHeader const&) const { return StringHashMap(); } + + /// Don't forget to call Super::verify when subclassing & overriding. + virtual void verify(Strictness _s, BlockHeader const& _bi, BlockHeader const& _parent = BlockHeader(), bytesConstRef _block = bytesConstRef()) const; + /// Additional verification for transactions in blocks. + virtual void verifyTransaction(ImportRequirements::value _ir, TransactionBase const& _t, BlockHeader const& _bi) const; + /// Don't forget to call Super::populateFromParent when subclassing & overriding. + virtual void populateFromParent(BlockHeader& _bi, BlockHeader const& _parent) const; + + bytes option(std::string const& _name) const { Guard l(x_options); return m_options.count(_name) ? m_options.at(_name) : bytes(); } + bool setOption(std::string const& _name, bytes const& _value) { Guard l(x_options); try { if (onOptionChanging(_name, _value)) { m_options[_name] = _value; return true; } } catch (...) {} return false; } + + virtual strings sealers() const { return { "default" }; } + virtual std::string sealer() const { return "default"; } + virtual void setSealer(std::string const&) {} + + virtual bool shouldSeal(Interface*) { return true; } + virtual void generateSeal(BlockHeader const& _bi, bytes const& _block_data = bytes()) = 0; + virtual void onSealGenerated(std::function const& _f) = 0; + virtual void cancelGeneration() {} + + virtual void setIntervalBlockTime(u256 _time) { m_intervalBlockTime = _time;} + virtual u256 getIntervalBlockTime() {return m_intervalBlockTime;} + + ChainOperationParams const& chainParams() const { return m_params; } + void setChainParams(ChainOperationParams const& _params) { m_params = _params; } + SealEngineFace* withChainParams(ChainOperationParams const& _params) { setChainParams(_params); return this; } + virtual EVMSchedule const& evmSchedule(EnvInfo const&) const { return DefaultSchedule; } + + virtual bool isPrecompiled(Address const& _a) const { return m_params.precompiled.count(_a); } + virtual bigint costOfPrecompiled(Address const& _a, bytesConstRef _in) const { return m_params.precompiled.at(_a).cost(_in); } + virtual void executePrecompiled(Address const& _a, bytesConstRef _in, bytesRef _out) const { return m_params.precompiled.at(_a).execute(_in, _out); } + +protected: + virtual bool onOptionChanging(std::string const&, bytes const&) { return true; } + void injectOption(std::string const& _name, bytes const& _value) { Guard l(x_options); m_options[_name] = _value; } + u256 m_intervalBlockTime = 1000; + +private: + mutable Mutex x_options; + std::unordered_map m_options; + + ChainOperationParams m_params; +}; + +class SealEngineBase: public SealEngineFace +{ +public: + virtual void generateSeal(BlockHeader const& _bi, bytes const& ) override + { + RLPStream ret; + _bi.streamRLP(ret); + if (m_onSealGenerated) + m_onSealGenerated(ret.out()); + } + void onSealGenerated(std::function const& _f) override { m_onSealGenerated = _f; } + EVMSchedule const& evmSchedule(EnvInfo const&) const override; + +protected: + std::function m_onSealGenerated; +}; + +using SealEngineFactory = std::function; + +class SealEngineRegistrar +{ +public: + /// Creates the seal engine and uses it to "polish" the params (i.e. fill in implicit values) as necessary. Use this rather than the other two + /// unless you *know* that the params contain all information regarding the seal on the Genesis block. + static SealEngineFace* create(ChainOperationParams const& _params); + static SealEngineFace* create(std::string const& _name) { if (!get()->m_sealEngines.count(_name)) return nullptr; return get()->m_sealEngines[_name](); } + + template static SealEngineFactory registerSealEngine(std::string const& _name) { return (get()->m_sealEngines[_name] = []() {return new SealEngine;}); } + static void unregisterSealEngine(std::string const& _name) { get()->m_sealEngines.erase(_name); } + +private: + static SealEngineRegistrar* get() { if (!s_this) s_this = new SealEngineRegistrar; return s_this; } + + std::unordered_map m_sealEngines; + static SealEngineRegistrar* s_this; +}; + +#define ETH_REGISTER_SEAL_ENGINE(Name) static SealEngineFactory __eth_registerSealEngineFactory ## Name = SealEngineRegistrar::registerSealEngine(#Name) + +class NoProof: public eth::SealEngineBase +{ +public: + std::string name() const override { return "NoProof"; } + static void init(); +}; + +} +} diff --git a/libethcore/Transaction.cpp b/libethcore/Transaction.cpp new file mode 100644 index 0000000000..31b46297bd --- /dev/null +++ b/libethcore/Transaction.cpp @@ -0,0 +1,205 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file TransactionBase.cpp + * @author Gav Wood + * @date 2014 + */ + +#include + +#include +#include +#include +#include +#include "Transaction.h" +#include + +using namespace std; +using namespace dev; +using namespace dev::eth; + +u256 TransactionBase::maxGas=20000000;//默认二千万 + +TransactionBase::TransactionBase(TransactionSkeleton const& _ts, Secret const& _s): + m_type(_ts.creation ? ContractCreation : MessageCall), + m_randomid(_ts.randomid), + m_value(_ts.value), + m_receiveAddress(_ts.to), + m_gasPrice(_ts.gasPrice), + m_gas(_ts.gas), + m_blockLimit(_ts.blockLimit), + m_data(_ts.data), + m_sender(_ts.from) +{ + if (_s) + sign(_s); +} + +TransactionBase::TransactionBase(bytesConstRef _rlpData, CheckTransaction _checkSig) +{ + + int field = 0; + RLP rlp(_rlpData); + try + { + if (!rlp.isList()) + BOOST_THROW_EXCEPTION(InvalidTransactionFormat() << errinfo_comment("transaction RLP must be a list")); + + + m_randomid = rlp[field = 0].toInt(); + m_gasPrice = rlp[field = 1].toInt(); + m_gas = rlp[field = 2].toInt(); + m_blockLimit = rlp[field = 3].toInt();//新加的 + m_type = rlp[field = 4].isEmpty() ? ContractCreation : MessageCall; + m_receiveAddress = rlp[field = 4].isEmpty() ? Address() : rlp[field = 4].toHash
(RLP::VeryStrict); + m_value = rlp[field = 5].toInt(); + + if (!rlp[field = 6].isData()) + BOOST_THROW_EXCEPTION(InvalidTransactionFormat() << errinfo_comment("transaction data RLP must be an array")); + + + + m_data = rlp[field = 6].toBytes(); + + byte v = rlp[field = 7].toInt(); + h256 r = rlp[field = 8].toInt(); + h256 s = rlp[field = 9].toInt(); + + if (v > 36) + m_chainId = (v - 35) / 2; + else if (v == 27 || v == 28) + m_chainId = -4; + else + BOOST_THROW_EXCEPTION(InvalidSignature()); + + v = v - (m_chainId * 2 + 35); + + if (rlp.itemCount() > 10) + BOOST_THROW_EXCEPTION(InvalidTransactionFormat() << errinfo_comment("to many fields in the transaction RLP")); + + m_vrs = SignatureStruct{ r, s, v }; + if (_checkSig >= CheckTransaction::Cheap && !m_vrs.isValid()){ + + BOOST_THROW_EXCEPTION(InvalidSignature()); + } + + if (_checkSig == CheckTransaction::Everything){ + + m_sender = sender(); + } + + } + catch (Exception& _e) + { + _e << errinfo_name("invalid transaction format: " + toString(rlp) + " RLP: " + toHex(rlp.data())); + throw; + } +} + +Address const& TransactionBase::safeSender() const noexcept +{ + try + { + return sender(); + } + catch (...) + { + return ZeroAddress; + } +} + +Address const& TransactionBase::sender() const +{ + + if (!m_sender) + { + auto p = recover(m_vrs, sha3(WithoutSignature)); + + if (!p) + BOOST_THROW_EXCEPTION(InvalidSignature()); + m_sender = right160(dev::sha3(bytesConstRef(p.data(), sizeof(p)))); + + } + + return m_sender; +} + +void TransactionBase::sign(Secret const& _priv) +{ + auto sig = dev::sign(_priv, sha3(WithoutSignature)); + SignatureStruct sigStruct = *(SignatureStruct const*)&sig; + if (sigStruct.isValid()) + m_vrs = sigStruct; +} + +void TransactionBase::streamRLP(RLPStream& _s, IncludeSignature _sig, bool _forEip155hash) const +{ + if (m_type == NullTransaction) + return; + + _s.appendList((_sig || _forEip155hash ? 3 : 0) + 7); + _s << m_randomid << m_gasPrice << m_gas<< m_blockLimit;//这里加入新字段 + if (m_type == MessageCall) + _s << m_receiveAddress; + else + _s << ""; + _s << m_value << m_data; + + if (_sig) + { + int vOffset = m_chainId*2 + 35; + _s << (m_vrs.v + vOffset) << (u256)m_vrs.r << (u256)m_vrs.s; + } + else if (_forEip155hash) + _s << m_chainId << 0 << 0; +} + +static const u256 c_secp256k1n("115792089237316195423570985008687907852837564279074904382605163141518161494337"); + +void TransactionBase::checkLowS() const +{ + if (m_vrs.s > c_secp256k1n / 2) + BOOST_THROW_EXCEPTION(InvalidSignature()); +} + +void TransactionBase::checkChainId(int chainId) const +{ + if (m_chainId != chainId && m_chainId != -4) + BOOST_THROW_EXCEPTION(InvalidSignature()); +} + +bigint TransactionBase::gasRequired(bool _contractCreation, bytesConstRef _data, EVMSchedule const& _es, u256 const& _gas) +{ + bigint ret = (_contractCreation ? _es.txCreateGas : _es.txGas) + _gas; + for (auto i: _data) + ret += i ? _es.txDataNonZeroGas : _es.txDataZeroGas; + return ret; +} + +h256 TransactionBase::sha3(IncludeSignature _sig) const +{ + if (_sig == WithSignature && m_hashWith) + return m_hashWith; + + RLPStream s; + streamRLP(s, _sig, m_chainId > 0 && _sig == WithoutSignature); + + auto ret = dev::sha3(s.out()); + if (_sig == WithSignature) + m_hashWith = ret; + return ret; +} diff --git a/libethcore/Transaction.h b/libethcore/Transaction.h new file mode 100644 index 0000000000..3c0389ee4f --- /dev/null +++ b/libethcore/Transaction.h @@ -0,0 +1,211 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file TransactionBase.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include +#include + +namespace dev +{ +namespace eth +{ + +struct EVMSchedule; + +/// Named-boolean type to encode whether a signature be included in the serialisation process. +enum IncludeSignature +{ + WithoutSignature = 0, ///< Do not include a signature. + WithSignature = 1, ///< Do include a signature. +}; + +enum class CheckTransaction +{ + None, + Cheap, + Everything +}; + +/// Encodes a transaction, ready to be exported to or freshly imported from RLP. +class TransactionBase +{ +public: + static u256 maxGas; //默认交易最大gas + /// Constructs a null transaction. + TransactionBase() {} + + /// Constructs a transaction from a transaction skeleton & optional secret. + TransactionBase(TransactionSkeleton const& _ts, Secret const& _s = Secret()); + + /// Constructs a signed message-call transaction. + TransactionBase(u256 const& _value, u256 const& _gasPrice, u256 const& _gas, Address const& _dest, bytes const& _data, u256 const& _randomid, Secret const& _secret): m_type(MessageCall), m_randomid(_randomid), m_value(_value), m_receiveAddress(_dest), m_gasPrice(_gasPrice), m_gas(_gas), m_data(_data) { sign(_secret); } + + /// Constructs a signed contract-creation transaction. + TransactionBase(u256 const& _value, u256 const& _gasPrice, u256 const& _gas, bytes const& _data, u256 const& _randomid, Secret const& _secret): m_type(ContractCreation), m_randomid(_randomid), m_value(_value), m_gasPrice(_gasPrice), m_gas(_gas), m_data(_data) { sign(_secret); } + + /// Constructs an unsigned message-call transaction. + TransactionBase(u256 const& _value, u256 const& _gasPrice, u256 const& _gas, Address const& _dest, bytes const& _data, u256 const& _randomid = 0): m_type(MessageCall), m_randomid(_randomid), m_value(_value), m_receiveAddress(_dest), m_gasPrice(_gasPrice), m_gas(_gas), m_data(_data) {} + + /// Constructs an unsigned contract-creation transaction. + TransactionBase(u256 const& _value, u256 const& _gasPrice, u256 const& _gas, bytes const& _data, u256 const& _randomid = 0): m_type(ContractCreation), m_randomid(_randomid), m_value(_value), m_gasPrice(_gasPrice), m_gas(_gas), m_data(_data) {} + + /// Constructs a transaction from the given RLP. + explicit TransactionBase(bytesConstRef _rlp, CheckTransaction _checkSig); + + /// Constructs a transaction from the given RLP. + explicit TransactionBase(bytes const& _rlp, CheckTransaction _checkSig): TransactionBase(&_rlp, _checkSig) {} + + /// Checks equality of transactions. + bool operator==(TransactionBase const& _c) const { return m_type == _c.m_type && (m_type == ContractCreation || m_receiveAddress == _c.m_receiveAddress) && m_value == _c.m_value && m_data == _c.m_data; } + /// Checks inequality of transactions. + bool operator!=(TransactionBase const& _c) const { return !operator==(_c); } + + /// @returns sender of the transaction from the signature (and hash). + Address const& sender() const; + /// Like sender() but will never throw. @returns a null Address if the signature is invalid. + Address const& safeSender() const noexcept; + /// Force the sender to a particular value. This will result in an invalid transaction RLP. + void forceSender(Address const& _a) { m_sender = _a; } + + /// @throws InvalidSValue if the signature has an invalid S value. + void checkLowS() const; + + /// @throws InvalidSValue if the chain id is neither -4 nor equal to @a chainId + /// Note that "-4" is the chain ID of the pre-155 rules, which should also be considered valid + /// after EIP155 + void checkChainId(int chainId = -4) const; + + /// @returns true if transaction is non-null. + explicit operator bool() const { return m_type != NullTransaction; } + + /// @returns true if transaction is contract-creation. + bool isCreation() const { return m_type == ContractCreation; } + + /// @returns true if transaction is message-call. + bool isMessageCall() const { return m_type == MessageCall; } + + /// Serialises this transaction to an RLPStream. + void streamRLP(RLPStream& _s, IncludeSignature _sig = WithSignature, bool _forEip155hash = false) const; + + /// @returns the RLP serialisation of this transaction. + bytes rlp(IncludeSignature _sig = WithSignature) const { RLPStream s; streamRLP(s, _sig); return s.out(); } + + /// @returns the SHA3 hash of the RLP serialisation of this transaction. + h256 sha3(IncludeSignature _sig = WithSignature) const; + + /// @returns the amount of ETH to be transferred by this (message-call) transaction, in Wei. Synonym for endowment(). + u256 value() const { return m_value; } + /// @returns the amount of ETH to be endowed by this (contract-creation) transaction, in Wei. Synonym for value(). + u256 endowment() const { return m_value; } + + /// @returns the base fee and thus the implied exchange rate of ETH to GAS. + u256 gasPrice() const { return m_gasPrice; } + + /// @returns the total gas to convert, paid for from sender's account. Any unused gas gets refunded once the contract is ended. + u256 gas() const + { + return TransactionBase::maxGas;//注意 + } + + /// @returns the receiving address of the message-call transaction (undefined for contract-creation transactions). + Address receiveAddress() const { return m_receiveAddress; } + + /// Synonym for receiveAddress(). + Address to() const { return m_receiveAddress; } + + /// Synonym for safeSender(). + Address from() const { return safeSender(); } + + /// @returns the data associated with this (message-call) transaction. Synonym for initCode(). + bytes const& data() const { return m_data; } + /// @returns the initialisation code associated with this (contract-creation) transaction. Synonym for data(). + bytes const& initCode() const { return m_data; } + + u256 randomid() const { return m_randomid; } + + /// Sets the nonce to the given value. Clears any signature. + void setRandomid(u256 const& _n) { clearSignature(); m_randomid = _n; } + + u256 blockLimit()const { return m_blockLimit;} + + u256 importTime()const {return m_importtime;} + void setImportTime(u256 _t){m_importtime=_t;} + /// Clears the signature. + void clearSignature() { m_vrs = SignatureStruct(); } + + /// @returns the signature of the transaction. Encodes the sender. + SignatureStruct const& signature() const { return m_vrs; } + + void sign(Secret const& _priv); ///< Sign the transaction. + + /// @returns true if the transaction contains enough gas for the basic payment. + bigint gasRequired(EVMSchedule const& _es, u256 const& _gas = 0) const { return gasRequired(m_type == TransactionBase::ContractCreation, &m_data, _es, _gas); } + + /// Get the fee associated for a transaction with the given data. + static bigint gasRequired(bool _contractCreation, bytesConstRef _data, EVMSchedule const& _es, u256 const& _gas = 0); + +protected: + /// Type of transaction. + enum Type + { + NullTransaction, ///< Null transaction. + ContractCreation, ///< Transaction to create contracts - receiveAddress() is ignored. + MessageCall ///< Transaction to invoke a message call - receiveAddress() is used. + }; + + Type m_type = NullTransaction; ///< Is this a contract-creation transaction or a message-call transaction? + u256 m_randomid; ///< The transaction-count of the sender. + u256 m_value; ///< The amount of ETH to be transferred by this transaction. Called 'endowment' for contract-creation transactions. + Address m_receiveAddress; ///< The receiving address of the transaction. + u256 m_gasPrice; ///< The base fee and thus the implied exchange rate of ETH to GAS. + u256 m_gas; ///< The total gas to convert, paid for from sender's account. Any unused gas gets refunded once the contract is ended. + u256 m_blockLimit; //注意 + bytes m_data; ///< The data associated with the transaction, or the initialiser if it's a creation transaction. + SignatureStruct m_vrs; ///< The signature of the transaction. Encodes the sender. + int m_chainId = -4; ///< EIP155 value for calculating transaction hash https://github.com/ethereum/EIPs/issues/155 + + u256 m_importtime=0; //入队时间 用来排序 + mutable h256 m_hashWith; ///< Cached hash of transaction with signature. + mutable Address m_sender; ///< Cached sender, determined from signature. + mutable bigint m_gasRequired = 0; ///< Memoised amount required for the transaction to run. +}; + +/// Nice name for vector of Transaction. +using TransactionBases = std::vector; + +/// Simple human-readable stream-shift operator. +inline std::ostream& operator<<(std::ostream& _out, TransactionBase const& _t) +{ + _out << _t.sha3().abridged() << "{"; + if (_t.receiveAddress()) + _out << _t.receiveAddress().abridged(); + else + _out << "[CREATE]"; + + _out << "/" << _t.data().size() << "$" << _t.value() << "+" << _t.gas() << "@" << _t.gasPrice(); + _out << "<-" << _t.safeSender().abridged() << " #" << _t.randomid() << "}"; + return _out; +} + +} +} diff --git a/libethereum/Account.cpp b/libethereum/Account.cpp new file mode 100644 index 0000000000..9a3b8d74c0 --- /dev/null +++ b/libethereum/Account.cpp @@ -0,0 +1,139 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Account.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "Account.h" +#include +#include +#include + +using namespace std; +using namespace dev; +using namespace dev::eth; + +void Account::setNewCode(bytes&& _code) +{ + m_codeCache = std::move(_code); + m_hasNewCode = true; + m_codeHash = sha3(m_codeCache); +} + +namespace js = json_spirit; + +uint64_t toUnsigned(js::mValue const& _v) +{ + switch (_v.type()) + { + case js::int_type: return _v.get_uint64(); + case js::str_type: return fromBigEndian(fromHex(_v.get_str())); + default: return 0; + } +} + +AccountMap dev::eth::jsonToAccountMap(std::string const& _json, u256 const& _defaultNonce, AccountMaskMap* o_mask, PrecompiledContractMap* o_precompiled) +{ + auto u256Safe = [](std::string const& s) -> u256 { + bigint ret(s); + if (ret >= bigint(1) << 256) + BOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("State value is equal or greater than 2**256") ); + return (u256)ret; + }; + + std::unordered_map ret; + + js::mValue val; + json_spirit::read_string(_json, val); + js::mObject o = val.get_obj(); + for (auto const& account: o.count("alloc") ? o["alloc"].get_obj() : o.count("accounts") ? o["accounts"].get_obj() : o) + { + Address a(fromHex(account.first)); + auto o = account.second.get_obj(); + + bool haveBalance = (o.count("wei") || o.count("finney") || o.count("balance")); + bool haveNonce = o.count("nonce"); + bool haveCode = o.count("code"); + bool haveStorage = o.count("storage"); + bool shouldNotExists = o.count("shouldnotexist"); + + if (haveStorage || haveCode || haveNonce || haveBalance) + { + u256 balance = 0; + if (o.count("wei")) + balance = u256Safe(o["wei"].get_str()); + else if (o.count("finney")) + balance = u256Safe(o["finney"].get_str()) * finney; + else if (o.count("balance")) + balance = u256Safe(o["balance"].get_str()); + + u256 nonce = haveNonce ? u256Safe(o["nonce"].get_str()) : _defaultNonce; + + if (haveCode) + { + ret[a] = Account(nonce, balance); + if (o["code"].type() == json_spirit::str_type) + { + if (o["code"].get_str().find("0x") != 0) + LOG(ERROR) << "Error importing code of account " << a << "! Code needs to be hex bytecode prefixed by \"0x\"."; + else + ret[a].setNewCode(fromHex(o["code"].get_str().substr(2))); + } + else + LOG(ERROR) << "Error importing code of account " << a << "! Code field needs to be a string"; + } + else + ret[a] = Account(nonce, balance); + + if (haveStorage) + for (pair const& j: o["storage"].get_obj()) + ret[a].setStorage(u256(j.first), u256(j.second.get_str())); + } + + if (o_mask) + { + (*o_mask)[a] = AccountMask(haveBalance, haveNonce, haveCode, haveStorage, shouldNotExists); + if (!haveStorage && !haveCode && !haveNonce && !haveBalance && shouldNotExists) //defined only shouldNotExists field + ret[a] = Account(0, 0); + } + + if (o_precompiled && o.count("precompiled")) + { + js::mObject p = o["precompiled"].get_obj(); + auto n = p["name"].get_str(); + try + { + if (p.count("linear")) + { + auto l = p["linear"].get_obj(); + unsigned base = toUnsigned(l["base"]); + unsigned word = toUnsigned(l["word"]); + o_precompiled->insert(make_pair(a, PrecompiledContract(base, word, PrecompiledRegistrar::executor(n)))); + } + } + catch (ExecutorNotFound) + { + // Oh dear - missing a plugin? + LOG(WARNING) << "Couldn't create a precompiled contract account. Missing an executor called:" << n; + throw; + } + } + } + + return ret; +} diff --git a/libethereum/Account.h b/libethereum/Account.h new file mode 100644 index 0000000000..c481936819 --- /dev/null +++ b/libethereum/Account.h @@ -0,0 +1,248 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Account.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace dev +{ +namespace eth +{ + +/** + * Models the state of a single Ethereum account. + * Used to cache a portion of the full Ethereum state. State keeps a mapping of Address's to Accounts. + * + * Aside from storing the nonce and balance, the account may also be "dead" (where isAlive() returns false). + * This allows State to explicitly store the notion of a deleted account in it's cache. kill() can be used + * for this. + * + * For the account's storage, the class operates a cache. baseRoot() specifies the base state of the storage + * given as the Trie root to be looked up in the state database. Alterations beyond this base are specified + * in the overlay, stored in this class and retrieved with storageOverlay(). setStorage allows the overlay + * to be altered. + * + * The code handling explicitly supports a two-stage commit model needed for contract-creation. When creating + * a contract (running the initialisation code), the code of the account is considered empty. The attribute + * of emptiness can be retrieved with codeBearing(). After initialisation one must set the code accordingly; + * the code of the Account can be set with setCode(). To validate a setCode() call, this class records the + * state of being in contract-creation (and thus in a state where setCode may validly be called). It can be + * determined through isFreshCode(). + * + * The code can be retrieved through code(), and its hash through codeHash(). codeHash() is only valid when + * the account is not in the contract-creation phase (i.e. when isFreshCode() returns false). This class + * supports populating code on-demand from the state database. To determine if the code has been prepopulated + * call codeCacheValid(). To populate the code, look it up with codeHash() and populate with noteCode(). + * + * @todo: need to make a noteCodeCommitted(). + * + * The constructor allows you to create an one of a number of "types" of accounts. The default constructor + * makes a dead account (this is ignored by State when writing out the Trie). Another three allow a basic + * or contract account to be specified along with an initial balance. The fina two allow either a basic or + * a contract account to be created with arbitrary values. + */ +class Account +{ +public: + /// Changedness of account to create. + enum Changedness + { + /// Account starts as though it has been changed. + Changed, + /// Account starts as though it has not been changed. + Unchanged + }; + + /// Construct a dead Account. + Account() {} + + /// Construct an alive Account, with given endowment, for either a normal (non-contract) account or for a + /// contract account in the + /// conception phase, where the code is not yet known. + Account(u256 _nonce, u256 _balance, Changedness _c = Changed): m_isAlive(true), m_isUnchanged(_c == Unchanged), m_nonce(_nonce), m_balance(_balance) {} + + /// Explicit constructor for wierd cases of construction or a contract account. + Account(u256 _nonce, u256 _balance, h256 _contractRoot, h256 _codeHash, Changedness _c): m_isAlive(true), m_isUnchanged(_c == Unchanged), m_nonce(_nonce), m_balance(_balance), m_storageRoot(_contractRoot), m_codeHash(_codeHash) { assert(_contractRoot); } + + + /// Kill this account. Useful for the suicide opcode. Following this call, isAlive() returns false. + void kill() { m_isAlive = false; m_storageOverlay.clear(); m_codeHash = EmptySHA3; m_storageRoot = EmptyTrie; m_balance = 0; m_nonce = 0; changed(); } + + /// @returns true iff this object represents an account in the state. Returns false if this object + /// represents an account that should no longer exist in the trie (an account that never existed or was + /// suicided). + bool isAlive() const { return m_isAlive; } + + /// @returns true if the account is unchanged from creation. + bool isDirty() const { return !m_isUnchanged; } + + void untouch() { m_isUnchanged = true; } + + /// @returns true if the nonce, balance and code is zero / empty. Code is considered empty + /// during creation phase. + bool isEmpty() const { return nonce() == 0 && balance() == 0 && codeHash() == EmptySHA3; } + + /// @returns the balance of this account. + u256 const& balance() const { return m_balance; } + + /// Increments the balance of this account by the given amount. + void addBalance(u256 _value) { m_balance += _value; changed(); } + + /// @returns the nonce of the account. + u256 nonce() const { return m_nonce; } + + /// Increment the nonce of the account by one. + void incNonce() { ++m_nonce; changed(); } + + /// Set nonce to a new value. This is used when reverting changes made to + /// the account. + void setNonce(u256 const& _nonce) { m_nonce = _nonce; changed(); } + + + /// @returns the root of the trie (whose nodes are stored in the state db externally to this class) + /// which encodes the base-state of the account's storage (upon which the storage is overlaid). + h256 baseRoot() const { assert(m_storageRoot); return m_storageRoot; } + + /// @returns the storage overlay as a simple hash map. + std::unordered_map const& storageOverlay() const { return m_storageOverlay; } + + /// Set a key/value pair in the account's storage. This actually goes into the overlay, for committing + /// to the trie later. + void setStorage(u256 _p, u256 _v) { m_storageOverlay[_p] = _v; changed(); } + + /// Set a key/value pair in the account's storage to a value that is already present inside the + /// database. + void setStorageCache(u256 _p, u256 _v) const { const_cast(m_storageOverlay)[_p] = _v; } + + /// @returns the hash of the account's code. + h256 codeHash() const { return m_codeHash; } + + bool hasNewCode() const { return m_hasNewCode; } + + /// Sets the code of the account. Used by "create" messages. + void setNewCode(bytes&& _code); + + /// Reset the code set by previous CREATE message. + void resetCode() { m_codeCache.clear(); m_hasNewCode = false; m_codeHash = EmptySHA3; } + + /// Specify to the object what the actual code is for the account. @a _code must have a SHA3 equal to + /// codeHash() and must only be called when isFreshCode() returns false. + void noteCode(bytesConstRef _code) { assert(sha3(_code) == m_codeHash); m_codeCache = _code.toBytes(); } + + /// @returns the account's code. + bytes const& code() const { return m_codeCache; } + +private: + /// Note that we've altered the account. + void changed() { m_isUnchanged = false; } + + /// Is this account existant? If not, it represents a deleted account. + bool m_isAlive = false; + + /// True if we've not made any alteration to the account having been given it's properties directly. + bool m_isUnchanged = false; + + /// True if new code was deployed to the account + bool m_hasNewCode = false; + + /// Account's nonce. + u256 m_nonce; + + /// Account's balance. + u256 m_balance = 0; + + /// The base storage root. Used with the state DB to give a base to the storage. m_storageOverlay is + /// overlaid on this and takes precedence for all values set. + h256 m_storageRoot = EmptyTrie; + + /** If c_contractConceptionCodeHash then we're in the limbo where we're running the initialisation code. + * We expect a setCode() at some point later. + * If EmptySHA3, then m_code, which should be empty, is valid. + * If anything else, then m_code is valid iff it's not empty, otherwise, State::ensureCached() needs to + * be called with the correct args. + */ + h256 m_codeHash = EmptySHA3; + + /// The map with is overlaid onto whatever storage is implied by the m_storageRoot in the trie. + std::unordered_map m_storageOverlay; + + /// The associated code for this account. The SHA3 of this should be equal to m_codeHash unless m_codeHash + /// equals c_contractConceptionCodeHash. + bytes m_codeCache; + + /// Value for m_codeHash when this account is having its code determined. + static const h256 c_contractConceptionCodeHash; +}; + +class AccountMask +{ +public: + AccountMask(bool _all = false): + m_hasBalance(_all), + m_hasNonce(_all), + m_hasCode(_all), + m_hasStorage(_all) + {} + + AccountMask( + bool _hasBalance, + bool _hasNonce, + bool _hasCode, + bool _hasStorage, + bool _shouldNotExist = false + ): + m_hasBalance(_hasBalance), + m_hasNonce(_hasNonce), + m_hasCode(_hasCode), + m_hasStorage(_hasStorage), + m_shouldNotExist(_shouldNotExist) + {} + + bool allSet() const { return m_hasBalance && m_hasNonce && m_hasCode && m_hasStorage; } + bool hasBalance() const { return m_hasBalance; } + bool hasNonce() const { return m_hasNonce; } + bool hasCode() const { return m_hasCode; } + bool hasStorage() const { return m_hasStorage; } + bool shouldExist() const { return !m_shouldNotExist; } + +private: + bool m_hasBalance; + bool m_hasNonce; + bool m_hasCode; + bool m_hasStorage; + bool m_shouldNotExist = false; +}; + +using AccountMap = std::unordered_map; +using AccountMaskMap = std::unordered_map; + +class PrecompiledContract; +using PrecompiledContractMap = std::unordered_map; + +AccountMap jsonToAccountMap(std::string const& _json, u256 const& _defaultNonce = 0, AccountMaskMap* o_mask = nullptr, PrecompiledContractMap* o_precompiled = nullptr); + +} +} diff --git a/libethereum/All.h b/libethereum/All.h new file mode 100644 index 0000000000..586a933279 --- /dev/null +++ b/libethereum/All.h @@ -0,0 +1,14 @@ +#pragma once + +#include "Account.h" +#include "Client.h" +#include "Defaults.h" +#include "Executive.h" +#include "ExtVM.h" +#include "CommonNet.h" +#include "EthereumHost.h" +#include "EthereumPeer.h" +#include "State.h" +#include "Transaction.h" +#include "TransactionQueue.h" +#include "Utility.h" diff --git a/libethereum/BasicGasPricer.cpp b/libethereum/BasicGasPricer.cpp new file mode 100644 index 0000000000..94a36a88e6 --- /dev/null +++ b/libethereum/BasicGasPricer.cpp @@ -0,0 +1,100 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file BasicGasPricer.cpp + * @author Gav Wood + * @date 2015 + */ + +#pragma warning(push) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#include +#pragma warning(pop) +#pragma GCC diagnostic pop +#include "BasicGasPricer.h" +#include "BlockChain.h" +using namespace std; +using namespace dev; +using namespace dev::eth; + +void BasicGasPricer::update(BlockChain const& _bc) +{ + unsigned c = 0; + h256 p = _bc.currentHash(); + m_gasPerBlock = _bc.info(p).gasLimit(); + + map dist; + u256 total = 0; + + // make gasPrice versus gasUsed distribution for the last 1000 blocks + while (c < 1000 && p) + { + BlockHeader bi = _bc.info(p); + if (bi.transactionsRoot() != EmptyTrie) + { + auto bb = _bc.block(p); + RLP r(bb); + BlockReceipts brs(_bc.receipts(bi.hash())); + size_t i = 0; + for (auto const& tr: r[1]) + { + Transaction tx(tr.data(), CheckTransaction::None); + u256 gu = brs.receipts[i].gasUsed(); + dist[tx.gasPrice()] += gu; + total += gu; + i++; + } + } + p = bi.parentHash(); + ++c; + } + + // fill m_octiles with weighted gasPrices + if (total > 0) + { + m_octiles[0] = dist.begin()->first; + + // calc mean + u256 mean = 0; + for (auto const& i: dist) + mean += i.first * i.second; + mean /= total; + + // calc standard deviation + u256 sdSquared = 0; + for (auto const& i: dist) + sdSquared += i.second * (i.first - mean) * (i.first - mean); + sdSquared /= total; + + if (sdSquared) + { + long double sd = sqrt(sdSquared.convert_to()); + long double normalizedSd = sd / mean.convert_to(); + + // calc octiles normalized to gaussian distribution + boost::math::normal gauss(1.0, (normalizedSd > 0.01) ? normalizedSd : 0.01); + for (size_t i = 1; i < 8; i++) + m_octiles[i] = u256(mean.convert_to() * boost::math::quantile(gauss, i / 8.0)); + m_octiles[8] = dist.rbegin()->first; + } + else + { + for (size_t i = 0; i < 9; i++) + m_octiles[i] = (i + 1) * mean / 5; + } + } +} diff --git a/libethereum/BasicGasPricer.h b/libethereum/BasicGasPricer.h new file mode 100644 index 0000000000..00dc8ca558 --- /dev/null +++ b/libethereum/BasicGasPricer.h @@ -0,0 +1,53 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file BasicGasPricer.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include "GasPricer.h" + +namespace dev +{ +namespace eth +{ + +class BasicGasPricer: public GasPricer +{ +public: + explicit BasicGasPricer(u256 _weiPerRef, u256 _refsPerBlock): m_weiPerRef(_weiPerRef), m_refsPerBlock(_refsPerBlock) {} + + void setRefPrice(u256 _weiPerRef) { if ((bigint)m_refsPerBlock * _weiPerRef > std::numeric_limits::max() ) BOOST_THROW_EXCEPTION(Overflow() << errinfo_comment("ether price * block fees is larger than 2**256-1, choose a smaller number.") ); else m_weiPerRef = _weiPerRef; } + void setRefBlockFees(u256 _refsPerBlock) { if ((bigint)m_weiPerRef * _refsPerBlock > std::numeric_limits::max() ) BOOST_THROW_EXCEPTION(Overflow() << errinfo_comment("ether price * block fees is larger than 2**256-1, choose a smaller number.") ); else m_refsPerBlock = _refsPerBlock; } + + u256 ask(Block const&) const override { return m_weiPerRef * m_refsPerBlock / m_gasPerBlock; } + u256 bid(TransactionPriority _p = TransactionPriority::Medium) const override { return m_octiles[(int)_p] > 0 ? m_octiles[(int)_p] : (m_weiPerRef * m_refsPerBlock / m_gasPerBlock); } + + void update(BlockChain const& _bc) override; + +private: + u256 m_weiPerRef; + u256 m_refsPerBlock; + u256 m_gasPerBlock = DefaultBlockGasLimit; + std::array m_octiles; +}; + +} +} diff --git a/libethereum/Block.cpp b/libethereum/Block.cpp new file mode 100644 index 0000000000..38b29fca71 --- /dev/null +++ b/libethereum/Block.cpp @@ -0,0 +1,1120 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Block.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "Block.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "BlockChain.h" +#include "Defaults.h" +#include "ExtVM.h" +#include "Executive.h" +#include "BlockChain.h" +#include "TransactionQueue.h" + +#include "SystemContractApi.h" +#include + +using namespace std; +using namespace dev; +using namespace dev::eth; +namespace fs = boost::filesystem; + +#define ETH_TIMED_ENACTMENTS 0 + +unsigned Block::c_maxSyncTransactions = 100; + +const char* BlockSafeExceptions::name() { return EthViolet "?" EthBlue " ?"; } +const char* BlockDetail::name() { return EthViolet "?" EthWhite " ?"; } +const char* BlockTrace::name() { return EthViolet "?" EthGray " ◎"; } +const char* BlockChat::name() { return EthViolet "?" EthWhite " ?"; } + +Block::Block(BlockChain const& _bc, OverlayDB const& _db, BaseState _bs, Address const& _author): + m_state(Invalid256, _db, _bs), + m_precommit(Invalid256), + m_author(_author) +{ + noteChain(_bc); + m_previousBlock.clear(); + m_currentBlock.clear(); + +} + +Block::Block(BlockChain const& _bc, OverlayDB const& _db, h256 const& _root, Address const& _author): + m_state(Invalid256, _db, BaseState::PreExisting), + m_precommit(Invalid256), + m_author(_author) +{ + noteChain(_bc); + m_state.setRoot(_root); + m_previousBlock.clear(); + m_currentBlock.clear(); + +} + +Block::Block(Block const& _s): + m_state(_s.m_state), + m_transactions(_s.m_transactions), + m_receipts(_s.m_receipts), + m_transactionSet(_s.m_transactionSet), + m_precommit(_s.m_state), + m_previousBlock(_s.m_previousBlock), + m_currentBlock(_s.m_currentBlock), + m_currentBytes(_s.m_currentBytes), + m_author(_s.m_author), + m_sealEngine(_s.m_sealEngine) +{ + m_committedToSeal = false; +} + +Block& Block::operator=(Block const& _s) +{ + if (&_s == this) + return *this; + + m_state = _s.m_state; + m_transactions = _s.m_transactions; + m_receipts = _s.m_receipts; + m_transactionSet = _s.m_transactionSet; + m_previousBlock = _s.m_previousBlock; + m_currentBlock = _s.m_currentBlock; + m_currentBytes = _s.m_currentBytes; + m_author = _s.m_author; + m_sealEngine = _s.m_sealEngine; + + m_precommit = m_state; + m_committedToSeal = false; + return *this; +} + +void Block::resetCurrent(u256 const& _timestamp) +{ + m_transactions.clear(); + m_receipts.clear(); + m_transactionSet.clear(); + m_currentBlock = BlockHeader(); + m_currentBlock.setAuthor(m_author); + m_currentBlock.setTimestamp(max(m_previousBlock.timestamp() + 1, _timestamp)); + m_currentBytes.clear(); + + + + sealEngine()->populateFromParent(m_currentBlock, m_previousBlock); + + + m_state.setRoot(m_previousBlock.stateRoot()); + + m_precommit = m_state; + m_committedToSeal = false; + + performIrregularModifications(); +} + +void Block::resetCurrentTime(u256 const& _timestamp) { + m_currentBlock.setTimestamp(max(m_previousBlock.timestamp() + 1, _timestamp)); +} +void Block::setIndex(u256 _idx) { + m_currentBlock.setIndex(_idx); +} +void Block::setNodeList(h512s const& _nodes) { + m_currentBlock.setNodeList(_nodes); +} + +SealEngineFace* Block::sealEngine() const +{ + if (!m_sealEngine) + BOOST_THROW_EXCEPTION(ChainOperationWithUnknownBlockChain()); + return m_sealEngine; +} + +void Block::noteChain(BlockChain const& _bc) +{ + if (!m_sealEngine) + { + m_state.noteAccountStartNonce(_bc.chainParams().accountStartNonce); + m_precommit.noteAccountStartNonce(_bc.chainParams().accountStartNonce); + m_sealEngine = _bc.sealEngine(); + } +} + +bool Block::empty() const +{ + if(!m_transactions.empty()) + return false; + + return m_receipts.empty(); +} + +PopulationStatistics Block::populateFromChain(BlockChain const& _bc, h256 const& _h, ImportRequirements::value _ir) +{ + + noteChain(_bc); + + PopulationStatistics ret { 0.0, 0.0 }; + + if (!_bc.isKnown(_h)) + { + // Might be worth throwing here. + LOG(WARNING) << "Invalid block given for state population: " << _h; + BOOST_THROW_EXCEPTION(BlockNotFound() << errinfo_target(_h)); + } + + auto b = _bc.block(_h); + BlockHeader bi(b); // No need to check - it's already in the DB. + + if (bi.number()) + { + // Non-genesis: + + // 1. Start at parent's end state (state root). + BlockHeader bip(_bc.block(bi.parentHash())); + sync(_bc, bi.parentHash(), bip); + + // 2. Enact the block's transactions onto this state. + m_author = bi.author(); + Timer t; + auto vb = _bc.verifyBlock(&b, function(), _ir | ImportRequirements::TransactionBasic); + ret.verify = t.elapsed(); + t.restart(); + enact(vb, _bc); + ret.enact = t.elapsed(); + } + else + { + // Genesis required: + // We know there are no transactions, so just populate directly. + m_state = State(m_state.accountStartNonce(), m_state.db(), BaseState::Empty); // TODO: try with PreExisting. + sync(_bc, _h, bi); + } + + return ret; +} + +bool Block::sync(BlockChain const& _bc) +{ + return sync(_bc, _bc.currentHash()); +} + +bool Block::sync(BlockChain const& _bc, h256 const& _block, BlockHeader const& _bi) +{ + noteChain(_bc); + + bool ret = false; + // BLOCK + BlockHeader bi = _bi ? _bi : _bc.info(_block); +#if ETH_PARANOIA + if (!bi) + while (1) + { + try + { + auto b = _bc.block(_block); + bi.populate(b); + break; + } + catch (Exception const& _e) + { + // TODO: Slightly nicer handling? :-) + LOG(ERROR) << "ERROR: Corrupt block-chain! Delete your block-chain DB and restart." << endl; + LOG(ERROR) << diagnostic_information(_e) << endl; + } + catch (std::exception const& _e) + { + // TODO: Slightly nicer handling? :-) + LOG(ERROR) << "ERROR: Corrupt block-chain! Delete your block-chain DB and restart." << endl; + LOG(ERROR) << _e.what() << endl; + } + } +#endif + if (bi == m_currentBlock) + { + + // We mined the last block. + // Our state is good - we just need to move on to next. + m_previousBlock = m_currentBlock; + resetCurrent(); + ret = true; + } + else if (bi == m_previousBlock) + { + // No change since last sync. + // Carry on as we were. + } + else + { + // New blocks available, or we've switched to a different branch. All change. + // Find most recent state dump and replay what's left. + // (Most recent state dump might end up being genesis.) + if (m_state.db().lookup(bi.stateRoot()).empty()) // TODO: API in State for this? + { + LOG(WARNING) << "Unable to sync to" << bi.hash() << "; state root" << bi.stateRoot() << "not found in database."; + LOG(WARNING) << "Database corrupt: contains block without stateRoot:" << bi; + LOG(WARNING) << "Try rescuing the database by running: eth --rescue"; + BOOST_THROW_EXCEPTION(InvalidStateRoot() << errinfo_target(bi.stateRoot())); + } + m_previousBlock = bi; + resetCurrent(); + ret = true; + } +#if ALLOW_REBUILD + else + { + // New blocks available, or we've switched to a different branch. All change. + // Find most recent state dump and replay what's left. + // (Most recent state dump might end up being genesis.) + + std::vector chain; + while (bi.number() != 0 && m_db.lookup(bi.stateRoot()).empty()) // while we don't have the state root of the latest block... + { + chain.push_back(bi.hash()); // push back for later replay. + bi.populate(_bc.block(bi.parentHash())); // move to parent. + } + + m_previousBlock = bi; + resetCurrent(); + + // Iterate through in reverse, playing back each of the blocks. + try + { + for (auto it = chain.rbegin(); it != chain.rend(); ++it) + { + auto b = _bc.block(*it); + enact(&b, _bc, _ir); + cleanup(true); + } + } + catch (...) + { + // TODO: Slightly nicer handling? :-) + LOG(ERROR) << "ERROR: Corrupt block-chain! Delete your block-chain DB and restart." << endl; + LOG(ERROR) << boost::current_exception_diagnostic_information() << endl; + exit(1); + } + + resetCurrent(); + ret = true; + } +#endif + return ret; +} + +pair Block::sync(BlockChain const& _bc, TransactionQueue& _tq, GasPricer const& _gp, unsigned msTimeout) +{ + LOG(TRACE) << "Block::sync "; + + if (isSealed()) + BOOST_THROW_EXCEPTION(InvalidOperationOnSealedBlock()); + + noteChain(_bc); + + // TRANSACTIONS + pair ret; + + auto ts = _tq.topTransactions(c_maxSyncTransactions, m_transactionSet); + ret.second = (ts.size() == c_maxSyncTransactions); // say there's more to the caller if we hit the limit + + LastHashes lh; + + auto deadline = chrono::steady_clock::now() + chrono::milliseconds(msTimeout); + + for (int goodTxs = max(0, (int)ts.size() - 1); goodTxs < (int)ts.size(); ) + { + goodTxs = 0; + for (auto const& t : ts) + if (!m_transactionSet.count(t.sha3())) + { + try + { + ++goodTxs; + + u256 check = _bc.filterCheck(t, FilterCheckScene::PackTranscation); + if ( (u256)SystemContractCode::Ok != check ) + { + LOG(WARNING) << "Block::sync " << t.sha3() << " transition filterCheck PackTranscation Fail" << check; + BOOST_THROW_EXCEPTION(FilterCheckFail()); + } + + if ( ! _bc.isBlockLimitOk(t) ) + { + LOG(WARNING) << "Block::sync " << t.sha3() << " transition blockLimit=" << t.blockLimit() << " chain number=" << _bc.number(); + BOOST_THROW_EXCEPTION(BlockLimitCheckFail()); + } + + if ( !_bc.isNonceOk(t) ) + { + LOG(WARNING) << "Block::sync " << t.sha3() << " " << t.randomid(); + BOOST_THROW_EXCEPTION(NonceCheckFail()); + } + for ( size_t pIndex = 0; pIndex < m_transactions.size(); pIndex++) + { + if ( (m_transactions[pIndex].from() == t.from() ) && (m_transactions[pIndex].randomid() == t.randomid()) ) + BOOST_THROW_EXCEPTION(NonceCheckFail()); + }//for + + u256 _t = _gp.ask(*this); + + if ( _t ) + _t = 0; + + if (lh.empty()) + lh = _bc.lastHashes(); + + execute(lh, t, Permanence::Committed, OnOpFunc(), &_bc); + ret.first.push_back(m_receipts.back()); + + + } + catch ( FilterCheckFail const& in) + { + LOG(WARNING) << t.sha3() << "Block::sync Dropping transaction (filter check fail!)"; + _tq.drop(t.sha3()); + } + catch ( NoDeployPermission const &in) + { + LOG(WARNING) << t.sha3() << "Block::sync Dropping transaction (NoDeployPermission fail!)"; + _tq.drop(t.sha3()); + } + catch (BlockLimitCheckFail const& in) + { + LOG(WARNING) << t.sha3() << "Block::sync Dropping transaction (blocklimit check fail!)"; + _tq.drop(t.sha3()); + } + catch (NonceCheckFail const& in) + { + LOG(WARNING) << t.sha3() << "Block::sync Dropping transaction (nonce check fail!)"; + _tq.drop(t.sha3()); + } + catch (InvalidNonce const& in) + { + bigint const& req = *boost::get_error_info(in); + bigint const& got = *boost::get_error_info(in); + + if (req > got) + { + // too old + LOG(TRACE) << t.sha3() << "Dropping old transaction (nonce too low)"; + _tq.drop(t.sha3()); + } + else if (got > req + _tq.waiting(t.sender())) + { + // too new + LOG(TRACE) << t.sha3() << "Dropping new transaction (too many nonces ahead)"; + _tq.drop(t.sha3()); + } + else + _tq.setFuture(t.sha3()); + } + catch (BlockGasLimitReached const& e) + { + bigint const& got = *boost::get_error_info(e); + if (got > m_currentBlock.gasLimit()) + { + LOG(TRACE) << t.sha3() << "Dropping over-gassy transaction (gas > block's gas limit)"; + _tq.drop(t.sha3()); + } + else + { + LOG(TRACE) << t.sha3() << "Temporarily no gas left in current block (txs gas > block's gas limit)"; + //_tq.drop(t.sha3()); + // Temporarily no gas left in current block. + // OPTIMISE: could note this and then we don't evaluate until a block that does have the gas left. + // for now, just leave alone. + } + } + catch (Exception const& _e) + { + // Something else went wrong - drop it. + LOG(TRACE) << t.sha3() << "Dropping invalid transaction:" << diagnostic_information(_e); + _tq.drop(t.sha3()); + } + catch (std::exception const&) + { + // Something else went wrong - drop it. + _tq.drop(t.sha3()); + LOG(WARNING) << t.sha3() << "Transaction caused low-level exception :("; + } + } + if (chrono::steady_clock::now() > deadline) + { + ret.second = true; // say there's more to the caller if we ended up crossing the deadline. + break; + } + } + return ret; +} + +u256 Block::enactOn(VerifiedBlockRef const& _block, BlockChain const& _bc) +{ + noteChain(_bc); + +#if ETH_TIMED_ENACTMENTS + Timer t; + double populateVerify; + double populateGrand; + double syncReset; + double enactment; +#endif + + // Check family: + BlockHeader biParent = _bc.info(_block.info.parentHash()); + _block.info.verify(CheckNothingNew/*CheckParent*/, biParent); + +#if ETH_TIMED_ENACTMENTS + populateVerify = t.elapsed(); + t.restart(); +#endif + + BlockHeader biGrandParent; + if (biParent.number()) + biGrandParent = _bc.info(biParent.parentHash()); + +#if ETH_TIMED_ENACTMENTS + populateGrand = t.elapsed(); + t.restart(); +#endif + + sync(_bc, _block.info.parentHash(), BlockHeader()); + resetCurrent(); + +#if ETH_TIMED_ENACTMENTS + syncReset = t.elapsed(); + t.restart(); +#endif + + + m_previousBlock = biParent; + auto ret = enact(_block, _bc, true); + +#if ETH_TIMED_ENACTMENTS + enactment = t.elapsed(); + if (populateVerify + populateGrand + syncReset + enactment > 0.5) + LOG(TRACE) << "popVer/popGrand/syncReset/enactment = " << populateVerify << "/" << populateGrand << "/" << syncReset << "/" << enactment; +#endif + return ret; +} + +u256 Block::enact(VerifiedBlockRef const& _block, BlockChain const& _bc, bool _filtercheck) +{ + noteChain(_bc); + + DEV_TIMED_FUNCTION_ABOVE(500); + + // m_currentBlock is assumed to be prepopulated and reset. +#if !ETH_RELEASE + assert(m_previousBlock.hash() == _block.info.parentHash()); + assert(m_currentBlock.parentHash() == _block.info.parentHash()); +#endif + + if (m_currentBlock.parentHash() != m_previousBlock.hash()) + // Internal client error. + BOOST_THROW_EXCEPTION(InvalidParentHash()); + + // Populate m_currentBlock with the correct values. + m_currentBlock.noteDirty(); + m_currentBlock = _block.info; + + + + LastHashes lh; + DEV_TIMED_ABOVE("lastHashes", 500) + lh = _bc.lastHashes(m_currentBlock.parentHash()); + + RLP rlp(_block.block); + + vector receipts; + + LOG(TRACE) << "Block:enact tx_num=" << _block.transactions.size(); + // All ok with the block generally. Play back the transactions now... + unsigned i = 0; + DEV_TIMED_ABOVE("txExec", 500) + for (Transaction const& tr : _block.transactions) + { + try + { + + LOG(TRACE) << "Enacting transaction: " << tr.randomid() << tr.from() << tr.value() << toString(tr.sha3()); + + execute(lh, tr, Permanence::Committed, OnOpFunc(), (_filtercheck ? (&_bc) : nullptr)); + + } + catch (Exception& ex) + { + + ex << errinfo_transactionIndex(i); + throw; + } + + LOG(TRACE) << "Block::enact: t=" << toString(tr.sha3()); + LOG(TRACE) << "Block::enact: stateRoot=" << toString(m_receipts.back().stateRoot()) << ",gasUsed=" << toString(m_receipts.back().gasUsed()) << ",sha3=" << toString(sha3(m_receipts.back().rlp())); + + RLPStream receiptRLP; + m_receipts.back().streamRLP(receiptRLP); + receipts.push_back(receiptRLP.out()); + ++i; + } + + h256 receiptsRoot; + DEV_TIMED_ABOVE(".receiptsRoot()", 500) + receiptsRoot = orderedTrieRoot(receipts); + + if (receiptsRoot != m_currentBlock.receiptsRoot()) + { + LOG(TRACE) << "Block::enact receiptsRoot" << toString(receiptsRoot) << ",m_currentBlock.receiptsRoot()=" << toString(m_currentBlock.receiptsRoot()) << ",header" << m_currentBlock; + + assert(false); + InvalidReceiptsStateRoot ex; + ex << Hash256RequirementError(receiptsRoot, m_currentBlock.receiptsRoot()); + ex << errinfo_receipts(receipts); + BOOST_THROW_EXCEPTION(ex); + } + + if (m_currentBlock.logBloom() != logBloom()) + { + InvalidLogBloom ex; + ex << LogBloomRequirementError(logBloom(), m_currentBlock.logBloom()); + ex << errinfo_receipts(receipts); + BOOST_THROW_EXCEPTION(ex); + } + + // Initialise total difficulty calculation. + u256 tdIncrease = m_currentBlock.difficulty(); + + // Check uncles & apply their rewards to state. + if (rlp[2].itemCount() > 2) + { + TooManyUncles ex; + ex << errinfo_max(2); + ex << errinfo_got(rlp[2].itemCount()); + BOOST_THROW_EXCEPTION(ex); + } + + vector rewarded; + h256Hash excluded; + DEV_TIMED_ABOVE("allKin", 500) + excluded = _bc.allKinFrom(m_currentBlock.parentHash(), 6); + excluded.insert(m_currentBlock.hash()); + + unsigned ii = 0; + DEV_TIMED_ABOVE("uncleCheck", 500) + for (auto const& i : rlp[2]) + { + try + { + auto h = sha3(i.data()); + if (excluded.count(h)) + { + UncleInChain ex; + ex << errinfo_comment("Uncle in block already mentioned"); + ex << errinfo_unclesExcluded(excluded); + ex << errinfo_hash256(sha3(i.data())); + BOOST_THROW_EXCEPTION(ex); + } + excluded.insert(h); + + // CheckNothing since it's a VerifiedBlock. + BlockHeader uncle(i.data(), HeaderData, h); + + BlockHeader uncleParent; + if (!_bc.isKnown(uncle.parentHash())) + BOOST_THROW_EXCEPTION(UnknownParent() << errinfo_hash256(uncle.parentHash())); + uncleParent = BlockHeader(_bc.block(uncle.parentHash())); + + // m_currentBlock.number() - uncle.number() m_cB.n - uP.n() + // 1 2 + // 2 + // 3 + // 4 + // 5 + // 6 7 + // (8 Invalid) + bigint depth = (bigint)m_currentBlock.number() - (bigint)uncle.number(); + if (depth > 6) + { + UncleTooOld ex; + ex << errinfo_uncleNumber(uncle.number()); + ex << errinfo_currentNumber(m_currentBlock.number()); + BOOST_THROW_EXCEPTION(ex); + } + else if (depth < 1) + { + UncleIsBrother ex; + ex << errinfo_uncleNumber(uncle.number()); + ex << errinfo_currentNumber(m_currentBlock.number()); + BOOST_THROW_EXCEPTION(ex); + } + // cB + // cB.p^1 1 depth, valid uncle + // cB.p^2 ---/ 2 + // cB.p^3 -----/ 3 + // cB.p^4 -------/ 4 + // cB.p^5 ---------/ 5 + // cB.p^6 -----------/ 6 + // cB.p^7 -------------/ + // cB.p^8 + auto expectedUncleParent = _bc.details(m_currentBlock.parentHash()).parent; + for (unsigned i = 1; i < depth; expectedUncleParent = _bc.details(expectedUncleParent).parent, ++i) {} + if (expectedUncleParent != uncleParent.hash()) + { + UncleParentNotInChain ex; + ex << errinfo_uncleNumber(uncle.number()); + ex << errinfo_currentNumber(m_currentBlock.number()); + BOOST_THROW_EXCEPTION(ex); + } + uncle.verify(CheckNothingNew/*CheckParent*/, uncleParent); + + rewarded.push_back(uncle); + ++ii; + } + catch (Exception& ex) + { + ex << errinfo_uncleIndex(ii); + throw; + } + } + + + // Commit all cached state changes to the state trie. + //bool removeEmptyAccounts = m_currentBlock.number() >= _bc.chainParams().u256Param("EIP158ForkBlock"); + + + m_state.commit( State::CommitBehaviour::KeepEmptyAccounts); + DEV_TIMED_ABOVE("commit", 500) + + // Hash the state trie and check against the state_root hash in m_currentBlock. + if (m_currentBlock.stateRoot() != m_previousBlock.stateRoot() && m_currentBlock.stateRoot() != rootHash()) + { + auto r = rootHash(); + m_state.db().rollback(); + LOG(TRACE) << "m_currentBlock.stateRoot()=" << m_currentBlock.stateRoot() << ",m_previousBlock.stateRoot()=" << m_previousBlock.stateRoot() << ",rootHash()=" << rootHash(); + + BOOST_THROW_EXCEPTION(InvalidStateRoot() << Hash256RequirementError(r, m_currentBlock.stateRoot())); + } + + if (m_currentBlock.gasUsed() != gasUsed()) + { + // Rollback the trie. + m_state.db().rollback(); + BOOST_THROW_EXCEPTION(InvalidGasUsed() << RequirementError(bigint(gasUsed()), bigint(m_currentBlock.gasUsed()))); + } + + return tdIncrease; +} + +// will throw exception +ExecutionResult Block::execute(LastHashes const& _lh, Transaction const& _t, Permanence _p, OnOpFunc const& _onOp, BlockChain const *_bcp) +{ + LOG(TRACE) << "Block::execute " << _t.sha3(); + if (isSealed()) + BOOST_THROW_EXCEPTION(InvalidOperationOnSealedBlock()); + + // Uncommitting is a non-trivial operation - only do it once we've verified as much of the + // transaction as possible. + uncommitToSeal(); + + if ( _bcp != nullptr ) + { + u256 check = _bcp->filterCheck(_t, FilterCheckScene::BlockExecuteTransation); + if ( (u256)SystemContractCode::Ok != check ) + { + LOG(WARNING) << "Block::execute " << _t.sha3() << " transition filterCheck Fail" << check; + BOOST_THROW_EXCEPTION(FilterCheckFail()); + } + } + + + if (VMFactory::getKind() == VMKind::Dual) { + + VMFactory::setKind(VMKind::JIT); + + Timer timer; + std::pair JITResultReceipt = m_state.execute(EnvInfo(info(), _lh, gasUsed()), *m_sealEngine, _t, Permanence::Dry, _onOp); + + std::unordered_map JITCache = m_state.getCache(); + m_state.clearCache(); + + VMFactory::setKind(VMKind::Interpreter); + + timer.restart(); + std::pair interpreterResultReceipt = m_state.execute(EnvInfo(info(), _lh, gasUsed()), *m_sealEngine, _t, _p, _onOp); + + std::unordered_map interpreterCache = m_state.getCache(); + + m_state.commit(State::CommitBehaviour::KeepEmptyAccounts); + + VMFactory::setKind(VMKind::Dual); + + + auto lhsResult = interpreterResultReceipt.first; + auto rhsResult = JITResultReceipt.first; + + for (auto lhsAccountIt = interpreterCache.begin(); lhsAccountIt != interpreterCache.end(); ++lhsAccountIt) { + auto rhsAccountIt = JITCache.find(lhsAccountIt->first); + + if (rhsAccountIt == JITCache.end()) { + LOG(WARNING) << "[Dual error]JIT执行缺少Account:" << lhsAccountIt->first; + } + else { + Account &lhs = lhsAccountIt->second; + Account &rhs = rhsAccountIt->second; + + if (lhs.nonce() != rhs.nonce() || lhs.balance() != rhs.balance() || lhs.code() != rhs.code()) { + LOG(WARNING) << "[Dual error]JIT Account与Interpreter Account差异:" << lhsAccountIt->first + << "nonce:" << lhs.nonce() << "," << rhs.nonce() + << "; balance:" << lhs.balance() << "," << rhs.balance() + << "; code:" << lhs.code() << "," << rhs.code(); + } + + auto lhsStorage = lhs.storageOverlay(); + auto rhsStorage = rhs.storageOverlay(); + + for (auto lhsStorageIt = lhsStorage.begin(); lhsStorageIt != lhsStorage.end(); ++lhsStorageIt) { + auto rhsStorageIt = rhsStorage.find(lhsStorageIt->first); + + if (rhsStorageIt == rhsStorage.end()) { + LOG(WARNING) << "[Dual error]JIT缺少Storage key, Account:" << lhsStorageIt->first << "storage key:" << lhsStorageIt->first; + } + else if (lhsStorageIt->second != rhsStorageIt->second) { + LOG(WARNING) << "[Dual error]JIT storage与Interpreter差异 Account:" << lhsStorageIt->first << "JIT:" << lhsStorageIt->second << "Interpreter:" << rhsStorageIt->second; + } + } + } + } + + if (_p == Permanence::Committed) + { + // Add to the user-originated transactions that we've executed. + m_transactions.push_back(_t); + m_receipts.push_back(interpreterResultReceipt.second); + m_transactionSet.insert(_t.sha3()); + + } + + return interpreterResultReceipt.first; + } + + + std::pair resultReceipt = m_state.execute(EnvInfo(info(), _lh, gasUsed(), m_evmCoverLog, m_evmEventLog), *m_sealEngine, _t, _p, _onOp); + + if (_p == Permanence::Committed) + { + // Add to the user-originated transactions that we've executed. + m_transactions.push_back(_t); + LOG(TRACE) << "Block::execute: t=" << toString(_t.sha3()); + m_receipts.push_back(resultReceipt.second); + LOG(TRACE) << "Block::execute: stateRoot=" << toString(resultReceipt.second.stateRoot()) << ",gasUsed=" << toString(resultReceipt.second.gasUsed()) << ",sha3=" << toString(sha3(resultReceipt.second.rlp())); + m_transactionSet.insert(_t.sha3()); + + if (_bcp) { + (_bcp)->updateCache(_t.to()); + } + + } + + return resultReceipt.first; +} + + +void Block::applyRewards(vector const& , u256 const& ) +{ + return ; + +} + +void Block::performIrregularModifications() +{ + +} + +void Block::commitToSeal(BlockChain const& _bc, bytes const& _extraData) +{ + if (isSealed()) + BOOST_THROW_EXCEPTION(InvalidOperationOnSealedBlock()); + + noteChain(_bc); + + if (m_committedToSeal) + uncommitToSeal(); + else + m_precommit = m_state; + + vector uncleBlockHeaders; + + RLPStream unclesData; + unsigned unclesCount = 0; + if (m_previousBlock.number() != 0) + { + // Find great-uncles (or second-cousins or whatever they are) - children of great-grandparents, great-great-grandparents... that were not already uncles in previous generations. + LOG(TRACE) << "Checking " << m_previousBlock.hash() << ", parent=" << m_previousBlock.parentHash(); + h256Hash excluded = _bc.allKinFrom(m_currentBlock.parentHash(), 6); + auto p = m_previousBlock.parentHash(); + for (unsigned gen = 0; gen < 6 && p != _bc.genesisHash() && unclesCount < 2; ++gen, p = _bc.details(p).parent) + { + auto us = _bc.details(p).children; + assert(us.size() >= 1); // must be at least 1 child of our grandparent - it's our own parent! + for (auto const& u : us) + if (!excluded.count(u)) // ignore any uncles/mainline blocks that we know about. + { + uncleBlockHeaders.push_back(_bc.info(u)); + unclesData.appendRaw(_bc.headerData(u)); + ++unclesCount; + if (unclesCount == 2) + break; + excluded.insert(u); + } + } + } + + BytesMap transactionsMap; + BytesMap receiptsMap; + + RLPStream txs; + txs.appendList(m_transactions.size()); + + for (unsigned i = 0; i < m_transactions.size(); ++i) + { + RLPStream k; + k << i; + + RLPStream receiptrlp; + m_receipts[i].streamRLP(receiptrlp); + receiptsMap.insert(std::make_pair(k.out(), receiptrlp.out())); + + RLPStream txrlp; + m_transactions[i].streamRLP(txrlp); + transactionsMap.insert(std::make_pair(k.out(), txrlp.out())); + + txs.appendRaw(txrlp.out()); + + } + + txs.swapOut(m_currentTxs); + + RLPStream(unclesCount).appendRaw(unclesData.out(), unclesCount).swapOut(m_currentUncles); + + DEV_TIMED_ABOVE("commit", 500) + + m_state.commit(State::CommitBehaviour::KeepEmptyAccounts); +/* + LOG(TRACE) << "Post-reward stateRoot:" << m_state.rootHash(); + LOG(TRACE) << m_state; + LOG(TRACE) << *this; +*/ + m_currentBlock.setLogBloom(logBloom()); + m_currentBlock.setGasUsed(gasUsed()); + m_currentBlock.setRoots(hash256(transactionsMap), hash256(receiptsMap), sha3(m_currentUncles), m_state.rootHash()); + + m_currentBlock.setParentHash(m_previousBlock.hash()); + m_currentBlock.setExtraData(_extraData); + if (m_currentBlock.extraData().size() > 32) + { + auto ed = m_currentBlock.extraData(); + ed.resize(32); + m_currentBlock.setExtraData(ed); + } + + m_committedToSeal = true; +} + +void Block::uncommitToSeal() +{ + if (m_committedToSeal) + { + m_state = m_precommit; + m_committedToSeal = false; + } +} + +bool Block::sealBlock(bytesConstRef _header) +{ + return sealBlock(BlockHeader(_header, HeaderData), _header); +} + +bool Block::sealBlock(BlockHeader const& _header, bytesConstRef _headerBytes) { + if (!m_committedToSeal) + return false; + + if (_header.hash(WithoutSeal) != m_currentBlock.hash(WithoutSeal)) + return false; + + LOG(TRACE) << "Sealing block!"; + + // Compile block: + RLPStream ret; + ret.appendList(5); + ret.appendRaw(_headerBytes); + ret.appendRaw(m_currentTxs); + ret.appendRaw(m_currentUncles); + ret.append(m_currentBlock.hash(WithoutSeal)); + std::vector> sig_list; + ret.appendVector(sig_list); + + + ret.swapOut(m_currentBytes); + m_currentBlock = _header; + + m_state = m_precommit; + + return true; +} + +bytes Block::blockBytes() const +{ + cdebug << "Block::blockBytes()"; + BlockHeader header = info(); + + RLPStream h; + header.streamRLP(h); + + RLPStream ret; + ret.appendList(3); + ret.appendRaw(h.out()); + ret.appendRaw(m_currentTxs); + ret.appendRaw(m_currentUncles); + + return ret.out(); +} + + +State Block::fromPending(unsigned _i) const +{ + State ret = m_state; + _i = min(_i, m_transactions.size()); + if (!_i) + ret.setRoot(m_previousBlock.stateRoot()); + else + ret.setRoot(m_receipts[_i - 1].stateRoot()); + return ret; +} + +LogBloom Block::logBloom() const +{ + LogBloom ret; + for (TransactionReceipt const& i : m_receipts) + ret |= i.bloom(); + return ret; +} + +void Block::cleanup(bool _fullCommit) +{ + if (_fullCommit) + { + // Commit the new trie to disk. + if (isChannelVisible()) // Avoid calling toHex if not needed + LOG(TRACE) << "Committing to disk: stateRoot" << m_currentBlock.stateRoot() << "=" << rootHash() << "=" << toHex(asBytes(db().lookup(rootHash()))); + + try + { + EnforceRefs er(db(), true); + rootHash(); + } + catch (BadRoot const&) + { + LOG(TRACE) << "Trie corrupt! :-("; + throw; + } + + m_state.db().commit(); // TODO: State API for this? + + if (isChannelVisible()) // Avoid calling toHex if not needed + LOG(TRACE) << "Committed: stateRoot" << m_currentBlock.stateRoot() << "=" << rootHash() << "=" << toHex(asBytes(db().lookup(rootHash()))); + + + m_previousBlock = m_currentBlock; + sealEngine()->populateFromParent(m_currentBlock, m_previousBlock); + + + LOG(TRACE) << "finalising enactment. current -> previous, hash is" << m_previousBlock.hash(); + } + else + m_state.db().rollback(); // TODO: State API for this? + + resetCurrent(); +} + +void Block::commitAll() { + // Commit the new trie to disk. + if (isChannelVisible()) // Avoid calling toHex if not needed + LOG(TRACE) << "Committing to disk: stateRoot" << m_currentBlock.stateRoot() << "=" << rootHash() << "=" << toHex(asBytes(db().lookup(rootHash()))); + + try + { + EnforceRefs er(db(), true); + rootHash(); + } + catch (BadRoot const&) + { + LOG(TRACE) << "Trie corrupt! :-("; + throw; + } + + m_state.db().commit(); // TODO: State API for this? + + if (isChannelVisible()) // Avoid calling toHex if not needed + LOG(TRACE) << "Committed: stateRoot" << m_currentBlock.stateRoot() << "=" << rootHash() << "=" << toHex(asBytes(db().lookup(rootHash()))); + + LOG(TRACE) << "finalising enactment. current -> previous, hash is" << m_previousBlock.hash(); +} + +void dev::eth::Block::clearCurrentBytes() { + m_currentBytes.clear(); +} + + +string Block::vmTrace(bytesConstRef _block, BlockChain const& _bc, ImportRequirements::value _ir) +{ + noteChain(_bc); + + RLP rlp(_block); + + cleanup(false); + BlockHeader bi(_block); + m_currentBlock = bi; + m_currentBlock.verify((_ir & ImportRequirements::ValidSeal) ? CheckEverything : IgnoreSeal, _block); + m_currentBlock.noteDirty(); + + LastHashes lh = _bc.lastHashes(m_currentBlock.parentHash()); + + string ret; + unsigned i = 0; + for (auto const& tr : rlp[1]) + { + StandardTrace st; + st.setShowMnemonics(); + execute(lh, Transaction(tr.data(), CheckTransaction::Everything), Permanence::Committed, st.onOp()); + ret += (ret.empty() ? "[" : ",") + st.json(); + ++i; + } + return ret.empty() ? "[]" : (ret + "]"); +} + +std::ostream& dev::eth::operator<<(std::ostream& _out, Block const& _s) +{ + (void)_s; + return _out; +} diff --git a/libethereum/Block.h b/libethereum/Block.h new file mode 100644 index 0000000000..fc40bc240e --- /dev/null +++ b/libethereum/Block.h @@ -0,0 +1,361 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Block.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Account.h" +#include "Transaction.h" +#include "TransactionReceipt.h" +#include "GasPricer.h" +#include "State.h" + +namespace dev +{ + +namespace test { class ImportTest; class StateLoader; } + +namespace eth +{ + +class SealEngineFace; +class BlockChain; +class State; +class TransactionQueue; +struct VerifiedBlockRef; + +struct BlockChat: public LogChannel { static const char* name(); static const int verbosity = 4; }; +struct BlockTrace: public LogChannel { static const char* name(); static const int verbosity = 5; }; +struct BlockDetail: public LogChannel { static const char* name(); static const int verbosity = 14; }; +struct BlockSafeExceptions: public LogChannel { static const char* name(); static const int verbosity = 21; }; + +struct PopulationStatistics +{ + double verify; + double enact; +}; + +DEV_SIMPLE_EXCEPTION(ChainOperationWithUnknownBlockChain); +DEV_SIMPLE_EXCEPTION(InvalidOperationOnSealedBlock); + +/** + * @brief Active model of a block within the block chain. + * Keeps track of all transactions, receipts and state for a particular block. Can apply all + * needed transforms of the state for rewards and contains logic for sealing the block. + */ +class Block +{ + friend class ExtVM; + friend class dev::test::ImportTest; + friend class dev::test::StateLoader; + friend class Executive; + friend class BlockChain; + +public: + // TODO: pass in ChainOperationParams rather than u256 + + /// Default constructor; creates with a blank database prepopulated with the genesis block. + Block(u256 const& _accountStartNonce): m_state(_accountStartNonce, OverlayDB(), BaseState::Empty), m_precommit(_accountStartNonce) {} + + /// Basic state object from database. + /// Use the default when you already have a database and you just want to make a Block object + /// which uses it. If you have no preexisting database then set BaseState to something other + /// than BaseState::PreExisting in order to prepopulate the Trie. + /// You can also set the author address. + Block(BlockChain const& _bc, OverlayDB const& _db, BaseState _bs = BaseState::PreExisting, Address const& _author = Address()); + + /// Basic state object from database. + /// Use the default when you already have a database and you just want to make a Block object + /// which uses it. + /// Will throw InvalidRoot if the root passed is not in the database. + /// You can also set the author address. + Block(BlockChain const& _bc, OverlayDB const& _db, h256 const& _root, Address const& _author = Address()); + + enum NullType { Null }; + Block(NullType): m_state(0, OverlayDB(), BaseState::Empty), m_precommit(0) {} + + /// Construct from a given blockchain. Empty, but associated with @a _bc 's chain params. + explicit Block(BlockChain const& _bc): Block(Null) { noteChain(_bc); } + + /// Copy state object. + Block(Block const& _s); + + /// Copy state object. + Block& operator=(Block const& _s); + + /// Get the author address for any transactions we do and rewards we get. + Address author() const { return m_author; } + + /// Set the author address for any transactions we do and rewards we get. + /// This causes a complete reset of current block. + void setAuthor(Address const& _id) { m_author = _id; resetCurrent(); } + + /// Note the fact that this block is being used with a particular chain. + /// Call this before using any non-const methods. + void noteChain(BlockChain const& _bc); + + // Account-getters. All operate on the final state. + + /// Get an account's balance. + /// @returns 0 if the address has never been used. + u256 balance(Address const& _address) const { return m_state.balance(_address); } + + /// Get the number of transactions a particular address has sent (used for the transaction nonce). + /// @returns 0 if the address has never been used. + u256 transactionsFrom(Address const& _address) const { return m_state.getNonce(_address); } + + /// Check if the address is in use. + bool addressInUse(Address const& _address) const { return m_state.addressInUse(_address); } + + /// Check if the address contains executable code. + bool addressHasCode(Address const& _address) const { return m_state.addressHasCode(_address); } + + /// Get the root of the storage of an account. + h256 storageRoot(Address const& _contract) const { return m_state.storageRoot(_contract); } + + /// Get the value of a storage position of an account. + /// @returns 0 if no account exists at that address. + u256 storage(Address const& _contract, u256 const& _memory) const { return m_state.storage(_contract, _memory); } + + /// Get the storage of an account. + /// @note This is expensive. Don't use it unless you need to. + /// @returns map of hashed keys to key-value pairs or empty map if no account exists at that address. + std::map> storage(Address const& _contract) const { return m_state.storage(_contract); } + + /// Get the code of an account. + /// @returns bytes() if no account exists at that address. + bytes const& code(Address const& _contract) const { return m_state.code(_contract); } + + /// Get the code hash of an account. + /// @returns EmptySHA3 if no account exists at that address or if there is no code associated with the address. + h256 codeHash(Address const& _contract) const { return m_state.codeHash(_contract); } + + // General information from state + + /// Get the backing state object. + State const& state() const { return m_state; } + + /// Open a DB - useful for passing into the constructor & keeping for other states that are necessary. + OverlayDB const& db() const { return m_state.db(); } + + /// The hash of the root of our state tree. + h256 rootHash() const { return m_state.rootHash(); } + + /// @returns the set containing all addresses currently in use in Ethereum. + /// @throws InterfaceNotSupported if compiled without ETH_FATDB. + std::unordered_map addresses() const { return m_state.addresses(); } + + // For altering accounts behind-the-scenes + + /// Get a mutable State object which is backing this block. + /// @warning Only use this is you know what you're doing. If you use it while constructing a + /// normal sealable block, don't expect things to work right. + State& mutableState() { return m_state; } + + // Information concerning ongoing transactions + + /// Get the remaining gas limit in this block. + u256 gasLimitRemaining() const { return m_currentBlock.gasLimit() - gasUsed(); } + + /// Get the list of pending transactions. + Transactions const& pending() const { return m_transactions; } + + /// Get the list of hashes of pending transactions. + h256Hash const& pendingHashes() const { return m_transactionSet; } + + /// Get the transaction receipt for the transaction of the given index. + TransactionReceipt const& receipt(unsigned _i) const { return m_receipts[_i]; } + + /// Get the list of pending transactions. + LogEntries const& log(unsigned _i) const { return m_receipts[_i].log(); } + + /// Get the bloom filter of all logs that happened in the block. + LogBloom logBloom() const; + + /// Get the bloom filter of a particular transaction that happened in the block. + LogBloom const& logBloom(unsigned _i) const { return m_receipts[_i].bloom(); } + + /// Get the State immediately after the given number of pending transactions have been applied. + /// If (_i == 0) returns the initial state of the block. + /// If (_i == pending().size()) returns the final state of the block, prior to rewards. + State fromPending(unsigned _i) const; + + // State-change operations + + /// Construct state object from arbitrary point in blockchain. + PopulationStatistics populateFromChain(BlockChain const& _bc, h256 const& _hash, ImportRequirements::value _ir = ImportRequirements::None); + + /// Execute a given transaction. + /// This will append @a _t to the transaction list and change the state accordingly. + ExecutionResult execute(LastHashes const& _lh, Transaction const& _t, Permanence _p = Permanence::Committed, OnOpFunc const& _onOp = OnOpFunc(), BlockChain const *_bc = nullptr); + + /// Sync our transactions, killing those from the queue that we have and assimilating those that we don't. + /// @returns a list of receipts one for each transaction placed from the queue into the state and bool, true iff there are more transactions to be processed. + std::pair sync(BlockChain const& _bc, TransactionQueue& _tq, GasPricer const& _gp, unsigned _msTimeout = 100); + + /// Sync our state with the block chain. + /// This basically involves wiping ourselves if we've been superceded and rebuilding from the transaction queue. + bool sync(BlockChain const& _bc); + + /// Sync with the block chain, but rather than synching to the latest block, instead sync to the given block. + bool sync(BlockChain const& _bc, h256 const& _blockHash, BlockHeader const& _bi = BlockHeader()); + + /// Execute all transactions within a given block. + /// @returns the additional total difficulty. + u256 enactOn(VerifiedBlockRef const& _block, BlockChain const& _bc); + + /// Returns back to a pristine state after having done a playback. + /// @arg _fullCommit if true flush everything out to disk. If false, this effectively only validates + /// the block since all state changes are ultimately reversed. + void cleanup(bool _fullCommit); + + /// Sets m_currentBlock to a clean state, (i.e. no change from m_previousBlock) and + /// optionally modifies the timestamp. + void resetCurrent(u256 const& _timestamp = u256(utcTime())); + + // Sealing + + /// Prepares the current state for mining. + /// Commits all transactions into the trie, compiles uncles and transactions list, applies all + /// rewards and populates the current block header with the appropriate hashes. + /// The only thing left to do after this is to actually mine(). + /// + /// This may be called multiple times and without issue. + void commitToSeal(BlockChain const& _bc, bytes const& _extraData = {}); + + /// Pass in a properly sealed header matching this block. + /// @returns true iff we were previously committed to sealing, the header is valid and it + /// corresponds to this block. + /// TODO: verify it prior to calling this. + /** Commit to DB and build the final block if the previous call to mine()'s result is completion. + * Typically looks like: + * @code + * while (!isSealed) + * { + * // lock + * commitToSeal(_blockChain); // will call uncommitToSeal if a repeat. + * sealBlock(sealedHeader); + * // unlock + * @endcode + */ + + void commitAll(); + bool sealBlock(BlockHeader const& _header, bytesConstRef _headerBytes); + + bool sealBlock(bytes const& _header) { return sealBlock(&_header); } + bool sealBlock(bytesConstRef _header); + bytes blockBytes() const; + /// @returns true if sealed - in this case you can no longer append transactions. + bool isSealed() const { return !m_currentBytes.empty(); } + + /// Get the complete current block, including valid nonce. + /// Only valid when isSealed() is true. + bytes const& blockData() const { return m_currentBytes; } + + /// Get the header information on the present block. + BlockHeader const& info() const { return m_currentBlock; } + + void setEvmEventLog(bool _el) { m_evmEventLog = _el;} + void setEvmCoverLog(bool _cl) { m_evmCoverLog = _cl;} + + bool evmEventLog() { return m_evmEventLog;} + bool evmCoverLog() { return m_evmCoverLog;} + + void resetCurrentTime(u256 const& _timestamp = u256(utcTime())); + void setIndex(u256 _idx); + void setNodeList(h512s const& _nodes); + + void clearCurrentBytes(); + bool empty() const; + +private: + SealEngineFace* sealEngine() const; + + /// Undo the changes to the state for committing to mine. + void uncommitToSeal(); + + /// Retrieve all information about a given address into the cache. + /// If _requireMemory is true, grab the full memory should it be a contract item. + /// If _forceCreate is true, then insert a default item into the cache, in the case it doesn't + /// exist in the DB. + void ensureCached(Address const& _a, bool _requireCode, bool _forceCreate) const; + + /// Retrieve all information about a given address into a cache. + void ensureCached(std::unordered_map& _cache, Address const& _a, bool _requireCode, bool _forceCreate) const; + + /// Execute the given block, assuming it corresponds to m_currentBlock. + /// Throws on failure. + u256 enact(VerifiedBlockRef const& _block, BlockChain const& _bc,bool _filtercheck=false); + + /// Finalise the block, applying the earned rewards. + void applyRewards(std::vector const& _uncleBlockHeaders, u256 const& _blockReward); + + /// @returns gas used by transactions thus far executed. + u256 gasUsed() const { return m_receipts.size() ? m_receipts.back().gasUsed() : 0; } + + /// Performs irregular modifications right after initialization, e.g. to implement a hard fork. + void performIrregularModifications(); + + /// Provide a standard VM trace for debugging purposes. + std::string vmTrace(bytesConstRef _block, BlockChain const& _bc, ImportRequirements::value _ir); + + State m_state; ///< Our state tree, as an OverlayDB DB. + Transactions m_transactions; ///< The current list of transactions that we've included in the state. + TransactionReceipts m_receipts; ///< The corresponding list of transaction receipts. + h256Hash m_transactionSet; ///< The set of transaction hashes that we've included in the state. + State m_precommit; ///< State at the point immediately prior to rewards. + + BlockHeader m_previousBlock; ///< The previous block's information. + BlockHeader m_currentBlock; ///< The current block's information. + bytes m_currentBytes; ///< The current block's bytes. + bool m_committedToSeal = false; ///< Have we committed to mine on the present m_currentBlock? + + bytes m_currentTxs; ///< The RLP-encoded block of transactions. + bytes m_currentUncles; ///< The RLP-encoded block of uncles. + + Address m_author; ///< Our address (i.e. the address to which fees go). + + SealEngineFace* m_sealEngine = nullptr; ///< The chain's seal engine. + + bool m_evmEventLog = false; + bool m_evmCoverLog = false; + + friend std::ostream& operator<<(std::ostream& _out, Block const& _s); + +public: + static unsigned c_maxSyncTransactions; +}; + +std::ostream& operator<<(std::ostream& _out, Block const& _s); + + +} + +} diff --git a/libethereum/BlockChain.cpp b/libethereum/BlockChain.cpp new file mode 100644 index 0000000000..b8ce173b60 --- /dev/null +++ b/libethereum/BlockChain.cpp @@ -0,0 +1,1873 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file BlockChain.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "BlockChain.h" + +#if ETH_PROFILING_GPERF +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "State.h" +#include "Block.h" +#include "Utility.h" +#include "Defaults.h" +#include "NodeConnParamsManagerApi.h" +#include + +using namespace std; +using namespace dev; +using namespace dev::eth; +namespace js = json_spirit; +namespace fs = boost::filesystem; + +#define ETH_CATCH 1 +#define ETH_TIMED_IMPORTS 1 + + + +u256 BlockChain::maxBlockLimit = 1000; + +std::ostream& dev::eth::operator<<(std::ostream& _out, BlockChain const& _bc) +{ + string cmp = toBigEndianString(_bc.currentHash()); + auto it = _bc.m_blocksDB->NewIterator(_bc.m_readOptions); + for (it->SeekToFirst(); it->Valid(); it->Next()) + if (it->key().ToString() != "best") + { + try { + BlockHeader d(bytesConstRef(it->value())); + _out << toHex(it->key().ToString()) << ": " << d.number() << " @ " << d.parentHash() << (cmp == it->key().ToString() ? " BEST" : "") << std::endl; + } + catch (...) { + LOG(WARNING) << "Invalid DB entry:" << toHex(it->key().ToString()) << " -> " << toHex(bytesConstRef(it->value())); + } + } + delete it; + return _out; +} + +ldb::Slice dev::eth::toSlice(h256 const& _h, unsigned _sub) +{ +#if ALL_COMPILERS_ARE_CPP11_COMPLIANT + static thread_local FixedHash<33> h = _h; + h[32] = (uint8_t)_sub; + return (ldb::Slice)h.ref(); +#else + static boost::thread_specific_ptr> t_h; + if (!t_h.get()) + t_h.reset(new FixedHash<33>); + *t_h = FixedHash<33>(_h); + (*t_h)[32] = (uint8_t)_sub; + return (ldb::Slice)t_h->ref(); +#endif //ALL_COMPILERS_ARE_CPP11_COMPLIANT +} + +ldb::Slice dev::eth::toSlice(uint64_t _n, unsigned _sub) +{ +#if ALL_COMPILERS_ARE_CPP11_COMPLIANT + static thread_local FixedHash<33> h; + toBigEndian(_n, bytesRef(h.data() + 24, 8)); + h[32] = (uint8_t)_sub; + return (ldb::Slice)h.ref(); +#else + static boost::thread_specific_ptr> t_h; + if (!t_h.get()) + t_h.reset(new FixedHash<33>); + bytesRef ref(t_h->data() + 24, 8); + toBigEndian(_n, ref); + (*t_h)[32] = (uint8_t)_sub; + return (ldb::Slice)t_h->ref(); +#endif +} + +namespace dev +{ +class WriteBatchNoter: public ldb::WriteBatch::Handler +{ + virtual void Put(ldb::Slice const& _key, ldb::Slice const& _value) { LOG(TRACE) << "Put" << toHex(bytesConstRef(_key)) << "=>" << toHex(bytesConstRef(_value)); } + virtual void Delete(ldb::Slice const& _key) { LOG(TRACE) << "Delete" << toHex(bytesConstRef(_key)); } +}; +} + +#if ETH_DEBUG&&0 +static const chrono::system_clock::duration c_collectionDuration = chrono::seconds(15); +static const unsigned c_collectionQueueSize = 2; +static const unsigned c_maxCacheSize = 1024 * 1024 * 1; +static const unsigned c_minCacheSize = 1; +#else + +/// Duration between flushes. +static const chrono::system_clock::duration c_collectionDuration = chrono::seconds(60); + +/// Length of death row (total time in cache is multiple of this and collection duration). +static const unsigned c_collectionQueueSize = 20; + +/// Max size, above which we start forcing cache reduction. +static const unsigned c_maxCacheSize = 1024 * 1024 * 64; + +/// Min size, below which we don't bother flushing it. +static const unsigned c_minCacheSize = 1024 * 1024 * 32; + +#endif + +BlockChain::BlockChain(std::shared_ptr _interface, ChainParams const& _p, std::string const& _dbPath, WithExisting _we, ProgressCallback const& _pc): + m_dbPath(_dbPath), + m_pnoncecheck(make_shared()) +{ + init(_p, _dbPath); + open(_dbPath, _we, _pc); + + m_pnoncecheck->init(*this ); + + m_interface = _interface; + +} + +BlockChain::~BlockChain() +{ + close(); +} + +bool BlockChain::isBlockLimitOk(Transaction const&_ts) const +{ + if ( (_ts.blockLimit() == Invalid256) || ( number() >= _ts.blockLimit() ) || (_ts.blockLimit() > (number() + BlockChain::maxBlockLimit) ) ) + { + LOG(TRACE) << "BlockChain::isBlockLimitOk Fail! t.sha3()=" << _ts.sha3() << ",t.blockLimit=" << _ts.blockLimit() << ",number()=" << number() << ",maxBlockLimit=" << BlockChain::maxBlockLimit; + return false; + } + + return true; +} +bool BlockChain::isNonceOk(Transaction const&_ts, bool _needinsert) const +{ + if ( (_ts.randomid() == Invalid256) || ( !m_pnoncecheck ) || (! m_pnoncecheck->ok(_ts, _needinsert) ) ) + { + LOG(TRACE) << "BlockChain::isNonceOk Fail! t.sha3()=" << _ts.sha3() << ",t.nonce=" << _ts.randomid(); + return false; + } + + return true; +} + +u256 BlockChain::filterCheck(const Transaction & _t, FilterCheckScene _checkscene) const +{ + return m_interface->filterCheck(_t, _checkscene); +} + +void BlockChain::updateSystemContract(std::shared_ptr block) +{ + m_interface->updateSystemContract(block); +} + +void BlockChain::updateCache(Address address) const { + m_interface->updateCache(address); +} + +BlockHeader const& BlockChain::genesis() const +{ + UpgradableGuard l(x_genesis); + if (!m_genesis) + { + auto gb = m_params.genesisBlock(); + UpgradeGuard ul(l); + m_genesis = BlockHeader(gb); + m_genesisHeaderBytes = BlockHeader::extractHeader(&gb).data().toBytes(); + m_genesisHash = m_genesis.hash(); + } + return m_genesis; +} + +void BlockChain::init(ChainParams const& _p, std::string const& _path) +{ + // initialise deathrow. + m_cacheUsage.resize(c_collectionQueueSize); + m_lastCollection = chrono::system_clock::now(); + + // Initialise with the genesis as the last block on the longest chain. + m_params = _p; + m_sealEngine.reset(m_params.createSealEngine()); + m_genesis.clear(); + genesis(); + + // remove the next line real soon. we don't need to be supporting this forever. + upgradeDatabase(_path, genesisHash()); +} + +unsigned BlockChain::open(std::string const& _path, WithExisting _we) +{ + string path = _path.empty() ? Defaults::get()->m_dbPath : _path; + string chainPath = path + "/" + toHex(m_genesisHash.ref().cropped(0, 4)); + string extrasPath = chainPath + "/" + toString(c_databaseVersion); + + fs::create_directories(extrasPath); + DEV_IGNORE_EXCEPTIONS(fs::permissions(extrasPath, fs::owner_all)); + + bytes status = contents(extrasPath + "/minor"); + unsigned lastMinor = c_minorProtocolVersion; + if (!status.empty()) + DEV_IGNORE_EXCEPTIONS(lastMinor = (unsigned)RLP(status)); + if (c_minorProtocolVersion != lastMinor) + { + LOG(TRACE) << "Killing extras database (DB minor version:" << lastMinor << " != our miner version: " << c_minorProtocolVersion << ")."; + DEV_IGNORE_EXCEPTIONS(boost::filesystem::remove_all(extrasPath + "/details.old")); + boost::filesystem::rename(extrasPath + "/extras", extrasPath + "/extras.old"); + boost::filesystem::remove_all(extrasPath + "/state"); + writeFile(extrasPath + "/minor", rlp(c_minorProtocolVersion)); + lastMinor = (unsigned)RLP(status); + } + if (_we == WithExisting::Kill) + { + LOG(TRACE) << "Killing blockchain & extras database (WithExisting::Kill)."; + boost::filesystem::remove_all(chainPath + "/blocks"); + boost::filesystem::remove_all(extrasPath + "/extras"); + } + + ldb::Options o; + o.create_if_missing = true; + o.max_open_files = 256; +#if ETH_ODBC + + LOG(INFO) << "state ethodbc is defined " << std::endl; + + m_blocksDB = nullptr; + m_extrasDB = nullptr; + m_blocksDB = ldb::LvlDbInterfaceFactory::create(leveldb::DBUseType::blockType); + if (m_blocksDB != nullptr) + { + LOG(INFO) << "block ethodbc is defined " << std::endl; + + } + else + { + LOG(INFO) << "block ethodbc is not defined " << std::endl; + } + + m_extrasDB = ldb::LvlDbInterfaceFactory::create(leveldb::DBUseType::extrasType); + if (m_extrasDB != nullptr) + { + LOG(INFO) << "extras ethodbc is defined " << std::endl; + } + else + { + LOG(INFO) << "extras ethodbc is not defined " << std::endl; + } +#else + ldb::DB::Open(o, chainPath + "/blocks", &m_blocksDB); + ldb::DB::Open(o, extrasPath + "/extras", &m_extrasDB); + if (!m_blocksDB || !m_extrasDB) + { + if (boost::filesystem::space(chainPath + "/blocks").available < 1024) + { + LOG(WARNING) << "Not enough available space found on hard drive. Please free some up and then re-run. Bailing."; + BOOST_THROW_EXCEPTION(NotEnoughAvailableSpace()); + } + else + { + LOG(WARNING) << + "Database " << + (chainPath + "/blocks") << + "or " << + (extrasPath + "/extras") << + "already open. You appear to have another instance of ethereum running. Bailing."; + BOOST_THROW_EXCEPTION(DatabaseAlreadyOpen()); + } + } +#endif + + if (_we != WithExisting::Verify && !details(m_genesisHash)) + { + BlockHeader gb(m_params.genesisBlock()); + // Insert details of genesis block. + m_details[m_genesisHash] = BlockDetails(0, gb.difficulty(), h256(), {}); + auto r = m_details[m_genesisHash].rlp(); + m_extrasDB->Put(m_writeOptions, toSlice(m_genesisHash, ExtraDetails), (ldb::Slice)dev::ref(r)); + assert(isKnown(gb.hash())); + } + +#if ETH_PARANOIA + checkConsistency(); +#endif + + // TODO: Implement ability to rebuild details map from DB. + std::string l; + m_extrasDB->Get(m_readOptions, ldb::Slice("best"), &l); + m_lastBlockHash = l.empty() ? m_genesisHash : *(h256*)l.data(); + m_lastBlockNumber = number(m_lastBlockHash); + + LOG(TRACE) << "Opened blockchain DB. Latest: " << currentHash() << (lastMinor == c_minorProtocolVersion ? "(rebuild not needed)" : "*** REBUILD NEEDED ***"); + return lastMinor; +} + +void BlockChain::open(std::string const& _path, WithExisting _we, ProgressCallback const& _pc) +{ + if (open(_path, _we) != c_minorProtocolVersion || _we == WithExisting::Verify) + rebuild(_path, _pc); +} + +void BlockChain::reopen(ChainParams const& _p, WithExisting _we, ProgressCallback const& _pc) +{ + close(); + init(_p, m_dbPath); + open(m_dbPath, _we, _pc); +} + +void BlockChain::close() +{ + LOG(TRACE) << "Closing blockchain DB"; + // Not thread safe... + delete m_extrasDB; + delete m_blocksDB; + m_lastBlockHash = m_genesisHash; + m_lastBlockNumber = 0; + m_details.clear(); + m_blocks.clear(); + m_logBlooms.clear(); + m_receipts.clear(); + m_transactionAddresses.clear(); + m_blockHashes.clear(); + m_blocksBlooms.clear(); + m_cacheUsage.clear(); + m_inUse.clear(); + m_lastLastHashes.clear(); +} + +void BlockChain::rebuild(std::string const& _path, std::function const& _progress) +{ + string path = _path.empty() ? Defaults::get()->m_dbPath : _path; + string chainPath = path + "/" + toHex(m_genesisHash.ref().cropped(0, 4)); + string extrasPath = chainPath + "/" + toString(c_databaseVersion); + +#if ETH_PROFILING_GPERF + ProfilerStart("BlockChain_rebuild.log"); +#endif + + unsigned originalNumber = m_lastBlockNumber; + + /////////////////////////////// + // TODO + // - KILL ALL STATE/CHAIN + // - REINSERT ALL BLOCKS + /////////////////////////////// + + // Keep extras DB around, but under a temp name + delete m_extrasDB; + m_extrasDB = nullptr; + boost::filesystem::rename(extrasPath + "/extras", extrasPath + "/extras.old"); + ldb::DB* oldExtrasDB; + ldb::Options o; + o.create_if_missing = true; + ldb::DB::Open(o, extrasPath + "/extras.old", &oldExtrasDB); + ldb::DB::Open(o, extrasPath + "/extras", &m_extrasDB); + + // Open a fresh state DB + Block s = genesisBlock(State::openDB(path, m_genesisHash, WithExisting::Kill)); + + // Clear all memos ready for replay. + m_details.clear(); + m_logBlooms.clear(); + m_receipts.clear(); + m_transactionAddresses.clear(); + m_blockHashes.clear(); + m_blocksBlooms.clear(); + m_lastLastHashes.clear(); + m_lastBlockHash = genesisHash(); + m_lastBlockNumber = 0; + + m_details[m_lastBlockHash].totalDifficulty = s.info().difficulty(); + + m_extrasDB->Put(m_writeOptions, toSlice(m_lastBlockHash, ExtraDetails), (ldb::Slice)dev::ref(m_details[m_lastBlockHash].rlp())); + + h256 lastHash = m_lastBlockHash; + Timer t; + for (unsigned d = 1; d <= originalNumber; ++d) + { + if (!(d % 1000)) + { + LOG(ERROR) << "\n1000 blocks in " << t.elapsed() << "s = " << (1000.0 / t.elapsed()) << "b/s" << endl; + t.restart(); + } + try + { + bytes b = block(queryExtras(d, m_blockHashes, x_blockHashes, NullBlockHash, oldExtrasDB).value); + + BlockHeader bi(&b); + + if (bi.parentHash() != lastHash) + { + LOG(WARNING) << "DISJOINT CHAIN DETECTED; " << bi.hash() << "#" << d << " -> parent is" << bi.parentHash() << "; expected" << lastHash << "#" << (d - 1); + return; + } + lastHash = bi.hash(); + import(b, s.db(), 0); + } + catch (...) + { + // Failed to import - stop here. + break; + } + + if (_progress) + _progress(d, originalNumber); + } + +#if ETH_PROFILING_GPERF + ProfilerStop(); +#endif + + delete oldExtrasDB; + boost::filesystem::remove_all(path + "/extras.old"); +} + +string BlockChain::dumpDatabase() const +{ + stringstream ss; + + ss << m_lastBlockHash << endl; + ldb::Iterator* i = m_extrasDB->NewIterator(m_readOptions); + for (i->SeekToFirst(); i->Valid(); i->Next()) + ss << toHex(bytesConstRef(i->key())) << "/" << toHex(bytesConstRef(i->value())) << endl; + return ss.str(); +} + +LastHashes BlockChain::lastHashes(h256 const& _parent) const +{ + Guard l(x_lastLastHashes); + if (m_lastLastHashes.empty() || m_lastLastHashes.front() != _parent) + { + m_lastLastHashes.resize(256); + m_lastLastHashes[0] = _parent; + for (unsigned i = 0; i < 255; ++i) + m_lastLastHashes[i + 1] = m_lastLastHashes[i] ? info(m_lastLastHashes[i]).parentHash() : h256(); + } + return m_lastLastHashes; +} + + +void BlockChain::addBlockCache(Block block, u256 td) const { + DEV_WRITE_GUARDED(x_blockcache) + { + if ( m_blockCache.size() > 10 ) + m_blockCache.clear(); + + m_blockCache.insert(std::make_pair(block.info().hash(), std::make_pair(block, td))); + + } + +} + +std::pair BlockChain::getBlockCache(h256 const& hash) const { + DEV_READ_GUARDED(x_blockcache) + { + + auto it = m_blockCache.find(hash); + if (it == m_blockCache.end()) { + return std::make_pair(Block(0), 0); + } + + return it->second; + } +} + +tuple BlockChain::sync(BlockQueue& _bq, OverlayDB const& _stateDB, unsigned _max) +{ +// _bq.tick(*this); + + VerifiedBlocks blocks; + _bq.drain(blocks, _max); + + h256s fresh; + h256s dead; + h256s badBlocks; + Transactions goodTransactions; + unsigned count = 0; + + uint64_t startimport=0; + uint64_t endimport=0; + + for (VerifiedBlock const& block : blocks) + { + do { + try + { + // Nonce & uncle nonces already verified in verification thread at this point. + ImportRoute r; + DEV_TIMED_ABOVE("BLOCKSTAT 超时500ms " +toString(block.verified.info.hash(WithoutSeal))+ toString(block.verified.info.number()), 500) + //DEV_BLOCK_STAT_LOG(block.verified.info.hash(WithoutSeal), block.verified.info.number(), utcTime(), "BeforeImport"); + startimport=utcTime(); + r = import(block.verified, _stateDB, (ImportRequirements::Everything & ~ImportRequirements::ValidSeal & ~ImportRequirements::CheckUncles) != 0); + endimport=utcTime(); + cblockstat< COnChainTimeLimit) + { + LOGCOMWARNING< receipts; + for (auto i : RLP(_receipts)) + receipts.push_back(i.data()); + h256 receiptsRoot = orderedTrieRoot(receipts); + if (_block.info.receiptsRoot() != receiptsRoot) + { + LOG(TRACE) << _block.info.hash() << ": Invalid receipts root " << _block.info.receiptsRoot() << " not " << receiptsRoot; + // We don't know the parent (yet) - discard for now. It'll get resent to us if we find out about its ancestry later on. + BOOST_THROW_EXCEPTION(InvalidReceiptsStateRoot()); + } + + auto pd = details(_block.info.parentHash()); + if (!pd) + { + auto pdata = pd.rlp(); + LOG(DEBUG) << "Details is returning false despite block known:" << RLP(pdata); + auto parentBlock = block(_block.info.parentHash()); + LOG(DEBUG) << "isKnown:" << isKnown(_block.info.parentHash()); + LOG(DEBUG) << "last/number:" << m_lastBlockNumber << m_lastBlockHash << _block.info.number(); + LOG(DEBUG) << "Block:" << BlockHeader(&parentBlock); + LOG(DEBUG) << "RLP:" << RLP(parentBlock); + LOG(DEBUG) << "DATABASE CORRUPTION: CRITICAL FAILURE"; + exit(-1); + } + + // Check it's not crazy + if (_block.info.timestamp() > utcTime() && !m_params.otherParams.count("allowFutureBlocks")) + { + LOG(TRACE) << _block.info.hash() << ": Future time " << _block.info.timestamp() << " (now at " << utcTime() << ")"; + // Block has a timestamp in the future. This is no good. + BOOST_THROW_EXCEPTION(FutureTime()); + } + + // Verify parent-critical parts, + verifyBlock(_block.block, m_onBad, ImportRequirements::InOrderChecks | ImportRequirements::CheckMinerSignatures); + + // OK - we're happy. Insert into database. + ldb::WriteBatch blocksBatch; + ldb::WriteBatch extrasBatch; + + BlockLogBlooms blb; + for (auto i : RLP(_receipts)) + blb.blooms.push_back(TransactionReceipt(i.data()).bloom()); + + // ensure parent is cached for later addition. + // TODO: this is a bit horrible would be better refactored into an enveloping UpgradableGuard + // together with an "ensureCachedWithUpdatableLock(l)" method. + // This is safe in practice since the caches don't get flushed nearly often enough to be + // done here. + details(_block.info.parentHash()); + DEV_WRITE_GUARDED(x_details) + { + if (!dev::contains(m_details[_block.info.parentHash()].children, _block.info.hash())) + m_details[_block.info.parentHash()].children.push_back(_block.info.hash()); + } + + blocksBatch.Put(toSlice(_block.info.hash()), ldb::Slice(_block.block)); + DEV_READ_GUARDED(x_details) + extrasBatch.Put(toSlice(_block.info.parentHash(), ExtraDetails), (ldb::Slice)dev::ref(m_details[_block.info.parentHash()].rlp())); + + BlockDetails bd((unsigned)pd.number + 1, pd.totalDifficulty + _block.info.difficulty(), _block.info.parentHash(), {}); + extrasBatch.Put(toSlice(_block.info.hash(), ExtraDetails), (ldb::Slice)dev::ref(bd.rlp())); + extrasBatch.Put(toSlice(_block.info.hash(), ExtraLogBlooms), (ldb::Slice)dev::ref(blb.rlp())); + extrasBatch.Put(toSlice(_block.info.hash(), ExtraReceipts), (ldb::Slice)_receipts); + + ldb::Status o = m_blocksDB->Write(m_writeOptions, &blocksBatch); + if (!o.ok()) + { + LOG(WARNING) << "Error writing to blockchain database: " << o.ToString(); + WriteBatchNoter n; + blocksBatch.Iterate(&n); + LOG(WARNING) << "Fail writing to blockchain database. Bombing out."; + exit(-1); + } + + o = m_extrasDB->Write(m_writeOptions, &extrasBatch); + if (!o.ok()) + { + LOG(WARNING) << "Error writing to extras database: " << o.ToString(); + WriteBatchNoter n; + extrasBatch.Iterate(&n); + LOG(WARNING) << "Fail writing to extras database. Bombing out."; + exit(-1); + } +} + +void BlockChain::checkBlockValid(h256 const& _hash, bytes const& _block, OverlayDB const& _db) const { + VerifiedBlockRef block = verifyBlock(&_block, m_onBad, ImportRequirements::Everything); + + if (_hash != block.info.hash()) { + LOG(WARNING) << "hash error, " << block.info.hash() << "," << _hash; + BOOST_THROW_EXCEPTION(HashError()); + } + + // 禁止叔块 + if (block.info.number() <= info().number()) { + LOG(WARNING) << "height error, h=" << block.info.number() << ", curr=" << info().number(); + BOOST_THROW_EXCEPTION(HeightError()); + } + + if (isKnown(block.info.hash())) { + LOG(WARNING) << block.info.hash() << ": Not new."; + BOOST_THROW_EXCEPTION(AlreadyHaveBlock()); + } + + if (!isKnown(block.info.parentHash(), false) || !details(block.info.parentHash())) { + LOG(WARNING) << block.info.hash() << ": Unknown parent " << block.info.parentHash(); + // We don't know the parent (yet) - discard for now. It'll get resent to us if we find out about its ancestry later on. + BOOST_THROW_EXCEPTION(UnknownParent() << errinfo_hash256(block.info.parentHash())); + } + + // Check it's not crazy + if (block.info.timestamp() > utcTime() && !m_params.otherParams.count("allowFutureBlocks")) + { + LOG(WARNING) << block.info.hash() << ": Future time " << block.info.timestamp() << " (now at " << utcTime() << ")"; + // Block has a timestamp in the future. This is no good. + BOOST_THROW_EXCEPTION(FutureTime()); + } + + std::map all_node; + NodeConnManagerSingleton::GetInstance().getAllNodeConnInfo(static_cast(block.info.number() - 1), all_node); + unsigned miner_num = 0; + for (auto iter = all_node.begin(); iter != all_node.end(); ++iter) { + if (iter->second._iIdentityType == EN_ACCOUNT_TYPE_MINER) { + ++miner_num; + } + } + h512s miner_list; + miner_list.resize(miner_num); + for (auto iter = all_node.begin(); iter != all_node.end(); ++iter) { + if (iter->second._iIdentityType == EN_ACCOUNT_TYPE_MINER) { + auto idx = static_cast(iter->second._iIdx); + + if (idx >= miner_num) { + LOG(WARNING) << "idx out of bound, idx=" << idx << ",miner_num=" << miner_num; + BOOST_THROW_EXCEPTION(MinerListError()); + } + + miner_list[idx] = jsToPublic(toJS(iter->second._sNodeId)); + + } + } + if (miner_list != block.info.nodeList()) { + LOG(WARNING) << "miner list error, " << _hash; + ostringstream oss; + for (size_t i = 0; i < miner_list.size(); ++i) { + oss << miner_list[i] << ","; + } + LOG(WARNING) << "get miner_list size=" << miner_list.size() << ",value=" << oss.str(); + ostringstream oss2; + for (size_t i = 0; i < block.info.nodeList().size(); ++i) { + oss2 << block.info.nodeList()[i] << ","; + } + LOG(WARNING) << "block node_list size=" << block.info.nodeList().size() << ",value=" << oss2.str(); + BOOST_THROW_EXCEPTION(MinerListError()); + } + + + std::pair ret = getBlockCache(block.info.hash(WithSeal)); + if(ret.second == 0) { + Block s(*this, _db); + u256 td = s.enactOn(block, *this); + s.setEvmCoverLog(m_params.evmCoverLog); + s.setEvmEventLog(m_params.evmEventLog); + + addBlockCache(s, td); + } + else { + //do nothing + } + +} + + +ImportRoute BlockChain::import(VerifiedBlockRef const& _block, OverlayDB const& _db, bool _mustBeNew) +{ + //@tidy This is a behemoth of a method - could do to be split into a few smaller ones. +#if ETH_TIMED_IMPORTS + Timer total; + double preliminaryChecks; + double enactment; + double collation; + double writing; + double checkBest; + Timer t; +#endif + + // Check block doesn't already exist first! + if (isKnown(_block.info.hash()) && _mustBeNew) + { + LOG(TRACE) << _block.info.hash() << ": Not new."; + BOOST_THROW_EXCEPTION(AlreadyHaveBlock() << errinfo_block(_block.block.toBytes())); + } + + // Work out its number as the parent's number + 1 + if (!isKnown(_block.info.parentHash(), false)) // doesn't have to be current. + { + LOG(TRACE) << _block.info.hash() << ": Unknown parent " << _block.info.parentHash(); + // We don't know the parent (yet) - discard for now. It'll get resent to us if we find out about its ancestry later on. + BOOST_THROW_EXCEPTION(UnknownParent() << errinfo_hash256(_block.info.parentHash())); + } + + auto pd = details(_block.info.parentHash()); + if (!pd) + { + auto pdata = pd.rlp(); + LOG(DEBUG) << "Details is returning false despite block known:" << RLP(pdata); + auto parentBlock = block(_block.info.parentHash()); + LOG(DEBUG) << "isKnown:" << isKnown(_block.info.parentHash()); + LOG(DEBUG) << "last/number:" << m_lastBlockNumber << m_lastBlockHash << _block.info.number(); + LOG(DEBUG) << "Block:" << BlockHeader(&parentBlock); + LOG(DEBUG) << "RLP:" << RLP(parentBlock); + LOG(DEBUG) << "DATABASE CORRUPTION: CRITICAL FAILURE"; + exit(-1); + } + + // Check it's not crazy + if (_block.info.timestamp() > utcTime() && !m_params.otherParams.count("allowFutureBlocks")) + { + LOG(TRACE) << _block.info.hash() << ": Future time " << _block.info.timestamp() << " (now at " << utcTime() << ")"; + // Block has a timestamp in the future. This is no good. + BOOST_THROW_EXCEPTION(FutureTime()); + } + + // Verify parent-critical parts, + verifyBlock(_block.block, m_onBad, ImportRequirements::InOrderChecks | ImportRequirements::CheckMinerSignatures); + + LOG(TRACE) << "Attempting import of " << _block.info.hash() << "..."; + + + +#if ETH_TIMED_IMPORTS + preliminaryChecks = t.elapsed(); + t.restart(); +#endif + + ldb::WriteBatch blocksBatch; + ldb::WriteBatch extrasBatch; + h256 newLastBlockHash = currentHash(); + unsigned newLastBlockNumber = number(); + + BlockLogBlooms blb; + BlockReceipts br; + + u256 td; + Transactions goodTransactions; + + std::shared_ptr tempBlock(new Block(*this, _db)); + +#if ETH_CATCH + try +#endif + { + // Check transactions are valid and that they result in a state equivalent to our state_root. + // Get total difficulty increase and update state, checking it. + + u256 tdIncrease =0; + + auto pair = getBlockCache(_block.info.hash()); + + if(pair.second != 0) { + tdIncrease = pair.second; + *tempBlock = pair.first; + } + else{ + tdIncrease = tempBlock->enactOn(_block, *this); + + tempBlock->setEvmCoverLog(m_params.evmCoverLog); + tempBlock->setEvmEventLog(m_params.evmEventLog); + + addBlockCache(*tempBlock, tdIncrease); + } + + for (unsigned i = 0; i < tempBlock->pending().size(); ++i) { + blb.blooms.push_back(tempBlock->receipt(i).bloom()); + br.receipts.push_back(tempBlock->receipt(i)); + goodTransactions.push_back(tempBlock->pending()[i]); + + + } + + tempBlock->commitAll(); + + + td = pd.totalDifficulty + tdIncrease; + +#if ETH_TIMED_IMPORTS + enactment = t.elapsed(); + t.restart(); +#endif // ETH_TIMED_IMPORTS + +#if ETH_PARANOIA + checkConsistency(); +#endif // ETH_PARANOIA + + // All ok - insert into DB + + // ensure parent is cached for later addition. + // TODO: this is a bit horrible would be better refactored into an enveloping UpgradableGuard + // together with an "ensureCachedWithUpdatableLock(l)" method. + // This is safe in practice since the caches don't get flushed nearly often enough to be + // done here. + details(_block.info.parentHash()); + DEV_WRITE_GUARDED(x_details) + m_details[_block.info.parentHash()].children.push_back(_block.info.hash()); + +#if ETH_TIMED_IMPORTS + collation = t.elapsed(); + t.restart(); +#endif // ETH_TIMED_IMPORTS + + blocksBatch.Put(toSlice(_block.info.hash()), ldb::Slice(_block.block));//_block.block [0]=head [1]=transactionlist [2]=unclelist [3]=hash [4]=siglist + DEV_READ_GUARDED(x_details) + extrasBatch.Put(toSlice(_block.info.parentHash(), ExtraDetails), (ldb::Slice)dev::ref(m_details[_block.info.parentHash()].rlp())); + + extrasBatch.Put(toSlice(_block.info.hash(), ExtraDetails), (ldb::Slice)dev::ref(BlockDetails((unsigned)pd.number + 1, td, _block.info.parentHash(), {}).rlp())); + extrasBatch.Put(toSlice(_block.info.hash(), ExtraLogBlooms), (ldb::Slice)dev::ref(blb.rlp())); + extrasBatch.Put(toSlice(_block.info.hash(), ExtraReceipts), (ldb::Slice)dev::ref(br.rlp())); + +#if ETH_TIMED_IMPORTS + writing = t.elapsed(); + t.restart(); +#endif // ETH_TIMED_IMPORTS + } + +#if ETH_CATCH + catch (BadRoot& ex) + { + m_pnoncecheck->delCache(goodTransactions); + LOG(WARNING) << "*** BadRoot error! Trying to import" << _block.info.hash() << "needed root" << ex.root; + LOG(WARNING) << _block.info; + // Attempt in import later. + BOOST_THROW_EXCEPTION(TransientError()); + } + catch ( BcFilterCheckError & ex) + { + LOG(WARNING) << "*** Bad Filter Check error! Trying to import" << _block.info.hash() ; + + ex << errinfo_now(time(0)); + ex << errinfo_block(_block.block.toBytes()); + if (!_block.info.extraData().empty()) + ex << errinfo_extraData(_block.info.extraData()); + throw; + } + catch ( BcNoDeployPermissionError &ex) + { + LOG(WARNING) << "*** Bad NoDeployPermissionError error! Trying to import" << _block.info.hash() ; + + ex << errinfo_now(time(0)); + ex << errinfo_block(_block.block.toBytes()); + if (!_block.info.extraData().empty()) + ex << errinfo_extraData(_block.info.extraData()); + throw; + } + catch ( FilterCheckFail const& ex) + { + LOG(WARNING) << "*** Bad BlockLimit error! Trying to import" << _block.info.hash() ; + ex << errinfo_now(time(0)); + ex << errinfo_block(_block.block.toBytes()); + if (!_block.info.extraData().empty()) + ex << errinfo_extraData(_block.info.extraData()); + throw; + } + catch ( BcBlockLimitCheckError & ex ) + { + LOG(WARNING) << "*** Bad BlockLimit error! Trying to import" << _block.info.hash() ; + //if( goodTransactions.size() ) + //LOG(WARNING)<<" "delCache(goodTransactions); + + LOG(WARNING) << "*** Bad Nonce error! Trying to import" << _block.info.hash() ; + + ex << errinfo_now(time(0)); + ex << errinfo_block(_block.block.toBytes()); + if (!_block.info.extraData().empty()) + ex << errinfo_extraData(_block.info.extraData()); + throw; + } + catch (Exception& ex) + { + + LOG(ERROR) << boost::current_exception_diagnostic_information() << endl; + m_pnoncecheck->delCache(goodTransactions); + ex << errinfo_now(time(0)); + ex << errinfo_block(_block.block.toBytes()); + // only populate extraData if we actually managed to extract it. otherwise, + // we might be clobbering the existing one. + if (!_block.info.extraData().empty()) + ex << errinfo_extraData(_block.info.extraData()); + throw; + } +#endif // ETH_CATCH + + bool isunclechain = false; + + h256s route; + h256 common; + bool isImportedAndBest = false; + // This might be the new best block... + h256 last = currentHash(); + if (td > details(last).totalDifficulty || (m_sealEngine->chainParams().tieBreakingGas && td == details(last).totalDifficulty && _block.info.gasUsed() > info(last).gasUsed())) + { + // don't include bi.hash() in treeRoute, since it's not yet in details DB... + // just tack it on afterwards. + unsigned commonIndex; + tie(route, common, commonIndex) = treeRoute(last, _block.info.parentHash()); + route.push_back(_block.info.hash()); + + // Most of the time these two will be equal - only when we're doing a chain revert will they not be + if (common != last) + { + clearCachesDuringChainReversion(number(common) + 1); + isunclechain = true; + } + + + // Go through ret backwards (i.e. from new head to common) until hash != last.parent and + // update m_transactionAddresses, m_blockHashes + for (auto i = route.rbegin(); i != route.rend() && *i != common; ++i) + { + BlockHeader tbi; + if (*i == _block.info.hash()) + tbi = _block.info; + else + tbi = BlockHeader(block(*i)); + + // Collate logs into blooms. + h256s alteredBlooms; + { + LogBloom blockBloom = tbi.logBloom(); + blockBloom.shiftBloom<3>(sha3(tbi.author().ref())); + + // Pre-memoize everything we need before locking x_blocksBlooms + for (unsigned level = 0, index = (unsigned)tbi.number(); level < c_bloomIndexLevels; level++, index /= c_bloomIndexSize) + blocksBlooms(chunkId(level, index / c_bloomIndexSize)); + + WriteGuard l(x_blocksBlooms); + for (unsigned level = 0, index = (unsigned)tbi.number(); level < c_bloomIndexLevels; level++, index /= c_bloomIndexSize) + { + unsigned i = index / c_bloomIndexSize; + unsigned o = index % c_bloomIndexSize; + alteredBlooms.push_back(chunkId(level, i)); + m_blocksBlooms[alteredBlooms.back()].blooms[o] |= blockBloom; + } + } + // Collate transaction hashes and remember who they were. + + { + bytes blockBytes; + RLP blockRLP(*i == _block.info.hash() ? _block.block : & (blockBytes = block(*i))); + TransactionAddress ta; + ta.blockHash = tbi.hash(); + for (ta.index = 0; ta.index < blockRLP[1].itemCount(); ++ta.index) + extrasBatch.Put(toSlice(sha3(blockRLP[1][ta.index].data()), ExtraTransactionAddress), (ldb::Slice)dev::ref(ta.rlp())); + + } + + // Update database with them. + ReadGuard l1(x_blocksBlooms); + for (auto const& h : alteredBlooms) + extrasBatch.Put(toSlice(h, ExtraBlocksBlooms), (ldb::Slice)dev::ref(m_blocksBlooms[h].rlp())); + extrasBatch.Put(toSlice(h256(tbi.number()), ExtraBlockHash), (ldb::Slice)dev::ref(BlockHash(tbi.hash()).rlp())); + } + + // FINALLY! change our best hash. + { + newLastBlockHash = _block.info.hash(); + newLastBlockNumber = (unsigned)_block.info.number(); + isImportedAndBest = true; + } + + LOG(TRACE) << " Imported and best" << td << " (#" << _block.info.number() << "). Has" << (details(_block.info.parentHash()).children.size() - 1) << "siblings. Route:" << route << " transcations size=" << goodTransactions.size() << ",genIndex=" << _block.info.genIndex(); + if(_block.info.gasUsed() > ((BlockHeader::maxBlockHeadGas*CGasUsedLimit)/100)) + { + LOGCOMWARNING << WarningMap.at(GasUsedWarning)<<"|blockNumber:"<<_block.info.number()<<" gasUsed:"<<_block.info.gasUsed(); + } + } + else + { + LOG(TRACE) << " Imported but not best (oTD:" << details(last).totalDifficulty << " > TD:" << td << "; " << details(last).number << ".." << _block.info.number() << ")"; + } + +#ifdef ETH_DEBUG + if(!m_bifurcate.count(_block.info.number())){ + m_bifurcate[_block.info.number()] = h256Set(); + } + + m_bifurcate[_block.info.number()].insert(_block.info.hash()); + if(m_bifurcate[_block.info.number()].size() > 1){ + LOG(TRACE) << "m_bifurcatealready:" << td << " (#" << _block.info.number() << "). Has" << (details(_block.info.parentHash()).children.size() - 1) << "siblings. Route:" << route << " transcations size=" << goodTransactions.size() << ",genIndex=" << _block.info.genIndex() << ",m_bifurcate[_block.info.number()]=" << m_bifurcate[_block.info.number()]; + }else{ + LOG(TRACE) << "notm_bifurcatealready" << td << " (#" << _block.info.number() << "). Has" << (details(_block.info.parentHash()).children.size() - 1) << "siblings. Route:" << route << " transcations size=" << goodTransactions.size() << ",genIndex=" << _block.info.genIndex() << ",m_bifurcate[_block.info.number()]=" << m_bifurcate[_block.info.number()]; + } +#endif + + ldb::Status o = m_blocksDB->Write(m_writeOptions, &blocksBatch); + if (!o.ok()) + { + LOG(WARNING) << "Error writing to blockchain database: " << o.ToString(); + WriteBatchNoter n; + blocksBatch.Iterate(&n); + LOG(WARNING) << "Fail writing to blockchain database. Bombing out."; + exit(-1); + } + + o = m_extrasDB->Write(m_writeOptions, &extrasBatch); + if (!o.ok()) + { + LOG(WARNING) << "Error writing to extras database: " << o.ToString(); + WriteBatchNoter n; + extrasBatch.Iterate(&n); + LOG(WARNING) << "Fail writing to extras database. Bombing out."; + exit(-1); + } + +#if ETH_PARANOIA + if (isKnown(_block.info.hash()) && !details(_block.info.hash())) + { + LOG(DEBUG) << "Known block just inserted has no details."; + LOG(DEBUG) << "Block:" << _block.info; + LOG(DEBUG) << "DATABASE CORRUPTION: CRITICAL FAILURE"; + exit(-1); + } + + try + { + State canary(_db, BaseState::Empty); + canary.populateFromChain(*this, _block.info.hash()); + } + catch (...) + { + LOG(DEBUG) << "Failed to initialise State object form imported block."; + LOG(DEBUG) << "Block:" << _block.info; + LOG(DEBUG) << "DATABASE CORRUPTION: CRITICAL FAILURE"; + exit(-1); + } +#endif // ETH_PARANOIA + + m_pnoncecheck->delCache(goodTransactions); + + if (m_lastBlockHash != newLastBlockHash) + + { + DEV_WRITE_GUARDED(x_lastBlockHash) + { + m_lastBlockHash = newLastBlockHash; + m_lastBlockNumber = newLastBlockNumber; + + o = m_extrasDB->Put(m_writeOptions, ldb::Slice("best"), ldb::Slice((char const*)&m_lastBlockHash, 32)); + if (!o.ok()) + { + LOG(WARNING) << "Error writing to extras database: " << o.ToString(); + cout << "Put" << toHex(bytesConstRef(ldb::Slice("best"))) << "=>" << toHex(bytesConstRef(ldb::Slice((char const*)&m_lastBlockHash, 32))); + LOG(WARNING) << "Fail writing to extras database. Bombing out."; + exit(-1); + } + } + + + m_pnoncecheck->updateCache(*this, isunclechain); + this->updateSystemContract(tempBlock); + } + +#if ETH_PARANOIA + checkConsistency(); +#endif // ETH_PARANOIA + +#if ETH_TIMED_IMPORTS + checkBest = t.elapsed(); + if (total.elapsed() > 0.5) + { + unsigned const gasPerSecond = static_cast(_block.info.gasUsed()) / enactment; + LOG(TRACE) << "SLOW IMPORT: " + << "{ \"blockHash\": \"" << _block.info.hash() << "\", " + << "\"blockNumber\": " << _block.info.number() << ", " + << "\"importTime\": " << total.elapsed() << ", " + << "\"gasPerSecond\": " << gasPerSecond << ", " + << "\"preliminaryChecks\":" << preliminaryChecks << ", " + << "\"enactment\":" << enactment << ", " + << "\"collation\":" << collation << ", " + << "\"writing\":" << writing << ", " + << "\"checkBest\":" << checkBest << ", " + << "\"transactions\":" << _block.transactions.size() << ", " + << "\"gasUsed\":" << _block.info.gasUsed() << " }"; + } +#endif // ETH_TIMED_IMPORTS + + if (!route.empty()) + noteCanonChanged(); + + if (isImportedAndBest && m_onBlockImport) + m_onBlockImport(_block.info); + + h256s fresh; + h256s dead; + bool isOld = true; + for (auto const& h : route) + if (h == common) + isOld = false; + else if (isOld) + dead.push_back(h); + else + fresh.push_back(h); + return ImportRoute{dead, fresh, move(goodTransactions)}; +} + +void BlockChain::clearBlockBlooms(unsigned _begin, unsigned _end) +{ + // ... c c c c c c c c c c C o o o o o o + // ... /=15 /=21 + // L0...| ' | ' | ' | ' | ' | ' | ' | 'b|x'x|x'x|x'e| /=11 + // L1...| ' | ' | ' | ' b | x ' x | x ' e | /=6 + // L2...| ' | ' b | x ' x | e /=3 + // L3...| ' b | x ' e + // model: c_bloomIndexLevels = 4, c_bloomIndexSize = 2 + + // ... /=15 /=21 + // L0...| ' ' ' | ' ' ' | ' ' ' | ' ' 'b|x'x'x'x|x'e' ' | + // L1...| ' ' ' b | x ' x ' e ' | + // L2...| b ' x ' e ' | + // model: c_bloomIndexLevels = 2, c_bloomIndexSize = 4 + + // algorithm doesn't have the best memoisation coherence, but eh well... + + unsigned beginDirty = _begin; + unsigned endDirty = _end; + for (unsigned level = 0; level < c_bloomIndexLevels; level++, beginDirty /= c_bloomIndexSize, endDirty = (endDirty - 1) / c_bloomIndexSize + 1) + { + // compute earliest & latest index for each level, rebuild from previous levels. + for (unsigned item = beginDirty; item != endDirty; ++item) + { + unsigned bunch = item / c_bloomIndexSize; + unsigned offset = item % c_bloomIndexSize; + auto id = chunkId(level, bunch); + LogBloom acc; + if (!!level) + { + // rebuild the bloom from the previous (lower) level (if there is one). + auto lowerChunkId = chunkId(level - 1, item); + for (auto const& bloom : blocksBlooms(lowerChunkId).blooms) + acc |= bloom; + } + blocksBlooms(id); // make sure it has been memoized. + m_blocksBlooms[id].blooms[offset] = acc; + } + } +} + +void BlockChain::rescue(OverlayDB const& _db) +{ + cout << "Rescuing database..." << endl; + + unsigned u = 1; + while (true) + { + try { + if (isKnown(numberHash(u))) + u *= 2; + else + break; + } + catch (...) + { + break; + } + } + unsigned l = u / 2; + cout << "Finding last likely block number..." << endl; + while (u - l > 1) + { + unsigned m = (u + l) / 2; + cout << " " << m << flush; + if (isKnown(numberHash(m))) + l = m; + else + u = m; + } + cout << " lowest is " << l << endl; + for (; l > 0; --l) + { + h256 h = numberHash(l); + cout << "Checking validity of " << l << " (" << h << ")..." << flush; + try + { + cout << "block..." << flush; + BlockHeader bi(block(h)); + cout << "extras..." << flush; + details(h); + cout << "state..." << flush; + if (_db.exists(bi.stateRoot())) + break; + } + catch (...) {} + } + cout << "OK." << endl; + rewind(l); +} + +void BlockChain::rewind(unsigned _newHead) +{ + DEV_WRITE_GUARDED(x_lastBlockHash) + { + if (_newHead >= m_lastBlockNumber) + return; + clearCachesDuringChainReversion(_newHead + 1); + m_lastBlockHash = numberHash(_newHead); + m_lastBlockNumber = _newHead; + auto o = m_extrasDB->Put(m_writeOptions, ldb::Slice("best"), ldb::Slice((char const*)&m_lastBlockHash, 32)); + if (!o.ok()) + { + LOG(WARNING) << "Error writing to extras database: " << o.ToString(); + cout << "Put" << toHex(bytesConstRef(ldb::Slice("best"))) << "=>" << toHex(bytesConstRef(ldb::Slice((char const*)&m_lastBlockHash, 32))); + LOG(WARNING) << "Fail writing to extras database. Bombing out."; + exit(-1); + } + noteCanonChanged(); + } +} + +tuple BlockChain::treeRoute(h256 const& _from, h256 const& _to, bool _common, bool _pre, bool _post) const +{ +// LOG(DEBUG) << "treeRoute" << _from << "..." << _to; + if (!_from || !_to) + return make_tuple(h256s(), h256(), 0); + h256s ret; + h256s back; + unsigned fn = details(_from).number; + unsigned tn = details(_to).number; +// LOG(DEBUG) << "treeRoute" << fn << "..." << tn; + h256 from = _from; + while (fn > tn) + { + if (_pre) + ret.push_back(from); + from = details(from).parent; + fn--; +// LOG(DEBUG) << "from:" << fn << _from; + } + h256 to = _to; + while (fn < tn) + { + if (_post) + back.push_back(to); + to = details(to).parent; + tn--; +// LOG(DEBUG) << "to:" << tn << _to; + } + for (;; from = details(from).parent, to = details(to).parent) + { + if (_pre && (from != to || _common)) + ret.push_back(from); + if (_post && (from != to || (!_pre && _common))) + back.push_back(to); + fn--; + tn--; +// LOG(DEBUG) << "from:" << fn << _from << "; to:" << tn << _to; + if (from == to) + break; + if (!from) + assert(from); + if (!to) + assert(to); + } + ret.reserve(ret.size() + back.size()); + unsigned i = ret.size() - (int)(_common && !ret.empty() && !back.empty()); + for (auto it = back.rbegin(); it != back.rend(); ++it) + ret.push_back(*it); + return make_tuple(ret, from, i); +} + +void BlockChain::noteUsed(h256 const& _h, unsigned _extra) const +{ + auto id = CacheID(_h, _extra); + Guard l(x_cacheUsage); + m_cacheUsage[0].insert(id); + if (m_cacheUsage[1].count(id)) + m_cacheUsage[1].erase(id); + else + m_inUse.insert(id); +} + +template static unsigned getHashSize(unordered_map const& _map) +{ + unsigned ret = 0; + for (auto const& i : _map) + ret += i.second.size + 64; + return ret; +} + +void BlockChain::updateStats() const +{ + m_lastStats.memBlocks = 0; + DEV_READ_GUARDED(x_blocks) + for (auto const& i : m_blocks) + m_lastStats.memBlocks += i.second.size() + 64; + DEV_READ_GUARDED(x_details) + m_lastStats.memDetails = getHashSize(m_details); + DEV_READ_GUARDED(x_logBlooms) + DEV_READ_GUARDED(x_blocksBlooms) + m_lastStats.memLogBlooms = getHashSize(m_logBlooms) + getHashSize(m_blocksBlooms); + DEV_READ_GUARDED(x_receipts) + m_lastStats.memReceipts = getHashSize(m_receipts); + DEV_READ_GUARDED(x_blockHashes) + m_lastStats.memBlockHashes = getHashSize(m_blockHashes); + DEV_READ_GUARDED(x_transactionAddresses) + m_lastStats.memTransactionAddresses = getHashSize(m_transactionAddresses); +} + +void BlockChain::garbageCollect(bool _force) +{ + updateStats(); + + if (!_force && chrono::system_clock::now() < m_lastCollection + c_collectionDuration && m_lastStats.memTotal() < c_maxCacheSize) + return; + if (m_lastStats.memTotal() < c_minCacheSize) + return; + + m_lastCollection = chrono::system_clock::now(); + + Guard l(x_cacheUsage); + WriteGuard l1(x_blocks); + WriteGuard l2(x_details); + WriteGuard l3(x_blockHashes); + WriteGuard l4(x_receipts); + WriteGuard l5(x_logBlooms); + WriteGuard l6(x_transactionAddresses); + WriteGuard l7(x_blocksBlooms); + for (CacheID const& id : m_cacheUsage.back()) + { + m_inUse.erase(id); + // kill i from cache. + switch (id.second) + { + case (unsigned)-1: + m_blocks.erase(id.first); + break; + case ExtraDetails: + m_details.erase(id.first); + break; + case ExtraReceipts: + m_receipts.erase(id.first); + break; + case ExtraLogBlooms: + m_logBlooms.erase(id.first); + break; + case ExtraTransactionAddress: + m_transactionAddresses.erase(id.first); + break; + case ExtraBlocksBlooms: + m_blocksBlooms.erase(id.first); + break; + } + } + m_cacheUsage.pop_back(); + m_cacheUsage.push_front(std::unordered_set {}); +} + +void BlockChain::checkConsistency() +{ + DEV_WRITE_GUARDED(x_details) + m_details.clear(); + ldb::Iterator* it = m_blocksDB->NewIterator(m_readOptions); + for (it->SeekToFirst(); it->Valid(); it->Next()) + if (it->key().size() == 32) + { + h256 h((byte const*)it->key().data(), h256::ConstructFromPointer); + auto dh = details(h); + auto p = dh.parent; + if (p != h256() && p != m_genesisHash) // TODO: for some reason the genesis details with the children get squished. not sure why. + { + auto dp = details(p); + if (asserts(contains(dp.children, h))) + LOG(TRACE) << "Apparently the database is corrupt. Not much we can do at this stage..."; + if (assertsEqual(dp.number, dh.number - 1)) + LOG(TRACE) << "Apparently the database is corrupt. Not much we can do at this stage..."; + } + } + delete it; +} + +void BlockChain::clearCachesDuringChainReversion(unsigned _firstInvalid) +{ + unsigned end = number() + 1; + DEV_WRITE_GUARDED(x_blockHashes) + for (auto i = _firstInvalid; i < end; ++i) + m_blockHashes.erase(i); + DEV_WRITE_GUARDED(x_transactionAddresses) + m_transactionAddresses.clear(); // TODO: could perhaps delete them individually? + + // If we are reverting previous blocks, we need to clear their blooms (in particular, to + // rebuild any higher level blooms that they contributed to). + clearBlockBlooms(_firstInvalid, end); +} + +static inline unsigned upow(unsigned a, unsigned b) { if (!b) return 1; while (--b > 0) a *= a; return a; } +static inline unsigned ceilDiv(unsigned n, unsigned d) { return (n + d - 1) / d; } +//static inline unsigned floorDivPow(unsigned n, unsigned a, unsigned b) { return n / upow(a, b); } +//static inline unsigned ceilDivPow(unsigned n, unsigned a, unsigned b) { return ceilDiv(n, upow(a, b)); } + +// Level 1 +// [xxx. ] + +// Level 0 +// [.x............F.] +// [........x.......] +// [T.............x.] +// [............ ] + +// F = 14. T = 32 + +vector BlockChain::withBlockBloom(LogBloom const& _b, unsigned _earliest, unsigned _latest) const +{ + vector ret; + + // start from the top-level + unsigned u = upow(c_bloomIndexSize, c_bloomIndexLevels); + + // run through each of the top-level blockbloom blocks + for (unsigned index = _earliest / u; index <= ceilDiv(_latest, u); ++index) // 0 + ret += withBlockBloom(_b, _earliest, _latest, c_bloomIndexLevels - 1, index); + + return ret; +} + +vector BlockChain::withBlockBloom(LogBloom const& _b, unsigned _earliest, unsigned _latest, unsigned _level, unsigned _index) const +{ + // 14, 32, 1, 0 + // 14, 32, 0, 0 + // 14, 32, 0, 1 + // 14, 32, 0, 2 + + vector ret; + + unsigned uCourse = upow(c_bloomIndexSize, _level + 1); + // 256 + // 16 + unsigned uFine = upow(c_bloomIndexSize, _level); + // 16 + // 1 + + unsigned obegin = _index == _earliest / uCourse ? _earliest / uFine % c_bloomIndexSize : 0; + // 0 + // 14 + // 0 + // 0 + unsigned oend = _index == _latest / uCourse ? (_latest / uFine) % c_bloomIndexSize + 1 : c_bloomIndexSize; + // 3 + // 16 + // 16 + // 1 + + BlocksBlooms bb = blocksBlooms(_level, _index); + for (unsigned o = obegin; o < oend; ++o) + if (bb.blooms[o].contains(_b)) + { + // This level has something like what we want. + if (_level > 0) + ret += withBlockBloom(_b, _earliest, _latest, _level - 1, o + _index * c_bloomIndexSize); + else + ret.push_back(o + _index * c_bloomIndexSize); + } + return ret; +} + +h256Hash BlockChain::allKinFrom(h256 const& _parent, unsigned _generations) const +{ + // Get all uncles cited given a parent (i.e. featured as uncles/main in parent, parent + 1, ... parent + 5). + h256 p = _parent; + h256Hash ret = { p }; + // p and (details(p).parent: i == 5) is likely to be overkill, but can't hurt to be cautious. + for (unsigned i = 0; i < _generations && p != m_genesisHash; ++i, p = details(p).parent) + { + ret.insert(details(p).parent); + auto b = block(p); + for (auto i : RLP(b)[2]) + ret.insert(sha3(i.data())); + } + return ret; +} + +bool BlockChain::isKnown(h256 const& _hash, bool _isCurrent) const +{ + if (_hash == m_genesisHash) + return true; + + DEV_READ_GUARDED(x_blocks) + if (!m_blocks.count(_hash)) + { + string d; + m_blocksDB->Get(m_readOptions, toSlice(_hash), &d); + if (d.empty()) + return false; + } + DEV_READ_GUARDED(x_details) + if (!m_details.count(_hash)) + { + string d; + m_extrasDB->Get(m_readOptions, toSlice(_hash, ExtraDetails), &d); + if (d.empty()) + return false; + } +// return true; + return !_isCurrent || details(_hash).number <= m_lastBlockNumber; // to allow rewind functionality. +} + +bytes BlockChain::block(h256 const& _hash) const +{ + if (_hash == m_genesisHash) + return m_params.genesisBlock(); + + { + ReadGuard l(x_blocks); + auto it = m_blocks.find(_hash); + if (it != m_blocks.end()) + return it->second; + } + + //LOG(TRACE)<<"BlockChain::block"<<_hash; + + string d; + m_blocksDB->Get(m_readOptions, toSlice(_hash), &d); + + if (d.empty()) + { + LOG(WARNING) << "Couldn't find requested block:" << _hash; + return bytes(); + } + + noteUsed(_hash); + + WriteGuard l(x_blocks); + m_blocks[_hash].resize(d.size()); + memcpy(m_blocks[_hash].data(), d.data(), d.size()); + + return m_blocks[_hash]; +} + +bytes BlockChain::headerData(h256 const& _hash) const +{ + if (_hash == m_genesisHash) + return m_genesisHeaderBytes; + + { + ReadGuard l(x_blocks); + auto it = m_blocks.find(_hash); + if (it != m_blocks.end()) + return BlockHeader::extractHeader(&it->second).data().toBytes(); + } + + string d; + m_blocksDB->Get(m_readOptions, toSlice(_hash), &d); + + if (d.empty()) + { + LOG(WARNING) << "Couldn't find requested block:" << _hash; + return bytes(); + } + + noteUsed(_hash); + + WriteGuard l(x_blocks); + m_blocks[_hash].resize(d.size()); + memcpy(m_blocks[_hash].data(), d.data(), d.size()); + + return BlockHeader::extractHeader(&m_blocks[_hash]).data().toBytes(); +} + +Block BlockChain::genesisBlock(OverlayDB const& _db) const +{ + h256 r = BlockHeader(m_params.genesisBlock()).stateRoot(); + Block ret(*this, _db, BaseState::Empty); + if (!_db.exists(r)) + { + ret.noteChain(*this); + dev::eth::commit(m_params.genesisState, ret.mutableState().m_state); // bit horrible. maybe consider a better way of constructing it? + ret.mutableState().db().commit(); // have to use this db() since it's the one that has been altered with the above commit. + if (ret.mutableState().rootHash() != r) + { + LOG(WARNING) << "Hinted genesis block's state root hash is incorrect!"; + LOG(WARNING) << "Hinted" << r << ", computed" << ret.mutableState().rootHash(); + // TODO: maybe try to fix it by altering the m_params's genesis block? + exit(-1); + } + } + ret.m_previousBlock = BlockHeader(m_params.genesisBlock()); + ret.resetCurrent(); + return ret; +} + +VerifiedBlockRef BlockChain::verifyBlock(bytesConstRef _block, std::function const& _onBad, ImportRequirements::value _ir) const +{ + VerifiedBlockRef res; + BlockHeader h; + try + { + h = BlockHeader(_block); + if (!!(_ir & ImportRequirements::PostGenesis) && (!h.parentHash() || h.number() == 0)) + BOOST_THROW_EXCEPTION(InvalidParentHash() << errinfo_required_h256(h.parentHash()) << errinfo_currentNumber(h.number())); + + BlockHeader parent; + if (!!(_ir & ImportRequirements::Parent)) + { + bytes parentHeader(headerData(h.parentHash())); + if (parentHeader.empty()) + BOOST_THROW_EXCEPTION(InvalidParentHash() << errinfo_required_h256(h.parentHash()) << errinfo_currentNumber(h.number())); + parent = BlockHeader(parentHeader, HeaderData, h.parentHash()); + } + sealEngine()->verify((_ir & ImportRequirements::ValidSeal) ? Strictness::CheckEverything : Strictness::QuickNonce, h, parent, _block); + res.info = h; + } + catch (Exception& ex) + { + ex << errinfo_phase(1); + ex << errinfo_now(time(0)); + ex << errinfo_block(_block.toBytes()); + // only populate extraData if we actually managed to extract it. otherwise, + // we might be clobbering the existing one. + if (!h.extraData().empty()) + ex << errinfo_extraData(h.extraData()); + if (_onBad) + _onBad(ex); + throw; + } + + RLP r(_block); + unsigned i = 0; + if (_ir & (ImportRequirements::UncleBasic | ImportRequirements::UncleParent | ImportRequirements::UncleSeals)) + for (auto const& uncle : r[2]) + { + BlockHeader uh(uncle.data(), HeaderData); + try + { + BlockHeader parent; + if (!!(_ir & ImportRequirements::UncleParent)) + { + bytes parentHeader(headerData(uh.parentHash())); + if (parentHeader.empty()) + BOOST_THROW_EXCEPTION(InvalidUncleParentHash() << errinfo_required_h256(uh.parentHash()) << errinfo_currentNumber(h.number()) << errinfo_uncleNumber(uh.number())); + parent = BlockHeader(parentHeader, HeaderData, uh.parentHash()); + } + sealEngine()->verify((_ir & ImportRequirements::UncleSeals) ? Strictness::CheckEverything : Strictness::IgnoreSeal, uh, parent); + } + catch (Exception& ex) + { + ex << errinfo_phase(1); + ex << errinfo_uncleIndex(i); + ex << errinfo_now(time(0)); + ex << errinfo_block(_block.toBytes()); + // only populate extraData if we actually managed to extract it. otherwise, + // we might be clobbering the existing one. + if (!uh.extraData().empty()) + ex << errinfo_extraData(uh.extraData()); + if (_onBad) + _onBad(ex); + throw; + } + ++i; + } + i = 0; + if (_ir & (ImportRequirements::TransactionBasic | ImportRequirements::TransactionSignatures)) + for (RLP const& tr : r[1]) + { + bytesConstRef d = tr.data(); + try + { + Transaction t(d, (_ir & ImportRequirements::TransactionSignatures) ? CheckTransaction::Everything : CheckTransaction::None); + m_sealEngine->verifyTransaction(_ir, t, h); + res.transactions.push_back(t); + } + catch (Exception& ex) + { + ex << errinfo_phase(1); + ex << errinfo_transactionIndex(i); + ex << errinfo_transaction(d.toBytes()); + ex << errinfo_block(_block.toBytes()); + // only populate extraData if we actually managed to extract it. otherwise, + // we might be clobbering the existing one. + if (!h.extraData().empty()) + ex << errinfo_extraData(h.extraData()); + if (_onBad) + _onBad(ex); + throw; + } + ++i; + } + + // 验证签名 + if (_ir & ImportRequirements::CheckMinerSignatures) { + if (m_sign_checker && !m_sign_checker(h, r[4].toVector>())) { + LOG(WARNING) << "Error - check sign failed:" << h.number(); + BOOST_THROW_EXCEPTION(CheckSignFailed()); + } + } + + res.block = bytesConstRef(_block); + return res; +} diff --git a/libethereum/BlockChain.h b/libethereum/BlockChain.h new file mode 100644 index 0000000000..b7aad86858 --- /dev/null +++ b/libethereum/BlockChain.h @@ -0,0 +1,460 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file BlockChain.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include "BlockDetails.h" +#include "Account.h" +#include "Transaction.h" +#include "BlockQueue.h" +#include "VerifiedBlock.h" +#include "ChainParams.h" +#include "State.h" +#include +#include "Interface.h" + +namespace std +{ +template <> struct hash> +{ + size_t operator()(pair const& _x) const { return hash()(_x.first) ^ hash()(_x.second); } +}; +} + +namespace dev +{ + +class OverlayDB; + +namespace eth +{ + +static const h256s NullH256s; + +class State; +class Block; +class NonceCheck; + +DEV_SIMPLE_EXCEPTION(AlreadyHaveBlock); +DEV_SIMPLE_EXCEPTION(FutureTime); +DEV_SIMPLE_EXCEPTION(TransientError); +DEV_SIMPLE_EXCEPTION(HashError); +DEV_SIMPLE_EXCEPTION(MinerListError); +DEV_SIMPLE_EXCEPTION(HeightError); +DEV_SIMPLE_EXCEPTION(BcNonceCheckError); +DEV_SIMPLE_EXCEPTION(BcBlockLimitCheckError); +DEV_SIMPLE_EXCEPTION(BcFilterCheckError); +DEV_SIMPLE_EXCEPTION(BcNoDeployPermissionError); +DEV_SIMPLE_EXCEPTION(CheckSignFailed); + + +// TODO: Move all this Genesis stuff into Genesis.h/.cpp +std::unordered_map const& genesisState(); + +ldb::Slice toSlice(h256 const& _h, unsigned _sub = 0); +ldb::Slice toSlice(uint64_t _n, unsigned _sub = 0); + +using BlocksHash = std::unordered_map; +using TransactionHashes = h256s; +using UncleHashes = h256s; + +enum { + ExtraDetails = 0, + ExtraBlockHash, + ExtraTransactionAddress, + ExtraLogBlooms, + ExtraReceipts, + ExtraBlocksBlooms +}; + +using ProgressCallback = std::function; + +class VersionChecker +{ +public: + VersionChecker(std::string const& _dbPath, h256 const& _genesisHash); +}; + +/** + * @brief Implements the blockchain database. All data this gives is disk-backed. + * @threadsafe + */ +class BlockChain +{ +public: + /// Doesn't open the database - if you want it open it's up to you to subclass this and open it + /// in the constructor there. + BlockChain(std::shared_ptr _interface, ChainParams const& _p, std::string const& _path, WithExisting _we = WithExisting::Trust, ProgressCallback const& _pc = ProgressCallback()); + ~BlockChain(); + + /// Reopen everything. + void reopen(WithExisting _we = WithExisting::Trust, ProgressCallback const& _pc = ProgressCallback()) { reopen(m_params, _we, _pc); } + void reopen(ChainParams const& _p, WithExisting _we = WithExisting::Trust, ProgressCallback const& _pc = ProgressCallback()); + + /// (Potentially) renders invalid existing bytesConstRef returned by lastBlock. + /// To be called from main loop every 100ms or so. + void process(); + + /// Sync the chain with any incoming blocks. All blocks should, if processed in order. + /// @returns fresh blocks, dead blocks and true iff there are additional blocks to be processed waiting. + std::tuple sync(BlockQueue& _bq, OverlayDB const& _stateDB, unsigned _max); + + /// Attempt to import the given block directly into the BlockChain and sync with the state DB. + /// @returns the block hashes of any blocks that came into/went out of the canonical block chain. + std::pair attemptImport(bytes const& _block, OverlayDB const& _stateDB, bool _mutBeNew = true) noexcept; + + /// Import block into disk-backed DB. + /// @returns the block hashes of any blocks that came into/went out of the canonical block chain. + ImportRoute import(bytes const& _block, OverlayDB const& _stateDB, bool _mustBeNew = true); + ImportRoute import(VerifiedBlockRef const& _block, OverlayDB const& _db, bool _mustBeNew = true); + + /// Import data into disk-backed DB. + /// This will not execute the block and populate the state trie, but rather will simply add the + /// block/header and receipts directly into the databases. + void insert(bytes const& _block, bytesConstRef _receipts, bool _mustBeNew = true); + void insert(VerifiedBlockRef _block, bytesConstRef _receipts, bool _mustBeNew = true); + + /// Returns true if the given block is known (though not necessarily a part of the canon chain). + bool isKnown(h256 const& _hash, bool _isCurrent = true) const; + + /// Get the partial-header of a block (or the most recent mined if none given). Thread-safe. + BlockHeader info(h256 const& _hash) const { return BlockHeader(headerData(_hash), HeaderData); } + BlockHeader info() const { return info(currentHash()); } + + /// Get a block (RLP format) for the given hash (or the most recent mined if none given). Thread-safe. + bytes block(h256 const& _hash) const; + bytes block() const { return block(currentHash()); } + + /// Get a block (RLP format) for the given hash (or the most recent mined if none given). Thread-safe. + bytes headerData(h256 const& _hash) const; + bytes headerData() const { return headerData(currentHash()); } + + /// Get the familial details concerning a block (or the most recent mined if none given). Thread-safe. + BlockDetails details(h256 const& _hash) const { return queryExtras(_hash, m_details, x_details, NullBlockDetails); } + BlockDetails details() const { return details(currentHash()); } + + /// Get the transactions' log blooms of a block (or the most recent mined if none given). Thread-safe. + BlockLogBlooms logBlooms(h256 const& _hash) const { return queryExtras(_hash, m_logBlooms, x_logBlooms, NullBlockLogBlooms); } + BlockLogBlooms logBlooms() const { return logBlooms(currentHash()); } + + /// Get the transactions' receipts of a block (or the most recent mined if none given). Thread-safe. + /// receipts are given in the same order are in the same order as the transactions + BlockReceipts receipts(h256 const& _hash) const { return queryExtras(_hash, m_receipts, x_receipts, NullBlockReceipts); } + BlockReceipts receipts() const { return receipts(currentHash()); } + + /// Get the transaction by block hash and index; + TransactionReceipt transactionReceipt(h256 const& _blockHash, unsigned _i) const { return receipts(_blockHash).receipts[_i]; } + + /// Get the transaction receipt by transaction hash. Thread-safe. + TransactionReceipt transactionReceipt(h256 const& _transactionHash) const { TransactionAddress ta = queryExtras(_transactionHash, m_transactionAddresses, x_transactionAddresses, NullTransactionAddress); if (!ta) return bytesConstRef(); return transactionReceipt(ta.blockHash, ta.index); } + + /// Get a list of transaction hashes for a given block. Thread-safe. + TransactionHashes transactionHashes(h256 const& _hash) const { auto b = block(_hash); RLP rlp(b); h256s ret; for (auto t : rlp[1]) ret.push_back(sha3(t.data())); return ret; } + TransactionHashes transactionHashes() const { return transactionHashes(currentHash()); } + + /// Get a list of uncle hashes for a given block. Thread-safe. + UncleHashes uncleHashes(h256 const& _hash) const { auto b = block(_hash); RLP rlp(b); h256s ret; for (auto t : rlp[2]) ret.push_back(sha3(t.data())); return ret; } + UncleHashes uncleHashes() const { return uncleHashes(currentHash()); } + + /// Get the hash for a given block's number. + h256 numberHash(unsigned _i) const { if (!_i) return genesisHash(); return queryExtras(_i, m_blockHashes, x_blockHashes, NullBlockHash).value; } + + /// Get the last N hashes for a given block. (N is determined by the LastHashes type.) + LastHashes lastHashes() const { return lastHashes(m_lastBlockHash); } + LastHashes lastHashes(h256 const& _mostRecentHash) const; + + /** Get the block blooms for a number of blocks. Thread-safe. + * @returns the object pertaining to the blocks: + * level 0: + * 0x, 0x + 1, .. (1x - 1) + * 1x, 1x + 1, .. (2x - 1) + * ... + * (255x .. (256x - 1)) + * level 1: + * 0x .. (1x - 1), 1x .. (2x - 1), ..., (255x .. (256x - 1)) + * 256x .. (257x - 1), 257x .. (258x - 1), ..., (511x .. (512x - 1)) + * ... + * level n, index i, offset o: + * i * (x ^ n) + o * x ^ (n - 1) + */ + BlocksBlooms blocksBlooms(unsigned _level, unsigned _index) const { return blocksBlooms(chunkId(_level, _index)); } + BlocksBlooms blocksBlooms(h256 const& _chunkId) const { return queryExtras(_chunkId, m_blocksBlooms, x_blocksBlooms, NullBlocksBlooms); } + LogBloom blockBloom(unsigned _number) const { return blocksBlooms(chunkId(0, _number / c_bloomIndexSize)).blooms[_number % c_bloomIndexSize]; } + std::vector withBlockBloom(LogBloom const& _b, unsigned _earliest, unsigned _latest) const; + std::vector withBlockBloom(LogBloom const& _b, unsigned _earliest, unsigned _latest, unsigned _topLevel, unsigned _index) const; + + /// Returns true if transaction is known. Thread-safe + bool isKnownTransaction(h256 const& _transactionHash) const { TransactionAddress ta = queryExtras(_transactionHash, m_transactionAddresses, x_transactionAddresses, NullTransactionAddress); return !!ta; } + + /// Get a transaction from its hash. Thread-safe. + bytes transaction(h256 const& _transactionHash) const { TransactionAddress ta = queryExtras(_transactionHash, m_transactionAddresses, x_transactionAddresses, NullTransactionAddress); if (!ta) return bytes(); return transaction(ta.blockHash, ta.index); } + std::pair transactionLocation(h256 const& _transactionHash) const {TransactionAddress ta = queryExtras(_transactionHash, m_transactionAddresses, x_transactionAddresses, NullTransactionAddress); if (!ta) return std::pair(h256(), 0); return std::make_pair(ta.blockHash, ta.index); } + + /// Get a block's transaction (RLP format) for the given block hash (or the most recent mined if none given) & index. Thread-safe. + bytes transaction(h256 const& _blockHash, unsigned _i) const { bytes b = block(_blockHash); return RLP(b)[1][_i].data().toBytes(); } + bytes transaction(unsigned _i) const { return transaction(currentHash(), _i); } + + /// Get all transactions from a block. + std::vector transactions(h256 const& _blockHash) const { bytes b = block(_blockHash); std::vector ret; for (auto const& i : RLP(b)[1]) ret.push_back(i.data().toBytes()); return ret; } + std::vector transactions() const { return transactions(currentHash()); } + + /// Get a number for the given hash (or the most recent mined if none given). Thread-safe. + unsigned number(h256 const& _hash) const { return details(_hash).number; } + unsigned number() const { return m_lastBlockNumber; } + + /// Get a given block (RLP format). Thread-safe. + h256 currentHash() const { ReadGuard l(x_lastBlockHash); return m_lastBlockHash; } + + /// Get the hash of the genesis block. Thread-safe. + h256 genesisHash() const { return m_genesisHash; } + + /// Get all blocks not allowed as uncles given a parent (i.e. featured as uncles/main in parent, parent + 1, ... parent + @a _generations). + /// @returns set including the header-hash of every parent (including @a _parent) up to and including generation + @a _generations + /// togther with all their quoted uncles. + h256Hash allKinFrom(h256 const& _parent, unsigned _generations) const; + + /// Run through database and verify all blocks by reevaluating. + /// Will call _progress with the progress in this operation first param done, second total. + void rebuild(std::string const& _path, ProgressCallback const& _progress = std::function()); + + /// Alter the head of the chain to some prior block along it. + void rewind(unsigned _newHead); + + /// Rescue the database. + void rescue(OverlayDB const& _db); + + /** @returns a tuple of: + * - an vector of hashes of all blocks between @a _from and @a _to, all blocks are ordered first by a number of + * blocks that are parent-to-child, then two sibling blocks, then a number of blocks that are child-to-parent; + * - the block hash of the latest common ancestor of both blocks; + * - the index where the latest common ancestor of both blocks would either be found or inserted, depending + * on whether it is included. + * + * @param _common if true, include the common ancestor in the returned vector. + * @param _pre if true, include all block hashes running from @a _from until the common ancestor in the returned vector. + * @param _post if true, include all block hashes running from the common ancestor until @a _to in the returned vector. + * + * e.g. if the block tree is 3a -> 2a -> 1a -> g and 2b -> 1b -> g (g is genesis, *a, *b are competing chains), + * then: + * @code + * treeRoute(3a, 2b, false) == make_tuple({ 3a, 2a, 1a, 1b, 2b }, g, 3); + * treeRoute(2a, 1a, false) == make_tuple({ 2a, 1a }, 1a, 1) + * treeRoute(1a, 2a, false) == make_tuple({ 1a, 2a }, 1a, 0) + * treeRoute(1b, 2a, false) == make_tuple({ 1b, 1a, 2a }, g, 1) + * treeRoute(3a, 2b, true) == make_tuple({ 3a, 2a, 1a, g, 1b, 2b }, g, 3); + * treeRoute(2a, 1a, true) == make_tuple({ 2a, 1a }, 1a, 1) + * treeRoute(1a, 2a, true) == make_tuple({ 1a, 2a }, 1a, 0) + * treeRoute(1b, 2a, true) == make_tuple({ 1b, g, 1a, 2a }, g, 1) + * @endcode + */ + std::tuple treeRoute(h256 const& _from, h256 const& _to, bool _common = true, bool _pre = true, bool _post = true) const; + + struct Statistics + { + unsigned memBlocks; + unsigned memDetails; + unsigned memLogBlooms; + unsigned memReceipts; + unsigned memTransactionAddresses; + unsigned memBlockHashes; + unsigned memTotal() const { return memBlocks + memDetails + memLogBlooms + memReceipts + memTransactionAddresses + memBlockHashes; } + }; + + /// @returns statistics about memory usage. + Statistics usage(bool _freshen = false) const { if (_freshen) updateStats(); return m_lastStats; } + + /// Deallocate unused data. + void garbageCollect(bool _force = false); + + /// Change the function that is called with a bad block. + template void setOnBad(T const& _t) { m_onBad = _t; } + /// Change the function that is called when a new block is imported + void setOnBlockImport(std::function _t) { m_onBlockImport = _t; } + + template void setSignChecker(T const& _t) { m_sign_checker = _t; } + + /// Get a pre-made genesis State object. + Block genesisBlock(OverlayDB const& _db) const; + + /// Verify block and prepare it for enactment + VerifiedBlockRef verifyBlock(bytesConstRef _block, std::function const& _onBad, ImportRequirements::value _ir = ImportRequirements::OutOfOrderChecks) const; + + /// Gives a dump of the blockchain database. For debug/test use only. + std::string dumpDatabase() const; + + ChainParams const& chainParams() const { return m_params; } + + SealEngineFace* sealEngine() const { return m_sealEngine.get(); } + + BlockHeader const& genesis() const; + + + bool isBlockLimitOk(Transaction const&_ts) const ; + bool isNonceOk(Transaction const&_ts, bool _needinsert = false) const ; + + u256 filterCheck(const Transaction & _t, FilterCheckScene _checkscene = FilterCheckScene::None) const ; + //void updateSystemContract(Transactions & _transcations); + void updateSystemContract(std::shared_ptr block); + void updateCache(Address address)const; + + static u256 maxBlockLimit; + + void checkBlockValid(h256 const& _head, bytes const& _block, OverlayDB const& _db) const; + + + void addBlockCache(Block block, u256 td) const; + + std::pair getBlockCache(h256 const& hash) const; + + +private: + static h256 chunkId(unsigned _level, unsigned _index) { return h256(_index * 0xff + _level); } + + /// Initialise everything and ready for openning the database. + // TODO: rename to init + void init(ChainParams const& _p, std::string const& _path); + /// Open the database. + // TODO: rename to open. + unsigned open(std::string const& _path, WithExisting _we); + /// Open the database, rebuilding if necessary. + void open(std::string const& _path, WithExisting _we, ProgressCallback const& _pc); + /// Finalise everything and close the database. + void close(); + + template T queryExtras(K const& _h, std::unordered_map& _m, boost::shared_mutex& _x, T const& _n, ldb::DB* _extrasDB = nullptr) const + { + { + ReadGuard l(_x); + auto it = _m.find(_h); + if (it != _m.end()) + return it->second; + } + + std::string s; + (_extrasDB ? _extrasDB : m_extrasDB)->Get(m_readOptions, toSlice(_h, N), &s); + if (s.empty()) + return _n; + + noteUsed(_h, N); + + WriteGuard l(_x); + auto ret = _m.insert(std::make_pair(_h, T(RLP(s)))); + return ret.first->second; + } + + template T queryExtras(h256 const& _h, std::unordered_map& _m, boost::shared_mutex& _x, T const& _n, ldb::DB* _extrasDB = nullptr) const + { + return queryExtras(_h, _m, _x, _n, _extrasDB); + } + + void checkConsistency(); + + /// Clears all caches from the tip of the chain up to (including) _firstInvalid. + /// These include the blooms, the block hashes and the transaction lookup tables. + void clearCachesDuringChainReversion(unsigned _firstInvalid); + void clearBlockBlooms(unsigned _begin, unsigned _end); + + /// The caches of the disk DB and their locks. + mutable SharedMutex x_blocks; + mutable BlocksHash m_blocks; + mutable SharedMutex x_details; + mutable BlockDetailsHash m_details; + mutable SharedMutex x_logBlooms; + mutable BlockLogBloomsHash m_logBlooms; + mutable SharedMutex x_receipts; + mutable BlockReceiptsHash m_receipts; + mutable SharedMutex x_transactionAddresses; + mutable TransactionAddressHash m_transactionAddresses; + mutable SharedMutex x_blockHashes; + mutable BlockHashHash m_blockHashes; + mutable SharedMutex x_blocksBlooms; + mutable BlocksBloomsHash m_blocksBlooms; + + using CacheID = std::pair; + mutable Mutex x_cacheUsage; + mutable std::deque> m_cacheUsage; + mutable std::unordered_set m_inUse; + void noteUsed(h256 const& _h, unsigned _extra = (unsigned) - 1) const; + void noteUsed(uint64_t const& _h, unsigned _extra = (unsigned) - 1) const { (void)_h; (void)_extra; } // don't note non-hash types + std::chrono::system_clock::time_point m_lastCollection; + + void noteCanonChanged() const { Guard l(x_lastLastHashes); m_lastLastHashes.clear(); } + mutable Mutex x_lastLastHashes; + mutable LastHashes m_lastLastHashes; + + void updateStats() const; + mutable Statistics m_lastStats; + + /// The disk DBs. Thread-safe, so no need for locks. + ldb::DB* m_blocksDB; + ldb::DB* m_extrasDB; + + /// Hash of the last (valid) block on the longest chain. + mutable boost::shared_mutex x_lastBlockHash; + h256 m_lastBlockHash; + unsigned m_lastBlockNumber = 0; + + ldb::ReadOptions m_readOptions; + ldb::WriteOptions m_writeOptions; + + ChainParams m_params; + std::shared_ptr m_sealEngine; // consider shared_ptr. + mutable SharedMutex x_genesis; + mutable BlockHeader m_genesis; // mutable because they're effectively memos. + mutable bytes m_genesisHeaderBytes; // mutable because they're effectively memos. + mutable h256 m_genesisHash; // mutable because they're effectively memos. + + std::function m_onBad; ///< Called if we have a block that doesn't verify. + std::function m_onBlockImport; ///< Called if we have imported a new block into the db + std::function>)> m_sign_checker; + + std::string m_dbPath; + + std::shared_ptr m_pnoncecheck; + std::shared_ptr m_interface; + + mutable SharedMutex x_blockcache; + mutable std::map > m_blockCache; + + + friend std::ostream& operator<<(std::ostream& _out, BlockChain const& _bc); + +#ifdef ETH_DEBUG + map m_bifurcate; +#endif +}; + +std::ostream& operator<<(std::ostream& _out, BlockChain const& _bc); + +} +} diff --git a/libethereum/BlockChainSync.cpp b/libethereum/BlockChainSync.cpp new file mode 100644 index 0000000000..f5baaab7b8 --- /dev/null +++ b/libethereum/BlockChainSync.cpp @@ -0,0 +1,1121 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file BlockChainSync.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "BlockChainSync.h" + +#include +#include +#include +#include +#include +#include +#include "BlockChain.h" +#include "BlockQueue.h" +#include "EthereumPeer.h" +#include "EthereumHost.h" +#include + +using namespace std; +using namespace dev; +using namespace dev::eth; +using namespace p2p; + +unsigned const c_maxPeerUknownNewBlocks = 1024; /// Max number of unknown new blocks peer can give us +unsigned const c_maxRequestHeaders = 1024; +unsigned const c_maxRequestBodies = 1024; + + +std::ostream& dev::eth::operator<<(std::ostream& _out, SyncStatus const& _sync) +{ + _out << "protocol: " << _sync.protocolVersion << endl; + _out << "state: " << EthereumHost::stateName(_sync.state) << " "; + if (_sync.state == SyncState::Blocks || _sync.state == SyncState::NewBlocks) + _out << _sync.currentBlockNumber << "/" << _sync.highestBlockNumber; + return _out; +} + +namespace // Helper functions. +{ + +template bool haveItem(std::map& _container, unsigned _number) +{ + if (_container.empty()) + return false; + auto lower = _container.lower_bound(_number); + if (lower != _container.end() && lower->first == _number) + return true; + if (lower == _container.begin()) + return false; + --lower; + return lower->first <= _number && (lower->first + lower->second.size()) > _number; +} + + +template T const* findItem(std::map>& _container, unsigned _number) +{ + if (_container.empty()) + return nullptr; + auto lower = _container.lower_bound(_number); + if (lower != _container.end() && lower->first == _number) + return &(*lower->second.begin()); + if (lower == _container.begin()) + return nullptr; + --lower; + if (lower->first <= _number && (lower->first + lower->second.size()) > _number) + return &lower->second.at(_number - lower->first); + return nullptr; +} + +template void removeItem(std::map>& _container, unsigned _number) +{ + if (_container.empty()) + return; + auto lower = _container.lower_bound(_number); + if (lower != _container.end() && lower->first == _number) + { + auto new_list = std::move(lower->second); + new_list.erase(new_list.begin()); + auto new_key = _number + 1; + _container.erase(lower); + if (new_list.size() > 0) { + _container.insert(std::make_pair(new_key, new_list)); + } + return; + } + if (lower == _container.begin()) { + return; + } + --lower; + if (lower->first <= _number && (lower->first + lower->second.size()) > _number) { + auto new_list = std::move(lower->second); + new_list.erase(new_list.begin(), new_list.begin() + (_number - lower->first + 1)); + auto new_key = _number + 1; + lower->second.erase(lower->second.begin() + (_number - lower->first), lower->second.end()); + if (new_list.size() > 0) { + _container.insert(std::make_pair(new_key, new_list)); + } + } +} + +template void removeAllStartingWith(std::map>& _container, unsigned _number) +{ + if (_container.empty()) + return; + auto lower = _container.lower_bound(_number); + if (lower != _container.end() && lower->first == _number) + { + _container.erase(lower, _container.end()); + return; + } + if (lower == _container.begin()) + { + _container.clear(); + return; + } + --lower; + if (lower->first <= _number && (lower->first + lower->second.size()) > _number) + lower->second.erase(lower->second.begin() + (_number - lower->first), lower->second.end()); + _container.erase(++lower, _container.end()); +} + +template void removeAllSmallerThan(std::map>& _container, unsigned _number) +{ + if (_container.empty()) + return; + auto lower = _container.lower_bound(_number); + if (lower != _container.end() && lower->first == _number) + { + auto new_list = std::move(lower->second); + new_list.erase(new_list.begin()); + auto new_key = _number + 1; + _container.erase(_container.begin(), ++lower); + if (new_list.size() > 0) { + _container.insert(std::make_pair(new_key, new_list)); + } + return; + } + if (lower == _container.begin()) + { + return; + } + --lower; + if (lower->first <= _number && (lower->first + lower->second.size()) > _number) { + auto new_list = std::move(lower->second); + new_list.erase(new_list.begin(), new_list.begin() + (_number - lower->first + 1)); + auto new_key = _number + 1; + _container.erase(_container.begin(), ++lower); + if (new_list.size() > 0) { + _container.insert(std::make_pair(new_key, new_list)); + } + } else { + _container.erase(_container.begin(), ++lower); + } +} + +template void mergeInto(std::map>& _container, unsigned _number, T&& _data) +{ + assert(!haveItem(_container, _number)); + auto lower = _container.lower_bound(_number); + if (!_container.empty() && lower != _container.begin()) + --lower; + if (lower != _container.end() && (lower->first + lower->second.size() == _number)) + { + // extend existing chunk + lower->second.emplace_back(_data); + + auto next = lower; + ++next; + if (next != _container.end() && (lower->first + lower->second.size() == next->first)) + { + // merge with the next chunk + std::move(next->second.begin(), next->second.end(), std::back_inserter(lower->second)); + _container.erase(next); + } + } + else + { + // insert a new chunk + auto inserted = _container.insert(lower, std::make_pair(_number, std::vector { _data })); + auto next = inserted; + ++next; + if (next != _container.end() && next->first == _number + 1) + { + std::move(next->second.begin(), next->second.end(), std::back_inserter(inserted->second)); + _container.erase(next); + } + } +} + +} // Anonymous namespace -- helper functions. + + + +BlockChainSync::BlockChainSync(EthereumHost& _host): + m_host(_host), + m_startingBlock(_host.chain().number()), + m_lastImportedBlock(m_startingBlock), + m_lastImportedBlockHash(_host.chain().currentHash()) +{ + m_bqRoomAvailable = host().bq().onRoomAvailable([this]() + { + RecursiveGuard l(x_sync); + LOG(TRACE) << "onRoomAvailable set state=SyncState::Blocks, before=" << EthereumHost::stateName(m_state); + auto raw_state = m_state; + m_state = SyncState::Blocks; + bool ret = continueSync(); + if (!ret) { + m_state = raw_state; + } + }); +} + +BlockChainSync::~BlockChainSync() +{ + RecursiveGuard l(x_sync); + abortSync(); +} + +void BlockChainSync::onForceSync() { + RecursiveGuard l(x_sync); + if (m_state != SyncState::Blocks) { + LOG(TRACE) << "onForceSync set state=SyncState::Blocks, before=" << EthereumHost::stateName(m_state); + auto raw_state = m_state; + m_state = SyncState::Blocks; + bool ret = continueSync(); + if (!ret) { + m_state = raw_state; + } + } +} + +void BlockChainSync::onBlockImported(BlockHeader const& _info) +{ + //if a block has been added via mining or other block import function + //through RPC, then we should count it as a last imported block + RecursiveGuard l(x_sync); + if (_info.number() > m_lastImportedBlock) + { + m_lastImportedBlock = static_cast(_info.number()); + m_lastImportedBlockHash = _info.hash(); + m_highestBlock = max(m_lastImportedBlock, m_highestBlock); + + auto head = findItem(m_headers, m_lastImportedBlock); + if (head && head->hash == m_lastImportedBlockHash) { // 在下载的块已经上链 + LOG(TRACE) << "BlockChainSync::onBlockImported remove header&body blk=" << m_lastImportedBlock << ",hash=" << m_lastImportedBlockHash; + removeItem(m_headers, m_lastImportedBlock); + removeItem(m_bodies, m_lastImportedBlock); + } + LOG(TRACE) << "BlockChainSync::onBlockImported remove downloading blk=" << m_lastImportedBlock << ",hash=" << m_lastImportedBlockHash; + m_headerIdToNumber.erase(m_lastImportedBlockHash); + m_downloadingBodies.erase(m_lastImportedBlock); + m_downloadingHeaders.erase(m_lastImportedBlock); + if (m_headers.empty()) { + if (!m_bodies.empty()) { + LOG(TRACE) << "Block headers map is empty, but block bodies map is not. Force-clearing."; + m_bodies.clear(); + } + completeSync(); + LOG(TRACE) << "BlockChainSync::onBlockImported completeSync"; + } + } +} + +void BlockChainSync::abortSync() +{ + resetSync(); + host().foreachPeer([&](std::shared_ptr _p) + { + _p->abortSync(); + return true; + }); +} + +void BlockChainSync::onPeerStatus(std::shared_ptr _peer) +{ + RecursiveGuard l(x_sync); + DEV_INVARIANT_CHECK; + std::shared_ptr session = _peer->session(); + if (!session) + return; // Expired + if (_peer->m_genesisHash != host().chain().genesisHash()) + _peer->disable("Invalid genesis hash"); + else if (_peer->m_protocolVersion != host().protocolVersion() && _peer->m_protocolVersion != EthereumHost::c_oldProtocolVersion) + _peer->disable("Invalid protocol version."); + else if (_peer->m_networkId != host().networkId()) + _peer->disable("Invalid network identifier."); + else if (session->info().clientVersion.find("/v0.7.0/") != string::npos) + _peer->disable("Blacklisted client version."); + else if (host().isBanned(session->id())) + _peer->disable("Peer banned for previous bad behaviour."); + else if (_peer->m_asking != Asking::State && _peer->m_asking != Asking::Nothing) + _peer->disable("Peer banned for unexpected status message."); + else { + LOG(TRACE) << "onPeerStatus call syncPeer"; + syncPeer(_peer, false); + } +} + +bool BlockChainSync::syncPeer(std::shared_ptr _peer, bool _force) +{ + + + LOG(TRACE) << "syncPeer: _force=" << _force << ",m_state=" << EthereumHost::stateName(m_state) << ",asking=" << EthereumPeer::toString(_peer->m_asking) << ",peer=" << _peer->id(); + + if (_peer->m_asking != Asking::Nothing) + { + LOG(TRACE) << "Can't sync with this peer - outstanding asks."; + return false; + } + + if (m_state == SyncState::Waiting) { // 等待bq队列空出之后回调onRoomAvaliable重置状态 + LOG(TRACE) << "Can't sync with this peer - waiting."; + return false; + } + + u256 td = host().chain().details().totalDifficulty; + if (host().bq().isActive()) + td += host().bq().difficulty(); + + u256 syncingDifficulty = std::max(m_syncingTotalDifficulty, td); + + LOG(TRACE) << "syncPeer: _force=" << _force << ",td=" << _peer->m_totalDifficulty << syncingDifficulty << m_syncingTotalDifficulty; + + if (_force || _peer->m_totalDifficulty > syncingDifficulty) + { + // start sync + m_syncingTotalDifficulty = _peer->m_totalDifficulty; + + if (m_state == SyncState::Idle || m_state == SyncState::NotSynced) { + LOG(TRACE) << "syncPeer set state=SyncState::Blocks, before=" << EthereumHost::stateName(m_state); + m_state = SyncState::Blocks; + } + + m_downloadingHeaders.insert(static_cast(_peer->m_height)); + m_headerSyncPeers[_peer].push_back(static_cast(_peer->m_height)); + _peer->requestBlockHeaders(_peer->m_latestHash, 1, 0, false); + LOG(TRACE) << "syncPeer:requestBlockHeaders, blk=" << _peer->m_height << ",peer=" << _peer->id(); + _peer->m_requireTransactions = true; + return true; + } + + if (m_state == SyncState::Blocks) + { + LOG(TRACE) << "syncPeer:requestBlocks, peer=" << _peer->id(); + return requestBlocks(_peer); + } + + return false; +} + +bool BlockChainSync::continueSync() +{ + bool ret = false; + host().foreachPeer([&](std::shared_ptr _p) + { + ret = this->syncPeer(_p, false) || ret; + return true; + }); + return ret; +} + +bool BlockChainSync::requestBlocks(std::shared_ptr _peer) +{ + + clearPeerDownload(_peer); + if (host().bq().knownFull()) + { + LOG(TRACE) << "Waiting for block queue before downloading blocks"; + pauseSync(); + return false; + } + // check to see if we need to download any block bodies first + auto header = m_headers.begin(); + h256s neededBodies; + vector neededNumbers; + unsigned index = 0; + if (m_haveCommonHeader && !m_headers.empty() && m_headers.begin()->first == m_lastImportedBlock + 1) + { + while (header != m_headers.end() && neededBodies.size() < c_maxRequestBodies && index < header->second.size()) + { + unsigned block = header->first + index; + if (m_downloadingBodies.count(block) == 0 && !haveItem(m_bodies, block) && _peer->m_height >= block) + { + neededBodies.push_back(header->second[index].hash); + neededNumbers.push_back(block); + m_downloadingBodies.insert(block); + } + + ++index; + if (index >= header->second.size()) + break; // Download bodies only for validated header chain + } + } + + if (neededBodies.size() > 0) + { + m_bodySyncPeers[_peer] = neededNumbers; + _peer->requestBlockBodies(neededBodies); + LOG(TRACE) << "requestBlockBodies, size=" << neededBodies.size() << ",peer=" << _peer->id(); + return true; + } + else + { + // check if need to download headers + unsigned start = 0; + if (!m_haveCommonHeader) + { + // download backwards until common block is found 1 header at a time + start = m_lastImportedBlock; + if (!m_headers.empty()) + start = std::min(start, m_headers.begin()->first - 1); + m_lastImportedBlock = start; + m_lastImportedBlockHash = host().chain().numberHash(start); + + if (start <= 0) + m_haveCommonHeader = ( true); //reached genesis + } + + if (m_haveCommonHeader) + { + start = m_lastImportedBlock + 1; + auto next = m_headers.begin(); + unsigned count = 0; + if (!m_headers.empty() && start >= m_headers.begin()->first) + { + start = m_headers.begin()->first + m_headers.begin()->second.size(); + ++next; + } + + while (count == 0 && next != m_headers.end()) + { + count = std::min(c_maxRequestHeaders, next->first - start); + while (count > 0 && (m_downloadingHeaders.count(start) != 0 || _peer->m_height < start)) + { + start++; + count--; + } + + std::vector headers; + for (unsigned block = start; block < start + count; block++) { + + headers.push_back(block); + m_downloadingHeaders.insert(block); + + } + count = headers.size(); + + + if (count > 0) + { + m_headerSyncPeers[_peer] = headers; + assert(!haveItem(m_headers, start)); + _peer->requestBlockHeaders(start, count, 0, false); + LOG(TRACE) << "requestBlockHeaders, start=" << start << ",count=" << count << ",peer=" << _peer->id(); + return true; + } + else if (start >= next->first) + { + start = next->first + next->second.size(); + ++next; + } + } + } + else { + m_downloadingHeaders.insert(start); + m_headerSyncPeers[_peer].push_back(start); + _peer->requestBlockHeaders(start, 1, 0, false); + LOG(TRACE) << "requestBlockHeaders, start=" << start << ",count=1,peer=" << _peer->id(); + return true; + } + } + + return false; +} + +void BlockChainSync::clearPeerDownload(std::shared_ptr _peer) +{ + ostringstream oss1, oss2; + auto syncPeer = m_headerSyncPeers.find(_peer); + if (syncPeer != m_headerSyncPeers.end()) + { + for (unsigned block : syncPeer->second) { + m_downloadingHeaders.erase(block); + oss1 << block << ","; + } + m_headerSyncPeers.erase(syncPeer); + } + syncPeer = m_bodySyncPeers.find(_peer); + if (syncPeer != m_bodySyncPeers.end()) + { + for (unsigned block : syncPeer->second) { + m_downloadingBodies.erase(block); + oss2 << block << ","; + } + m_bodySyncPeers.erase(syncPeer); + } + + LOG(TRACE) << "clearPeerDownload: peer=" << _peer->id() << ", delete_header=" << oss1.str() << "delete_body=" << oss2.str(); +} + +void BlockChainSync::clearPeerDownloadHeaders(std::shared_ptr _peer) +{ + ostringstream oss1; + auto syncPeer = m_headerSyncPeers.find(_peer); + if (syncPeer != m_headerSyncPeers.end()) + { + for (unsigned block : syncPeer->second) { + m_downloadingHeaders.erase(block); + oss1 << block << ","; + } + m_headerSyncPeers.erase(syncPeer); + } + + LOG(TRACE) << "clearPeerDownloadHeaders: peer=" << _peer->id() << ", delete_header=" << oss1.str(); +} + +void BlockChainSync::clearPeerDownloadBodies(std::shared_ptr _peer) +{ + ostringstream oss2; + auto syncPeer = m_bodySyncPeers.find(_peer); + if (syncPeer != m_bodySyncPeers.end()) + { + for (unsigned block : syncPeer->second) { + m_downloadingBodies.erase(block); + oss2 << block << ","; + } + m_bodySyncPeers.erase(syncPeer); + } + + LOG(TRACE) << "clearPeerDownloadBodies: peer=" << _peer->id() << "delete_body=" << oss2.str(); +} + +void BlockChainSync::clearPeerDownload() +{ + for (auto s = m_headerSyncPeers.begin(); s != m_headerSyncPeers.end();) + { + if (s->first.expired()) + { + for (unsigned block : s->second) + m_downloadingHeaders.erase(block); + m_headerSyncPeers.erase(s++); + } + else + ++s; + } + for (auto s = m_bodySyncPeers.begin(); s != m_bodySyncPeers.end();) + { + if (s->first.expired()) + { + for (unsigned block : s->second) + m_downloadingBodies.erase(block); + m_bodySyncPeers.erase(s++); + } + else + ++s; + } +} + +void BlockChainSync::logNewBlock(h256 const& _h) +{ + if (m_state == SyncState::NewBlocks) + LOG(TRACE) << "NewBlock: " << _h; + m_knownNewHashes.erase(_h); +} + +void BlockChainSync::onPeerBlockHeaders(std::shared_ptr _peer, RLP const& _r) +{ + + RecursiveGuard l(x_sync); + DEV_INVARIANT_CHECK; + size_t itemCount = _r.itemCount(); + LOG(TRACE) << "BlocksHeaders (" << dec << itemCount << "entries)" << (itemCount ? "" : ": NoMoreHeaders") << ",from=" << _peer->id(); + + clearPeerDownload(_peer); + if (m_state != SyncState::Blocks && m_state != SyncState::NewBlocks && m_state != SyncState::Waiting) + { + LOG(TRACE) << "Ignoring unexpected blocks" << EthereumHost::stateName(m_state); + return; + } + if (m_state == SyncState::Waiting) + { + LOG(TRACE) << "Ignored blocks while waiting"; + return; + } + if (itemCount == 0) + { + LOG(TRACE) << "Peer does not have the blocks requested"; + _peer->addRating(-1); + } + for (unsigned i = 0; i < itemCount; i++) + { + BlockHeader info(_r[i].data(), HeaderData); + unsigned blockNumber = static_cast(info.number()); + + if (haveItem(m_headers, blockNumber)) + { + LOG(TRACE) << "block in m_headers, Skipping header " << blockNumber; + continue; + } + if (blockNumber <= m_lastImportedBlock && m_haveCommonHeader ) + { + LOG(TRACE) << "block small than m_lastImportedBlock, Skipping header " << blockNumber; + continue; + } + if (blockNumber > m_highestBlock) + m_highestBlock = blockNumber; + + auto status = host().bq().blockStatus(info.hash()); + + LOG(TRACE) << "BlockChainSync::onPeerBlockHeaders status=" << (unsigned)status << ",blockNumber=" << blockNumber << ",m_haveCommonHeader=" << m_haveCommonHeader << ",m_lastImportedBlock=" << m_lastImportedBlock << ",isKown=" << toString(host().chain().isKnown(info.hash())); + if (status == QueueStatus::Importing || status == QueueStatus::Ready || host().chain().isKnown(info.hash())) + { + m_haveCommonHeader = ( true); + m_lastImportedBlock = blockNumber; + m_lastImportedBlockHash = info.hash(); + } + else + { + Header hdr { _r[i].data().toBytes(), info.hash(), info.parentHash() }; + + // validate chain + if (m_haveCommonHeader) + { + // 在已下载的块头中,看是否存在自己的父块 + Header const* prevBlock = findItem(m_headers, blockNumber - 1); + + if ((prevBlock && prevBlock->hash != info.parentHash()) || (blockNumber == m_lastImportedBlock + 1 && info.parentHash() != m_lastImportedBlockHash)) + { + // mismatching parent id, delete the previous block and don't add this one + LOG(TRACE) << "Unknown block header " << blockNumber << " " << info.hash() << " (Restart syncing)"; + _peer->addRating(-1); + restartSync(); + return ; + } + + Header const* nextBlock = findItem(m_headers, blockNumber + 1); + + if (nextBlock && nextBlock->parent != info.hash()) + { + LOG(TRACE) << "Unknown block header " << blockNumber + 1 << " " << nextBlock->hash; + // clear following headers + unsigned n = blockNumber + 1; + auto headers = m_headers.at(n); + for (auto const& h : headers) + { + //BlockHeader deletingInfo(h.data, HeaderData); + //HeaderId header_id = { deletingInfo.transactionsRoot(), deletingInfo.sha3Uncles() }; + m_headerIdToNumber.erase(h.hash); + m_downloadingBodies.erase(n); + m_downloadingHeaders.erase(n); + ++n; + } + removeAllStartingWith(m_headers, blockNumber + 1); + removeAllStartingWith(m_bodies, blockNumber + 1); + } + } + + + mergeInto(m_headers, blockNumber, std::move(hdr)); + + m_headerIdToNumber[info.hash()] = blockNumber; + + } + } + collectBlocks(); + continueSync(); +} + +void BlockChainSync::onPeerBlockBodies(std::shared_ptr _peer, RLP const& _r) +{ + + + RecursiveGuard l(x_sync); + DEV_INVARIANT_CHECK; + size_t itemCount = _r.itemCount(); + LOG(TRACE) << "BlocksBodies (" << dec << itemCount << "entries)" << (itemCount ? "" : ": NoMoreBodies") << ",from=" << _peer->id(); + + clearPeerDownload(_peer); + if (m_state != SyncState::Blocks && m_state != SyncState::NewBlocks && m_state != SyncState::Waiting) { + LOG(TRACE) << "Ignoring unexpected blocks" << EthereumHost::stateName(m_state); + return; + } + if (m_state == SyncState::Waiting) + { + LOG(TRACE) << "Ignored blocks while waiting"; + return; + } + if (itemCount == 0) + { + LOG(TRACE) << "Peer does not have the blocks requested"; + _peer->addRating(-1); + } + for (unsigned i = 0; i < itemCount; i++) + { + RLP body(_r[i]); + + auto id = body[2].toHash(); + auto iter = m_headerIdToNumber.find(id); + if (iter == m_headerIdToNumber.end()) + { + LOG(TRACE) << "Ignored unknown block body, not in m_headerIdToNumber"; + continue; + } + + unsigned blockNumber = iter->second; + Header const* header = findItem(m_headers, blockNumber); + if (header == nullptr) { + LOG(TRACE) << "Ignored unknown block body " << blockNumber; + continue; + } + + if (haveItem(m_bodies, blockNumber)) + { + LOG(TRACE) << "Skipping already downloaded block body " << blockNumber; + continue; + } + auto txList = body[0]; + h256 transactionRoot = trieRootOver(txList.itemCount(), [&](unsigned i) { return rlp(i); }, [&](unsigned i) { return txList[i].data().toBytes(); }); + h256 uncles = sha3(body[1].data()); + + auto bi = BlockHeader(header->data, HeaderData); + if (transactionRoot != bi.transactionsRoot() || uncles != bi.sha3Uncles()) { + LOG(TRACE) << "Ignored illegal downloaded block body " << blockNumber; + continue; + } + + m_headerIdToNumber.erase(id); + mergeInto(m_bodies, blockNumber, body.data().toBytes()); + } + collectBlocks(); + continueSync(); +} + +void BlockChainSync::collectBlocks() +{ + + if (m_haveCommonHeader && m_headers.empty() && m_downloadingHeaders.empty() && m_downloadingBodies.empty()) { + if (!m_bodies.empty()) + { + LOG(TRACE) << "Block headers map is empty, but block bodies map is not. Force-clearing."; + m_bodies.clear(); + } + completeSync(); + LOG(TRACE) << "collectBlocks: (0) completeSync"; + return; + } + + if (!m_haveCommonHeader || m_headers.empty() || m_bodies.empty()) { + LOG(TRACE) << "collectBlocks: (1)" << m_haveCommonHeader << m_headers.empty() << m_bodies.empty(); + return; + } + + // merge headers and bodies + auto& headers = *m_headers.begin(); + auto& bodies = *m_bodies.begin(); + if (headers.first != bodies.first || headers.first != m_lastImportedBlock + 1) { + LOG(TRACE) << "collectBlocks: (2)" << headers.first << ", " << bodies.first << ", " << m_lastImportedBlock; + return; + } + + unsigned success = 0; + unsigned future = 0; + unsigned got = 0; + unsigned unknown = 0; + size_t i = 0; + for (; i < headers.second.size() && i < bodies.second.size(); i++) + { + RLPStream blockStream(5); + blockStream.appendRaw(headers.second[i].data); // header + RLP body(bodies.second[i]); + blockStream.appendRaw(body[0].data()); // tx + blockStream.appendRaw(body[1].data()); // uncles + blockStream.appendRaw(body[2].data()); // hash + blockStream.appendRaw(body[3].data()); // sign_list + bytes block; + blockStream.swapOut(block); + auto block_number = headers.first + (unsigned)i; + switch (host().bq().import(&block)) + { + case ImportResult::Success: + success++; + if (block_number > m_lastImportedBlock) + { + m_lastImportedBlock = block_number; + m_lastImportedBlockHash = headers.second[i].hash; + } + m_highestBlock = max(m_lastImportedBlock, m_highestBlock); + m_downloadingBodies.erase(block_number); + m_downloadingHeaders.erase(block_number); + if (block_number % 100 == 0) { + DEV_BLOCK_STAT_LOG(headers.second[i].hash, block_number, utcTime(), "BlockChainSync::collectBlocks"); + } + break; + case ImportResult::Malformed: + case ImportResult::BadChain: + LOG(TRACE) << "collectBlocks BadChain"; + restartSync(); + return; + + case ImportResult::FutureTimeKnown: + future++; + break; + case ImportResult::AlreadyInChain: + case ImportResult::AlreadyKnown: + ++got; + break; + case ImportResult::FutureTimeUnknown: + case ImportResult::UnknownParent: + ++unknown; + if (headers.first + i > m_lastImportedBlock) + { + resetSync(); + LOG(TRACE) << "collectBlocks (3) set m_haveCommonHeader=false block_number=" << block_number; + m_haveCommonHeader = false; // fork detected, search for common header again + } + return; + + default:; + } + } + + LOG(TRACE) << dec << success << "imported OK," << unknown << "with unknown parents," << future << "with future timestamps," << got << " already known received."; + + if (host().bq().unknownFull()) + { + clog(NetWarn) << "Too many unknown blocks, restarting sync"; + restartSync(); + return; + } + + auto newHeaders = std::move(headers.second); + newHeaders.erase(newHeaders.begin(), newHeaders.begin() + i); + unsigned newHeaderHead = headers.first + i; + auto newBodies = std::move(bodies.second); + newBodies.erase(newBodies.begin(), newBodies.begin() + i); + unsigned newBodiesHead = bodies.first + i; + m_headers.erase(m_headers.begin()); + m_bodies.erase(m_bodies.begin()); + if (!newHeaders.empty()) + m_headers[newHeaderHead] = newHeaders; + if (!newBodies.empty()) + m_bodies[newBodiesHead] = newBodies; + + if (m_headers.empty()) + { + LOG(TRACE) << "collectBlocks completeSync"; + assert(m_bodies.empty()); + completeSync(); + } + DEV_INVARIANT_CHECK_HERE; +} + +void BlockChainSync::onPeerNewBlock(std::shared_ptr _peer, RLP const& _r) +{ + RecursiveGuard l(x_sync); + DEV_INVARIANT_CHECK; + + if (_r.itemCount() != 2) + { + _peer->disable("NewBlock without 2 data fields."); + return; + } + BlockHeader info(_r[0][0].data(), HeaderData); + auto h = info.hash(); + LOG(TRACE) << "onPeerNewBlock: blk=" << info.number() << ",hash=" << h; + DEV_GUARDED(_peer->x_knownBlocks) + { + if (_peer->m_knownBlocks.size() > EthereumPeer::kKnownBlockSize) { + _peer->m_knownBlocks.pop(); + } + _peer->m_knownBlocks.insert(h); + } + if (info.number() > _peer->m_height) { + _peer->m_height = info.number(); + _peer->m_latestHash = h; + } + u256 totalDifficulty = _r[1].toInt(); + u256 rawPeerTd = _peer->m_totalDifficulty; + if (totalDifficulty > _peer->m_totalDifficulty) { + _peer->m_totalDifficulty = totalDifficulty; + } + + unsigned blockNumber = static_cast(info.number()); + if (blockNumber > (m_lastImportedBlock + 1)) + { + LOG(TRACE) << "Received unknown new block, height=" << blockNumber << ",hash=" << h << "m_lastImportedBlock=" << m_lastImportedBlock; + syncPeer(_peer, true); + return; + } + + switch (host().bq().import(_r[0].data())) + { + case ImportResult::Success: + _peer->addRating(100); + logNewBlock(h); + if (blockNumber > m_lastImportedBlock) + { + m_lastImportedBlock = max(m_lastImportedBlock, blockNumber); + m_lastImportedBlockHash = h; + } + m_highestBlock = max(m_lastImportedBlock, m_highestBlock); + m_downloadingBodies.erase(blockNumber); + m_downloadingHeaders.erase(blockNumber); + removeItem(m_headers, blockNumber); + removeItem(m_bodies, blockNumber); + if (m_headers.empty()) + { + if (!m_bodies.empty()) + { + LOG(TRACE) << "Block headers map is empty, but block bodies map is not. Force-clearing."; + m_bodies.clear(); + } + completeSync(); + } + break; + case ImportResult::FutureTimeKnown: + //TODO: Rating dependent on how far in future it is. + break; + + case ImportResult::Malformed: + case ImportResult::BadChain: + logNewBlock(h); + _peer->disable("Malformed block received."); + return; + + case ImportResult::AlreadyInChain: + case ImportResult::AlreadyKnown: + break; + + case ImportResult::FutureTimeUnknown: + case ImportResult::UnknownParent: + { + _peer->m_unknownNewBlocks++; + if (_peer->m_unknownNewBlocks > c_maxPeerUknownNewBlocks) + { + _peer->disable("Too many uknown new blocks"); + restartSync(); + } + logNewBlock(h); + //u256 totalDifficulty = _r[1].toInt(); + if (totalDifficulty > rawPeerTd) + { + LOG(TRACE) << "Received block with no known parent. Peer needs syncing..."; + syncPeer(_peer, true); + } + break; + } + default:; + } +} + +SyncStatus BlockChainSync::status() const +{ + RecursiveGuard l(x_sync); + SyncStatus res; + res.state = m_state; + res.protocolVersion = 62; + res.startBlockNumber = m_startingBlock; + res.currentBlockNumber = host().chain().number(); + res.highestBlockNumber = m_highestBlock; + return res; +} + +void BlockChainSync::resetSync() +{ + m_downloadingHeaders.clear(); + m_downloadingBodies.clear(); + m_headers.clear(); + m_bodies.clear(); + m_headerSyncPeers.clear(); + m_bodySyncPeers.clear(); + m_headerIdToNumber.clear(); + m_syncingTotalDifficulty = 0; + m_state = SyncState::NotSynced; +} + +void BlockChainSync::restartSync() +{ + RecursiveGuard l(x_sync); + resetSync(); + m_highestBlock = 0; + m_haveCommonHeader = false; + host().bq().clear(); + m_startingBlock = host().chain().number(); + m_lastImportedBlock = m_startingBlock; + m_lastImportedBlockHash = host().chain().currentHash(); +} + +void BlockChainSync::completeSync() +{ + resetSync(); + m_state = SyncState::Idle; +} + +void BlockChainSync::pauseSync() +{ + m_state = SyncState::Waiting; +} + +bool BlockChainSync::isSyncing() const +{ + return m_state != SyncState::Idle; +} + +void BlockChainSync::onPeerNewHashes(std::shared_ptr _peer, RLP const& _r) +{ + RecursiveGuard l(x_sync); + unsigned itemCount = _r.itemCount(); + std::vector> hashes(itemCount); + for (unsigned i = 0; i < itemCount; ++i) + hashes[i] = std::make_pair(_r[i][0].toHash(), _r[i][1].toInt()); + + DEV_INVARIANT_CHECK; + if (_peer->isConversing()) + { + LOG(TRACE) << "Ignoring new hashes since we're already downloading." << EthereumPeer::toString(_peer->m_asking); + return; + } + + unsigned knowns = 0; + unsigned unknowns = 0; + //unsigned maxHeight = 0; + for (auto const& p : hashes) + { + h256 const& h = p.first; + _peer->addRating(1); + DEV_GUARDED(_peer->x_knownBlocks) + { + if (_peer->m_knownBlocks.size() > EthereumPeer::kKnownBlockSize) { + _peer->m_knownBlocks.pop(); + } + _peer->m_knownBlocks.insert(h); + } + if (p.second > _peer->m_height) + { + //maxHeight = (unsigned)p.second; + _peer->m_height = p.second; + _peer->m_latestHash = h; + } + + auto status = host().bq().blockStatus(h); + if (status == QueueStatus::Importing || status == QueueStatus::Ready || host().chain().isKnown(h)) + knowns++; + else if (status == QueueStatus::Bad) + { + LOG(WARNING) << "block hash bad!" << h << ". Bailing..."; + return; + } + else if (status == QueueStatus::Unknown) + { + LOG(TRACE) << "recv unknown BlockHash, height=" << p.second << ",hash=" << h; + unknowns++; + + } + else + knowns++; + } + LOG(TRACE) << "onPeerNewHashes:" << itemCount << " newHashes," << knowns << " knowns," << unknowns << " unknowns" << ",peer=" << _peer->id(); + if (unknowns > 0) + { + LOG(TRACE) << "Not syncing and new block hash discovered: syncing." << _peer->id(); + syncPeer(_peer, true); + } +} + +void BlockChainSync::onPeerAborting() +{ + RecursiveGuard l(x_sync); + // Can't check invariants here since the peers is already removed from the list and the state is not updated yet. + clearPeerDownload(); + LOG(TRACE) << "onPeerAborting call continueSync"; + continueSync(); + DEV_INVARIANT_CHECK_HERE; +} + +bool BlockChainSync::invariants() const +{ + return true; + if (!isSyncing() && !m_headers.empty()) { + LOG(TRACE) << "isSyncing() =" << isSyncing() << ",m_headers.empty()=" << m_headers.empty(); + BOOST_THROW_EXCEPTION(FailedInvariant() << errinfo_comment("Got headers while not syncing")); + } + if (!isSyncing() && !m_bodies.empty()) { + LOG(TRACE) << "isSyncing() =" << isSyncing() << ",m_bodies.empty()=" << m_bodies.empty(); + BOOST_THROW_EXCEPTION(FailedInvariant() << errinfo_comment("Got bodies while not syncing")); + } + if (isSyncing() && m_host.chain().number() > 0 && m_haveCommonHeader && m_lastImportedBlock == 0) { + LOG(TRACE) << "isSyncing() =" << isSyncing() << ",m_host.chain().number()=" << m_host.chain().number() << ",m_haveCommonHeader=" << m_haveCommonHeader << ",m_lastImportedBlock=" << m_lastImportedBlock; + BOOST_THROW_EXCEPTION(FailedInvariant() << errinfo_comment("Common block not found")); + } + if (isSyncing() && !m_headers.empty() && m_lastImportedBlock >= m_headers.begin()->first) { + LOG(TRACE) << "isSyncing() =" << isSyncing() << ",m_headers.empty()=" << m_headers.empty() << ",m_lastImportedBlock=" << m_lastImportedBlock << ",m_headers.begin()->first=" << m_headers.begin()->first; + BOOST_THROW_EXCEPTION(FailedInvariant() << errinfo_comment("Header is too old")); + } + if (m_headerSyncPeers.empty() != m_downloadingHeaders.empty()) { + LOG(TRACE) << "m_headerSyncPeers.empty() =" << m_headerSyncPeers.empty() << ",m_downloadingHeaders.empty()=" << m_downloadingHeaders.empty(); + BOOST_THROW_EXCEPTION(FailedInvariant() << errinfo_comment("Header download map mismatch")); + } + if (m_bodySyncPeers.empty() != m_downloadingBodies.empty() && m_downloadingBodies.size() <= m_headerIdToNumber.size()) { + LOG(TRACE) << "m_bodySyncPeers.empty() =" << m_bodySyncPeers.empty() << ",m_downloadingBodies.empty()=" << m_downloadingBodies.empty() << ",m_downloadingBodies.size()=" << m_downloadingBodies.size() << ",m_headerIdToNumber.size()=" << m_headerIdToNumber.size(); + BOOST_THROW_EXCEPTION(FailedInvariant() << errinfo_comment("Body download map mismatch")); + } + return true; +} diff --git a/libethereum/BlockChainSync.h b/libethereum/BlockChainSync.h new file mode 100644 index 0000000000..89626d9015 --- /dev/null +++ b/libethereum/BlockChainSync.h @@ -0,0 +1,178 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file BlockChainSync.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include + +#include +#include +#include +#include +#include +#include +#include "CommonNet.h" + +namespace dev +{ + +class RLPStream; + +namespace eth +{ + +class EthereumHost; +class BlockQueue; +class EthereumPeer; + +/** + * @brief Base BlockChain synchronization strategy class. + * Syncs to peers and keeps up to date. Base class handles blocks downloading but does not contain any details on state transfer logic. + */ +class BlockChainSync: public HasInvariants +{ +public: + BlockChainSync(EthereumHost& _host); + ~BlockChainSync(); + void abortSync(); ///< Abort all sync activity + + /// @returns true is Sync is in progress + bool isSyncing() const; + + /// Restart sync + void restartSync(); + + /// Called by peer to report status + void onPeerStatus(std::shared_ptr _peer); + + /// Called by peer once it has new block headers during sync + void onPeerBlockHeaders(std::shared_ptr _peer, RLP const& _r); + + /// Called by peer once it has new block bodies + void onPeerBlockBodies(std::shared_ptr _peer, RLP const& _r); + + /// Called by peer once it has new block bodies + void onPeerNewBlock(std::shared_ptr _peer, RLP const& _r); + + void onPeerNewHashes(std::shared_ptr _peer, RLP const& _r); + + /// Called by peer when it is disconnecting + void onPeerAborting(); + + /// Called when a blockchain has imported a new block onto the DB + void onBlockImported(BlockHeader const& _info); + + void onForceSync(); + + /// @returns Synchonization status + SyncStatus status() const; + + static char const* stateName(SyncState _s) { return s_stateNames[static_cast(_s)]; } + +private: + /// Resume downloading after witing state + bool continueSync(); + + /// Called after all blocks have been donloaded + void completeSync(); + + /// Enter waiting state + void pauseSync(); + + EthereumHost& host() { return m_host; } + EthereumHost const& host() const { return m_host; } + + void resetSync(); + bool syncPeer(std::shared_ptr _peer, bool _force); + bool requestBlocks(std::shared_ptr _peer); + void clearPeerDownload(std::shared_ptr _peer); + void clearPeerDownloadHeaders(std::shared_ptr _peer); + void clearPeerDownloadBodies(std::shared_ptr _peer); + void clearPeerDownload(); + void collectBlocks(); + +private: + struct Header + { + bytes data; ///< Header data + h256 hash; ///< Block hash + h256 parent; ///< Parent hash + }; + + /// Used to identify header by transactions and uncles hashes + struct HeaderId + { + h256 transactionsRoot; + h256 uncles; + + bool operator==(HeaderId const& _other) const + { + return transactionsRoot == _other.transactionsRoot && uncles == _other.uncles; + } + }; + + struct HeaderIdHash + { + std::size_t operator()(const HeaderId& _k) const + { + size_t seed = 0; + h256::hash hasher; + boost::hash_combine(seed, hasher(_k.transactionsRoot)); + boost::hash_combine(seed, hasher(_k.uncles)); + return seed; + } + }; + + EthereumHost& m_host; + Handler<> m_bqRoomAvailable; ///< Triggered once block queue has space for more blocks + mutable RecursiveMutex x_sync; + SyncState m_state = SyncState::Idle; ///< Current sync state + h256Hash m_knownNewHashes; ///< New hashes we know about use for logging only + unsigned m_startingBlock = 0; ///< Last block number for the start of sync + unsigned m_highestBlock = 0; ///< Highest block number seen + std::unordered_set m_downloadingHeaders; ///< Set of block body numbers being downloaded + std::unordered_set m_downloadingBodies; ///< Set of block header numbers being downloaded + std::map> m_headers; ///< Downloaded headers + std::map> m_bodies; ///< Downloaded block bodies + std::map, std::vector, std::owner_less>> m_headerSyncPeers; ///< Peers to m_downloadingSubchain number map + std::map, std::vector, std::owner_less>> m_bodySyncPeers; ///< Peers to m_downloadingSubchain number map + //std::unordered_map m_headerIdToNumber; + std::unordered_map m_headerIdToNumber; + + bool m_haveCommonHeader = false; ///< True if common block for our and remote chain has been found + + unsigned m_lastImportedBlock = 0; ///< Last imported block number + h256 m_lastImportedBlockHash; ///< Last imported block hash + u256 m_syncingTotalDifficulty; ///< Highest peer difficulty + +private: + static char const* const s_stateNames[static_cast(SyncState::Size)]; + bool invariants() const override; + void logNewBlock(h256 const& _h); + + +}; + +std::ostream& operator<<(std::ostream& _out, SyncStatus const& _sync); + +} +} diff --git a/libethereum/BlockDetails.cpp b/libethereum/BlockDetails.cpp new file mode 100644 index 0000000000..20b13dc564 --- /dev/null +++ b/libethereum/BlockDetails.cpp @@ -0,0 +1,43 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file BlockDetails.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "BlockDetails.h" + +#include +using namespace std; +using namespace dev; +using namespace dev::eth; + +BlockDetails::BlockDetails(RLP const& _r) +{ + number = _r[0].toInt(); + totalDifficulty = _r[1].toInt(); + parent = _r[2].toHash(); + children = _r[3].toVector(); + size = _r.size(); +} + +bytes BlockDetails::rlp() const +{ + auto ret = rlpList(number, totalDifficulty, parent, children); + size = ret.size(); + return ret; +} diff --git a/libethereum/BlockDetails.h b/libethereum/BlockDetails.h new file mode 100644 index 0000000000..3cdc78ba20 --- /dev/null +++ b/libethereum/BlockDetails.h @@ -0,0 +1,129 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file BlockDetails.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include + +#include +#include "TransactionReceipt.h" + +namespace dev +{ +namespace eth +{ + +// TODO: OPTIMISE: constructors take bytes, RLP used only in necessary classes. + +static const unsigned c_bloomIndexSize = 16; +static const unsigned c_bloomIndexLevels = 2; + +static const unsigned InvalidNumber = (unsigned)-1; + +struct BlockDetails +{ + BlockDetails(): number(InvalidNumber), totalDifficulty(Invalid256) {} + BlockDetails(unsigned _n, u256 _tD, h256 _p, h256s _c): number(_n), totalDifficulty(_tD), parent(_p), children(_c) {} + BlockDetails(RLP const& _r); + bytes rlp() const; + + bool isNull() const { return number == InvalidNumber; } + explicit operator bool() const { return !isNull(); } + + unsigned number = InvalidNumber; + u256 totalDifficulty = Invalid256; + h256 parent; + h256s children; + + mutable unsigned size; +}; + +struct BlockLogBlooms +{ + BlockLogBlooms() {} + BlockLogBlooms(RLP const& _r) { blooms = _r.toVector(); size = _r.data().size(); } + bytes rlp() const { bytes r = dev::rlp(blooms); size = r.size(); return r; } + + LogBlooms blooms; + mutable unsigned size; +}; + +struct BlocksBlooms +{ + BlocksBlooms() {} + BlocksBlooms(RLP const& _r) { blooms = _r.toArray(); size = _r.data().size(); } + bytes rlp() const { bytes r = dev::rlp(blooms); size = r.size(); return r; } + + std::array blooms; + mutable unsigned size; +}; + +struct BlockReceipts +{ + BlockReceipts() {} + BlockReceipts(RLP const& _r) { for (auto const& i: _r) receipts.emplace_back(i.data()); size = _r.data().size(); } + bytes rlp() const { RLPStream s(receipts.size()); for (TransactionReceipt const& i: receipts) i.streamRLP(s); size = s.out().size(); return s.out(); } + + TransactionReceipts receipts; + mutable unsigned size = 0; +}; + +struct BlockHash +{ + BlockHash() {} + BlockHash(h256 const& _h): value(_h) {} + BlockHash(RLP const& _r) { value = _r.toHash(); } + bytes rlp() const { return dev::rlp(value); } + + h256 value; + static const unsigned size = 65; +}; + +struct TransactionAddress +{ + TransactionAddress() {} + TransactionAddress(RLP const& _rlp) { blockHash = _rlp[0].toHash(); index = _rlp[1].toInt(); } + bytes rlp() const { RLPStream s(2); s << blockHash << index; return s.out(); } + + explicit operator bool() const { return !!blockHash; } + + h256 blockHash; + unsigned index = 0; + + static const unsigned size = 67; +}; + +using BlockDetailsHash = std::unordered_map; +using BlockLogBloomsHash = std::unordered_map; +using BlockReceiptsHash = std::unordered_map; +using TransactionAddressHash = std::unordered_map; +using BlockHashHash = std::unordered_map; +using BlocksBloomsHash = std::unordered_map; + +static const BlockDetails NullBlockDetails; +static const BlockLogBlooms NullBlockLogBlooms; +static const BlockReceipts NullBlockReceipts; +static const TransactionAddress NullTransactionAddress; +static const BlockHash NullBlockHash; +static const BlocksBlooms NullBlocksBlooms; + +} +} diff --git a/libethereum/BlockQueue.cpp b/libethereum/BlockQueue.cpp new file mode 100644 index 0000000000..8a4d0f310e --- /dev/null +++ b/libethereum/BlockQueue.cpp @@ -0,0 +1,623 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file BlockQueue.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "BlockQueue.h" +#include +#include + +#include +#include +#include "BlockChain.h" +#include "VerifiedBlock.h" +#include "State.h" +#include +using namespace std; +using namespace dev; +using namespace dev::eth; + + +size_t const c_maxKnownCount = 100000; +size_t const c_maxKnownSize = 128 * 1024 * 1024; +size_t const c_maxUnknownCount = 100000; +size_t const c_maxUnknownSize = 512 * 1024 * 1024; // Block size can be ~50kb + +BlockQueue::BlockQueue() +{ + // Allow some room for other activity + unsigned verifierThreads = std::max(thread::hardware_concurrency(), 3U) - 2U; + for (unsigned i = 0; i < verifierThreads; ++i) + m_verifiers.emplace_back([ = ]() { + setThreadName("verifier" + toString(i)); + this->verifierBody(); + }); +} + +BlockQueue::~BlockQueue() +{ + stop(); +} + +void BlockQueue::stop() +{ + DEV_GUARDED(m_verification) + m_deleting = true; + + m_moreToVerify.notify_all(); + for (auto& i : m_verifiers) + i.join(); + m_verifiers.clear(); +} + +void BlockQueue::clear() +{ + WriteGuard l(m_lock); + DEV_INVARIANT_CHECK; + Guard l2(m_verification); + m_readySet.clear(); + m_drainingSet.clear(); + m_verified.clear(); + m_unverified.clear(); + m_verifying.clear(); + m_unknownSet.clear(); + m_unknown.clear(); + m_future.clear(); + m_difficulty = 0; + m_drainingDifficulty = 0; +} + +void BlockQueue::verifierBody() +{ + while (!m_deleting) + { + UnverifiedBlock work; + + { + unique_lock l(m_verification); + + LOG(TRACE) << "BlockQueue::verifierBody"; + + m_moreToVerify.wait(l, [&]() { return !m_unverified.isEmpty() || m_deleting; }); + + if (m_deleting) + return; + + work = m_unverified.dequeue(); + + BlockHeader bi; + bi.setSha3Uncles(work.hash); + bi.setParentHash(work.parentHash); + m_verifying.enqueue(move(bi)); + } + + VerifiedBlock res; + swap(work.blockData, res.blockData); + try + { + res.verified = m_bc->verifyBlock(&res.blockData, m_onBad, ImportRequirements::OutOfOrderChecks); + } + catch (std::exception const& _ex) + { + // bad block. + // has to be this order as that's how invariants() assumes. + LOG(WARNING) << "Unexpected exception when verifying block: " << res.verified.info.number() << _ex.what(); + WriteGuard l2(m_lock); + unique_lock l(m_verification); + m_readySet.erase(work.hash); + m_knownBad.insert(work.hash); + if (!m_verifying.remove(work.hash)) + LOG(WARNING) << "Unexpected exception when verifying block: " << _ex.what(); + drainVerified_WITH_BOTH_LOCKS(); + continue; + } + + bool ready = false; + { + WriteGuard l2(m_lock); + unique_lock l(m_verification); + if (!m_verifying.isEmpty() && m_verifying.nextHash() == work.hash) + { + // we're next! + m_verifying.dequeue(); + if (m_knownBad.count(res.verified.info.parentHash())) + { + m_readySet.erase(res.verified.info.hash()); + m_knownBad.insert(res.verified.info.hash()); + } + else + m_verified.enqueue(move(res)); + + drainVerified_WITH_BOTH_LOCKS(); + ready = true; + } + else + { + LOG(WARNING) << "Unexpected exception when enqueue verified block " << res.verified.info.number(); + if (!m_verifying.replace(work.hash, move(res))) + LOG(WARNING) << "BlockQueue missing our job: was there a GM?"; + } + } + if (ready) + m_onReady(); + } +} + +void BlockQueue::drainVerified_WITH_BOTH_LOCKS() +{ + while (!m_verifying.isEmpty() && !m_verifying.next().blockData.empty()) + { + VerifiedBlock block = m_verifying.dequeue(); + if (m_knownBad.count(block.verified.info.parentHash())) + { + m_readySet.erase(block.verified.info.hash()); + m_knownBad.insert(block.verified.info.hash()); + } + else + m_verified.enqueue(move(block)); + } +} + + +ImportResult BlockQueue::importVerified(bytesConstRef _block) { + LOG(TRACE) << std::this_thread::get_id(); + // Check if we already know this block. + h256 h = BlockHeader::headerHashFromBlock(_block); + + LOG(TRACE) << "Queuing block" << h << "for import..."; + + UpgradableGuard l(m_lock); + + if (m_readySet.count(h) || m_drainingSet.count(h) || m_unknownSet.count(h) || m_knownBad.count(h)) { + // Already know about this one. + LOG(WARNING) << "Already known. hash=" << h; + return ImportResult::AlreadyKnown; + } + + VerifiedBlock res; + BlockHeader bi; + try { + + res.verified = m_bc->verifyBlock(_block, m_onBad, ImportRequirements::OutOfOrderChecks); + bi = res.verified.info; + res.blockData = _block.toVector(); + res.verified.block = &res.blockData; + } catch (Exception const& _e) { + LOG(WARNING) << "Ignoring malformed block: " << diagnostic_information(_e); + return ImportResult::Malformed; + } + + LOG(TRACE) << "Block" << h << "is" << bi.number() << "parent is" << bi.parentHash(); + + // Check block doesn't already exist first! + if (m_bc->isKnown(h)) { + LOG(WARNING) << "Already known in chain. hash=" << h; + return ImportResult::AlreadyInChain; + } + + UpgradeGuard ul(l); + DEV_INVARIANT_CHECK; + + + if (m_knownBad.count(bi.parentHash())) { // bad block处理 + m_knownBad.insert(bi.hash()); + updateBad_WITH_LOCK(bi.hash()); + LOG(WARNING) << "knowBad. hash=" << h; + return ImportResult::BadChain; + } else if (!m_bc->isKnown(bi.parentHash())) { + LOG(WARNING) << "unknown parent:" << bi.parentHash() << ",hash=" << h; + m_unknown.insert(bi.parentHash(), h, _block.toBytes()); + m_unknownSet.insert(h); + return ImportResult::UnknownParent; + } else { + + DEV_GUARDED(m_verification) { + if (m_verified.exist(bi.hash())) { + LOG(WARNING) << "in verified. hash=" << h; + return ImportResult::AlreadyKnown; + } + + LOG(TRACE) << "OK - ready for chain insertion."; + m_verified.enqueue(move(res)); + m_difficulty += bi.difficulty(); + drainVerified_WITH_BOTH_LOCKS(); + m_onReady(); + } + } + + return ImportResult::Success; +} + +ImportResult BlockQueue::import(bytesConstRef _block, bool _isOurs) +{ + LOG(TRACE) << std::this_thread::get_id(); + // Check if we already know this block. + h256 h = BlockHeader::headerHashFromBlock(_block); + + LOG(TRACE) << "Queuing block" << h << "for import..."; + + UpgradableGuard l(m_lock); + + if (m_readySet.count(h) || m_drainingSet.count(h) || m_unknownSet.count(h) || m_knownBad.count(h)) + { + // Already know about this one. + LOG(TRACE) << "Already known."; + return ImportResult::AlreadyKnown; + } + + BlockHeader bi; + try + { + // TODO: quick verification of seal - will require BlockQueue to be templated on SealEngine + // VERIFY: populates from the block and checks the block is internally coherent. + bi = m_bc->verifyBlock(_block, m_onBad, ImportRequirements::PostGenesis).info; + } + catch (Exception const& _e) + { + LOG(WARNING) << "Ignoring malformed block: " << diagnostic_information(_e); + return ImportResult::Malformed; + } + + LOG(TRACE) << "Block" << h << "is" << bi.number() << "parent is" << bi.parentHash(); + + // Check block doesn't already exist first! + if (m_bc->isKnown(h)) + { + LOG(TRACE) << "Already known in chain."; + return ImportResult::AlreadyInChain; + } + + UpgradeGuard ul(l); + DEV_INVARIANT_CHECK; + + // Check it's not in the future + if (!(m_bc->chainParams().otherParams.count("allowFutureBlocks")) && bi.timestamp() > utcTime() && !_isOurs) + { + m_future.insert(static_cast(bi.timestamp()), h, _block.toBytes()); + char buf[24]; + time_t bit = static_cast(bi.timestamp()); + if (strftime(buf, 24, "%X", localtime(&bit)) == 0) + buf[0] = '\0'; // empty if case strftime fails + LOG(TRACE) << "OK - queued for future [" << bi.timestamp() << "vs" << utcTime() << "] - will wait until" << buf; + m_difficulty += bi.difficulty(); + bool unknown = !m_readySet.count(bi.parentHash()) && !m_drainingSet.count(bi.parentHash()) && !m_bc->isKnown(bi.parentHash()); + return unknown ? ImportResult::FutureTimeUnknown : ImportResult::FutureTimeKnown; + } + else + { + // We now know it. + if (m_knownBad.count(bi.parentHash())) + { + m_knownBad.insert(bi.hash()); + updateBad_WITH_LOCK(bi.hash()); + // bad parent; this is bad too, note it as such + return ImportResult::BadChain; + } + else if (!m_readySet.count(bi.parentHash()) && !m_drainingSet.count(bi.parentHash()) && !m_bc->isKnown(bi.parentHash())) + { + // We don't know the parent (yet) - queue it up for later. It'll get resent to us if we find out about its ancestry later on. + LOG(TRACE) << "OK - queued as unknown parent:" << bi.parentHash(); + m_unknown.insert(bi.parentHash(), h, _block.toBytes()); + m_unknownSet.insert(h); + m_difficulty += bi.difficulty(); + + return ImportResult::UnknownParent; + } + else + { + // If valid, append to blocks. + LOG(TRACE) << "OK - ready for chain insertion."; + DEV_GUARDED(m_verification) + m_unverified.enqueue(UnverifiedBlock { h, bi.parentHash(), _block.toBytes() }); + m_moreToVerify.notify_one(); + m_readySet.insert(h); + m_difficulty += bi.difficulty(); + + noteReady_WITH_LOCK(h); + + return ImportResult::Success; + } + } +} + +void BlockQueue::updateBad_WITH_LOCK(h256 const& _bad) +{ + DEV_INVARIANT_CHECK; + DEV_GUARDED(m_verification) + { + collectUnknownBad_WITH_BOTH_LOCKS(_bad); + bool moreBad = true; + while (moreBad) + { + moreBad = false; + std::vector badVerified = m_verified.removeIf([this](VerifiedBlock const & _b) + { + return m_knownBad.count(_b.verified.info.parentHash()) || m_knownBad.count(_b.verified.info.hash()); + }); + for (auto& b : badVerified) + { + m_knownBad.insert(b.verified.info.hash()); + m_readySet.erase(b.verified.info.hash()); + collectUnknownBad_WITH_BOTH_LOCKS(b.verified.info.hash()); + moreBad = true; + } + + std::vector badUnverified = m_unverified.removeIf([this](UnverifiedBlock const & _b) + { + return m_knownBad.count(_b.parentHash) || m_knownBad.count(_b.hash); + }); + for (auto& b : badUnverified) + { + m_knownBad.insert(b.hash); + m_readySet.erase(b.hash); + collectUnknownBad_WITH_BOTH_LOCKS(b.hash); + moreBad = true; + } + + std::vector badVerifying = m_verifying.removeIf([this](VerifiedBlock const & _b) + { + return m_knownBad.count(_b.verified.info.parentHash()) || m_knownBad.count(_b.verified.info.sha3Uncles()); + }); + for (auto& b : badVerifying) + { + h256 const& h = b.blockData.size() != 0 ? b.verified.info.hash() : b.verified.info.sha3Uncles(); + m_knownBad.insert(h); + m_readySet.erase(h); + collectUnknownBad_WITH_BOTH_LOCKS(h); + moreBad = true; + } + } + } +} + +void BlockQueue::collectUnknownBad_WITH_BOTH_LOCKS(h256 const& _bad) +{ + list badQueue(1, _bad); + while (!badQueue.empty()) + { + vector> const removed = m_unknown.removeByKeyEqual(badQueue.front()); + badQueue.pop_front(); + for (auto& newBad : removed) + { + m_unknownSet.erase(newBad.first); + m_knownBad.insert(newBad.first); + badQueue.push_back(newBad.first); + } + } +} + +bool BlockQueue::doneDrain(h256s const& _bad) +{ + WriteGuard l(m_lock); + DEV_INVARIANT_CHECK; + m_drainingSet.clear(); + m_difficulty -= m_drainingDifficulty; + m_drainingDifficulty = 0; + if (_bad.size()) + { + // at least one of them was bad. + m_knownBad += _bad; + for (h256 const& b : _bad) + updateBad_WITH_LOCK(b); + } + return !m_readySet.empty(); +} + +void BlockQueue::tick() +{ + vector> todo; + { + UpgradableGuard l(m_lock); + if (m_future.isEmpty()) + return; + + LOG(TRACE) << "Checking past-future blocks..."; + + uint64_t t = utcTime(); + if (t < m_future.firstKey()) + return; + + LOG(TRACE) << "Past-future blocks ready."; + + { + UpgradeGuard l2(l); + DEV_INVARIANT_CHECK; + todo = m_future.removeByKeyNotGreater(t); + } + } + LOG(TRACE) << "Importing" << todo.size() << "past-future blocks."; + + for (auto const& b : todo) { + LOG(TRACE) << "Importing past-future block, hash=" << b.first; + import(&b.second); + } +} + +BlockQueueStatus BlockQueue::status() const +{ + ReadGuard l(m_lock); + Guard l2(m_verification); + return BlockQueueStatus{ m_drainingSet.size(), m_verified.count(), m_verifying.count(), m_unverified.count(), + m_future.count(), m_unknown.count(), m_knownBad.size() }; +} + +QueueStatus BlockQueue::blockStatus(h256 const& _h) const +{ + ReadGuard l(m_lock); + return + m_readySet.count(_h) ? + QueueStatus::Ready : + m_drainingSet.count(_h) ? + QueueStatus::Importing : + m_unknownSet.count(_h) ? + QueueStatus::UnknownParent : + m_knownBad.count(_h) ? + QueueStatus::Bad : + QueueStatus::Unknown; +} + +bool BlockQueue::knownFull() const +{ + Guard l(m_verification); + return knownSize() > c_maxKnownSize || knownCount() > c_maxKnownCount; +} + +std::size_t BlockQueue::knownSize() const +{ + return m_verified.size() + m_unverified.size() + m_verifying.size(); +} + +std::size_t BlockQueue::knownCount() const +{ + return m_verified.count() + m_unverified.count() + m_verifying.count(); +} + +bool BlockQueue::unknownFull() const +{ + ReadGuard l(m_lock); + return unknownSize() > c_maxUnknownSize || unknownCount() > c_maxUnknownCount; +} + +std::size_t BlockQueue::unknownSize() const +{ + return m_future.size() + m_unknown.size(); +} + +std::size_t BlockQueue::unknownCount() const +{ + return m_future.count() + m_unknown.count(); +} + +void BlockQueue::drain(VerifiedBlocks& o_out, unsigned _max) +{ + bool wasFull = false; + DEV_WRITE_GUARDED(m_lock) + { + DEV_INVARIANT_CHECK; + wasFull = knownFull(); + if (m_drainingSet.empty()) + { + m_drainingDifficulty = 0; + DEV_GUARDED(m_verification) + o_out = m_verified.dequeueMultiple(min(_max, m_verified.count())); + + for (auto const& bs : o_out) + { + // TODO: @optimise use map rather than vector & set. + auto h = bs.verified.info.hash(); + m_drainingSet.insert(h); + m_drainingDifficulty += bs.verified.info.difficulty(); + m_readySet.erase(h); + } + } + } + if (wasFull && !knownFull()) + m_onRoomAvailable(); +} + +bool BlockQueue::invariants() const +{ + Guard l(m_verification); + if (m_readySet.size() != knownCount()) + { + std::stringstream s; + s << "Failed BlockQueue invariant: m_readySet: " << m_readySet.size() << " m_verified: " << m_verified.count() << " m_unverified: " << m_unverified.count() << " m_verifying" << m_verifying.count(); + BOOST_THROW_EXCEPTION(FailedInvariant() << errinfo_comment(s.str())); + } + return true; +} + +void BlockQueue::noteReady_WITH_LOCK(h256 const& _good) +{ + DEV_INVARIANT_CHECK; + list goodQueue(1, _good); + bool notify = false; + while (!goodQueue.empty()) + { + h256 const parent = goodQueue.front(); + vector> const removed = m_unknown.removeByKeyEqual(parent); + goodQueue.pop_front(); + for (auto& newReady : removed) + { + DEV_GUARDED(m_verification) + m_unverified.enqueue(UnverifiedBlock { newReady.first, parent, move(newReady.second) }); + m_unknownSet.erase(newReady.first); + m_readySet.insert(newReady.first); + goodQueue.push_back(newReady.first); + notify = true; + } + } + if (notify) + m_moreToVerify.notify_all(); +} + +void BlockQueue::retryAllUnknown() +{ + WriteGuard l(m_lock); + DEV_INVARIANT_CHECK; + while (!m_unknown.isEmpty()) + { + h256 parent = m_unknown.firstKey(); + vector> removed = m_unknown.removeByKeyEqual(parent); + for (auto& newReady : removed) + { + DEV_GUARDED(m_verification) + m_unverified.enqueue(UnverifiedBlock{ newReady.first, parent, move(newReady.second) }); + m_unknownSet.erase(newReady.first); + m_readySet.insert(newReady.first); + m_moreToVerify.notify_one(); + } + } + m_moreToVerify.notify_all(); +} + +std::ostream& dev::eth::operator<<(std::ostream& _out, BlockQueueStatus const& _bqs) +{ + _out << "importing: " << _bqs.importing << endl; + _out << "verified: " << _bqs.verified << endl; + _out << "verifying: " << _bqs.verifying << endl; + _out << "unverified: " << _bqs.unverified << endl; + _out << "future: " << _bqs.future << endl; + _out << "unknown: " << _bqs.unknown << endl; + _out << "bad: " << _bqs.bad << endl; + + return _out; +} + +u256 BlockQueue::difficulty() const +{ + UpgradableGuard l(m_lock); + return m_difficulty; +} + +bool BlockQueue::isActive() const +{ + UpgradableGuard l(m_lock); + if (m_readySet.empty() && m_drainingSet.empty()) + DEV_GUARDED(m_verification) + if (m_verified.isEmpty() && m_verifying.isEmpty() && m_unverified.isEmpty()) + return false; + return true; +} + +std::ostream& dev::eth::operator<< (std::ostream& os, QueueStatus const& obj) +{ + os << static_cast::type>(obj); + return os; +} diff --git a/libethereum/BlockQueue.h b/libethereum/BlockQueue.h new file mode 100644 index 0000000000..326dc4c7af --- /dev/null +++ b/libethereum/BlockQueue.h @@ -0,0 +1,338 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file BlockQueue.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include "VerifiedBlock.h" + +namespace dev +{ + +namespace eth +{ + +class BlockChain; + + + +struct BlockQueueStatus +{ + size_t importing; + size_t verified; + size_t verifying; + size_t unverified; + size_t future; + size_t unknown; + size_t bad; +}; + +enum class QueueStatus +{ + Ready, + Importing, + UnknownParent, + Bad, + Unknown +}; + +std::ostream& operator<< (std::ostream& os, QueueStatus const& obj); + +template +class SizedBlockQueue +{ +public: + std::size_t count() const { return m_queue.size(); } + + std::size_t size() const { return m_size; } + + bool isEmpty() const { return m_queue.empty(); } + + h256 nextHash() const { return m_queue.front().verified.info.sha3Uncles(); } + + T const& next() const { return m_queue.front(); } + + void clear() + { + m_queue.clear(); + m_size = 0; + } + + void enqueue(T&& _t) + { + m_queue.emplace_back(std::move(_t)); + m_size += m_queue.back().blockData.size(); + } + + T dequeue() + { + T t; + std::swap(t, m_queue.front()); + m_queue.pop_front(); + m_size -= t.blockData.size(); + + return t; + } + + std::vector dequeueMultiple(std::size_t _n) + { + return removeRange(m_queue.begin(), m_queue.begin() + _n); + } + + bool remove(h256 const& _hash) + { + std::vector removed = removeIf(sha3UnclesEquals(_hash)); + return !removed.empty(); + } + + template + std::vector removeIf(Pred _pred) + { + auto const removedBegin = std::remove_if(m_queue.begin(), m_queue.end(), _pred); + + return removeRange(removedBegin, m_queue.end()); + } + + bool replace(h256 const& _hash, T&& _t) + { + auto const it = std::find_if(m_queue.begin(), m_queue.end(), sha3UnclesEquals(_hash)); + + if (it == m_queue.end()) + return false; + + m_size -= it->blockData.size(); + m_size += _t.blockData.size(); + *it = std::move(_t); + + return true; + } + + bool exist(h256 const& _hash) { + auto const it = std::find_if(m_queue.begin(), m_queue.end(), sha3UnclesEquals(_hash)); + return it != m_queue.end(); + } + +private: + static std::function sha3UnclesEquals(h256 const& _hash) + { + return [&_hash](T const & _t) { return _t.verified.info.sha3Uncles() == _hash; }; + } + + std::vector removeRange(typename std::deque::iterator _begin, typename std::deque::iterator _end) + { + std::vector ret(std::make_move_iterator(_begin), std::make_move_iterator(_end)); + + for (auto it = ret.begin(); it != ret.end(); ++it) + m_size -= it->blockData.size(); + + m_queue.erase(_begin, _end); + return ret; + } + + std::deque m_queue; + std::atomic m_size = {0}; ///< Tracks total size in bytes +}; + +template +class SizedBlockMap +{ +public: + std::size_t count() const { return m_map.size(); } + + std::size_t size() const { return m_size; } + + bool isEmpty() const { return m_map.empty(); } + + KeyType firstKey() const { return m_map.begin()->first; } + + void clear() + { + m_map.clear(); + m_size = 0; + } + + void insert(KeyType const& _key, h256 const& _hash, bytes&& _blockData) + { + auto hashAndBlock = std::make_pair(_hash, std::move(_blockData)); + auto keyAndValue = std::make_pair(_key, std::move(hashAndBlock)); + m_map.insert(std::move(keyAndValue)); + m_size += _blockData.size(); + } + + std::vector> removeByKeyEqual(KeyType const& _key) + { + auto const equalRange = m_map.equal_range(_key); + return removeRange(equalRange.first, equalRange.second); + } + + std::vector> removeByKeyNotGreater(KeyType const& _key) + { + return removeRange(m_map.begin(), m_map.upper_bound(_key)); + } + +private: + using BlockMultimap = std::multimap>; + + std::vector> removeRange(typename BlockMultimap::iterator _begin, typename BlockMultimap::iterator _end) + { + std::vector> removed; + std::size_t removedSize = 0; + for (auto it = _begin; it != _end; ++it) + { + removed.push_back(std::move(it->second)); + removedSize += removed.back().second.size(); + } + + m_size -= removedSize; + m_map.erase(_begin, _end); + + return removed; + } + + BlockMultimap m_map; + std::atomic m_size = {0}; ///< Tracks total size in bytes +}; + +/** + * @brief A queue of blocks. Sits between network or other I/O and the BlockChain. + * Sorts them ready for blockchain insertion (with the BlockChain::sync() method). + * @threadsafe + */ +class BlockQueue: HasInvariants +{ +public: + BlockQueue(); + ~BlockQueue(); + + void setChain(BlockChain const& _bc) { m_bc = &_bc; } + + /// Import a block into the queue. + ImportResult import(bytesConstRef _block, bool _isOurs = false); + + + ImportResult importVerified(bytesConstRef _block); + + /// Notes that time has moved on and some blocks that used to be "in the future" may no be valid. + void tick(); + + /// Grabs at most @a _max of the blocks that are ready, giving them in the correct order for insertion into the chain. + /// Don't forget to call doneDrain() once you're done importing. + void drain(std::vector& o_out, unsigned _max); + + /// Must be called after a drain() call. Notes that the drained blocks have been imported into the blockchain, so we can forget about them. + /// @returns true iff there are additional blocks ready to be processed. + bool doneDrain(h256s const& _knownBad = h256s()); + + /// Notify the queue that the chain has changed and a new block has attained 'ready' status (i.e. is in the chain). + void noteReady(h256 const& _b) { WriteGuard l(m_lock); noteReady_WITH_LOCK(_b); } + + /// Force a retry of all the blocks with unknown parents. + void retryAllUnknown(); + + /// Get information on the items queued. + std::pair items() const { ReadGuard l(m_lock); return std::make_pair(m_readySet.size(), m_unknownSet.size()); } + + /// Clear everything. + void clear(); + + /// Stop all activity, leaves the class in limbo, waiting for destruction + void stop(); + + /// Return first block with an unknown parent. + h256 firstUnknown() const { ReadGuard l(m_lock); return m_unknownSet.size() ? *m_unknownSet.begin() : h256(); } + + /// Get some infomration on the current status. + BlockQueueStatus status() const; + + /// Get some infomration on the given block's status regarding us. + QueueStatus blockStatus(h256 const& _h) const; + + template Handler<> onReady(T const& _t) { return m_onReady.add(_t); } + template Handler<> onRoomAvailable(T const& _t) { return m_onRoomAvailable.add(_t); } + + template void setOnBad(T const& _t) { m_onBad = _t; } + + bool knownFull() const; + bool unknownFull() const; + u256 difficulty() const; // Total difficulty of queueud blocks + bool isActive() const; + +private: + struct UnverifiedBlock + { + h256 hash; + h256 parentHash; + bytes blockData; + }; + + void noteReady_WITH_LOCK(h256 const& _b); + + bool invariants() const override; + + void verifierBody(); + void collectUnknownBad_WITH_BOTH_LOCKS(h256 const& _bad); + void updateBad_WITH_LOCK(h256 const& _bad); + void drainVerified_WITH_BOTH_LOCKS(); + + std::size_t knownSize() const; + std::size_t knownCount() const; + std::size_t unknownSize() const; + std::size_t unknownCount() const; + + BlockChain const* m_bc; ///< The blockchain into which our imports go. + + mutable boost::shared_mutex m_lock; ///< General lock for the sets, m_future and m_unknown. + h256Hash m_drainingSet; ///< All blocks being imported. + h256Hash m_readySet; ///< All blocks ready for chain import. + h256Hash m_unknownSet; ///< Set of all blocks whose parents are not ready/in-chain. + SizedBlockMap m_unknown; ///< For blocks that have an unknown parent; we map their parent hash to the block stuff, and insert once the block appears. + h256Hash m_knownBad; ///< Set of blocks that we know will never be valid. + SizedBlockMap m_future; ///< Set of blocks that are not yet valid. Ordered by timestamp + Signal<> m_onReady; ///< Called when a subsequent call to import blocks will return a non-empty container. Be nice and exit fast. + Signal<> m_onRoomAvailable; ///< Called when space for new blocks becomes availabe after a drain. Be nice and exit fast. + + mutable Mutex m_verification; ///< Mutex that allows writing to m_verified, m_verifying and m_unverified. + std::condition_variable m_moreToVerify; ///< Signaled when m_unverified has a new entry. + SizedBlockQueue m_verified; ///< List of blocks, in correct order, verified and ready for chain-import. + SizedBlockQueue m_verifying; ///< List of blocks being verified; as long as the block component (bytes) is empty, it's not finished. + SizedBlockQueue m_unverified; ///< List of in correct order, ready for verification. + + std::vector m_verifiers; ///< Threads who only verify. + std::atomic m_deleting = {false}; ///< Exit condition for verifiers. + + std::function m_onBad; ///< Called if we have a block that doesn't verify. + u256 m_difficulty; ///< Total difficulty of blocks in the queue + u256 m_drainingDifficulty; ///< Total difficulty of blocks in draining +}; + +std::ostream& operator<<(std::ostream& _out, BlockQueueStatus const& _s); + +} +} diff --git a/libethereum/CMakeLists.txt b/libethereum/CMakeLists.txt new file mode 100644 index 0000000000..fbf34b2e01 --- /dev/null +++ b/libethereum/CMakeLists.txt @@ -0,0 +1,40 @@ +file(GLOB SRC_LIST "*.cpp") +file(GLOB HEADERS "*.h") + +include(EthDependencies) + + +add_library(ethereum ${SRC_LIST} ${HEADERS}) + +target_link_libraries(ethereum ${Boost_REGEX_LIBRARIES} JsonCpp) + +find_package(Dev) +find_package(Eth) + +target_include_directories(ethereum PRIVATE ..) +target_include_directories(ethereum PRIVATE ../utils) + +include_directories(../libodbc/include + ../libodbc/include/db2_linux + ../libodbc/include/ibase + ../libodbc/include/infomix + ../libodbc/include/mysql + ../libodbc/include/odbc_linux + ../libodbc/include/pgsql + ../libodbc/include/sqlbase + ../libodbc/include/sqllite + ../libodbc/include/ss_linux + ../libodbc/include/sybase) + +target_link_libraries(ethereum ${Eth_ODBC_LIBRARIES}) +target_link_libraries(ethereum ${Eth_ETHCORE_LIBRARIES}) +target_link_libraries(ethereum ${Eth_EVM_LIBRARIES}) + +if (NOT EMSCRIPTEN) + target_link_libraries(ethereum ${Dev_P2P_LIBRARIES}) + target_link_libraries(ethereum ${Dev_DEVCRYPTO_LIBRARIES}) +endif() + +if (EVMJIT) + target_link_libraries(ethereum ${Eth_EVMJIT_LIBRARIES}) +endif() diff --git a/libethereum/ChainParams.cpp b/libethereum/ChainParams.cpp new file mode 100644 index 0000000000..6d91046560 --- /dev/null +++ b/libethereum/ChainParams.cpp @@ -0,0 +1,293 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file ChainParams.h + * @author Gav Wood + * @date 2015 + */ + +#include "ChainParams.h" +#include + +#include +#include +#include +#include + +#include "State.h" +#include "Account.h" +using namespace std; +using namespace dev; +using namespace eth; +namespace js = json_spirit; + + +ChainParams::ChainParams() +{ + for (unsigned i = 1; i <= 4; ++i) + genesisState[Address(i)] = Account(0, 1); + // Setup default precompiled contracts as equal to genesis of Frontier. + precompiled.insert(make_pair(Address(1), PrecompiledContract(3000, 0, PrecompiledRegistrar::executor("ecrecover")))); + precompiled.insert(make_pair(Address(2), PrecompiledContract(60, 12, PrecompiledRegistrar::executor("sha256")))); + precompiled.insert(make_pair(Address(3), PrecompiledContract(600, 120, PrecompiledRegistrar::executor("ripemd160")))); + precompiled.insert(make_pair(Address(4), PrecompiledContract(15, 3, PrecompiledRegistrar::executor("identity")))); +} + +ChainParams::ChainParams(string const& _json, h256 const& _stateRoot) +{ + *this = loadConfig(_json, _stateRoot); +} + +ChainParams ChainParams::loadGodMiner(std::string const& _json) const +{ + ChainParams cp(*this); + js::mValue val; + json_spirit::read_string(_json, val); + js::mObject obj = val.get_obj(); + + cp.godMinerStart = obj.count("godMinerStart") ? u256(fromBigEndian(fromHex(obj["godMinerStart"].get_str()))):0; + cp.godMinerEnd = obj.count("godMinerEnd") ? u256(fromBigEndian(fromHex(obj["godMinerEnd"].get_str()))):0; + if( obj.count("miners") ) + { + for (auto node : obj["miners"].get_array()) + { + NodeConnParams nodeConnParam; + nodeConnParam._sNodeId = node.get_obj()["Nodeid"].get_str(); + nodeConnParam._sAgencyInfo = node.get_obj()["Agencyinfo"].get_str(); + nodeConnParam._sIP = node.get_obj()["Peerip"].get_str(); + nodeConnParam._iPort = node.get_obj()["Port"].get_int(); + nodeConnParam._iIdentityType = node.get_obj()["Identitytype"].get_int(); + nodeConnParam._sAgencyDesc = node.get_obj()["Nodedesc"].get_str(); + nodeConnParam._iIdx = u256(node.get_obj()["Idx"].get_int()); + + cp.godMinerList[nodeConnParam._sNodeId] = nodeConnParam; + } + } + + return cp; +} + +ChainParams ChainParams::loadConfig(string const& _json, h256 const& _stateRoot) const +{ + ChainParams cp(*this); + js::mValue val; + json_spirit::read_string(_json, val); + js::mObject obj = val.get_obj(); + + cp.sealEngineName = obj["sealEngine"].get_str(); + //系统代理合约地址 + cp.sysytemProxyAddress = obj.count("systemproxyaddress") ? h160(obj["systemproxyaddress"].get_str()) : h160(); + cp.listenIp = obj.count("listenip") ? obj["listenip"].get_str() : "0.0.0.0"; + cp.rpcPort = obj.count("rpcport") ? std::stoi(obj["rpcport"].get_str()) : 6789; + cp.p2pPort = obj.count("p2pport") ? std::stoi(obj["p2pport"].get_str()) : 16789; + cp.wallet = obj.count("wallet") ? obj["wallet"].get_str() : "keys.info"; + cp.keystoreDir = obj.count("keystoredir") ? obj["keystoredir"].get_str() : "keystore/"; + cp.dataDir = obj.count("datadir") ? obj["datadir"].get_str() : ""; + cp.logFileConf = obj.count("logconf") ? obj["logconf"].get_str() : ""; + cp.vmKind = obj.count("vm") ? obj["vm"].get_str() : "interpreter"; + cp.networkId = obj.count("networkid") ? std::stoi(obj["networkid"].get_str()) : (unsigned) - 1; + cp.logVerbosity = obj.count("logverbosity") ? std::stoi(obj["logverbosity"].get_str()) : 4; + cp.evmEventLog = obj.count("eventlog") ? ( (obj["eventlog"].get_str() == "ON") ? true : false) : false; + cp.evmCoverLog = obj.count("coverlog") ? ( (obj["coverlog"].get_str() == "ON") ? true : false) : false; + cp.evmCoverLog = obj.count("broadcastToNormalNode") ? ( (obj["broadcastToNormalNode"].get_str() == "ON") ? true : false) : false; + //dfs related configure items + cp.nodeId = obj.count("dfsNode") ? obj["dfsNode"].get_str() : ""; + cp.groupId = obj.count("dfsGroup") ? obj["dfsGroup"].get_str() : ""; + cp.storagePath = obj.count("dfsStorage") ? obj["dfsStorage"].get_str() : ""; + + // params + js::mObject params = obj["params"].get_obj(); + cp.accountStartNonce = u256(fromBigEndian(fromHex(params["accountStartNonce"].get_str()))); + cp.maximumExtraDataSize = u256(fromBigEndian(fromHex(params["maximumExtraDataSize"].get_str()))); + cp.tieBreakingGas = params.count("tieBreakingGas") ? params["tieBreakingGas"].get_bool() : true; + cp.blockReward = u256(fromBigEndian(fromHex(params["blockReward"].get_str()))); + for (auto i : params) + if (i.first != "accountStartNonce" && i.first != "maximumExtraDataSize" && i.first != "blockReward" && i.first != "tieBreakingGas") + cp.otherParams[i.first] = i.second.get_str(); + + // genesis state + string genesisStateStr = json_spirit::write_string(obj["accounts"], false); + + LOG(TRACE) << "genesisStateStr = " << genesisStateStr; + if(genesisStateStr.length() && genesisStateStr != "null"){ + jsonToAccountMap(genesisStateStr, cp.accountStartNonce, nullptr, &cp.precompiled); + } + + if(0 == cp.dataDir.length()) + cp.dataDir = getDataDir("ethereum"); + if(cp.wallet[0] != '/') + cp.wallet = cp.dataDir + "/" + cp.wallet; + if(cp.keystoreDir[0] != '/') + cp.keystoreDir = cp.dataDir + "/" + cp.keystoreDir; + if(cp.logFileConf[0] != '/') + cp.logFileConf = cp.dataDir + "/" + cp.logFileConf; + if(cp.storagePath[0] != '/') + cp.storagePath = cp.dataDir + "/" + cp.storagePath; + + LOG(INFO) << "cp.dataDir=" << cp.dataDir << ",cp.wallet=" << cp.wallet << ",cp.keystoreDir=" << cp.keystoreDir << ",cp.logFileConf=" << cp.logFileConf << ",cp.storagePath=" << cp.storagePath; + return cp; +} + + +ChainParams ChainParams::loadGenesisState(string const& _json, h256 const& _stateRoot) const +{ + ChainParams cp(*this); + cp.genesisState = jsonToAccountMap(_json, cp.accountStartNonce, nullptr, &cp.precompiled); + cp.stateRoot = _stateRoot ? _stateRoot : cp.calculateStateRoot(true); + return cp; +} + +ChainParams ChainParams::loadGenesis(string const& _json, h256 const& _stateRoot) const +{ + ChainParams cp(*this); + + js::mValue val; + json_spirit::read_string(_json, val); + js::mObject genesis = val.get_obj(); + + cp.parentHash = h256(genesis["parentHash"].get_str()); + cp.author = h160(); + cp.difficulty = genesis.count("difficulty") ? u256(fromBigEndian(fromHex(genesis["difficulty"].get_str()))) : 1; + cp.gasLimit = u256(fromBigEndian(fromHex(genesis["gasLimit"].get_str()))); + cp.gasUsed = 0; + cp.timestamp = u256(fromBigEndian(fromHex(genesis["timestamp"].get_str()))); + cp.extraData = bytes(fromHex(genesis["extraData"].get_str())); + + + cp.god = genesis.count("god") ? h160(genesis["god"].get_str()) : h160(); + + cp.author = cp.god; + + // magic code for handling ethash stuff: + if ((genesis.count("mixhash") || genesis.count("mixHash")) && genesis.count("nonce")) + { + h256 mixHash(genesis[genesis.count("mixhash") ? "mixhash" : "mixHash"].get_str()); + h64 nonce(genesis["nonce"].get_str()); + cp.sealFields = 2; + cp.sealRLP = rlp(mixHash) + rlp(nonce); + } + + cp.genesisState = jsonToAccountMap(_json, cp.accountStartNonce, nullptr, &cp.precompiled); + + //读取initNodes + if (genesis.count("initMinerNodes")) + { + for (auto initNode : genesis["initMinerNodes"].get_array()) + { + cp._vInitIdentityNodes.push_back(initNode.get_str()); + std::cout << "initNodes size : " << cp._vInitIdentityNodes.size() << "| node :" << initNode.get_str() << std::endl; + } + } + + cp.stateRoot = _stateRoot ? _stateRoot : cp.calculateStateRoot(); + cout << "loadGenesis: stateRoot=" << cp.stateRoot; + return cp; +} + +SealEngineFace* ChainParams::createSealEngine() +{ + SealEngineFace* ret = SealEngineRegistrar::create(sealEngineName); + cdebug << "sealEngineName=" << sealEngineName; + assert(ret && "Seal engine not found"); + if (!ret) + return nullptr; + ret->setChainParams(*this); + if (sealRLP.empty()) + { + sealFields = ret->sealFields(); + sealRLP = ret->sealRLP(); + } + return ret; +} + +void ChainParams::populateFromGenesis(bytes const& _genesisRLP, AccountMap const& _state) +{ + BlockHeader bi(_genesisRLP, RLP(&_genesisRLP)[0].isList() ? BlockData : HeaderData); + parentHash = bi.parentHash(); + author = bi.author(); + difficulty = bi.difficulty(); + gasLimit = bi.gasLimit(); + gasUsed = bi.gasUsed(); + timestamp = bi.timestamp(); + extraData = bi.extraData(); + genesisState = _state; + RLP r(_genesisRLP); + sealFields = r[0].itemCount() - BlockHeader::BasicFields; + sealRLP.clear(); + for (unsigned i = BlockHeader::BasicFields; i < r[0].itemCount(); ++i) + sealRLP += r[0][i].data(); + + calculateStateRoot(true); + + auto b = genesisBlock(); + if (b != _genesisRLP) + { + LOG(DEBUG) << "Block passed:" << bi.hash() << bi.hash(WithoutSeal); + LOG(DEBUG) << "Genesis now:" << BlockHeader::headerHashFromBlock(b); + LOG(DEBUG) << RLP(b); + LOG(DEBUG) << RLP(_genesisRLP); + throw 0; + } +} + +h256 ChainParams::calculateStateRoot(bool _force) const +{ + MemoryDB db; + SecureTrieDB state(&db); + state.init(); + if (!stateRoot || _force) + { + // TODO: use hash256 + + dev::eth::commit(genesisState, state); + stateRoot = state.root(); + } + return stateRoot; +} + +bytes ChainParams::genesisBlock() const +{ + RLPStream block(3); + + calculateStateRoot(); + + std::vector node_list; + RLPStream node_rs; + for (size_t i = 0; i < node_list.size(); ++i) { + node_rs << node_list[i]; + } + + block.appendList(BlockHeader::BasicFields + sealFields) + << parentHash + << EmptyListSHA3 // sha3(uncles) + << author + << stateRoot + << EmptyTrie // transactions + << EmptyTrie // receipts + << LogBloom() + << difficulty + << 0 // number + << gasLimit + << gasUsed // gasUsed + << timestamp + << extraData + << 0 + << node_rs.out(); + block.appendRaw(sealRLP, sealFields); + block.appendRaw(RLPEmptyList); + block.appendRaw(RLPEmptyList); + return block.out(); +} diff --git a/libethereum/ChainParams.h b/libethereum/ChainParams.h new file mode 100644 index 0000000000..23192f2a5d --- /dev/null +++ b/libethereum/ChainParams.h @@ -0,0 +1,77 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file ChainParams.h + * @author Gav Wood + * @date 2015 + */ + +#pragma once + +#include +#include +#include +#include +#include "Account.h" + +namespace dev +{ +namespace eth +{ + +class SealEngineFace; + +struct ChainParams: public ChainOperationParams +{ + ChainParams(); + ChainParams(ChainParams const& /*_org*/) = default; + ChainParams(std::string const& _s, h256 const& _stateRoot = h256()); + ChainParams(bytes const& _genesisRLP, AccountMap const& _state) { populateFromGenesis(_genesisRLP, _state); } + ChainParams(std::string const& _json, bytes const& _genesisRLP, AccountMap const& _state): ChainParams(_json) { populateFromGenesis(_genesisRLP, _state); } + + SealEngineFace* createSealEngine(); + + /// Genesis params. + h256 parentHash = h256(); + Address author = Address(); + u256 difficulty = 1; + u256 gasLimit = 1 << 31; + u256 gasUsed = 0; + u256 timestamp = 0; + bytes extraData; + mutable h256 stateRoot; ///< Only pre-populate if known equivalent to genesisState's root. If they're different Bad Things Will Happen. + AccountMap genesisState; + + unsigned sealFields = 0; + bytes sealRLP; + + h256 calculateStateRoot(bool _force = false) const; + + std::vector _vInitIdentityNodes; + /// Genesis block info. + bytes genesisBlock() const; + /// load config/genesis + ChainParams loadConfig(std::string const& _json, h256 const& _stateRoot = h256()) const; + ChainParams loadGenesisState(std::string const& _json, h256 const& _stateRoot = h256()) const; + ChainParams loadGenesis(std::string const& _json, h256 const& _stateRoot = h256()) const; + ChainParams loadGodMiner(std::string const& _json) const; + +private: + void populateFromGenesis(bytes const& _genesisRLP, AccountMap const& _state); +}; + +} +} diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp new file mode 100644 index 0000000000..311403977c --- /dev/null +++ b/libethereum/Client.cpp @@ -0,0 +1,1007 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Client.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "Client.h" +#include +#include +#include +#include + +#include +#include "Defaults.h" +#include "Executive.h" +#include "EthereumHost.h" +#include "Utility.h" +#include "Block.h" +#include "NodeConnParamsManager.h" +#include "TransactionQueue.h" +#include + +using namespace std; +using namespace dev; +using namespace dev::eth; +using namespace p2p; + +std::ostream& dev::eth::operator<<(std::ostream& _out, ActivityReport const& _r) +{ + _out << "Since " << toString(_r.since) << " (" << std::chrono::duration_cast(std::chrono::system_clock::now() - _r.since).count(); + _out << "): " << _r.ticks << "ticks"; + return _out; +} + +#if defined(_WIN32) +const char* ClientNote::name() { return EthTeal "^" EthBlue " i"; } +const char* ClientChat::name() { return EthTeal "^" EthWhite " o"; } +const char* ClientTrace::name() { return EthTeal "^" EthGray " O"; } +const char* ClientDetail::name() { return EthTeal "^" EthCoal " 0"; } +#else +const char* ClientNote::name() { return EthTeal "?" EthBlue " ?"; } +const char* ClientChat::name() { return EthTeal "?" EthWhite " ?"; } +const char* ClientTrace::name() { return EthTeal "?" EthGray " ◎"; } +const char* ClientDetail::name() { return EthTeal "?" EthCoal " ●"; } +#endif + +Client::Client( + ChainParams const& _params, + int _networkID, + p2p::Host* _host, + std::shared_ptr _gpForAdoption, + std::string const& _dbPath, + WithExisting _forceAction, + TransactionQueue::Limits const& _l +): + ClientBase(_l), + Worker("eth", 0), + m_bc(std::shared_ptr(this), _params, _dbPath, _forceAction, [](unsigned d, unsigned t) { LOG(ERROR) << "REVISING BLOCKCHAIN: Processed " << d << " of " << t << "...\r"; }), + m_gp(_gpForAdoption ? _gpForAdoption : make_shared()), + m_preSeal(chainParams().accountStartNonce), + m_postSeal(chainParams().accountStartNonce), + m_working(chainParams().accountStartNonce) +{ + init(_host, _dbPath, _forceAction, _networkID); + + + //创建系统合约api + m_systemcontractapi = SystemContractApiFactory::create(_params.sysytemProxyAddress, _params.god, this); + //上帝模式 + if(_params.godMinerStart> 0 ) + { + if( _params.godMinerStart != bc().number()+1 ) + { + cwarn<<"当前区块链高度不符合上帝模式配置,请检查上帝模式配置!blockchain.number="<addCBOn("config", [ this ](string) { + + updateConfig(); + }); + + //必须放在后面,里面用到的变量修改后才可见 + NodeConnManagerSingleton::GetInstance().setSysContractApi(m_systemcontractapi); +} + +void Client::updateConfig() { + string value; + + m_systemcontractapi->getValue("maxBlockTranscations", value); + u256 uvalue = 0; + uvalue = u256(fromBigEndian(fromHex(value))); + if ( uvalue < 1000 ) + uvalue = 1000; + m_maxBlockTranscations = uvalue; + + + value = ""; + m_systemcontractapi->getValue("intervalBlockTime", value); + uvalue = u256(fromBigEndian(fromHex(value))); + if ( uvalue < 1000 ) + uvalue = 1000; + sealEngine()->setIntervalBlockTime(uvalue); + + value = ""; + m_systemcontractapi->getValue("maxBlockHeadGas", value); + uvalue = u256(fromBigEndian(fromHex(value))); + if ( uvalue < 200000000 ) + uvalue = 200000000; + BlockHeader::maxBlockHeadGas = uvalue; + + value = ""; + m_systemcontractapi->getValue("maxTranscationGas", value); + uvalue = u256(fromBigEndian(fromHex(value))); + if ( uvalue < 20000000 ) + uvalue = 20000000; + TransactionBase::maxGas = uvalue; + + value = ""; + m_systemcontractapi->getValue("maxNonceCheckBlock", value); + uvalue = u256(fromBigEndian(fromHex(value))); + if ( uvalue < 1000 ) + uvalue = 1000; + NonceCheck::maxblocksize = uvalue; + + value = ""; + m_systemcontractapi->getValue("maxBlockLimit", value); + uvalue = u256(fromBigEndian(fromHex(value))); + if ( uvalue < 1000 ) + uvalue = 1000; + BlockChain::maxBlockLimit = uvalue; + + value = ""; + m_systemcontractapi->getValue("CAVerify", value); + if ( "true" == value ) + NodeConnParamsManager::CAVerify = true; + else + NodeConnParamsManager::CAVerify = false; + + LOG(TRACE) << "Client::Client m_maxBlockTranscations:" << m_maxBlockTranscations; + LOG(TRACE) << "Client::Client sealEngine() m_intervalBlockTime:" << sealEngine()->getIntervalBlockTime(); + LOG(TRACE) << "Client::Client BlockHeader::maxBlockHeadGas:" << BlockHeader::maxBlockHeadGas; + LOG(TRACE) << "Client::Client TransactionBase::maxTranscationGas:" << TransactionBase::maxGas; + LOG(TRACE) << "Client::Client NonceCheck::maxNonceCheckBlock:" << NonceCheck::maxblocksize; + LOG(TRACE) << "Client::Client BlockChain::maxBlockLimit:" << BlockChain::maxBlockLimit; + LOG(TRACE) << "Client::Client BlockChain::CAVerify:" << NodeConnParamsManager::CAVerify; + +} + + + +u256 Client::filterCheck(const Transaction & _t, FilterCheckScene) const +{ + + + if ( m_systemcontractapi ) + return m_systemcontractapi->transactionFilterCheck(_t); + else + return (u256)SystemContractCode::Other; +} + + +void Client::updateSystemContract(std::shared_ptr block) +{ + m_systemcontractapi->updateSystemContract(block); +} + +void Client::updateCache(Address address) { + m_systemcontractapi->updateCache(address); +} + + + +Client::~Client() +{ + stopWorking(); +} + +void Client::init(p2p::Host* _extNet, std::string const& _dbPath, WithExisting _forceAction, u256 _networkId) +{ + DEV_TIMED_FUNCTION_ABOVE(500); + + // Cannot be opened until after blockchain is open, since BlockChain may upgrade the database. + // TODO: consider returning the upgrade mechanism here. will delaying the opening of the blockchain database + // until after the construction. + m_stateDB = State::openDB(_dbPath, bc().genesisHash(), _forceAction); + // LAZY. TODO: move genesis state construction/commiting to stateDB openning and have this just take the root from the genesis block. + m_preSeal = bc().genesisBlock(m_stateDB); + m_postSeal = m_preSeal; + + + m_bq.setChain(bc()); + + m_lastGetWork = std::chrono::system_clock::now() - chrono::seconds(30); + m_tqReady = m_tq.onReady([ = ]() { this->onTransactionQueueReady(); }); // TODO: should read m_tq->onReady(thisThread, syncTransactionQueue); + m_tqReplaced = m_tq.onReplaced([ = ](h256 const&) { m_needStateReset = true; }); + m_bqReady = m_bq.onReady([ = ]() { this->onBlockQueueReady(); }); // TODO: should read m_bq->onReady(thisThread, syncBlockQueue); + m_bq.setOnBad([ = ](Exception & ex) { this->onBadBlock(ex); }); + bc().setOnBad([ = ](Exception & ex) { this->onBadBlock(ex); }); + bc().setOnBlockImport([ = ](BlockHeader const & _info) { + if (auto h = m_host.lock()) + h->onBlockImported(_info); + }); + + if (_forceAction == WithExisting::Rescue) + bc().rescue(m_stateDB); + + m_gp->update(bc()); + + //注册协议 + auto host = _extNet->registerCapability(make_shared(bc(), m_stateDB, m_tq, m_bq, _networkId)); + m_host = host; + _extNet->addCapability(host, EthereumHost::staticName(), EthereumHost::c_oldProtocolVersion); //TODO: remove this once v61+ protocol is common + + if (_dbPath.size()) + Defaults::setDBPath(_dbPath); + doWork(false); + startWorking(); +} + +ImportResult Client::queueBlock(bytes const& _block, bool _isSafe) +{ + if (m_bq.status().verified + m_bq.status().verifying + m_bq.status().unverified > 10000) + this_thread::sleep_for(std::chrono::milliseconds(500)); + return m_bq.import(&_block, _isSafe); +} + +tuple Client::syncQueue(unsigned _max) +{ + stopWorking(); + return bc().sync(m_bq, m_stateDB, _max); +} + +void Client::onBadBlock(Exception& _ex) const +{ + // BAD BLOCK!!! + bytes const* block = boost::get_error_info(_ex); + if (!block) + { + LOG(WARNING) << "ODD: onBadBlock called but exception (" << _ex.what() << ") has no block in it."; + LOG(WARNING) << boost::diagnostic_information(_ex); + return; + } + + badBlock(*block, _ex.what()); +} + +void Client::callQueuedFunctions() +{ + while (true) + { + function f; + DEV_WRITE_GUARDED(x_functionQueue) + if (!m_functionQueue.empty()) + { + f = m_functionQueue.front(); + m_functionQueue.pop(); + } + if (f) + f(); + else + break; + } +} + +u256 Client::networkId() const +{ + if (auto h = m_host.lock()) + return h->networkId(); + return 0; +} + +void Client::setNetworkId(u256 const& _n) +{ + if (auto h = m_host.lock()) + h->setNetworkId(_n); +} + +bool Client::isSyncing() const +{ + if (auto h = m_host.lock()) + return h->isSyncing(); + return false; +} + +bool Client::isMajorSyncing() const +{ + if (auto h = m_host.lock()) + { + SyncState state = h->status().state; + return (state != SyncState::Idle && state != SyncState::NewBlocks) || h->bq().items().first > 10; + } + return false; +} + +void Client::startedWorking() +{ + // Synchronise the state according to the head of the block chain. + // TODO: currently it contains keys for *all* blocks. Make it remove old ones. + LOG(TRACE) << "startedWorking()"; + + DEV_WRITE_GUARDED(x_preSeal) + m_preSeal.sync(bc()); + DEV_READ_GUARDED(x_preSeal) + { + DEV_WRITE_GUARDED(x_working) + m_working = m_preSeal; + DEV_WRITE_GUARDED(x_postSeal) + m_postSeal = m_preSeal; + } +} + +void Client::doneWorking() +{ + // Synchronise the state according to the head of the block chain. + // TODO: currently it contains keys for *all* blocks. Make it remove old ones. + DEV_WRITE_GUARDED(x_preSeal) + m_preSeal.sync(bc()); + DEV_READ_GUARDED(x_preSeal) + { + DEV_WRITE_GUARDED(x_working) + m_working = m_preSeal; + DEV_WRITE_GUARDED(x_postSeal) + m_postSeal = m_preSeal; + } +} + +void Client::reopenChain(WithExisting _we) +{ + reopenChain(bc().chainParams(), _we); +} + +void Client::reopenChain(ChainParams const& _p, WithExisting _we) +{ + bool wasSealing = wouldSeal(); + if (wasSealing) + stopSealing(); + stopWorking(); + + m_tq.clear(); + m_bq.clear(); + sealEngine()->cancelGeneration(); + + { + WriteGuard l(x_postSeal); + WriteGuard l2(x_preSeal); + WriteGuard l3(x_working); + + auto author = m_preSeal.author(); // backup and restore author. + m_preSeal = Block(chainParams().accountStartNonce); + m_postSeal = Block(chainParams().accountStartNonce); + m_working = Block(chainParams().accountStartNonce); + + m_stateDB = OverlayDB(); + bc().reopen(_p, _we); + m_stateDB = State::openDB(Defaults::dbPath(), bc().genesisHash(), _we); + + m_preSeal = bc().genesisBlock(m_stateDB); + m_preSeal.setAuthor(author); + m_postSeal = m_preSeal; + m_working = Block(chainParams().accountStartNonce); + } + + if (auto h = m_host.lock()) + h->reset(); + + startedWorking(); + doWork(); + + startWorking(); + if (wasSealing) + startSealing(); +} + +void Client::executeInMainThread(function const& _function) +{ + DEV_WRITE_GUARDED(x_functionQueue) + m_functionQueue.push(_function); + m_signalled.notify_all(); +} + +void Client::clearPending() +{ + DEV_WRITE_GUARDED(x_postSeal) + { + if (!m_postSeal.pending().size()) + return; + m_tq.clear(); + DEV_READ_GUARDED(x_preSeal) + m_postSeal = m_preSeal; + } + + startSealing(); + h256Hash changeds; + noteChanged(changeds); +} + +template +static S& filtersStreamOut(S& _out, T const& _fs) +{ + _out << "{"; + unsigned i = 0; + for (h256 const& f : _fs) + { + _out << (i++ ? ", " : ""); + if (f == PendingChangedFilter) + _out << LogTag::Special << "pending"; + else if (f == ChainChangedFilter) + _out << LogTag::Special << "chain"; + else + _out << f; + } + _out << "}"; + return _out; +} + +void Client::appendFromNewPending(TransactionReceipt const& _receipt, h256Hash& io_changed, h256 _sha3) +{ + Guard l(x_filtersWatches); + io_changed.insert(PendingChangedFilter); + m_specialFilters.at(PendingChangedFilter).push_back(_sha3); + for (pair& i : m_filters) + { + // acceptable number. + auto m = i.second.filter.matches(_receipt); + if (m.size()) + { + // filter catches them + for (LogEntry const& l : m) + i.second.changes.push_back(LocalisedLogEntry(l)); + io_changed.insert(i.first); + } + } +} + +void Client::appendFromBlock(h256 const& _block, BlockPolarity _polarity, h256Hash& io_changed) +{ + // TODO: more precise check on whether the txs match. + auto receipts = bc().receipts(_block).receipts; + + Guard l(x_filtersWatches); + io_changed.insert(ChainChangedFilter); + m_specialFilters.at(ChainChangedFilter).push_back(_block); + for (pair& i : m_filters) + { + // acceptable number & looks like block may contain a matching log entry. + for (size_t j = 0; j < receipts.size(); j++) + { + auto tr = receipts[j]; + auto m = i.second.filter.matches(tr); + if (m.size()) + { + auto transactionHash = transaction(_block, j).sha3(); + // filter catches them + for (LogEntry const& l : m) + i.second.changes.push_back(LocalisedLogEntry(l, _block, (BlockNumber)bc().number(_block), transactionHash, j, 0, _polarity)); + io_changed.insert(i.first); + } + } + } +} + +ExecutionResult Client::call(Address _dest, bytes const& _data, u256 _gas, u256 _value, u256 _gasPrice, Address const& _from) +{ + ExecutionResult ret; + try + { + Block temp(chainParams().accountStartNonce); + temp.setEvmEventLog(bc().chainParams().evmEventLog); + + clog(ClientDetail) << "Nonce at " << _dest << " pre:" << m_preSeal.transactionsFrom(_dest) << " post:" << m_postSeal.transactionsFrom(_dest); + DEV_READ_GUARDED(x_postSeal) + temp = m_postSeal; + temp.mutableState().addBalance(_from, _value + _gasPrice * _gas); + Executive e(temp); + e.setResultRecipient(ret); + if (!e.call(_dest, _from, _value, _gasPrice, &_data, _gas)) + e.go(); + e.finalize(); + } + catch (...) + { + LOG(WARNING) << "Client::call failed: " << boost::current_exception_diagnostic_information(); + } + return ret; +} + +unsigned static const c_syncMin = 1; +unsigned static const c_syncMax = 1000; +double static const c_targetDuration = 1; + +void Client::syncBlockQueue() +{ + + ImportRoute ir; + unsigned count; + Timer t; + tie(ir, m_syncBlockQueue, count) = bc().sync(m_bq, m_stateDB, m_syncAmount); + double elapsed = t.elapsed(); + + if (count) + { + LOG(TRACE) << count << "blocks imported in" << unsigned(elapsed * 1000) << "ms (" << (count / elapsed) << "blocks/s) in #" << bc().number(); + } + + if (elapsed > c_targetDuration * 1.1 && count > c_syncMin) + m_syncAmount = max(c_syncMin, count * 9 / 10); + else if (count == m_syncAmount && elapsed < c_targetDuration * 0.9 && m_syncAmount < c_syncMax) + m_syncAmount = min(c_syncMax, m_syncAmount * 11 / 10 + 1); + if (ir.liveBlocks.empty()) + return; + onChainChanged(ir); +} + +void Client::syncTransactionQueue() +{ + Timer timer; + + h256Hash changeds; + TransactionReceipts newPendingReceipts; + + DEV_WRITE_GUARDED(x_working) + { + if (m_working.isSealed()) + { + LOG(TRACE) << "Skipping txq sync for a sealed block."; + return; + } + if ( m_working.pending().size() >= m_maxBlockTranscations ) + { + LOG(TRACE) << "Skipping txq sync for Full block ."; + return; + } + + tie(newPendingReceipts, m_syncTransactionQueue) = m_working.sync(bc(), m_tq, *m_gp); + } + + if (newPendingReceipts.empty()) + { + auto s = m_tq.status(); + LOG(TRACE) << "No transactions to process. " << m_working.pending().size() << " pending, " << s.current << " queued, " << s.future << " future, " << s.unverified << " unverified"; + return; + } + + DEV_READ_GUARDED(x_working) + DEV_WRITE_GUARDED(x_postSeal) + m_postSeal = m_working; + + DEV_READ_GUARDED(x_postSeal) + for (size_t i = 0; i < newPendingReceipts.size(); i++) + appendFromNewPending(newPendingReceipts[i], changeds, m_postSeal.pending()[i].sha3()); + + // Tell farm about new transaction (i.e. restart mining). + onPostStateChanged(); + + // Tell watches about the new transactions. + noteChanged(changeds); + + // Tell network about the new transactions. + if (auto h = m_host.lock()) + h->noteNewTransactions(); + + LOG(TRACE) << "Processed " << newPendingReceipts.size() << " transactions in" << (timer.elapsed() * 1000) << "(" << (bool)m_syncTransactionQueue << ")"; +} + +void Client::onDeadBlocks(h256s const& _blocks, h256Hash& io_changed) +{ + // insert transactions that we are declaring the dead part of the chain + for (auto const& h : _blocks) + { + LOG(TRACE) << "Dead block:" << h; + for (auto const& t : bc().transactions(h)) + { + LOG(TRACE) << "Resubmitting dead-block transaction " << Transaction(t, CheckTransaction::None); + LOG(TRACE) << "Resubmitting dead-block transaction " << Transaction(t, CheckTransaction::None); + m_tq.import(t, IfDropped::Retry); + } + } + + for (auto const& h : _blocks) + appendFromBlock(h, BlockPolarity::Dead, io_changed); +} + +Host* Client::host() +{ + if (auto h = m_host.lock()) + return h->host(); + + return 0; +} + +void Client::onNewBlocks(h256s const& _blocks, h256Hash& io_changed) +{ + // remove transactions from m_tq nicely rather than relying on out of date nonce later on. + for (auto const& h : _blocks) + LOG(TRACE) << "Live block:" << h; + + if (auto h = m_host.lock()) + h->noteNewBlocks(); + + for (auto const& h : _blocks) + appendFromBlock(h, BlockPolarity::Live, io_changed); +} + +void Client::resyncStateFromChain() +{ + // RESTART MINING + + if (!isMajorSyncing()) + { + bool preChanged = false; + Block newPreMine(chainParams().accountStartNonce); + DEV_READ_GUARDED(x_preSeal) + newPreMine = m_preSeal; + + // TODO: use m_postSeal to avoid re-evaluating our own blocks. + preChanged = newPreMine.sync(bc()); + + if (preChanged || m_postSeal.author() != m_preSeal.author()) + { + DEV_WRITE_GUARDED(x_preSeal) + m_preSeal = newPreMine; + DEV_WRITE_GUARDED(x_working) + m_working = newPreMine; + DEV_READ_GUARDED(x_postSeal) + if (!m_postSeal.isSealed() || m_postSeal.info().hash() != newPreMine.info().parentHash()) + for (auto const& t : m_postSeal.pending()) + { + LOG(TRACE) << "Resubmitting post-seal transaction " << t; + + auto ir = m_tq.import(t, IfDropped::Retry); + if (ir != ImportResult::Success) + onTransactionQueueReady(); + } + DEV_READ_GUARDED(x_working) DEV_WRITE_GUARDED(x_postSeal) + m_postSeal = m_working; + + onPostStateChanged(); + } + + // Quick hack for now - the TQ at this point already has the prior pending transactions in it; + // we should resync with it manually until we are stricter about what constitutes "knowing". + onTransactionQueueReady(); + } +} + +void Client::resetState() +{ + Block newPreMine(chainParams().accountStartNonce); + DEV_READ_GUARDED(x_preSeal) + newPreMine = m_preSeal; + + DEV_WRITE_GUARDED(x_working) + m_working = newPreMine; + DEV_READ_GUARDED(x_working) DEV_WRITE_GUARDED(x_postSeal) + m_postSeal = m_working; + + onPostStateChanged(); + onTransactionQueueReady(); +} + +void Client::onChainChanged(ImportRoute const& _ir) +{ + + h256Hash changeds; + onDeadBlocks(_ir.deadBlocks, changeds); + for (auto const& t : _ir.goodTranactions) + { + LOG(TRACE) << "Safely dropping transaction " << t.sha3(); + m_tq.dropGood(t); + } + onNewBlocks(_ir.liveBlocks, changeds); + resyncStateFromChain(); + noteChanged(changeds); +} + +bool Client::remoteActive() const +{ + return chrono::system_clock::now() - m_lastGetWork < chrono::seconds(30); +} + +void Client::onPostStateChanged() +{ + LOG(TRACE) << "Post state changed."; + m_signalled.notify_all(); + m_remoteWorking = false; +} + +void Client::startSealing() +{ + if (m_wouldSeal == true) + return; + + LOG(TRACE) << "Client Mining Beneficiary: " << author(); + + { + m_wouldSeal = true; + m_signalled.notify_all(); + } + +} + +void Client::rejigSealing() +{ + + if ((wouldSeal() || remoteActive()) && !isMajorSyncing()) + { + if (sealEngine()->shouldSeal(this)) + { + + m_wouldButShouldnot = false; + + LOG(TRACE) << "Rejigging seal engine..."; + DEV_WRITE_GUARDED(x_working) + { + if (m_working.isSealed()) + { + LOG(TRACE) << "Tried to seal sealed block..."; + return; + } + m_working.commitToSeal(bc(), m_extraData); + } + DEV_READ_GUARDED(x_working) + { + DEV_WRITE_GUARDED(x_postSeal) + m_postSeal = m_working; + m_sealingInfo = m_working.info(); + } + + if (wouldSeal()) + { + sealEngine()->onSealGenerated([ = ](bytes const & header) { + if (!this->submitSealed(header)) + LOG(TRACE) << "Submitting block failed..."; + }); + LOG(TRACE) << "Generating seal on" << m_sealingInfo.hash(WithoutSeal) << "#" << m_sealingInfo.number(); + sealEngine()->generateSeal(m_sealingInfo); + } + } + else + m_wouldButShouldnot = true; + } + if (!m_wouldSeal) + sealEngine()->cancelGeneration(); +} + +void Client::noteChanged(h256Hash const& _filters) +{ + Guard l(x_filtersWatches); + + /*if (_filters.size()) + filtersStreamOut(cwatch << "noteChanged:", _filters);*/ + // accrue all changes left in each filter into the watches. + for (auto& w : m_watches) + if (_filters.count(w.second.id)) + { + if (m_filters.count(w.second.id)) + { + //cwatch << "!!!" << w.first << w.second.id.abridged(); + w.second.changes += m_filters.at(w.second.id).changes; + } + else if (m_specialFilters.count(w.second.id)) + for (h256 const& hash : m_specialFilters.at(w.second.id)) + { + //cwatch << "!!!" << w.first << LogTag::Special << (w.second.id == PendingChangedFilter ? "pending" : w.second.id == ChainChangedFilter ? "chain" : "???"); + w.second.changes.push_back(LocalisedLogEntry(SpecialLogEntry, hash)); + } + } + // clear the filters now. + for (auto& i : m_filters) + i.second.changes.clear(); + for (auto& i : m_specialFilters) + i.second.clear(); +} + +void Client::doWork(bool _doWait) +{ + bool t = true; + if (m_syncBlockQueue.compare_exchange_strong(t, false)) + syncBlockQueue(); + + if (m_needStateReset) + { + resetState(); + m_needStateReset = false; + } + + t = true; + bool isSealed = false; + DEV_READ_GUARDED(x_working) + isSealed = m_working.isSealed(); + if (!isSealed && !isSyncing() && !m_remoteWorking && m_syncTransactionQueue.compare_exchange_strong(t, false)) + syncTransactionQueue(); + + tick(); + + rejigSealing(); + + callQueuedFunctions(); + + DEV_READ_GUARDED(x_working) + isSealed = m_working.isSealed(); + // If the block is sealed, we have to wait for it to tickle through the block queue + // (which only signals as wanting to be synced if it is ready). + if (!m_syncBlockQueue && !m_syncTransactionQueue && (_doWait || isSealed)) + { + std::unique_lock l(x_signalled); + m_signalled.wait_for(l, chrono::seconds(1)); + } +} + +void Client::tick() +{ + if (chrono::system_clock::now() - m_lastTick > chrono::seconds(1)) + { + m_report.ticks++; + checkWatchGarbage(); + m_bq.tick(); + m_lastTick = chrono::system_clock::now(); + if (m_report.ticks == 15) + LOG(TRACE) << activityReport(); + } +} + +void Client::checkWatchGarbage() +{ + if (chrono::system_clock::now() - m_lastGarbageCollection > chrono::seconds(5)) + { + // watches garbage collection + vector toUninstall; + DEV_GUARDED(x_filtersWatches) + for (auto key : keysOf(m_watches)) + if (m_watches[key].lastPoll != chrono::system_clock::time_point::max() && chrono::system_clock::now() - m_watches[key].lastPoll > chrono::seconds(20)) + { + toUninstall.push_back(key); + LOG(TRACE) << "GC: Uninstall" << key << "(" << chrono::duration_cast(chrono::system_clock::now() - m_watches[key].lastPoll).count() << "s old)"; + } + for (auto i : toUninstall) + uninstallWatch(i); + + // blockchain GC + bc().garbageCollect(); + + m_lastGarbageCollection = chrono::system_clock::now(); + } +} + +void Client::prepareForTransaction() +{ + startWorking(); +} + +Block Client::block(h256 const& _block) const +{ + + try + { + Block ret(bc(), m_stateDB); + ret.populateFromChain(bc(), _block); + return ret; + } + catch (Exception& ex) + { + //LOG(ERROR) << boost::current_exception_diagnostic_information() << endl; + ex << errinfo_block(bc().block(_block)); + onBadBlock(ex); + return Block(bc()); + } +} + +Block Client::block(h256 const& _blockHash, PopulationStatistics* o_stats) const +{ + try + { + Block ret(bc(), m_stateDB); + PopulationStatistics s = ret.populateFromChain(bc(), _blockHash); + if (o_stats) + swap(s, *o_stats); + return ret; + } + catch (Exception& ex) + { + ex << errinfo_block(bc().block(_blockHash)); + onBadBlock(ex); + return Block(bc()); + } +} + +State Client::state(unsigned _txi, h256 const& _blockHash) const +{ + try + { + return block(_blockHash).fromPending(_txi); + } + catch (Exception& ex) + { + ex << errinfo_block(bc().block(_blockHash)); + onBadBlock(ex); + return State(chainParams().accountStartNonce); + } +} + +eth::State Client::state(unsigned _txi) const +{ + DEV_READ_GUARDED(x_postSeal) + return m_postSeal.fromPending(_txi); + assert(false); + return State(chainParams().accountStartNonce); +} + +void Client::flushTransactions() +{ + doWork(); +} + +SyncStatus Client::syncStatus() const +{ + auto h = m_host.lock(); + if (!h) + return SyncStatus(); + SyncStatus status = h->status(); + status.majorSyncing = isMajorSyncing(); + return status; +} + +bool Client::submitSealed(bytes const& _header) +{ + bytes newBlock; + { + UpgradableGuard l(x_working); + { + UpgradeGuard l2(l); + if (!m_working.sealBlock(_header)) + return false; + } + DEV_WRITE_GUARDED(x_postSeal) + m_postSeal = m_working; + newBlock = m_working.blockData(); + } + + // OPTIMISE: very inefficient to not utilise the existing OverlayDB in m_postSeal that contains all trie changes. + return m_bq.import(&newBlock, true) == ImportResult::Success; +} + +void Client::rewind(unsigned _n) +{ + executeInMainThread([ = ]() { + bc().rewind(_n); + onChainChanged(ImportRoute()); + }); + + for (unsigned i = 0; i < 10; ++i) + { + u256 n; + DEV_READ_GUARDED(x_working) + n = m_working.info().number(); + if (n == _n + 1) + break; + this_thread::sleep_for(std::chrono::milliseconds(50)); + } + auto h = m_host.lock(); + if (h) + h->reset(); +} + +int Client::getResultInt(ExecutionResult& result, int& value) +{ + value = -1; + if (result.output.size() < 32) + { + LOG(ERROR) << "bad result, less than 32 < " << result.output.size(); + return -1; + } + + //LOG(TRACE) << "the result size:" << result.output.size() << ",data: " << result.output; + value = fromBigEndian(bytes(result.output.begin(), result.output.begin()+32)).convert_to(); + return 0; +} + +//find the contract address by name +Address Client::findContract(const string& contract) +{ + return m_systemcontractapi->getRoute(contract); +} diff --git a/libethereum/Client.h b/libethereum/Client.h new file mode 100644 index 0000000000..49fa57363d --- /dev/null +++ b/libethereum/Client.h @@ -0,0 +1,367 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Client.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include "BlockChain.h" +#include "Block.h" +#include "CommonNet.h" +#include "ClientBase.h" +#include "SystemContractApi.h" + +namespace dev +{ +namespace eth +{ + +class Client; +class DownloadMan; +class SystemContractApi; + +enum ClientWorkState +{ + Active = 0, + Deleting, + Deleted +}; + +struct ClientNote: public LogChannel { static const char* name(); static const int verbosity = 2; }; +struct ClientChat: public LogChannel { static const char* name(); static const int verbosity = 4; }; +struct ClientTrace: public LogChannel { static const char* name(); static const int verbosity = 7; }; +struct ClientDetail: public LogChannel { static const char* name(); static const int verbosity = 14; }; + + +struct ActivityReport +{ + unsigned ticks = 0; + std::chrono::system_clock::time_point since = std::chrono::system_clock::now(); +}; + +std::ostream& operator<<(std::ostream& _out, ActivityReport const& _r); + +/** + * @brief Main API hub for interfacing with Ethereum. + */ +class Client: public ClientBase, protected Worker +{ +public: + Client( + ChainParams const& _params, + int _networkID, + p2p::Host* _host, + std::shared_ptr _gpForAdoption, + std::string const& _dbPath = std::string(), + WithExisting _forceAction = WithExisting::Trust, + TransactionQueue::Limits const& _l = TransactionQueue::Limits {1024, 1024} + ); + /// Destructor. + virtual ~Client(); + + /// Get information on this chain. + ChainParams const& chainParams() const { return bc().chainParams(); } + + /// Resets the gas pricer to some other object. + void setGasPricer(std::shared_ptr _gp) { m_gp = _gp; } + std::shared_ptr gasPricer() const { return m_gp; } + + /// Blocks until all pending transactions have been processed. + virtual void flushTransactions() override; + + /// Queues a block for import. + ImportResult queueBlock(bytes const& _block, bool _isSafe = false); + + using Interface::call; // to remove warning about hiding virtual function + /// Makes the given call. Nothing is recorded into the state. This cheats by creating a null address and endowing it with a lot of ETH. + ExecutionResult call(Address _dest, bytes const& _data = bytes(), u256 _gas = 125000, u256 _value = 0, u256 _gasPrice = 1 * ether, Address const& _from = Address()); + + /// Get the remaining gas limit in this block. + virtual u256 gasLimitRemaining() const override { return m_postSeal.gasLimitRemaining(); } + /// Get the gas bid price + virtual u256 gasBidPrice() const override { return m_gp->bid(); } + + // [PRIVATE API - only relevant for base clients, not available in general] + /// Get the block. + dev::eth::Block block(h256 const& _blockHash, PopulationStatistics* o_stats) const; + /// Get the state of the given block part way through execution, immediately before transaction + /// index @a _txi. + dev::eth::State state(unsigned _txi, h256 const& _block) const; + /// Get the state of the currently pending block part way through execution, immediately before + /// transaction index @a _txi. + dev::eth::State state(unsigned _txi) const; + + /// Get the object representing the current state of Ethereum. + dev::eth::Block postState() const { ReadGuard l(x_postSeal); return m_postSeal; } + /// Get the object representing the current canonical blockchain. + BlockChain const& blockChain() const { return bc(); } + /// Get some information on the block queue. + BlockQueueStatus blockQueueStatus() const { return m_bq.status(); } + /// Get some information on the block syncing. + SyncStatus syncStatus() const override; + /// Get the block queue. + BlockQueue const& blockQueue() const { return m_bq; } + /// Get the block queue. + OverlayDB const& stateDB() const { return m_stateDB; } + /// Get some information on the transaction queue. + TransactionQueue::Status transactionQueueStatus() const { return m_tq.status(); } + TransactionQueue::Limits transactionQueueLimits() const { return m_tq.limits(); } + + /// Freeze worker thread and sync some of the block queue. + std::tuple syncQueue(unsigned _max = 1); + + // Sealing stuff: + // Note: "mining"/"miner" is deprecated. Use "sealing"/"sealer". + + virtual Address author() const override { ReadGuard l(x_preSeal); return m_preSeal.author(); } + virtual void setAuthor(Address const& _us) override { WriteGuard l(x_preSeal); m_preSeal.setAuthor(_us); } + + /// Type of sealers available for this seal engine. + strings sealers() const { return sealEngine()->sealers(); } + /// Current sealer in use. + std::string sealer() const { return sealEngine()->sealer(); } + /// Change sealer. + void setSealer(std::string const& _id) { sealEngine()->setSealer(_id); if (wouldSeal()) startSealing(); } + /// Review option for the sealer. + bytes sealOption(std::string const& _name) const { return sealEngine()->option(_name); } + /// Set option for the sealer. + bool setSealOption(std::string const& _name, bytes const& _value) { auto ret = sealEngine()->setOption(_name, _value); if (wouldSeal()) startSealing(); return ret; } + + /// Start sealing. + virtual void startSealing() override; + /// Stop sealing. + virtual void stopSealing() override { m_wouldSeal = false; } + /// Are we sealing now? + bool wouldSeal() const override { return m_wouldSeal; } + + /// Are we updating the chain (syncing or importing a new block)? + bool isSyncing() const override; + /// Are we syncing the chain? + bool isMajorSyncing() const override; + + /// Gets the network id. + u256 networkId() const override; + /// Sets the network id. + void setNetworkId(u256 const& _n) override; + + /// Get the seal engine. + SealEngineFace* sealEngine() const override { return bc().sealEngine(); } + + // Debug stuff: + + DownloadMan const* downloadMan() const; + /// Clears pending transactions. Just for debug use. + void clearPending(); + /// Kills the blockchain. Just for debug use. + void killChain() { reopenChain(WithExisting::Kill); } + /// Reloads the blockchain. Just for debug use. + void reopenChain(ChainParams const& _p, WithExisting _we = WithExisting::Trust); + void reopenChain(WithExisting _we); + /// Retries all blocks with unknown parents. + void retryUnknown() { m_bq.retryAllUnknown(); } + /// Get a report of activity. + ActivityReport activityReport() { ActivityReport ret; std::swap(m_report, ret); return ret; } + /// Set the extra data that goes into sealed blocks. + void setExtraData(bytes const& _extraData) { m_extraData = _extraData; } + /// Rewind to a prior head. + void rewind(unsigned _n); + /// Rescue the chain. + void rescue() { bc().rescue(m_stateDB); } + + /// Queues a function to be executed in the main thread (that owns the blockchain, etc). + void executeInMainThread(std::function const& _function); + + virtual Block block(h256 const& _block) const override; + using ClientBase::block; + + u256 filterCheck(const Transaction & _t, FilterCheckScene _checkscene = FilterCheckScene::None) const override; + void updateSystemContract(std::shared_ptr block) override; + void updateCache(Address address) override; + + + + virtual bool isMining() const { return m_wouldSeal; } + bool checkWorking(){return isWorking();}; + p2p::Host* host(); + + //get the result from state query result + int getResultInt(ExecutionResult& result, int& value); + //find the contract address by name + Address findContract(const string& contract); + +protected: + /// Perform critical setup functions. + /// Must be called in the constructor of the finally derived class. + void init(p2p::Host* _extNet, std::string const& _dbPath, WithExisting _forceAction, u256 _networkId); + + /// InterfaceStub methods + BlockChain& bc() override { return m_bc; } + BlockChain const& bc() const override { return m_bc; } + + /// Returns the state object for the full block (i.e. the terminal state) for index _h. + /// Works properly with LatestBlock and PendingBlock. + virtual Block preSeal() const override { ReadGuard l(x_preSeal); return m_preSeal; } + virtual Block postSeal() const override { ReadGuard l(x_postSeal); return m_postSeal; } + virtual void prepareForTransaction() override; + + /// Collate the changed filters for the bloom filter of the given pending transaction. + /// Insert any filters that are activated into @a o_changed. + void appendFromNewPending(TransactionReceipt const& _receipt, h256Hash& io_changed, h256 _sha3); + + /// Collate the changed filters for the hash of the given block. + /// Insert any filters that are activated into @a o_changed. + void appendFromBlock(h256 const& _blockHash, BlockPolarity _polarity, h256Hash& io_changed); + + /// Record that the set of filters @a _filters have changed. + /// This doesn't actually make any callbacks, but incrememnts some counters in m_watches. + void noteChanged(h256Hash const& _filters); + + /// Submit + virtual bool submitSealed(bytes const& _s); + +protected: + /// Called when Worker is starting. + void startedWorking() override; + + /// Do some work. Handles blockchain maintenance and sealing. + virtual void doWork(bool _doWait); + virtual void doWork() override { doWork(true); } + + /// Called when Worker is exiting. + void doneWorking() override; + + /// Called when wouldSeal(), pendingTransactions() have changed. + virtual void rejigSealing(); + + /// Called on chain changes + void onDeadBlocks(h256s const& _blocks, h256Hash& io_changed); + + /// Called on chain changes + virtual void onNewBlocks(h256s const& _blocks, h256Hash& io_changed); + + /// Called after processing blocks by onChainChanged(_ir) + void resyncStateFromChain(); + + /// Clear working state of transactions + void resetState(); + + /// Magically called when the chain has changed. An import route is provided. + /// Called by either submitWork() or in our main thread through syncBlockQueue(). + void onChainChanged(ImportRoute const& _ir); + + /// Signal handler for when the block queue needs processing. + virtual void syncBlockQueue(); + + /// Signal handler for when the block queue needs processing. + virtual void syncTransactionQueue(); + + /// Magically called when m_tq needs syncing. Be nice and don't block. + virtual void onTransactionQueueReady() { m_syncTransactionQueue = true; m_signalled.notify_all(); } + + /// Magically called when m_bq needs syncing. Be nice and don't block. + void onBlockQueueReady() { m_syncBlockQueue = true; m_signalled.notify_all(); } + + /// Called when the post state has changed (i.e. when more transactions are in it or we're sealing on a new block). + /// This updates m_sealingInfo. + void onPostStateChanged(); + + /// Does garbage collection on watches. + void checkWatchGarbage(); + + /// Ticks various system-level objects. + void tick(); + + /// Called when we have attempted to import a bad block. + /// @warning May be called from any thread. + void onBadBlock(Exception& _ex) const; + + /// Executes the pending functions in m_functionQueue + void callQueuedFunctions(); + + void updateConfig(); + + BlockChain m_bc; ///< Maintains block database and owns the seal engine. + BlockQueue m_bq; ///< Maintains a list of incoming blocks not yet on the blockchain (to be imported). + std::shared_ptr m_gp; ///< The gas pricer. + + OverlayDB m_stateDB; ///< Acts as the central point for the state database, so multiple States can share it. + mutable SharedMutex x_preSeal; ///< Lock on m_preSeal. + Block m_preSeal; ///< The present state of the client. + mutable SharedMutex x_postSeal; ///< Lock on m_postSeal. + Block m_postSeal; ///< The state of the client which we're sealing (i.e. it'll have all the rewards added). + mutable SharedMutex x_working; ///< Lock on m_working. + Block m_working; ///< The state of the client which we're sealing (i.e. it'll have all the rewards added), while we're actually working on it. + BlockHeader m_sealingInfo; ///< The header we're attempting to seal on (derived from m_postSeal). + bool remoteActive() const; ///< Is there an active and valid remote worker? + bool m_remoteWorking = false; ///< Has the remote worker recently been reset? + std::atomic m_needStateReset = { false }; ///< Need reset working state to premin on next sync + std::chrono::system_clock::time_point m_lastGetWork; ///< Is there an active and valid remote worker? + + std::weak_ptr m_host; ///< Our Ethereum Host. Don't do anything if we can't lock. + + Handler<> m_tqReady; + Handler m_tqReplaced; + Handler<> m_bqReady; + + bool m_wouldSeal = false; ///< True if we /should/ be sealing. + bool m_wouldButShouldnot = false; ///< True if the last time we called rejigSealing wouldSeal() was true but sealer's shouldSeal() was false. + + mutable std::chrono::system_clock::time_point m_lastGarbageCollection; + ///< When did we last both doing GC on the watches? + mutable std::chrono::system_clock::time_point m_lastTick = std::chrono::system_clock::now(); + ///< When did we last tick()? + + unsigned m_syncAmount = 50; ///< Number of blocks to sync in each go. + + ActivityReport m_report; + + SharedMutex x_functionQueue; + std::queue> m_functionQueue; ///< Functions waiting to be executed in the main thread. + + std::condition_variable m_signalled; + Mutex x_signalled; + std::atomic m_syncTransactionQueue = {false}; + std::atomic m_syncBlockQueue = {false}; + + + bytes m_extraData; + + u256 m_maxBlockTranscations = 1000; + std::shared_ptr m_systemcontractapi; +}; + +} +} diff --git a/libethereum/ClientBase.cpp b/libethereum/ClientBase.cpp new file mode 100644 index 0000000000..5249c7495a --- /dev/null +++ b/libethereum/ClientBase.cpp @@ -0,0 +1,622 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . + */ +/** @file ClientBase.cpp + * @author Gav Wood + * @author Marek Kotewicz + * @date 2015 + */ + +#include "ClientBase.h" +#include +#include "BlockChain.h" +#include "Executive.h" +#include "State.h" +#include "SystemContractApi.h" + +using namespace std; +using namespace dev; +using namespace dev::eth; + + + +namespace dev { namespace eth { const u256 c_maxGasEstimate = 50000000; } } + +bool ClientBase::isNonceOk(Transaction const&_ts) const +{ + return bc().isNonceOk(_ts); +} +bool ClientBase::isBlockLimitOk(Transaction const&_ts) const +{ + return bc().isBlockLimitOk(_ts); +} + +pair ClientBase::submitTransaction(TransactionSkeleton const& _t, Secret const& _secret) +{ + prepareForTransaction(); + + TransactionSkeleton ts(_t); + ts.from = toAddress(_secret); + + + + Transaction t(ts, _secret); + LOG(TRACE) << "ClientBase::submitTransaction " << t.sha3(); + ImportResult ir = m_tq.import(t.rlp()); + if ( ir == ImportResult::NonceCheckFail ) + { + return make_pair(t.sha3(), Address(1) ); + } + else if ( ImportResult::BlockLimitCheckFail == ir ) + { + return make_pair(t.sha3(), Address(2) ); + } + else if ( ImportResult::NoTxPermission == ir ) + { + return make_pair(t.sha3(), Address(3)); + } + else if ( ImportResult::NoDeployPermission == ir ) + { + return make_pair(t.sha3(), Address(4) ); + } + return make_pair(t.sha3(), toAddress(ts.from, ts.randomid)); +} + +// TODO: remove try/catch, allow exceptions +ExecutionResult ClientBase::call(Address const& _from, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, FudgeFactor _ff) +{ + ExecutionResult ret; + try + { + + + Block temp = block(_blockNumber); + temp.setEvmEventLog(bc().chainParams().evmEventLog); + + u256 nonce = max(temp.transactionsFrom(_from), m_tq.maxNonce(_from)); + u256 gas = _gas == Invalid256 ? gasLimitRemaining() : _gas; + u256 gasPrice = _gasPrice == Invalid256 ? gasBidPrice() : _gasPrice; + Transaction t(_value, gasPrice, gas, _dest, _data, nonce); + + + t.forceSender(_from); + if (_ff == FudgeFactor::Lenient) + temp.mutableState().addBalance(_from, (u256)(t.gas() * t.gasPrice() + t.value())); + + u256 check = bc().filterCheck(t, FilterCheckScene::CheckCall); + if ( (u256)SystemContractCode::Ok != check ) + { + BOOST_THROW_EXCEPTION(NoCallPermission()); + } + ret = temp.execute(bc().lastHashes(), t, Permanence::Reverted); + + } + catch (...) + { + LOG(ERROR) << boost::current_exception_diagnostic_information() << endl; + throw; + // TODO: Some sort of notification of failure. + } + return ret; +} + +ExecutionResult ClientBase::create(Address const& _from, u256 _value, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, FudgeFactor _ff) +{ + ExecutionResult ret; + try + { + Block temp = block(_blockNumber); + u256 n = temp.transactionsFrom(_from); + + Transaction t(_value, _gasPrice, _gas, _data, n); + t.forceSender(_from); + if (_ff == FudgeFactor::Lenient) + temp.mutableState().addBalance(_from, (u256)(t.gas() * t.gasPrice() + t.value())); + ret = temp.execute(bc().lastHashes(), t, Permanence::Reverted); + } + catch (...) + { + // TODO: Some sort of notification of failure. + } + return ret; +} + +std::pair ClientBase::estimateGas(Address const& _from, u256 _value, Address _dest, bytes const& _data, u256 _maxGas, u256 _gasPrice, BlockNumber _blockNumber, GasEstimationCallback const& _callback) +{ + try + { + u256 upperBound = _maxGas; + if (upperBound == Invalid256 || upperBound > c_maxGasEstimate) + upperBound = c_maxGasEstimate; + u256 lowerBound = (u256)Transaction::gasRequired(!_dest, &_data, EVMSchedule(), 0); + Block bk = block(_blockNumber); + u256 gasPrice = _gasPrice == Invalid256 ? gasBidPrice() : _gasPrice; + ExecutionResult er; + ExecutionResult lastGood; + bool good = false; + while (upperBound != lowerBound) + { + u256 mid = (lowerBound + upperBound) / 2; + u256 n = bk.transactionsFrom(_from); + Transaction t; + if (_dest) + t = Transaction(_value, gasPrice, mid, _dest, _data, n); + else + t = Transaction(_value, gasPrice, mid, _data, n); + t.forceSender(_from); + EnvInfo env(bk.info(), bc().lastHashes(), 0); + env.setGasLimit(mid.convert_to()); + State tempState(bk.state()); + tempState.addBalance(_from, (u256)(t.gas() * t.gasPrice() + t.value())); + er = tempState.execute(env, *bc().sealEngine(), t, Permanence::Reverted).first; + if (er.excepted == TransactionException::OutOfGas || + er.excepted == TransactionException::OutOfGasBase || + er.excepted == TransactionException::OutOfGasIntrinsic || + er.codeDeposit == CodeDeposit::Failed || + er.excepted == TransactionException::BadJumpDestination) + lowerBound = lowerBound == mid ? upperBound : mid; + else + { + lastGood = er; + upperBound = upperBound == mid ? lowerBound : mid; + good = true; + } + + if (_callback) + _callback(GasEstimationProgress { lowerBound, upperBound }); + } + if (_callback) + _callback(GasEstimationProgress { lowerBound, upperBound }); + return make_pair(upperBound, good ? lastGood : er); + } + catch (...) + { + // TODO: Some sort of notification of failure. + return make_pair(u256(), ExecutionResult()); + } +} + +ImportResult ClientBase::injectBlock(bytes const& _block) +{ + return bc().attemptImport(_block, preSeal().db()).first; +} + +u256 ClientBase::balanceAt(Address _a, BlockNumber _block) const +{ + return block(_block).balance(_a); +} + +u256 ClientBase::countAt(Address _a, BlockNumber _block) const +{ + return block(_block).transactionsFrom(_a); +} + +u256 ClientBase::stateAt(Address _a, u256 _l, BlockNumber _block) const +{ + return block(_block).storage(_a, _l); +} + +h256 ClientBase::stateRootAt(Address _a, BlockNumber _block) const +{ + return block(_block).storageRoot(_a); +} + +bytes ClientBase::codeAt(Address _a, BlockNumber _block) const +{ + return block(_block).code(_a); +} + +h256 ClientBase::codeHashAt(Address _a, BlockNumber _block) const +{ + return block(_block).codeHash(_a); +} + +map> ClientBase::storageAt(Address _a, BlockNumber _block) const +{ + return block(_block).storage(_a); +} + + +LocalisedLogEntries ClientBase::logs(unsigned _watchId) const +{ + LogFilter f; + try + { + Guard l(x_filtersWatches); + f = m_filters.at(m_watches.at(_watchId).id).filter; + } + catch (...) + { + return LocalisedLogEntries(); + } + return logs(f); +} + +LocalisedLogEntries ClientBase::logs(LogFilter const& _f) const +{ + LocalisedLogEntries ret; + unsigned begin = min(bc().number() + 1, (unsigned)numberFromHash(_f.latest())); + unsigned end = min(bc().number(), min(begin, (unsigned)numberFromHash(_f.earliest()))); + + // Handle pending transactions differently as they're not on the block chain. + if (begin > bc().number()) + { + Block temp = postSeal(); + for (unsigned i = 0; i < temp.pending().size(); ++i) + { + // Might have a transaction that contains a matching log. + TransactionReceipt const& tr = temp.receipt(i); + LogEntries le = _f.matches(tr); + for (unsigned j = 0; j < le.size(); ++j) + ret.insert(ret.begin(), LocalisedLogEntry(le[j])); + } + begin = bc().number(); + } + + // Handle reverted blocks + // There are not so many, so let's iterate over them + h256s blocks; + h256 ancestor; + unsigned ancestorIndex; + tie(blocks, ancestor, ancestorIndex) = bc().treeRoute(_f.earliest(), _f.latest(), false); + + for (size_t i = 0; i < ancestorIndex; i++) + prependLogsFromBlock(_f, blocks[i], BlockPolarity::Dead, ret); + + // cause end is our earliest block, let's compare it with our ancestor + // if ancestor is smaller let's move our end to it + // example: + // + // 3b -> 2b -> 1b + // -> g + // 3a -> 2a -> 1a + // + // if earliest is at 2a and latest is a 3b, coverting them to numbers + // will give us pair (2, 3) + // and we want to get all logs from 1 (ancestor + 1) to 3 + // so we have to move 2a to g + 1 + end = min(end, (unsigned)numberFromHash(ancestor) + 1); + + // Handle blocks from main chain + set matchingBlocks; + if (!_f.isRangeFilter()) + for (auto const& i : _f.bloomPossibilities()) + for (auto u : bc().withBlockBloom(i, end, begin)) + matchingBlocks.insert(u); + else + // if it is a range filter, we want to get all logs from all blocks in given range + for (unsigned i = end; i <= begin; i++) + matchingBlocks.insert(i); + + for (auto n : matchingBlocks) + prependLogsFromBlock(_f, bc().numberHash(n), BlockPolarity::Live, ret); + + reverse(ret.begin(), ret.end()); + return ret; +} + +void ClientBase::prependLogsFromBlock(LogFilter const& _f, h256 const& _blockHash, BlockPolarity _polarity, LocalisedLogEntries& io_logs) const +{ + auto receipts = bc().receipts(_blockHash).receipts; + for (size_t i = 0; i < receipts.size(); i++) + { + TransactionReceipt receipt = receipts[i]; + auto th = transaction(_blockHash, i).sha3(); + LogEntries le = _f.matches(receipt); + for (unsigned j = 0; j < le.size(); ++j) + io_logs.insert(io_logs.begin(), LocalisedLogEntry(le[j], _blockHash, (BlockNumber)bc().number(_blockHash), th, i, 0, _polarity)); + } +} + +unsigned ClientBase::installWatch(LogFilter const& _f, Reaping _r) +{ + h256 h = _f.sha3(); + { + Guard l(x_filtersWatches); + if (!m_filters.count(h)) + { + LOG(TRACE) << "FFF" << _f << h; + m_filters.insert(make_pair(h, _f)); + } + } + return installWatch(h, _r); +} + +unsigned ClientBase::installWatch(h256 _h, Reaping _r) +{ + unsigned ret; + { + Guard l(x_filtersWatches); + ret = m_watches.size() ? m_watches.rbegin()->first + 1 : 0; + m_watches[ret] = ClientWatch(_h, _r); + LOG(TRACE) << "+++" << ret << _h; + } +#if INITIAL_STATE_AS_CHANGES + auto ch = logs(ret); + if (ch.empty()) + ch.push_back(InitialChange); + { + Guard l(x_filtersWatches); + swap(m_watches[ret].changes, ch); + } +#endif + return ret; +} + +bool ClientBase::uninstallWatch(unsigned _i) +{ + LOG(TRACE) << "XXX" << _i; + + Guard l(x_filtersWatches); + + auto it = m_watches.find(_i); + if (it == m_watches.end()) + return false; + auto id = it->second.id; + m_watches.erase(it); + + auto fit = m_filters.find(id); + if (fit != m_filters.end()) + if (!--fit->second.refCount) + { + LOG(TRACE) << "*X*" << fit->first << ":" << fit->second.filter; + m_filters.erase(fit); + } + return true; +} + +LocalisedLogEntries ClientBase::peekWatch(unsigned _watchId) const +{ + Guard l(x_filtersWatches); + + + auto& w = m_watches.at(_watchId); + + if (w.lastPoll != chrono::system_clock::time_point::max()) + w.lastPoll = chrono::system_clock::now(); + return w.changes; +} + +LocalisedLogEntries ClientBase::checkWatch(unsigned _watchId) +{ + Guard l(x_filtersWatches); + LocalisedLogEntries ret; + + auto& w = m_watches.at(_watchId); + + std::swap(ret, w.changes); + if (w.lastPoll != chrono::system_clock::time_point::max()) + w.lastPoll = chrono::system_clock::now(); + + return ret; +} + +BlockHeader ClientBase::blockInfo(h256 _hash) const +{ + if (_hash == PendingBlockHash) + return preSeal().info(); + return BlockHeader(bc().block(_hash)); +} + +BlockDetails ClientBase::blockDetails(h256 _hash) const +{ + return bc().details(_hash); +} + +Transaction ClientBase::transaction(h256 _transactionHash) const +{ + return Transaction(bc().transaction(_transactionHash), CheckTransaction::Cheap); +} + +LocalisedTransaction ClientBase::localisedTransaction(h256 const& _transactionHash) const +{ + std::pair tl = bc().transactionLocation(_transactionHash); + return localisedTransaction(tl.first, tl.second); +} + +Transaction ClientBase::transaction(h256 _blockHash, unsigned _i) const +{ + auto bl = bc().block(_blockHash); + RLP b(bl); + if (_i < b[1].itemCount()) + return Transaction(b[1][_i].data(), CheckTransaction::Cheap); + else + return Transaction(); +} + +LocalisedTransaction ClientBase::localisedTransaction(h256 const& _blockHash, unsigned _i) const +{ + Transaction t = Transaction(bc().transaction(_blockHash, _i), CheckTransaction::Cheap); + return LocalisedTransaction(t, _blockHash, _i, numberFromHash(_blockHash)); +} + +TransactionReceipt ClientBase::transactionReceipt(h256 const& _transactionHash) const +{ + return bc().transactionReceipt(_transactionHash); +} + +LocalisedTransactionReceipt ClientBase::localisedTransactionReceipt(h256 const& _transactionHash) const +{ + std::pair tl = bc().transactionLocation(_transactionHash); + Transaction t = Transaction(bc().transaction(tl.first, tl.second), CheckTransaction::Cheap); + TransactionReceipt tr = bc().transactionReceipt(tl.first, tl.second); + return LocalisedTransactionReceipt( + tr, + t.sha3(), + tl.first, + numberFromHash(tl.first), + tl.second); +} + +pair ClientBase::transactionLocation(h256 const& _transactionHash) const +{ + return bc().transactionLocation(_transactionHash); +} + +Transactions ClientBase::transactions(h256 _blockHash) const +{ + auto bl = bc().block(_blockHash); + RLP b(bl); + Transactions res; + for (unsigned i = 0; i < b[1].itemCount(); i++) + res.emplace_back(b[1][i].data(), CheckTransaction::Cheap); + return res; +} + +TransactionHashes ClientBase::transactionHashes(h256 _blockHash) const +{ + return bc().transactionHashes(_blockHash); +} + +BlockHeader ClientBase::uncle(h256 _blockHash, unsigned _i) const +{ + auto bl = bc().block(_blockHash); + RLP b(bl); + if (_i < b[2].itemCount()) + return BlockHeader(b[2][_i].data(), HeaderData); + else + return BlockHeader(); +} + +UncleHashes ClientBase::uncleHashes(h256 _blockHash) const +{ + return bc().uncleHashes(_blockHash); +} + +unsigned ClientBase::transactionCount(h256 _blockHash) const +{ + auto bl = bc().block(_blockHash); + RLP b(bl); + return b[1].itemCount(); +} + +unsigned ClientBase::uncleCount(h256 _blockHash) const +{ + auto bl = bc().block(_blockHash); + RLP b(bl); + return b[2].itemCount(); +} + +unsigned ClientBase::number() const +{ + return bc().number(); +} + +Transactions ClientBase::pending() const +{ + return postSeal().pending(); +} + +h256s ClientBase::pendingHashes() const +{ + return h256s() + postSeal().pendingHashes(); +} + +BlockHeader ClientBase::pendingInfo() const +{ + return postSeal().info(); +} + +BlockDetails ClientBase::pendingDetails() const +{ + auto pm = postSeal().info(); + auto li = Interface::blockDetails(LatestBlock); + return BlockDetails((unsigned)pm.number(), li.totalDifficulty + pm.difficulty(), pm.parentHash(), h256s{}); +} + +Addresses ClientBase::addresses(BlockNumber _block) const +{ + Addresses ret; + for (auto const& i : block(_block).addresses()) + ret.push_back(i.first); + return ret; +} + +u256 ClientBase::gasLimitRemaining() const +{ + return postSeal().gasLimitRemaining(); +} + +Address ClientBase::author() const +{ + return preSeal().author(); +} + +h256 ClientBase::hashFromNumber(BlockNumber _number) const +{ + if (_number == PendingBlock) + return h256(); + if (_number == LatestBlock) + return bc().currentHash(); + return bc().numberHash(_number); +} + +BlockNumber ClientBase::numberFromHash(h256 _blockHash) const +{ + if (_blockHash == PendingBlockHash) + return bc().number() + 1; + else if (_blockHash == LatestBlockHash) + return bc().number(); + else if (_blockHash == EarliestBlockHash) + return 0; + return bc().number(_blockHash); +} + +int ClientBase::compareBlockHashes(h256 _h1, h256 _h2) const +{ + BlockNumber n1 = numberFromHash(_h1); + BlockNumber n2 = numberFromHash(_h2); + + if (n1 > n2) + return 1; + else if (n1 == n2) + return 0; + return -1; +} + +bool ClientBase::isKnown(h256 const& _hash) const +{ + return _hash == PendingBlockHash || + _hash == LatestBlockHash || + _hash == EarliestBlockHash || + bc().isKnown(_hash); +} + +bool ClientBase::isKnown(BlockNumber _block) const +{ + return _block == PendingBlock || + _block == LatestBlock || + bc().numberHash(_block) != h256(); +} + +bool ClientBase::isKnownTransaction(h256 const& _transactionHash) const +{ + return bc().isKnownTransaction(_transactionHash); +} + +bool ClientBase::isKnownTransaction(h256 const& _blockHash, unsigned _i) const +{ + return isKnown(_blockHash) && block(_blockHash).pending().size() > _i; +} + +Block ClientBase::block(BlockNumber _h) const +{ + if (_h == PendingBlock) + return postSeal(); + else if (_h == LatestBlock) + return preSeal(); + return block(bc().numberHash(_h)); +} diff --git a/libethereum/ClientBase.h b/libethereum/ClientBase.h new file mode 100644 index 0000000000..fba07e95ec --- /dev/null +++ b/libethereum/ClientBase.h @@ -0,0 +1,194 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . + */ +/** @file ClientBase.h + * @author Gav Wood + * @author Marek Kotewicz + * @date 2015 + */ + +#pragma once +#include +#include +#include "Interface.h" +#include "LogFilter.h" +#include "TransactionQueue.h" +#include "Block.h" +#include "CommonNet.h" + +namespace dev +{ + +namespace eth +{ + +struct InstalledFilter +{ + InstalledFilter(LogFilter const& _f): filter(_f) {} + + LogFilter filter; + unsigned refCount = 1; + LocalisedLogEntries changes; +}; + +static const h256 PendingChangedFilter = u256(0); +static const h256 ChainChangedFilter = u256(1); + +static const LogEntry SpecialLogEntry = LogEntry(Address(), h256s(), bytes()); +static const LocalisedLogEntry InitialChange(SpecialLogEntry); + +struct ClientWatch +{ + ClientWatch(): lastPoll(std::chrono::system_clock::now()) {} + explicit ClientWatch(h256 _id, Reaping _r): id(_id), lastPoll(_r == Reaping::Automatic ? std::chrono::system_clock::now() : std::chrono::system_clock::time_point::max()) {} + + h256 id; +#if INITIAL_STATE_AS_CHANGES + LocalisedLogEntries changes = LocalisedLogEntries{ InitialChange }; +#else + LocalisedLogEntries changes; +#endif + mutable std::chrono::system_clock::time_point lastPoll = std::chrono::system_clock::now(); +}; + + + +class ClientBase: public Interface +{ +public: + ClientBase(TransactionQueue::Limits const& _l = TransactionQueue::Limits{1024, 1024}): m_tq(std::shared_ptr(this),_l) {} + virtual ~ClientBase() {} + + /// Submits the given transaction. + /// @returns the new transaction's hash. + virtual std::pair submitTransaction(TransactionSkeleton const& _t, Secret const& _secret) override; + using Interface::submitTransaction; + + /// Makes the given call. Nothing is recorded into the state. + virtual ExecutionResult call(Address const& _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, FudgeFactor _ff = FudgeFactor::Strict) override; + using Interface::call; + + /// Makes the given create. Nothing is recorded into the state. + virtual ExecutionResult create(Address const& _secret, u256 _value, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, FudgeFactor _ff = FudgeFactor::Strict) override; + + /// Estimate gas usage for call/create. + /// @param _maxGas An upper bound value for estimation, if not provided default value of c_maxGasEstimate will be used. + /// @param _callback Optional callback function for progress reporting + virtual std::pair estimateGas(Address const& _from, u256 _value, Address _dest, bytes const& _data, u256 _maxGas, u256 _gasPrice, BlockNumber _blockNumber, GasEstimationCallback const& _callback) override; + + using Interface::create; + + using Interface::balanceAt; + using Interface::countAt; + using Interface::stateAt; + using Interface::codeAt; + using Interface::codeHashAt; + using Interface::storageAt; + + virtual u256 balanceAt(Address _a, BlockNumber _block) const override; + virtual u256 countAt(Address _a, BlockNumber _block) const override; + virtual u256 stateAt(Address _a, u256 _l, BlockNumber _block) const override; + virtual h256 stateRootAt(Address _a, BlockNumber _block) const override; + virtual bytes codeAt(Address _a, BlockNumber _block) const override; + virtual h256 codeHashAt(Address _a, BlockNumber _block) const override; + virtual std::map> storageAt(Address _a, BlockNumber _block) const override; + + virtual LocalisedLogEntries logs(unsigned _watchId) const override; + virtual LocalisedLogEntries logs(LogFilter const& _filter) const override; + virtual void prependLogsFromBlock(LogFilter const& _filter, h256 const& _blockHash, BlockPolarity _polarity, LocalisedLogEntries& io_logs) const; + + /// Install, uninstall and query watches. + virtual unsigned installWatch(LogFilter const& _filter, Reaping _r = Reaping::Automatic) override; + virtual unsigned installWatch(h256 _filterId, Reaping _r = Reaping::Automatic) override; + virtual bool uninstallWatch(unsigned _watchId) override; + virtual LocalisedLogEntries peekWatch(unsigned _watchId) const override; + virtual LocalisedLogEntries checkWatch(unsigned _watchId) override; + + virtual h256 hashFromNumber(BlockNumber _number) const override; + virtual BlockNumber numberFromHash(h256 _blockHash) const override; + virtual int compareBlockHashes(h256 _h1, h256 _h2) const override; + virtual BlockHeader blockInfo(h256 _hash) const override; + virtual BlockDetails blockDetails(h256 _hash) const override; + virtual Transaction transaction(h256 _transactionHash) const override; + virtual LocalisedTransaction localisedTransaction(h256 const& _transactionHash) const override; + virtual Transaction transaction(h256 _blockHash, unsigned _i) const override; + virtual LocalisedTransaction localisedTransaction(h256 const& _blockHash, unsigned _i) const override; + virtual TransactionReceipt transactionReceipt(h256 const& _transactionHash) const override; + virtual LocalisedTransactionReceipt localisedTransactionReceipt(h256 const& _transactionHash) const override; + virtual std::pair transactionLocation(h256 const& _transactionHash) const override; + virtual Transactions transactions(h256 _blockHash) const override; + virtual TransactionHashes transactionHashes(h256 _blockHash) const override; + virtual BlockHeader uncle(h256 _blockHash, unsigned _i) const override; + virtual UncleHashes uncleHashes(h256 _blockHash) const override; + virtual unsigned transactionCount(h256 _blockHash) const override; + virtual unsigned uncleCount(h256 _blockHash) const override; + virtual unsigned number() const override; + virtual Transactions pending() const override; + virtual h256s pendingHashes() const override; + virtual BlockHeader pendingInfo() const override; + virtual BlockDetails pendingDetails() const override; + + virtual EVMSchedule evmSchedule() const override { return sealEngine()->evmSchedule(EnvInfo(pendingInfo())); } + + virtual ImportResult injectTransaction(bytes const& _rlp, IfDropped _id = IfDropped::Ignore) override { prepareForTransaction(); return m_tq.import(_rlp, _id); } + virtual ImportResult injectBlock(bytes const& _block) override; + + using Interface::addresses; + virtual Addresses addresses(BlockNumber _block) const override; + virtual u256 gasLimitRemaining() const override; + virtual u256 gasBidPrice() const override { return DefaultGasPrice; } + + /// Get the block author + virtual Address author() const override; + + virtual bool isKnown(h256 const& _hash) const override; + virtual bool isKnown(BlockNumber _block) const override; + virtual bool isKnownTransaction(h256 const& _transactionHash) const override; + virtual bool isKnownTransaction(h256 const& _blockHash, unsigned _i) const override; + + virtual void startSealing() override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("ClientBase::startSealing")); } + virtual void stopSealing() override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("ClientBase::stopSealing")); } + virtual bool wouldSeal() const override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("ClientBase::wouldSeal")); } + + virtual SyncStatus syncStatus() const override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("ClientBase::syncStatus")); } + + Block block(BlockNumber _h) const; + + virtual bool isNonceOk(Transaction const&_ts) const override; + virtual bool isBlockLimitOk(Transaction const&_ts) const override; + +protected: + /// The interface that must be implemented in any class deriving this. + /// { + virtual BlockChain& bc() = 0; + virtual BlockChain const& bc() const = 0; + virtual Block block(h256 const& _h) const = 0; + virtual Block preSeal() const = 0; + virtual Block postSeal() const = 0; + virtual void prepareForTransaction() = 0; + /// } + + TransactionQueue m_tq; ///< Maintains a list of incoming transactions not yet in a block on the blockchain. + + // filters + mutable Mutex x_filtersWatches; ///< Our lock. + std::unordered_map m_filters; ///< The dictionary of filters that are active. + std::unordered_map m_specialFilters = std::unordered_map>{{PendingChangedFilter, {}}, {ChainChangedFilter, {}}}; + ///< The dictionary of special filters and their additional data + std::map m_watches; ///< Each and every watch - these reference a filter. +}; + +}} diff --git a/libethereum/ClientTest.cpp b/libethereum/ClientTest.cpp new file mode 100644 index 0000000000..76f94c779f --- /dev/null +++ b/libethereum/ClientTest.cpp @@ -0,0 +1,118 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file ClientTest.cpp + * @author Dimitry Khokhlov + * @date 2016 + */ + +#include +#include + +using namespace std; +using namespace dev; +using namespace dev::eth; +using namespace p2p; + +ClientTest& dev::eth::asClientTest(Interface& _c) +{ + return dynamic_cast(_c); +} + +ClientTest* dev::eth::asClientTest(Interface* _c) +{ + return &dynamic_cast(*_c); +} + +ClientTest::ClientTest( + ChainParams const& _params, + int _networkID, + p2p::Host* _host, + std::shared_ptr _gpForAdoption, + std::string const& _dbPath, + WithExisting _forceAction, + TransactionQueue::Limits const& _limits +): + Client(_params, _networkID, _host, _gpForAdoption, _dbPath, _forceAction, _limits) +{} + +void ClientTest::setChainParams(string const& _genesis) +{ + ChainParams params; + try + { + params = params.loadConfig(_genesis); + if (params.sealEngineName != "NoProof") + BOOST_THROW_EXCEPTION(ChainParamsNotNoProof() << errinfo_comment("Provided configuration is not well formatted.")); + + reopenChain(params, WithExisting::Kill); + setAuthor(params.author); //for some reason author is not being set + } + catch (...) + { + BOOST_THROW_EXCEPTION(ChainParamsInvalid() << errinfo_comment("Provided configuration is not well formatted.")); + } +} + +bool ClientTest::addBlock(string const& _rlp) +{ + if (auto h = m_host.lock()) + h->noteNewBlocks(); + + bytes rlpBytes = fromHex(_rlp, WhenError::Throw); + RLP blockRLP(rlpBytes); + return (m_bq.import(blockRLP.data(), true) == ImportResult::Success); +} + +void ClientTest::modifyTimestamp(u256 const& _timestamp) +{ + Block block(chainParams().accountStartNonce); + DEV_READ_GUARDED(x_preSeal) + block = m_preSeal; + + Transactions transactions; + DEV_READ_GUARDED(x_postSeal) + transactions = m_postSeal.pending(); + block.resetCurrent(_timestamp); + + DEV_WRITE_GUARDED(x_preSeal) + m_preSeal = block; + + auto lastHashes = bc().lastHashes(); + for (auto const& t: transactions) + block.execute(lastHashes, t); + + DEV_WRITE_GUARDED(x_working) + m_working = block; + DEV_READ_GUARDED(x_postSeal) + m_postSeal = block; + + onPostStateChanged(); +} + +void ClientTest::mineBlocks(unsigned _count) +{ + m_blocksToMine = _count; + startSealing(); +} + +void ClientTest::onNewBlocks(h256s const& _blocks, h256Hash& io_changed) +{ + Client::onNewBlocks(_blocks, io_changed); + + if(--m_blocksToMine <= 0) + stopSealing(); +} diff --git a/libethereum/ClientTest.h b/libethereum/ClientTest.h new file mode 100644 index 0000000000..7565ebe921 --- /dev/null +++ b/libethereum/ClientTest.h @@ -0,0 +1,64 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file ClientTest.h + * @author Kholhlov Dimitry + * @date 2016 + */ + +#pragma once + +#include +#include + +namespace dev +{ +namespace eth +{ + +DEV_SIMPLE_EXCEPTION(ChainParamsInvalid); +DEV_SIMPLE_EXCEPTION(ChainParamsNotNoProof); + +class ClientTest: public Client +{ +public: + /// Trivial forwarding constructor. + ClientTest( + ChainParams const& _params, + int _networkID, + p2p::Host* _host, + std::shared_ptr _gpForAdoption, + std::string const& _dbPath = std::string(), + WithExisting _forceAction = WithExisting::Trust, + TransactionQueue::Limits const& _l = TransactionQueue::Limits{1024, 1024} + ); + + void setChainParams(std::string const& _genesis); + void mineBlocks(unsigned _count); + void modifyTimestamp(u256 const& _timestamp); + void rewindToBlock(unsigned _number); + bool addBlock(std::string const& _rlp); + +protected: + unsigned m_blocksToMine; + virtual void onNewBlocks(h256s const& _blocks, h256Hash& io_changed) override; +}; + +ClientTest& asClientTest(Interface& _c); +ClientTest* asClientTest(Interface* _c); + +} +} diff --git a/libethereum/CodeSizeCache.h b/libethereum/CodeSizeCache.h new file mode 100644 index 0000000000..eb5f73c590 --- /dev/null +++ b/libethereum/CodeSizeCache.h @@ -0,0 +1,79 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file CodeSizeCache.h + * @date 2016 + */ + +#pragma once + +#include +#include +#include + +namespace dev +{ +namespace eth +{ + +/** + * @brief Simple thread-safe cache to store a mapping from code hash to code size. + * If the cache is full, a random element is removed. + */ +class CodeSizeCache +{ +public: + void store(h256 const& _hash, size_t size) + { + UniqueGuard g(x_cache); + if (m_cache.size() >= c_maxSize) + removeRandomElement(); + m_cache[_hash] = size; + } + bool contains(h256 const& _hash) const + { + UniqueGuard g(x_cache); + return m_cache.count(_hash); + } + size_t get(h256 const& _hash) const + { + UniqueGuard g(x_cache); + return m_cache.at(_hash); + } + + static CodeSizeCache& instance() { static CodeSizeCache cache; return cache; } + +private: + /// Removes a random element from the cache. + void removeRandomElement() + { + if (!m_cache.empty()) + { + auto it = m_cache.lower_bound(h256::random()); + if (it == m_cache.end()) + it = m_cache.begin(); + m_cache.erase(it); + } + } + + static const size_t c_maxSize = 50000; + mutable Mutex x_cache; + std::map m_cache; +}; + +} +} + diff --git a/libethereum/CommonNet.cpp b/libethereum/CommonNet.cpp new file mode 100644 index 0000000000..404efafaf4 --- /dev/null +++ b/libethereum/CommonNet.cpp @@ -0,0 +1,28 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file CommonNet.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "CommonNet.h" +using namespace std; +using namespace dev; +using namespace dev::eth; + +#pragma GCC diagnostic ignored "-Wunused-variable" +namespace { char dummy; } diff --git a/libethereum/CommonNet.h b/libethereum/CommonNet.h new file mode 100644 index 0000000000..59e83927f4 --- /dev/null +++ b/libethereum/CommonNet.h @@ -0,0 +1,116 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file CommonNet.h + * @author Gav Wood + * @date 2014 + * + * Miscellanea required for the PeerServer/Session classes. + */ + +#pragma once + +#include +#include +#include + + +namespace dev +{ + +class OverlayDB; + +namespace eth +{ + +#if ETH_DEBUG +static const unsigned c_maxHeaders = 2048; ///< Maximum number of hashes BlockHashes will ever send. +static const unsigned c_maxHeadersAsk = 2048; ///< Maximum number of hashes GetBlockHashes will ever ask for. +static const unsigned c_maxBlocks = 128; ///< Maximum number of blocks Blocks will ever send. +static const unsigned c_maxBlocksAsk = 128; ///< Maximum number of blocks we ask to receive in Blocks (when using GetChain). +static const unsigned c_maxPayload = 262144; ///< Maximum size of packet for us to send. +#else +static const unsigned c_maxHeaders = 2048; ///< Maximum number of hashes BlockHashes will ever send. +static const unsigned c_maxHeadersAsk = 2048; ///< Maximum number of hashes GetBlockHashes will ever ask for. +static const unsigned c_maxBlocks = 128; ///< Maximum number of blocks Blocks will ever send. +static const unsigned c_maxBlocksAsk = 128; ///< Maximum number of blocks we ask to receive in Blocks (when using GetChain). +static const unsigned c_maxPayload = 262144; ///< Maximum size of packet for us to send. +#endif +static const unsigned c_maxNodes = c_maxBlocks; ///< Maximum number of nodes will ever send. +static const unsigned c_maxReceipts = c_maxBlocks; ///< Maximum number of receipts will ever send. + +class BlockChain; +class TransactionQueue; +class EthereumHost; +class EthereumPeer; + +enum SubprotocolPacketType : byte +{ + StatusPacket = 0x00, + NewBlockHashesPacket = 0x01, + TransactionsPacket = 0x02, + GetBlockHeadersPacket = 0x03, + BlockHeadersPacket = 0x04, + GetBlockBodiesPacket = 0x05, + BlockBodiesPacket = 0x06, + NewBlockPacket = 0x07, + + GetNodeDataPacket = 0x0d, + NodeDataPacket = 0x0e, + GetReceiptsPacket = 0x0f, + ReceiptsPacket = 0x10, + + //同步配置 + NodeInfoSync = 0x11, //增加节点信息 + DelNodeInfoSync = 0x12, //删除节点信息 + + PacketCount +}; + +enum class Asking +{ + State, + BlockHeaders, + BlockBodies, + NodeData, + Receipts, + Nothing +}; + +enum class SyncState +{ + NotSynced, ///< Initial chain sync has not started yet + Idle, ///< Initial chain sync complete. Waiting for new packets + Waiting, ///< Block downloading paused. Waiting for block queue to process blocks and free space + Blocks, ///< Downloading blocks + State, ///< Downloading state + NewBlocks, ///< Downloading blocks learned from NewHashes packet + + Size /// Must be kept last +}; + +struct SyncStatus +{ + SyncState state = SyncState::Idle; + unsigned protocolVersion = 0; + unsigned startBlockNumber; + unsigned currentBlockNumber; + unsigned highestBlockNumber; + bool majorSyncing = false; +}; + +} +} diff --git a/libethereum/Defaults.cpp b/libethereum/Defaults.cpp new file mode 100644 index 0000000000..1a9278d057 --- /dev/null +++ b/libethereum/Defaults.cpp @@ -0,0 +1,34 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Defaults.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "Defaults.h" + +#include +using namespace std; +using namespace dev; +using namespace dev::eth; + +Defaults* Defaults::s_this = nullptr; + +Defaults::Defaults() +{ + m_dbPath = getDataDir(); +} diff --git a/libethereum/Defaults.h b/libethereum/Defaults.h new file mode 100644 index 0000000000..bece26c962 --- /dev/null +++ b/libethereum/Defaults.h @@ -0,0 +1,50 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Defaults.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include + +namespace dev +{ +namespace eth +{ + +struct Defaults +{ + friend class BlockChain; + friend class State; + +public: + Defaults(); + + static Defaults* get() { if (!s_this) s_this = new Defaults; return s_this; } + static void setDBPath(std::string const& _dbPath) { get()->m_dbPath = _dbPath; } + static std::string const& dbPath() { return get()->m_dbPath; } + +private: + std::string m_dbPath; + + static Defaults* s_this; +}; + +} +} diff --git a/libethereum/EthereumHost.cpp b/libethereum/EthereumHost.cpp new file mode 100644 index 0000000000..aa7b4aca28 --- /dev/null +++ b/libethereum/EthereumHost.cpp @@ -0,0 +1,737 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file EthereumHost.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "EthereumHost.h" + +#include +#include +#include +#include +#include +#include +#include "BlockChain.h" +#include "TransactionQueue.h" +#include "BlockQueue.h" +#include "EthereumPeer.h" +#include "BlockChainSync.h" +#include "NodeConnParamsManagerApi.h" +#include + +using namespace std; +using namespace dev; +using namespace dev::eth; +using namespace p2p; + +unsigned const EthereumHost::c_oldProtocolVersion = 62; +static unsigned const c_maxSendTransactions = 256; + +char const* const EthereumHost::s_stateNames[static_cast(SyncState::Size)] = {"NotSynced", "Idle", "Waiting", "Blocks", "State", "NewBlocks" }; + + + +namespace +{ +class EthereumPeerObserver: public EthereumPeerObserverFace +{ +public: + EthereumPeerObserver(BlockChainSync& _sync, RecursiveMutex& _syncMutex, TransactionQueue& _tq): m_sync(_sync), m_syncMutex(_syncMutex), m_tq(_tq) {} + + void onPeerStatus(std::shared_ptr _peer) override + { + RecursiveGuard l(m_syncMutex); + try + { + m_sync.onPeerStatus(_peer); + } + catch (FailedInvariant const&) + { + // "fix" for https://github.com/ethereum/webthree-umbrella/issues/300 + LOG(WARNING) << "Failed invariant during sync, restarting sync"; + m_sync.restartSync(); + } + } + + void onPeerTransactions(std::shared_ptr _peer, RLP const& _r) override + { + unsigned itemCount = _r.itemCount(); + LOG(TRACE) << "Transactions (" << dec << itemCount << "entries)"; + m_tq.enqueue(_r, _peer->id()); + } + + void onPeerAborting() override + { + RecursiveGuard l(m_syncMutex); + try + { + m_sync.onPeerAborting(); + } + catch (Exception&) + { + LOG(WARNING) << "Exception on peer destruciton: " << boost::current_exception_diagnostic_information(); + } + } + + void onPeerBlockHeaders(std::shared_ptr _peer, RLP const& _headers) override + { + RecursiveGuard l(m_syncMutex); + try + { + m_sync.onPeerBlockHeaders(_peer, _headers); + } + catch (FailedInvariant const&) + { + // "fix" for https://github.com/ethereum/webthree-umbrella/issues/300 + LOG(WARNING) << "Failed invariant during sync, restarting sync"; + m_sync.restartSync(); + } + } + + void onPeerBlockBodies(std::shared_ptr _peer, RLP const& _r) override + { + RecursiveGuard l(m_syncMutex); + try + { + m_sync.onPeerBlockBodies(_peer, _r); + } + catch (FailedInvariant const&) + { + // "fix" for https://github.com/ethereum/webthree-umbrella/issues/300 + LOG(WARNING) << "Failed invariant during sync, restarting sync"; + m_sync.restartSync(); + } + } + + void onPeerNewHashes(std::shared_ptr _peer, RLP const& _r) override + { + RecursiveGuard l(m_syncMutex); + try + { + m_sync.onPeerNewHashes(_peer, _r); + } + catch (FailedInvariant const&) + { + // "fix" for https://github.com/ethereum/webthree-umbrella/issues/300 + LOG(WARNING) << "Failed invariant during sync, restarting sync"; + m_sync.restartSync(); + } + } + + void onPeerNewBlock(std::shared_ptr _peer, RLP const& _r) override + { + RecursiveGuard l(m_syncMutex); + try + { + m_sync.onPeerNewBlock(_peer, _r); + } + catch (FailedInvariant const&) + { + // "fix" for https://github.com/ethereum/webthree-umbrella/issues/300 + LOG(WARNING) << "Failed invariant during sync, restarting sync"; + m_sync.restartSync(); + } + } + + void onPeerNodeData(std::shared_ptr /* _peer */, RLP const& _r) override + { + unsigned itemCount = _r.itemCount(); + LOG(TRACE) << "Node Data (" << dec << itemCount << "entries)"; + } + + void onPeerReceipts(std::shared_ptr /* _peer */, RLP const& _r) override + { + unsigned itemCount = _r.itemCount(); + LOG(TRACE) << "Receipts (" << dec << itemCount << "entries)"; + } + +private: + BlockChainSync& m_sync; + RecursiveMutex& m_syncMutex; + TransactionQueue& m_tq; +}; + +class EthereumHostData: public EthereumHostDataFace +{ +public: + EthereumHostData(BlockChain const& _chain, OverlayDB const& _db): m_chain(_chain), m_db(_db) {} + + pair blockHeaders(RLP const& _blockId, unsigned _maxHeaders, u256 _skip, bool _reverse) const override + { + auto numHeadersToSend = _maxHeaders; + + auto step = static_cast(_skip) + 1; + assert(step > 0 && "step must not be 0"); + + h256 blockHash; + if (_blockId.size() == 32) // block id is a hash + { + blockHash = _blockId.toHash(); + //blockNumber = host()->chain().number(blockHash); + LOG(TRACE) << "GetBlockHeaders (block (hash): " << blockHash + << ", maxHeaders: " << _maxHeaders + << ", skip: " << _skip << ", reverse: " << _reverse << ")"; + + if (!_reverse) + { + auto n = m_chain.number(blockHash); + if (numHeadersToSend == 0) + blockHash = {}; + else if (n != 0 || blockHash == m_chain.genesisHash()) + { + auto top = n + uint64_t(step) * numHeadersToSend - 1; + auto lastBlock = m_chain.number(); + if (top > lastBlock) + { + numHeadersToSend = (lastBlock - n) / step + 1; + top = n + step * (numHeadersToSend - 1); + } + assert(top <= lastBlock && "invalid top block calculated"); + blockHash = m_chain.numberHash(static_cast(top)); // override start block hash with the hash of the top block we have + } + else + blockHash = {}; + } + else if (!m_chain.isKnown(blockHash)) + blockHash = {}; + } + else // block id is a number + { + auto n = _blockId.toInt(); + LOG(TRACE) << "GetBlockHeaders (" << n + << "max: " << _maxHeaders + << "skip: " << _skip << (_reverse ? "reverse" : "") << ")"; + + if (!_reverse) + { + auto lastBlock = m_chain.number(); + if (n > lastBlock || numHeadersToSend == 0) + blockHash = {}; + else + { + bigint top = n + uint64_t(step) * (numHeadersToSend - 1); + if (top > lastBlock) + { + numHeadersToSend = (lastBlock - static_cast(n)) / step + 1; + top = n + step * (numHeadersToSend - 1); + } + assert(top <= lastBlock && "invalid top block calculated"); + blockHash = m_chain.numberHash(static_cast(top)); // override start block hash with the hash of the top block we have + } + } + else if (n <= std::numeric_limits::max()) + blockHash = m_chain.numberHash(static_cast(n)); + else + blockHash = {}; + } + + auto nextHash = [this](h256 _h, unsigned _step) + { + static const unsigned c_blockNumberUsageLimit = 1000; + + const auto lastBlock = m_chain.number(); + const auto limitBlock = lastBlock > c_blockNumberUsageLimit ? lastBlock - c_blockNumberUsageLimit : 0; // find the number of the block below which we don't expect BC changes. + + while (_step) // parent hash traversal + { + auto details = m_chain.details(_h); + if (details.number < limitBlock) + break; // stop using parent hash traversal, fallback to using block numbers + _h = details.parent; + --_step; + } + + if (_step) // still need lower block + { + auto n = m_chain.number(_h); + if (n >= _step) + _h = m_chain.numberHash(n - _step); + else + _h = {}; + } + + + return _h; + }; + + bytes rlp; + unsigned itemCount = 0; + vector hashes; + for (unsigned i = 0; i != numHeadersToSend; ++i) + { + if (!blockHash || !m_chain.isKnown(blockHash)) + break; + + hashes.push_back(blockHash); + ++itemCount; + + blockHash = nextHash(blockHash, step); + } + + for (unsigned i = 0; i < hashes.size() && rlp.size() < c_maxPayload; ++i) + rlp += m_chain.headerData(hashes[_reverse ? i : hashes.size() - 1 - i]); + + return make_pair(rlp, itemCount); + } + + pair blockBodies(RLP const& _blockHashes) const override + { + unsigned const count = static_cast(_blockHashes.itemCount()); + + bytes rlp; + unsigned n = 0; + auto numBodiesToSend = std::min(count, c_maxBlocks); + for (unsigned i = 0; i < numBodiesToSend && rlp.size() < c_maxPayload; ++i) + { + auto h = _blockHashes[i].toHash(); + if (m_chain.isKnown(h)) + { + bytes blockBytes = m_chain.block(h); + RLP block{blockBytes}; + RLPStream body; + body.appendList(4); + body.appendRaw(block[1].data()); // transactions + body.appendRaw(block[2].data()); // uncles + body.appendRaw(block[3].data()); // block hash + body.appendRaw(block[4].data()); // sign_list + auto bodyBytes = body.out(); + rlp.insert(rlp.end(), bodyBytes.begin(), bodyBytes.end()); + ++n; + } + } + if (count > 20 && n == 0) + LOG(WARNING) << "all" << count << "unknown blocks requested; peer on different chain?"; + else + LOG(TRACE) << n << "blocks known and returned;" << (numBodiesToSend - n) << "blocks unknown;" << (count > c_maxBlocks ? count - c_maxBlocks : 0) << "blocks ignored"; + + return make_pair(rlp, n); + } + + strings nodeData(RLP const& _dataHashes) const override + { + unsigned const count = static_cast(_dataHashes.itemCount()); + + strings data; + size_t payloadSize = 0; + auto numItemsToSend = std::min(count, c_maxNodes); + for (unsigned i = 0; i < numItemsToSend && payloadSize < c_maxPayload; ++i) + { + auto h = _dataHashes[i].toHash(); + auto node = m_db.lookup(h); + if (!node.empty()) + { + payloadSize += node.length(); + data.push_back(move(node)); + } + } + LOG(TRACE) << data.size() << " nodes known and returned;" << (numItemsToSend - data.size()) << " unknown;" << (count > c_maxNodes ? count - c_maxNodes : 0) << " ignored"; + + return data; + } + + pair receipts(RLP const& _blockHashes) const override + { + unsigned const count = static_cast(_blockHashes.itemCount()); + + bytes rlp; + unsigned n = 0; + auto numItemsToSend = std::min(count, c_maxReceipts); + for (unsigned i = 0; i < numItemsToSend && rlp.size() < c_maxPayload; ++i) + { + auto h = _blockHashes[i].toHash(); + if (m_chain.isKnown(h)) + { + auto const receipts = m_chain.receipts(h); + auto receiptsRlpList = receipts.rlp(); + rlp.insert(rlp.end(), receiptsRlpList.begin(), receiptsRlpList.end()); + ++n; + } + } + LOG(TRACE) << n << " receipt lists known and returned;" << (numItemsToSend - n) << " unknown;" << (count > c_maxReceipts ? count - c_maxReceipts : 0) << " ignored"; + + return make_pair(rlp, n); + } + +private: + BlockChain const& m_chain; + OverlayDB const& m_db; +}; + +} + +EthereumHost::EthereumHost(BlockChain const& _ch, OverlayDB const& _db, TransactionQueue& _tq, BlockQueue& _bq, u256 _networkId): + HostCapability(), + Worker ("ethsync"), + m_chain (_ch), + m_db(_db), + m_tq (_tq), + m_bq (_bq), + m_networkId (_networkId), + m_hostData(make_shared(m_chain, m_db)) +{ + // TODO: Composition would be better. Left like that to avoid initialization + // issues as BlockChainSync accesses other EthereumHost members. + m_sync.reset(new BlockChainSync(*this)); + m_peerObserver = make_shared(*m_sync, x_sync, m_tq); + NodeConnManagerSingleton::GetInstance().setEthereumHost(this); + m_latestBlockSent = _ch.currentHash(); + m_tq.onImport([this](ImportResult _ir, h256 const & _h, h512 const & _nodeId) { onTransactionImported(_ir, _h, _nodeId); }); +} + +EthereumHost::~EthereumHost() +{ +} + +bool EthereumHost::ensureInitialised() +{ + if (!m_latestBlockSent) + { + // First time - just initialise. + m_latestBlockSent = m_chain.currentHash(); + LOG(TRACE) << "Initialising: latest=" << m_latestBlockSent; + + Guard l(x_transactions); + m_transactionsSent = m_tq.knownTransactions(); + return true; + } + return false; +} + +void EthereumHost::reset() +{ + RecursiveGuard l(x_sync); + m_sync->abortSync(); + + m_latestBlockSent = h256(); + Guard tl(x_transactions); + m_transactionsSent.clear(); +} + +void EthereumHost::doWork() +{ + bool netChange = ensureInitialised(); + auto h = m_chain.currentHash(); + // If we've finished our initial sync (including getting all the blocks into the chain so as to reduce invalid transactions), start trading transactions & blocks + if (!isSyncing() && m_chain.isKnown(m_latestBlockSent)) + { + if (m_newTransactions) + { + m_newTransactions = false; + maintainTransactions();//广播交易 + } + if (m_newBlocks) + { + m_newBlocks = false; + maintainBlocks(h);//广播块 + } + } + + time_t now = std::chrono::system_clock::to_time_t(chrono::system_clock::now()); + if (now - m_lastTick >= 1) + { + m_lastTick = now; + foreachPeer([](std::shared_ptr _p) { _p->tick(); return true; }); + } + +// return netChange; + // TODO: Figure out what to do with netChange. + (void)netChange; +} + + +void EthereumHost::maintainTransactions() +{ + // Send any new transactions. + unordered_map, std::vector> peerTransactions; + + + + auto ts = m_tq.allTransactions(); + { + Guard l(x_transactions); + unsigned count = 0; + for (size_t i = 0; count < c_maxSendTransactions && i < ts.size(); ++i) { + auto const& t = ts[i]; + bool unsent = !m_transactionsSent.count(t.sha3()); + auto peers = get<1>(randomSelection(0, [&](EthereumPeer * p) { + DEV_GUARDED(p->x_knownTransactions) + return p->m_requireTransactions || (unsent && !p->m_knownTransactions.count(t.sha3())); + return false; + })); + for (auto const& p : peers) { + peerTransactions[p].push_back(i); + } + if (peers.size() > 0) { + count++; + } + if (unsent) { + m_transactionsSent.insert(t.sha3()); + } + } + } + + foreachPeer([&](shared_ptr _p) + { + bytes b; + unsigned n = 0; + + DEV_GUARDED(_p->x_knownTransactions) + for (auto const& i : peerTransactions[_p]) + { + if (_p->m_knownTransactions.size() > c_maxSendTransactions) { + _p->m_knownTransactions.pop(); + } + _p->m_knownTransactions.insert(ts[i].sha3()); + b += ts[i].rlp(); + ++n; + } + + + + if (n || _p->m_requireTransactions) + { + RLPStream ts; + _p->prep(ts, TransactionsPacket, n).appendRaw(b, n); + _p->sealAndSend(ts); + LOG(TRACE) << "Sent" << n << "transactions to " << _p->session()->info().clientVersion; + } + _p->m_requireTransactions = false; + return true; + }); +} + +void EthereumHost::foreachPeer(std::function)> const & _f) const +{ + //order peers by protocol, rating, connection age + + auto sessions = peerSessions(); + + + auto sessionLess = [](std::pair, std::shared_ptr> const & _left, std::pair, std::shared_ptr> const & _right) + { return _left.first->rating() == _right.first->rating() ? _left.first->connectionTime() < _right.first->connectionTime() : _left.first->rating() > _right.first->rating(); }; + + std::sort(sessions.begin(), sessions.end(), sessionLess); + for (auto s : sessions) + if (!_f(capabilityFromSession(*s.first))) + return; + + sessions = peerSessions(c_oldProtocolVersion); //TODO: remove once v61+ is common + std::sort(sessions.begin(), sessions.end(), sessionLess); + for (auto s : sessions) + if (!_f(capabilityFromSession(*s.first, c_oldProtocolVersion))) + return; +} + +tuple>, vector>, vector>> EthereumHost::randomSelection(unsigned _percent, std::function const & _allow) +{ + vector> chosen; + vector> allowed; + vector> sessions; + + size_t peerCount = 0; + foreachPeer([&](std::shared_ptr _p) + { + if (_allow(_p.get())) + { + allowed.push_back(_p); + sessions.push_back(_p->session()); + } + ++peerCount; + return true; + }); + + size_t chosenSize = (peerCount * _percent + 99) / 100; + chosen.reserve(chosenSize); + for (unsigned i = chosenSize; i && allowed.size(); i--) + { + unsigned n = rand() % allowed.size(); + chosen.push_back(std::move(allowed[n])); + allowed.erase(allowed.begin() + n); + } + return make_tuple(move(chosen), move(allowed), move(sessions)); +} + +void EthereumHost::maintainBlocks(h256 const & _currentHash) +{ + // Send any new blocks. + auto detailsFrom = m_chain.details(m_latestBlockSent); + auto detailsTo = m_chain.details(_currentHash); + if (detailsFrom.totalDifficulty < detailsTo.totalDifficulty) + { + if (diff(detailsFrom.number, detailsTo.number) < 20) + { + // don't be sending more than 20 "new" blocks. if there are any more we were probably waaaay behind. + LOG(TRACE) << "Sending a new block (current is" << _currentHash << ", was" << m_latestBlockSent << ")"; + + h256s blocks = get<0>(m_chain.treeRoute(m_latestBlockSent, _currentHash, false, false, true)); + //先发送NewBlockHash + auto s = randomSelection(25, [&](EthereumPeer * p) { + DEV_GUARDED(p->x_knownBlocks) + return !p->m_knownBlocks.count(_currentHash); + return false; + }); + for (shared_ptr const& p : get<1>(s)) + { + RLPStream ts; + p->prep(ts, NewBlockHashesPacket, blocks.size()); + for (auto const& b : blocks) + { + ts.appendList(2); + ts.append(b); + ts.append(m_chain.number(b)); + } + + + p->sealAndSend(ts); + + } + + std::this_thread::sleep_for(chrono::milliseconds(100)); + + auto s2 = randomSelection(25, [&](EthereumPeer * p) { + DEV_GUARDED(p->x_knownBlocks) + return !p->m_knownBlocks.count(_currentHash); + return false; + }); + for (shared_ptr const& p : get<0>(s2)) + for (auto const& b : blocks) + { + RLPStream ts; + p->prep(ts, NewBlockPacket, 2).appendRaw(m_chain.block(b), 1).append(m_chain.details(b).totalDifficulty); + + + p->sealAndSend(ts); + + DEV_GUARDED(p->x_knownBlocks) + { + if (p->m_knownBlocks.size() > EthereumPeer::kKnownBlockSize) { + p->m_knownBlocks.pop(); + } + p->m_knownBlocks.insert(b); + } + } + } + m_latestBlockSent = _currentHash; + } +} + +bool EthereumHost::isSyncing() const +{ + return m_sync->isSyncing(); +} + +SyncStatus EthereumHost::status() const +{ + RecursiveGuard l(x_sync); + return m_sync->status(); +} + +void EthereumHost::onTransactionImported(ImportResult _ir, h256 const & _h, h512 const & _nodeId) +{ + auto session = host()->peerSession(_nodeId); + if (!session) + return; + + std::shared_ptr peer = capabilityFromSession(*session); + if (!peer) + peer = capabilityFromSession(*session, c_oldProtocolVersion); + if (!peer) + return; + + Guard l(peer->x_knownTransactions); + peer->m_knownTransactions.insert(_h); + switch (_ir) + { + case ImportResult::Malformed: + peer->addRating(-100); + break; + case ImportResult::AlreadyKnown: + // if we already had the transaction, then don't bother sending it on. + DEV_GUARDED(x_transactions) + m_transactionsSent.insert(_h); + peer->addRating(0); + break; + case ImportResult::Success: + peer->addRating(100); + break; + default:; + } +} + +shared_ptr EthereumHost::newPeerCapability(shared_ptr const & _s, unsigned _idOffset, p2p::CapDesc const & _cap, uint16_t _capID) +{ + auto ret = HostCapability::newPeerCapability(_s, _idOffset, _cap, _capID); + + auto cap = capabilityFromSession(*_s, _cap.second); + assert(cap); + LOG(TRACE) << "EthereumHost::newPeerCapability totalDifficulty=" << m_chain.details().totalDifficulty << ",number=" << m_chain.info().number(); + + cap->init( + protocolVersion(), + m_networkId, + m_chain.details().totalDifficulty, + m_chain.currentHash(), + m_chain.genesisHash(), + m_chain.info().number(), + m_hostData, + m_peerObserver + ); + + return ret; +} + +void EthereumHost::addNodeConnParam(std::vector const & vParams) +{ + foreachPeer([&](std::shared_ptr _p) + { + RLPStream ts; + _p->prep(ts, NodeInfoSync, vParams.size()); + for (auto const& param : vParams) + { + ts.appendList(6); + ts.append(param._sNodeId); + ts.append(param._sAgencyInfo); + ts.append(param._sAgencyDesc); + ts.append(param._iIdentityType); + ts.append(param._sIP); + ts.append(param._iPort); + } + LOG(TRACE) << "EthereumHost::addNodeConnParam sealandsend " << vParams.size() << std::endl; + _p->sealAndSend(ts); + return true; + }); +} + + +void EthereumHost::delNodeConnParam(std::string const & sParams) +{ + if (sParams == "") + { + return; + } + + foreachPeer([&](std::shared_ptr _p) + { + RLPStream ts; + _p->prep(ts, DelNodeInfoSync, 1) << sParams; + LOG(TRACE) << "EthereumHost::delNodeConnParam sealandsend " << sParams << std::endl; + _p->sealAndSend(ts); + return true; + }); +} diff --git a/libethereum/EthereumHost.h b/libethereum/EthereumHost.h new file mode 100644 index 0000000000..4b28c6f2c1 --- /dev/null +++ b/libethereum/EthereumHost.h @@ -0,0 +1,157 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file EthereumHost.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include "BlockChainSync.h" +#include "CommonNet.h" +#include "EthereumPeer.h" + +namespace dev +{ + +class RLPStream; + +namespace eth +{ + +class TransactionQueue; +class BlockQueue; +class BlockChainSync; +class NodeConnParams; + + +/** + * @brief The EthereumHost class + * @warning None of this is thread-safe. You have been warned. + * @doWork Syncs to peers and sends new blocks and transactions. + */ +class EthereumHost: public p2p::HostCapability, Worker +{ +public: + /// Start server, but don't listen. + EthereumHost(BlockChain const& _ch, OverlayDB const& _db, TransactionQueue& _tq, BlockQueue& _bq, u256 _networkId); + + /// Will block on network process events. + virtual ~EthereumHost(); + + unsigned protocolVersion() const { return c_protocolVersion; } + u256 networkId() const { return m_networkId; } + void setNetworkId(u256 _n) { m_networkId = _n; } + + void reset(); + + bool isSyncing() const; + bool isBanned(p2p::NodeID const& _id) const { return !!m_banned.count(_id); } + + void noteNewTransactions() { m_newTransactions = true; } + void noteNewBlocks() { m_newBlocks = true; } + void onForceSync() { m_sync->onForceSync(); } + void onBlockImported(BlockHeader const& _info) { m_sync->onBlockImported(_info); } + + BlockChain const& chain() const { return m_chain; } + OverlayDB const& db() const { return m_db; } + BlockQueue& bq() { return m_bq; } + BlockQueue const& bq() const { return m_bq; } + SyncStatus status() const; + h256 latestBlockSent() { return m_latestBlockSent; } + static char const* stateName(SyncState _s) { return s_stateNames[static_cast(_s)]; } + + static unsigned const c_oldProtocolVersion; + void foreachPeer(std::function)> const& _f) const; + + /** + * 给所有已连接节点发送新增的节点配置 + * in : vParams - 需要新加的节点配置信息 + */ + void addNodeConnParam(std::vector const &vParams); + + + /** + * 给所有已连接节点发送删除节点配置 + * in : sParams - 删除节点的NodeId + */ + void delNodeConnParam(std::string const &sParams); + +protected: + std::shared_ptr newPeerCapability(std::shared_ptr const& _s, unsigned _idOffset, p2p::CapDesc const& _cap, uint16_t _capID) override; + +private: + static char const* const s_stateNames[static_cast(SyncState::Size)]; + + std::tuple>, std::vector>, std::vector>> randomSelection(unsigned _percent = 25, std::function const& _allow = [](EthereumPeer const*) { return true; }); + + /// Sync with the BlockChain. It might contain one of our mined blocks, we might have new candidates from the network. + virtual void doWork() override; + + void maintainTransactions(); + void maintainBlocks(h256 const& _currentBlock); + void onTransactionImported(ImportResult _ir, h256 const& _h, h512 const& _nodeId); + + /// Check to see if the network peer-state initialisation has happened. + bool isInitialised() const { return (bool)m_latestBlockSent; } + + /// Initialises the network peer-state, doing the stuff that needs to be once-only. @returns true if it really was first. + bool ensureInitialised(); + + virtual void onStarting() override { startWorking(); } + virtual void onStopping() override { stopWorking(); } + + BlockChain const& m_chain; + OverlayDB const& m_db; ///< References to DB, needed for some of the Ethereum Protocol responses. + TransactionQueue& m_tq; ///< Maintains a list of incoming transactions not yet in a block on the blockchain. + BlockQueue& m_bq; ///< Maintains a list of incoming blocks not yet on the blockchain (to be imported). + + u256 m_networkId; + + h256 m_latestBlockSent; + h256Hash m_transactionsSent; + + std::unordered_set m_banned; + + bool m_newTransactions = false; + bool m_newBlocks = false; + + mutable RecursiveMutex x_sync; + mutable Mutex x_transactions; + std::unique_ptr m_sync; + std::atomic m_lastTick = { 0 }; + + std::shared_ptr m_hostData; + std::shared_ptr m_peerObserver; +}; + +} +} diff --git a/libethereum/EthereumPeer.cpp b/libethereum/EthereumPeer.cpp new file mode 100644 index 0000000000..fda702eb95 --- /dev/null +++ b/libethereum/EthereumPeer.cpp @@ -0,0 +1,475 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file EthereumPeer.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "EthereumPeer.h" + +#include +#include +#include +#include +#include +#include "EthereumHost.h" +#include "NodeConnParamsManagerApi.h" +#include + +using namespace std; +using namespace dev; +using namespace dev::eth; +using namespace p2p; + +static const unsigned c_maxIncomingNewHashes = 1024; +static const unsigned c_maxHeadersToSend = 1024; + +string EthereumPeer::toString(Asking _a) +{ + switch (_a) + { + case Asking::BlockHeaders: return "BlockHeaders"; + case Asking::BlockBodies: return "BlockBodies"; + case Asking::NodeData: return "NodeData"; + case Asking::Receipts: return "Receipts"; + case Asking::Nothing: return "Nothing"; + case Asking::State: return "State"; + } + return "?"; +} + +EthereumPeer::EthereumPeer(std::shared_ptr _s, HostCapabilityFace* _h, unsigned _i, CapDesc const& _cap, uint16_t _capID): + Capability(_s, _h, _i, _capID), + m_peerCapabilityVersion(_cap.second) +{ + session()->addNote("manners", isRude() ? "RUDE" : "nice"); +} + +EthereumPeer::~EthereumPeer() +{ + if (m_asking != Asking::Nothing) + { + LOG(TRACE) << "Peer aborting while being asked for " << toString(m_asking); + setRude(); + } + clog(NetWarn) << "EthereumPeer::~EthereumPeer"; + abortSync(); +} + +void EthereumPeer::init(unsigned _hostProtocolVersion, u256 _hostNetworkId, u256 _chainTotalDifficulty, h256 _chainCurrentHash, h256 _chainGenesisHash, u256 _height, shared_ptr _hostData, shared_ptr _observer) +{ + m_hostData = _hostData; + m_observer = _observer; + m_hostProtocolVersion = _hostProtocolVersion; + requestStatus(_hostNetworkId, _chainTotalDifficulty, _chainCurrentHash, _chainGenesisHash, _height); +} + +bool EthereumPeer::isRude() const +{ + auto s = session(); + if (s) + return s->repMan().isRude(*s, name()); + return false; +} + +unsigned EthereumPeer::askOverride() const +{ + std::string static const badGeth = "Geth/v0.9.27"; + auto s = session(); + if (!s) + return c_maxBlocksAsk; + if (s->info().clientVersion.substr(0, badGeth.size()) == badGeth) + return 1; + bytes const& d = s->repMan().data(*s, name()); + return d.empty() ? c_maxBlocksAsk : RLP(d).toInt(RLP::LaissezFaire); +} + +void EthereumPeer::setRude() +{ + auto s = session(); + if (!s) + return; + auto old = askOverride(); + s->repMan().setData(*s, name(), rlp(askOverride() / 2 + 1)); + cnote << "Rude behaviour; askOverride now" << askOverride() << ", was" << old; + s->repMan().noteRude(*s, name()); + session()->addNote("manners", "RUDE"); +} + +void EthereumPeer::abortSync() +{ + if (m_observer) + m_observer->onPeerAborting(); +} + + +/* + * Possible asking/syncing states for two peers: + */ + +void EthereumPeer::setIdle() +{ + setAsking(Asking::Nothing); +} + +void EthereumPeer::requestStatus(u256 _hostNetworkId, u256 _chainTotalDifficulty, h256 _chainCurrentHash, h256 _chainGenesisHash, u256 _height) +{ + assert(m_asking == Asking::Nothing); + setAsking(Asking::State); + m_requireTransactions = true; + RLPStream s; + bool latest = m_peerCapabilityVersion == m_hostProtocolVersion; + prep(s, StatusPacket, 6) + << (latest ? m_hostProtocolVersion : EthereumHost::c_oldProtocolVersion) + << _hostNetworkId + << _chainTotalDifficulty + << _chainCurrentHash + << _chainGenesisHash + << _height; + sealAndSend(s); +} + +void EthereumPeer::requestBlockHeaders(unsigned _startNumber, unsigned _count, unsigned _skip, bool _reverse) +{ + if (m_asking != Asking::Nothing) + { + clog(NetWarn) << "Asking headers while requesting " << toString(m_asking); + } + setAsking(Asking::BlockHeaders); + RLPStream s; + prep(s, GetBlockHeadersPacket, 4) << _startNumber << _count << _skip << (_reverse ? 1 : 0); + clog(NetMessageDetail) << "Requesting " << _count << " block headers starting from " << _startNumber << (_reverse ? " in reverse" : ""); + m_lastAskedHeaders = _count; + sealAndSend(s); +} + +void EthereumPeer::requestBlockHeaders(h256 const& _startHash, unsigned _count, unsigned _skip, bool _reverse) +{ + if (m_asking != Asking::Nothing) + { + clog(NetWarn) << "Asking headers while requesting " << toString(m_asking); + } + setAsking(Asking::BlockHeaders); + RLPStream s; + prep(s, GetBlockHeadersPacket, 4) << _startHash << _count << _skip << (_reverse ? 1 : 0); + clog(NetMessageDetail) << "EthereumPeer::requestBlockHeaders " << " Requesting " << _count << " block headers starting from " << _startHash << (_reverse ? " in reverse" : ""); + m_lastAskedHeaders = _count; + sealAndSend(s); +} + + +void EthereumPeer::requestBlockBodies(h256s const& _blocks) +{ + requestByHashes(_blocks, Asking::BlockBodies, GetBlockBodiesPacket); +} + +void EthereumPeer::requestNodeData(h256s const& _hashes) +{ + requestByHashes(_hashes, Asking::NodeData, GetNodeDataPacket); +} + +void EthereumPeer::requestReceipts(h256s const& _blocks) +{ + requestByHashes(_blocks, Asking::Receipts, GetReceiptsPacket); +} + +void EthereumPeer::requestByHashes(h256s const& _hashes, Asking _asking, SubprotocolPacketType _packetType) +{ + if (m_asking != Asking::Nothing) + { + clog(NetWarn) << "Asking " << toString(_asking) << " while requesting " << toString(m_asking); + } + setAsking(_asking); + if (_hashes.size()) + { + RLPStream s; + prep(s, _packetType, _hashes.size()); + for (auto const& i : _hashes) + s << i; + sealAndSend(s); + } + else + setIdle(); +} + +void EthereumPeer::setAsking(Asking _a) +{ + m_asking = _a; + m_lastAsk = std::chrono::system_clock::to_time_t(chrono::system_clock::now()); + + auto s = session(); + if (s) + { + s->addNote("ask", toString(_a)); + s->addNote("sync", string(isCriticalSyncing() ? "ONGOING" : "holding") + (needsSyncing() ? " & needed" : "")); + } +} + +void EthereumPeer::tick() +{ + auto s = session(); + time_t now = std::chrono::system_clock::to_time_t(chrono::system_clock::now()); + if (s && (now - m_lastAsk > 10 && m_asking != Asking::Nothing)) + // timeout + s->disconnect(PingTimeout); +} + +bool EthereumPeer::isConversing() const +{ + return m_asking != Asking::Nothing; +} + +bool EthereumPeer::isCriticalSyncing() const +{ + return m_asking == Asking::BlockHeaders || m_asking == Asking::State || (m_asking == Asking::BlockBodies && m_protocolVersion == 62); +} + +bool EthereumPeer::interpret(unsigned _id, RLP const& _r) +{ + assert(m_observer); + + m_lastAsk = std::chrono::system_clock::to_time_t(chrono::system_clock::now()); + try + { + switch (_id) + { + case StatusPacket: + { + m_protocolVersion = _r[0].toInt(); + m_networkId = _r[1].toInt(); + m_totalDifficulty = _r[2].toInt(); + m_latestHash = _r[3].toHash(); + m_genesisHash = _r[4].toHash(); + m_height = _r[5].toInt(); + if (m_peerCapabilityVersion == m_hostProtocolVersion) + m_protocolVersion = m_hostProtocolVersion; + + LOG(TRACE) << "Status:" << m_protocolVersion << "/" << m_networkId << "/" << m_genesisHash << ", TD:" << m_totalDifficulty << "=" << m_latestHash << ", Height=" << m_height; + setIdle(); + m_observer->onPeerStatus(dynamic_pointer_cast(dynamic_pointer_cast(shared_from_this()))); + break; + } + case TransactionsPacket: + { + m_observer->onPeerTransactions(dynamic_pointer_cast(dynamic_pointer_cast(shared_from_this())), _r); + break; + } + case GetBlockHeadersPacket: + { + /// Packet layout: + /// [ block: { P , B_32 }, maxHeaders: P, skip: P, reverse: P in { 0 , 1 } ] + const auto blockId = _r[0]; + const auto maxHeaders = _r[1].toInt(); + const auto skip = _r[2].toInt(); + const auto reverse = _r[3].toInt(); + + auto numHeadersToSend = maxHeaders <= c_maxHeadersToSend ? static_cast(maxHeaders) : c_maxHeadersToSend; + + if (skip > std::numeric_limits::max() - 1) + { + LOG(TRACE) << "Requested block skip is too big: " << skip; + break; + } + + //取到对端要的head + pair const rlpAndItemCount = m_hostData->blockHeaders(blockId, numHeadersToSend, skip, reverse); + + RLPStream s; + prep(s, BlockHeadersPacket, rlpAndItemCount.second).appendRaw(rlpAndItemCount.first, rlpAndItemCount.second); + sealAndSend(s); + addRating(0); + break; + } + case BlockHeadersPacket: + { + if (m_asking != Asking::BlockHeaders) + LOG(TRACE) << "Peer giving us block headers when we didn't ask for them."; + else + { + setIdle(); + m_observer->onPeerBlockHeaders(dynamic_pointer_cast(shared_from_this()), _r); + } + break; + } + case GetBlockBodiesPacket: + { + unsigned count = static_cast(_r.itemCount()); + LOG(TRACE) << "GetBlockBodies (" << dec << count << "entries)"; + + if (!count) + { + LOG(TRACE) << "Zero-entry GetBlockBodies: Not replying."; + addRating(-10); + break; + } + + pair const rlpAndItemCount = m_hostData->blockBodies(_r); + + addRating(0); + RLPStream s; + prep(s, BlockBodiesPacket, rlpAndItemCount.second).appendRaw(rlpAndItemCount.first, rlpAndItemCount.second); + sealAndSend(s); + break; + } + case BlockBodiesPacket: + { + if (m_asking != Asking::BlockBodies) + LOG(TRACE) << "Peer giving us block bodies when we didn't ask for them."; + else + { + setIdle(); + m_observer->onPeerBlockBodies(dynamic_pointer_cast(shared_from_this()), _r); + } + break; + } + case NewBlockPacket: + { + LOG(TRACE) << "NewBlockPacket..."; + m_observer->onPeerNewBlock(dynamic_pointer_cast(shared_from_this()), _r); + break; + } + case NewBlockHashesPacket: + { + unsigned itemCount = _r.itemCount(); + + LOG(TRACE) << "NewBlockHashesPacket (" << dec << itemCount << "entries)" << (itemCount ? "" : ": NoMoreHashes"); + + if (itemCount > c_maxIncomingNewHashes) + { + disable("Too many new hashes"); + break; + } + + + m_observer->onPeerNewHashes(dynamic_pointer_cast(shared_from_this()), _r); + break; + } + case GetNodeDataPacket: + { + unsigned count = static_cast(_r.itemCount()); + if (!count) + { + LOG(TRACE) << "Zero-entry GetNodeData: Not replying."; + addRating(-10); + break; + } + LOG(TRACE) << "GetNodeData (" << dec << count << " entries)"; + + strings const data = m_hostData->nodeData(_r); + + addRating(0); + RLPStream s; + prep(s, NodeDataPacket, data.size()); + for (auto const& element : data) + s.append(element); + sealAndSend(s); + break; + } + case GetReceiptsPacket: + { + unsigned count = static_cast(_r.itemCount()); + if (!count) + { + LOG(TRACE) << "Zero-entry GetReceipts: Not replying."; + addRating(-10); + break; + } + LOG(TRACE) << "GetReceipts (" << dec << count << " entries)"; + + pair const rlpAndItemCount = m_hostData->receipts(_r); + + addRating(0); + RLPStream s; + prep(s, ReceiptsPacket, rlpAndItemCount.second).appendRaw(rlpAndItemCount.first, rlpAndItemCount.second); + sealAndSend(s); + break; + } + case NodeDataPacket: + { + if (m_asking != Asking::NodeData) + LOG(TRACE) << "Peer giving us node data when we didn't ask for them."; + else + { + setIdle(); + m_observer->onPeerNodeData(dynamic_pointer_cast(shared_from_this()), _r); + } + break; + } + case ReceiptsPacket: + { + if (m_asking != Asking::Receipts) + LOG(TRACE) << "Peer giving us receipts when we didn't ask for them."; + else + { + setIdle(); + m_observer->onPeerReceipts(dynamic_pointer_cast(shared_from_this()), _r); + } + break; + } + case NodeInfoSync: + { + //处理新加节点配置信息 + unsigned itemCount = _r.itemCount(); + LOG(INFO) << "NodeInfoSync itemCount is : " << itemCount << std::endl; + if (itemCount <= 0) + { + break; + } + vector vParams(itemCount); + for (unsigned i = 0; i < itemCount; ++i) + { + eth::NodeConnParams params; + params._sNodeId = _r[i][0].toStringStrict(); + params._sAgencyInfo = _r[i][1].toStringStrict(); + params._sAgencyDesc = _r[i][2].toStringStrict(); + params._iIdentityType = _r[i][3].toInt(); + params._sIP = _r[i][4].toStringStrict(); + params._iPort = _r[i][5].toInt(); + + //增加新节点到内存,并落地 + NodeConnManagerSingleton::GetInstance().addNewNodeConnInfo(params); + + } + + break; + } + case DelNodeInfoSync: + { + //删除节点请求 + const string sNodeId = _r[0].toString(); + LOG(INFO) << "DelNodeInfoSync nodeid is : " << sNodeId << std::endl; + bool bExisted = false; + NodeConnManagerSingleton::GetInstance().delNodeConnInfo(sNodeId, bExisted); + LOG(INFO) << "delNodeConnInfo " << sNodeId << "|" << bExisted << std::endl; + + break; + } + default: + break; + } + } + catch (Exception const&) + { + clog(NetWarn) << "Peer causing an Exception:" << boost::current_exception_diagnostic_information() << _r; + } + catch (std::exception const& _e) + { + clog(NetWarn) << "Peer causing an exception:" << _e.what() << _r; + } + + return true; +} diff --git a/libethereum/EthereumPeer.h b/libethereum/EthereumPeer.h new file mode 100644 index 0000000000..bcaa0b0d8e --- /dev/null +++ b/libethereum/EthereumPeer.h @@ -0,0 +1,205 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file EthereumPeer.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include +#include +#include + +#include +#include +#include +#include +#include "CommonNet.h" + +namespace dev +{ +namespace eth +{ + +class EthereumPeerObserverFace +{ +public: + virtual ~EthereumPeerObserverFace() {} + + virtual void onPeerStatus(std::shared_ptr _peer) = 0; + + virtual void onPeerTransactions(std::shared_ptr _peer, RLP const& _r) = 0; + + virtual void onPeerBlockHeaders(std::shared_ptr _peer, RLP const& _headers) = 0; + + virtual void onPeerBlockBodies(std::shared_ptr _peer, RLP const& _r) = 0; + + virtual void onPeerNewHashes(std::shared_ptr _peer, RLP const& _r) = 0; + + virtual void onPeerNewBlock(std::shared_ptr _peer, RLP const& _r) = 0; + + virtual void onPeerNodeData(std::shared_ptr _peer, RLP const& _r) = 0; + + virtual void onPeerReceipts(std::shared_ptr _peer, RLP const& _r) = 0; + + virtual void onPeerAborting() = 0; +}; + +class EthereumHostDataFace +{ +public: + virtual ~EthereumHostDataFace() {} + + virtual std::pair blockHeaders(RLP const& _blockId, unsigned _maxHeaders, u256 _skip, bool _reverse) const = 0; + + virtual std::pair blockBodies(RLP const& _blockHashes) const = 0; + + virtual strings nodeData(RLP const& _dataHashes) const = 0; + + virtual std::pair receipts(RLP const& _blockHashes) const = 0; +}; + +/** + * @brief The EthereumPeer class + * @todo Document fully. + * @todo make state transitions thread-safe. + */ +class EthereumPeer: public p2p::Capability +{ + friend class EthereumHost; //TODO: remove this + friend class BlockChainSync; //TODO: remove this +public: + static std::string toString(Asking _a); + /// Basic constructor. + EthereumPeer(std::shared_ptr _s, p2p::HostCapabilityFace* _h, unsigned _i, p2p::CapDesc const& _cap, uint16_t _capID); + + /// Basic destructor. + virtual ~EthereumPeer(); + + /// What is our name? + static std::string name() { return "eth"; } + + /// What is our version? + static u256 version() { return c_protocolVersion; } + + /// How many message types do we have? + static unsigned messageCount() { return PacketCount; } + + void init(unsigned _hostProtocolVersion, u256 _hostNetworkId, u256 _chainTotalDifficulty, h256 _chainCurrentHash, h256 _chainGenesisHash, u256 _height, std::shared_ptr _hostData, std::shared_ptr _observer); + + p2p::NodeID id() const { return session()->id(); } + + /// Abort sync and reset fetch + void setIdle(); + + /// Request hashes for given parent hash. + void requestBlockHeaders(h256 const& _startHash, unsigned _count, unsigned _skip, bool _reverse); + void requestBlockHeaders(unsigned _startNumber, unsigned _count, unsigned _skip, bool _reverse); + + /// Request specified blocks from peer. + void requestBlockBodies(h256s const& _blocks); + + /// Request values for specified keys from peer. + void requestNodeData(h256s const& _hashes); + + /// Request receipts for specified blocks from peer. + void requestReceipts(h256s const& _blocks); + + /// Check if this node is rude. + bool isRude() const; + + /// Set that it's a rude node. + void setRude(); + + /// Abort the sync operation. + void abortSync(); + + using p2p::Capability::sealAndSend; +private: + + /// Figure out the amount of blocks we should be asking for. + unsigned askOverride() const; + + /// Interpret an incoming message. + virtual bool interpret(unsigned _id, RLP const& _r); + + /// Request status. Called from constructor + void requestStatus(u256 _hostNetworkId, u256 _chainTotalDifficulty, h256 _chainCurrentHash, h256 _chainGenesisHash, u256 _height); + + /// Clear all known transactions. + void clearKnownTransactions() { std::lock_guard l(x_knownTransactions); m_knownTransactions.clear(); } + + // Request of type _packetType with _hashes as input parameters + void requestByHashes(h256s const& _hashes, Asking _asking, SubprotocolPacketType _packetType); + + /// Update our asking state. + void setAsking(Asking _g); + + /// Do we presently need syncing with this peer? + bool needsSyncing() const { return !isRude() && !!m_latestHash; } + + /// Are we presently in the process of communicating with this peer? + bool isConversing() const; + + /// Are we presently in a critical part of the syncing process with this peer? + bool isCriticalSyncing() const; + + /// Runs period checks to check up on the peer. + void tick(); + + unsigned m_hostProtocolVersion = 0; + + /// Peer's protocol version. + unsigned m_protocolVersion; + + /// Peer's network id. + u256 m_networkId; + + /// What, if anything, we last asked the other peer for. + Asking m_asking = Asking::Nothing; + /// When we asked for it. Allows a time out. + std::atomic m_lastAsk; + + /// These are determined through either a Status message or from NewBlock. + h256 m_latestHash; ///< Peer's latest block's hash that we know about or default null value if no need to sync. + u256 m_totalDifficulty; ///< Peer's latest block's total difficulty. + h256 m_genesisHash; ///< Peer's genesis hash + u256 m_height = 0; ///< Chain height + u256 const m_peerCapabilityVersion; ///< Protocol version this peer supports received as capability + /// Have we received a GetTransactions packet that we haven't yet answered? + bool m_requireTransactions = false; + + Mutex x_knownBlocks; + //h256Hash m_knownBlocks; ///< Blocks that the peer already knows about (that don't need to be sent to them). + QueueSet m_knownBlocks; + Mutex x_knownTransactions; + //h256Hash m_knownTransactions; ///< Transactions that the peer already knows of. + QueueSet m_knownTransactions; + static const size_t kKnownBlockSize = 100; + static const size_t kKnownTranscationsSize = 1024; + unsigned m_unknownNewBlocks = 0; ///< Number of unknown NewBlocks received from this peer + unsigned m_lastAskedHeaders = 0; ///< Number of hashes asked + + std::shared_ptr m_observer; + std::shared_ptr m_hostData; + +}; + +} +} diff --git a/libethereum/Executive.cpp b/libethereum/Executive.cpp new file mode 100644 index 0000000000..fcfc46de98 --- /dev/null +++ b/libethereum/Executive.cpp @@ -0,0 +1,461 @@ +/* + This file is part of cpp-ethereum. + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + cpp-ethereum 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 General Public License for more details. + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Executive.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "Executive.h" + +#include +#include +#include +#include +#include +#include +#include +#include "Interface.h" +#include "State.h" +#include "ExtVM.h" +#include "BlockChain.h" +#include "Block.h" +using namespace std; +using namespace dev; +using namespace dev::eth; + + +StandardTrace::StandardTrace(): + m_trace(Json::arrayValue) +{} + +bool changesMemory(Instruction _inst) +{ + return + _inst == Instruction::MSTORE || + _inst == Instruction::MSTORE8 || + _inst == Instruction::MLOAD || + _inst == Instruction::CREATE || + _inst == Instruction::CALL || + _inst == Instruction::CALLCODE || + _inst == Instruction::SHA3 || + _inst == Instruction::CALLDATACOPY || + _inst == Instruction::CODECOPY || + _inst == Instruction::EXTCODECOPY || + _inst == Instruction::DELEGATECALL; +} + +bool changesStorage(Instruction _inst) +{ + return _inst == Instruction::SSTORE; +} + +void StandardTrace::operator()(uint64_t _steps, uint64_t PC, Instruction inst, bigint newMemSize, bigint gasCost, bigint gas, VM* voidVM, ExtVMFace const* voidExt) +{ + (void)_steps; + + ExtVM const& ext = dynamic_cast(*voidExt); + VM& vm = *voidVM; + + Json::Value r(Json::objectValue); + + Json::Value stack(Json::arrayValue); + if (!m_options.disableStack) + { + for (auto const& i: vm.stack()) + stack.append("0x" + toHex(toCompactBigEndian(i, 1))); + r["stack"] = stack; + } + + bool newContext = false; + Instruction lastInst = Instruction::STOP; + + if (m_lastInst.size() == ext.depth) + { + // starting a new context + assert(m_lastInst.size() == ext.depth); + m_lastInst.push_back(inst); + newContext = true; + } + else if (m_lastInst.size() == ext.depth + 2) + { + m_lastInst.pop_back(); + lastInst = m_lastInst.back(); + } + else if (m_lastInst.size() == ext.depth + 1) + { + // continuing in previous context + lastInst = m_lastInst.back(); + m_lastInst.back() = inst; + } + else + { + LOG(WARNING) << "GAA!!! Tracing VM and more than one new/deleted stack frame between steps!"; + LOG(WARNING) << "Attmepting naive recovery..."; + m_lastInst.resize(ext.depth + 1); + } + + Json::Value memJson(Json::arrayValue); + if (!m_options.disableMemory && (changesMemory(lastInst) || newContext)) + { + for (unsigned i = 0; i < vm.memory().size(); i += 32) + { + bytesConstRef memRef(vm.memory().data() + i, 32); + memJson.append(toHex(memRef, 2, HexPrefix::DontAdd)); + } + r["memory"] = memJson; + } + + if (!m_options.disableStorage && (m_options.fullStorage || changesStorage(lastInst) || newContext)) + { + Json::Value storage(Json::objectValue); + for (auto const& i: ext.state().storage(ext.myAddress)) + storage["0x" + toHex(toCompactBigEndian(i.second.first, 1))] = "0x" + toHex(toCompactBigEndian(i.second.second, 1)); + r["storage"] = storage; + } + + if (m_showMnemonics) + r["op"] = instructionInfo(inst).name; + r["pc"] = toString(PC); + r["gas"] = toString(gas); + r["gasCost"] = toString(gasCost); + if (!!newMemSize) + r["memexpand"] = toString(newMemSize); + + m_trace.append(r); +} + +string StandardTrace::json(bool _styled) const +{ + return _styled ? Json::StyledWriter().write(m_trace) : Json::FastWriter().write(m_trace); +} + +Executive::Executive(Block& _s, BlockChain const& _bc, unsigned _level): + m_s(_s.mutableState()), + m_envInfo(_s.info(), _bc.lastHashes(_s.info().parentHash())), + m_depth(_level), + m_sealEngine(*_bc.sealEngine()) +{ +} + +Executive::Executive(Block& _s, LastHashes const& _lh, unsigned _level): + m_s(_s.mutableState()), + m_envInfo(_s.info(), _lh), + m_depth(_level), + m_sealEngine(*_s.sealEngine()) +{ +} + +Executive::Executive(State& _s, Block const& _block, unsigned _txIndex, BlockChain const& _bc, unsigned _level): + m_s(_s = _block.fromPending(_txIndex)), + m_envInfo(_block.info(), _bc.lastHashes(_block.info().parentHash()), _txIndex ? _block.receipt(_txIndex - 1).gasUsed() : 0), + m_depth(_level), + m_sealEngine(*_bc.sealEngine()) +{ +} + +u256 Executive::gasUsed() const +{ + return m_t.gas() - m_gas; +} + +u256 Executive::gasUsedNoRefunds() const +{ + return m_t.gas() - m_gas + m_refunded; +} + +void Executive::accrueSubState(SubState& _parentContext) +{ + if (m_ext) + _parentContext += m_ext->sub; +} + +void Executive::initialize(Transaction const& _transaction) +{ + m_t = _transaction; + + // Avoid transactions that would take us beyond the block gas limit. + u256 startGasUsed = m_envInfo.gasUsed(); + + //判断交易使用的gas和初始gas是否大于环境设置的gaslimit + if (startGasUsed + (bigint)m_t.gas() > m_envInfo.gasLimit()) + { + LOG(TRACE) << "Cannot fit tx in block" << m_envInfo.number() << ": Require <" << (m_envInfo.gasLimit() - startGasUsed) << " Got" << m_t.gas(); + m_excepted = TransactionException::BlockGasLimitReached; + BOOST_THROW_EXCEPTION(BlockGasLimitReached() << RequirementError((bigint)(m_envInfo.gasLimit() - startGasUsed), (bigint)m_t.gas())); + } + + + m_baseGasRequired = m_t.gasRequired(m_sealEngine.evmSchedule(m_envInfo)); + + // Avoid unaffordable transactions. + bigint gasCost = (bigint)m_t.gas() * m_t.gasPrice(); + bigint totalCost = m_t.value() + gasCost; + + m_gasCost = (u256)gasCost; // Convert back to 256-bit, safe now. +} + +bool Executive::execute() +{ + LOG(TRACE)<<"Executive::execute"; + + m_s.subBalance(m_t.safeSender(), m_gasCost); + + if (m_t.isCreation()) + return create(m_t.sender(), m_t.value(), m_t.gasPrice(), m_t.gas() - (u256)m_baseGasRequired, &m_t.data(), m_t.sender()); + else + return call(m_t.receiveAddress(), m_t.safeSender(), m_t.value(), m_t.gasPrice(), bytesConstRef(&m_t.data()), m_t.gas() - (u256)m_baseGasRequired); +} + +bool Executive::call(Address _receiveAddress, Address _senderAddress, u256 _value, u256 _gasPrice, bytesConstRef _data, u256 _gas) +{ + CallParameters params{_senderAddress, _receiveAddress, _receiveAddress, _value, _value, _gas, _data, {}, {}}; + return call(params, _gasPrice, _senderAddress); +} + +bool Executive::call(CallParameters const& _p, u256 const& _gasPrice, Address const& _origin) +{ + LOG(TRACE)<<"Executive::call"<(m_s, m_envInfo, m_sealEngine, _p.receiveAddress, _p.senderAddress, _origin, _p.apparentValue, _gasPrice, _p.data, &c, codeHash, m_depth); + } + } + + // Transfer ether. + m_s.transferBalance(_p.senderAddress, _p.receiveAddress, _p.valueTransfer); + return !m_ext; +} + +bool Executive::create(Address _sender, u256 _endowment, u256 _gasPrice, u256 _gas, bytesConstRef _init, Address _origin) +{ + LOG(TRACE)<<"Executive::create"<<_sender; + + + u256 nonce = m_s.getNonce(_sender); + m_s.incNonce(_sender); + + m_savepoint = m_s.savepoint(); + + m_isCreation = true; + + // We can allow for the reverted state (i.e. that with which m_ext is constructed) to contain the m_orig.address, since + // we delete it explicitly if we decide we need to revert. + m_newAddress = right160(sha3(rlpList(_sender, nonce))); + LOG(TRACE)<<"Executive::create "<= m_sealEngine.chainParams().u256Param("EIP158ForkBlock")) + m_s.incNonce(m_newAddress); + + // Schedule _init execution if not empty. + if (!_init.empty()) + m_ext = make_shared(m_s, m_envInfo, m_sealEngine, m_newAddress, _sender, _origin, _endowment, _gasPrice, bytesConstRef(), _init, sha3(_init), m_depth); + else if (m_s.addressHasCode(m_newAddress)) + // Overwrite with empty code in case the account already has a code + // (address collision -- not real life case but we can check it with + // synthetic tests). + m_s.setNewCode(m_newAddress, {}); + + return !m_ext; +} + +OnOpFunc Executive::simpleTrace() +{ + return [](uint64_t steps, uint64_t PC, Instruction inst, bigint newMemSize, bigint gasCost, bigint gas, VM* voidVM, ExtVMFace const* voidExt) + { + ExtVM const& ext = *static_cast(voidExt); + VM& vm = *voidVM; + + ostringstream o; + o << endl << " STACK" << endl; + for (auto i: vm.stack()) + o << (h256)i << endl; + o << " MEMORY" << endl << ((vm.memory().size() > 1000) ? " mem size greater than 1000 bytes " : memDump(vm.memory())); + o << " STORAGE" << endl; + for (auto const& i: ext.state().storage(ext.myAddress)) + o << showbase << hex << i.second.first << ": " << i.second.second << endl; + LOG(TRACE) << o.str(); + LOG(TRACE) << " < " << dec << ext.depth << " : " << ext.myAddress << " : #" << steps << " : " << hex << setw(4) << setfill('0') << PC << " : " << instructionInfo(inst).name << " : " << dec << gas << " : -" << dec << gasCost << " : " << newMemSize << "x32" << " >"; + }; +} + +bool Executive::go(OnOpFunc const& _onOp) +{ + LOG(TRACE)<<"Executive::go"; + + if (m_ext) + { + + Timer t; + + try + { + // Create VM instance. Force Interpreter if tracing requested. + auto vm = _onOp ? VMFactory::create(VMKind::Interpreter) : VMFactory::create(); + if (m_isCreation) + { + auto out = vm->exec(m_gas, *m_ext, _onOp); + if (m_res) + { + m_res->gasForDeposit = m_gas; + m_res->depositSize = out.size(); + } + if (out.size() > m_ext->evmSchedule().maxCodeSize) + BOOST_THROW_EXCEPTION(OutOfGas()); + else if (out.size() * m_ext->evmSchedule().createDataGas <= m_gas) + { + if (m_res) + m_res->codeDeposit = CodeDeposit::Success; + m_gas -= out.size() * m_ext->evmSchedule().createDataGas; + } + else + { + if (m_ext->evmSchedule().exceptionalFailedCodeDeposit) + BOOST_THROW_EXCEPTION(OutOfGas()); + else + { + if (m_res) + m_res->codeDeposit = CodeDeposit::Failed; + out.clear(); + } + } + if (m_res) + m_res->output = out; // copy output to execution result + + LOG(TRACE)<<"Executive::go setCode "<myAddress, std::move(out)); + } + else + { + if (m_res) + { + m_res->output = vm->exec(m_gas, *m_ext, _onOp); // take full output + bytesConstRef{&m_res->output}.copyTo(m_outRef); + } + else + vm->exec(m_gas, *m_ext, m_outRef, _onOp); // take only expected output + } + } + catch (VMException const& _e) + { + clog(StateSafeExceptions) << "Safe VM Exception. " << diagnostic_information(_e); + m_gas = 0; + m_excepted = toTransactionException(_e); + revert(); + } + catch (Exception const& _e) + { + // TODO: AUDIT: check that this can never reasonably happen. Consider what to do if it does. + LOG(WARNING) << "Unexpected exception in VM. There may be a bug in this implementation. " << diagnostic_information(_e); + exit(1); + // Another solution would be to reject this transaction, but that also + // has drawbacks. Essentially, the amount of ram has to be increased here. + } + catch (std::exception const& _e) + { + // TODO: AUDIT: check that this can never reasonably happen. Consider what to do if it does. + LOG(WARNING) << "Unexpected std::exception in VM. Not enough RAM? " << _e.what(); + exit(1); + // Another solution would be to reject this transaction, but that also + // has drawbacks. Essentially, the amount of ram has to be increased here. + } + + ctxstat<<"VM took:"<<(t.elapsed()*1000000)<<" Hash="<<(m_t.sha3())<<",Randid="<sub.refunds += m_ext->evmSchedule().suicideRefundGas * m_ext->sub.suicides.size(); + + // SSTORE refunds... + // must be done before the miner gets the fees. + m_refunded = m_ext ? min((m_t.gas() - m_gas) / 2, m_ext->sub.refunds) : 0; + m_gas += m_refunded; + + if (m_t) + { + //m_s.addBalance(m_t.sender(), m_gas * m_t.gasPrice()); + + //u256 feesEarned = (m_t.gas() - m_gas) * m_t.gasPrice(); + //m_s.addBalance(m_envInfo.author(), feesEarned); + } + + // Suicides... + if (m_ext) + for (auto a: m_ext->sub.suicides) + m_s.kill(a); + + // Logs.. + if (m_ext) + m_logs = m_ext->sub.logs; + + if (m_res) // Collect results + { + m_res->gasUsed = gasUsed(); + m_res->excepted = m_excepted; // TODO: m_except is used only in ExtVM::call + m_res->newAddress = m_newAddress; + m_res->gasRefunded = m_ext ? m_ext->sub.refunds : 0; + } +} + +void Executive::revert() +{ + if (m_ext) + m_ext->sub.clear(); + + // Set result address to the null one. + m_newAddress = {}; + m_s.rollback(m_savepoint); +} \ No newline at end of file diff --git a/libethereum/Executive.h b/libethereum/Executive.h new file mode 100644 index 0000000000..88f0a8b299 --- /dev/null +++ b/libethereum/Executive.h @@ -0,0 +1,211 @@ +/* + This file is part of cpp-ethereum. + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + cpp-ethereum 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 General Public License for more details. + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Executive.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include + +#include +#include +#include +#include "Transaction.h" + +namespace Json +{ + class Value; +} + +namespace dev +{ + +class OverlayDB; + +namespace eth +{ + +class State; +class Block; +class BlockChain; +class ExtVM; +class SealEngineFace; +struct Manifest; + + + +class StandardTrace +{ +public: + struct DebugOptions + { + bool disableStorage = false; + bool disableMemory = false; + bool disableStack = false; + bool fullStorage = false; + }; + + StandardTrace(); + void operator()(uint64_t _steps, uint64_t _PC, Instruction _inst, bigint _newMemSize, bigint _gasCost, bigint _gas, VM* _vm, ExtVMFace const* _extVM); + + void setShowMnemonics() { m_showMnemonics = true; } + void setOptions(DebugOptions _options) { m_options = _options; } + + std::string json(bool _styled = false) const; + + OnOpFunc onOp() { return [=](uint64_t _steps, uint64_t _PC, Instruction _inst, bigint _newMemSize, bigint _gasCost, bigint _gas, VM* _vm, ExtVMFace const* _extVM) { (*this)(_steps, _PC, _inst, _newMemSize, _gasCost, _gas, _vm, _extVM); }; } + +private: + bool m_showMnemonics = false; + std::vector m_lastInst; + bytes m_lastCallData; + Json::Value m_trace; + DebugOptions m_options; +}; + + +/** + * @brief Message-call/contract-creation executor; useful for executing transactions. + * + * Two ways of using this class - either as a transaction executive or a CALL/CREATE executive. + * + * In the first use, after construction, begin with initialize(), then execute() and end with finalize(). Call go() + * after execute() only if it returns false. + * + * In the second use, after construction, begin with call() or create() and end with + * accrueSubState(). Call go() after call()/create() only if it returns false. + * + * Example: + * @code + * Executive e(state, blockchain, 0); + * e.initialize(transaction); + * if (!e.execute()) + * e.go(); + * e.finalize(); + * @endcode + */ +class Executive +{ +public: + /// Simple constructor; executive will operate on given state, with the given environment info. + Executive(State& _s, EnvInfo const& _envInfo, SealEngineFace const& _sealEngine, unsigned _level = 0): m_s(_s), m_envInfo(_envInfo), m_depth(_level), m_sealEngine(_sealEngine) {} + + /** Easiest constructor. + * Creates executive to operate on the state of end of the given block, populating environment + * info from given Block and the LastHashes portion from the BlockChain. + */ + Executive(Block& _s, BlockChain const& _bc, unsigned _level = 0); + + /** LastHashes-split constructor. + * Creates executive to operate on the state of end of the given block, populating environment + * info accordingly, with last hashes given explicitly. + */ + Executive(Block& _s, LastHashes const& _lh = LastHashes(), unsigned _level = 0); + + /** Previous-state constructor. + * Creates executive to operate on the state of a particular transaction in the given block, + * populating environment info from the given Block and the LastHashes portion from the BlockChain. + * State is assigned the resultant value, but otherwise unused. + */ + Executive(State& _s, Block const& _block, unsigned _txIndex, BlockChain const& _bc, unsigned _level = 0); + + Executive(Executive const&) = delete; + void operator=(Executive) = delete; + + /// Initializes the executive for evaluating a transaction. You must call finalize() at some point following this. + void initialize(bytesConstRef _transaction) { initialize(Transaction(_transaction, CheckTransaction::None)); } + void initialize(Transaction const& _transaction); + /// Finalise a transaction previously set up with initialize(). + /// @warning Only valid after initialize() and execute(), and possibly go(). + void finalize(); + /// Begins execution of a transaction. You must call finalize() following this. + /// @returns true if the transaction is done, false if go() must be called. + bool execute(); + /// @returns the transaction from initialize(). + /// @warning Only valid after initialize(). + Transaction const& t() const { return m_t; } + /// @returns the log entries created by this operation. + /// @warning Only valid after finalise(). + LogEntries const& logs() const { return m_logs; } + /// @returns total gas used in the transaction/operation. + /// @warning Only valid after finalise(). + u256 gasUsed() const; + /// @returns total gas used in the transaction/operation, excluding anything refunded. + /// @warning Only valid after finalise(). + u256 gasUsedNoRefunds() const; + + /// Set up the executive for evaluating a bare CREATE (contract-creation) operation. + /// @returns false iff go() must be called (and thus a VM execution in required). + bool create(Address _txSender, u256 _endowment, u256 _gasPrice, u256 _gas, bytesConstRef _code, Address _originAddress); + /// Set up the executive for evaluating a bare CALL (message call) operation. + /// @returns false iff go() must be called (and thus a VM execution in required). + bool call(Address _receiveAddress, Address _txSender, u256 _txValue, u256 _gasPrice, bytesConstRef _txData, u256 _gas); + bool call(CallParameters const& _cp, u256 const& _gasPrice, Address const& _origin); + /// Finalise an operation through accruing the substate into the parent context. + void accrueSubState(SubState& _parentContext); + + /// Executes (or continues execution of) the VM. + /// @returns false iff go() must be called again to finish the transaction. + bool go(OnOpFunc const& _onOp = OnOpFunc()); + + /// Operation function for providing a simple trace of the VM execution. + static OnOpFunc simpleTrace(); + + /// Operation function for providing a simple trace of the VM execution. + static OnOpFunc standardTrace(std::ostream& o_output); + + /// @returns gas remaining after the transaction/operation. Valid after the transaction has been executed. + u256 gas() const { return m_gas; } + + /// @returns the new address for the created contract in the CREATE operation. + Address newAddress() const { return m_newAddress; } + /// @returns true iff the operation ended with a VM exception. + bool excepted() const { return m_excepted != TransactionException::None; } + + /// Collect execution results in the result storage provided. + void setResultRecipient(ExecutionResult& _res) { m_res = &_res; } + + /// Revert all changes made to the state by this execution. + void revert(); + +private: + State& m_s; ///< The state to which this operation/transaction is applied. + // TODO: consider changign to EnvInfo const& to avoid LastHashes copy at every CALL/CREATE + EnvInfo m_envInfo; ///< Information on the runtime environment. + std::shared_ptr m_ext; ///< The VM externality object for the VM execution or null if no VM is required. shared_ptr used only to allow ExtVM forward reference. This field does *NOT* survive this object. + bytesRef m_outRef; ///< Reference to "expected output" buffer. + ExecutionResult* m_res = nullptr; ///< Optional storage for execution results. + + unsigned m_depth = 0; ///< The context's call-depth. + TransactionException m_excepted = TransactionException::None; ///< Details if the VM's execution resulted in an exception. + bigint m_baseGasRequired; ///< The base amount of gas requried for executing this transactions. + u256 m_gas = 0; ///< The gas for EVM code execution. Initial amount before go() execution, final amount after go() execution. + u256 m_refunded = 0; ///< The amount of gas refunded. + + Transaction m_t; ///< The original transaction. Set by setup(). + LogEntries m_logs; ///< The log entries created by this transaction. Set by finalize(). + + u256 m_gasCost; + SealEngineFace const& m_sealEngine; + + bool m_isCreation = false; + Address m_newAddress; + size_t m_savepoint = 0; +}; + +} +} diff --git a/libethereum/ExtVM.cpp b/libethereum/ExtVM.cpp new file mode 100644 index 0000000000..adec4d787a --- /dev/null +++ b/libethereum/ExtVM.cpp @@ -0,0 +1,139 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file ExtVM.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "ExtVM.h" +#include +#include +#include +using namespace dev; +using namespace dev::eth; + +namespace // anonymous +{ + +static unsigned const c_depthLimit = 1024; + +/// Upper bound of stack space needed by single CALL/CREATE execution. Set experimentally. +static size_t const c_singleExecutionStackSize = 14 * 1024; + +/// Standard thread stack size. +static size_t const c_defaultStackSize = +#if defined(__linux) + 8 * 1024 * 1024; +#elif defined(_WIN32) + 16 * 1024 * 1024; +#else + 512 * 1024; // OSX and other OSs +#endif + +/// Stack overhead prior to allocation. +static size_t const c_entryOverhead = 128 * 1024; + +/// On what depth execution should be offloaded to additional separated stack space. +static unsigned const c_offloadPoint = (c_defaultStackSize - c_entryOverhead) / c_singleExecutionStackSize; + +void goOnOffloadedStack(Executive& _e, OnOpFunc const& _onOp) +{ + // Set new stack size enouth to handle the rest of the calls up to the limit. + boost::thread::attributes attrs; + attrs.set_stack_size((c_depthLimit - c_offloadPoint) * c_singleExecutionStackSize); + + // Create new thread with big stack and join immediately. + // TODO: It is possible to switch the implementation to Boost.Context or similar when the API is stable. + boost::exception_ptr exception; + boost::thread{attrs, [&]{ + try + { + _e.go(_onOp); + } + catch (...) + { + exception = boost::current_exception(); // Catch all exceptions to be rethrown in parent thread. + } + }}.join(); + if (exception) + boost::rethrow_exception(exception); +} + +void go(unsigned _depth, Executive& _e, OnOpFunc const& _onOp) +{ + // If in the offloading point we need to switch to additional separated stack space. + // Current stack is too small to handle more CALL/CREATE executions. + // It needs to be done only once as newly allocated stack space it enough to handle + // the rest of the calls up to the depth limit (c_depthLimit). + + if (_depth == c_offloadPoint) + { + LOG(TRACE) << "Stack offloading (depth: " << c_offloadPoint << ")"; + goOnOffloadedStack(_e, _onOp); + } + else + _e.go(_onOp); +} + +} // anonymous namespace + + +bool ExtVM::call(CallParameters& _p) +{ + Executive e{m_s, envInfo(), m_sealEngine, depth + 1}; + if (!e.call(_p, gasPrice, origin)) + { + go(depth, e, _p.onOp); + e.accrueSubState(sub); + } + _p.gas = e.gas(); + + if (e.excepted()) + return false; + + return true; +} + +size_t ExtVM::codeSizeAt(dev::Address _a) +{ + return m_s.codeSize(_a); +} + +void ExtVM::setStore(u256 _n, u256 _v) +{ + m_s.setStorage(myAddress, _n, _v); +} + +h160 ExtVM::create(u256 _endowment, u256& io_gas, bytesConstRef _code, OnOpFunc const& _onOp) +{ + Executive e{m_s, envInfo(), m_sealEngine, depth + 1}; + if (!e.create(myAddress, _endowment, gasPrice, io_gas, _code, origin)) + { + go(depth, e, _onOp); + e.accrueSubState(sub); + } + io_gas = e.gas(); + return e.newAddress(); +} + +void ExtVM::suicide(Address _a) +{ + // TODO: Why transfer is no used here? + m_s.addBalance(_a, m_s.balance(myAddress)); + m_s.subBalance(myAddress, m_s.balance(myAddress)); + ExtVMFace::suicide(_a); +} diff --git a/libethereum/ExtVM.h b/libethereum/ExtVM.h new file mode 100644 index 0000000000..6ba08ded4b --- /dev/null +++ b/libethereum/ExtVM.h @@ -0,0 +1,102 @@ + /* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file ExtVM.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include +#include +#include +#include +#include "State.h" +#include "Executive.h" + +namespace dev +{ +namespace eth +{ + +class SealEngineFace; + +/** + * @brief Externality interface for the Virtual Machine providing access to world state. + */ +class ExtVM: public ExtVMFace +{ +public: + /// Full constructor. + ExtVM(State& _s, EnvInfo const& _envInfo, SealEngineFace const& _sealEngine, Address _myAddress, Address _caller, Address _origin, u256 _value, u256 _gasPrice, bytesConstRef _data, bytesConstRef _code, h256 const& _codeHash, unsigned _depth = 0): + ExtVMFace(_envInfo, _myAddress, _caller, _origin, _value, _gasPrice, _data, _code.toBytes(), _codeHash, _depth), m_s(_s), m_sealEngine(_sealEngine) + { + // Contract: processing account must exist. In case of CALL, the ExtVM + // is created only if an account has code (so exist). In case of CREATE + // the account must be created first. + + + assert(m_s.addressInUse(_myAddress)); + } + + /// Read storage location. + virtual u256 store(u256 _n) override final { return m_s.storage(myAddress, _n); } + + /// Write a value in storage. + virtual void setStore(u256 _n, u256 _v) override final; + + /// Read address's code. + virtual bytes const& codeAt(Address _a) override final { return m_s.code(_a); } + + /// @returns the size of the code in bytes at the given address. + virtual size_t codeSizeAt(Address _a) override final; + + /// Create a new contract. + virtual h160 create(u256 _endowment, u256& io_gas, bytesConstRef _code, OnOpFunc const& _onOp = {}) override final; + + /// Create a new message call. Leave _myAddressOverride as the default to use the present address as caller. + virtual bool call(CallParameters& _params) override final; + + /// Read address's balance. + virtual u256 balance(Address _a) override final { return m_s.balance(_a); } + + /// Does the account exist? + virtual bool exists(Address _a) override final + { + if (evmSchedule().emptinessIsNonexistence()) + return m_s.accountNonemptyAndExisting(_a); + else + return m_s.addressInUse(_a); + } + + /// Suicide the associated contract to the given address. + virtual void suicide(Address _a) override final; + + /// Return the EVM gas-price schedule for this execution context. + virtual EVMSchedule const& evmSchedule() const override final { return m_sealEngine.evmSchedule(envInfo()); } + + State const& state() const { return m_s; } + +private: + State& m_s; ///< A reference to the base state. + SealEngineFace const& m_sealEngine; +}; + +} +} + diff --git a/libethereum/GasPricer.cpp b/libethereum/GasPricer.cpp new file mode 100644 index 0000000000..a771ebf576 --- /dev/null +++ b/libethereum/GasPricer.cpp @@ -0,0 +1,26 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file GasPricer.cpp + * @author Gav Wood + * @date 2015 + */ + +#include "GasPricer.h" + +using namespace std; +using namespace dev; +using namespace dev::eth; diff --git a/libethereum/GasPricer.h b/libethereum/GasPricer.h new file mode 100644 index 0000000000..423f45a5a8 --- /dev/null +++ b/libethereum/GasPricer.h @@ -0,0 +1,76 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file GasPricer.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include + +namespace dev +{ +namespace eth +{ + +class Block; +class BlockChain; + +enum class TransactionPriority +{ + Lowest = 0, + Low = 2, + Medium = 4, + High = 6, + Highest = 8 +}; + +static const u256 DefaultGasPrice = 20 * shannon; + +class GasPricer +{ +public: + GasPricer() = default; + virtual ~GasPricer() = default; + + virtual u256 ask(Block const&) const = 0; + virtual u256 bid(TransactionPriority _p = TransactionPriority::Medium) const = 0; + + virtual void update(BlockChain const&) {} +}; + +class TrivialGasPricer: public GasPricer +{ +public: + TrivialGasPricer() = default; + TrivialGasPricer(u256 const& _ask, u256 const& _bid): m_ask(_ask), m_bid(_bid) {} + + void setAsk(u256 const& _ask) { m_ask = _ask; } + void setBid(u256 const& _bid) { m_bid = _bid; } + + u256 ask() const { return m_ask; } + u256 ask(Block const&) const override { return m_ask; } + u256 bid(TransactionPriority = TransactionPriority::Medium) const override { return m_bid; } + +private: + u256 m_ask = DefaultGasPrice; + u256 m_bid = DefaultGasPrice; +}; + +} +} diff --git a/libethereum/GenericFarm.h b/libethereum/GenericFarm.h new file mode 100644 index 0000000000..bb8af5495a --- /dev/null +++ b/libethereum/GenericFarm.h @@ -0,0 +1,204 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . + */ +/** @file GenericFarm.h + * @author Gav Wood + * @date 2015 + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace dev +{ + +namespace eth +{ + +/** + * @brief A collective of Miners. + * Miners ask for work, then submit proofs + * @threadsafe + */ +template +class GenericFarm: public GenericFarmFace +{ +public: + using WorkPackage = typename PoW::WorkPackage; + using Solution = typename PoW::Solution; + using Miner = GenericMiner; + + struct SealerDescriptor + { + std::function instances; + std::function create; + }; + + ~GenericFarm() + { + stop(); + } + + /** + * @brief Sets the current mining mission. + * @param _wp The work package we wish to be mining. + */ + void setWork(WorkPackage const& _wp) + { + WriteGuard l(x_minerWork); + if (_wp.headerHash == m_work.headerHash) + return; + m_work = _wp; + for (auto const& m: m_miners) + m->setWork(m_work); + resetTimer(); + } + + void setSealers(std::map const& _sealers) { m_sealers = _sealers; } + + /** + * @brief Start a number of miners. + */ + bool start(std::string const& _sealer) + { + WriteGuard l(x_minerWork); + if (!m_miners.empty() && m_lastSealer == _sealer) + return true; + if (!m_sealers.count(_sealer)) + return false; + + m_miners.clear(); + auto ins = m_sealers[_sealer].instances(); + m_miners.reserve(ins); + for (unsigned i = 0; i < ins; ++i) + { + m_miners.push_back(std::shared_ptr(m_sealers[_sealer].create(std::make_pair(this, i)))); + m_miners.back()->setWork(m_work); + } + m_isMining = true; + m_lastSealer = _sealer; + resetTimer(); + return true; + } + /** + * @brief Stop all mining activities. + */ + void stop() + { + WriteGuard l(x_minerWork); + m_miners.clear(); + m_work.reset(); + m_isMining = false; + } + + bool isMining() const + { + return m_isMining; + } + + /** + * @brief Get information on the progress of mining this work package. + * @return The progress with mining so far. + */ + WorkingProgress const& miningProgress() const + { + WorkingProgress p; + p.ms = std::chrono::duration_cast(std::chrono::steady_clock::now() - m_lastStart).count(); + { + ReadGuard l2(x_minerWork); + for (auto const& i: m_miners) + p.hashes += i->hashCount(); + } + WriteGuard l(x_progress); + m_progress = p; + return m_progress; + } + + /** + * @brief Reset the mining progess counter. + */ + void resetMiningProgress() + { + DEV_READ_GUARDED(x_minerWork) + for (auto const& i: m_miners) + i->resetHashCount(); + resetTimer(); + } + + using SolutionFound = std::function; + + /** + * @brief Provides a valid header based upon that received previously with setWork(). + * @param _bi The now-valid header. + * @return true if the header was good and that the Farm should pause until more work is submitted. + */ + void onSolutionFound(SolutionFound const& _handler) { m_onSolutionFound = _handler; } + + WorkPackage work() const { ReadGuard l(x_minerWork); return m_work; } + + /** + * @brief Called from a Miner to note a WorkPackage has a solution. + * @param _p The solution. + * @param _wp The WorkPackage that the Solution is for. + * @return true iff the solution was good (implying that mining should be . + */ + bool submitProof(Solution const& _s, Miner* _m) override + { + if (m_onSolutionFound && m_onSolutionFound(_s)) + if (x_minerWork.try_lock()) + { + for (std::shared_ptr const& m: m_miners) + if (m.get() != _m) + m->setWork(); + m_work.reset(); + x_minerWork.unlock(); + return true; + } + return false; + } + +private: + void resetTimer() + { + m_lastStart = std::chrono::steady_clock::now(); + } + + mutable SharedMutex x_minerWork; + std::vector> m_miners; + WorkPackage m_work; + + std::atomic m_isMining = {false}; + + mutable SharedMutex x_progress; + mutable WorkingProgress m_progress; + std::chrono::steady_clock::time_point m_lastStart; + + SolutionFound m_onSolutionFound; + + std::map m_sealers; + std::string m_lastSealer; +}; + +} +} diff --git a/libethereum/GenericMiner.cpp b/libethereum/GenericMiner.cpp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/libethereum/GenericMiner.h b/libethereum/GenericMiner.h new file mode 100644 index 0000000000..002ad771bc --- /dev/null +++ b/libethereum/GenericMiner.h @@ -0,0 +1,164 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . + */ +/** @file Miner.h + * @author Gav Wood + * @date 2015 + */ + +#pragma once + +#include + +#include +#include + +namespace dev +{ + +namespace eth +{ + +struct MineInfo: public WorkingProgress {}; + +inline std::ostream& operator<<(std::ostream& _out, WorkingProgress _p) +{ + _out << _p.rate() << " H/s = " << _p.hashes << " hashes / " << (double(_p.ms) / 1000) << " s"; + return _out; +} + +template class GenericMiner; + +/** + * @brief Class for hosting one or more Miners. + * @warning Must be implemented in a threadsafe manner since it will be called from multiple + * miner threads. + */ +template class GenericFarmFace +{ +public: + using WorkPackage = typename PoW::WorkPackage; + using Solution = typename PoW::Solution; + using Miner = GenericMiner; + + virtual ~GenericFarmFace() {} + + /** + * @brief Called from a Miner to note a WorkPackage has a solution. + * @param _p The solution. + * @param _wp The WorkPackage that the Solution is for; this will be reset if the work is accepted. + * @param _finder The miner that found it. + * @return true iff the solution was good (implying that mining should be . + */ + virtual bool submitProof(Solution const& _p, Miner* _finder) = 0; +}; + +/** + * @brief A miner - a member and adoptee of the Farm. + * @warning Not threadsafe. It is assumed Farm will synchronise calls to/from this class. + */ +template class GenericMiner +{ +public: + using WorkPackage = typename PoW::WorkPackage; + using Solution = typename PoW::Solution; + using FarmFace = GenericFarmFace; + using ConstructionInfo = std::pair; + + GenericMiner(ConstructionInfo const& _ci): + m_farm(_ci.first), + m_index(_ci.second) + {} + virtual ~GenericMiner() {} + + // API FOR THE FARM TO CALL IN WITH + + void setWork(WorkPackage const& _work = WorkPackage()) + { + auto old = m_work; + { + Guard l(x_work); + m_work = _work; + } + if (!!_work) + { + DEV_TIMED_ABOVE("pause", 250) + pause(); + DEV_TIMED_ABOVE("kickOff", 250) + kickOff(); + } + else if (!_work && !!old) + pause(); + m_hashCount = 0; + } + + uint64_t hashCount() const { return m_hashCount; } + + void resetHashCount() { m_hashCount = 0; } + + unsigned index() const { return m_index; } + +protected: + + // REQUIRED TO BE REIMPLEMENTED BY A SUBCLASS: + + /** + * @brief Begin working on a given work package, discarding any previous work. + * @param _work The package for which to find a solution. + */ + virtual void kickOff() = 0; + + /** + * @brief No work left to be done. Pause until told to kickOff(). + */ + virtual void pause() = 0; + + // AVAILABLE FOR A SUBCLASS TO CALL: + + /** + * @brief Notes that the Miner found a solution. + * @param _s The solution. + * @return true if the solution was correct and that the miner should pause. + */ + bool submitProof(Solution const& _s) + { + if (!m_farm) + return true; + if (m_farm->submitProof(_s, this)) + { + Guard l(x_work); + m_work.reset(); + return true; + } + return false; + } + + WorkPackage const& work() const { Guard l(x_work); return m_work; } + + void accumulateHashes(unsigned _n) { m_hashCount += _n; } + +private: + FarmFace* m_farm = nullptr; + unsigned m_index; + + uint64_t m_hashCount = 0; + + WorkPackage m_work; + mutable Mutex x_work; +}; + +} +} diff --git a/libethereum/GenesisInfo.cpp b/libethereum/GenesisInfo.cpp new file mode 100644 index 0000000000..36f1b4f65a --- /dev/null +++ b/libethereum/GenesisInfo.cpp @@ -0,0 +1,321 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file GenesisInfo.cpp + * @author Gav Wood + * @date 2014 + */ + +#include +#include +#include "GenesisInfo.h" + +using namespace dev; +using namespace eth; + +std::string const dev::eth::c_genesisInfoTestBasicAuthority = +R"E( +{ + "sealEngine": "BasicAuthority", + "params": { + "accountStartNonce": "0x00", + "maximumExtraDataSize": "0x20", + "minGasLimit": "0x1388", + "maxGasLimit": "0x7fffffffffffffff", + "gasLimitBoundDivisor": "0x0400", + "minimumDifficulty": "0x020000", + "difficultyBoundDivisor": "0x0800", + "durationLimit": "0x0d", + "blockReward": "0x4563918244F40000", + "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", + "networkID" : "0x1" + }, + "genesis": { + "nonce": "0x0000000000000042", + "difficulty": "0x400000000", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "author": "0x0000000000000000000000000000000000000000", + "timestamp": "0x00", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "extraData": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa", + "gasLimit": "0x2fefd8" + }, + "accounts": { + "0000000000000000000000000000000000000001": { "wei": "1", "precompiled": { "name": "ecrecover", "linear": { "base": 3000, "word": 0 } } }, + "0000000000000000000000000000000000000002": { "wei": "1", "precompiled": { "name": "sha256", "linear": { "base": 60, "word": 12 } } }, + "0000000000000000000000000000000000000003": { "wei": "1", "precompiled": { "name": "ripemd160", "linear": { "base": 600, "word": 120 } } }, + "0000000000000000000000000000000000000004": { "wei": "1", "precompiled": { "name": "identity", "linear": { "base": 15, "word": 3 } } }, + "00c9b024c2efc853ecabb8be2fb1d16ce8174ab1": { "wei": "1606938044258990275541962092341162602522202993782792835301376" } + } +} +)E"; + +static std::string const c_childDaos = +R"E( +{ +"accounts": [ + { + "address":"0xd4fe7bc31cedb7bfb8a345f31e668033056b2728", + "extraBalanceAccount":"0xb3fb0e5aba0e20e5c49d252dfd30e102b171a425" + }, + { + "address":"0x2c19c7f9ae8b751e37aeb2d93a699722395ae18f", + "extraBalanceAccount":"0xecd135fa4f61a655311e86238c92adcd779555d2" + }, + { + "address":"0x1975bd06d486162d5dc297798dfc41edd5d160a7", + "extraBalanceAccount":"0xa3acf3a1e16b1d7c315e23510fdd7847b48234f6" + }, + { + "address":"0x319f70bab6845585f412ec7724b744fec6095c85", + "extraBalanceAccount":"0x06706dd3f2c9abf0a21ddcc6941d9b86f0596936" + }, + { + "address":"0x5c8536898fbb74fc7445814902fd08422eac56d0", + "extraBalanceAccount":"0x6966ab0d485353095148a2155858910e0965b6f9" + }, + { + "address":"0x779543a0491a837ca36ce8c635d6154e3c4911a6", + "extraBalanceAccount":"0x2a5ed960395e2a49b1c758cef4aa15213cfd874c" + }, + { + "address":"0x5c6e67ccd5849c0d29219c4f95f1a7a93b3f5dc5", + "extraBalanceAccount":"0x9c50426be05db97f5d64fc54bf89eff947f0a321" + }, + { + "address":"0x200450f06520bdd6c527622a273333384d870efb", + "extraBalanceAccount":"0xbe8539bfe837b67d1282b2b1d61c3f723966f049" + }, + { + "address":"0x6b0c4d41ba9ab8d8cfb5d379c69a612f2ced8ecb", + "extraBalanceAccount":"0xf1385fb24aad0cd7432824085e42aff90886fef5" + }, + { + "address":"0xd1ac8b1ef1b69ff51d1d401a476e7e612414f091", + "extraBalanceAccount":"0x8163e7fb499e90f8544ea62bbf80d21cd26d9efd" + }, + { + "address":"0x51e0ddd9998364a2eb38588679f0d2c42653e4a6", + "extraBalanceAccount":"0x627a0a960c079c21c34f7612d5d230e01b4ad4c7" + }, + { + "address":"0xf0b1aa0eb660754448a7937c022e30aa692fe0c5", + "extraBalanceAccount":"0x24c4d950dfd4dd1902bbed3508144a54542bba94" + }, + { + "address":"0x9f27daea7aca0aa0446220b98d028715e3bc803d", + "extraBalanceAccount":"0xa5dc5acd6a7968a4554d89d65e59b7fd3bff0f90" + }, + { + "address":"0xd9aef3a1e38a39c16b31d1ace71bca8ef58d315b", + "extraBalanceAccount":"0x63ed5a272de2f6d968408b4acb9024f4cc208ebf" + }, + { + "address":"0x6f6704e5a10332af6672e50b3d9754dc460dfa4d", + "extraBalanceAccount":"0x77ca7b50b6cd7e2f3fa008e24ab793fd56cb15f6" + }, + { + "address":"0x492ea3bb0f3315521c31f273e565b868fc090f17", + "extraBalanceAccount":"0x0ff30d6de14a8224aa97b78aea5388d1c51c1f00" + }, + { + "address":"0x9ea779f907f0b315b364b0cfc39a0fde5b02a416", + "extraBalanceAccount":"0xceaeb481747ca6c540a000c1f3641f8cef161fa7" + }, + { + "address":"0xcc34673c6c40e791051898567a1222daf90be287", + "extraBalanceAccount":"0x579a80d909f346fbfb1189493f521d7f48d52238" + }, + { + "address":"0xe308bd1ac5fda103967359b2712dd89deffb7973", + "extraBalanceAccount":"0x4cb31628079fb14e4bc3cd5e30c2f7489b00960c" + }, + { + "address":"0xac1ecab32727358dba8962a0f3b261731aad9723", + "extraBalanceAccount":"0x4fd6ace747f06ece9c49699c7cabc62d02211f75" + }, + { + "address":"0x440c59b325d2997a134c2c7c60a8c61611212bad", + "extraBalanceAccount":"0x4486a3d68fac6967006d7a517b889fd3f98c102b" + }, + { + "address":"0x9c15b54878ba618f494b38f0ae7443db6af648ba", + "extraBalanceAccount":"0x27b137a85656544b1ccb5a0f2e561a5703c6a68f" + }, + { + "address":"0x21c7fdb9ed8d291d79ffd82eb2c4356ec0d81241", + "extraBalanceAccount":"0x23b75c2f6791eef49c69684db4c6c1f93bf49a50" + }, + { + "address":"0x1ca6abd14d30affe533b24d7a21bff4c2d5e1f3b", + "extraBalanceAccount":"0xb9637156d330c0d605a791f1c31ba5890582fe1c" + }, + { + "address":"0x6131c42fa982e56929107413a9d526fd99405560", + "extraBalanceAccount":"0x1591fc0f688c81fbeb17f5426a162a7024d430c2" + }, + { + "address":"0x542a9515200d14b68e934e9830d91645a980dd7a", + "extraBalanceAccount":"0xc4bbd073882dd2add2424cf47d35213405b01324" + }, + { + "address":"0x782495b7b3355efb2833d56ecb34dc22ad7dfcc4", + "extraBalanceAccount":"0x58b95c9a9d5d26825e70a82b6adb139d3fd829eb" + }, + { + "address":"0x3ba4d81db016dc2890c81f3acec2454bff5aada5", + "extraBalanceAccount":"0xb52042c8ca3f8aa246fa79c3feaa3d959347c0ab" + }, + { + "address":"0xe4ae1efdfc53b73893af49113d8694a057b9c0d1", + "extraBalanceAccount":"0x3c02a7bc0391e86d91b7d144e61c2c01a25a79c5" + }, + { + "address":"0x0737a6b837f97f46ebade41b9bc3e1c509c85c53", + "extraBalanceAccount":"0x97f43a37f595ab5dd318fb46e7a155eae057317a" + }, + { + "address":"0x52c5317c848ba20c7504cb2c8052abd1fde29d03", + "extraBalanceAccount":"0x4863226780fe7c0356454236d3b1c8792785748d" + }, + { + "address":"0x5d2b2e6fcbe3b11d26b525e085ff818dae332479", + "extraBalanceAccount":"0x5f9f3392e9f62f63b8eac0beb55541fc8627f42c" + }, + { + "address":"0x057b56736d32b86616a10f619859c6cd6f59092a", + "extraBalanceAccount":"0x9aa008f65de0b923a2a4f02012ad034a5e2e2192" + }, + { + "address":"0x304a554a310c7e546dfe434669c62820b7d83490", + "extraBalanceAccount":"0x914d1b8b43e92723e64fd0a06f5bdb8dd9b10c79" + }, + { + "address":"0x4deb0033bb26bc534b197e61d19e0733e5679784", + "extraBalanceAccount":"0x07f5c1e1bc2c93e0402f23341973a0e043f7bf8a" + }, + { + "address":"0x35a051a0010aba705c9008d7a7eff6fb88f6ea7b", + "extraBalanceAccount":"0x4fa802324e929786dbda3b8820dc7834e9134a2a" + }, + { + "address":"0x9da397b9e80755301a3b32173283a91c0ef6c87e", + "extraBalanceAccount":"0x8d9edb3054ce5c5774a420ac37ebae0ac02343c6" + }, + { + "address":"0x0101f3be8ebb4bbd39a2e3b9a3639d4259832fd9", + "extraBalanceAccount":"0x5dc28b15dffed94048d73806ce4b7a4612a1d48f" + }, + { + "address":"0xbcf899e6c7d9d5a215ab1e3444c86806fa854c76", + "extraBalanceAccount":"0x12e626b0eebfe86a56d633b9864e389b45dcb260" + }, + { + "address":"0xa2f1ccba9395d7fcb155bba8bc92db9bafaeade7", + "extraBalanceAccount":"0xec8e57756626fdc07c63ad2eafbd28d08e7b0ca5" + }, + { + "address":"0xd164b088bd9108b60d0ca3751da4bceb207b0782", + "extraBalanceAccount":"0x6231b6d0d5e77fe001c2a460bd9584fee60d409b" + }, + { + "address":"0x1cba23d343a983e9b5cfd19496b9a9701ada385f", + "extraBalanceAccount":"0xa82f360a8d3455c5c41366975bde739c37bfeb8a" + }, + { + "address":"0x9fcd2deaff372a39cc679d5c5e4de7bafb0b1339", + "extraBalanceAccount":"0x005f5cee7a43331d5a3d3eec71305925a62f34b6" + }, + { + "address":"0x0e0da70933f4c7849fc0d203f5d1d43b9ae4532d", + "extraBalanceAccount":"0xd131637d5275fd1a68a3200f4ad25c71a2a9522e" + }, + { + "address":"0xbc07118b9ac290e4622f5e77a0853539789effbe", + "extraBalanceAccount":"0x47e7aa56d6bdf3f36be34619660de61275420af8" + }, + { + "address":"0xacd87e28b0c9d1254e868b81cba4cc20d9a32225", + "extraBalanceAccount":"0xadf80daec7ba8dcf15392f1ac611fff65d94f880" + }, + { + "address":"0x5524c55fb03cf21f549444ccbecb664d0acad706", + "extraBalanceAccount":"0x40b803a9abce16f50f36a77ba41180eb90023925" + }, + { + "address":"0xfe24cdd8648121a43a7c86d289be4dd2951ed49f", + "extraBalanceAccount":"0x17802f43a0137c506ba92291391a8a8f207f487d" + }, + { + "address":"0x253488078a4edf4d6f42f113d1e62836a942cf1a", + "extraBalanceAccount":"0x86af3e9626fce1957c82e88cbf04ddf3a2ed7915" + }, + { + "address":"0xb136707642a4ea12fb4bae820f03d2562ebff487", + "extraBalanceAccount":"0xdbe9b615a3ae8709af8b93336ce9b477e4ac0940" + }, + { + "address":"0xf14c14075d6c4ed84b86798af0956deef67365b5", + "extraBalanceAccount":"0xca544e5c4687d109611d0f8f928b53a25af72448" + }, + { + "address":"0xaeeb8ff27288bdabc0fa5ebb731b6f409507516c", + "extraBalanceAccount":"0xcbb9d3703e651b0d496cdefb8b92c25aeb2171f7" + }, + { + "address":"0x6d87578288b6cb5549d5076a207456a1f6a63dc0", + "extraBalanceAccount":"0xb2c6f0dfbb716ac562e2d85d6cb2f8d5ee87603e" + }, + { + "address":"0xaccc230e8a6e5be9160b8cdf2864dd2a001c28b6", + "extraBalanceAccount":"0x2b3455ec7fedf16e646268bf88846bd7a2319bb2" + }, + { + "address":"0x4613f3bca5c44ea06337a9e439fbc6d42e501d0a", + "extraBalanceAccount":"0xd343b217de44030afaa275f54d31a9317c7f441e" + }, + { + "address":"0x84ef4b2357079cd7a7c69fd7a37cd0609a679106", + "extraBalanceAccount":"0xda2fef9e4a3230988ff17df2165440f37e8b1708" + }, + { + "address":"0xf4c64518ea10f995918a454158c6b61407ea345c", + "extraBalanceAccount":"0x7602b46df5390e432ef1c307d4f2c9ff6d65cc97" + }, + { + "address":"0xbb9bc244d798123fde783fcc1c72d3bb8c189413", + "extraBalanceAccount":"0x807640a13483f8ac783c557fcdf27be11ea4ac7a" + }] +})E"; + +dev::Addresses dev::eth::childDaos() +{ + Addresses daos; + json_spirit::mValue val; + json_spirit::read_string(c_childDaos, val); + json_spirit::mObject obj = val.get_obj(); + for(auto const& items: obj) + { + json_spirit::mArray array = items.second.get_array(); + for (auto account: array) + { + daos.push_back(Address(account.get_obj()["address"].get_str())); + daos.push_back(Address(account.get_obj()["extraBalanceAccount"].get_str())); + } + } + return daos; +} + diff --git a/libethereum/GenesisInfo.h b/libethereum/GenesisInfo.h new file mode 100644 index 0000000000..8fa97d5eda --- /dev/null +++ b/libethereum/GenesisInfo.h @@ -0,0 +1,36 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file GenesisInfo.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include + +namespace dev +{ +namespace eth +{ + +extern std::string const c_genesisInfoTestBasicAuthority; +extern dev::Addresses childDaos(); + +} +} diff --git a/libethereum/Interface.cpp b/libethereum/Interface.cpp new file mode 100644 index 0000000000..42a104b5a9 --- /dev/null +++ b/libethereum/Interface.cpp @@ -0,0 +1,64 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Interface.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "Interface.h" +using namespace std; +using namespace dev; +using namespace eth; + +void Interface::submitTransaction(Secret const& _secret, u256 const& _value, Address const& _dest, bytes const& _data, u256 const& _gas, u256 const& _gasPrice, u256 const& _randomid) +{ + TransactionSkeleton ts; + ts.creation = false; + ts.value = _value; + ts.to = _dest; + ts.data = _data; + ts.gas = _gas; + ts.gasPrice = _gasPrice; + ts.randomid = _randomid; + submitTransaction(ts, _secret); +} + +Address Interface::submitTransaction(Secret const& _secret, u256 const& _endowment, bytes const& _init, u256 const& _gas, u256 const& _gasPrice, u256 const& _randomid) +{ + TransactionSkeleton ts; + ts.creation = true; + ts.value = _endowment; + ts.data = _init; + ts.gas = _gas; + ts.gasPrice = _gasPrice; + ts.randomid = _randomid; + return submitTransaction(ts, _secret).second; +} + +BlockHeader Interface::blockInfo(BlockNumber _block) const +{ + if (_block == PendingBlock) + return pendingInfo(); + return blockInfo(hashFromNumber(_block)); +} + +BlockDetails Interface::blockDetails(BlockNumber _block) const +{ + if (_block == PendingBlock) + return pendingDetails(); + return blockDetails(hashFromNumber(_block)); +} diff --git a/libethereum/Interface.h b/libethereum/Interface.h new file mode 100644 index 0000000000..b751aaa074 --- /dev/null +++ b/libethereum/Interface.h @@ -0,0 +1,302 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Interface.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include +#include +#include +#include +#include "GasPricer.h" +#include "LogFilter.h" +#include "Transaction.h" +#include "BlockDetails.h" + +namespace dev +{ +namespace eth +{ + +struct SyncStatus; + +using TransactionHashes = h256s; +using UncleHashes = h256s; + +enum class Reaping +{ + Automatic, + Manual +}; + +enum class FudgeFactor +{ + Strict, + Lenient +}; + +struct GasEstimationProgress +{ + u256 lowerBound; + u256 upperBound; +}; + +using GasEstimationCallback = std::function; +extern const u256 c_maxGasEstimate; + +/** + * @brief Main API hub for interfacing with Ethereum. + */ +class Interface +{ +public: + /// Constructor. + Interface() {} + + /// Destructor. + virtual ~Interface() {} + + // [TRANSACTION API] + + /// Submits a new transaction. + /// @returns the transaction's hash. + virtual std::pair submitTransaction(TransactionSkeleton const& _t, Secret const& _secret) = 0; + + /// Submits the given message-call transaction. + void submitTransaction(Secret const& _secret, u256 const& _value, Address const& _dest, bytes const& _data = bytes(), u256 const& _gas = 1000000, u256 const& _gasPrice = DefaultGasPrice, u256 const& _randomid = Invalid256); + + /// Submits a new contract-creation transaction. + /// @returns the new contract's address (assuming it all goes through). + Address submitTransaction(Secret const& _secret, u256 const& _endowment, bytes const& _init, u256 const& _gas = 1000000, u256 const& _gasPrice = DefaultGasPrice, u256 const& _randomid = Invalid256); + + /// Blocks until all pending transactions have been processed. + virtual void flushTransactions() = 0; + + /// Makes the given call. Nothing is recorded into the state. + virtual ExecutionResult call(Address const& _from, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, FudgeFactor _ff = FudgeFactor::Strict) = 0; + ExecutionResult call(Address const& _from, u256 _value, Address _dest, bytes const& _data = bytes(), u256 _gas = 1000000, u256 _gasPrice = DefaultGasPrice, FudgeFactor _ff = FudgeFactor::Strict) { return call(_from, _value, _dest, _data, _gas, _gasPrice, m_default, _ff); } + ExecutionResult call(Secret const& _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, FudgeFactor _ff = FudgeFactor::Strict) { return call(toAddress(_secret), _value, _dest, _data, _gas, _gasPrice, _blockNumber, _ff); } + ExecutionResult call(Secret const& _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, FudgeFactor _ff = FudgeFactor::Strict) { return call(toAddress(_secret), _value, _dest, _data, _gas, _gasPrice, _ff); } + + /// Does the given creation. Nothing is recorded into the state. + /// @returns the pair of the Address of the created contract together with its code. + virtual ExecutionResult create(Address const& _from, u256 _value, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, FudgeFactor _ff = FudgeFactor::Strict) = 0; + ExecutionResult create(Address const& _from, u256 _value, bytes const& _data = bytes(), u256 _gas = 1000000, u256 _gasPrice = DefaultGasPrice, FudgeFactor _ff = FudgeFactor::Strict) { return create(_from, _value, _data, _gas, _gasPrice, m_default, _ff); } + ExecutionResult create(Secret const& _secret, u256 _value, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, FudgeFactor _ff = FudgeFactor::Strict) { return create(toAddress(_secret), _value, _data, _gas, _gasPrice, _blockNumber, _ff); } + ExecutionResult create(Secret const& _secret, u256 _value, bytes const& _data, u256 _gas, u256 _gasPrice, FudgeFactor _ff = FudgeFactor::Strict) { return create(toAddress(_secret), _value, _data, _gas, _gasPrice, _ff); } + + /// Injects the RLP-encoded transaction given by the _rlp into the transaction queue directly. + virtual ImportResult injectTransaction(bytes const& _rlp, IfDropped _id = IfDropped::Ignore) = 0; + + /// Injects the RLP-encoded block given by the _rlp into the block queue directly. + virtual ImportResult injectBlock(bytes const& _block) = 0; + + /// Estimate gas usage for call/create. + /// @param _maxGas An upper bound value for estimation, if not provided default value of c_maxGasEstimate will be used. + /// @param _callback Optional callback function for progress reporting + virtual std::pair estimateGas(Address const& _from, u256 _value, Address _dest, bytes const& _data, u256 _maxGas, u256 _gasPrice, BlockNumber _blockNumber, GasEstimationCallback const& _callback = GasEstimationCallback()) = 0; + + // [STATE-QUERY API] + + int getDefault() const { return m_default; } + void setDefault(BlockNumber _block) { m_default = _block; } + + u256 balanceAt(Address _a) const { return balanceAt(_a, m_default); } + u256 countAt(Address _a) const { return countAt(_a, m_default); } + u256 stateAt(Address _a, u256 _l) const { return stateAt(_a, _l, m_default); } + bytes codeAt(Address _a) const { return codeAt(_a, m_default); } + h256 codeHashAt(Address _a) const { return codeHashAt(_a, m_default); } + std::map> storageAt(Address _a) const { return storageAt(_a, m_default); } + + virtual u256 balanceAt(Address _a, BlockNumber _block) const = 0; + virtual u256 countAt(Address _a, BlockNumber _block) const = 0; + virtual u256 stateAt(Address _a, u256 _l, BlockNumber _block) const = 0; + virtual h256 stateRootAt(Address _a, BlockNumber _block) const = 0; + virtual bytes codeAt(Address _a, BlockNumber _block) const = 0; + virtual h256 codeHashAt(Address _a, BlockNumber _block) const = 0; + virtual std::map> storageAt(Address _a, BlockNumber _block) const = 0; + + // [LOGS API] + + virtual LocalisedLogEntries logs(unsigned _watchId) const = 0; + virtual LocalisedLogEntries logs(LogFilter const& _filter) const = 0; + + /// Install, uninstall and query watches. + virtual unsigned installWatch(LogFilter const& _filter, Reaping _r = Reaping::Automatic) = 0; + virtual unsigned installWatch(h256 _filterId, Reaping _r = Reaping::Automatic) = 0; + virtual bool uninstallWatch(unsigned _watchId) = 0; + LocalisedLogEntries peekWatchSafe(unsigned _watchId) const { try { return peekWatch(_watchId); } catch (...) { return LocalisedLogEntries(); } } + LocalisedLogEntries checkWatchSafe(unsigned _watchId) { try { return checkWatch(_watchId); } catch (...) { return LocalisedLogEntries(); } } + virtual LocalisedLogEntries peekWatch(unsigned _watchId) const = 0; + virtual LocalisedLogEntries checkWatch(unsigned _watchId) = 0; + + // [BLOCK QUERY API] + + virtual bool isKnownTransaction(h256 const& _transactionHash) const = 0; + virtual bool isKnownTransaction(h256 const& _blockHash, unsigned _i) const = 0; + virtual Transaction transaction(h256 _transactionHash) const = 0; + virtual LocalisedTransaction localisedTransaction(h256 const& _transactionHash) const = 0; + virtual TransactionReceipt transactionReceipt(h256 const& _transactionHash) const = 0; + virtual LocalisedTransactionReceipt localisedTransactionReceipt(h256 const& _transactionHash) const = 0; + virtual std::pair transactionLocation(h256 const& _transactionHash) const = 0; + virtual h256 hashFromNumber(BlockNumber _number) const = 0; + virtual BlockNumber numberFromHash(h256 _blockHash) const = 0; + virtual int compareBlockHashes(h256 _h1, h256 _h2) const = 0; + + virtual bool isKnown(BlockNumber _block) const = 0; + virtual bool isKnown(h256 const& _hash) const = 0; + virtual BlockHeader blockInfo(h256 _hash) const = 0; + virtual BlockDetails blockDetails(h256 _hash) const = 0; + virtual Transaction transaction(h256 _blockHash, unsigned _i) const = 0; + virtual LocalisedTransaction localisedTransaction(h256 const& _blockHash, unsigned _i) const = 0; + virtual BlockHeader uncle(h256 _blockHash, unsigned _i) const = 0; + virtual UncleHashes uncleHashes(h256 _blockHash) const = 0; + virtual unsigned transactionCount(h256 _blockHash) const = 0; + virtual unsigned uncleCount(h256 _blockHash) const = 0; + virtual Transactions transactions(h256 _blockHash) const = 0; + virtual TransactionHashes transactionHashes(h256 _blockHash) const = 0; + + virtual BlockHeader pendingInfo() const { return BlockHeader(); } + virtual BlockDetails pendingDetails() const { return BlockDetails(); } + /// @returns the EVMSchedule in the context of the pending block. + virtual EVMSchedule evmSchedule() const { return EVMSchedule(); } + + BlockHeader blockInfo(BlockNumber _block) const; + BlockDetails blockDetails(BlockNumber _block) const; + Transaction transaction(BlockNumber _block, unsigned _i) const { auto p = transactions(_block); return _i < p.size() ? p[_i] : Transaction(); } + unsigned transactionCount(BlockNumber _block) const { if (_block == PendingBlock) { auto p = pending(); return p.size(); } return transactionCount(hashFromNumber(_block)); } + Transactions transactions(BlockNumber _block) const { if (_block == PendingBlock) return pending(); return transactions(hashFromNumber(_block)); } + TransactionHashes transactionHashes(BlockNumber _block) const { if (_block == PendingBlock) return pendingHashes(); return transactionHashes(hashFromNumber(_block)); } + BlockHeader uncle(BlockNumber _block, unsigned _i) const { return uncle(hashFromNumber(_block), _i); } + UncleHashes uncleHashes(BlockNumber _block) const { return uncleHashes(hashFromNumber(_block)); } + unsigned uncleCount(BlockNumber _block) const { return uncleCount(hashFromNumber(_block)); } + + // [EXTRA API]: + + /// @returns The height of the chain. + virtual unsigned number() const = 0; + + /// Get a map containing each of the pending transactions. + /// @TODO: Remove in favour of transactions(). + virtual Transactions pending() const = 0; + virtual h256s pendingHashes() const = 0; + + /// Get a list of all active addresses. + /// NOTE: This only works when compiled with ETH_FATDB; otherwise will throw InterfaceNotSupported. + virtual Addresses addresses() const { return addresses(m_default); } + virtual Addresses addresses(BlockNumber _block) const = 0; + + /// Get the remaining gas limit in this block. + virtual u256 gasLimitRemaining() const = 0; + // Get the gas bidding price + virtual u256 gasBidPrice() const = 0; + + /// Get some information on the block queue. + virtual SyncStatus syncStatus() const = 0; + + // [SEALING API]: + + /// Set the block author address. + virtual void setAuthor(Address const& _us) = 0; + /// Get the block author address. + virtual Address author() const = 0; + + /// Start sealing. + /// NOT thread-safe - call it & stopSealing only from a single thread + virtual void startSealing() = 0; + /// Stop sealing. + /// NOT thread-safe + virtual void stopSealing() = 0; + /// Would we like to be sealing now? + virtual bool wouldSeal() const = 0; + + /// Are we updating the chain (syncing or importing a new block)? + virtual bool isSyncing() const { return false; } + /// Are we syncing the chain? + virtual bool isMajorSyncing() const { return false; } + + /// Gets the network id. + virtual u256 networkId() const { return 0; } + /// Sets the network id. + virtual void setNetworkId(u256 const&) {} + + /// Get the seal engine. + virtual SealEngineFace* sealEngine() const { return nullptr; } + + virtual bool isNonceOk(Transaction const&_ts) const = 0; + virtual bool isBlockLimitOk(Transaction const&_ts) const = 0; + + virtual u256 filterCheck(const Transaction & _t,FilterCheckScene _checkscene=FilterCheckScene::None) const =0; + virtual void updateSystemContract(std::shared_ptr) =0; + + virtual void updateCache(Address ){} + + + + +protected: + int m_default = PendingBlock; +}; + +class Watch; + +} +} + +namespace std { void swap(dev::eth::Watch& _a, dev::eth::Watch& _b); } + +namespace dev +{ +namespace eth +{ + +class Watch: public boost::noncopyable +{ + friend void std::swap(Watch& _a, Watch& _b); + +public: + Watch() {} + Watch(Interface& _c, h256 _f): m_c(&_c), m_id(_c.installWatch(_f)) {} + Watch(Interface& _c, LogFilter const& _tf): m_c(&_c), m_id(_c.installWatch(_tf)) {} + ~Watch() { if (m_c) m_c->uninstallWatch(m_id); } + + LocalisedLogEntries check() { return m_c ? m_c->checkWatch(m_id) : LocalisedLogEntries(); } + LocalisedLogEntries peek() { return m_c ? m_c->peekWatch(m_id) : LocalisedLogEntries(); } + LocalisedLogEntries logs() const { return m_c->logs(m_id); } + +private: + Interface* m_c = nullptr; + unsigned m_id = 0; +}; + +} +} + +namespace std +{ + +inline void swap(dev::eth::Watch& _a, dev::eth::Watch& _b) +{ + swap(_a.m_c, _b.m_c); + swap(_a.m_id, _b.m_id); +} + +} diff --git a/libethereum/LogFilter.cpp b/libethereum/LogFilter.cpp new file mode 100644 index 0000000000..723e940e07 --- /dev/null +++ b/libethereum/LogFilter.cpp @@ -0,0 +1,166 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file LogFilter.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "LogFilter.h" + +#include +#include "Block.h" +using namespace std; +using namespace dev; +using namespace dev::eth; + +std::ostream& dev::eth::operator<<(std::ostream& _out, LogFilter const& _s) +{ + // TODO + _out << "(@" << _s.m_addresses << "#" << _s.m_topics << ">" << _s.m_earliest << "-" << _s.m_latest << "< )"; + return _out; +} + +void LogFilter::streamRLP(RLPStream& _s) const +{ + _s.appendList(4) << m_addresses << m_topics << m_earliest << m_latest; +} + +h256 LogFilter::sha3() const +{ + RLPStream s; + streamRLP(s); + return dev::sha3(s.out()); +} + +bool LogFilter::isRangeFilter() const +{ + if (m_addresses.size()) + return false; + + for (auto const& t: m_topics) + if (t.size()) + return false; + + return true; +} + +bool LogFilter::matches(LogBloom _bloom) const +{ + if (m_addresses.size()) + { + for (auto const& i: m_addresses) + if (_bloom.containsBloom<3>(dev::sha3(i))) + goto OK1; + return false; + } + OK1: + for (auto const& t: m_topics) + if (t.size()) + { + for (auto const& i: t) + if (_bloom.containsBloom<3>(dev::sha3(i))) + goto OK2; + return false; + OK2:; + } + return true; +} + +bool LogFilter::matches(Block const& _s, unsigned _i) const +{ + return matches(_s.receipt(_i)).size() > 0; +} + +vector LogFilter::bloomPossibilities() const +{ + // return combination of each of the addresses/topics + vector ret; + + // | every address with every topic + for (auto const& i: m_addresses) + { + // 1st case, there are addresses and topics + // + // m_addresses = [a0, a1]; + // m_topics = [[t0], [t1a, t1b], [], []]; + // + // blooms = [ + // a0 | t0, a0 | t1a | t1b, + // a1 | t0, a1 | t1a | t1b + // ] + // + for (auto const& t: m_topics) + if (t.size()) + { + LogBloom b = LogBloom().shiftBloom<3>(dev::sha3(i)); + for (auto const &j: t) + b = b.shiftBloom<3>(dev::sha3(j)); + ret.push_back(b); + } + } + + // 2nd case, there are no topics + // + // m_addresses = [a0, a1]; + // m_topics = [[t0], [t1a, t1b], [], []]; + // + // blooms = [a0, a1]; + // + if (!ret.size()) + for (auto const& i: m_addresses) + ret.push_back(LogBloom().shiftBloom<3>(dev::sha3(i))); + + // 3rd case, there are no addresses, at least create blooms from topics + // + // m_addresses = []; + // m_topics = [[t0], [t1a, t1b], [], []]; + // + // blooms = [t0, t1a | t1b]; + // + if (!m_addresses.size()) + for (auto const& t: m_topics) + if (t.size()) + { + LogBloom b; + for (auto const &j: t) + b = b.shiftBloom<3>(dev::sha3(j)); + ret.push_back(b); + } + + return ret; +} + +LogEntries LogFilter::matches(TransactionReceipt const& _m) const +{ + // there are no addresses or topics to filter + if (isRangeFilter()) + return _m.log(); + + LogEntries ret; + if (matches(_m.bloom())) + for (LogEntry const& e: _m.log()) + { + if (!m_addresses.empty() && !m_addresses.count(e.address)) + goto continue2; + for (unsigned i = 0; i < 4; ++i) + if (!m_topics[i].empty() && (e.topics.size() < i || !m_topics[i].count(e.topics[i]))) + goto continue2; + ret.push_back(e); + continue2:; + } + return ret; +} diff --git a/libethereum/LogFilter.h b/libethereum/LogFilter.h new file mode 100644 index 0000000000..aca014df3c --- /dev/null +++ b/libethereum/LogFilter.h @@ -0,0 +1,92 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file LogFilter.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include +#include +#include "TransactionReceipt.h" + +#ifdef __INTEL_COMPILER +#pragma warning(disable:1098) //the qualifier on this friend declaration is ignored +#endif + +namespace dev +{ + +namespace eth +{ +class LogFilter; +} + +namespace eth +{ + +/// Simple stream output for the StateDiff. +std::ostream& operator<<(std::ostream& _out, dev::eth::LogFilter const& _s); + +class State; +class Block; + +class LogFilter +{ +public: + LogFilter(h256 _earliest = EarliestBlockHash, h256 _latest = PendingBlockHash): m_earliest(_earliest), m_latest(_latest) {} + + void streamRLP(RLPStream& _s) const; + h256 sha3() const; + + /// hash of earliest block which should be filtered + h256 earliest() const { return m_earliest; } + + /// hash of latest block which should be filtered + h256 latest() const { return m_latest; } + + /// Range filter is a filter which doesn't care about addresses or topics + /// Matches are all entries from earliest to latest + /// @returns true if addresses and topics are unspecified + bool isRangeFilter() const; + + /// @returns bloom possibilities for all addresses and topics + std::vector bloomPossibilities() const; + + bool matches(LogBloom _bloom) const; + bool matches(Block const& _b, unsigned _i) const; + LogEntries matches(TransactionReceipt const& _r) const; + + LogFilter address(Address _a) { m_addresses.insert(_a); return *this; } + LogFilter topic(unsigned _index, h256 const& _t) { if (_index < 4) m_topics[_index].insert(_t); return *this; } + LogFilter withEarliest(h256 _e) { m_earliest = _e; return *this; } + LogFilter withLatest(h256 _e) { m_latest = _e; return *this; } + + friend std::ostream& dev::eth::operator<<(std::ostream& _out, dev::eth::LogFilter const& _s); + +private: + AddressHash m_addresses; + std::array m_topics; + h256 m_earliest = EarliestBlockHash; + h256 m_latest = PendingBlockHash; +}; + +} + +} diff --git a/libethereum/MiningClient.cpp b/libethereum/MiningClient.cpp new file mode 100644 index 0000000000..81e67841f6 --- /dev/null +++ b/libethereum/MiningClient.cpp @@ -0,0 +1,22 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file MiningClient.cpp + * @author Gav Wood + * @date 2015 + */ + +#include "MiningClient.h" diff --git a/libethereum/MiningClient.h b/libethereum/MiningClient.h new file mode 100644 index 0000000000..6d473481e0 --- /dev/null +++ b/libethereum/MiningClient.h @@ -0,0 +1,32 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file M=iningClient.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include "Client.h" + +namespace dev +{ +namespace eth +{ +} +} diff --git a/libethereum/NodeConnParamsManager.cpp b/libethereum/NodeConnParamsManager.cpp new file mode 100644 index 0000000000..b7c2b85b65 --- /dev/null +++ b/libethereum/NodeConnParamsManager.cpp @@ -0,0 +1,927 @@ + +#include +#include +#include +#include +#include +#include + +#include "EthereumHost.h" +#include "NodeConnParamsManager.h" +#include "SystemContractApi.h" + +#include "libdevcore/Hash.h" +#include +#include "libdevcrypto/Rsa.h" +#include + +using namespace std; +using namespace dev; +using namespace eth; +namespace js = json_spirit; + + + +NodeConnParams::NodeConnParams(const std::string & json) +{ + try { + js::mValue val; + js::read_string(json, val); + js::mObject jsObj = val.get_obj(); + _sNodeId = jsObj["Nodeid"].get_str(); + _sAgencyInfo = jsObj["Agencyinfo"].get_str(); + _sIP = jsObj["Peerip"].get_str(); + _iPort = jsObj["Port"].get_int(); + _iIdentityType = jsObj["Identitytype"].get_int(); + _sAgencyDesc = jsObj["Nodedesc"].get_str(); + _iIdx = jsObj["Idx"].get_int(); + } + catch (...) + { + LOG(INFO) << "NodeConnParams format error: " << json << std::endl; + } +} + +/** + 读取节点连接配置 + */ +NodeConnParamsManager::NodeConnParamsManager(std::string const& _json) +{ + + if (_json == "") { + return; + } + _sConfig = _json; + js::mValue val; + js::read_string(_sConfig, val); + js::mObject obj = val.get_obj(); + + + //读取连接的节点信息 + for (auto node : obj["NodeextraInfo"].get_array()) { + NodeConnParams nodeConnParam; + + nodeConnParam._sNodeId = node.get_obj()["Nodeid"].get_str(); + nodeConnParam._sAgencyInfo = node.get_obj()["Agencyinfo"].get_str(); + nodeConnParam._sIP = node.get_obj()["Peerip"].get_str(); + nodeConnParam._iPort = node.get_obj()["Port"].get_int(); + nodeConnParam._iIdentityType = node.get_obj()["Identitytype"].get_int(); + nodeConnParam._sAgencyDesc = node.get_obj()["Nodedesc"].get_str(); + nodeConnParam._iIdx = u256(node.get_obj()["Idx"].get_int()); + + _mConfNodeConnParams[nodeConnParam._sNodeId] = nodeConnParam; + + _mNodeConnParams[nodeConnParam._sNodeId] = nodeConnParam; + } + + LOG(INFO) << "loadNodeConnParams _mConfNodeConnParams size is : " << _mConfNodeConnParams.size() << std::endl; + + //读取共识需要的节点数据 + //从合约里面取一次 修改共识的节点数据 + if (_pSysContractApi != nullptr) { + callSysContractData(-1); + } + + LOG(INFO) << "loadNodeConnParams _mNodeConnParams size is : " << _mNodeConnParams.size() << std::endl; + +} + +bool NodeConnParamsManager::CAVerify = false; + +//设置sysEthereumApi 同时设置回调函数 +void NodeConnParamsManager::setSysContractApi(std::shared_ptr sysContractApi) +{ + //如果为空这设置 + if (_pSysContractApi == nullptr) + { + _pSysContractApi = sysContractApi; + + //注册回调 + _pSysContractApi->addCBOn("node", [ = ](string) { + LOG(TRACE) << "receive systemcontract node call"; + //LOG(INFO) << "receive systemcontract node call" << std::endl; + callSysContractData(-1); + }); + + //CA callback + _pSysContractApi->addCBOn("ca", [=](string pub256) { + LOG(TRACE) << "receive systemcontract node call"; + //LOG(INFO) << "receive systemcontract CA callback" << std::endl; + CAInfoModifyCallback(pub256); + }); + + //CA verify callback + _pSysContractApi->addCBOn("config", [=](string) { + LOG(TRACE) << "receive systemcontract node call"; + //LOG(INFO) << "receive systemcontract CA callback" << std::endl; + CAVerifyModifyCallback(); + }); + + callSysContractData(-1); + } +} + +void NodeConnParamsManager::callSysContractData(int const& blockNum) +{ + std::vector< NodeConnParams> vNodeParams; + //默认获取最高块 + _pSysContractApi->getAllNode(blockNum, vNodeParams); + LOG(TRACE) << "call systemcontract get all Nodes size is " << vNodeParams.size() << ".block is " << blockNum; + + //如果取出数据就使用该数据 + if (vNodeParams.size() > 0 && checkNodesValid(vNodeParams)) + { + + std::vector< NodeConnParams> vAddNodes; + std::vector< NodeConnParams> vDelNodes; + + { + //更新内存数据,不存在的节点进行断连,新加节点进行连接 + //和共识节点数据进行比较 如果有变化则修改共识节点的数据 + Guard l(_xNodeConnParam); + diffNodes(vNodeParams, vAddNodes, vDelNodes); + if( vNodeParams.size() > 0 ) + { + + LOG(INFO) << "call systemcontract diff nodes. add nodes size is " << vAddNodes.size() << ".del nodes size is " << vDelNodes.size() << std::endl; + //设置合约内的节点数据 + _mNodeConnParams.clear(); + for (auto stNode : vNodeParams) + { + _mNodeConnParams[stNode._sNodeId] = stNode; + } + } + } + + { + //判断节点是否在配置文件中 如果节点在配置文件中 则不进行断连 因为配置文件还允许连接 + //断掉删除的节点 + std::map mNodeConnParams; + NodeConnParamsManagerApi::getAllConfNodeConnInfo(mNodeConnParams); + for (auto stDelNode : vDelNodes) + { + if (mNodeConnParams.find(stDelNode._sNodeId) == mNodeConnParams.end()) + { + disconnNode(stDelNode._sNodeId); + } + } + + //判断节点是否在配置文件中 如果节点在配置文件中 则不进行新的连接 因为已经有连接呢 + //连接新节点 + for (auto stAddNode : vAddNodes) + { + if (mNodeConnParams.find(stAddNode._sNodeId) == mNodeConnParams.end()) + { + connNode(stAddNode); + } + } + } + } +} + +//检查节点是否连续 +/* + 检查条件 + 1、idx从0开始 + 2、idx是连续的 + 3、前面是记账者节点,后面是非记账节点 + ps : 数据出来时保证 idx是递增的,例如1.5.9 + */ +bool NodeConnParamsManager::checkNodesValid(const std::vector< NodeConnParams> &vNodes) +{ + bool rRet = false; + if (vNodes.size() == 0) + { + return rRet; + } + + //从0开始 + int i = 0; + bool bContinuous = true; + dev::u256 iMaxSignNodeIdx = -1; + dev::u256 iMaxNotSignNodeIdx = -1; + for (auto node : vNodes) + { + LOG(INFO) << "checkNodesValid : " << node.toString() << std::endl; + if (node._iIdx != i) + { + bContinuous = false; + break; + } + i++; + + //用枚举 + if (node._iIdentityType == AccountType::EN_ACCOUNT_TYPE_MINER) + { + iMaxSignNodeIdx = node._iIdx; + } + else { + iMaxNotSignNodeIdx = node._iIdx; + } + } + if (!bContinuous) + { + return rRet; + } + + if (iMaxSignNodeIdx < iMaxNotSignNodeIdx || iMaxNotSignNodeIdx == -1) + { + rRet = true; + } + + LOG(INFO) << "checkNodesValid is " << rRet << std::endl; + return rRet; +} + + +//不支持修改数据, 即不支持重复数据 +bool NodeConnParamsManager::diffNodes(const std::vector< NodeConnParams> &vNodeParams, std::vector< NodeConnParams> &vAddNodes, std::vector< NodeConnParams> &vDelNodes) +{ + if (vNodeParams.size() == 0) + { + return false; + } + + std::map mTmpNode; + //找到新节点 + for (auto stNewNode : vNodeParams) + { + if (_mNodeConnParams.find(stNewNode._sNodeId) == _mNodeConnParams.end()) + { + vAddNodes.push_back(stNewNode); + } + mTmpNode[stNewNode._sNodeId] = stNewNode; + } + + //找到不存在的节点 + for (auto stOldNode : _mNodeConnParams) + { + if (mTmpNode.find(stOldNode.first) == mTmpNode.end()) + { + vDelNodes.push_back(stOldNode.second); + } + } + + return vAddNodes.size() > 0 || vDelNodes.size() > 0; +} +std::pair > NodeConnParamsManager::getGodMiner(int blockNum)const +{ + std::map temp; + + if( _chainParams.godMinerStart > 0 )//开启了上帝模式 + { + u256 lastBlockNumber=blockNum; + if (blockNum < 0) + { + lastBlockNumber=_pSysContractApi->getBlockChainNumber(); + } + + if( ( lastBlockNumber >=(_chainParams.godMinerStart-1) ) && ( lastBlockNumber <_chainParams.godMinerEnd) ) + { + clog(NodeConnManageNote)<<" getAllNodeConnInfo lastBlockNumber="< & mNodeConnParams) const +{ + LOG(TRACE)<<"NodeConnParamsManager::getAllNodeConnInfo="< > checkGodMiner=getGodMiner(blockNum); + if( checkGodMiner.first == true ) + { + mNodeConnParams=checkGodMiner.second; + return; + } + + if (blockNum < 0) { + NodeConnParamsManagerApi::getAllNodeConnInfoContract(mNodeConnParams); + } + else { + std::vector vNodeParams; + //默认获取最高块 + //创世块中一定有数据 不考虑为空的情况 + _pSysContractApi->getAllNode(blockNum, vNodeParams); + LOG(TRACE)<<"_pSysContractApi->getAllNode= "< 0) + { + for (auto node : vNodeParams) + { + mNodeConnParams[node._sNodeId] = node; + } + } + else + { + //NodeConnParamsManagerApi::getAllNodeConnInfoContract(mNodeConnParams); + int idx = 0; + for (auto nodeid : _vInitIdentityNodes) + { + NodeConnParams node; + node._sNodeId = nodeid; + node._iIdx = idx++; + node._iIdentityType = 1; // 默认这里的都是记账节点 + mNodeConnParams[nodeid] = node; + } + } + } +} + +//增加新的节点配置 +bool NodeConnParamsManager::addNewNodeConnInfo(const std::string &_json) +{ + bool bRet = false; + if (_json == "") + { + return bRet; + } + + js::mValue val; + js::read_string(_json, val); + js::mObject obj = val.get_obj(); + + NodeConnParams nodeConnParam; + nodeConnParam._sNodeId = obj["Nodeid"].get_str(); + nodeConnParam._sAgencyInfo = obj["Agencyinfo"].get_str(); + nodeConnParam._sIP = obj["Peerip"].get_str(); + nodeConnParam._iPort = obj["Port"].get_int(); + nodeConnParam._iIdentityType = obj["Identitytype"].get_int(); + nodeConnParam._sAgencyDesc = obj["Nodedesc"].get_str(); + nodeConnParam._iIdx = obj["Idx"].get_int(); + + Guard l(_xConfigNodeConnParam); + if (_mConfNodeConnParams.find(nodeConnParam._sNodeId) != _mConfNodeConnParams.end()) + { + if (!(_mConfNodeConnParams[nodeConnParam._sNodeId] == nodeConnParam)) + { + LOG(INFO) << "new param existed .but not the same . old is " << _mConfNodeConnParams[nodeConnParam._sNodeId].toString() << "| new is " << nodeConnParam.toString() << std::endl; + } + } + else + { + _mConfNodeConnParams[nodeConnParam._sNodeId] = nodeConnParam; + writeNodeFile(); + bRet = true; + } + + return bRet; +} + +//增加新的节点配置 +bool NodeConnParamsManager::addNewNodeConnInfo(const NodeConnParams &nodeParam) +{ + Guard l(_xConfigNodeConnParam); + if (_mConfNodeConnParams.find(nodeParam._sNodeId) == _mConfNodeConnParams.end()) + { + _mConfNodeConnParams[nodeParam._sNodeId] = nodeParam; + + writeNodeFile(); + } + + return true; +} + +//发送配置同步请求 +void NodeConnParamsManager::sendNodeInfoSync(const std::vector &vParams) +{ + if (vParams.size() == 0 || _pHost == nullptr) + { + return; + } + LOG(INFO) << "sendNodeInfoSync " << vParams.size() << std::endl; + //增加节点配置 + _pHost->addNodeConnParam(vParams); +} + +//进行节点连接 +void NodeConnParamsManager::connNode(const NodeConnParams ¶m) +{ + LOG(TRACE)<<"NodeConnParamsManager::connNode"<delNodeConnParam(sNodeId); +} + +//删除节点信息 删除config.json中的数据 并落地 +void NodeConnParamsManager::delNodeConnInfo(const std::string &sNodeId, bool &bExisted) +{ + bExisted = false; + Guard l(_xConfigNodeConnParam); + if (_mConfNodeConnParams.find(sNodeId) != _mConfNodeConnParams.end()) + { + LOG(INFO) << "NodeConnParamsManager::delNodeConnInfo del node :" << sNodeId << std::endl; + + auto ite = _mConfNodeConnParams.find(sNodeId); + _mConfNodeConnParams.erase(ite); + writeNodeFile(); + bExisted = true; + } + else + { + LOG(INFO) << "NodeConnParamsManager::delNodeConnInfo no node : " << sNodeId << std::endl; + } +} + +//写节点文件 +void NodeConnParamsManager::writeNodeFile() +{ + Json::Value resConn; + Json::Reader reader; + if (reader.parse(_sConfig, resConn)) + { + resConn.removeMember("NodeextraInfo"); + resConn["NodeextraInfo"] = Json::Value(Json::arrayValue); + + for (auto const & param : _mConfNodeConnParams) + { + Json::Value res; + res["Nodeid"] = param.second._sNodeId; + res["Agencyinfo"] = param.second._sAgencyInfo; + res["Peerip"] = param.second._sIP; + res["Port"] = param.second._iPort; + res["Identitytype"] = param.second._iIdentityType; + res["Nodedesc"] = param.second._sAgencyDesc; + res["Idx"] = static_cast(param.second._iIdx); + resConn["NodeextraInfo"].append(res); + } + + writeFile(getConfigPath(), resConn.toStyledString()); + LOG(INFO) << "writeNodeFile succ" << std::endl; + } + +} + +//断掉连接 +void NodeConnParamsManager::disconnNode(const std::string & sNodeId) +{ + if (_pNetwork == nullptr || sNodeId == "") + { + return; + } + + LOG(INFO) << "disconnNode node id is " << sNodeId << std::endl; + try { + _pNetwork->disconnectByNodeId(sNodeId); + } + catch (...) + { + LOG(ERROR) << "NodeConnParamsManager::connNode network disconnect error. enode is " << sNodeId << std::endl; + } +} + +//-------------------------共识需要下面的接口(数据全部从共识中取) start--------------------------------------// +bool NodeConnParamsManager::getPublicKey(u256 const& _idx, Public & _pub) const { + std::pair > checkGodMiner=getGodMiner(-1); + if( checkGodMiner.first == true )//上帝模式 + { + for (auto iter = checkGodMiner.second.begin(); iter != checkGodMiner.second.end(); ++iter) { + if (iter->second._iIdx == _idx) { + _pub = jsToPublic(toJS(iter->second._sNodeId)); + return true; + } + } + return false; + } + else + { + Guard l(_xNodeConnParam); + for (auto iter = _mNodeConnParams.begin(); iter != _mNodeConnParams.end(); ++iter) { + if (iter->second._iIdx == _idx) { + _pub = jsToPublic(toJS(iter->second._sNodeId)); + return true; + } + } + return false; + } +} + +bool NodeConnParamsManager::getIdx(p2p::NodeID const& _nodeId, u256 &_idx) const { + std::pair > checkGodMiner=getGodMiner(-1); + if( checkGodMiner.first == true )//上帝模式 + { + auto iter = checkGodMiner.second.find(_nodeId.hex()); + if (iter != checkGodMiner.second.end()) { + _idx = iter->second._iIdx; + return true; + } + return false; + } + else + { + Guard l(_xNodeConnParam); + auto iter = _mNodeConnParams.find(_nodeId.hex()); + if (iter != _mNodeConnParams.end()) { + _idx = iter->second._iIdx; + return true; + } + return false; + } +} + +unsigned NodeConnParamsManager::getMinerNum() const { + std::pair > checkGodMiner=getGodMiner(-1); + if( checkGodMiner.first == true )//上帝模式 + { + unsigned count = 0; + for (auto iter = checkGodMiner.second.begin(); iter != checkGodMiner.second.end(); ++iter) { + if (iter->second._iIdentityType == EN_ACCOUNT_TYPE_MINER) { + ++count; + } + } + return count; + } + else + { + Guard l(_xNodeConnParam); + unsigned count = 0; + for (auto iter = _mNodeConnParams.begin(); iter != _mNodeConnParams.end(); ++iter) { + if (iter->second._iIdentityType == EN_ACCOUNT_TYPE_MINER) { + ++count; + } + } + return count; + } +} + +bool NodeConnParamsManager::getAccountType(p2p::NodeID const& _nodeId, unsigned & _type) const { + std::pair > checkGodMiner=getGodMiner(-1); + if( checkGodMiner.first == true )//上帝模式 + { + std::string _nodeIdStr = _nodeId.hex(); + auto iter = checkGodMiner.second.find(_nodeId.hex()); + if (iter != checkGodMiner.second.end()) { + _type = iter->second._iIdentityType; + return true; + } + return false; + } + else + { + Guard l(_xNodeConnParam); + std::string _nodeIdStr = _nodeId.hex(); + auto iter = _mNodeConnParams.find(_nodeId.hex()); + if (iter != _mNodeConnParams.end()) { + _type = iter->second._iIdentityType; + return true; + } + return false; + } +} + +unsigned NodeConnParamsManager::getNodeNum() const { + std::pair > checkGodMiner=getGodMiner(-1); + if( checkGodMiner.first == true )//上帝模式 + { + return checkGodMiner.second.size(); + } + else + { + Guard l(_xNodeConnParam); + return _mNodeConnParams.size(); + } +} + + + +//签名验证的数据全部从两边数据中读取 +bool NodeConnParamsManager::signNodeInfo(CABaseData & caBaseData) +{ + try{ + eth::NodeConnParams stNodeConnParam; + std::string sNodeId = m_host->id().hex(); + if (!getNodeConnInfoBoth(sNodeId, stNodeConnParam)) + { + LOG(INFO) << "No NodeConninfo (" << sNodeId << ")." << std::endl; + return false; + } + //crypto Common中进行加密 + RLPStream _rlps; + _rlps.appendList(3) << stNodeConnParam._sNodeId << stNodeConnParam._sAgencyInfo << stNodeConnParam._sIP; + auto hash = dev::sha3(_rlps.out()); + LOG(INFO) << " getSelfSignData hash is " << hash << "|nodeid is " << stNodeConnParam._sNodeId << "|agenceinfo is " << stNodeConnParam._sAgencyInfo << "|ip is " << stNodeConnParam._sIP << std::endl; + caBaseData.setNodeSign(sign(m_host->sec(), hash)); + return true; + } + catch (...) + { + LOG(INFO) << "getSelfSignData throws exceptions. nodeId is " << m_host->id().hex() << std::endl; + } + return false; +} + +bool NodeConnParamsManager::signCAInfo(std::string seedStr, CABaseData & caBaseData) +{ + try + { + std::string privateKeyFile = getDataDir() + "/CA/private.key"; + std::string pubFile = getDataDir() + "/CA/public.key"; + std::ifstream pubFileStream(pubFile.c_str()); + std::ifstream privateFileStream(privateKeyFile.c_str()); + if (pubFileStream.is_open() && privateFileStream.is_open()) + { + std::string signMsg = dev::crypto::RSAKeySign(privateKeyFile, seedStr); + if (signMsg.empty()) + { + LOG(INFO) << "RSAKeySign failed!" << std::endl; + return false; + } + + std::string content((std::istreambuf_iterator(pubFileStream)), std::istreambuf_iterator()); + pubFileStream.close(); + privateFileStream.close(); + bytes tmp1(content.begin(), content.end()); + bytesConstRef bcr(tmp1.data(), tmp1.size()); + std::string hexStr = dev::sha256(bcr).hex(); + + caBaseData.setSeed(seedStr); + caBaseData.setPub256(hexStr); + caBaseData.setSign(signMsg); + } + } catch(...) + { + LOG(ERROR) << "catch exception in RSAKeySign" << std::endl; + } + + return true; +} + +bool NodeConnParamsManager::checkNodeInfo(std::string remoteNodeID, CABaseData & caBaseData) +{ + bool bRet = false; + std::string sEndPointNodeId = remoteNodeID; + LOG(INFO) << " checkNodeConnInfo nodeid is " << sEndPointNodeId << "| sign is " << caBaseData.getNodeSign() << std::endl; + //获取对端节点信息(从合约还有配置文件中取) + NodeConnParams stNodeConnParam; + if (!getNodeConnInfoBoth(sEndPointNodeId, stNodeConnParam)) + { + LOG(INFO) << "No NodeConninfo (" << sEndPointNodeId << ")." << std::endl; + return bRet; + } + + //对数据进行hash + RLPStream _rlps; + _rlps.appendList(3) << stNodeConnParam._sNodeId << stNodeConnParam._sAgencyInfo << stNodeConnParam._sIP; + auto hash = dev::sha3(_rlps.out()); + + LOG(INFO) << "checkNodeConnInfo hash is " << hash << "|" << stNodeConnParam._sNodeId << "|" << stNodeConnParam._sAgencyInfo << "|" << stNodeConnParam._sIP << std::endl; + //用公钥进行解析 + //判断数据是否一致 + if (!verify(Public(sEndPointNodeId), caBaseData.getNodeSign(), hash)) + { + LOG(INFO) << "Sign error. (" << sEndPointNodeId << ") sSign is " << caBaseData.getNodeSign() << "." << std::endl; + return bRet; + } + + bRet = true; + return bRet; +} + +bool NodeConnParamsManager::checkIP(std::string remoteNodeID, CaInfo &caInfo) +{ + eth::NodeConnParams params; + bool found = getNodeConnInfoBoth(remoteNodeID, params); + if (!found) + { + LOG(INFO) << "not found params in getNodeConnInfo,remoteNodeID:" << remoteNodeID << std::endl; + return false; + } + std::string remoteIp = params._sIP; + + if (!caInfo.black.empty()) + { + for(std::string blackIp : caInfo.getBlackList()) + { + if (blackIp == remoteIp) + { + LOG(INFO) << "remoteIp is in black list.remoteIp:" << remoteIp << std::endl; + return false; + } + } + } + + if (!caInfo.white.empty()) + { + found = false; + for(std::string whiteIp : caInfo.getWhiteList()) + { + if (whiteIp == remoteIp) + { + found = true; + break; + } + } + + if (!found) + { + LOG(INFO) << "remoteIp is not in white list.remoteIp:" << remoteIp << std::endl; + return false; + } + } + + return true; +} + +bool NodeConnParamsManager::checkCA(std::string remoteNodeID, CABaseData & caBaseData) +{ + bool caVerify = eth::NodeConnParamsManager::CAVerify; + if (!caVerify) + { + //没有开启,统一返回true + LOG(INFO) << "CAVerify is false." << std::endl; + return true; + } + + std::string seedStr = caBaseData.getSeed(); + if (seedStr.empty()) + { + LOG(INFO) << "seedStr is empty.remoteNodeID:" << remoteNodeID << std::endl; + return false; + } + + std::string pub256 = caBaseData.getPub256(); + std::string sign = caBaseData.getSign(); + if (pub256.empty() || sign.empty()) + { + LOG(INFO) << "pub256 or sign is empty." << std::endl; + return false; + } + + + eth::CaInfo caInfo; + std::shared_ptr pSysContractApi = getSysContractApi(); + pSysContractApi->getCaInfo(pub256, caInfo); + LOG(INFO) << "getCaInfo, key:" << pub256 << ",info:" << caInfo.toString() << ",CAVerify:" << caVerify <(); + Signature signature = _rlp[5].toHash(); //获取签名信息 + std::string caSign = _rlp[6].toString(); + std::string caPub256 = _rlp[7].toString(); + LOG(INFO) << "SerializeHandShakeRLP,pub:" << pub << ",signature:" << signature << ",caPub256:" << caPub256 << std::endl; + + std::string seed(_rbd.getSeed().begin(), _rbd.getSeed().end()); + caBaseData.setSeed(seed); + caBaseData.setNodeSign(signature); + caBaseData.setSign(caSign); + caBaseData.setPub256(caPub256); + + return CheckAll(pub.hex(), caBaseData); + //checkNodeInfo(pub.hex(), wbCAData) && checkCA(pub.hex(), seedStr, wbCAData); +} + +bool NodeConnParamsManager::CheckAll(const std::string& sNodeId, CABaseData &caBaseData){ + return checkNodeInfo(sNodeId, caBaseData) && checkCA(sNodeId, caBaseData); +} + +void NodeConnParamsManager::ConstructHandShakeRLP(RLPStream &_rlp, RLPBaseData &_rbd) +{ + std::string seedStr(_rbd.getSeed().begin(), _rbd.getSeed().end()); + if (seedStr.empty()) + { + LOG(INFO) << "seedStr is empty.nodeId:" << m_host->id().hex() << std::endl; + return; + } + + WBCAData wbCAData; + bool ok = signNodeInfo(wbCAData); + if (!ok) + { + LOG(INFO) << "signNodeInfo false!!! nodeId:" << m_host->id().hex() << std::endl; + return; + } + ok = signCAInfo(seedStr, wbCAData); + if (!ok) + { + LOG(INFO) << "signCAInfo false!!! nodeId:" << m_host->id().hex() << std::endl; + return; + } + + _rlp.append((unsigned)HelloPacket).appendList(8) + << dev::p2p::c_protocolVersion + << m_host->nodeInfo().version + << m_host->caps() + << m_host->listenPort() + << m_host->id() + << wbCAData.getNodeSign() + << wbCAData.getSign() + << wbCAData.getPub256(); + + LOG(INFO) << "ConstructHandShakeRLP, pub256:" << wbCAData.getPub256() << ",nodeSign:" << wbCAData.getNodeSign() << ",nodeId:" << m_host->id().hex() << std::endl; +} + + +void NodeConnParamsManager::SaveCADataInSession(const std::string nodeId, CABaseData &caBaseData) +{ + if (nodeId.empty()) + { + return; + } + + m_host->saveCADataByNodeId(nodeId, caBaseData); +} + +//证书内容更新,或者吊销的 +void NodeConnParamsManager::CAInfoModifyCallback(const std::string& pub256) +{ + bool caVerify = eth::NodeConnParamsManager::CAVerify; + if (!caVerify) + { + LOG(INFO) << "CAInfoModifyCallback CAVerify is false." << std::endl; + return; + } + + eth::CaInfo caInfo; + std::shared_ptr pSysContractApi = getSysContractApi(); + pSysContractApi->getCaInfo(pub256, caInfo); + LOG(INFO) << "CAInfoModifyCallback getCaInfo, key:" << pub256 << ",info:" << caInfo.toString() << ",CAVerify:" << caVerify <disconnectByPub256(pub256); + return; + } + + return; +} + +void NodeConnParamsManager::CAVerifyModifyCallback() +{ + bool caVerify = eth::NodeConnParamsManager::CAVerify; + if (!caVerify) + { + return; + } + + m_host->recheckAllCA(); +}; + +void NodeConnParamsManager::SetHost(Host *host) +{ + m_host = host; +}; + diff --git a/libethereum/NodeConnParamsManager.h b/libethereum/NodeConnParamsManager.h new file mode 100644 index 0000000000..cf7f4eaa49 --- /dev/null +++ b/libethereum/NodeConnParamsManager.h @@ -0,0 +1,161 @@ +#pragma once + +#include +#include "NodeConnParamsManagerApi.h" + +namespace dev +{ +class NetworkFace; + +namespace eth +{ + +struct NodeConnManageNote : public LogChannel { static const char* name(){return "NodeConnManageNote";}; static const int verbosity = 3; }; + +class EthereumHost; +class SystemContractApi; + +enum class CaStatus { + Invalid, //失效 + Ok //有效 +}; +struct CaInfo +{ + std::string hash; // 节点机构证书哈希 + std::string pubkey;// 公钥 + std::string orgname; // 机构名称 + u256 notbefore; + u256 notafter; + CaStatus status; + std::string white; + std::string black; + + u256 blocknumber; + + std::string toString()const + { + std::ostringstream os; + os << hash << "|" << pubkey << "|" << orgname << "|" << notbefore << "|" << notafter << "|" << (int)status << "|" << blocknumber; + os << "|white:"; + std::vector whitelist = getWhiteList(); + for (std::vector::iterator it = whitelist.begin(); it != whitelist.end(); it++) + os << (*it); + os << "|black:"; + std::vector blacklist = getBlackList(); + for (std::vector::iterator it = blacklist.begin(); it != blacklist.end(); it++) + os << (*it); + + return os.str(); + } + + std::vector getWhiteList() const + { + std::vector whitelist; + boost::split(whitelist, white, boost::is_any_of(";")); + return whitelist; + } + std::vector getBlackList() const + { + std::vector blacklist; + boost::split(blacklist, black, boost::is_any_of(";")); + return blacklist; + } + +}; + + +/*** +* 节点配置管理类 单例 +* 里面需要赋值NetworkFace和EthereumHost 指针进行控制 +**/ +class NodeConnParamsManager : public NodeConnParamsManagerApi +{ +public: + + static bool CAVerify; + + NodeConnParamsManager(std::string const& _json); + + //增加新节点 + //in - sNewNodeConnInfo json结构的数据 + //out - 是否新加成功 + virtual bool addNewNodeConnInfo(const std::string &sNewNodeConnInfo) override; + //in - nodeParam 配置节点的NodeConnParams数据结构 + //out - 是否新加成功 + virtual bool addNewNodeConnInfo(const NodeConnParams &nodeParam) override; + /** + * 删除节点 + * in - sNodeId 需要删除的节点nodeid + * out - bExisted 需要删除的节点是之前存在 + **/ + virtual void delNodeConnInfo(const std::string &sNodeId, bool &bExisted) override; + + /** + * 发起网络同步(增加的节点配置) 调用networkFace的发起网络请求 + * in - vParams 新加的节点连接 + **/ + virtual void sendNodeInfoSync(const std::vector &vParams) override; + + /** + * 发起网络同步(删除某个节点信息) 调用networkFace的发起网络请求 + * in - sNodeId 需要删除的节点nodeid + **/ + virtual void sendDelNodeInfoSync(const std::string &sNodeId) override; + + //获取共识需要的数据 + virtual void getAllNodeConnInfo(int blockNum, std::map & mNodeConnParams) const override; + /** + * 对节点进行连接 + * in - param 需连接的节点 + **/ + virtual void connNode(const NodeConnParams ¶m) override; + + /** + * 对已连接的节点进行断开 + * in - sNodeId 已连接节点的nodeid + **/ + virtual void disconnNode(const std::string & sNodeId) override; + + //设置sysEthereumApi 同时设置回调函数 + virtual void setSysContractApi(std::shared_ptr sysContractApi) override; + + //将内存中的配置文件 刷入到文件中 ${datadir}/nodeextrainfo.json + void writeNodeFile(); + + void callSysContractData(int const& blockNum); + + bool getPublicKey(u256 const& _idx, Public & _pub) const override; + bool getIdx(p2p::NodeID const& _nodeId, u256 & _idx) const override; + unsigned getMinerNum() const override; + bool getAccountType(p2p::NodeID const& _nodeId, unsigned & _type) const override; + unsigned getNodeNum() const override; + + std::string _sConfig; + + /* + * CA + */ + bool CheckAndSerialize(const RLP &_rlp, RLPBaseData &_rbd, CABaseData &caBaseData) override; + bool CheckAll(const std::string& sNodeId, CABaseData &caBaseData) override ; + void ConstructHandShakeRLP(RLPStream &_rlp, RLPBaseData &_rbd) override ; + void SaveCADataInSession(const std::string nodeId, CABaseData &caBaseData) override ; + void CAInfoModifyCallback(const std::string& pub256); + void CAVerifyModifyCallback(); + void SetHost(Host *host); + +private: + bool checkNodesValid(const std::vector< NodeConnParams> &vNodes); + bool diffNodes(const std::vector< NodeConnParams> &vNodeParams, std::vector< NodeConnParams> &vAddNodes, std::vector< NodeConnParams> &vDelNodes); + bool signNodeInfo(CABaseData & caBaseData); + bool signCAInfo(std::string seedStr, CABaseData & caBaseData); + bool checkNodeInfo(std::string remoteNodeID, CABaseData & caBaseData); + bool checkIP(std::string remoteNodeID, CaInfo &caInfo); + bool checkCA(std::string remoteNodeID, CABaseData & caBaseData); + std::pair > getGodMiner(int blockNum)const; + + Host* m_host; +}; + +} +} + diff --git a/libethereum/NodeConnParamsManagerApi.cpp b/libethereum/NodeConnParamsManagerApi.cpp new file mode 100644 index 0000000000..62b8f79dc2 --- /dev/null +++ b/libethereum/NodeConnParamsManagerApi.cpp @@ -0,0 +1,89 @@ +#include "NodeConnParamsManagerApi.h" +#include "NodeConnParamsManager.h" +#include + +using namespace std; +using namespace dev; +using namespace eth; + +Mutex NodeConnParamsManagerApi::_xNodeConnParam; +Mutex NodeConnParamsManagerApi::_xConfigNodeConnParam; + +bool NodeConnParamsManagerApi::getNodeConnInfo(std::string const& sNodeID, NodeConnParams &retNode) const +{ + bool bFind = false; + Guard l(_xNodeConnParam); + if (_mNodeConnParams.find(sNodeID) != _mNodeConnParams.end()) + { + bFind = true; + retNode = _mNodeConnParams[sNodeID]; + } + return bFind; +} + +//从内存中 和config数据中查找 更多的是用于自己的 +bool NodeConnParamsManagerApi::getNodeConnInfoBoth(std::string const& sNodeID, NodeConnParams &retNode) const +{ + bool bFind = getNodeConnInfo(sNodeID, retNode); + if (!bFind) + { + Guard l(_xConfigNodeConnParam); + if (_mConfNodeConnParams.find(sNodeID) != _mConfNodeConnParams.end()) + { + bFind = true; + retNode = _mConfNodeConnParams[sNodeID]; + } + } + return bFind; +} + + +void NodeConnParamsManagerApi::getAllNodeConnInfoContract(std::map & mNodeConnParams) const +{ + Guard l(_xNodeConnParam); + mNodeConnParams = _mNodeConnParams; +} + + +void NodeConnParamsManagerApi::getAllConfNodeConnInfo(std::map & mNodeConnParams) const +{ + Guard l(_xConfigNodeConnParam); + mNodeConnParams = _mConfNodeConnParams; +} + +void NodeConnParamsManagerApi::getAllNodeConnInfoContractAndConf(std::map & mNodeConnParams) const +{ + mNodeConnParams.clear(); + { + Guard l(_xNodeConnParam); + mNodeConnParams = _mNodeConnParams; + } + + { + Guard l(_xConfigNodeConnParam); + for (auto node : _mConfNodeConnParams) + { + if (mNodeConnParams.find(node.first) == mNodeConnParams.end()) + { + mNodeConnParams[node.first] = node.second; + } + } + } + +} + +dev::eth::NodeConnParamsManagerApi& NodeConnManagerSingleton::GetInstance() +{ + if (getCaInitType() == "webank") + { + static dev::eth::NodeConnParamsManager nodeConnParamsManager(contentsString(getConfigPath())); + + return nodeConnParamsManager; + } + else{ + + static dev::eth::NodeConnParamsManager nodeConnParamsManager(contentsString(getConfigPath())); + + return nodeConnParamsManager; + } +} diff --git a/libethereum/NodeConnParamsManagerApi.h b/libethereum/NodeConnParamsManagerApi.h new file mode 100644 index 0000000000..0b12159beb --- /dev/null +++ b/libethereum/NodeConnParamsManagerApi.h @@ -0,0 +1,159 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include "ChainParams.h" +#include + + +using namespace dev::p2p; +enum AccountType { + EN_ACCOUNT_TYPE_NORMAL = 0, + EN_ACCOUNT_TYPE_MINER = 1 +}; +namespace dev +{ + class NetworkFace; + namespace eth + { + class EthereumHost; + class SystemContractApi; + + + class NodeConnParamsManagerApi + { + public: + ~NodeConnParamsManagerApi(){} + /** + * 根据节点nodeid 获取对应的配置 + * in - sNodeID 节点的nodeid + * out - retNode 节点的配置信息 + * out - bool 是否存在 + **/ + virtual bool getNodeConnInfo(std::string const& sNodeID, NodeConnParams &retNode) const; + + /** + * 根据节点nodeid 获取对应的配置(从合约中读取,读取不到再从内存中读取, 主要用于查找自己的数据) + * in - sNodeID 节点的nodeid + * out - retNode 节点的配置信息 + * out - bool 是否存在 + **/ + virtual bool getNodeConnInfoBoth(std::string const& sNodeID, NodeConnParams &retNode) const; + /** + * 获取全部节点连接配置 + * int - blockNum 小于0为取当前配置 其余为对应区块的临时数据 + * out - mNodeConnParams 所有的节点配置信息 + **/ + virtual void getAllNodeConnInfo(int, std::map & mNodeConnParams) const = 0; + // virtual void getAllNodeConnInfo(int, std::map & mNodeConnParams) const{ getAllNodeConnInfoContractAndConf(mNodeConnParams); }; + /** + * 获取全部节点连接配置 + * out - mNodeConnParams 所有的节点配置信息 + **/ + virtual void getAllNodeConnInfoContract(std::map & mNodeConnParams) const; + /** + * 获取全部节点连接配置 config.json + * out - mNodeConnParams 所有的节点配置信息 + **/ + virtual void getAllConfNodeConnInfo(std::map & mNodeConnParams) const; + + /** + * 获取全部节点信息(合约和配置文件做并集,已合约的信息为主,即一个nodeid两边都有的话 已合约里对应的信息为主) + * out - mNodeConnParams 所有的节点配置信息 + **/ + virtual void getAllNodeConnInfoContractAndConf(std::map & mNodeConnParams) const; + + + //设置NetworkFace + //用于发送p2p新协议, + virtual void setNetworkFace(NetworkFace *net) { _pNetwork = net; } + //设置ethereumHost + virtual void setEthereumHost(EthereumHost *host) { _pHost = host; } + //设置sysEthereumApi 同时设置回调函数 + virtual void setSysContractApi(std::shared_ptr sysContractApi) { _pSysContractApi = sysContractApi; } + //获取sysContractApi + virtual std::shared_ptr getSysContractApi() const{ return _pSysContractApi; } + //增加新节点 + //in - sNewNodeConnInfo json结构的数据 + //out - 是否新加成功 + virtual bool addNewNodeConnInfo(const std::string &){ return true; }; + virtual bool addNewNodeConnInfo(const NodeConnParams &){ return true; }; + /** + * 删除节点 + * in - sNodeId 需要删除的节点nodeid + * out - bExisted 需要删除的节点是之前存在 + **/ + virtual void delNodeConnInfo(const std::string &, bool &){}; + /** + * 对节点进行连接 + * in - param 需连接的节点 + **/ + virtual void connNode(const NodeConnParams &){}; + /** + * 发起网络同步(增加的节点配置) 调用networkFace的发起网络请求 + * in - vParams 新加的节点连接 + **/ + virtual void sendNodeInfoSync(const std::vector &){} + /** + * 发起网络同步(删除某个节点信息) 调用networkFace的发起网络请求 + * in - sNodeId 需要删除的节点nodeid + **/ + virtual void sendDelNodeInfoSync(const std::string &){} + virtual void setInitIdentityNodes(const eth::ChainParams & cp){ + _vInitIdentityNodes = cp._vInitIdentityNodes; + } + virtual void setChainParams(const eth::ChainParams & cp){ + _chainParams = cp; + } + /** + * 对已连接的节点进行断开 + * in - sNodeId 已连接节点的nodeid + **/ + virtual void disconnNode(const std::string &){}; + //virtual void getAllNodeConnInfo(std::map & mNodeConnParams) const = 0; + virtual bool getPublicKey(u256 const&, Public &) const { return false; } + virtual bool getIdx(p2p::NodeID const&, u256 &) const { return false; } + virtual unsigned getMinerNum() const { return 0; } + virtual bool getAccountType(p2p::NodeID const&, unsigned &) const { return false; } + virtual unsigned getNodeNum() const{ return 0; } + + /* + *对连接控制,CA的一些连接控制 + **/ + virtual bool CheckAndSerialize(const RLP &_rlp, RLPBaseData &_rbd, CABaseData &caBaseData) = 0; + virtual bool CheckAll(const std::string& , CABaseData &) {return true;}; + virtual void ConstructHandShakeRLP(RLPStream &_rlp, RLPBaseData &_rbd) = 0; + virtual void SaveCADataInSession(const std::string, CABaseData &) {}; + virtual void SetHost(Host*) {}; + protected: + //节点信息锁 + static Mutex _xNodeConnParam; + //节点连接信息(合约数据) + mutable std::map _mNodeConnParams; + + //config.json中的配置数据 找自己信息的时候先找合约 找不到再从这里面找 + static Mutex _xConfigNodeConnParam; + mutable std::map _mConfNodeConnParams; + //进行网络请求 + EthereumHost *_pHost = nullptr; + //进行连接节点控制 + NetworkFace *_pNetwork = nullptr; + //全局函数 + std::shared_ptr _pSysContractApi = nullptr; + ////初始化时参与签名的节点数据 + std::vector _vInitIdentityNodes; + eth::ChainParams _chainParams; + NodeConnParamsManagerApi(){} + }; + } + + class NodeConnManagerSingleton{ + public: + //默认初始化生成webank的基类,则需要有webank的配置项。 + static dev::eth::NodeConnParamsManagerApi& GetInstance(); + }; +} diff --git a/libethereum/NonceCheck.cpp b/libethereum/NonceCheck.cpp new file mode 100644 index 0000000000..528ca9aecb --- /dev/null +++ b/libethereum/NonceCheck.cpp @@ -0,0 +1,149 @@ +#include +#include +#include +using namespace dev; + + + +NonceCheck:: ~NonceCheck() +{ + +} + +u256 NonceCheck::maxblocksize=1000; + +void NonceCheck::init(BlockChain const& _bc) +{ + m_startblk=0; + m_endblk=0; + + + updateCache(_bc,true); + +} + + +std::string NonceCheck::generateKey(Transaction const & _t) +{ + Address account=_t.from(); + std::string key=toHex(account.ref()); + key += "_"+toString(_t.randomid()); + + return key; +} + +bool NonceCheck::ok(Transaction const & _transaction,bool _needinsert) +{ + DEV_WRITE_GUARDED(m_lock) + { + string key=this->generateKey(_transaction); + auto iter= m_cache.find( key ); + if( iter != m_cache.end() ) + return false; + if( _needinsert ) + { + m_cache.insert(std::pair(key,true)); + } + + + + } + + return true; +} + + + +void NonceCheck::delCache( Transactions const & _transcations) +{ + DEV_WRITE_GUARDED(m_lock) + { + for( unsigned i=0;i<_transcations.size();i++) + { + string key=this->generateKey(_transcations[i]); + auto iter= m_cache.find( key ); + if( iter != m_cache.end() ) + m_cache.erase(iter); + } + } +} + + + +void NonceCheck::updateCache(BlockChain const& _bc,bool _rebuild/*是否强制rebuild */) +{ + + DEV_WRITE_GUARDED(m_lock) + { + try + { + Timer timer; + unsigned lastnumber=_bc.number(); + + + unsigned prestartblk=m_startblk; + unsigned preendblk=m_endblk; + + m_endblk=lastnumber; + if( lastnumber >(unsigned)NonceCheck::maxblocksize ) + m_startblk=lastnumber-(unsigned)NonceCheck::maxblocksize; + else + m_startblk=0; + + LOG(TRACE)<<"NonceCheck::updateCache m_startblk="< bytestrans=_bc.transactions(blockhash); + for( unsigned j=0;jgenerateKey(t); + auto iter= m_cache.find( key ); + if( iter != m_cache.end() ) + m_cache.erase(iter); + } + } + } + + + for( unsigned i=std::max(preendblk+1,m_startblk);i<=m_endblk;i++) + { + h256 blockhash=_bc.numberHash(i); + + std::vector bytestrans=_bc.transactions(blockhash); + for( unsigned j=0;jgenerateKey(t); + auto iter= m_cache.find( key ); + if( iter == m_cache.end() ) + m_cache.insert(std::pair(key,true)); + } + } + + LOG(TRACE)<<"NonceCheck::updateCache cache size="< +#include + +#include +#include +#include +#include +#include +#include + + +using namespace std; +using namespace dev::eth; + +namespace dev +{ +namespace eth +{ + + +class NonceCheck +{ +private: + + + std::unordered_map< std::string,bool > m_cache; + unsigned m_startblk; + unsigned m_endblk; + mutable SharedMutex m_lock; + std::string generateKey(Transaction const & _t); + +public: + static u256 maxblocksize; + + + NonceCheck(){} + ~NonceCheck() ; + + void init(BlockChain const& _bc); + bool ok(Transaction const & _transaction,bool _needinsert=false/*如果不存在是否插入*/); + void updateCache(BlockChain const& _bc,bool _rebuild=false); + void delCache( Transactions const & _transcations); + +}; + + + +} +} diff --git a/libethereum/State.cpp b/libethereum/State.cpp new file mode 100644 index 0000000000..4cd46b927c --- /dev/null +++ b/libethereum/State.cpp @@ -0,0 +1,672 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file State.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "State.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "BlockChain.h" +#include "CodeSizeCache.h" +#include "Defaults.h" +#include "ExtVM.h" +#include "Executive.h" +#include "BlockChain.h" +#include "TransactionQueue.h" +#include + +using namespace std; +using namespace dev; +using namespace dev::eth; +using namespace dev::eth::detail; +namespace fs = boost::filesystem; + +const char* StateSafeExceptions::name() { return EthViolet "⚙" EthBlue " ℹ"; } +const char* StateDetail::name() { return EthViolet "⚙" EthWhite " ◌"; } +const char* StateTrace::name() { return EthViolet "⚙" EthGray " ◎"; } +const char* StateChat::name() { return EthViolet "⚙" EthWhite " ◌"; } + +State::State(u256 const& _accountStartNonce, OverlayDB const& _db, BaseState _bs): + m_db(_db), + m_state(&m_db), + m_accountStartNonce(_accountStartNonce) +{ + if (_bs != BaseState::PreExisting) + // Initialise to the state entailed by the genesis block; this guarantees the trie is built correctly. + + m_state.init(); +} + +State::State(State const& _s): + m_db(_s.m_db), + m_state(&m_db, _s.m_state.root(), Verification::Skip), + m_cache(_s.m_cache), + m_unchangedCacheEntries(_s.m_unchangedCacheEntries), + m_nonExistingAccountsCache(_s.m_nonExistingAccountsCache), + m_touched(_s.m_touched), + m_accountStartNonce(_s.m_accountStartNonce) +{} + +OverlayDB State::openDB(std::string const& _basePath, h256 const& _genesisHash, WithExisting _we) +{ + std::string path = _basePath.empty() ? Defaults::get()->m_dbPath : _basePath; + + if (_we == WithExisting::Kill) + { + LOG(TRACE) << "Killing state database (WithExisting::Kill)."; + boost::filesystem::remove_all(path + "/state"); + } + + path += "/" + toHex(_genesisHash.ref().cropped(0, 4)) + "/" + toString(c_databaseVersion); + boost::filesystem::create_directories(path); + DEV_IGNORE_EXCEPTIONS(fs::permissions(path, fs::owner_all)); + + ldb::Options o; + o.max_open_files = 256; + o.create_if_missing = true; + + ldb::DB* db = nullptr; + #if ETH_ODBC + LOG(INFO) << "state ethodbc is defined " << std::endl; + + db = ldb::LvlDbInterfaceFactory::create(leveldb::DBUseType::stateType); + if(db != nullptr) + { + LOG(INFO) << "state ethodbc is defined " << std::endl; + } + else + { + LOG(INFO) << "state ethodbc is not defined " << std::endl; + //todo 打开失败 可能要throw exception + } + #else + //初始化state db + ldb::Status status = ldb::DB::Open(o, path + "/state", &db); + if (!status.ok() || !db) + { + if (boost::filesystem::space(path + "/state").available < 1024) + { + LOG(WARNING) << "Not enough available space found on hard drive. Please free some up and then re-run. Bailing."; + BOOST_THROW_EXCEPTION(NotEnoughAvailableSpace()); + } + else + { + LOG(WARNING) << status.ToString(); + LOG(WARNING) << + "Database " << + (path + "/state") << + "already open. You appear to have another instance of ethereum running. Bailing."; + BOOST_THROW_EXCEPTION(DatabaseAlreadyOpen()); + } + } + + LOG(TRACE) << "Opened state DB."; + #endif + return OverlayDB(db); + +} + +void State::populateFrom(AccountMap const& _map) +{ + eth::commit(_map, m_state); + commit(State::CommitBehaviour::KeepEmptyAccounts); +} + +u256 const& State::requireAccountStartNonce() const +{ + if (m_accountStartNonce == Invalid256) + BOOST_THROW_EXCEPTION(InvalidAccountStartNonceInState()); + return m_accountStartNonce; +} + +void State::noteAccountStartNonce(u256 const& _actual) +{ + if (m_accountStartNonce == Invalid256) + m_accountStartNonce = _actual; + else if (m_accountStartNonce != _actual) + BOOST_THROW_EXCEPTION(IncorrectAccountStartNonceInState()); +} + +void State::removeEmptyAccounts() +{ + for (auto& i: m_cache) + if (i.second.isDirty() && i.second.isEmpty()) + i.second.kill(); +} + +State& State::operator=(State const& _s) +{ + if (&_s == this) + return *this; + + m_db = _s.m_db; + m_state.open(&m_db, _s.m_state.root(), Verification::Skip); + m_cache = _s.m_cache; + m_unchangedCacheEntries = _s.m_unchangedCacheEntries; + m_nonExistingAccountsCache = _s.m_nonExistingAccountsCache; + m_touched = _s.m_touched; + m_accountStartNonce = _s.m_accountStartNonce; + return *this; +} + +Account const* State::account(Address const& _a) const +{ + return const_cast(this)->account(_a); +} + +Account* State::account(Address const& _addr) +{ + auto it = m_cache.find(_addr); + if (it != m_cache.end()) + return &it->second; + + if (m_nonExistingAccountsCache.count(_addr)) + return nullptr; + + // Populate basic info. + string stateBack = m_state.at(_addr); + if (stateBack.empty()) + { + m_nonExistingAccountsCache.insert(_addr); + return nullptr; + } + + clearCacheIfTooLarge(); + + RLP state(stateBack); + auto i = m_cache.emplace( + std::piecewise_construct, + std::forward_as_tuple(_addr), + std::forward_as_tuple(state[0].toInt(), state[1].toInt(), state[2].toHash(), state[3].toHash(), Account::Unchanged) + ); + m_unchangedCacheEntries.push_back(_addr); + return &i.first->second; +} + +void State::clearCacheIfTooLarge() const +{ + // TODO: Find a good magic number + while (m_unchangedCacheEntries.size() > 1000) + { + // Remove a random element + size_t const randomIndex = boost::random::uniform_int_distribution(0, m_unchangedCacheEntries.size() - 1)(dev::s_fixedHashEngine); + + Address const addr = m_unchangedCacheEntries[randomIndex]; + swap(m_unchangedCacheEntries[randomIndex], m_unchangedCacheEntries.back()); + m_unchangedCacheEntries.pop_back(); + + auto cacheEntry = m_cache.find(addr); + if (cacheEntry != m_cache.end() && !cacheEntry->second.isDirty()) + m_cache.erase(cacheEntry); + } +} + +void State::commit(CommitBehaviour _commitBehaviour) +{ + if (_commitBehaviour == CommitBehaviour::RemoveEmptyAccounts) + removeEmptyAccounts(); + + LOG(TRACE)<<"State::commit m_touched.size()="< State::addresses() const +{ +#if ETH_FATDB + unordered_map ret; + for (auto& i: m_cache) + if (i.second.isAlive()) + ret[i.first] = i.second.balance(); + for (auto const& i: m_state) + if (m_cache.find(i.first) == m_cache.end()) + ret[i.first] = RLP(i.second)[1].toInt(); + return ret; +#else + BOOST_THROW_EXCEPTION(InterfaceNotSupported("State::addresses()")); +#endif +} + +void State::setRoot(h256 const& _r) +{ + m_cache.clear(); + m_unchangedCacheEntries.clear(); + m_nonExistingAccountsCache.clear(); +// m_touched.clear(); + m_state.setRoot(_r); +} + +bool State::addressInUse(Address const& _id) const +{ + return !!account(_id); +} + +bool State::accountNonemptyAndExisting(Address const& _address) const +{ + if (Account const* a = account(_address)) + return !a->isEmpty(); + else + return false; +} + +bool State::addressHasCode(Address const& _id) const +{ + if (auto a = account(_id)) + return a->codeHash() != EmptySHA3; + else + return false; +} + +u256 State::balance(Address const& ) const +{ + return 0xFFFFFFFFFFFFFFFF; + /* + if (auto a = account(_id)) + return a->balance(); + else + return 0;*/ +} + +void State::incNonce(Address const& _addr) +{ + if (Account* a = account(_addr)) + { + a->incNonce(); + m_changeLog.emplace_back(Change::Nonce, _addr); + } + else + // This is possible if a transaction has gas price 0. + createAccount(_addr, Account(requireAccountStartNonce() + 1, 0)); +} + +void State::addBalance(Address const& _id, u256 const& _amount) +{ + //不能直接return + + if (Account* a = account(_id)) + { + // Log empty account being touched. Empty touched accounts are cleared + // after the transaction, so this event must be also reverted. + // We only log the first touch (not dirty yet), and only for empty + // accounts, as other accounts does not matter. + // TODO: to save space we can combine this event with Balance by having + // Balance and Balance+Touch events. + if (!a->isDirty() && a->isEmpty()) + m_changeLog.emplace_back(Change::Touch, _id); + + // Increase the account balance. This also is done for value 0 to mark + // the account as dirty. Dirty account are not removed from the cache + // and are cleared if empty at the end of the transaction. + + //a->addBalance(_amount); + } + else + createAccount(_id, {requireAccountStartNonce(), _amount}); + + if (_amount) + m_changeLog.emplace_back(Change::Balance, _id, _amount); +} + +void State::subBalance(Address const& _addr, u256 const& _value) +{ + return; + + if (_value == 0) + return; + + Account* a = account(_addr); + if (!a || a->balance() < _value) + // TODO: I expect this never happens. + BOOST_THROW_EXCEPTION(NotEnoughCash()); + + // Fall back to addBalance(). + addBalance(_addr, 0 - _value); +} + +void State::createContract(Address const& _address) +{ + createAccount(_address, {requireAccountStartNonce(), 0}); +} + +void State::createAccount(Address const& _address, Account const&& _account) +{ + assert(!addressInUse(_address) && "Account already exists"); + m_cache[_address] = std::move(_account); + m_nonExistingAccountsCache.erase(_address); + m_changeLog.emplace_back(Change::Create, _address); +} + +void State::kill(Address _addr) +{ + if (auto a = account(_addr)) + a->kill(); + // If the account is not in the db, nothing to kill. +} + +u256 State::getNonce(Address const& _addr) const +{ + if (auto a = account(_addr)) + return a->nonce(); + else + return m_accountStartNonce; +} + +u256 State::storage(Address const& _id, u256 const& _key) const +{ + if (Account const* a = account(_id)) + { + //从对应的account下找寻存在的key + auto mit = a->storageOverlay().find(_key); + if (mit != a->storageOverlay().end()) + return mit->second; + + // Not in the storage cache - go to the DB. + //对应的state下没有找到 则去db中寻找 + SecureTrieDB memdb(const_cast(&m_db), a->baseRoot()); // promise we won't change the overlay! :) + string payload = memdb.at(_key); + u256 ret = payload.size() ? RLP(payload).toInt() : 0; + a->setStorageCache(_key, ret); + return ret; + } + else + return 0; +} + +void State::setStorage(Address const& _contract, u256 const& _key, u256 const& _value) +{ + + m_changeLog.emplace_back(_contract, _key, storage(_contract, _key)); + m_cache[_contract].setStorage(_key, _value); +} + +map> State::storage(Address const& _id) const +{ + + + map> ret; + + if (Account const* a = account(_id)) + { + // Pull out all values from trie storage. + if (h256 root = a->baseRoot()) + { + SecureTrieDB memdb(const_cast(&m_db), root); // promise we won't alter the overlay! :) + + for (auto it = memdb.hashedBegin(); it != memdb.hashedEnd(); ++it) + { + h256 const hashedKey((*it).first); + u256 const key = h256(it.key()); + u256 const value = RLP((*it).second).toInt(); + ret[hashedKey] = make_pair(key, value); + + } + } + + // Then merge cached storage over the top. + for (auto const& i : a->storageOverlay()) + { + h256 const key = i.first; + h256 const hashedKey = sha3(key); + if (i.second) + ret[hashedKey] = i; + else + ret.erase(hashedKey); + } + + + } + return ret; +} + +h256 State::storageRoot(Address const& _id) const +{ + string s = m_state.at(_id); + if (s.size()) + { + RLP r(s); + return r[2].toHash(); + } + return EmptyTrie; +} + +bytes const& State::code(Address const& _addr) const +{ + Account const* a = account(_addr); + if (!a || a->codeHash() == EmptySHA3) + return NullBytes; + + if (a->code().empty()) + { + // Load the code from the backend. + Account* mutableAccount = const_cast(a); + mutableAccount->noteCode(m_db.lookup(a->codeHash())); + CodeSizeCache::instance().store(a->codeHash(), a->code().size()); + } + + return a->code(); +} + +void State::setNewCode(Address const& _address, bytes&& _code) +{ + m_cache[_address].setNewCode(std::move(_code)); + m_changeLog.emplace_back(Change::NewCode, _address); +} + +h256 State::codeHash(Address const& _a) const +{ + if (Account const* a = account(_a)) + return a->codeHash(); + else + return EmptySHA3; +} + +size_t State::codeSize(Address const& _a) const +{ + if (Account const* a = account(_a)) + { + if (a->hasNewCode()) + return a->code().size(); + auto& codeSizeCache = CodeSizeCache::instance(); + h256 codeHash = a->codeHash(); + if (codeSizeCache.contains(codeHash)) + return codeSizeCache.get(codeHash); + else + { + size_t size = code(_a).size(); + codeSizeCache.store(codeHash, size); + return size; + } + } + else + return 0; +} + +size_t State::savepoint() const +{ + return m_changeLog.size(); +} + +void State::rollback(size_t _savepoint) +{ + while (_savepoint != m_changeLog.size()) + { + auto& change = m_changeLog.back(); + auto& account = m_cache[change.address]; + + // Public State API cannot be used here because it will add another + // change log entry. + switch (change.kind) + { + case Change::Storage: + account.setStorage(change.key, change.value); + break; + case Change::Balance: + account.addBalance(0 - change.value); + break; + case Change::Nonce: + account.setNonce(account.nonce() - 1); + break; + case Change::Create: + m_cache.erase(change.address); + break; + case Change::NewCode: + account.resetCode(); + break; + case Change::Touch: + account.untouch(); + m_unchangedCacheEntries.emplace_back(change.address); + break; + } + m_changeLog.pop_back(); + } +} + +std::pair State::execute(EnvInfo const& _envInfo, SealEngineFace const& _sealEngine, Transaction const& _t, Permanence _p, OnOpFunc const& _onOp) +{ + + + auto onOp = _onOp; +#if ETH_VMTRACE + if (isChannelVisible()) + onOp = Executive::simpleTrace(); // override tracer +#endif + + + + // Create and initialize the executive. This will throw fairly cheaply and quickly if the + // transaction is bad in any way. + Executive e(*this, _envInfo, _sealEngine); + ExecutionResult res; + e.setResultRecipient(res); + e.initialize(_t); + + // OK - transaction looks valid - execute. + u256 startGasUsed = _envInfo.gasUsed(); + if (!e.execute()) + e.go(onOp); + e.finalize(); + + if (_p == Permanence::Dry) { + + } + else if (_p == Permanence::Reverted) + m_cache.clear(); + else + { + bool removeEmptyAccounts = _envInfo.number() >= _sealEngine.chainParams().u256Param("EIP158ForkBlock"); + commit(removeEmptyAccounts ? State::CommitBehaviour::RemoveEmptyAccounts : State::CommitBehaviour::KeepEmptyAccounts); + } + + return make_pair(res, TransactionReceipt(rootHash(), startGasUsed + e.gasUsed(), e.logs(),e.newAddress())); +} + +void dev::eth::State::clearCache() { + m_cache.clear(); +} + +std::unordered_map dev::eth::State::getCache() { + return m_cache; +} + +std::ostream& dev::eth::operator<<(std::ostream& _out, State const& _s) +{ + _out << "--- " << _s.rootHash() << std::endl; + std::set
d; + std::set
dtr; + auto trie = SecureTrieDB(const_cast(&_s.m_db), _s.rootHash()); + for (auto i: trie) + d.insert(i.first), dtr.insert(i.first); + for (auto i: _s.m_cache) + d.insert(i.first); + + for (auto i: d) + { + auto it = _s.m_cache.find(i); + Account* cache = it != _s.m_cache.end() ? &it->second : nullptr; + string rlpString = dtr.count(i) ? trie.at(i) : ""; + RLP r(rlpString); + assert(cache || r); + + if (cache && !cache->isAlive()) + _out << "XXX " << i << std::endl; + else + { + string lead = (cache ? r ? " * " : " + " : " "); + if (cache && r && cache->nonce() == r[0].toInt() && cache->balance() == r[1].toInt()) + lead = " . "; + + stringstream contout; + + if ((cache && cache->codeHash() == EmptySHA3) || (!cache && r && (h256)r[3] != EmptySHA3)) + { + std::map mem; + std::set back; + std::set delta; + std::set cached; + if (r) + { + SecureTrieDB memdb(const_cast(&_s.m_db), r[2].toHash()); // promise we won't alter the overlay! :) + for (auto const& j: memdb) + mem[j.first] = RLP(j.second).toInt(), back.insert(j.first); + } + if (cache) + for (auto const& j: cache->storageOverlay()) + { + if ((!mem.count(j.first) && j.second) || (mem.count(j.first) && mem.at(j.first) != j.second)) + mem[j.first] = j.second, delta.insert(j.first); + else if (j.second) + cached.insert(j.first); + } + if (!delta.empty()) + lead = (lead == " . ") ? "*.* " : "*** "; + + contout << " @:"; + if (!delta.empty()) + contout << "???"; + else + contout << r[2].toHash(); + if (cache && cache->hasNewCode()) + contout << " $" << toHex(cache->code()); + else + contout << " $" << (cache ? cache->codeHash() : r[3].toHash()); + + for (auto const& j: mem) + if (j.second) + contout << std::endl << (delta.count(j.first) ? back.count(j.first) ? " * " : " + " : cached.count(j.first) ? " . " : " ") << std::hex << nouppercase << std::setw(64) << j.first << ": " << std::setw(0) << j.second ; + else + contout << std::endl << "XXX " << std::hex << nouppercase << std::setw(64) << j.first << ""; + } + else + contout << " [SIMPLE]"; + _out << lead << i << ": " << std::dec << (cache ? cache->nonce() : r[0].toInt()) << " #:" << (cache ? cache->balance() : r[1].toInt()) << contout.str() << std::endl; + } + } + return _out; +} diff --git a/libethereum/State.h b/libethereum/State.h new file mode 100644 index 0000000000..9de1eb4fc0 --- /dev/null +++ b/libethereum/State.h @@ -0,0 +1,396 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file State.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Account.h" +#include "Transaction.h" +#include "TransactionReceipt.h" +#include "GasPricer.h" + +namespace dev +{ + +namespace test { class ImportTest; class StateLoader; } + +namespace eth +{ + +// Import-specific errinfos +using errinfo_uncleIndex = boost::error_info; +using errinfo_currentNumber = boost::error_info; +using errinfo_uncleNumber = boost::error_info; +using errinfo_unclesExcluded = boost::error_info; +using errinfo_block = boost::error_info; +using errinfo_now = boost::error_info; + +using errinfo_transactionIndex = boost::error_info; + +using errinfo_vmtrace = boost::error_info; +using errinfo_receipts = boost::error_info>; +using errinfo_transaction = boost::error_info; +using errinfo_phase = boost::error_info; +using errinfo_required_LogBloom = boost::error_info; +using errinfo_got_LogBloom = boost::error_info; +using LogBloomRequirementError = boost::tuple; + +class BlockChain; +class State; +class TransactionQueue; +struct VerifiedBlockRef; + +struct StateChat: public LogChannel { static const char* name(); static const int verbosity = 4; }; +struct StateTrace: public LogChannel { static const char* name(); static const int verbosity = 5; }; +struct StateDetail: public LogChannel { static const char* name(); static const int verbosity = 14; }; +struct StateSafeExceptions: public LogChannel { static const char* name(); static const int verbosity = 21; }; + +enum class BaseState +{ + PreExisting, + Empty +}; + +enum class Permanence +{ + Reverted, + Committed, + Dry +}; + +#if ETH_FATDB +template using SecureTrieDB = SpecificTrieDB, KeyType>; +#else +template using SecureTrieDB = SpecificTrieDB, KeyType>; +#endif + +DEV_SIMPLE_EXCEPTION(InvalidAccountStartNonceInState); +DEV_SIMPLE_EXCEPTION(IncorrectAccountStartNonceInState); + +class SealEngineFace; + + +namespace detail +{ + +/// An atomic state changelog entry. +struct Change +{ + enum Kind: int + { + /// Account balance changed. Change::value contains the amount the + /// balance was increased by. + Balance, + + /// Account storage was modified. Change::key contains the storage key, + /// Change::value the storage value. + Storage, + + /// Account nonce was increased by 1. + Nonce, + + /// Account was created (it was not existing before). + Create, + + /// New code was added to an account (by "create" message execution). + NewCode, + + /// Account was touched for the first time. + Touch + }; + + Kind kind; ///< The kind of the change. + Address address; ///< Changed account address. + u256 value; ///< Change value, e.g. balance, storage. + u256 key; ///< Storage key. Last because used only in one case. + + /// Helper constructor to make change log update more readable. + Change(Kind _kind, Address const& _addr, u256 const& _value = 0): + kind(_kind), address(_addr), value(_value) + {} + + /// Helper constructor especially for storage change log. + Change(Address const& _addr, u256 const& _key, u256 const& _value): + kind(Storage), address(_addr), value(_value), key(_key) + {} +}; + +} + + +/** + * Model of an Ethereum state, essentially a facade for the trie. + * + * Allows you to query the state of accounts as well as creating and modifying + * accounts. It has built-in caching for various aspects of the state. + * + * # State Changelog + * + * Any atomic change to any account is registered and appended in the changelog. + * In case some changes must be reverted, the changes are popped from the + * changelog and undone. For possible atomic changes list @see Change::Kind. + * The changelog is managed by savepoint(), rollback() and commit() methods. + */ +class State +{ + friend class ExtVM; + friend class dev::test::ImportTest; + friend class dev::test::StateLoader; + friend class BlockChain; + +public: + enum class CommitBehaviour + { + KeepEmptyAccounts, + RemoveEmptyAccounts + }; + + /// Default constructor; creates with a blank database prepopulated with the genesis block. + explicit State(u256 const& _accountStartNonce): State(_accountStartNonce, OverlayDB(), BaseState::Empty) {} + + /// Basic state object from database. + /// Use the default when you already have a database and you just want to make a State object + /// which uses it. If you have no preexisting database then set BaseState to something other + /// than BaseState::PreExisting in order to prepopulate the Trie. + explicit State(u256 const& _accountStartNonce, OverlayDB const& _db, BaseState _bs = BaseState::PreExisting); + + enum NullType { Null }; + State(NullType): State(Invalid256, OverlayDB(), BaseState::Empty) {} + + /// Copy state object. + State(State const& _s); + + /// Copy state object. + State& operator=(State const& _s); + + /// Open a DB - useful for passing into the constructor & keeping for other states that are necessary. + static OverlayDB openDB(std::string const& _path, h256 const& _genesisHash, WithExisting _we = WithExisting::Trust); + OverlayDB const& db() const { return m_db; } + OverlayDB& db() { return m_db; } + + /// Populate the state from the given AccountMap. Just uses dev::eth::commit(). + void populateFrom(AccountMap const& _map); + + /// @returns the set containing all addresses currently in use in Ethereum. + /// @warning This is slowslowslow. Don't use it unless you want to lock the object for seconds or minutes at a time. + /// @throws InterfaceNotSupported if compiled without ETH_FATDB. + std::unordered_map addresses() const; + + /// Execute a given transaction. + /// This will change the state accordingly. + std::pair execute(EnvInfo const& _envInfo, SealEngineFace const& _sealEngine, Transaction const& _t, Permanence _p = Permanence::Committed, OnOpFunc const& _onOp = OnOpFunc()); + + /// Check if the address is in use. + bool addressInUse(Address const& _address) const; + + /// Check if the account exists in the state and is non empty (nonce > 0 || balance > 0 || code nonempty). + /// These two notions are equivalent after EIP158. + bool accountNonemptyAndExisting(Address const& _address) const; + + /// Check if the address contains executable code. + bool addressHasCode(Address const& _address) const; + + /// Get an account's balance. + /// @returns 0 if the address has never been used. + u256 balance(Address const& _id) const; + + /// Add some amount to balance. + /// Will initialise the address if it has never been used. + void addBalance(Address const& _id, u256 const& _amount); + + /// Subtract the @p _value amount from the balance of @p _addr account. + /// @throws NotEnoughCash if the balance of the account is less than the + /// amount to be subtrackted (also in case the account does not exist). + void subBalance(Address const& _addr, u256 const& _value); + + /** + * @brief Transfers "the balance @a _value between two accounts. + * @param _from Account from which @a _value will be deducted. + * @param _to Account to which @a _value will be added. + * @param _value Amount to be transferred. + */ + void transferBalance(Address const& _from, Address const& _to, u256 const& _value) { subBalance(_from, _value); addBalance(_to, _value); } + + /// Get the root of the storage of an account. + h256 storageRoot(Address const& _contract) const; + + /// Get the value of a storage position of an account. + /// @returns 0 if no account exists at that address. + u256 storage(Address const& _contract, u256 const& _memory) const; + + /// Set the value of a storage position of an account. + void setStorage(Address const& _contract, u256 const& _location, u256 const& _value); + + /// Create a contract at the given address (with unset code and unchanged balance). + void createContract(Address const& _address); + + /// Sets the code of the account. Must only be called during / after contract creation. + void setNewCode(Address const& _address, bytes&& _code); + + /// Delete an account (used for processing suicides). + void kill(Address _a); + + /// Get the storage of an account. + /// @note This is expensive. Don't use it unless you need to. + /// @returns map of hashed keys to key-value pairs or empty map if no account exists at that address. + std::map> storage(Address const& _contract) const; + + /// Get the code of an account. + /// @returns bytes() if no account exists at that address. + /// @warning The reference to the code is only valid until the access to + /// other account. Do not keep it. + bytes const& code(Address const& _addr) const; + + /// Get the code hash of an account. + /// @returns EmptySHA3 if no account exists at that address or if there is no code associated with the address. + h256 codeHash(Address const& _contract) const; + + /// Get the byte-size of the code of an account. + /// @returns code(_contract).size(), but utilizes CodeSizeHash. + size_t codeSize(Address const& _contract) const; + + /// Increament the account nonce. + void incNonce(Address const& _id); + + /// Get the account nonce -- the number of transactions it has sent. + /// @returns 0 if the address has never been used. + u256 getNonce(Address const& _addr) const; + + /// The hash of the root of our state tree. + h256 rootHash() const { return m_state.root(); } + + /// Commit all changes waiting in the address cache to the DB. + /// @param _commitBehaviour whether or not to remove empty accounts during commit. + void commit(CommitBehaviour _commitBehaviour); + + /// Resets any uncommitted changes to the cache. + void setRoot(h256 const& _root); + + /// Get the account start nonce. May be required. + u256 const& accountStartNonce() const { return m_accountStartNonce; } + u256 const& requireAccountStartNonce() const; + void noteAccountStartNonce(u256 const& _actual); + + void clearCache(); + + std::unordered_map getCache(); + + /// Create a savepoint in the state changelog. /// + /// @return The savepoint index that can be used in rollback() function. + size_t savepoint() const; + + /// Revert all recent changes up to the given @p _savepoint savepoint. + void rollback(size_t _savepoint); + +private: + /// Turns all "touched" empty accounts into non-alive accounts. + void removeEmptyAccounts(); + + /// @returns the account at the given address or a null pointer if it does not exist. + /// The pointer is valid until the next access to the state or account. + Account const* account(Address const& _addr) const; + + /// @returns the account at the given address or a null pointer if it does not exist. + /// The pointer is valid until the next access to the state or account. + Account* account(Address const& _addr); + + /// Purges non-modified entries in m_cache if it grows too large. + void clearCacheIfTooLarge() const; + + void createAccount(Address const& _address, Account const&& _account); + + OverlayDB m_db; ///< Our overlay for the state tree. + SecureTrieDB m_state; ///< Our state tree, as an OverlayDB DB. + mutable std::unordered_map m_cache; ///< Our address cache. This stores the states of each address that has (or at least might have) been changed. + mutable std::vector
m_unchangedCacheEntries; ///< Tracks entries in m_cache that can potentially be purged if it grows too large. + mutable std::set
m_nonExistingAccountsCache; ///< Tracks addresses that are known to not exist. + AddressHash m_touched; ///< Tracks all addresses touched so far. + + u256 m_accountStartNonce; + + friend std::ostream& operator<<(std::ostream& _out, State const& _s); + std::vector m_changeLog; +}; + +std::ostream& operator<<(std::ostream& _out, State const& _s); + +template +AddressHash commit(AccountMap const& _cache, SecureTrieDB& _state) +{ + AddressHash ret; + for (auto const& i: _cache) + if (i.second.isDirty()) + { + if (!i.second.isAlive()) + _state.remove(i.first); + else + { + RLPStream s(4); + s << i.second.nonce() << i.second.balance(); + + if (i.second.storageOverlay().empty()) + { + assert(i.second.baseRoot()); + s.append(i.second.baseRoot()); + } + else + { + SecureTrieDB storageDB(_state.db(), i.second.baseRoot()); + for (auto const& j: i.second.storageOverlay()) + if (j.second) + storageDB.insert(j.first, rlp(j.second)); + else + storageDB.remove(j.first); + assert(storageDB.root()); + s.append(storageDB.root()); + } + + if (i.second.hasNewCode()) + { + h256 ch = i.second.codeHash(); + // Store the size of the code + CodeSizeCache::instance().store(ch, i.second.code().size()); + _state.db()->insert(ch, &i.second.code()); + s << ch; + } + else + s << i.second.codeHash(); + + _state.insert(i.first, &s.out()); + } + ret.insert(i.first); + } + return ret; +} + +} +} + diff --git a/libethereum/SystemContract.cpp b/libethereum/SystemContract.cpp new file mode 100644 index 0000000000..8f0598a43b --- /dev/null +++ b/libethereum/SystemContract.cpp @@ -0,0 +1,633 @@ +#include +#include + +#include "SystemContract.h" +#include +using namespace dev::eth; + +/* +* 对block中所有的交易的遍历,命中address+method hash 才更新 +*/ +void SystemContract::updateSystemContract(std::shared_ptr block) +{ + + + Timer t; + + LOG(TRACE)<<"SystemContract::updateSystemContract m_systemproxyaddress="<blockChain().number()<<","<blockChain().info(); + + DEV_WRITE_GUARDED(m_blocklock) + { + m_tempblock = block; + m_tempblock->clearCurrentBytes(); + m_tempblock->setEvmEventLog(true);//方便看log + LOG(TRACE)<<"SystemContract::updateSystemContract blocknumber="<info().number(); + } + + + + bool configChange=false,nodeChange=false,caChange=false,routeChange=false; + std::vector configChangeArg; + configChangeArg.push_back(""); + std::vector nodeChangeArg; + nodeChangeArg.push_back(""); + std::vector caChangeArg;// 下面push + std::vector routeChangeArg; + routeChangeArg.push_back(""); + + + bytes nodehash1=sha3("cancelNode(string)").ref().cropped(0, 4).toBytes(); + bytes nodehash2=sha3("registerNode(string,string,uint256,uint8,string,string,string,uint256)").ref().cropped(0, 4).toBytes(); + + bytes cahash1=sha3("updateStatus(string,uint8)").ref().cropped(0, 4).toBytes(); + bytes cahash2=sha3("update(string,string,string,uint256,uint256,uint8,string,string)").ref().cropped(0, 4).toBytes(); + + + Address configaction; + Address nodeAction; + Address caAction; + DEV_READ_GUARDED(m_lockroute) + { + configaction = getRoute("ConfigAction"); + nodeAction = getRoute("NodeAction"); + caAction= getRoute("CAAction"); + } + + + for(auto it = m_tempblock->pending().begin(); it != m_tempblock->pending().end(); ++it) + { + + bytes tempdata=it->data(); + bytesRef fundata=ref(tempdata); + bytes funhash=fundata.cropped(0, 4).toBytes(); + + + if( (it->to() == m_systemproxyaddress )&&(dev::ZeroAddress != m_systemproxyaddress) )//命中 + { + routeChange=true; + LOG(TRACE)<<"SystemContract::updateSystemContract SystemProxy setRoute! to="<to()<<",sha3="<sha3()) ; + } + else if( (it->to() == configaction ) &&(dev::ZeroAddress != configaction) )//命中 + { + configChange=true; + LOG(TRACE)<<"SystemContract::updateSystemContract ConfigAction set! to="<to()<<",sha3="<sha3()) ; + } + else if( (it->to() == nodeAction )&&(dev::ZeroAddress != nodeAction)&& ((funhash == nodehash1) || (funhash== nodehash2) ) )//命中 + { + nodeChange=true; + LOG(TRACE)<<"SystemContract::updateSystemContract NodeAction cancelNode|registerNode ! to="<to()<<",sha3="<sha3()) ; + } + else if( (it->to() == caAction )&&(dev::ZeroAddress != caAction)&& ( (funhash == cahash1) || (funhash== cahash2) ) )//命中 + { + string hashkey; + + bytes calldata=fundata.cropped(4, fundata.size()-4).toBytes(); + bytesConstRef o(&(calldata)); + + if( funhash == cahash2 ) + { + string pubkey; + string orgname; + u256 notbefore; + u256 notafter; + byte status;// uint8 + string white; + string black; + + dev::eth::ContractABI().abiOut<>(o,hashkey,pubkey,orgname,notbefore,notafter,status,white,black); + } + else if( funhash == cahash1 ) + { + byte status; + dev::eth::ContractABI().abiOut<>(o,hashkey,status); + } + + caChangeArg.push_back(hashkey); + caChange=true; + LOG(TRACE)<<"SystemContract::updateSystemContract CAAction updateStatus|update ! hash="<first) ) + { + ok=true; + changeArg=configChangeArg; + } + else if( (routeChange && "route"==it->first) ) + { + ok=true; + changeArg=routeChangeArg; + } + else if( (nodeChange && "node"==it->first) ) + { + ok=true; + changeArg=nodeChangeArg; + } + else if( (caChange && "ca"==it->first) ) + { + ok=true; + changeArg=caChangeArg; + } + + if( ok && (it->second.size() ) ) + { + LOG(TRACE) << "SystemContract::updateSystemContract Change:" << it->first; + for (std::vector< std::function >::iterator cbit = it->second.begin(); cbit != it->second.end(); ++cbit) + { + for( std::vector::iterator argit=changeArg.begin();argit !=changeArg.end();argit++) + { + LOG(TRACE) << "SystemContract::updateSystemContract cb=" << &(*cbit)<<",arg="<<*argit; + (*cbit)(*argit); + } + } + } + }// + } + + LOG(TRACE)<<"SystemContract::updateSystemContract took:"<<(t.elapsed()*1000000); + +} + +void SystemContract::updateRoute() +{ + + /*********************构建actionlist***********************/ + DEV_WRITE_GUARDED(m_lockroute) + { + bytes inputdata5 = abiIn("getRouteSize()"); + ExecutionResult ret5 = call(m_systemproxyaddress, inputdata5); + u256 routesize = abiOut(ret5.output); + LOG(TRACE) << "SystemContract::updateRoute RouteSize" << routesize; + + m_routes.clear(); + for ( size_t i = 0; i < (size_t)routesize; i++) + { + //第一步,先拿到route name + bytes inputdata6 = abiIn("getRouteNameByIndex(uint256)", (u256)i); + ExecutionResult ret6 = call(m_systemproxyaddress, inputdata6); + string routename = abiOut(ret6.output); + //第二步,拿到 route + bytes inputdata7 = abiIn("getRoute(string)", routename); + ExecutionResult ret7 = call(m_systemproxyaddress, inputdata7); + Address route = abiOut
(ret7.output); + + m_routes.push_back({route, routename}); + LOG(TRACE) << "SystemContract::updateRoute [" << i << "]=0x" << toString(route) << "," << routename; + }//for + } + DEV_WRITE_GUARDED(m_lockfilter) + { + m_transactionfilter.filter=getRoute("TransactionFilterChain"); + m_transactionfilter.name="TransactionFilterChain"; + + m_filterchecktranscache.clear(); + } + +} + +void SystemContract::updateNode( ) +{ + + DEV_WRITE_GUARDED(m_locknode) + { + this->getNodeFromContract(std::bind(&SystemContract::call,this,std::placeholders::_1,std::placeholders::_2,std::placeholders::_3),m_nodelist); + + LOG(TRACE) << "SystemContract::updateNode m_nodelist.size=" << m_nodelist.size(); + } + + +} +void SystemContract::updateConfig() +{ + //没有缓存 +} +void SystemContract::updateCa( ) +{ + DEV_WRITE_GUARDED(m_lockca) + { + + Address caAction; + + DEV_READ_GUARDED(m_lockroute) + { + caAction = getRoute("CAAction"); + } + if ( Address() != caAction ) + { + bytes inputdata1 = abiIn("getHashsLength()"); + + ExecutionResult ret1 = call(caAction, inputdata1); + u256 hashslen = abiOut(ret1.output); + LOG(TRACE) << "SystemContract::updateCa "<(ret2.output); + + //第二步,拿到ca 信息 + std::string hash; // 节点机构证书哈希 + std::string pubkey;// 公钥 + std::string orgname; // 机构名称 + u256 notbefore; + u256 notafter; + byte status; + u256 blocknumber; + + bytes inputdata4 = abiIn("get(string)",hashkey); + ExecutionResult ret4 = call(caAction, inputdata4); + + bytesConstRef o(&(ret4.output)); + dev::eth::ContractABI().abiOut<>(o,hash,pubkey,orgname,notbefore,notafter,status,blocknumber); + + string white; + string black; + + bytes inputdata5 = abiIn("getIp(string)",hashkey); + ExecutionResult ret5 = call(caAction, inputdata5); + + bytesConstRef o2(&(ret5.output)); + dev::eth::ContractABI().abiOut<>(o2,white,black); + + CaInfo cainfo; + cainfo.hash=hash; + cainfo.pubkey=pubkey; + cainfo.orgname=orgname; + cainfo.notbefore=notbefore; + cainfo.notafter=notafter; + cainfo.status=status?CaStatus::Ok:CaStatus::Invalid; + cainfo.blocknumber=blocknumber; + cainfo.white=white; + cainfo.black=black; + + m_calist.insert(pair(hash,cainfo) ); + LOG(TRACE) << "SystemContract::updateCa Ca[" << i << "]=" << cainfo.toString(); + + }//for + } + else + { + LOG(INFO)<<"SystemContract::updateCa No CAAction!!!!!!!!!!!!"; + } + + } +} + +void SystemContract::getNodeFromContract(std::function _call,std::vector< NodeConnParams> & _nodelist) +{ + Address nodeAction; + DEV_READ_GUARDED(m_lockroute) + { + nodeAction = getRoute("NodeAction"); + } + if ( Address() != nodeAction ) + { + bytes inputdata1 = abiIn("getNodeIdsLength()"); + + ExecutionResult ret1 = _call(nodeAction, inputdata1,false); + u256 nodeidslen = abiOut(ret1.output); + LOG(TRACE) << "SystemContract::getNodeFromContract "<(ret2.output); + + //第二步,拿到node 信息 + + string ip = ""; //节点ip + u256 port = 0; //节点端口 + u256 category = 0; //NodeConnParams应该定义枚举 + string desc; //节点描述 + string cahash = ""; //节点的机构信息 + string agencyinfo=""; + u256 idx; //节点索引 + u256 blocknumber; + + bytes inputdata4 = abiIn("getNode(string)",nodeid); + ExecutionResult ret4 = _call(nodeAction, inputdata4,false); + + bytesConstRef o(&(ret4.output)); + dev::eth::ContractABI().abiOut<>(o,ip,port,category,desc,cahash,agencyinfo,blocknumber); + + bytes inputdata5 = abiIn("getNodeIdx(string)",nodeid); + ExecutionResult ret5 = _call(nodeAction, inputdata5,false); + + bytesConstRef o2(&(ret5.output)); + dev::eth::ContractABI().abiOut<>(o2,idx); + + + NodeConnParams nodeconnparam; + nodeconnparam._sNodeId = nodeid; + nodeconnparam._sAgencyInfo = agencyinfo; + nodeconnparam._sIP = ip; + nodeconnparam._iPort =(int) port; + nodeconnparam._iIdentityType = (int)category; + nodeconnparam._sAgencyDesc=desc; + nodeconnparam._sCAhash=cahash; + nodeconnparam._iIdx=idx; + + _nodelist.push_back(nodeconnparam); + LOG(TRACE) << "SystemContract::updateNode Node[" << i << "]=" << nodeconnparam.toString(); + + }//for + + //排序连续 + sort(_nodelist.begin(), _nodelist.end(), [&](const NodeConnParams & a, const NodeConnParams & b) { + return a._iIdx < b._iIdx; + }); + + } + else + { + LOG(INFO)<<"SystemContract::getNodeFromContract No NodeAction!!!!!!!!!!!!"; + } + +} + +void SystemContract::tempGetAllNode(int _blocknumber,std::vector< NodeConnParams> & _nodelist ) +{ + + if( _blocknumber<0 ) + _blocknumber=m_client->blockChain().number(); + LOG(TRACE)<<"SystemContract::tempGetAllNode blocknumber="<<_blocknumber; + + + Block tempblock = m_client->block(_blocknumber ); + tempblock.setEvmEventLog(true); + + + auto tempCall = [&](Address const& _to, bytes const& _inputdata,bool ) { + ExecutionResult ret; + try + { + srand((unsigned)utcTime()); + struct timeval tv; + gettimeofday(&tv, NULL); + u256 nonce = (u256)(rand() + rand() + tv.tv_usec); + + u256 gas = tempblock.gasLimitRemaining() ; + u256 gasPrice = 100000000; + Transaction t(0, gasPrice, gas, _to, _inputdata, nonce); + t.forceSender(m_god); + ret = tempblock.execute(m_client->blockChain().lastHashes(), t, Permanence::Reverted); + + } + catch (...) + { + // TODO: Some sort of notification of failure. + LOG(ERROR) << boost::current_exception_diagnostic_information() << endl; + LOG(INFO) << "SystemContract::tempCall call Fail!" << toString(_inputdata); + } + return ret; + }; + + getNodeFromContract(tempCall,_nodelist); + LOG(TRACE) << "SystemContract::tempGetAllNode _nodelist.size=" << _nodelist.size(); + +} +void SystemContract::getAllNode(int _blocknumber/*-1 代表最新块*/ ,std::vector< NodeConnParams> & _nodevector ) +{ + DEV_READ_GUARDED(m_locknode) + { + + DEV_READ_GUARDED(m_blocklock) + { + LOG(TRACE)<< "SystemContract::getAllNode _blocknumber=" <<_blocknumber + <<",m_tempblock.info().number()="<info().number()<<",m_nodelist.size()="<info().number()) || ( _blocknumber < 0 ) ) + { + for( size_t i=0;iinfo().number(); + } + +} + +void SystemContract::getCaInfo(string _hash,CaInfo & _cainfo) +{ + DEV_READ_GUARDED(m_lockca) + { + if( m_calist.find(_hash) != m_calist.end() ) + _cainfo=m_calist.find(_hash)->second; + } +}//function + + + +Address SystemContract::getRoute(const string & _route) const +{ + + //非线程安全 + for ( size_t i = 0; i < m_routes.size(); i++) + { + if ( m_routes[i].name == _route ) + { + return m_routes[i].action; + } + }//for + + return Address(); +} + + +h256 SystemContract::filterCheckTransCacheKey(const Transaction & _t) const +{ + RLPStream s; + s << _t.safeSender() << _t.from() << _t.to() << toString(_t.data()) ;//<< _t.randomid() ; + return dev::sha3(s.out()); +} + +u256 SystemContract::transactionFilterCheck(const Transaction & transaction) { + + LOG(TRACE)<<"SystemContract::transactionFilterCheck"; + + if( isGod(transaction.safeSender())) + { + return (u256)SystemContractCode::Ok; + } + + + + u256 checkresult = (u256)SystemContractCode::Other; + h256 key = filterCheckTransCacheKey(transaction); + + if ( m_filterchecktranscache.find(key) != m_filterchecktranscache.end() ) //命中cache + { + checkresult = m_filterchecktranscache.find(key)->second; + + } + else{ + string input = toHex(transaction.data()); + string func = input.substr(0,8); + + bytes inputBytes = dev::eth::ContractABI().abiIn( + "process(address,address,address,string,string)", + transaction.safeSender(), transaction.from(), transaction.to(), func, + input); + + ExecutionResult res = call(m_transactionfilter.filter, inputBytes); + + if(res.output.empty()) { + //未部署系统合约或权限合约 + checkresult=(u256)SystemContractCode::Ok; + } + else{ + bool result = false; + dev::eth::ContractABI().abiOut(bytesConstRef(&res.output), result); + checkresult=result?((u256)SystemContractCode::Ok):(u256)SystemContractCode::Other; + } + + m_filterchecktranscache.insert(pair(key, checkresult)); //更新cache + } + + if ( (u256)SystemContractCode::Ok != checkresult ) + { + LOG(INFO) << "SystemContract::transactionFilterCheck Fail!" << toJS(transaction.sha3()) << ",from=" << toJS(transaction.from()); + } + else{ + LOG(TRACE) << "SystemContract::transactionFilterCheck Suc!" << toJS(transaction.sha3()) << ",from=" << toJS(transaction.from()); + } + + + + return checkresult; + +} + + +void SystemContract::updateCache(Address ) { + + +} + + +bool SystemContract::isAdmin(const Address &) +{ + return false; +} + + +bool SystemContract::getValue(const string _key, string & _value) +{ + DEV_READ_GUARDED(m_lockroute) + { + Address action = getRoute("ConfigAction"); + if ( Address() != action ) + { + bytes inputdata = abiIn("get(string)", _key); + + ExecutionResult ret = call(action, inputdata); + _value = abiOut(ret.output); + + } + else + { + LOG(TRACE) << "SystemContract::getValue NO ConfigAction!" ; + } + } + return true; +} + + +ExecutionResult SystemContract::call(Address const& _to, bytes const& _inputdata, bool ) +{ + + + ExecutionResult ret; + try + { + + srand((unsigned)utcTime()); + struct timeval tv; + gettimeofday(&tv, NULL); + u256 nonce = (u256)(rand() + rand() + tv.tv_usec); + + DEV_WRITE_GUARDED(m_blocklock) + { + u256 gas = m_tempblock->gasLimitRemaining() ; + + u256 gasPrice = 100000000; + Transaction t(0, gasPrice, gas, _to, _inputdata, nonce); + t.forceSender(m_god); + ret = m_tempblock->execute(m_client->blockChain().lastHashes(), t, Permanence::Reverted); + } + + + } + catch (...) + { + // TODO: Some sort of notification of failure. + LOG(ERROR) << boost::current_exception_diagnostic_information() << endl; + LOG(INFO) << "SystemContract::call Fail!" << toString(_inputdata); + } + return ret; +} diff --git a/libethereum/SystemContract.h b/libethereum/SystemContract.h new file mode 100644 index 0000000000..fdbfea4e9e --- /dev/null +++ b/libethereum/SystemContract.h @@ -0,0 +1,135 @@ + + + +#pragma once +#include +#include +#include +#include +#include "Client.h" +#include "SystemContractApi.h" + +using namespace std; +using namespace dev; + +using namespace dev::eth; + + +namespace dev +{ +namespace eth +{ + +enum class FilterType { + Account, + Node +}; + +class SystemContractApi; +enum class SystemContractCode; + +using Address = h160; + + +/** + * @brief Main API hub for System Contract + */ +//过滤器 +struct SystemFilter { + Address filter; + string name; +}; + +struct SystemAction { + Address action; + string name; +}; + +class SystemContract: public SystemContractApi +{ +public: + /// Constructor. + SystemContract(const Address _address, const Address _god, Client* _client) : SystemContractApi( _address, _god), m_client(_client), m_tempblock(0) + { + + std::shared_ptr tempblock(new Block(0)); + *tempblock = m_client->block(m_client->blockChain().number()); + updateSystemContract(tempblock); + } + + /// Destructor. + virtual ~SystemContract() {} + + //所有的filter检查 + virtual u256 transactionFilterCheck(const Transaction & transaction) override; + + + + virtual void updateCache(Address address) override; + + //是否是链的管理员 + virtual bool isAdmin(const Address & _address) override; + //获取全网配置项 + virtual bool getValue(const string _key, string & _value) override; + + // 获取节点列表 里面已经含有idx + virtual void getAllNode(int _blocknumber/*<0 代表最新块*/ ,std::vector< NodeConnParams> & _nodelist )override; + virtual u256 getBlockChainNumber()override; + virtual void getCaInfo(string _hash,CaInfo & _cainfo) override; + virtual void updateSystemContract(std::shared_ptr block) override; + +private: + + + + Client* m_client; + + mutable SharedMutex m_blocklock; + + std::shared_ptr m_tempblock; + + mutable SharedMutex m_lockroute; + std::vector m_routes; + + mutable SharedMutex m_lockfilter; + SystemFilter m_transactionfilter; + std::map m_filterchecktranscache; + + + + mutable SharedMutex m_locknode; + std::vector< NodeConnParams> m_nodelist; + + mutable SharedMutex m_lockca; + std::map m_calist; + + ExecutionResult call(Address const& _to, bytes const& _inputdata, bool cache = false) ; + + Address getRoute(const string & _route)const; + + h256 filterCheckTransCacheKey(const Transaction & _t) const ; + + void updateRoute( ); + void updateNode( ); + void tempGetAllNode(int _blocknumber,std::vector< NodeConnParams> & _nodevector); + void updateConfig( ); + void updateCa( ); + + + + void getNodeFromContract(std::function,std::vector< NodeConnParams> & _nodelist); + + struct CallCache { + std::map res; + }; + + std::map _callCaches; +}; + + + +} +} + + + diff --git a/libethereum/SystemContractApi.cpp b/libethereum/SystemContractApi.cpp new file mode 100644 index 0000000000..3c3c0297e2 --- /dev/null +++ b/libethereum/SystemContractApi.cpp @@ -0,0 +1,10 @@ +#include "SystemContractApi.h" +#include "SystemContract.h" + +using namespace dev::eth; + + +std::shared_ptr SystemContractApiFactory::create(const Address _address, const Address _god, Client* _client) +{ + return shared_ptr(new SystemContract(_address, _god, _client)); +} \ No newline at end of file diff --git a/libethereum/SystemContractApi.h b/libethereum/SystemContractApi.h new file mode 100644 index 0000000000..ac07e0077b --- /dev/null +++ b/libethereum/SystemContractApi.h @@ -0,0 +1,146 @@ + + +#pragma once + +#include +#include +#include + +#include "Client.h" +#include "Transaction.h" +#include "NodeConnParamsManager.h" +#include + +using namespace std; +using namespace dev::eth; + +namespace dev +{ +namespace eth +{ + +class Client; + + + +enum class SystemContractCode +{ + Ok, + NoDeployPermission, //没有部署合约权限 + NoTxPermission, //没有交易权限 + NoCallPermission, //没有查询Call权限 + NoGraoupAdmin, //不是组管理员帐号 + NoAdmin, //不是链管理员帐号 + InterveneAccount,//帐号被干预 + InterveneContract,//合约被干预 + InterveneContractFunc,//合约接口被干预 + NodeNoRegister, //节点未登记 + NodeNoregister, //节点未登记 + NodeCAError, //节点机构证书无效 + NodeCANoExist, //节点机构证书不存在 + NodeSignError, //节点签名错误 + Other +}; + +using Address = h160; + +/** + * @brief Main API hub for System Contract + */ + + + +class SystemContractApi +{ + protected: + Address m_systemproxyaddress; + Address m_god; + /*系统合约变更回调 + key : config| filter | node | ca */ + mutable SharedMutex m_lockcbs; + std::map > > m_cbs; + + + + public: + + + bool isGod(const Address _address ) const + { + return (m_god!=Address() && m_god == _address)?true:false; + } + /// Constructor. + SystemContractApi( const Address _address,const Address _god):m_systemproxyaddress(_address),m_god(_god) {} + + /// Destructor. + virtual ~SystemContractApi() {} + + + virtual u256 transactionFilterCheck(const Transaction &) { return (u256)SystemContractCode::Ok; }; + + //更新缓存 + virtual void updateCache(Address) {}; + + + virtual void getAllNode(int /*<0 代表最新块*/ ,std::vector< NodeConnParams> & ) + { + } + virtual u256 getBlockChainNumber() + { + return 0; + } + virtual void getCaInfo(string ,CaInfo & ) + { + } + //注册回调 + virtual void addCBOn(string _name/*route | config | node | ca*/,std::function _cb) + { + DEV_WRITE_GUARDED(m_lockcbs) + { + if( m_cbs.find(_name ) != m_cbs.end() ) + { + m_cbs.find(_name )->second.push_back(_cb); + } + else + { + std::vector< std::function > cbs; + cbs.push_back(_cb); + m_cbs.insert( std::pair >>(_name,cbs)); + } + } + + } + + virtual void updateSystemContract(std::shared_ptr) + { + } + + //是否是链的管理员 + virtual bool isAdmin(const Address & ) + { + return true; + } + + //获取全网配置项 + virtual bool getValue(const string ,string & ) + { + return true; + } + + //get the contract address + virtual Address getRoute(const string & _route) const=0; + +}; + +class SystemContractApiFactory +{ + public: + static std::shared_ptr create(const Address _address, const Address _god, Client* _client); +}; + + +} +} + + + diff --git a/libethereum/Transaction.cpp b/libethereum/Transaction.cpp new file mode 100644 index 0000000000..9c6f2f62a7 --- /dev/null +++ b/libethereum/Transaction.cpp @@ -0,0 +1,100 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Transaction.cpp + * @author Gav Wood + * @date 2014 + */ + +#include + +#include +#include +#include +#include +#include "Interface.h" +#include "Transaction.h" +using namespace std; +using namespace dev; +using namespace dev::eth; + +#define ETH_ADDRESS_DEBUG 0 + +std::ostream& dev::eth::operator<<(std::ostream& _out, ExecutionResult const& _er) +{ + _out << "{" << _er.gasUsed << ", " << _er.newAddress << ", " << toHex(_er.output) << "}"; + return _out; +} + +TransactionException dev::eth::toTransactionException(Exception const& _e) +{ + // Basic Transaction exceptions + if (!!dynamic_cast(&_e)) + return TransactionException::BadRLP; + if (!!dynamic_cast(&_e)) + return TransactionException::OutOfGasIntrinsic; + if (!!dynamic_cast(&_e)) + return TransactionException::InvalidSignature; + // Executive exceptions + if (!!dynamic_cast(&_e)) + return TransactionException::OutOfGasBase; + if (!!dynamic_cast(&_e)) + return TransactionException::InvalidNonce; + if (!!dynamic_cast(&_e)) + return TransactionException::NotEnoughCash; + if (!!dynamic_cast(&_e)) + return TransactionException::BlockGasLimitReached; + // VM execution exceptions + if (!!dynamic_cast(&_e)) + return TransactionException::BadInstruction; + if (!!dynamic_cast(&_e)) + return TransactionException::BadJumpDestination; + if (!!dynamic_cast(&_e)) + return TransactionException::OutOfGas; + if (!!dynamic_cast(&_e)) + return TransactionException::OutOfStack; + if (!!dynamic_cast(&_e)) + return TransactionException::StackUnderflow; + return TransactionException::Unknown; +} + +std::ostream& dev::eth::operator<<(std::ostream& _out, TransactionException const& _er) +{ + switch (_er) + { + case TransactionException::None: _out << "None"; break; + case TransactionException::BadRLP: _out << "BadRLP"; break; + case TransactionException::InvalidFormat: _out << "InvalidFormat"; break; + case TransactionException::OutOfGasIntrinsic: _out << "OutOfGasIntrinsic"; break; + case TransactionException::InvalidSignature: _out << "InvalidSignature"; break; + case TransactionException::InvalidNonce: _out << "InvalidNonce"; break; + case TransactionException::NotEnoughCash: _out << "NotEnoughCash"; break; + case TransactionException::OutOfGasBase: _out << "OutOfGasBase"; break; + case TransactionException::BlockGasLimitReached: _out << "BlockGasLimitReached"; break; + case TransactionException::BadInstruction: _out << "BadInstruction"; break; + case TransactionException::BadJumpDestination: _out << "BadJumpDestination"; break; + case TransactionException::OutOfGas: _out << "OutOfGas"; break; + case TransactionException::OutOfStack: _out << "OutOfStack"; break; + case TransactionException::StackUnderflow: _out << "StackUnderflow"; break; + default: _out << "Unknown"; break; + } + return _out; +} + +Transaction::Transaction(bytesConstRef _rlpData, CheckTransaction _checkSig): + TransactionBase(_rlpData, _checkSig) +{ +} diff --git a/libethereum/Transaction.h b/libethereum/Transaction.h new file mode 100644 index 0000000000..cbe669ba7f --- /dev/null +++ b/libethereum/Transaction.h @@ -0,0 +1,154 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Transaction.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace dev +{ +namespace eth +{ + +enum class TransactionException +{ + None = 0, + Unknown, + BadRLP, + InvalidFormat, + OutOfGasIntrinsic, ///< Too little gas to pay for the base transaction cost. + InvalidSignature, + InvalidNonce, + NotEnoughCash, + OutOfGasBase, ///< Too little gas to pay for the base transaction cost. + BlockGasLimitReached, + BadInstruction, + BadJumpDestination, + OutOfGas, ///< Ran out of gas executing code of the transaction. + OutOfStack, ///< Ran out of stack executing code of the transaction. + StackUnderflow, + NonceCheckFail, // noncecheck ok() == false + BlockLimitCheckFail, + FilterCheckFail, + NoDeployPermission, + NoCallPermission, + NoTxPermission + +}; + +enum class CodeDeposit +{ + None = 0, + Failed, + Success +}; + +struct VMException; + +TransactionException toTransactionException(Exception const& _e); +std::ostream& operator<<(std::ostream& _out, TransactionException const& _er); + +/// Description of the result of executing a transaction. +struct ExecutionResult +{ + u256 gasUsed = 0; + TransactionException excepted = TransactionException::Unknown; + Address newAddress; + bytes output; + CodeDeposit codeDeposit = CodeDeposit::None; ///< Failed if an attempted deposit failed due to lack of gas. + u256 gasRefunded = 0; + unsigned depositSize = 0; ///< Amount of code of the creation's attempted deposit. + u256 gasForDeposit; ///< Amount of gas remaining for the code deposit phase. +}; + +std::ostream& operator<<(std::ostream& _out, ExecutionResult const& _er); + +/// Encodes a transaction, ready to be exported to or freshly imported from RLP. +class Transaction: public TransactionBase +{ +public: + /// Constructs a null transaction. + Transaction() {} + + /// Constructs from a transaction skeleton & optional secret. + Transaction(TransactionSkeleton const& _ts, Secret const& _s = Secret()): TransactionBase(_ts, _s) {} + + /// Constructs a signed message-call transaction. + Transaction(u256 const& _value, u256 const& _gasPrice, u256 const& _gas, Address const& _dest, bytes const& _data, u256 const& _randomid, Secret const& _secret): + TransactionBase(_value, _gasPrice, _gas, _dest, _data, _randomid, _secret) + {} + + /// Constructs a signed contract-creation transaction. + Transaction(u256 const& _value, u256 const& _gasPrice, u256 const& _gas, bytes const& _data, u256 const& _randomid, Secret const& _secret): + TransactionBase(_value, _gasPrice, _gas, _data, _randomid, _secret) + {} + + /// Constructs an unsigned message-call transaction. + Transaction(u256 const& _value, u256 const& _gasPrice, u256 const& _gas, Address const& _dest, bytes const& _data, u256 const& _randomid = Invalid256): + TransactionBase(_value, _gasPrice, _gas, _dest, _data, _randomid) + {} + + /// Constructs an unsigned contract-creation transaction. + Transaction(u256 const& _value, u256 const& _gasPrice, u256 const& _gas, bytes const& _data, u256 const& _randomid = Invalid256): + TransactionBase(_value, _gasPrice, _gas, _data, _randomid) + {} + + /// Constructs a transaction from the given RLP. + explicit Transaction(bytesConstRef _rlp, CheckTransaction _checkSig); + + /// Constructs a transaction from the given RLP. + explicit Transaction(bytes const& _rlp, CheckTransaction _checkSig): Transaction(&_rlp, _checkSig) {} +}; + +/// Nice name for vector of Transaction. +using Transactions = std::vector; + +class LocalisedTransaction: public Transaction +{ +public: + LocalisedTransaction( + Transaction const& _t, + h256 const& _blockHash, + unsigned _transactionIndex, + BlockNumber _blockNumber = 0 + ): + Transaction(_t), + m_blockHash(_blockHash), + m_transactionIndex(_transactionIndex), + m_blockNumber(_blockNumber) + {} + + h256 const& blockHash() const { return m_blockHash; } + unsigned transactionIndex() const { return m_transactionIndex; } + BlockNumber blockNumber() const { return m_blockNumber; } + +private: + h256 m_blockHash; + unsigned m_transactionIndex; + BlockNumber m_blockNumber; +}; + +} +} diff --git a/libethereum/TransactionQueue.cpp b/libethereum/TransactionQueue.cpp new file mode 100644 index 0000000000..5a20b2152e --- /dev/null +++ b/libethereum/TransactionQueue.cpp @@ -0,0 +1,477 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file TransactionQueue.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "TransactionQueue.h" + + +#include +#include "Transaction.h" +#include +using namespace std; +using namespace dev; +using namespace dev::eth; +#include + + +const size_t c_maxVerificationQueueSize = 8192; + +TransactionQueue::TransactionQueue(std::shared_ptr _interface, unsigned _limit, unsigned _futureLimit): + m_current(PriorityCompare { *this }), + m_limit(_limit), + m_futureLimit(_futureLimit) +{ + m_interface = _interface; + unsigned verifierThreads = std::max(thread::hardware_concurrency(), 3U) - 2U; + for (unsigned i = 0; i < verifierThreads; ++i) + m_verifiers.emplace_back([ = ]() { + setThreadName("txcheck" + toString(i)); + this->verifierBody(); + }); +} + +TransactionQueue::~TransactionQueue() +{ + m_aborting = true; + m_queueReady.notify_all(); + for (auto& i : m_verifiers) + i.join(); + + m_verifiers.clear(); +} + +ImportResult TransactionQueue::import(bytesConstRef _transactionRLP, IfDropped _ik) +{ + LOG(TRACE) << "TransactionQueue::import "; + // Check if we already know this transaction. + h256 h = sha3(_transactionRLP); + + Transaction t; + ImportResult ir; + { + UpgradableGuard l(m_lock); + + ir = check_WITH_LOCK(h, _ik); + if (ir != ImportResult::Success) + return ir; + + try + { + // Check validity of _transactionRLP as a transaction. To do this we just deserialise and attempt to determine the sender. + // If it doesn't work, the signature is bad. + // The transaction's nonce may yet be invalid (or, it could be "valid" but we may be missing a marginally older transaction). + + + t = Transaction(_transactionRLP, CheckTransaction::Everything); + t.setImportTime(utcTime()); + + + UpgradeGuard ul(l); + LOG(TRACE) << "Importing" << t; + ir = manageImport_WITH_LOCK(h, t); + } + catch (...) + { + LOG(ERROR) << boost::current_exception_diagnostic_information() << endl; + return ImportResult::Malformed; + } + } + return ir; +} + +ImportResult TransactionQueue::check_WITH_LOCK(h256 const& _h, IfDropped _ik) +{ + + if (m_known.count(_h)) + return ImportResult::AlreadyKnown; + + if (m_dropped.count(_h) && _ik == IfDropped::Ignore) + return ImportResult::AlreadyInChain; + + return ImportResult::Success; +} + +ImportResult TransactionQueue::import(Transaction const& _transaction, IfDropped _ik) +{ + // Check if we already know this transaction. + h256 h = _transaction.sha3(WithSignature); + + ImportResult ret; + { + UpgradableGuard l(m_lock); + auto ir = check_WITH_LOCK(h, _ik); + if (ir != ImportResult::Success) + return ir; + + { + _transaction.safeSender(); // Perform EC recovery outside of the write lock + + UpgradeGuard ul(l); + ret = manageImport_WITH_LOCK(h, _transaction); + } + } + return ret; +} + +Transactions TransactionQueue::topTransactions(unsigned _limit, h256Hash const& _avoid) const +{ + ReadGuard l(m_lock); + Transactions ret; + for (auto t = m_current.begin(); ret.size() < _limit && t != m_current.end(); ++t) + if (!_avoid.count(t->transaction.sha3())) + { + ret.push_back(t->transaction); + LOG(TRACE) << "TransactionQueue::topTransactions " << t->transaction.sha3() << ",nonce=" << t->transaction.randomid(); + } + + LOG(TRACE) << "TransactionQueue::topTransactions " << ret.size(); + + return ret; +} + +Transactions TransactionQueue::allTransactions() const { + ReadGuard l(m_lock); + Transactions ret; + for (auto t = m_current.begin(); t != m_current.end(); ++t) { + ret.push_back(t->transaction); + } + return ret; +} + +h256Hash TransactionQueue::knownTransactions() const +{ + ReadGuard l(m_lock); + return m_known; +} + +ImportResult TransactionQueue::manageImport_WITH_LOCK(h256 const& _h, Transaction const& _transaction) +{ + LOG(TRACE) << " TransactionQueue::manageImport_WITH_LOCK " << _transaction.sha3(); + + try + { + assert(_h == _transaction.sha3()); + + //回调client noncecheck类 检查nonce 这里判断是,nonce是否在chain上已经出现过 + if ( false == m_interface->isNonceOk(_transaction)) + { + + LOG(WARNING) << "TransactionQueue::manageImport_WITH_LOCK NonceCheck fail! " << _transaction.sha3() << "," << _transaction.randomid(); + return ImportResult::NonceCheckFail; + } + + if ( false == m_interface->isBlockLimitOk(_transaction)) + { + LOG(WARNING) << "TransactionQueue::manageImport_WITH_LOCK BlockLimit fail! " << _transaction.sha3() << "," << _transaction.blockLimit(); + return ImportResult::BlockLimitCheckFail; + } + + + // Remove any prior transaction with the same nonce but a lower gas price. + // Bomb out if there's a prior transaction with higher gas price. + auto cs = m_currentByAddressAndNonce.find(_transaction.from()); + if (cs != m_currentByAddressAndNonce.end()) + { + auto t = cs->second.find(_transaction.randomid()); + if (t != cs->second.end()) + { + if (_transaction.gasPrice() < (*t->second).transaction.gasPrice()) + return ImportResult::OverbidGasPrice; + else + { + h256 dropped = (*t->second).transaction.sha3(); + remove_WITH_LOCK(dropped); + LOG(WARNING) << _transaction.from() << "," << dropped << " Dropping Same Nonce" << _transaction.randomid(); + m_onReplaced(dropped); + } + } + } + auto fs = m_future.find(_transaction.from()); + if (fs != m_future.end()) + { + auto t = fs->second.find(_transaction.randomid()); + if (t != fs->second.end()) + { + if (_transaction.gasPrice() < t->second.transaction.gasPrice()) + return ImportResult::OverbidGasPrice; + else + { + fs->second.erase(t); + --m_futureSize; + if (fs->second.empty()) + m_future.erase(fs); + } + } + } + // If valid, append to transactions. + insertCurrent_WITH_LOCK(make_pair(_h, _transaction)); + LOG(TRACE) << "Queued vaguely legit-looking transaction" << _h; + + while (m_current.size() > m_limit) + { + + LOG(WARNING) << "Dropping out of bounds transaction" << _h; + remove_WITH_LOCK(m_current.rbegin()->transaction.sha3()); + } + + m_onReady(); + } + catch (Exception const& _e) + { + LOG(ERROR) << "Ignoring invalid transaction: " << diagnostic_information(_e); + return ImportResult::Malformed; + } + catch (std::exception const& _e) + { + LOG(ERROR) << "Ignoring invalid transaction: " << _e.what(); + return ImportResult::Malformed; + } + + return ImportResult::Success; +} + +u256 TransactionQueue::maxNonce(Address const& _a) const +{ + ReadGuard l(m_lock); + return maxNonce_WITH_LOCK(_a); +} + +u256 TransactionQueue::maxNonce_WITH_LOCK(Address const& _a) const +{ + u256 ret = 0; + auto cs = m_currentByAddressAndNonce.find(_a); + if (cs != m_currentByAddressAndNonce.end() && !cs->second.empty()) + ret = cs->second.rbegin()->first + 1; + auto fs = m_future.find(_a); + if (fs != m_future.end() && !fs->second.empty()) + ret = std::max(ret, fs->second.rbegin()->first + 1); + return ret; +} + +void TransactionQueue::insertCurrent_WITH_LOCK(std::pair const& _p) +{ + LOG(TRACE) << " TransactionQueue::insertCurrent_WITH_LOCK " << _p.first; + + if (m_currentByHash.count(_p.first)) + { + LOG(WARNING) << "Transaction hash" << _p.first << "already in current?!"; + return; + } + + Transaction const& t = _p.second; + // Insert into current + auto inserted = m_currentByAddressAndNonce[t.from()].insert(std::make_pair(t.randomid(), PriorityQueue::iterator())); + PriorityQueue::iterator handle = m_current.emplace(VerifiedTransaction(t)); + inserted.first->second = handle; + m_currentByHash[_p.first] = handle; + + // Move following transactions from future to current + makeCurrent_WITH_LOCK(t); + m_known.insert(_p.first); + + +} + +bool TransactionQueue::remove_WITH_LOCK(h256 const& _txHash) +{ + auto t = m_currentByHash.find(_txHash); + if (t == m_currentByHash.end()) + return false; + + Address from = (*t->second).transaction.from(); + auto it = m_currentByAddressAndNonce.find(from); + assert (it != m_currentByAddressAndNonce.end()); + it->second.erase((*t->second).transaction.randomid()); + m_current.erase(t->second); + m_currentByHash.erase(t); + if (it->second.empty()) + m_currentByAddressAndNonce.erase(it); + m_known.erase(_txHash); + + LOG(TRACE) << "TransactionQueue::remove_WITH_LOCK " << toString(_txHash); + return true; +} + +unsigned TransactionQueue::waiting(Address const& _a) const +{ + ReadGuard l(m_lock); + unsigned ret = 0; + auto cs = m_currentByAddressAndNonce.find(_a); + if (cs != m_currentByAddressAndNonce.end()) + ret = cs->second.size(); + auto fs = m_future.find(_a); + if (fs != m_future.end()) + ret += fs->second.size(); + return ret; +} + +void TransactionQueue::setFuture(h256 const& _txHash) +{ + WriteGuard l(m_lock); + auto it = m_currentByHash.find(_txHash); + if (it == m_currentByHash.end()) + return; + + VerifiedTransaction const& st = *(it->second); + + Address from = st.transaction.from(); + auto& queue = m_currentByAddressAndNonce[from]; + auto& target = m_future[from]; + auto cutoff = queue.lower_bound(st.transaction.randomid()); + for (auto m = cutoff; m != queue.end(); ++m) + { + VerifiedTransaction& t = const_cast(*(m->second)); // set has only const iterators. Since we are moving out of container that's fine + m_currentByHash.erase(t.transaction.sha3()); + target.emplace(t.transaction.randomid(), move(t)); + m_current.erase(m->second); + ++m_futureSize; + } + queue.erase(cutoff, queue.end()); + if (queue.empty()) + m_currentByAddressAndNonce.erase(from); +} + +void TransactionQueue::makeCurrent_WITH_LOCK(Transaction const& _t) +{ + + bool newCurrent = false; + auto fs = m_future.find(_t.from()); + if (fs != m_future.end()) + { + u256 nonce = _t.randomid() + 1; + auto fb = fs->second.find(nonce); + if (fb != fs->second.end()) + { + auto ft = fb; + while (ft != fs->second.end() && ft->second.transaction.randomid() == nonce) + { + auto inserted = m_currentByAddressAndNonce[_t.from()].insert(std::make_pair(ft->second.transaction.randomid(), PriorityQueue::iterator())); + PriorityQueue::iterator handle = m_current.emplace(move(ft->second)); + inserted.first->second = handle; + m_currentByHash[(*handle).transaction.sha3()] = handle; + --m_futureSize; + ++ft; + ++nonce; + newCurrent = true; + } + fs->second.erase(fb, ft); + if (fs->second.empty()) + m_future.erase(_t.from()); + } + } + + while (m_futureSize > m_futureLimit) + { + // TODO: priority queue for future transactions + // For now just drop random chain end + --m_futureSize; + LOG(WARNING) << "Dropping out of bounds future transaction" << m_future.begin()->second.rbegin()->second.transaction.sha3(); + m_future.begin()->second.erase(--m_future.begin()->second.end()); + if (m_future.begin()->second.empty()) + m_future.erase(m_future.begin()); + } + + if (newCurrent) + m_onReady(); +} + +void TransactionQueue::drop(h256 const& _txHash) +{ + UpgradableGuard l(m_lock); + + if (!m_known.count(_txHash)) + return; + + UpgradeGuard ul(l); + m_dropped.insert(_txHash); + remove_WITH_LOCK(_txHash); +} + +void TransactionQueue::dropGood(Transaction const& _t) +{ + WriteGuard l(m_lock); + makeCurrent_WITH_LOCK(_t); + if (!m_known.count(_t.sha3())) + return; + remove_WITH_LOCK(_t.sha3()); +} + +void TransactionQueue::clear() +{ + WriteGuard l(m_lock); + m_known.clear(); + m_current.clear(); + m_currentByAddressAndNonce.clear(); + m_currentByHash.clear(); + m_future.clear(); + m_futureSize = 0; +} + +void TransactionQueue::enqueue(RLP const& _data, h512 const& _nodeId) +{ + bool queued = false; + { + Guard l(x_queue); + unsigned itemCount = _data.itemCount(); + for (unsigned i = 0; i < itemCount; ++i) + { + if (m_unverified.size() >= c_maxVerificationQueueSize) + { + LOG(WARNING) << "Transaction verification queue is full. Dropping" << itemCount - i << "transactions"; + break; + } + m_unverified.emplace_back(UnverifiedTransaction(_data[i].data(), _nodeId)); + queued = true; + } + } + if (queued) + m_queueReady.notify_all(); +} + +void TransactionQueue::verifierBody() +{ + while (!m_aborting) + { + UnverifiedTransaction work; + + { + unique_lock l(x_queue); + m_queueReady.wait(l, [&]() { return !m_unverified.empty() || m_aborting; }); + if (m_aborting) + return; + work = move(m_unverified.front()); + m_unverified.pop_front(); + } + + try + { + Transaction t(work.transaction, CheckTransaction::Everything); //Signature will be checked later + + t.setImportTime(utcTime()); + ImportResult ir = import(t); + m_onImport(ir, t.sha3(), work.nodeId); + } + catch (...) + { + // should not happen as exceptions are handled in import. + LOG(WARNING) << "Bad transaction:" << boost::current_exception_diagnostic_information(); + } + } +} diff --git a/libethereum/TransactionQueue.h b/libethereum/TransactionQueue.h new file mode 100644 index 0000000000..906f4b6511 --- /dev/null +++ b/libethereum/TransactionQueue.h @@ -0,0 +1,222 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file TransactionQueue.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include "Transaction.h" +#include "Interface.h" + +namespace dev +{ +namespace eth +{ + + + +/** + * @brief A queue of Transactions, each stored as RLP. + * Maintains a transaction queue sorted by nonce diff and gas price. + * @threadsafe + */ +class TransactionQueue +{ +public: + struct Limits { size_t current; size_t future; }; + + /// @brief TransactionQueue + /// @param _limit Maximum number of pending transactions in the queue. + /// @param _futureLimit Maximum number of future nonce transactions. + TransactionQueue(std::shared_ptr _interface, unsigned _limit = 1024, unsigned _futureLimit = 1024); + TransactionQueue(std::shared_ptr _interface, Limits const& _l): TransactionQueue(_interface, _l.current, _l.future) {} + ~TransactionQueue(); + /// Add transaction to the queue to be verified and imported. + /// @param _data RLP encoded transaction data. + /// @param _nodeId Optional network identified of a node transaction comes from. + void enqueue(RLP const& _data, h512 const& _nodeId); + + /// Verify and add transaction to the queue synchronously. + /// @param _tx RLP encoded transaction data. + /// @param _ik Set to Retry to force re-addinga transaction that was previously dropped. + /// @returns Import result code. + ImportResult import(bytes const& _tx, IfDropped _ik = IfDropped::Ignore) { return import(&_tx, _ik); } + + /// Verify and add transaction to the queue synchronously. + /// @param _tx Trasnaction data. + /// @param _ik Set to Retry to force re-addinga transaction that was previously dropped. + /// @returns Import result code. + ImportResult import(Transaction const& _tx, IfDropped _ik = IfDropped::Ignore); + + /// Remove transaction from the queue + /// @param _txHash Trasnaction hash + void drop(h256 const& _txHash); + + /// Get number of pending transactions for account. + /// @returns Pending transaction count. + unsigned waiting(Address const& _a) const; + + /// Get top transactions from the queue. Returned transactions are not removed from the queue automatically. + /// @param _limit Max number of transactions to return. + /// @param _avoid Transactions to avoid returning. + /// @returns up to _limit transactions ordered by nonce and gas price. + Transactions topTransactions(unsigned _limit, h256Hash const& _avoid = h256Hash()) const; + + Transactions allTransactions() const; + + /// Get a hash set of transactions in the queue + /// @returns A hash set of all transactions in the queue + h256Hash knownTransactions() const; + + /// Get max nonce for an account + /// @returns Max transaction nonce for account in the queue + u256 maxNonce(Address const& _a) const; + + /// Mark transaction as future. It wont be retured in topTransactions list until a transaction with a preceeding nonce is imported or marked with dropGood + /// @param _t Transaction hash + void setFuture(h256 const& _t); + + /// Drop a trasnaction from the list if exists and move following future trasnactions to current (if any) + /// @param _t Transaction hash + void dropGood(Transaction const& _t); + + struct Status + { + size_t current; + size_t future; + size_t unverified; + size_t dropped; + }; + /// @returns the status of the transaction queue. + Status status() const { Status ret; DEV_GUARDED(x_queue) { ret.unverified = m_unverified.size(); } ReadGuard l(m_lock); ret.dropped = m_dropped.size(); ret.current = m_currentByHash.size(); ret.future = m_future.size(); return ret; } + + /// @returns the transacrtion limits on current/future. + Limits limits() const { return Limits{m_limit, m_futureLimit}; } + + /// Clear the queue + void clear(); + + /// Register a handler that will be called once there is a new transaction imported + template Handler<> onReady(T const& _t) { return m_onReady.add(_t); } + + /// Register a handler that will be called once asynchronous verification is comeplte an transaction has been imported + template Handler onImport(T const& _t) { return m_onImport.add(_t); } + + /// Register a handler that will be called once asynchronous verification is comeplte an transaction has been imported + template Handler onReplaced(T const& _t) { return m_onReplaced.add(_t); } + +private: + + /// Verified and imported transaction + struct VerifiedTransaction + { + VerifiedTransaction(Transaction const& _t): transaction(_t) {} + VerifiedTransaction(VerifiedTransaction&& _t): transaction(std::move(_t.transaction)) {} + + VerifiedTransaction(VerifiedTransaction const&) = delete; + VerifiedTransaction& operator=(VerifiedTransaction const&) = delete; + + Transaction transaction; ///< Transaction data + }; + + /// Transaction pending verification + struct UnverifiedTransaction + { + UnverifiedTransaction() {} + UnverifiedTransaction(bytesConstRef const& _t, h512 const& _nodeId): transaction(_t.toBytes()), nodeId(_nodeId) {} + UnverifiedTransaction(UnverifiedTransaction&& _t): transaction(std::move(_t.transaction)), nodeId(std::move(_t.nodeId)) {} + UnverifiedTransaction& operator=(UnverifiedTransaction&& _other) + { + assert(&_other != this); + + transaction = std::move(_other.transaction); + nodeId = std::move(_other.nodeId); + return *this; + } + + UnverifiedTransaction(UnverifiedTransaction const&) = delete; + UnverifiedTransaction& operator=(UnverifiedTransaction const&) = delete; + + bytes transaction; ///< RLP encoded transaction data + h512 nodeId; ///< Network Id of the peer transaction comes from + }; + + struct PriorityCompare + { + TransactionQueue& queue; + /// Compare transaction by nonce height and gas price. + bool operator()(VerifiedTransaction const& _first, VerifiedTransaction const& _second) const + { + return _first.transaction.importTime() <= _second.transaction.importTime(); + + } + }; + + // Use a set with dynamic comparator for minmax priority queue. The comparator takes into account min account nonce. Updating it does not affect the order. + using PriorityQueue = std::multiset; + + ImportResult import(bytesConstRef _tx, IfDropped _ik = IfDropped::Ignore); + ImportResult check_WITH_LOCK(h256 const& _h, IfDropped _ik); + ImportResult manageImport_WITH_LOCK(h256 const& _h, Transaction const& _transaction); + + void insertCurrent_WITH_LOCK(std::pair const& _p); + void makeCurrent_WITH_LOCK(Transaction const& _t); + bool remove_WITH_LOCK(h256 const& _txHash); + u256 maxNonce_WITH_LOCK(Address const& _a) const; + void verifierBody(); + + mutable SharedMutex m_lock; ///< General lock. + h256Hash m_known; ///< Headers of transactions in both sets. + + std::unordered_map> m_callbacks; ///< Called once. + h256Hash m_dropped; ///< Transactions that have previously been dropped + + PriorityQueue m_current; + std::unordered_map m_currentByHash; ///< Transaction hash to set ref + std::unordered_map> m_currentByAddressAndNonce; ///< Transactions grouped by account and nonce + std::unordered_map> m_future; /// Future transactions + + Signal<> m_onReady; ///< Called when a subsequent call to import transactions will return a non-empty container. Be nice and exit fast. + Signal m_onImport; ///< Called for each import attempt. Arguments are result, transaction id an node id. Be nice and exit fast. + Signal m_onReplaced; ///< Called whan transction is dropped during a call to import() to make room for another transaction. + unsigned m_limit; ///< Max number of pending transactions + unsigned m_futureLimit; ///< Max number of future transactions + unsigned m_futureSize = 0; ///< Current number of future transactions + + std::condition_variable m_queueReady; ///< Signaled when m_unverified has a new entry. + std::vector m_verifiers; + std::deque m_unverified; ///< Pending verification queue + mutable Mutex x_queue; ///< Verification queue mutex + std::atomic m_aborting = {false}; ///< Exit condition for verifier. + + std::shared_ptr m_interface; + +}; + +} +} + diff --git a/libethereum/TransactionReceipt.cpp b/libethereum/TransactionReceipt.cpp new file mode 100644 index 0000000000..7db985dd07 --- /dev/null +++ b/libethereum/TransactionReceipt.cpp @@ -0,0 +1,72 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file TransactionReceipt.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "TransactionReceipt.h" + +using namespace std; +using namespace dev; +using namespace dev::eth; + +TransactionReceipt::TransactionReceipt(bytesConstRef _rlp) +{ + RLP r(_rlp); + m_stateRoot = (h256)r[0]; + m_gasUsed = (u256)r[1]; + m_contractAddress=(Address)r[2];//新加的 + m_bloom = (LogBloom)r[3]; + for (auto const& i: r[4]) + m_log.emplace_back(i); +} + +TransactionReceipt::TransactionReceipt(h256 _root, u256 _gasUsed, LogEntries const& _log, Address const& _contractAddress) +{ + + m_stateRoot=(_root); + m_gasUsed=(_gasUsed); + m_bloom=(eth::bloom(_log)); + m_contractAddress=(_contractAddress); + m_log=(_log); +} + +void TransactionReceipt::streamRLP(RLPStream& _s) const +{ + _s.appendList(5) << m_stateRoot << m_gasUsed << m_contractAddress<< m_bloom; + _s.appendList(m_log.size()); + for (LogEntry const& l: m_log) + l.streamRLP(_s); +} + +std::ostream& dev::eth::operator<<(std::ostream& _out, TransactionReceipt const& _r) +{ + _out << "Root: " << _r.stateRoot() << std::endl; + _out << "Gas used: " << _r.gasUsed() << std::endl; + _out << "contractAddress : " << _r.contractAddress() << std::endl; + _out << "Logs: " << _r.log().size() << " entries:" << std::endl; + for (LogEntry const& i: _r.log()) + { + _out << "Address " << i.address << ". Topics:" << std::endl; + for (auto const& j: i.topics) + _out << " " << j << std::endl; + _out << " Data: " << toHex(i.data) << std::endl; + } + _out << "Bloom: " << _r.bloom() << std::endl; + return _out; +} diff --git a/libethereum/TransactionReceipt.h b/libethereum/TransactionReceipt.h new file mode 100644 index 0000000000..f97e9b9538 --- /dev/null +++ b/libethereum/TransactionReceipt.h @@ -0,0 +1,106 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file TransactionReceipt.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include +#include +#include + +namespace dev +{ + +namespace eth +{ + +class TransactionReceipt +{ +public: + TransactionReceipt(bytesConstRef _rlp); + TransactionReceipt(h256 _root, u256 _gasUsed, LogEntries const& _log, Address const& _contractAddress = Address()); + + h256 const& stateRoot() const { return m_stateRoot; } + u256 const& gasUsed() const { return m_gasUsed; } + Address const& contractAddress() const { return m_contractAddress; } + LogBloom const& bloom() const { return m_bloom; } + LogEntries const& log() const { return m_log; } + + void streamRLP(RLPStream& _s) const; + + bytes rlp() const { RLPStream s; streamRLP(s); return s.out(); } + +private: + h256 m_stateRoot; + u256 m_gasUsed; + Address m_contractAddress; + LogBloom m_bloom; + LogEntries m_log; +}; + +using TransactionReceipts = std::vector; + +std::ostream& operator<<(std::ostream& _out, eth::TransactionReceipt const& _r); + +class LocalisedTransactionReceipt: public TransactionReceipt +{ +public: + LocalisedTransactionReceipt( + TransactionReceipt const& _t, + h256 const& _hash, + h256 const& _blockHash, + BlockNumber _blockNumber, + unsigned _transactionIndex + ): + TransactionReceipt(_t), + m_hash(_hash), + m_blockHash(_blockHash), + m_blockNumber(_blockNumber), + m_transactionIndex(_transactionIndex) + { + LogEntries entries = log(); + for (unsigned i = 0; i < entries.size(); i++) + m_localisedLogs.push_back(LocalisedLogEntry( + entries[i], + m_blockHash, + m_blockNumber, + m_hash, + m_transactionIndex, + i + )); + } + + h256 const& hash() const { return m_hash; } + h256 const& blockHash() const { return m_blockHash; } + BlockNumber blockNumber() const { return m_blockNumber; } + unsigned transactionIndex() const { return m_transactionIndex; } + LocalisedLogEntries const& localisedLogs() const { return m_localisedLogs; }; + +private: + h256 m_hash; + h256 m_blockHash; + BlockNumber m_blockNumber; + unsigned m_transactionIndex = 0; + LocalisedLogEntries m_localisedLogs; +}; + +} +} diff --git a/libethereum/Utility.cpp b/libethereum/Utility.cpp new file mode 100644 index 0000000000..7f7855e316 --- /dev/null +++ b/libethereum/Utility.cpp @@ -0,0 +1,144 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Utility.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "Utility.h" + +#include +#include +#include +#include + +#include +#include "BlockChain.h" +#include "Defaults.h" +#include +using namespace std; +using namespace dev; +using namespace dev::eth; +namespace fs = boost::filesystem; + +bytes dev::eth::parseData(string const& _args) +{ + bytes m_data; + + boost::smatch what; + static const boost::regex r("(!|#|@|\\$)?\"([^\"]*)\"(\\s.*)?"); + static const boost::regex d("(@|\\$)?([0-9]+)(\\s*(ether)|(finney)|(szabo))?(\\s.*)?"); + static const boost::regex h("(@|\\$)?(0x)?(([a-fA-F0-9])+)(\\s.*)?"); + + string s = _args; + while (s.size()) + if (boost::regex_match(s, what, d)) + { + u256 v((string)what[2]); + if (what[6] == "szabo") + v *= dev::eth::szabo; + else if (what[5] == "finney") + v *= dev::eth::finney; + else if (what[4] == "ether") + v *= dev::eth::ether; + bytes bs = dev::toCompactBigEndian(v); + if (what[1] != "$") + for (auto i = bs.size(); i < 32; ++i) + m_data.push_back(0); + for (auto b: bs) + m_data.push_back(b); + s = what[7]; + } + else if (boost::regex_match(s, what, h)) + { + bytes bs = fromHex(((what[3].length() & 1) ? "0" : "") + what[3]); + if (what[1] != "$") + for (auto i = bs.size(); i < 32; ++i) + m_data.push_back(0); + for (auto b: bs) + m_data.push_back(b); + s = what[5]; + } + else if (boost::regex_match(s, what, r)) + { + bytes d = asBytes(what[2]); + if (what[1] == "!") + m_data += FixedHash<4>(sha3(d)).asBytes(); + else if (what[1] == "#") + m_data += sha3(d).asBytes(); + else if (what[1] == "$") + m_data += d + bytes{0}; + else + m_data += d + bytes(32 - what[2].length() % 32, 0); + s = what[3]; + } + else + s = s.substr(1); + + return m_data; +} + +void dev::eth::upgradeDatabase(std::string const& _basePath, h256 const& _genesisHash) +{ + std::string path = _basePath.empty() ? Defaults::get()->dbPath() : _basePath; + + //判断是否有该status和details和blocks文件 在path下有该对应文件 则复制拷贝到 对应的chainpath和extrasPath下面去 + if (fs::exists(path + "/state") && fs::exists(path + "/details") && fs::exists(path + "/blocks")) + { + // upgrade + cnote << "Upgrading database to new layout..."; + bytes statusBytes = contents(path + "/status"); + RLP status(statusBytes); + try + { + auto minorProtocolVersion = (unsigned)status[1]; + auto databaseVersion = (unsigned)status[2]; + auto genesisHash = status.itemCount() > 3 ? (h256)status[3] : _genesisHash; + + string chainPath = path + "/" + toHex(genesisHash.ref().cropped(0, 4)); + string extrasPath = chainPath + "/" + toString(databaseVersion); + + // write status + if (!fs::exists(chainPath + "/blocks")) + { + fs::create_directories(chainPath); + DEV_IGNORE_EXCEPTIONS(fs::permissions(chainPath, fs::owner_all)); + fs::rename(path + "/blocks", chainPath + "/blocks"); + + if (!fs::exists(extrasPath + "/extras")) + { + fs::create_directories(extrasPath); + DEV_IGNORE_EXCEPTIONS(fs::permissions(extrasPath, fs::owner_all)); + fs::rename(path + "/details", extrasPath + "/extras"); + fs::rename(path + "/state", extrasPath + "/state"); + writeFile(extrasPath + "/minor", rlp(minorProtocolVersion)); + } + } + } + catch (Exception& ex) + { + LOG(TRACE) << "Couldn't upgrade: " << ex.what() << boost::diagnostic_information(ex); + } + catch (...) + { + LOG(TRACE) << "Couldn't upgrade. Some issue with moving files around. Probably easiest just to redownload."; + } + + fs::rename(path + "/status", path + "/status.old"); + } +} + diff --git a/libethereum/Utility.h b/libethereum/Utility.h new file mode 100644 index 0000000000..5b6532da58 --- /dev/null +++ b/libethereum/Utility.h @@ -0,0 +1,49 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Utility.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include +#include + +namespace dev +{ +namespace eth +{ + +/** + * Takes a user-authorable string with several whitespace delimited arguments and builds a byte array + * from it. Arguments can be hex data/numerals, decimal numbers or ASCII strings. Literals are padded + * to 32 bytes if prefixed by a '@' (or not prefixed at all), and tightly packed if prefixed by a '$'. + * Currency multipliers can be provided. + * + * Example: + * @code + * parseData("$42 0x42 $\"Hello\""); // == bytes(1, 0x2a) + bytes(31, 0) + bytes(1, 0x42) + asBytes("Hello"); + * @endcode + */ +bytes parseData(std::string const& _args); + +void upgradeDatabase(std::string const& _basePath, h256 const& _genesisHash); + +} +} diff --git a/libethereum/VerifiedBlock.h b/libethereum/VerifiedBlock.h new file mode 100644 index 0000000000..141c9da1bf --- /dev/null +++ b/libethereum/VerifiedBlock.h @@ -0,0 +1,79 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file VerfiedBlock.h + * @author Gav Wood + * @date 2014 + */ + + +#include +#include + +#pragma once + +namespace dev +{ +namespace eth +{ + +class Transaction; + +/// @brief Verified block info, does not hold block data, but a reference instead +struct VerifiedBlockRef +{ + bytesConstRef block; ///< Block data reference + BlockHeader info; ///< Prepopulated block info + std::vector transactions; ///< Verified list of block transactions +}; + +/// @brief Verified block info, combines block data and verified info/transactions +struct VerifiedBlock +{ + VerifiedBlock() {} + + VerifiedBlock(BlockHeader&& _bi) + { + verified.info = std::move(_bi); + } + + VerifiedBlock(VerifiedBlock&& _other): + verified(std::move(_other.verified)), + blockData(std::move(_other.blockData)) + { + } + + VerifiedBlock& operator=(VerifiedBlock&& _other) + { + assert(&_other != this); + + verified = (std::move(_other.verified)); + blockData = (std::move(_other.blockData)); + return *this; + } + + VerifiedBlockRef verified; ///< Verified block structures + bytes blockData; ///< Block data + +private: + VerifiedBlock(VerifiedBlock const&) = delete; + VerifiedBlock operator=(VerifiedBlock const&) = delete; +}; + +using VerifiedBlocks = std::vector; + +} +} diff --git a/libevm/All.h b/libevm/All.h new file mode 100644 index 0000000000..dd5bb2320e --- /dev/null +++ b/libevm/All.h @@ -0,0 +1,4 @@ +#pragma once + +#include "ExtVMFace.h" +#include "VM.h" diff --git a/libevm/CMakeLists.txt b/libevm/CMakeLists.txt new file mode 100644 index 0000000000..cc4692a36d --- /dev/null +++ b/libevm/CMakeLists.txt @@ -0,0 +1,49 @@ + +set(SOURCES + ExtVMFace.cpp + VM.cpp + VMOpt.cpp + VMCalls.cpp + VMFactory.cpp + CoverTool.cpp + VMExtends.cpp +) + +if (EVMJIT) + list(APPEND SOURCES + JitVM.cpp + SmartVM.cpp + ) +endif() + +file(GLOB HEADERS "*.h") + +add_library(evm ${SOURCES} ${HEADERS}) + +find_package(Eth) + +include_directories(../libodbc/include + ../libodbc/include/db2_linux + ../libodbc/include/ibase + ../libodbc/include/infomix + ../libodbc/include/mysql + ../libodbc/include/odbc_linux + ../libodbc/include/pgsql + ../libodbc/include/sqlbase + ../libodbc/include/sqllite + ../libodbc/include/ss_linux + ../libodbc/include/sybase + ../libpailler) + + +target_link_libraries(evm ${Eth_ETHCORE_LIBRARIES}) +target_link_libraries(evm ${Eth_EVMCORE_LIBRARIES}) +target_link_libraries(evm pailler) +target_include_directories(evm PRIVATE .. ${JSONCPP_INCLUDE_DIR}) + +if (EVMJIT) + target_include_directories(evm PRIVATE ../evmjit/include) + target_link_libraries(evm ${Eth_EVMJIT_LIBRARIES}) +endif() + +install(TARGETS evm RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib) diff --git a/libevm/CoverTool.cpp b/libevm/CoverTool.cpp new file mode 100644 index 0000000000..27973fa9ca --- /dev/null +++ b/libevm/CoverTool.cpp @@ -0,0 +1,124 @@ +#include "CoverTool.h" + + + + +CoverTool::CoverTool() +{ + + + size_t threads=1;//一个就好了 + for (unsigned i = 0; i < threads; ++i) + m_checks.emplace_back([=](){ + + setThreadName("CoverTool:check" ); + this->output(); + }); + + +} + +CoverTool:: ~CoverTool() +{ + // cout<<"~CoverTool"<first)+"\n"; + //message +="lasttime:"+toString(iter->second.lasttime)+"\n"; + //message +="outputtime:"+toString(now)+"\n"; + + for( size_t i=0;isecond.vectorinfo.size();i++) + { + message +=iter->second.vectorinfo.at(i).opname+"\t"; + message +=toString(iter->second.vectorinfo.at(i).hint)+"\n"; + }//for + + //写文件 + if( !m_outputpath.empty() ) + writeFile(m_outputpath+toString(iter->first), message, true); + + + //一天没更新就删除 + if( now - iter->second.lasttime > 24*3600*1000 ) + m_statitems.erase(iter); + }//if + }//for + + } + catch (...) + { + // should not happen as exceptions + LOG(WARNING) << "Bad CoverTool:" << boost::current_exception_diagnostic_information(); + m_aborting=true; + } + } + + + this_thread::sleep_for(std::chrono::milliseconds(10000)); + }//while + +}//fun + + + diff --git a/libevm/CoverTool.h b/libevm/CoverTool.h new file mode 100644 index 0000000000..45bffb49bd --- /dev/null +++ b/libevm/CoverTool.h @@ -0,0 +1,150 @@ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace dev::eth; +using namespace std; + +namespace dev +{ +namespace eth +{ + + + +using Address = h160; + +struct OpcodeInfo +{ + OpcodeInfo(size_t i,Instruction o=Instruction::STOP,std::string n="INVALID_INSTRUCTION"):index(i),op(o),opname(n),hint(0){} + + size_t index; //下标 + Instruction op; //opcode + std::string opname; + u64 hint; +}; + +struct StatItem +{ + StatItem(bytes cspace) + { + codespace=cspace; + code=codespace.data(); + + //初始化 + size_t codesize=codespace.size(); + + for (size_t i = 0; i < codesize; ++i) + { + Instruction op = Instruction(code[i]); + OpcodeInfo opcodeinfo(i,op,instructionInfo(op).name); + + //下面修正 + if (op == Instruction::PUSHC || + op == Instruction::JUMPC || + op == Instruction::JUMPCI) + { + opcodeinfo.op = Instruction::BAD; + opcodeinfo.opname=instructionInfo(Instruction::BAD).name; + } + + if ((byte)Instruction::PUSH1 <= (byte)op && + (byte)op <= (byte)Instruction::PUSH32) + { + vectorinfo.push_back (opcodeinfo);//先将当前的插入 + + size_t len=(byte)op - (byte)Instruction::PUSH1 + 1;//中间都是 字节value + + for( size_t j=i+1;j<(i+len+1);j++) + { + OpcodeInfo _opcodeinfo(j,Instruction::STOP,"" ); + vectorinfo.push_back(_opcodeinfo); + } + + i +=len; + } + else + { + vectorinfo.push_back (opcodeinfo);//先将当前的插入 + } + + + //cout<<"i="< vectorinfo; + + void hint(size_t index,size_t codespacesize) + { + if( codespace.size() > codespacesize ) + { + //说明进来的是普通交易,不是部署合约,所以要加上偏移量 + index=index+(codespace.size()-codespacesize); + } + if( index < vectorinfo.size() ) + { + vectorinfo.at(index).hint++; + lasttime=utcTime(); + } + + + } + +}; + + + +class CoverTool +{ +private: + std::vector m_checks; + std::map m_statitems; //合约地址为key + + mutable SharedMutex m_lock; //虽然没啥必要 + bool m_aborting = false; + std::string m_outputpath;//输出路径 + +public: + + CoverTool() ; + ~CoverTool() ; + + void outputpath(std::string path)//这么做,是因为covertool在vm中是静态类成员,初始化时datadir并没有更新 + { + m_outputpath=path; + } + bool has(Address address); + void init(Address address,bytes cspace); + void hint(Address address,size_t index,size_t codespacesize); + + + +private: + + void output(); + + +}; + + + +} +} diff --git a/libevm/ExtVMFace.cpp b/libevm/ExtVMFace.cpp new file mode 100644 index 0000000000..a4fd6253b9 --- /dev/null +++ b/libevm/ExtVMFace.cpp @@ -0,0 +1,38 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file ExtVMFace.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "ExtVMFace.h" +#include +using namespace dev; +using namespace dev::eth; + +ExtVMFace::ExtVMFace(EnvInfo const& _envInfo, Address _myAddress, Address _caller, Address _origin, u256 _value, u256 _gasPrice, bytesConstRef _data, bytes _code, h256 const& _codeHash, unsigned _depth): + m_envInfo(_envInfo), + myAddress(_myAddress), + caller(_caller), + origin(_origin), + value(_value), + gasPrice(_gasPrice), + data(_data), + code(std::move(_code)), + codeHash(_codeHash), + depth(_depth) +{} diff --git a/libevm/ExtVMFace.h b/libevm/ExtVMFace.h new file mode 100644 index 0000000000..9d9ab51883 --- /dev/null +++ b/libevm/ExtVMFace.h @@ -0,0 +1,332 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file ExtVMFace.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +namespace dev +{ +namespace eth +{ + +enum class BlockPolarity +{ + Unknown, + Dead, + Live +}; + +struct LogEntry +{ + LogEntry() {} + LogEntry(RLP const& _r) { address = (Address)_r[0]; topics = _r[1].toVector(); data = _r[2].toBytes(); } + LogEntry(Address const& _address, h256s const& _ts, bytes&& _d): address(_address), topics(_ts), data(std::move(_d)) {} + + void streamRLP(RLPStream& _s) const { _s.appendList(3) << address << topics << data; } + + LogBloom bloom() const + { + LogBloom ret; + ret.shiftBloom<3>(sha3(address.ref())); + for (auto t: topics) + ret.shiftBloom<3>(sha3(t.ref())); + return ret; + } + + Address address; + h256s topics; + bytes data; +}; + +using LogEntries = std::vector; + +struct LocalisedLogEntry: public LogEntry +{ + LocalisedLogEntry() {} + explicit LocalisedLogEntry(LogEntry const& _le): LogEntry(_le) {} + + explicit LocalisedLogEntry( + LogEntry const& _le, + h256 _special + ): + LogEntry(_le), + isSpecial(true), + special(_special) + {} + + explicit LocalisedLogEntry( + LogEntry const& _le, + h256 const& _blockHash, + BlockNumber _blockNumber, + h256 const& _transactionHash, + unsigned _transactionIndex, + unsigned _logIndex, + BlockPolarity _polarity = BlockPolarity::Unknown + ): + LogEntry(_le), + blockHash(_blockHash), + blockNumber(_blockNumber), + transactionHash(_transactionHash), + transactionIndex(_transactionIndex), + logIndex(_logIndex), + polarity(_polarity), + mined(true) + {} + + h256 blockHash; + BlockNumber blockNumber = 0; + h256 transactionHash; + unsigned transactionIndex = 0; + unsigned logIndex = 0; + BlockPolarity polarity = BlockPolarity::Unknown; + bool mined = false; + bool isSpecial = false; + h256 special; +}; + +using LocalisedLogEntries = std::vector; + +inline LogBloom bloom(LogEntries const& _logs) +{ + LogBloom ret; + for (auto const& l: _logs) + ret |= l.bloom(); + return ret; +} + +struct SubState +{ + std::set
suicides; ///< Any accounts that have suicided. + LogEntries logs; ///< Any logs. + u256 refunds; ///< Refund counter of SSTORE nonzero->zero. + + SubState& operator+=(SubState const& _s) + { + suicides += _s.suicides; + refunds += _s.refunds; + logs += _s.logs; + return *this; + } + + void clear() + { + suicides.clear(); + logs.clear(); + refunds = 0; + } +}; + +class ExtVMFace; +class VM; + +using LastHashes = std::vector; + +using OnOpFunc = std::function; + +struct CallParameters +{ + Address senderAddress; + Address codeAddress; + Address receiveAddress; + u256 valueTransfer; + u256 apparentValue; + u256 gas; + bytesConstRef data; + bytesRef out; + OnOpFunc onOp; +}; + +class EnvInfo +{ +public: + EnvInfo() {} + EnvInfo(BlockHeader const& _current, LastHashes const& _lh = LastHashes(), u256 const& _gasUsed = u256(),bool const & _cl=false,bool const & _el=false): + m_number(_current.number()), + m_author(_current.author()), + m_timestamp(_current.timestamp()), + m_difficulty(_current.difficulty()), + // Trim gas limit to int64. convert_to used explicitly instead of + // static_cast to be noticed when BlockHeader::gasLimit() will be + // changed to int64 too. + m_gasLimit(_current.gasLimit().convert_to()), + m_lastHashes(_lh), + m_gasUsed(_gasUsed), + m_coverlog(_cl), + m_eventlog(_el) + { + + } + + EnvInfo(BlockHeader const& _current, LastHashes&& _lh, u256 const& _gasUsed = u256(),bool const & _cl=false,bool const & _el=false): + m_number(_current.number()), + m_author(_current.author()), + m_timestamp(_current.timestamp()), + m_difficulty(_current.difficulty()), + // Trim gas limit to int64. convert_to used explicitly instead of + // static_cast to be noticed when BlockHeader::gasLimit() will be + // changed to int64 too. + m_gasLimit(_current.gasLimit().convert_to()), + m_lastHashes(_lh), + m_gasUsed(_gasUsed), + m_coverlog(_cl), + m_eventlog(_el) + { + + } + + u256 const& number() const { return m_number; } + Address const& author() const { return m_author; } + u256 const& timestamp() const { return m_timestamp; } + u256 const& difficulty() const { return m_difficulty; } + int64_t gasLimit() const { return m_gasLimit; } + LastHashes const& lastHashes() const { return m_lastHashes; } + u256 const& gasUsed() const { return m_gasUsed; } + + void setNumber(u256 const& _v) { m_number = _v; } + void setAuthor(Address const& _v) { m_author = _v; } + void setTimestamp(u256 const& _v) { m_timestamp = _v; } + void setDifficulty(u256 const& _v) { m_difficulty = _v; } + void setGasLimit(int64_t _v) { m_gasLimit = _v; } + void setLastHashes(LastHashes const& _lh) { m_lastHashes = _lh; } + void setLastHashes(LastHashes&& _lh) { m_lastHashes = _lh; } + void setGasUsed(u256 const& _v) { m_gasUsed = _v; } + + bool coverLog()const { return m_coverlog;} + bool eventLog()const { return m_eventlog;} + void setCoverLog(bool _cl){ m_coverlog=_cl;} + void setEventLog(bool _el){ m_eventlog=_el;} + +private: + u256 m_number; + Address m_author; + u256 m_timestamp; + u256 m_difficulty; + int64_t m_gasLimit; + LastHashes m_lastHashes; + u256 m_gasUsed; + + bool m_coverlog;//是否打印覆盖率日志 + bool m_eventlog;//是否打印event log +}; + +/** + * @brief Interface and null implementation of the class for specifying VM externalities. + */ +class ExtVMFace +{ +public: + /// Null constructor. + ExtVMFace() = default; + + /// Full constructor. + ExtVMFace(EnvInfo const& _envInfo, Address _myAddress, Address _caller, Address _origin, u256 _value, u256 _gasPrice, bytesConstRef _data, bytes _code, h256 const& _codeHash, unsigned _depth); + + virtual ~ExtVMFace() = default; + + ExtVMFace(ExtVMFace const&) = delete; + void operator=(ExtVMFace) = delete; + + /// Read storage location. + virtual u256 store(u256) { return 0; } + + /// Write a value in storage. + virtual void setStore(u256, u256) {} + + /// Read address's balance. + virtual u256 balance(Address) { return 0; } + + /// Read address's code. + virtual bytes const& codeAt(Address) { return NullBytes; } + + /// @returns the size of the code in bytes at the given address. + virtual size_t codeSizeAt(Address) { return 0; } + + /// Does the account exist? + virtual bool exists(Address) { return false; } + + /// Suicide the associated contract and give proceeds to the given address. + virtual void suicide(Address) { sub.suicides.insert(myAddress); } + + /// Create a new (contract) account. + virtual h160 create(u256, u256&, bytesConstRef, OnOpFunc const&) { return h160(); } + + /// Make a new message call. + virtual bool call(CallParameters&) { return false; } + + /// Revert any changes made (by any of the other calls). + virtual void log(h256s&& _topics, bytesConstRef _data) + { + + + if( envInfo().eventLog() ) + { + std::stringstream smsg; + smsg<<"LOG 0x"<= (std::max(256, envInfo().number()) - 256) ? envInfo().lastHashes()[(unsigned)(envInfo().number() - 1 - _number)] : h256(); } + + /// Get the code at the given location in code ROM. + byte getCode(u256 _n) const { return _n < code.size() ? code[(size_t)_n] : 0; } + + /// Get the execution environment information. + EnvInfo const& envInfo() const { return m_envInfo; } + + /// Return the EVM gas-price schedule for this execution context. + virtual EVMSchedule const& evmSchedule() const { return DefaultSchedule; } + +private: + EnvInfo const& m_envInfo; + +public: + // TODO: make private + Address myAddress; ///< Address associated with executing code (a contract, or contract-to-be). + Address caller; ///< Address which sent the message (either equal to origin or a contract). + Address origin; ///< Original transactor. + u256 value; ///< Value (in Wei) that was passed to this address. + u256 gasPrice; ///< Price of gas (that we already paid). + bytesConstRef data; ///< Current input data. + bytes code; ///< Current code that is executing. + h256 codeHash; ///< SHA3 hash of the executing code + SubState sub; ///< Sub-band VM state (suicides, refund counter, logs). + unsigned depth = 0; ///< Depth of the present call. +}; + +} +} diff --git a/libevm/JitVM.cpp b/libevm/JitVM.cpp new file mode 100644 index 0000000000..42bb5156c2 --- /dev/null +++ b/libevm/JitVM.cpp @@ -0,0 +1,367 @@ +#include "JitVM.h" + + +#include +#include + +namespace dev +{ +namespace eth +{ +namespace +{ + +static_assert(sizeof(Address) == sizeof(evm_uint160be), + "Address types size mismatch"); +static_assert(alignof(Address) == alignof(evm_uint160be), + "Address types alignment mismatch"); + +inline evm_uint160be toEvmC(Address _addr) +{ + return *reinterpret_cast(&_addr); +} + +inline Address fromEvmC(evm_uint160be _addr) +{ + return *reinterpret_cast(&_addr); +} + +static_assert(sizeof(h256) == sizeof(evm_uint256be), "Hash types size mismatch"); +static_assert(alignof(h256) == alignof(evm_uint256be), "Hash types alignment mismatch"); + +inline evm_uint256be toEvmC(h256 _h) +{ + return *reinterpret_cast(&_h); +} + +inline u256 asUint(evm_uint256be _n) +{ + return fromBigEndian(_n.bytes); +} + +inline h256 asHash(evm_uint256be _n) +{ + return h256(&_n.bytes[0], h256::ConstructFromPointer); +} + +evm_variant evm_query( + evm_env* _opaqueEnv, + evm_query_key _key, + evm_variant _arg +) noexcept +{ + auto &env = *reinterpret_cast(_opaqueEnv); + evm_variant v; + switch (_key) + { + case EVM_ADDRESS: + v.address = toEvmC(env.myAddress); + break; + case EVM_CALLER: + v.address = toEvmC(env.caller); + break; + case EVM_ORIGIN: + v.address = toEvmC(env.origin); + break; + case EVM_GAS_PRICE: + v.uint256be = toEvmC(env.gasPrice); + break; + case EVM_COINBASE: + v.address = toEvmC(env.envInfo().author()); + break; + case EVM_DIFFICULTY: + v.uint256be = toEvmC(env.envInfo().difficulty()); + break; + case EVM_GAS_LIMIT: + v.int64 = env.envInfo().gasLimit(); + break; + case EVM_NUMBER: + // TODO: Handle overflow / exception + v.int64 = static_cast(env.envInfo().number()); + break; + case EVM_TIMESTAMP: + // TODO: Handle overflow / exception + v.int64 = static_cast(env.envInfo().timestamp()); + break; + case EVM_CODE_BY_ADDRESS: + { + auto addr = fromEvmC(_arg.address); + auto &code = env.codeAt(addr); + v.data = code.data(); + v.data_size = code.size(); + break; + } + case EVM_CODE_SIZE: + { + auto addr = fromEvmC(_arg.address); + v.int64 = env.codeSizeAt(addr); + break; + } + case EVM_BALANCE: + { + auto addr = fromEvmC(_arg.address); + v.uint256be = toEvmC(env.balance(addr)); + break; + } + case EVM_BLOCKHASH: + v.uint256be = toEvmC(env.blockHash(_arg.int64)); + break; + case EVM_SLOAD: + { + auto key = asUint(_arg.uint256be); + v.uint256be = toEvmC(env.store(key)); + break; + } + case EVM_ACCOUNT_EXISTS: + { + auto addr = fromEvmC(_arg.address); + v.int64 = env.exists(addr); + break; + } + case EVM_CALL_DEPTH: + v.int64 = env.depth; + break; + } + return v; +} + +void evm_update( + evm_env* _opaqueEnv, + evm_update_key _key, + evm_variant _arg1, + evm_variant _arg2 +) noexcept +{ + auto &env = *reinterpret_cast(_opaqueEnv); + switch (_key) + { + case EVM_SSTORE: + { + auto index = asUint(_arg1.uint256be); + auto value = asUint(_arg2.uint256be); + if (value == 0 && env.store(index) != 0) // If delete + env.sub.refunds += env.evmSchedule().sstoreRefundGas; // Increase refund counter + + env.setStore(index, value); // Interface uses native endianness + break; + } + case EVM_LOG: + { + size_t numTopics = _arg2.data_size / sizeof(h256); + h256 const* pTopics = reinterpret_cast(_arg2.data); + env.log({pTopics, pTopics + numTopics}, {_arg1.data, _arg1.data_size}); + break; + } + case EVM_SELFDESTRUCT: + // Register selfdestruction beneficiary. + env.suicide(fromEvmC(_arg1.address)); + break; + } +} + +int64_t evm_call( + evm_env* _opaqueEnv, + evm_call_kind _kind, + int64_t _gas, + evm_uint160be _address, + evm_uint256be _value, + uint8_t const* _inputData, + size_t _inputSize, + uint8_t* _outputData, + size_t _outputSize +) noexcept +{ + assert(_gas >= 0 && "Invalid gas value"); + auto &env = *reinterpret_cast(_opaqueEnv); + auto value = asUint(_value); + bytesConstRef input{_inputData, _inputSize}; + + if (_kind == EVM_CREATE) + { + assert(_outputSize == 20); + u256 gas = _gas; + auto addr = env.create(value, gas, input, {}); + auto gasLeft = static_cast(gas); + if (addr) + std::memcpy(_outputData, addr.data(), 20); + else + gasLeft |= EVM_CALL_FAILURE; + return gasLeft; + } + + CallParameters params; + params.gas = _gas; + params.apparentValue = _kind == EVM_DELEGATECALL ? env.value : value; + params.valueTransfer = _kind == EVM_DELEGATECALL ? 0 : params.apparentValue; + params.senderAddress = _kind == EVM_DELEGATECALL ? env.caller : env.myAddress; + params.codeAddress = fromEvmC(_address); + params.receiveAddress = _kind == EVM_CALL ? params.codeAddress : env.myAddress; + params.data = input; + params.out = {_outputData, _outputSize}; + params.onOp = {}; + + auto ret = env.call(params); + auto gasLeft = static_cast(params.gas); + + // Add failure indicator. + if (!ret) + gasLeft |= EVM_CALL_FAILURE; + + return gasLeft; +} + + +/// RAII wrapper for an evm instance. +class EVM +{ +public: + EVM(evm_query_fn _queryFn, evm_update_fn _updateFn, evm_call_fn _callFn): + m_interface(evmjit_get_interface()), + m_instance(m_interface.create(_queryFn, _updateFn, _callFn)) + {} + + ~EVM() + { + m_interface.destroy(m_instance); + } + + EVM(EVM const&) = delete; + EVM& operator=(EVM) = delete; + + class Result + { + public: + explicit Result(evm_result const& _result): + m_result(_result) + {} + + ~Result() + { + if (m_result.release) + m_result.release(&m_result); + } + + Result(Result&& _other): + m_result(_other.m_result) + { + // Disable releaser of the rvalue object. + _other.m_result.release = nullptr; + } + + Result(Result const&) = delete; + Result& operator=(Result const&) = delete; + + evm_result_code code() const + { + return m_result.code; + } + + int64_t gasLeft() const + { + return m_result.gas_left; + } + + bytesConstRef output() const + { + return {m_result.output_data, m_result.output_size}; + } + + private: + evm_result m_result; + }; + + /// Handy wrapper for evm_execute(). + Result execute(ExtVMFace& _ext, int64_t gas) + { + auto env = reinterpret_cast(&_ext); + auto mode = JitVM::scheduleToMode(_ext.evmSchedule()); + return Result{m_interface.execute( + m_instance, env, mode, toEvmC(_ext.codeHash), _ext.code.data(), + _ext.code.size(), gas, _ext.data.data(), _ext.data.size(), + toEvmC(_ext.value) + )}; + } + + bool isCodeReady(evm_mode _mode, h256 _codeHash) + { + return m_interface.get_code_status(m_instance, _mode, toEvmC(_codeHash)) == EVM_READY; + } + + void compile(evm_mode _mode, bytesConstRef _code, h256 _codeHash) + { + m_interface.prepare_code( + m_instance, _mode, toEvmC(_codeHash), _code.data(), _code.size() + ); + } + +private: + /// VM interface -- contains pointers to VM's methods. + /// + /// @internal + /// This field does not have initializer because old versions of GCC emit + /// invalid warning about `= {}`. The field is initialized in ctors. + evm_interface m_interface; + + /// The VM instance created with m_interface.create(). + evm_instance* m_instance = nullptr; +}; + +EVM& getJit() +{ + // Create EVM JIT instance by using EVM-C interface. + static EVM jit(evm_query, evm_update, evm_call); + return jit; +} + +} + +bytesConstRef JitVM::execImpl(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp) +{ + auto rejected = false; + // TODO: Rejecting transactions with gas limit > 2^63 can be used by attacker to take JIT out of scope + rejected |= io_gas > std::numeric_limits::max(); // Do not accept requests with gas > 2^63 (int64 max) + rejected |= _ext.envInfo().number() > std::numeric_limits::max(); + rejected |= _ext.envInfo().timestamp() > std::numeric_limits::max(); + rejected |= _ext.envInfo().gasLimit() > std::numeric_limits::max(); + if (rejected) + { + LOG(WARNING) << "Execution rejected by EVM JIT (gas limit: " << io_gas << "), executing with interpreter"; + m_fallbackVM = VMFactory::create(VMKind::Interpreter); + return m_fallbackVM->execImpl(io_gas, _ext, _onOp); + } + + auto gas = static_cast(io_gas); + auto r = getJit().execute(_ext, gas); + + // TODO: Add EVM-C result codes mapping with exception types. + if (r.code() != EVM_SUCCESS) + BOOST_THROW_EXCEPTION(OutOfGas()); + + io_gas = r.gasLeft(); + // FIXME: Copy the output for now, but copyless version possible. + auto output = r.output(); + m_output.assign(output.begin(), output.end()); + return {m_output.data(), m_output.size()}; +} + +evm_mode JitVM::scheduleToMode(EVMSchedule const& _schedule) +{ + if (_schedule.eip158Mode) + return EVM_CLEARING; + if (_schedule.eip150Mode) + return EVM_ANTI_DOS; + return _schedule.haveDelegateCall ? EVM_HOMESTEAD : EVM_FRONTIER; +} + +bool JitVM::isCodeReady(evm_mode _mode, h256 _codeHash) +{ + return getJit().isCodeReady(_mode, _codeHash); +} + +void JitVM::compile(evm_mode _mode, bytesConstRef _code, h256 _codeHash) +{ + getJit().compile(_mode, _code, _codeHash); +} + +} +} diff --git a/libevm/JitVM.h b/libevm/JitVM.h new file mode 100644 index 0000000000..78d0c119c9 --- /dev/null +++ b/libevm/JitVM.h @@ -0,0 +1,27 @@ +#pragma once + +#include +#include + +namespace dev +{ +namespace eth +{ + +class JitVM: public VMFace +{ +public: + virtual bytesConstRef execImpl(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp) override final; + + static evm_mode scheduleToMode(EVMSchedule const& _schedule); + static bool isCodeReady(evm_mode _mode, h256 _codeHash); + static void compile(evm_mode _mode, bytesConstRef _code, h256 _codeHash); + +private: + std::unique_ptr m_fallbackVM; ///< VM used in case of input data rejected by JIT + bytes m_output; +}; + + +} +} diff --git a/libevm/SmartVM.cpp b/libevm/SmartVM.cpp new file mode 100644 index 0000000000..3b4b189998 --- /dev/null +++ b/libevm/SmartVM.cpp @@ -0,0 +1,123 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ + +#include "SmartVM.h" +#include +#include +#include + +#include +#include "VMFactory.h" +#include "JitVM.h" + +namespace dev +{ +namespace eth +{ +namespace +{ + struct JitInfo: LogChannel { static const char* name() { return "JIT"; }; static const int verbosity = 11; }; + + using HitMap = std::unordered_map; + + HitMap& getHitMap() + { + static HitMap s_hitMap; + return s_hitMap; + } + + struct JitTask + { + bytes code; + h256 codeHash; + evm_mode mode; + + static JitTask createStopSentinel() { return JitTask(); } + + bool isStopSentinel() + { + assert((!code.empty() || !codeHash) && "'empty code => empty hash' invariant failed"); + return code.empty(); + } + }; + + class JitWorker + { + concurrent_queue m_queue; + std::thread m_worker; // Worker must be last to initialize + + void work() + { + clog(JitInfo) << "JIT worker started."; + JitTask task; + while (!(task = m_queue.pop()).isStopSentinel()) + { + clog(JitInfo) << "Compilation... " << task.codeHash; + JitVM::compile(task.mode, {task.code.data(), task.code.size()}, task.codeHash); + clog(JitInfo) << " ...finished " << task.codeHash; + } + clog(JitInfo) << "JIT worker finished."; + } + + public: + JitWorker() noexcept: m_worker([this]{ work(); }) + {} + + ~JitWorker() + { + push(JitTask::createStopSentinel()); + m_worker.join(); + } + + void push(JitTask&& _task) { m_queue.push(std::move(_task)); } + }; +} + +bytesConstRef SmartVM::execImpl(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp) +{ + auto vmKind = VMKind::Interpreter; // default VM + auto mode = JitVM::scheduleToMode(_ext.evmSchedule()); + // Jitted EVM code already in memory? + if (JitVM::isCodeReady(mode, _ext.codeHash)) + { + clog(JitInfo) << "JIT: " << _ext.codeHash; + vmKind = VMKind::JIT; + } + else if (!_ext.code.empty()) // This check is needed for VM tests + { + static JitWorker s_worker; + + // Check EVM code hit count + static const uint64_t c_hitTreshold = 2; + auto& hits = getHitMap()[_ext.codeHash]; + ++hits; + if (hits == c_hitTreshold) + { + clog(JitInfo) << "Schedule: " << _ext.codeHash; + s_worker.push({_ext.code, _ext.codeHash, mode}); + } + clog(JitInfo) << "Interpreter: " << _ext.codeHash; + } + + // TODO: Selected VM must be kept only because it returns reference to its internal memory. + // VM implementations should be stateless, without escaping memory reference. + m_selectedVM = VMFactory::create(vmKind); + return m_selectedVM->execImpl(io_gas, _ext, _onOp); +} + +} +} diff --git a/libevm/SmartVM.h b/libevm/SmartVM.h new file mode 100644 index 0000000000..a583d032c4 --- /dev/null +++ b/libevm/SmartVM.h @@ -0,0 +1,41 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +#pragma once + +#include "VMFace.h" + +namespace dev +{ +namespace eth +{ + +/// Smart VM proxy. +/// +/// This class is a strategy pattern implementation for VM. For every EVM code +/// execution request it tries to select the best VM implementation (Interpreter or JIT) +/// by analyzing available information like: code size, hit count, JIT status, etc. +class SmartVM: public VMFace +{ +public: + virtual bytesConstRef execImpl(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp) override final; + +private: + std::unique_ptr m_selectedVM; +}; + +} +} diff --git a/libevm/VM.cpp b/libevm/VM.cpp new file mode 100644 index 0000000000..f0217ac227 --- /dev/null +++ b/libevm/VM.cpp @@ -0,0 +1,1132 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file VM.cpp + * @author Gav Wood + * @date 2014 + */ + +#include +#include "VMConfig.h" +#include "VM.h" +#include "VMExtends.h" + +using namespace std; +using namespace dev; +using namespace dev::eth; + +#ifdef EVM_COVERTOOL + CoverTool VM::covertool; +#endif + +uint64_t VM::memNeed(u256 _offset, u256 _size) +{ + return toUint64(_size ? u512(_offset) + _size : u512(0)); +} + +template S divWorkaround(S const& _a, S const& _b) +{ + return (S)(s512(_a) / s512(_b)); +} + +template S modWorkaround(S const& _a, S const& _b) +{ + return (S)(s512(_a) % s512(_b)); +} + + +// +// for decoding destinations of JUMPTO, JUMPV, JUMPSUB and JUMPSUBV +// + +uint64_t VM::decodeJumpDest(const byte* const _code, uint64_t& _pc) +{ + // turn 4 MSB-first bytes in the code into a native-order integer + uint64_t dest = _code[_pc++]; + dest = (dest << 8) | _code[_pc++]; + dest = (dest << 8) | _code[_pc++]; + dest = (dest << 8) | _code[_pc++]; + return dest; +} + +uint64_t VM::decodeJumpvDest(const byte* const _code, uint64_t& _pc, u256*& _sp) +{ + // Layout of jump table in bytecode... + // byte opcode + // byte n_jumps + // byte table[n_jumps][4] + // + uint64_t i = uint64_t(*_sp--); // byte on stack indexes into jump table + uint64_t pc = _pc; + byte n = _code[++pc]; // byte after opcode is number of jumps + if (i >= n) i = n - 1; // if index overflow use default jump + pc += 1 + i * 4; // adjust pc to index destination in table + + uint64_t dest = decodeJumpDest(_code, pc); + + _pc += 1 + n * 4; // adust input _pc to opcode after table + return dest; +} + + +// +// for tracing, checking, metering, measuring ... +// +void VM::onOperation() +{ + if (m_onOp) + (m_onOp)(++m_nSteps, m_pc, m_op, + m_newMemSize > m_mem.size() ? (m_newMemSize - m_mem.size()) / 32 : uint64_t(0), + m_runGas, m_io_gas, this, m_ext); +} + +void VM::checkStack(unsigned _removed, unsigned _added) +{ + int const size = 1 + m_sp - m_stack; + int const usedSize = size - _removed; + if (usedSize < 0 || usedSize + _added > 1024) + throwBadStack(size, _removed, _added); +} + +uint64_t VM::gasForMem(u512 _size) +{ + u512 s = _size / 32; + return toUint64((u512)m_schedule->memoryGas * s + s * s / m_schedule->quadCoeffDiv); +} + +void VM::updateIOGas() +{ + if (m_io_gas < m_runGas) + throwOutOfGas(); + m_io_gas -= m_runGas; +} + +void VM::updateGas() +{ + if (m_newMemSize > m_mem.size()) + m_runGas += toUint64(gasForMem(m_newMemSize) - gasForMem(m_mem.size())); + m_runGas += (m_schedule->copyGas * ((m_copyMemSize + 31) / 32)); + if (m_io_gas < m_runGas) + throwOutOfGas(); +} + +void VM::updateMem() +{ + m_newMemSize = (m_newMemSize + 31) / 32 * 32; + updateGas(); + if (m_newMemSize > m_mem.size()) + m_mem.resize(m_newMemSize); +} + +void VM::logGasMem() +{ + unsigned n = (unsigned)m_op - (unsigned)Instruction::LOG0; + m_runGas = toUint64(m_schedule->logGas + m_schedule->logTopicGas * n + u512(m_schedule->logDataGas) * *(m_sp - 1)); + m_newMemSize = memNeed(*m_sp, *(m_sp - 1)); + updateMem(); +} + +void VM::fetchInstruction() +{ + m_op = Instruction(m_code[m_pc]); + + #ifdef EVM_COVERTOOL + if( m_ext->envInfo().coverLog() ) + { + //cout<<"VM::fetchInstruction"<myAddress,(size_t)m_pc,m_codeSpace.size() ); + //这个地方把code的大小传进去,是为了比较是部署合约,还是交易,因为这两者之间的code有偏移,CoverTool计算的时候需要加上 + } + #endif + + const InstructionMetric& metric = c_metrics[static_cast(m_op)]; + checkStack(metric.args, metric.ret); + + // FEES... + m_runGas = toUint64(m_schedule->tierStepGas[static_cast(metric.gasPriceTier)]); + m_newMemSize = m_mem.size(); + m_copyMemSize = 0; +} + +#if EVM_HACK_ON_OPERATION + #define onOperation() +#endif +#if EVM_HACK_UPDATE_IO_GAS + #define updateIOGas() +#endif +#if EVM_HACK_STACK + #define checkStack(r,a) +#endif + +/////////////////////////////////////////////////////////////////////////////// +// +// interpreter entry point + +bytesConstRef VM::execImpl(u256& _io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp) +{ + io_gas = &_io_gas; + m_io_gas = uint64_t(_io_gas); + m_ext = &_ext; + m_schedule = &m_ext->evmSchedule(); + m_onOp = _onOp; + m_onFail = &VM::onOperation; + + try + { + // trampoline to minimize depth of call stack when calling out + m_bounce = &VM::initEntry; + do + (this->*m_bounce)(); + while (m_bounce); + + } + catch (...) + { + LOG(ERROR)<<"exception,"<<_io_gas<<","<haveDelegateCall) + throwBadInstruction(); + + CASE_BEGIN(CALL) + CASE_BEGIN(CALLCODE) + m_bounce = &VM::caseCall; + CASE_RETURN + + CASE_BEGIN(RETURN) + { + m_newMemSize = memNeed(*m_sp, *(m_sp - 1)); + updateMem(); + ON_OP(); + updateIOGas(); + + uint64_t b = (uint64_t)*m_sp--; + uint64_t s = (uint64_t)*m_sp--; + m_bytes = bytesConstRef(m_mem.data() + b, s); + m_bounce = 0; + } + CASE_RETURN + + CASE_BEGIN(SUICIDE) + { + m_runGas = toUint64(m_schedule->suicideGas); + Address dest = asAddress(*m_sp); + + // After EIP158 zero-value suicides do not have to pay account creation gas. + if (m_ext->balance(m_ext->myAddress) > 0 || m_schedule->zeroValueTransferChargesNewAccountGas()) + // After EIP150 hard fork charge additional cost of sending + // ethers to non-existing account. + if (m_schedule->suicideChargesNewAccountGas() && !m_ext->exists(dest)) + m_runGas += m_schedule->callNewAccountGas; + + ON_OP(); + updateIOGas(); + m_ext->suicide(dest); + m_bounce = 0; + } + CASE_RETURN + + CASE_BEGIN(STOP) + ON_OP(); + updateIOGas(); + m_bounce = 0; + CASE_RETURN; + + + // + // instructions potentially expanding memory + // + + CASE_BEGIN(MLOAD) + { + m_newMemSize = toUint64(*m_sp) + 32; + updateMem(); + ON_OP(); + updateIOGas(); + + *m_sp = (u256)*(h256 const*)(m_mem.data() + (unsigned)*m_sp); + ++m_pc; + } + CASE_END + + CASE_BEGIN(MSTORE) + { + m_newMemSize = toUint64(*m_sp) + 32; + updateMem(); + ON_OP(); + updateIOGas(); + + *(h256*)&m_mem[(unsigned)*m_sp] = (h256)*(m_sp - 1); + m_sp -= 2; + ++m_pc; + } + CASE_END + + CASE_BEGIN(MSTORE8) + { + m_newMemSize = toUint64(*m_sp) + 1; + updateMem(); + ON_OP(); + updateIOGas(); + + m_mem[(unsigned)*m_sp] = (byte)(*(m_sp - 1) & 0xff); + m_sp -= 2; + ++m_pc; + } + CASE_END + + CASE_BEGIN(SHA3) + { + m_runGas = toUint64(m_schedule->sha3Gas + (u512(*(m_sp - 1)) + 31) / 32 * m_schedule->sha3WordGas); + m_newMemSize = memNeed(*m_sp, *(m_sp - 1)); + updateMem(); + ON_OP(); + updateIOGas(); + + uint64_t inOff = (uint64_t)*m_sp--; + uint64_t inSize = (uint64_t)*m_sp--; + + string arg((char *)m_mem.data() + inOff, inSize); + int paramOff = 0; + string cmd = ExtendRegistrar::parseExtend(arg, paramOff); + if (!cmd.empty()) + { + try { + ExtendExecutor _extend = ExtendRegistrar::executor(cmd); + *++m_sp = _extend(arg.substr(paramOff), (char *)m_mem.data()); + } + catch (...) { + *++m_sp = 0; + } + } + else + { + *++m_sp = (u256)sha3(bytesConstRef(m_mem.data() + inOff, inSize)); + } + + ++m_pc; + } + CASE_END + + CASE_BEGIN(LOG0) + logGasMem(); + ON_OP(); + updateIOGas(); + + m_ext->log({}, bytesConstRef(m_mem.data() + (uint64_t)*m_sp, (uint64_t)*(m_sp - 1))); + m_sp -= 2; + ++m_pc; + CASE_END + + CASE_BEGIN(LOG1) + logGasMem(); + ON_OP(); + updateIOGas(); + + m_ext->log({*(m_sp - 2)}, bytesConstRef(m_mem.data() + (uint64_t)*m_sp, (uint64_t)*(m_sp - 1))); + m_sp -= 3; + ++m_pc; + CASE_END + + CASE_BEGIN(LOG2) + logGasMem(); + ON_OP(); + updateIOGas(); + + m_ext->log({*(m_sp - 2), *(m_sp-3)}, bytesConstRef(m_mem.data() + (uint64_t)*m_sp, (uint64_t)*(m_sp - 1))); + m_sp -= 4; + ++m_pc; + CASE_END + + CASE_BEGIN(LOG3) + logGasMem(); + ON_OP(); + updateIOGas(); + + m_ext->log({*(m_sp - 2), *(m_sp-3), *(m_sp-4)}, bytesConstRef(m_mem.data() + (uint64_t)*m_sp, (uint64_t)*(m_sp - 1))); + m_sp -= 5; + ++m_pc; + CASE_END + + CASE_BEGIN(LOG4) + logGasMem(); + ON_OP(); + updateIOGas(); + + m_ext->log({*(m_sp - 2), *(m_sp-3), *(m_sp-4), *(m_sp-5)}, bytesConstRef(m_mem.data() + (uint64_t)*m_sp, (uint64_t)*(m_sp - 1))); + m_sp -= 6; + ++m_pc; + CASE_END + + CASE_BEGIN(EXP) + { + u256 expon = *(m_sp - 1); + m_runGas = toUint64(m_schedule->expGas + m_schedule->expByteGas * (32 - (h256(expon).firstBitSet() / 8))); + ON_OP(); + updateIOGas(); + + u256 base = *m_sp--; + *m_sp = exp256(base, expon); + ++m_pc; + } + CASE_END + + // + // ordinary instructions + // + + CASE_BEGIN(ADD) + ON_OP(); + updateIOGas(); + + //pops two items and pushes S[-1] + S[-2] mod 2^256. + *(m_sp - 1) += *m_sp; + --m_sp; + ++m_pc; + CASE_END + + CASE_BEGIN(MUL) + ON_OP(); + updateIOGas(); + + //pops two items and pushes S[-1] * S[-2] mod 2^256. +#if EVM_HACK_MUL_64 + *(uint64_t*)(m_sp - 1) *= *(uint64_t*)m_sp; +#else + *(m_sp - 1) *= *m_sp; +#endif + --m_sp; + ++m_pc; + CASE_END + + CASE_BEGIN(SUB) + ON_OP(); + updateIOGas(); + + *(m_sp - 1) = *m_sp - *(m_sp - 1); + --m_sp; + ++m_pc; + CASE_END + + CASE_BEGIN(DIV) + ON_OP(); + updateIOGas(); + + *(m_sp - 1) = *(m_sp - 1) ? divWorkaround(*m_sp, *(m_sp - 1)) : 0; + --m_sp; + ++m_pc; + CASE_END + + CASE_BEGIN(SDIV) + ON_OP(); + updateIOGas(); + + *(m_sp - 1) = *(m_sp - 1) ? s2u(divWorkaround(u2s(*m_sp), u2s(*(m_sp - 1)))) : 0; + --m_sp; + ++m_pc; + CASE_END + + CASE_BEGIN(MOD) + ON_OP(); + updateIOGas(); + + *(m_sp - 1) = *(m_sp - 1) ? modWorkaround(*m_sp, *(m_sp - 1)) : 0; + --m_sp; + ++m_pc; + CASE_END + + CASE_BEGIN(SMOD) + ON_OP(); + updateIOGas(); + + *(m_sp - 1) = *(m_sp - 1) ? s2u(modWorkaround(u2s(*m_sp), u2s(*(m_sp - 1)))) : 0; + --m_sp; + ++m_pc; + CASE_END + + CASE_BEGIN(NOT) + ON_OP(); + updateIOGas(); + + *m_sp = ~*m_sp; + ++m_pc; + CASE_END + + CASE_BEGIN(LT) + ON_OP(); + updateIOGas(); + + *(m_sp - 1) = *m_sp < *(m_sp - 1) ? 1 : 0; + --m_sp; + ++m_pc; + CASE_END + + CASE_BEGIN(GT) + ON_OP(); + updateIOGas(); + + *(m_sp - 1) = *m_sp > *(m_sp - 1) ? 1 : 0; + --m_sp; + ++m_pc; + CASE_END + + CASE_BEGIN(SLT) + ON_OP(); + updateIOGas(); + + *(m_sp - 1) = u2s(*m_sp) < u2s(*(m_sp - 1)) ? 1 : 0; + --m_sp; + ++m_pc; + CASE_END + + CASE_BEGIN(SGT) + ON_OP(); + updateIOGas(); + + *(m_sp - 1) = u2s(*m_sp) > u2s(*(m_sp - 1)) ? 1 : 0; + --m_sp; + ++m_pc; + CASE_END + + CASE_BEGIN(EQ) + ON_OP(); + updateIOGas(); + + *(m_sp - 1) = *m_sp == *(m_sp - 1) ? 1 : 0; + --m_sp; + ++m_pc; + CASE_END + + CASE_BEGIN(ISZERO) + ON_OP(); + updateIOGas(); + + *m_sp = *m_sp ? 0 : 1; + ++m_pc; + CASE_END + + CASE_BEGIN(AND) + ON_OP(); + updateIOGas(); + + *(m_sp - 1) = *m_sp & *(m_sp - 1); + --m_sp; + ++m_pc; + CASE_END + + CASE_BEGIN(OR) + ON_OP(); + updateIOGas(); + + *(m_sp - 1) = *m_sp | *(m_sp - 1); + --m_sp; + ++m_pc; + CASE_END + + CASE_BEGIN(XOR) + ON_OP(); + updateIOGas(); + + *(m_sp - 1) = *m_sp ^ *(m_sp - 1); + --m_sp; + ++m_pc; + CASE_END + + CASE_BEGIN(BYTE) + ON_OP(); + updateIOGas(); + + *(m_sp - 1) = *m_sp < 32 ? (*(m_sp - 1) >> (unsigned)(8 * (31 - *m_sp))) & 0xff : 0; + --m_sp; + ++m_pc; + CASE_END + + CASE_BEGIN(ADDMOD) + ON_OP(); + updateIOGas(); + + *(m_sp - 2) = *(m_sp - 2) ? u256((u512(*m_sp) + u512(*(m_sp - 1))) % *(m_sp - 2)) : 0; + m_sp -= 2; + ++m_pc; + CASE_END + + CASE_BEGIN(MULMOD) + ON_OP(); + updateIOGas(); + + *(m_sp - 2) = *(m_sp - 2) ? u256((u512(*m_sp) * u512(*(m_sp - 1))) % *(m_sp - 2)) : 0; + m_sp -= 2; + ++m_pc; + CASE_END + + CASE_BEGIN(SIGNEXTEND) + ON_OP(); + updateIOGas(); + + if (*m_sp < 31) + { + unsigned testBit = static_cast(*m_sp) * 8 + 7; + u256& number = *(m_sp - 1); + u256 mask = ((u256(1) << testBit) - 1); + if (boost::multiprecision::bit_test(number, testBit)) + number |= ~mask; + else + number &= mask; + } + --m_sp; + ++m_pc; + CASE_END + + CASE_BEGIN(ADDRESS) + ON_OP(); + updateIOGas(); + + *++m_sp = fromAddress(m_ext->myAddress); + ++m_pc; + CASE_END + + CASE_BEGIN(ORIGIN) + ON_OP(); + updateIOGas(); + + *++m_sp = fromAddress(m_ext->origin); + ++m_pc; + CASE_END + + CASE_BEGIN(BALANCE) + { + m_runGas = toUint64(m_schedule->balanceGas); + ON_OP(); + updateIOGas(); + + *m_sp = m_ext->balance(asAddress(*m_sp)); + ++m_pc; + } + CASE_END + + + CASE_BEGIN(CALLER) + ON_OP(); + updateIOGas(); + + *++m_sp = fromAddress(m_ext->caller); + ++m_pc; + CASE_END + + CASE_BEGIN(CALLVALUE) + ON_OP(); + updateIOGas(); + + *++m_sp = m_ext->value; + ++m_pc; + CASE_END + + + CASE_BEGIN(CALLDATALOAD) + { + ON_OP(); + updateIOGas(); + + if (u512(*m_sp) + 31 < m_ext->data.size()) + *m_sp = (u256)*(h256 const*)(m_ext->data.data() + (size_t)*m_sp); + else if (*m_sp >= m_ext->data.size()) + *m_sp = u256(0); + else + { + h256 r; + for (uint64_t i = (uint64_t)*m_sp, e = (uint64_t)*m_sp + (uint64_t)32, j = 0; i < e; ++i, ++j) + r[j] = i < m_ext->data.size() ? m_ext->data[i] : 0; + *m_sp = (u256)r; + } + ++m_pc; + } + CASE_END + + + CASE_BEGIN(CALLDATASIZE) + ON_OP(); + updateIOGas(); + + *++m_sp = m_ext->data.size(); + ++m_pc; + CASE_END + + CASE_BEGIN(CODESIZE) + ON_OP(); + updateIOGas(); + + *++m_sp = m_ext->code.size(); + ++m_pc; + CASE_END + + CASE_BEGIN(EXTCODESIZE) + m_runGas = toUint64(m_schedule->extcodesizeGas); + ON_OP(); + updateIOGas(); + + *m_sp = m_ext->codeSizeAt(asAddress(*m_sp)); + ++m_pc; + CASE_END + + CASE_BEGIN(CALLDATACOPY) + m_copyMemSize = toUint64(*(m_sp - 2)); + m_newMemSize = memNeed(*m_sp, *(m_sp - 2)); + updateMem(); + ON_OP(); + updateIOGas(); + + copyDataToMemory(m_ext->data, m_sp); + ++m_pc; + CASE_END + + CASE_BEGIN(CODECOPY) + m_copyMemSize = toUint64(*(m_sp - 2)); + m_newMemSize = memNeed(*m_sp, *(m_sp - 2)); + updateMem(); + ON_OP(); + updateIOGas(); + + copyDataToMemory(&m_ext->code, m_sp); + ++m_pc; + CASE_END + + CASE_BEGIN(EXTCODECOPY) + { + m_runGas = toUint64(m_schedule->extcodecopyGas); + m_copyMemSize = toUint64(*(m_sp - 3)); + m_newMemSize = memNeed(*(m_sp - 1), *(m_sp - 3)); + updateMem(); + ON_OP(); + updateIOGas(); + + Address a = asAddress(*m_sp); + --m_sp; + copyDataToMemory(&m_ext->codeAt(a), m_sp); + ++m_pc; + } + CASE_END + + + CASE_BEGIN(GASPRICE) + ON_OP(); + updateIOGas(); + + *++m_sp = m_ext->gasPrice; + ++m_pc; + CASE_END + + CASE_BEGIN(BLOCKHASH) + ON_OP(); + updateIOGas(); + + *m_sp = (u256)m_ext->blockHash(*m_sp); + ++m_pc; + CASE_END + + CASE_BEGIN(COINBASE) + ON_OP(); + updateIOGas(); + + *++m_sp = (u160)m_ext->envInfo().author(); + ++m_pc; + CASE_END + + CASE_BEGIN(TIMESTAMP) + ON_OP(); + updateIOGas(); + + *++m_sp = m_ext->envInfo().timestamp(); + ++m_pc; + CASE_END + + CASE_BEGIN(NUMBER) + ON_OP(); + updateIOGas(); + + *++m_sp = m_ext->envInfo().number(); + ++m_pc; + CASE_END + + CASE_BEGIN(DIFFICULTY) + ON_OP(); + updateIOGas(); + + *++m_sp = m_ext->envInfo().difficulty(); + ++m_pc; + CASE_END + + CASE_BEGIN(GASLIMIT) + ON_OP(); + updateIOGas(); + + *++m_sp = m_ext->envInfo().gasLimit(); + ++m_pc; + CASE_END + + CASE_BEGIN(POP) + ON_OP(); + updateIOGas(); + + --m_sp; + ++m_pc; + CASE_END + + CASE_BEGIN(PUSHC) +#ifdef EVM_USE_CONSTANT_POOL + { + ON_OP(); + updateIOGas(); + + ++m_pc; + *++m_sp = m_pool[m_code[m_pc]]; + ++m_pc; + m_pc += m_code[m_pc]; + } +#else + throwBadInstruction(); +#endif + CASE_END + + CASE_BEGIN(PUSH1) + ON_OP(); + updateIOGas(); + *++m_sp = m_code[++m_pc]; + ++m_pc; + CASE_END + + CASE_BEGIN(PUSH2) + CASE_BEGIN(PUSH3) + CASE_BEGIN(PUSH4) + CASE_BEGIN(PUSH5) + CASE_BEGIN(PUSH6) + CASE_BEGIN(PUSH7) + CASE_BEGIN(PUSH8) + CASE_BEGIN(PUSH9) + CASE_BEGIN(PUSH10) + CASE_BEGIN(PUSH11) + CASE_BEGIN(PUSH12) + CASE_BEGIN(PUSH13) + CASE_BEGIN(PUSH14) + CASE_BEGIN(PUSH15) + CASE_BEGIN(PUSH16) + CASE_BEGIN(PUSH17) + CASE_BEGIN(PUSH18) + CASE_BEGIN(PUSH19) + CASE_BEGIN(PUSH20) + CASE_BEGIN(PUSH21) + CASE_BEGIN(PUSH22) + CASE_BEGIN(PUSH23) + CASE_BEGIN(PUSH24) + CASE_BEGIN(PUSH25) + CASE_BEGIN(PUSH26) + CASE_BEGIN(PUSH27) + CASE_BEGIN(PUSH28) + CASE_BEGIN(PUSH29) + CASE_BEGIN(PUSH30) + CASE_BEGIN(PUSH31) + CASE_BEGIN(PUSH32) + { + ON_OP(); + updateIOGas(); + + int numBytes = (int)m_op - (int)Instruction::PUSH1 + 1; + *++m_sp = 0; + // Construct a number out of PUSH bytes. + // This requires the code has been copied and extended by 32 zero + // bytes to handle "out of code" push data here. + for (++m_pc; numBytes--; ++m_pc) + *m_sp = (*m_sp << 8) | m_code[m_pc]; + } + CASE_END + + CASE_BEGIN(JUMP) + ON_OP(); + updateIOGas(); + + m_pc = verifyJumpDest(*m_sp); + --m_sp; + CASE_END + + CASE_BEGIN(JUMPI) + ON_OP(); + updateIOGas(); + if (*(m_sp - 1)) + m_pc = verifyJumpDest(*m_sp); + else + ++m_pc; + m_sp -= 2; + CASE_END + +#if EVM_JUMPS_AND_SUBS + CASE_BEGIN(JUMPTO) + ON_OP(); + updateIOGas(); + m_pc = decodeJumpDest(m_code, m_pc); + CASE_END + + CASE_BEGIN(JUMPIF) + ON_OP(); + updateIOGas(); + if (*m_sp) + m_pc = decodeJumpDest(m_code, m_pc); + else + ++m_pc; + --m_sp; + CASE_END + + CASE_BEGIN(JUMPV) + ON_OP(); + updateIOGas(); + m_pc = decodeJumpvDest(m_code, m_pc, m_sp); + CASE_END + + CASE_BEGIN(JUMPSUB) + ON_OP(); + updateIOGas(); + { + *++m_rp = m_pc++; + m_pc = decodeJumpDest(m_code, m_pc); + } + CASE_END + + CASE_BEGIN(JUMPSUBV) + ON_OP(); + updateIOGas(); + { + *++m_rp = m_pc; + m_pc = + jumpvDest(m_code, m_pc, m_sp); + } + CASE_END + + CASE_BEGIN(RETURNSUB) + ON_OP(); + updateIOGas(); + + m_pc = *m_rp--; + ++m_pc; + CASE_END +#else + CASE_BEGIN(JUMPTO) + CASE_BEGIN(JUMPIF) + CASE_BEGIN(JUMPV) + CASE_BEGIN(JUMPSUB) + CASE_BEGIN(JUMPSUBV) + CASE_BEGIN(RETURNSUB) + throwBadInstruction(); + CASE_END +#endif + + CASE_BEGIN(JUMPC) +#ifdef EVM_REPLACE_CONST_JUMP + ON_OP(); + updateIOGas(); + + m_pc = uint64_t(*m_sp); + --m_sp; +#else + throwBadInstruction(); +#endif + CASE_END + + CASE_BEGIN(JUMPCI) +#ifdef EVM_REPLACE_CONST_JUMP + ON_OP(); + updateIOGas(); + + if (*(m_sp - 1)) + m_pc = uint64_t(*m_sp); + else + ++m_pc; + m_sp -= 2; +#else + throwBadInstruction(); +#endif + CASE_END + + CASE_BEGIN(DUP1) + CASE_BEGIN(DUP2) + CASE_BEGIN(DUP3) + CASE_BEGIN(DUP4) + CASE_BEGIN(DUP5) + CASE_BEGIN(DUP6) + CASE_BEGIN(DUP7) + CASE_BEGIN(DUP8) + CASE_BEGIN(DUP9) + CASE_BEGIN(DUP10) + CASE_BEGIN(DUP11) + CASE_BEGIN(DUP12) + CASE_BEGIN(DUP13) + CASE_BEGIN(DUP14) + CASE_BEGIN(DUP15) + CASE_BEGIN(DUP16) + { + ON_OP(); + updateIOGas(); + + unsigned n = 1 + (unsigned)m_op - (unsigned)Instruction::DUP1; +#if EVM_HACK_DUP_64 + *(uint64_t*)(m_sp+1) = *(uint64_t*)&m_stack[(1 + m_sp - m_stack) - n]; +#else + *(m_sp+1) = m_stack[(1 + m_sp - m_stack) - n]; +#endif + ++m_sp; + ++m_pc; + } + CASE_END + + + CASE_BEGIN(SWAP1) + CASE_BEGIN(SWAP2) + CASE_BEGIN(SWAP3) + CASE_BEGIN(SWAP4) + CASE_BEGIN(SWAP5) + CASE_BEGIN(SWAP6) + CASE_BEGIN(SWAP7) + CASE_BEGIN(SWAP8) + CASE_BEGIN(SWAP9) + CASE_BEGIN(SWAP10) + CASE_BEGIN(SWAP11) + CASE_BEGIN(SWAP12) + CASE_BEGIN(SWAP13) + CASE_BEGIN(SWAP14) + CASE_BEGIN(SWAP15) + CASE_BEGIN(SWAP16) + { + ON_OP(); + updateIOGas(); + + unsigned n = (unsigned)m_op - (unsigned)Instruction::SWAP1 + 2; + u256 d = *m_sp; + *m_sp = m_stack[(1 + m_sp - m_stack) - n]; + m_stack[(1 + m_sp - m_stack) - n] = d; + ++m_pc; + } + CASE_END + + + CASE_BEGIN(SLOAD) + m_runGas = toUint64(m_schedule->sloadGas); + ON_OP(); + updateIOGas(); + + *m_sp = m_ext->store(*m_sp); + ++m_pc; + CASE_END + + CASE_BEGIN(SSTORE) + if (!m_ext->store(*m_sp) && *(m_sp - 1)) + m_runGas = toUint64(m_schedule->sstoreSetGas); + else if (m_ext->store(*m_sp) && !*(m_sp - 1)) + { + m_runGas = toUint64(m_schedule->sstoreResetGas); + m_ext->sub.refunds += m_schedule->sstoreRefundGas; + } + else + m_runGas = toUint64(m_schedule->sstoreResetGas); + ON_OP(); + updateIOGas(); + + m_ext->setStore(*m_sp, *(m_sp - 1)); + m_sp -= 2; + ++m_pc; + CASE_END + + CASE_BEGIN(PC) + ON_OP(); + updateIOGas(); + + *++m_sp = m_pc; + ++m_pc; + CASE_END + + CASE_BEGIN(MSIZE) + ON_OP(); + updateIOGas(); + + *++m_sp = m_mem.size(); + ++m_pc; + CASE_END + + CASE_BEGIN(GAS) + ON_OP(); + updateIOGas(); + + *++m_sp = m_io_gas; + ++m_pc; + CASE_END + + CASE_BEGIN(JUMPDEST) + m_runGas = 1; + ON_OP(); + updateIOGas(); + ++m_pc; + CASE_END + +#if EVM_JUMPS_AND_SUBS + CASE_BEGIN(BEGINSUB) + m_runGas = 1; + ON_OP(); + updateIOGas(); + ++m_pc; + CASE_END + + CASE_BEGIN(BEGINDATA) + throwBadInstruction(); + CASE_END +#else + CASE_BEGIN(BEGINSUB) + CASE_BEGIN(BEGINDATA) + throwBadInstruction(); + CASE_END +#endif + + CASE_BEGIN(BAD) + throwBadInstruction(); + CASE_END + + CASE_DEFAULT + throwBadInstruction(); + CASE_END + + END_CASES +} diff --git a/libevm/VM.h b/libevm/VM.h new file mode 100644 index 0000000000..0c505c5f1a --- /dev/null +++ b/libevm/VM.h @@ -0,0 +1,183 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file VM.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include "VMFace.h" + +#ifdef EVM_COVERTOOL +#include "CoverTool.h" +#endif + +namespace dev +{ +namespace eth +{ + +// Convert from a 256-bit integer stack/memory entry into a 160-bit Address hash. +// Currently we just pull out the right (low-order in BE) 160-bits. +inline Address asAddress(u256 _item) +{ + return right160(h256(_item)); +} + +inline u256 fromAddress(Address _a) +{ + return (u160)_a; +} + + +struct InstructionMetric +{ + Tier gasPriceTier; + int args; + int ret; +}; + + +/** + */ +class VM: public VMFace +{ +public: + virtual bytesConstRef execImpl(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp) override final; + + bytes const& memory() const { return m_mem; } + u256s stack() const { assert(m_stack <= m_sp + 1); return u256s(m_stack, m_sp + 1); }; + + #ifdef EVM_COVERTOOL + static CoverTool covertool; + #endif + +private: + + u256* io_gas = 0; + uint64_t m_io_gas = 0; + ExtVMFace* m_ext = 0; + OnOpFunc m_onOp; + + static std::array c_metrics; + static void initMetrics(); + static u256 exp256(u256 _base, u256 _exponent); + void copyCode(int); + const void* const* c_jumpTable = 0; + bool m_caseInit = false; + + typedef void (VM::*MemFnPtr)(); + MemFnPtr m_bounce = 0; + MemFnPtr m_onFail = 0; + uint64_t m_nSteps = 0; + EVMSchedule const* m_schedule = nullptr; + + // return bytes + bytesConstRef m_bytes = bytesConstRef(); + + // space for memory + bytes m_mem; + + // space for code and pointer to data + bytes m_codeSpace; + byte* m_code = nullptr; + + // space for stack and pointer to data + u256 m_stackSpace[1025]; + u256* m_stack = m_stackSpace + 1; + +#if EVM_JUMPS_AND_SUBS + // space for return stack and pointer to data + uint64_t m_returnSpace[1025]; + uint64_t* m_return = m_returnSpace + 1; +#endif + + // constant pool + u256 m_pool[256]; + + // interpreter state + Instruction m_op; // current operator + uint64_t m_pc = 0; // program counter + u256* m_sp = m_stack - 1; // stack pointer +#if EVM_JUMPS_AND_SUBS + uint64_t* m_rp = m_return - 1; // return pointer +#endif + + // metering and memory state + uint64_t m_runGas = 0; + uint64_t m_newMemSize = 0; + uint64_t m_copyMemSize = 0; + + // initialize interpreter + void initEntry(); + void optimize(); + + // interpreter loop & switch + void interpretCases(); + + // interpreter cases that call out + void caseCreate(); + bool caseCallSetup(CallParameters*); + void caseCall(); + + void copyDataToMemory(bytesConstRef _data, u256*& m_sp); + uint64_t memNeed(u256 _offset, u256 _size); + + void throwOutOfGas(); + void throwBadInstruction(); + void throwBadJumpDestination(); + void throwBadStack(unsigned _size, unsigned _n, unsigned _d); + + void reportStackUse(); + + std::vector m_beginSubs; + std::vector m_jumpDests; + int64_t verifyJumpDest(u256 const& _dest, bool _throw = true); + + int poolConstant(const u256&); + + void onOperation(); + void checkStack(unsigned _n, unsigned _d); + uint64_t gasForMem(u512 _size); + void updateIOGas(); + void updateGas(); + void updateMem(); + void logGasMem(); + void fetchInstruction(); + + uint64_t decodeJumpDest(const byte* const _code, uint64_t& _pc); + uint64_t decodeJumpvDest(const byte* const _code, uint64_t& _pc, u256*& _sp); + + template uint64_t toUint64(T v) + { + // check for overflow + if (v > 0x7FFFFFFFFFFFFFFF) + throwOutOfGas(); + uint64_t w = uint64_t(v); + return w; + } + }; + +} +} diff --git a/libevm/VMCalls.cpp b/libevm/VMCalls.cpp new file mode 100644 index 0000000000..8eabecf66e --- /dev/null +++ b/libevm/VMCalls.cpp @@ -0,0 +1,209 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ + + +#include +#include "VMConfig.h" +#include "VM.h" +using namespace std; +using namespace dev; +using namespace dev::eth; + + + +void VM::copyDataToMemory(bytesConstRef _data, u256*& _sp) +{ + auto offset = static_cast(*_sp--); + s512 bigIndex = *_sp--; + auto index = static_cast(bigIndex); + auto size = static_cast(*_sp--); + + size_t sizeToBeCopied = bigIndex + size > _data.size() ? _data.size() < bigIndex ? 0 : _data.size() - index : size; + + if (sizeToBeCopied > 0) + std::memcpy(m_mem.data() + offset, _data.data() + index, sizeToBeCopied); + if (size > sizeToBeCopied) + std::memset(m_mem.data() + offset + sizeToBeCopied, 0, size - sizeToBeCopied); +} + + +// consolidate exception throws to avoid spraying boost code all over interpreter + +void VM::throwOutOfGas() +{ + BOOST_THROW_EXCEPTION(OutOfGas()); +} + +void VM::throwBadInstruction() +{ + BOOST_THROW_EXCEPTION(BadInstruction()); +} + +void VM::throwBadJumpDestination() +{ + BOOST_THROW_EXCEPTION(BadJumpDestination()); +} + +void VM::throwBadStack(unsigned _size, unsigned _removed, unsigned _added) +{ + if (_size < _removed) + { + if (m_onFail) + (this->*m_onFail)(); + BOOST_THROW_EXCEPTION(StackUnderflow() << RequirementError((bigint)_removed, (bigint)_size)); + } + if (_size - _removed + _added > 1024) + { + if (m_onFail) + (this->*m_onFail)(); + BOOST_THROW_EXCEPTION(OutOfStack() << RequirementError((bigint)(_added - _removed), (bigint)_size)); + } +} + +int64_t VM::verifyJumpDest(u256 const& _dest, bool _throw) +{ + + // check for overflow + if (_dest <= 0x7FFFFFFFFFFFFFFF) { + + // check for within bounds and to a jump destination + // use binary search of array because hashtable collisions are exploitable + uint64_t pc = uint64_t(_dest); + if (std::binary_search(m_jumpDests.begin(), m_jumpDests.end(), pc)) + return pc; + } + if (_throw) + throwBadJumpDestination(); + return -1; +} + + +// +// interpreter cases that call out +// + +void VM::caseCreate() +{ + m_bounce = &VM::interpretCases; + m_newMemSize = memNeed(*(m_sp - 1), *(m_sp - 2)); + m_runGas = toUint64(m_schedule->createGas); + updateMem(); + ON_OP(); + updateIOGas(); + + auto const& endowment = *m_sp--; + uint64_t initOff = (uint64_t)*m_sp--; + uint64_t initSize = (uint64_t)*m_sp--; + + if (m_ext->balance(m_ext->myAddress) >= endowment && m_ext->depth < 1024) + { + *io_gas = m_io_gas; + u256 createGas = *io_gas; + if (!m_schedule->staticCallDepthLimit()) + createGas -= createGas / 64; + u256 gas = createGas; + *++m_sp = (u160)m_ext->create(endowment, gas, bytesConstRef(m_mem.data() + initOff, initSize), m_onOp); + *io_gas -= (createGas - gas); + m_io_gas = uint64_t(*io_gas); + } + else + *++m_sp = 0; + ++m_pc; +} + +void VM::caseCall() +{ + m_bounce = &VM::interpretCases; + unique_ptr callParams(new CallParameters()); + if (caseCallSetup(&*callParams)) + *++m_sp = m_ext->call(*callParams); + else + *++m_sp = 0; + m_io_gas += uint64_t(callParams->gas); + ++m_pc; +} + +bool VM::caseCallSetup(CallParameters *callParams) +{ + m_runGas = toUint64(m_schedule->callGas); + + if (m_op == Instruction::CALL && !m_ext->exists(asAddress(*(m_sp - 1)))) + if (*(m_sp - 2) > 0 || m_schedule->zeroValueTransferChargesNewAccountGas()) + m_runGas += toUint64(m_schedule->callNewAccountGas); + + if (m_op != Instruction::DELEGATECALL && *(m_sp - 2) > 0) + m_runGas += toUint64(m_schedule->callValueTransferGas); + + unsigned sizesOffset = m_op == Instruction::DELEGATECALL ? 3 : 4; + m_newMemSize = std::max( + memNeed(m_stack[(1 + m_sp - m_stack) - sizesOffset - 2], m_stack[(1 + m_sp - m_stack) - sizesOffset - 3]), + memNeed(m_stack[(1 + m_sp - m_stack) - sizesOffset], m_stack[(1 + m_sp - m_stack) - sizesOffset - 1]) + ); + updateMem(); + updateIOGas(); + + // "Static" costs already applied. Calculate call gas. + if (m_schedule->staticCallDepthLimit()) + // With static call depth limit we just charge the provided gas amount. + callParams->gas = *m_sp; + else + { + // Apply "all but one 64th" rule. + u256 maxAllowedCallGas = m_io_gas - m_io_gas / 64; + callParams->gas = std::min(*m_sp, maxAllowedCallGas); + } + + m_runGas = toUint64(callParams->gas); + ON_OP(); + updateIOGas(); + + if (m_op != Instruction::DELEGATECALL && *(m_sp - 2) > 0) + callParams->gas += m_schedule->callStipend; + --m_sp; + + callParams->codeAddress = asAddress(*m_sp); + --m_sp; + + if (m_op == Instruction::DELEGATECALL) + { + callParams->apparentValue = m_ext->value; + callParams->valueTransfer = 0; + } + else + { + callParams->apparentValue = callParams->valueTransfer = *m_sp; + --m_sp; + } + + uint64_t inOff = (uint64_t)*m_sp--; + uint64_t inSize = (uint64_t)*m_sp--; + uint64_t outOff = (uint64_t)*m_sp--; + uint64_t outSize = (uint64_t)*m_sp--; + + if (m_ext->balance(m_ext->myAddress) >= callParams->valueTransfer && m_ext->depth < 1024) + { + callParams->onOp = m_onOp; + callParams->senderAddress = m_op == Instruction::DELEGATECALL ? m_ext->caller : m_ext->myAddress; + callParams->receiveAddress = m_op == Instruction::CALL ? callParams->codeAddress : m_ext->myAddress; + callParams->data = bytesConstRef(m_mem.data() + inOff, inSize); + callParams->out = bytesRef(m_mem.data() + outOff, outSize); + return true; + } + else + return false; +} + diff --git a/libevm/VMConfig.h b/libevm/VMConfig.h new file mode 100644 index 0000000000..88da994a8a --- /dev/null +++ b/libevm/VMConfig.h @@ -0,0 +1,429 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ + +namespace dev +{ +namespace eth +{ + +/////////////////////////////////////////////////////////////////////////////// +// +// interpreter configuration macros for optimizations and tracing +// +// EVM_SWITCH_DISPATCH - dispatch via loop and switch +// EVM_JUMP_DISPATCH - dispatch via a jump table - available only on GCC +// +// EVM_USE_CONSTANT_POOL - 256 constants unpacked and ready to assign to stack +// +// EVM_REPLACE_CONST_JUMP - with pre-verified jumps to save runtime lookup +// +// EVM_TRACE - provides various levels of tracing + +#if true + #define EVM_COVERTOOL +#endif + +#if true && defined(__GNUG__) + #define EVM_JUMP_DISPATCH +#else + #define EVM_SWITCH_DISPATCH +#endif + +#if defined(EVM_COVERTOOL) + +#else + + #if false + #define EVM_REPLACE_CONST_JUMP + #endif + + #if false + #define EVM_USE_CONSTANT_POOL + #endif + + #if defined(EVM_USE_CONSTANT_POOL) || \ + defined(EVM_REPLACE_CONST_JUMP) + #define EVM_DO_FIRST_PASS_OPTIMIZATION + #endif + +#endif + + +#define EVM_JUMPS_AND_SUBS false + + + +/////////////////////////////////////////////////////////////////////////////// +// +// set this to 2, 1, or 0 for more, less, or no tracing to cerr +// +#ifndef EVM_TRACE + #define EVM_TRACE 0 +#endif +#if EVM_TRACE > 0 + + #undef ON_OP + #if EVM_TRACE > 1 + #define ON_OP() \ + (onOperation(), \ + (cerr <<"### "<< m_nSteps <<" @"<< m_pc <<" "<< instructionInfo(m_op).name < 0 + #define THROW_EXCEPTION(X) \ + ((cerr << "!!! EVM EXCEPTION " << (X).what() << endl), BOOST_THROW_EXCEPTION(X)) + #else + #define THROW_EXCEPTION(X) BOOST_THROW_EXCEPTION(X) + #endif +#endif + + +/////////////////////////////////////////////////////////////////////////////// +// +// build a simple loop-and-switch interpreter +// +#if defined(EVM_SWITCH_DISPATCH) + + #define INIT_CASES if (!m_caseInit) { m_caseInit = true; return; } + #define DO_CASES for(;;) { fetchInstruction(); switch(m_op) { + #define CASE_BEGIN(name) case Instruction::name: + #define CASE_END break; + #define CASE_RETURN return; + #define CASE_DEFAULT default: + #define END_CASES } } + + +/////////////////////////////////////////////////////////////////////////////// +// +// build an indirect-threaded interpreter using a jump table of +// label addresses (a gcc extension) +// +#elif defined(EVM_JUMP_DISPATCH) + + #define INIT_CASES \ + \ + static const void * const jumpTable[256] = \ + { \ + &&STOP, /* 00 */ \ + &&ADD, \ + &&MUL, \ + &&SUB, \ + &&DIV, \ + &&SDIV, \ + &&MOD, \ + &&SMOD, \ + &&ADDMOD, \ + &&MULMOD, \ + &&EXP, \ + &&SIGNEXTEND, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &<, /* 10, */ \ + &>, \ + &&SLT, \ + &&SGT, \ + &&EQ, \ + &&ISZERO, \ + &&AND, \ + &&OR, \ + &&XOR, \ + &&NOT, \ + &&BYTE, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&SHA3, /* 20, */ \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&ADDRESS, /* 30, */ \ + &&BALANCE, \ + &&ORIGIN, \ + &&CALLER, \ + &&CALLVALUE, \ + &&CALLDATALOAD, \ + &&CALLDATASIZE, \ + &&CALLDATACOPY, \ + &&CODESIZE, \ + &&CODECOPY, \ + &&GASPRICE, \ + &&EXTCODESIZE, \ + &&EXTCODECOPY, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&BLOCKHASH, /* 40, */ \ + &&COINBASE, \ + &&TIMESTAMP, \ + &&NUMBER, \ + &&DIFFICULTY, \ + &&GASLIMIT, \ + &&JUMPTO, \ + &&JUMPIF, \ + &&JUMPV, \ + &&JUMPSUB, \ + &&JUMPSUBV, \ + &&RETURNSUB, \ + &&BEGINSUB, \ + &&BEGINDATA, \ + &&INVALID, \ + &&INVALID, \ + &&POP, /* 50, */ \ + &&MLOAD, \ + &&MSTORE, \ + &&MSTORE8, \ + &&SLOAD, \ + &&SSTORE, \ + &&JUMP, \ + &&JUMPI, \ + &&PC, \ + &&MSIZE, \ + &&GAS, \ + &&JUMPDEST, \ + &&BEGINDATA, \ + &&BEGINSUB, \ + &&INVALID, \ + &&INVALID, \ + &&PUSH1, /* 60, */ \ + &&PUSH2, \ + &&PUSH3, \ + &&PUSH4, \ + &&PUSH5, \ + &&PUSH6, \ + &&PUSH7, \ + &&PUSH8, \ + &&PUSH9, \ + &&PUSH10, \ + &&PUSH11, \ + &&PUSH12, \ + &&PUSH13, \ + &&PUSH14, \ + &&PUSH15, \ + &&PUSH16, \ + &&PUSH17, /* 70, */ \ + &&PUSH18, \ + &&PUSH19, \ + &&PUSH20, \ + &&PUSH21, \ + &&PUSH22, \ + &&PUSH23, \ + &&PUSH24, \ + &&PUSH25, \ + &&PUSH26, \ + &&PUSH27, \ + &&PUSH28, \ + &&PUSH29, \ + &&PUSH30, \ + &&PUSH31, \ + &&PUSH32, \ + &&DUP1, /* 80, */ \ + &&DUP2, \ + &&DUP3, \ + &&DUP4, \ + &&DUP5, \ + &&DUP6, \ + &&DUP7, \ + &&DUP8, \ + &&DUP9, \ + &&DUP10, \ + &&DUP11, \ + &&DUP12, \ + &&DUP13, \ + &&DUP14, \ + &&DUP15, \ + &&DUP16, \ + &&SWAP1, /* 90, */ \ + &&SWAP2, \ + &&SWAP3, \ + &&SWAP4, \ + &&SWAP5, \ + &&SWAP6, \ + &&SWAP7, \ + &&SWAP8, \ + &&SWAP9, \ + &&SWAP10, \ + &&SWAP11, \ + &&SWAP12, \ + &&SWAP13, \ + &&SWAP14, \ + &&SWAP15, \ + &&SWAP16, \ + &&LOG0, /* A0, */ \ + &&LOG1, \ + &&LOG2, \ + &&LOG3, \ + &&LOG4, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&PUSHC, \ + &&JUMPC, \ + &&JUMPCI, \ + &&BAD, \ + &&INVALID, /* B0, */ \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, /* C0, */ \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, /* D0, */ \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, /* E0, */ \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&CREATE, /* F0, */ \ + &&CALL, \ + &&CALLCODE, \ + &&RETURN, \ + &&DELEGATECALL, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&INVALID, \ + &&SUICIDE, \ + }; \ + if (!m_caseInit) { \ + c_jumpTable = jumpTable; \ + m_caseInit = true; \ + return; \ + } + + #define DO_CASES fetchInstruction(); goto *jumpTable[(int)m_op]; + #define CASE_BEGIN(name) name: + #define CASE_END fetchInstruction(); goto *jumpTable[m_code[m_pc]]; + #define CASE_RETURN return; + #define CASE_DEFAULT INVALID: + #define END_CASES + +#else + #error No opcode dispatch configured +#endif + +}} \ No newline at end of file diff --git a/libevm/VMExtends.cpp b/libevm/VMExtends.cpp new file mode 100644 index 0000000000..57cdf1d47b --- /dev/null +++ b/libevm/VMExtends.cpp @@ -0,0 +1,139 @@ +/** @file VMExtends.cpp + * @author ximi + * @date 2017.05.24 + */ + +#include +#include "VMExtends.h" +#include +#include "pailler.h" + +using namespace std; +using namespace dev; +using namespace dev::eth; + +ExtendRegistrar* ExtendRegistrar::s_this = nullptr; + +ExtendExecutor const& ExtendRegistrar::executor(std::string const& _name) +{ + if (!get()->m_execs.count(_name)) + BOOST_THROW_EXCEPTION(ExtendExecutorNotFound()); + return get()->m_execs[_name]; +} + +std::string ExtendRegistrar::parseExtend(std::string const& _param, int & _paramOff) +{ + std::string ret; + _paramOff = 0; + const std::string extendTag("[69d98d6a04c41b4605aacb7bd2f74bee]"); + const int tagLen = 34;//[69d98d6a04c41b4605aacb7bd2f74bee] + const int minLen = 39;//[69d98d6a04c41b4605aacb7bd2f74bee][01a] + + if (_param.length() < minLen + || _param.substr(0, tagLen) != extendTag) + return ret; + + int cmdLen = ::atoi(_param.substr(tagLen+1, 2).c_str()); + if (cmdLen <= 0) + { + return ret; + } + std::string cmd(_param.c_str()+tagLen+3, cmdLen); + if (cmd.length() != (unsigned)cmdLen) + { + return ret; + } + + _paramOff = tagLen+cmdLen+4; + ret = cmd; + std::transform(ret.begin(), ret.end(), ret.begin(), ::tolower); + + return ret; +} + +namespace +{ +static int paillier(std::string& d1, std::string& d2, std::string& result) +{ + S32 bytelen = 0; + U8 blen[4]; + CharToByte(d1.c_str(), 4, blen, &bytelen); + + U16 len = 0; + U16 nLen = 0; + memcpy((char *)&len, (char *)blen, sizeof(len)); + nLen = len; + len = (ntohs(len) + 2) * 2; + + if (memcmp(d1.c_str(), d1.c_str(), len) != 0) + { + return -1; + } + + std::string str_n = d1.substr(4, len - 4); + d1 = d1.substr(len); + d2 = d2.substr(len); + + U8 BN_C1[4*2*PaiBNWordLen]; + U8 BN_C2[4*2*PaiBNWordLen]; + U8 BN_N[4*PaiBNWordLen]; + U8 BN_Result[4*2*PaiBNWordLen]; + U8 BN_CryptResult[4*2*PaiBNWordLen + len]; + + CharToByte(d1.c_str(), 512, BN_C1, &bytelen); + CharToByte(d2.c_str(), 512, BN_C2, &bytelen); + CharToByte(str_n.c_str(), 256, BN_N, &bytelen); + + PAI_HomAdd(BN_Result, BN_C1, BN_C2, BN_N, PaiBNWordLen); + + memcpy((char *)BN_CryptResult, (char *)&nLen, sizeof(nLen)); + memcpy((char *)(BN_CryptResult + sizeof(nLen)), BN_N, sizeof(BN_N)); + memcpy((char *)(BN_CryptResult + sizeof(nLen) + sizeof(BN_N)), BN_Result, sizeof(BN_Result)); + + for (size_t i=0; i &pm_vecArray) +{ + size_t iPosBegin = 0; + size_t iPosEnd; + while ((iPosEnd = pm_sExpression.find(pm_cDelimiter, iPosBegin)) != string::npos) + { + if (iPosEnd>iPosBegin) + pm_vecArray.push_back(pm_sExpression.substr(iPosBegin, iPosEnd - iPosBegin)); + iPosBegin = iPosEnd + 1; + } + + pm_vecArray.push_back(pm_sExpression.substr(iPosBegin)); +} + +ETH_REGISTER_EXTEND(paillier)(std::string const& _param, char* _ptmem) +{ + uint32_t ret = 1; + std::vector vargs; + SplitString(_param, '|', vargs); + + if (vargs.size() < 3 || vargs[0].length() != vargs[1].length()) + { + return ret; + } + else + { + std::string result; + if (paillier(vargs[0], vargs[1], result) == 0) + { + ::memcpy(_ptmem + atoi(vargs[2].c_str()), result.c_str(), result.length()); + ret = 0; + } + } + + return ret; +} +} diff --git a/libevm/VMExtends.h b/libevm/VMExtends.h new file mode 100644 index 0000000000..79b487afdd --- /dev/null +++ b/libevm/VMExtends.h @@ -0,0 +1,43 @@ +/** @file VMExtends.h + * @author ximi + * @date 2017.05.24 + */ + +#pragma once + +#include +#include +#include + +namespace dev +{ +namespace eth +{ + +using ExtendExecutor = std::function; + +DEV_SIMPLE_EXCEPTION(ExtendExecutorNotFound); + +class ExtendRegistrar +{ +public: + /// Get the executor object for @a _name function or @throw ExtendExecutorNotFound if not found. + static ExtendExecutor const& executor(std::string const& _name); + static std::string parseExtend(std::string const& _param, int & _paramOff); + + /// Register an executor. In general just use ETH_REGISTER_EXTEND. + static ExtendExecutor registerExtend(std::string const& _name, ExtendExecutor const& _exec) { return (get()->m_execs[_name] = _exec); } + /// Unregister an executor. Shouldn't generally be necessary. + static void unregisterExtend(std::string const& _name) { get()->m_execs.erase(_name); } + +private: + static ExtendRegistrar* get() { if (!s_this) s_this = new ExtendRegistrar; return s_this; } + + std::unordered_map m_execs; + static ExtendRegistrar* s_this; +}; + +#define ETH_REGISTER_EXTEND(Name) static uint32_t __eth_registerExtendFunction ## Name(std::string const& _param, char* _ptmem); static ExtendExecutor __eth_registerExtendFactory ## Name = ::dev::eth::ExtendRegistrar::registerExtend(#Name, &__eth_registerExtendFunction ## Name); static uint32_t __eth_registerExtendFunction ## Name + +} +} diff --git a/libevm/VMFace.h b/libevm/VMFace.h new file mode 100644 index 0000000000..0f5d010b56 --- /dev/null +++ b/libevm/VMFace.h @@ -0,0 +1,65 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +#pragma once + +#include +#include +#include "ExtVMFace.h" + +namespace dev +{ +namespace eth +{ + +struct VMException: virtual Exception {}; +#define ETH_SIMPLE_EXCEPTION_VM(X) struct X: virtual VMException { const char* what() const noexcept override { return #X; } } +ETH_SIMPLE_EXCEPTION_VM(BreakPointHit); +ETH_SIMPLE_EXCEPTION_VM(BadInstruction); +ETH_SIMPLE_EXCEPTION_VM(BadJumpDestination); +ETH_SIMPLE_EXCEPTION_VM(OutOfGas); +ETH_SIMPLE_EXCEPTION_VM(OutOfStack); +ETH_SIMPLE_EXCEPTION_VM(StackUnderflow); + +/// EVM Virtual Machine interface +class VMFace +{ +public: + VMFace() = default; + virtual ~VMFace() = default; + VMFace(VMFace const&) = delete; + VMFace& operator=(VMFace const&) = delete; + + /// Execute EVM code by VM. + /// + /// @param _out Expected output + void exec(u256& io_gas, ExtVMFace& _ext, bytesRef _out, OnOpFunc const& _onOp = {}) + { + execImpl(io_gas, _ext, _onOp).copyTo(_out); + } + + /// The same as above but returns a copy of full output. + bytes exec(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp = {}) + { + return execImpl(io_gas, _ext, _onOp).toVector(); + } + + /// VM implementation + virtual bytesConstRef execImpl(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp) = 0; +}; + +} +} diff --git a/libevm/VMFactory.cpp b/libevm/VMFactory.cpp new file mode 100644 index 0000000000..0e078bfdef --- /dev/null +++ b/libevm/VMFactory.cpp @@ -0,0 +1,70 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ + +#include "VMFactory.h" +#include +#include "VM.h" + +#if ETH_EVMJIT +#include "JitVM.h" +#include "SmartVM.h" +#endif + +namespace dev +{ +namespace eth +{ +namespace +{ + auto g_kind = VMKind::Interpreter; +} + +void VMFactory::setKind(VMKind _kind) +{ + g_kind = _kind; +} +VMKind VMFactory::getKind() { + return g_kind; +} +std::unique_ptr VMFactory::create() +{ + return create(g_kind); +} + +std::unique_ptr VMFactory::create(VMKind _kind) +{ +#if ETH_EVMJIT + switch (_kind) + { + default: + case VMKind::Interpreter: + return std::unique_ptr(new VM); + case VMKind::JIT: + return std::unique_ptr(new JitVM); + case VMKind::Smart: + return std::unique_ptr(new SmartVM); + case VMKind::Dual: + return std::unique_ptr(new VM); + } +#else + asserts(_kind == VMKind::Interpreter && "JIT disabled in build configuration"); + return std::unique_ptr(new VM); +#endif +} + +} +} diff --git a/libevm/VMFactory.h b/libevm/VMFactory.h new file mode 100644 index 0000000000..1861db7258 --- /dev/null +++ b/libevm/VMFactory.h @@ -0,0 +1,52 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +#pragma once + +#include "VMFace.h" + +namespace dev +{ +namespace eth +{ + +enum class VMKind +{ + Interpreter, + JIT, + Smart, + Dual +}; + +class VMFactory +{ +public: + VMFactory() = delete; + + /// Creates a VM instance of global kind (controlled by setKind() function). + static std::unique_ptr create(); + + /// Creates a VM instance of kind provided. + static std::unique_ptr create(VMKind _kind); + + /// Set global VM kind + static void setKind(VMKind _kind); + + static VMKind getKind(); +}; + +} +} diff --git a/libevm/VMOpt.cpp b/libevm/VMOpt.cpp new file mode 100644 index 0000000000..d54266401f --- /dev/null +++ b/libevm/VMOpt.cpp @@ -0,0 +1,298 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ + + +#include +#include "VMConfig.h" +#include "VM.h" +using namespace std; +using namespace dev; +using namespace dev::eth; + +void VM::reportStackUse() +{ + static intptr_t p = 0; + intptr_t q = intptr_t(&q); + if (p) + LOG(ERROR) << "STACK: " << p << " - " << q << " = " << (p - q) << endl; + p = q; +} + +std::array VM::c_metrics; +void VM::initMetrics() +{ + static bool done=false; + if (!done) + { + for (unsigned i = 0; i < 256; ++i) + { + InstructionInfo op = instructionInfo((Instruction)i); + c_metrics[i].gasPriceTier = op.gasPriceTier; + c_metrics[i].args = op.args; + c_metrics[i].ret = op.ret; + } + } + done = true; +} + +void VM::copyCode(int _extraBytes) +{ + // Copy code so that it can be safely modified and extend code by + // _extraBytes zero bytes to allow reading virtual data at the end + // of the code without bounds checks. + auto extendedSize = m_ext->code.size() + _extraBytes; + m_codeSpace.reserve(extendedSize); + m_codeSpace = m_ext->code; + m_codeSpace.resize(extendedSize); + m_code = m_codeSpace.data(); +} + +void VM::optimize() +{ + copyCode(33); + + size_t const nBytes = m_ext->code.size(); + + // build a table of jump destinations for use in verifyJumpDest + + TRACE_STR(1, "Build JUMPDEST table") + for (size_t pc = 0; pc < nBytes; ++pc) + { + Instruction op = Instruction(m_code[pc]); + TRACE_OP(2, pc, op); + + // make synthetic ops in user code trigger invalid instruction if run + if ( + op == Instruction::PUSHC || + op == Instruction::JUMPC || + op == Instruction::JUMPCI + ) + { + TRACE_OP(1, pc, op); + m_code[pc] = (byte)Instruction::BAD; + } + + if (op == Instruction::JUMPDEST) + { + m_jumpDests.push_back(pc); + } + else if ( + (byte)Instruction::PUSH1 <= (byte)op && + (byte)op <= (byte)Instruction::PUSH32 + ) + { + pc += (byte)op - (byte)Instruction::PUSH1 + 1; + } +#if EVM_JUMPS_AND_SUBS + else if ( + op == Instruction::JUMPTO || + op == Instruction::JUMPIF || + op == Instruction::JUMPSUB) + { + ++pc; + pc += 4; + } + else if (op == Instruction::JUMPV || op == Instruction::JUMPSUBV) + { + ++pc; + pc += 4 * m_code[pc]; // number of 4-byte dests followed by table + } + else if (op == Instruction::BEGINSUB) + { + m_beginSubs.push_back(pc); + } + else if (op == Instruction::BEGINDATA) + { + break; + } +#endif + } + +#ifdef EVM_DO_FIRST_PASS_OPTIMIZATION + + #ifdef EVM_USE_CONSTANT_POOL + + // maintain constant pool as a hash table of up to 256 u256 constants + struct hash256 + { + // FNV chosen as good, fast, and byte-at-a-time + const uint32_t FNV_PRIME1 = 2166136261; + const uint32_t FNV_PRIME2 = 16777619; + uint32_t hash = FNV_PRIME1; + + u256 (&table)[256]; + bool empty[256]; + + hash256(u256 (&table)[256]) : table(table) + { + for (int i = 0; i < 256; ++i) + { + table[i] = 0; + empty[i] = true; + } + } + + void hashInit() { hash = FNV_PRIME1; } + + // hash in successive bytes + void hashByte(byte b) { hash ^= (b), hash *= FNV_PRIME2; } + + // fold hash into 1 byte + byte getHash() { return ((hash >> 8) ^ hash) & 0xff; } + + // insert value at byte index in table, false if collision + bool insertVal(byte hash, u256& val) + { + if (empty[hash]) + { + empty[hash] = false; + table[hash] = val; + return true; + } + return table[hash] == val; + } + } constantPool(m_pool); + #define CONST_POOL_HASH_INIT() constantPool.hashInit() + #define CONST_POOL_HASH_BYTE(b) constantPool.hashByte(b) + #define CONST_POOL_GET_HASH() constantPool.getHash() + #define CONST_POOL_INSERT_VAL(hash, val) constantPool.insertVal((hash), (val)) + #else + #define CONST_POOL_HASH_INIT() + #define CONST_POOL_HASH_BYTE(b) + #define CONST_POOL_GET_HASH() 0 + #define CONST_POOL_INSERT_VAL(hash, val) false + #endif + + TRACE_STR(1, "Do first pass optimizations") + for (size_t pc = 0; pc < nBytes; ++pc) + { + u256 val = 0; + Instruction op = Instruction(m_code[pc]); + + if ((byte)Instruction::PUSH1 <= (byte)op && (byte)op <= (byte)Instruction::PUSH32) + { + byte nPush = (byte)op - (byte)Instruction::PUSH1 + 1; + + + // decode pushed bytes to integral value + CONST_POOL_HASH_INIT(); + val = m_code[pc+1]; + for (uint64_t i = pc+2, n = nPush; --n; ++i) { + val = (val << 8) | m_code[i]; + CONST_POOL_HASH_BYTE(m_code[i]); + } + + #ifdef EVM_USE_CONSTANT_POOL + if (1 < nPush) + { + // try to put value in constant pool at hash index + // if there is no collision replace PUSHn with PUSHC + TRACE_PRE_OPT(1, pc, op); + byte hash = CONST_POOL_GET_HASH(); + if (CONST_POOL_INSERT_VAL(hash, val)) + { + m_code[pc] = (byte)Instruction::PUSHC; + m_code[pc+1] = hash; + m_code[pc+2] = nPush - 1; + TRACE_VAL(1, "constant pooled", val); + } + TRACE_POST_OPT(1, pc, op); + } + #endif + + #ifdef EVM_REPLACE_CONST_JUMP + // replace JUMP or JUMPI to constant location with JUMPC or JUMPCI + // verifyJumpDest is M = log(number of jump destinations) + // outer loop is N = number of bytes in code array + // so complexity is N log M, worst case is N log N + size_t i = pc + nPush + 1; + op = Instruction(m_code[i]); + if (op == Instruction::JUMP) + { + TRACE_STR(1, "Replace const JUMPC") + TRACE_PRE_OPT(1, i, op); + + if (0 <= verifyJumpDest(val, false)) + m_code[i] = byte(op = Instruction::JUMPC); + + TRACE_POST_OPT(1, i, op); + } + else if (op == Instruction::JUMPI) + { + TRACE_STR(1, "Replace const JUMPCI") + TRACE_PRE_OPT(1, i, op); + + if (0 <= verifyJumpDest(val, false)) + m_code[i] = byte(op = Instruction::JUMPCI); + + TRACE_POST_OPT(1, ii, op); + } + #endif + + pc += nPush; + } + + } + TRACE_STR(1, "Finished optimizations") +#endif +} + + +// +// Init interpreter on entry. +// +void VM::initEntry() +{ + m_bounce = &VM::interpretCases; + interpretCases(); // first call initializes jump table + initMetrics(); + optimize();//初始化跳表 + + #ifdef EVM_COVERTOOL + if( m_ext->envInfo().coverLog() ) + { + VM::covertool.outputpath(getDataDir("ethereum") + "/cover/");//设置输出目录 + + if( !VM::covertool.has(m_ext->myAddress) ) + { + covertool.init(m_ext->myAddress,m_codeSpace);//部署合约的时候就会进来 + } + } + #endif + +} + + +// Implementation of EXP. +// +// This implements exponentiation by squaring algorithm. +// Is faster than boost::multiprecision::powm() because it avoids explicit +// mod operation. +// Do not inline it. +u256 VM::exp256(u256 _base, u256 _exponent) +{ + using boost::multiprecision::limb_type; + u256 result = 1; + while (_exponent) + { + if (static_cast(_exponent) & 1) // If exponent is odd. + result *= _base; + _base *= _base; + _exponent >>= 1; + } + return result; +} diff --git a/libevm/VMValidate.cpp b/libevm/VMValidate.cpp new file mode 100644 index 0000000000..3c949318bd --- /dev/null +++ b/libevm/VMValidate.cpp @@ -0,0 +1,170 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file + */ + +#include +#include "VMConfig.h" +#include "VM.h" +using namespace std; +using namespace dev; +using namespace dev::eth; + +#if EVM_JUMPS_AND_SUBS + +/////////////////////////////////////////////////////////////////////////////// +// +// invalid code will throw an exception +// + +void VM::validate(ExtVMFace& _ext) +{ + m_ext = &_ext; + initEntry(); + size_t PC; + byte OP; + for (PC = 0; (OP = m_code[PC]); ++PC) + if (OP == byte(Instruction::BEGINSUB)) + validateSubroutine(PC, m_return, m_stack); + else if (OP == byte(Instruction::BEGINDATA)) + break; + else if ( + (byte)Instruction::PUSH1 <= (byte)OP && + (byte)PC <= (byte)Instruction::PUSH32) + PC += (byte)OP - (byte)Instruction::PUSH1; + else if ( + OP == Instruction::JUMPTO || + OP == Instruction::JUMPIF || + OP == Instruction::JUMPSUB) + PC += 4; + else if (OP == Instruction::JUMPV || op == Instruction::JUMPSUBV) + PC += 4 * m_code[PC]; // number of 4-byte dests followed by table + } +} + +// we validate each subroutine individually, as if at top level +// - PC is the offset in the code to start validating at +// - RP is the top PC on return stack that RETURNSUB returns to +// - SP = FP at the top level, so the stack size is also the frame size +void VM::validateSubroutine(uint64_t _PC, uint64_t* _RP, u256* _SP) +{ + // set current interpreter state + m_PC = _PC, m_RP = _RP, m_SP = _SP; + + INIT_CASES + DO_CASES + { + CASE(JUMPDEST) + { + // if frame size is set then we have been here before + ptrdiff_t frameSize = m_frameSize[m_PC]; + if (0 <= frameSize) + { + // check for constant frame size + if (stackSize() != frameSize) + throwBadStack(stackSize(), frameSize, 0); + + // return to break cycle in control flow graph + return; + } + // set frame size to check later + m_frameSize[m_PC] = stackSize(); + ++m_PC; + } + NEXT + + CASE(JUMPTO) + { + // extract jump destination from bytecode + m_PC = decodeJumpDest(m_code, m_PC); + } + NEXT + + CASE(JUMPIF) + { + // recurse to validate code to jump to, saving and restoring + // interpreter state around call + _PC = m_PC, _RP = m_RP, _SP = m_SP; + validateSubroutine(decodeJumpvDest(m_code, m_PC, m_SP), _RP, _SP); + m_PC = _PC, m_RP = _RP, m_SP = _SP; + ++m_PC; + } + NEXT + + CASE(JUMPV) + { + // for every jump destination in jump vector + for (size_t dest = 0, nDests = m_code[m_PC+1]; dest < nDests; ++dest) + { + // recurse to validate code to jump to, saving and + // restoring interpreter state around call + _PC = m_PC, _RP = m_RP, _SP = m_SP; + validateSubroutine(decodeJumpDest(m_code, m_PC), _RP, _SP); + m_PC = _PC, m_RP = _RP, m_SP = _SP; + } + } + RETURN + + CASE(JUMPSUB) + { + // check for enough arguments on stack + size_t destPC = decodeJumpDest(m_code, m_PC); + byte nArgs = m_code[destPC+1]; + if (stackSize() < nArgs) + throwBadStack(stackSize(), nArgs, 0); + } + NEXT + + CASE(JUMPSUBV) + { + // for every subroutine in jump vector + _PC = m_PC; + for (size_t sub = 0, nSubs = m_code[m_PC+1]; sub < nSubs; ++sub) + { + // check for enough arguments on stack + u256 slot = sub; + _SP = &slot; + size_t destPC = decodeJumpvDest(m_code, _PC, _SP); + byte nArgs = m_code[destPC+1]; + if (stackSize() < nArgs) + throwBadStack(stackSize(), nArgs, 0); + } + m_PC = _PC; + } + NEXT + + CASE(RETURNSUB) + CASE(RETURN) + CASE(SUICIDE) + CASE(STOP) + { + // return to top level + } + BREAK; + + CASE(BEGINSUB) + CASE(BEGINDATA) + CASE(BAD) + DEFAULT + { + throwBadInstruction(); + } + } + END_CASES +} + +#endif diff --git a/libevmcore/CMakeLists.txt b/libevmcore/CMakeLists.txt new file mode 100644 index 0000000000..f79107fd9a --- /dev/null +++ b/libevmcore/CMakeLists.txt @@ -0,0 +1,12 @@ +aux_source_directory(. SRC_LIST) + +file(GLOB HEADERS "*.h") + +add_library(evmcore ${SRC_LIST} ${HEADERS}) + +find_package(Boost QUIET REQUIRED) + +target_include_directories(evmcore PRIVATE ..) +target_include_directories(evmcore SYSTEM PUBLIC ${Boost_INCLUDE_DIRS}) + +install(TARGETS evmcore RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib) diff --git a/libevmcore/EVMSchedule.cpp b/libevmcore/EVMSchedule.cpp new file mode 100644 index 0000000000..d3f5a12faa --- /dev/null +++ b/libevmcore/EVMSchedule.cpp @@ -0,0 +1 @@ + diff --git a/libevmcore/EVMSchedule.h b/libevmcore/EVMSchedule.h new file mode 100644 index 0000000000..3d439bd484 --- /dev/null +++ b/libevmcore/EVMSchedule.h @@ -0,0 +1,109 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file EVMSchedule.h + * @author Gav + * @author Christian + * @date 2015 + */ + +#pragma once + +#include +#include + +namespace dev +{ +namespace eth +{ + +struct EVMSchedule +{ + EVMSchedule(): tierStepGas(std::array{{0, 2, 3, 5, 8, 10, 20, 0}}) {} + EVMSchedule(bool _efcd, bool _hdc, unsigned const& _txCreateGas): exceptionalFailedCodeDeposit(_efcd), haveDelegateCall(_hdc), tierStepGas(std::array{{0, 2, 3, 5, 8, 10, 20, 0}}), txCreateGas(_txCreateGas) {} + bool exceptionalFailedCodeDeposit = true; + bool haveDelegateCall = true; + bool eip150Mode = false; + bool eip158Mode = false; + unsigned stackLimit = 1024; + std::array tierStepGas; + unsigned expGas = 10; + unsigned expByteGas = 10; + unsigned sha3Gas = 30; + unsigned sha3WordGas = 6; + unsigned sloadGas = 50; + unsigned sstoreSetGas = 20000; + unsigned sstoreResetGas = 5000; + unsigned sstoreRefundGas = 15000; + unsigned jumpdestGas = 1; + unsigned logGas = 375; + unsigned logDataGas = 8; + unsigned logTopicGas = 375; + unsigned createGas = 32000; + unsigned callGas = 40; + unsigned callStipend = 2300; + unsigned callValueTransferGas = 9000; + unsigned callNewAccountGas = 25000; + unsigned suicideRefundGas = 24000; + unsigned memoryGas = 3; + unsigned quadCoeffDiv = 512; + unsigned createDataGas = 200; + unsigned txGas = 21000; + unsigned txCreateGas = 53000; + unsigned txDataZeroGas = 4; + unsigned txDataNonZeroGas = 68; + unsigned copyGas = 3; + + unsigned extcodesizeGas = 20; + unsigned extcodecopyGas = 20; + unsigned balanceGas = 20; + unsigned suicideGas = 0; + unsigned maxCodeSize = unsigned(-1); + + bool staticCallDepthLimit() const { return !eip150Mode; } + bool suicideChargesNewAccountGas() const { return eip150Mode; } + bool emptinessIsNonexistence() const { return eip158Mode; } + bool zeroValueTransferChargesNewAccountGas() const { return !eip158Mode; } +}; + +static const EVMSchedule DefaultSchedule = EVMSchedule(); +static const EVMSchedule FrontierSchedule = EVMSchedule(false, false, 21000); +static const EVMSchedule HomesteadSchedule = EVMSchedule(true, true, 53000); + +static const EVMSchedule EIP150Schedule = [] +{ + EVMSchedule schedule = HomesteadSchedule; + schedule.eip150Mode = true; + schedule.extcodesizeGas = 700; + schedule.extcodecopyGas = 700; + schedule.balanceGas = 400; + schedule.sloadGas = 200; + schedule.callGas = 700; + schedule.suicideGas = 5000; + schedule.maxCodeSize = 0x6000; + return schedule; +}(); + +static const EVMSchedule EIP158Schedule = [] +{ + EVMSchedule schedule = EIP150Schedule; + schedule.expByteGas = 50; + schedule.eip158Mode = true; + return schedule; +}(); + +} +} diff --git a/libevmcore/Exceptions.h b/libevmcore/Exceptions.h new file mode 100644 index 0000000000..a7fe7a56d1 --- /dev/null +++ b/libevmcore/Exceptions.h @@ -0,0 +1,35 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Exceptions.h + * @author Christian + * @date 2014 + */ + +#pragma once + +#include + +namespace dev +{ +namespace eth +{ + +DEV_SIMPLE_EXCEPTION(InvalidDeposit); +DEV_SIMPLE_EXCEPTION(InvalidOpcode); + +} +} diff --git a/libevmcore/Instruction.cpp b/libevmcore/Instruction.cpp new file mode 100644 index 0000000000..d8eda97d1c --- /dev/null +++ b/libevmcore/Instruction.cpp @@ -0,0 +1,378 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Instruction.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "Instruction.h" + +#include +#include +#include + +using namespace std; +using namespace dev; +using namespace dev::eth; + +const std::map dev::eth::c_instructions = +{ + { "STOP", Instruction::STOP }, + { "ADD", Instruction::ADD }, + { "SUB", Instruction::SUB }, + { "MUL", Instruction::MUL }, + { "DIV", Instruction::DIV }, + { "SDIV", Instruction::SDIV }, + { "MOD", Instruction::MOD }, + { "SMOD", Instruction::SMOD }, + { "EXP", Instruction::EXP }, + { "BNOT", Instruction::NOT }, + { "LT", Instruction::LT }, + { "GT", Instruction::GT }, + { "SLT", Instruction::SLT }, + { "SGT", Instruction::SGT }, + { "EQ", Instruction::EQ }, + { "NOT", Instruction::ISZERO }, + { "AND", Instruction::AND }, + { "OR", Instruction::OR }, + { "XOR", Instruction::XOR }, + { "BYTE", Instruction::BYTE }, + { "ADDMOD", Instruction::ADDMOD }, + { "MULMOD", Instruction::MULMOD }, + { "SIGNEXTEND", Instruction::SIGNEXTEND }, + { "SHA3", Instruction::SHA3 }, + { "ADDRESS", Instruction::ADDRESS }, + { "BALANCE", Instruction::BALANCE }, + { "ORIGIN", Instruction::ORIGIN }, + { "CALLER", Instruction::CALLER }, + { "CALLVALUE", Instruction::CALLVALUE }, + { "CALLDATALOAD", Instruction::CALLDATALOAD }, + { "CALLDATASIZE", Instruction::CALLDATASIZE }, + { "CALLDATACOPY", Instruction::CALLDATACOPY }, + { "CODESIZE", Instruction::CODESIZE }, + { "CODECOPY", Instruction::CODECOPY }, + { "GASPRICE", Instruction::GASPRICE }, + { "EXTCODESIZE", Instruction::EXTCODESIZE }, + { "EXTCODECOPY", Instruction::EXTCODECOPY }, + { "BLOCKHASH", Instruction::BLOCKHASH }, + { "COINBASE", Instruction::COINBASE }, + { "TIMESTAMP", Instruction::TIMESTAMP }, + { "NUMBER", Instruction::NUMBER }, + { "DIFFICULTY", Instruction::DIFFICULTY }, + { "GASLIMIT", Instruction::GASLIMIT }, + { "JUMPTO", Instruction::JUMPTO }, + { "JUMPIF", Instruction::JUMPTO }, + { "JUMPSUB", Instruction::JUMPSUB }, + { "JUMPV", Instruction::JUMPV }, + { "JUMPSUBV", Instruction::JUMPSUBV }, + { "RETURNSUB", Instruction::RETURNSUB }, + { "POP", Instruction::POP }, + { "MLOAD", Instruction::MLOAD }, + { "MSTORE", Instruction::MSTORE }, + { "MSTORE8", Instruction::MSTORE8 }, + { "SLOAD", Instruction::SLOAD }, + { "SSTORE", Instruction::SSTORE }, + { "JUMP", Instruction::JUMP }, + { "JUMPI", Instruction::JUMPI }, + { "PC", Instruction::PC }, + { "MSIZE", Instruction::MSIZE }, + { "GAS", Instruction::GAS }, + { "BEGIN", Instruction::JUMPDEST }, + { "JUMPDEST", Instruction::JUMPDEST }, + { "BEGINDATA", Instruction::BEGINDATA }, + { "BEGINSUB", Instruction::BEGINSUB }, + { "PUSH1", Instruction::PUSH1 }, + { "PUSH2", Instruction::PUSH2 }, + { "PUSH3", Instruction::PUSH3 }, + { "PUSH4", Instruction::PUSH4 }, + { "PUSH5", Instruction::PUSH5 }, + { "PUSH6", Instruction::PUSH6 }, + { "PUSH7", Instruction::PUSH7 }, + { "PUSH8", Instruction::PUSH8 }, + { "PUSH9", Instruction::PUSH9 }, + { "PUSH10", Instruction::PUSH10 }, + { "PUSH11", Instruction::PUSH11 }, + { "PUSH12", Instruction::PUSH12 }, + { "PUSH13", Instruction::PUSH13 }, + { "PUSH14", Instruction::PUSH14 }, + { "PUSH15", Instruction::PUSH15 }, + { "PUSH16", Instruction::PUSH16 }, + { "PUSH17", Instruction::PUSH17 }, + { "PUSH18", Instruction::PUSH18 }, + { "PUSH19", Instruction::PUSH19 }, + { "PUSH20", Instruction::PUSH20 }, + { "PUSH21", Instruction::PUSH21 }, + { "PUSH22", Instruction::PUSH22 }, + { "PUSH23", Instruction::PUSH23 }, + { "PUSH24", Instruction::PUSH24 }, + { "PUSH25", Instruction::PUSH25 }, + { "PUSH26", Instruction::PUSH26 }, + { "PUSH27", Instruction::PUSH27 }, + { "PUSH28", Instruction::PUSH28 }, + { "PUSH29", Instruction::PUSH29 }, + { "PUSH30", Instruction::PUSH30 }, + { "PUSH31", Instruction::PUSH31 }, + { "PUSH32", Instruction::PUSH32 }, + { "DUP1", Instruction::DUP1 }, + { "DUP2", Instruction::DUP2 }, + { "DUP3", Instruction::DUP3 }, + { "DUP4", Instruction::DUP4 }, + { "DUP5", Instruction::DUP5 }, + { "DUP6", Instruction::DUP6 }, + { "DUP7", Instruction::DUP7 }, + { "DUP8", Instruction::DUP8 }, + { "DUP9", Instruction::DUP9 }, + { "DUP10", Instruction::DUP10 }, + { "DUP11", Instruction::DUP11 }, + { "DUP12", Instruction::DUP12 }, + { "DUP13", Instruction::DUP13 }, + { "DUP14", Instruction::DUP14 }, + { "DUP15", Instruction::DUP15 }, + { "DUP16", Instruction::DUP16 }, + { "SWAP1", Instruction::SWAP1 }, + { "SWAP2", Instruction::SWAP2 }, + { "SWAP3", Instruction::SWAP3 }, + { "SWAP4", Instruction::SWAP4 }, + { "SWAP5", Instruction::SWAP5 }, + { "SWAP6", Instruction::SWAP6 }, + { "SWAP7", Instruction::SWAP7 }, + { "SWAP8", Instruction::SWAP8 }, + { "SWAP9", Instruction::SWAP9 }, + { "SWAP10", Instruction::SWAP10 }, + { "SWAP11", Instruction::SWAP11 }, + { "SWAP12", Instruction::SWAP12 }, + { "SWAP13", Instruction::SWAP13 }, + { "SWAP14", Instruction::SWAP14 }, + { "SWAP15", Instruction::SWAP15 }, + { "SWAP16", Instruction::SWAP16 }, + { "LOG0", Instruction::LOG0 }, + { "LOG1", Instruction::LOG1 }, + { "LOG2", Instruction::LOG2 }, + { "LOG3", Instruction::LOG3 }, + { "LOG4", Instruction::LOG4 }, + { "CREATE", Instruction::CREATE }, + { "CALL", Instruction::CALL }, + { "CALLCODE", Instruction::CALLCODE }, + { "RETURN", Instruction::RETURN }, + { "DELEGATECALL", Instruction::DELEGATECALL }, + { "SUICIDE", Instruction::SUICIDE }, + + // these are generated by the interpreter - should never be in user code + { "PUSHC", Instruction::PUSHC }, + { "JUMPC", Instruction::JUMPC }, + { "JUMPCI", Instruction::JUMPCI } +}; + +static const std::map c_instructionInfo = +{ // Add, Args, Ret, SideEffects, GasPriceTier + { Instruction::STOP, { "STOP", 0, 0, 0, true, Tier::Zero } }, + { Instruction::ADD, { "ADD", 0, 2, 1, false, Tier::VeryLow } }, + { Instruction::SUB, { "SUB", 0, 2, 1, false, Tier::VeryLow } }, + { Instruction::MUL, { "MUL", 0, 2, 1, false, Tier::Low } }, + { Instruction::DIV, { "DIV", 0, 2, 1, false, Tier::Low } }, + { Instruction::SDIV, { "SDIV", 0, 2, 1, false, Tier::Low } }, + { Instruction::MOD, { "MOD", 0, 2, 1, false, Tier::Low } }, + { Instruction::SMOD, { "SMOD", 0, 2, 1, false, Tier::Low } }, + { Instruction::EXP, { "EXP", 0, 2, 1, false, Tier::Special } }, + { Instruction::NOT, { "NOT", 0, 1, 1, false, Tier::VeryLow } }, + { Instruction::LT, { "LT", 0, 2, 1, false, Tier::VeryLow } }, + { Instruction::GT, { "GT", 0, 2, 1, false, Tier::VeryLow } }, + { Instruction::SLT, { "SLT", 0, 2, 1, false, Tier::VeryLow } }, + { Instruction::SGT, { "SGT", 0, 2, 1, false, Tier::VeryLow } }, + { Instruction::EQ, { "EQ", 0, 2, 1, false, Tier::VeryLow } }, + { Instruction::ISZERO, { "ISZERO", 0, 1, 1, false, Tier::VeryLow } }, + { Instruction::AND, { "AND", 0, 2, 1, false, Tier::VeryLow } }, + { Instruction::OR, { "OR", 0, 2, 1, false, Tier::VeryLow } }, + { Instruction::XOR, { "XOR", 0, 2, 1, false, Tier::VeryLow } }, + { Instruction::BYTE, { "BYTE", 0, 2, 1, false, Tier::VeryLow } }, + { Instruction::ADDMOD, { "ADDMOD", 0, 3, 1, false, Tier::Mid } }, + { Instruction::MULMOD, { "MULMOD", 0, 3, 1, false, Tier::Mid } }, + { Instruction::SIGNEXTEND, { "SIGNEXTEND", 0, 2, 1, false, Tier::Low } }, + { Instruction::SHA3, { "SHA3", 0, 2, 1, false, Tier::Special } }, + { Instruction::ADDRESS, { "ADDRESS", 0, 0, 1, false, Tier::Base } }, + { Instruction::BALANCE, { "BALANCE", 0, 1, 1, false, Tier::Special } }, + { Instruction::ORIGIN, { "ORIGIN", 0, 0, 1, false, Tier::Base } }, + { Instruction::CALLER, { "CALLER", 0, 0, 1, false, Tier::Base } }, + { Instruction::CALLVALUE, { "CALLVALUE", 0, 0, 1, false, Tier::Base } }, + { Instruction::CALLDATALOAD, { "CALLDATALOAD", 0, 1, 1, false, Tier::VeryLow } }, + { Instruction::CALLDATASIZE, { "CALLDATASIZE", 0, 0, 1, false, Tier::Base } }, + { Instruction::CALLDATACOPY, { "CALLDATACOPY", 0, 3, 0, true, Tier::VeryLow } }, + { Instruction::CODESIZE, { "CODESIZE", 0, 0, 1, false, Tier::Base } }, + { Instruction::CODECOPY, { "CODECOPY", 0, 3, 0, true, Tier::VeryLow } }, + { Instruction::GASPRICE, { "GASPRICE", 0, 0, 1, false, Tier::Base } }, + { Instruction::EXTCODESIZE, { "EXTCODESIZE", 0, 1, 1, false, Tier::Special } }, + { Instruction::EXTCODECOPY, { "EXTCODECOPY", 0, 4, 0, true, Tier::Special } }, + { Instruction::BLOCKHASH, { "BLOCKHASH", 0, 1, 1, false, Tier::Ext } }, + { Instruction::COINBASE, { "COINBASE", 0, 0, 1, false, Tier::Base } }, + { Instruction::TIMESTAMP, { "TIMESTAMP", 0, 0, 1, false, Tier::Base } }, + { Instruction::NUMBER, { "NUMBER", 0, 0, 1, false, Tier::Base } }, + { Instruction::DIFFICULTY, { "DIFFICULTY", 0, 0, 1, false, Tier::Base } }, + { Instruction::GASLIMIT, { "GASLIMIT", 0, 0, 1, false, Tier::Base } }, + { Instruction::JUMPTO, { "JUMPTO", 4, 1, 0, true, Tier::VeryLow } }, + { Instruction::JUMPIF, { "JUMPIF", 4, 2, 0, true, Tier::Low } }, + { Instruction::JUMPV, { "JUMPV", 4, 1, 0, true, Tier::Mid } }, + { Instruction::JUMPSUB, { "JUMPSUB", 4, 1, 0, true, Tier::Low } }, + { Instruction::JUMPSUBV, { "JUMPSUBV", 4, 1, 0, true, Tier::Mid } }, + { Instruction::RETURNSUB, { "RETURNSUB", 0, 1, 0, true, Tier::Mid } }, + { Instruction::POP, { "POP", 0, 1, 0, false, Tier::Base } }, + { Instruction::MLOAD, { "MLOAD", 0, 1, 1, false, Tier::VeryLow } }, + { Instruction::MSTORE, { "MSTORE", 0, 2, 0, true, Tier::VeryLow } }, + { Instruction::MSTORE8, { "MSTORE8", 0, 2, 0, true, Tier::VeryLow } }, + { Instruction::SLOAD, { "SLOAD", 0, 1, 1, false, Tier::Special } }, + { Instruction::SSTORE, { "SSTORE", 0, 2, 0, true, Tier::Special } }, + { Instruction::JUMP, { "JUMP", 0, 1, 0, true, Tier::Mid } }, + { Instruction::JUMPI, { "JUMPI", 0, 2, 0, true, Tier::High } }, + { Instruction::PC, { "PC", 0, 0, 1, false, Tier::Base } }, + { Instruction::MSIZE, { "MSIZE", 0, 0, 1, false, Tier::Base } }, + { Instruction::GAS, { "GAS", 0, 0, 1, false, Tier::Base } }, + { Instruction::JUMPDEST, { "JUMPDEST", 0, 0, 0, true, Tier::Special } }, + { Instruction::BEGINDATA, { "BEGINDATA", 0, 0, 0, true, Tier::Special } }, + { Instruction::BEGINSUB, { "BEGINSUB", 0, 0, 0, true, Tier::Special } }, + { Instruction::PUSH1, { "PUSH1", 1, 0, 1, false, Tier::VeryLow } }, + { Instruction::PUSH2, { "PUSH2", 2, 0, 1, false, Tier::VeryLow } }, + { Instruction::PUSH3, { "PUSH3", 3, 0, 1, false, Tier::VeryLow } }, + { Instruction::PUSH4, { "PUSH4", 4, 0, 1, false, Tier::VeryLow } }, + { Instruction::PUSH5, { "PUSH5", 5, 0, 1, false, Tier::VeryLow } }, + { Instruction::PUSH6, { "PUSH6", 6, 0, 1, false, Tier::VeryLow } }, + { Instruction::PUSH7, { "PUSH7", 7, 0, 1, false, Tier::VeryLow } }, + { Instruction::PUSH8, { "PUSH8", 8, 0, 1, false, Tier::VeryLow } }, + { Instruction::PUSH9, { "PUSH9", 9, 0, 1, false, Tier::VeryLow } }, + { Instruction::PUSH10, { "PUSH10", 10, 0, 1, false, Tier::VeryLow } }, + { Instruction::PUSH11, { "PUSH11", 11, 0, 1, false, Tier::VeryLow } }, + { Instruction::PUSH12, { "PUSH12", 12, 0, 1, false, Tier::VeryLow } }, + { Instruction::PUSH13, { "PUSH13", 13, 0, 1, false, Tier::VeryLow } }, + { Instruction::PUSH14, { "PUSH14", 14, 0, 1, false, Tier::VeryLow } }, + { Instruction::PUSH15, { "PUSH15", 15, 0, 1, false, Tier::VeryLow } }, + { Instruction::PUSH16, { "PUSH16", 16, 0, 1, false, Tier::VeryLow } }, + { Instruction::PUSH17, { "PUSH17", 17, 0, 1, false, Tier::VeryLow } }, + { Instruction::PUSH18, { "PUSH18", 18, 0, 1, false, Tier::VeryLow } }, + { Instruction::PUSH19, { "PUSH19", 19, 0, 1, false, Tier::VeryLow } }, + { Instruction::PUSH20, { "PUSH20", 20, 0, 1, false, Tier::VeryLow } }, + { Instruction::PUSH21, { "PUSH21", 21, 0, 1, false, Tier::VeryLow } }, + { Instruction::PUSH22, { "PUSH22", 22, 0, 1, false, Tier::VeryLow } }, + { Instruction::PUSH23, { "PUSH23", 23, 0, 1, false, Tier::VeryLow } }, + { Instruction::PUSH24, { "PUSH24", 24, 0, 1, false, Tier::VeryLow } }, + { Instruction::PUSH25, { "PUSH25", 25, 0, 1, false, Tier::VeryLow } }, + { Instruction::PUSH26, { "PUSH26", 26, 0, 1, false, Tier::VeryLow } }, + { Instruction::PUSH27, { "PUSH27", 27, 0, 1, false, Tier::VeryLow } }, + { Instruction::PUSH28, { "PUSH28", 28, 0, 1, false, Tier::VeryLow } }, + { Instruction::PUSH29, { "PUSH29", 29, 0, 1, false, Tier::VeryLow } }, + { Instruction::PUSH30, { "PUSH30", 30, 0, 1, false, Tier::VeryLow } }, + { Instruction::PUSH31, { "PUSH31", 31, 0, 1, false, Tier::VeryLow } }, + { Instruction::PUSH32, { "PUSH32", 32, 0, 1, false, Tier::VeryLow } }, + { Instruction::DUP1, { "DUP1", 0, 1, 2, false, Tier::VeryLow } }, + { Instruction::DUP2, { "DUP2", 0, 2, 3, false, Tier::VeryLow } }, + { Instruction::DUP3, { "DUP3", 0, 3, 4, false, Tier::VeryLow } }, + { Instruction::DUP4, { "DUP4", 0, 4, 5, false, Tier::VeryLow } }, + { Instruction::DUP5, { "DUP5", 0, 5, 6, false, Tier::VeryLow } }, + { Instruction::DUP6, { "DUP6", 0, 6, 7, false, Tier::VeryLow } }, + { Instruction::DUP7, { "DUP7", 0, 7, 8, false, Tier::VeryLow } }, + { Instruction::DUP8, { "DUP8", 0, 8, 9, false, Tier::VeryLow } }, + { Instruction::DUP9, { "DUP9", 0, 9, 10, false, Tier::VeryLow } }, + { Instruction::DUP10, { "DUP10", 0, 10, 11, false, Tier::VeryLow } }, + { Instruction::DUP11, { "DUP11", 0, 11, 12, false, Tier::VeryLow } }, + { Instruction::DUP12, { "DUP12", 0, 12, 13, false, Tier::VeryLow } }, + { Instruction::DUP13, { "DUP13", 0, 13, 14, false, Tier::VeryLow } }, + { Instruction::DUP14, { "DUP14", 0, 14, 15, false, Tier::VeryLow } }, + { Instruction::DUP15, { "DUP15", 0, 15, 16, false, Tier::VeryLow } }, + { Instruction::DUP16, { "DUP16", 0, 16, 17, false, Tier::VeryLow } }, + { Instruction::SWAP1, { "SWAP1", 0, 2, 2, false, Tier::VeryLow } }, + { Instruction::SWAP2, { "SWAP2", 0, 3, 3, false, Tier::VeryLow } }, + { Instruction::SWAP3, { "SWAP3", 0, 4, 4, false, Tier::VeryLow } }, + { Instruction::SWAP4, { "SWAP4", 0, 5, 5, false, Tier::VeryLow } }, + { Instruction::SWAP5, { "SWAP5", 0, 6, 6, false, Tier::VeryLow } }, + { Instruction::SWAP6, { "SWAP6", 0, 7, 7, false, Tier::VeryLow } }, + { Instruction::SWAP7, { "SWAP7", 0, 8, 8, false, Tier::VeryLow } }, + { Instruction::SWAP8, { "SWAP8", 0, 9, 9, false, Tier::VeryLow } }, + { Instruction::SWAP9, { "SWAP9", 0, 10, 10, false, Tier::VeryLow } }, + { Instruction::SWAP10, { "SWAP10", 0, 11, 11, false, Tier::VeryLow } }, + { Instruction::SWAP11, { "SWAP11", 0, 12, 12, false, Tier::VeryLow } }, + { Instruction::SWAP12, { "SWAP12", 0, 13, 13, false, Tier::VeryLow } }, + { Instruction::SWAP13, { "SWAP13", 0, 14, 14, false, Tier::VeryLow } }, + { Instruction::SWAP14, { "SWAP14", 0, 15, 15, false, Tier::VeryLow } }, + { Instruction::SWAP15, { "SWAP15", 0, 16, 16, false, Tier::VeryLow } }, + { Instruction::SWAP16, { "SWAP16", 0, 17, 17, false, Tier::VeryLow } }, + { Instruction::LOG0, { "LOG0", 0, 2, 0, true, Tier::Special } }, + { Instruction::LOG1, { "LOG1", 0, 3, 0, true, Tier::Special } }, + { Instruction::LOG2, { "LOG2", 0, 4, 0, true, Tier::Special } }, + { Instruction::LOG3, { "LOG3", 0, 5, 0, true, Tier::Special } }, + { Instruction::LOG4, { "LOG4", 0, 6, 0, true, Tier::Special } }, + { Instruction::CREATE, { "CREATE", 0, 3, 1, true, Tier::Special } }, + { Instruction::CALL, { "CALL", 0, 7, 1, true, Tier::Special } }, + { Instruction::CALLCODE, { "CALLCODE", 0, 7, 1, true, Tier::Special } }, + { Instruction::RETURN, { "RETURN", 0, 2, 0, true, Tier::Zero } }, + { Instruction::DELEGATECALL,{ "DELEGATECALL", 0, 6, 1, true, Tier::Special } }, + { Instruction::SUICIDE, { "SUICIDE", 0, 1, 0, true, Tier::Special } }, + + // these are generated by the interpreter - should never be in user code + { Instruction::PUSHC, { "PUSHC", 2, 0 , 1, false, Tier::VeryLow } }, + { Instruction::JUMPC, { "JUMPC", 0, 1, 0, true, Tier::Mid } }, + { Instruction::JUMPCI, { "JUMPCI", 0, 1, 0, true, Tier::High } }, + { Instruction::STOP, { "BAD", 0, 0, 0, true, Tier::Zero } }, +}; + +void dev::eth::eachInstruction( + bytes const& _mem, + function const& _onInstruction +) +{ + for (auto it = _mem.begin(); it < _mem.end(); ++it) + { + Instruction instr = Instruction(*it); + size_t additional = 0; + if (isValidInstruction(instr)) + additional = instructionInfo(instr).additional; + u256 data; + for (size_t i = 0; i < additional; ++i) + { + data <<= 8; + if (++it < _mem.end()) + data |= *it; + } + _onInstruction(instr, data); + } +} + +string dev::eth::disassemble(bytes const& _mem) +{ + stringstream ret; + eachInstruction(_mem, [&](Instruction _instr, u256 const& _data) { + if (!isValidInstruction(_instr)) + ret << "0x" << hex << int(_instr) << " "; + else + { + InstructionInfo info = instructionInfo(_instr); + ret << info.name << " "; + if (info.additional) + ret << "0x" << hex << _data << " "; + } + }); + return ret.str(); +} + +InstructionInfo dev::eth::instructionInfo(Instruction _inst) +{ + auto it = c_instructionInfo.find(_inst); + if (it != c_instructionInfo.end()) + return it->second; + return InstructionInfo({{}, 0, 0, 0, false, Tier::Invalid}); +} + +bool dev::eth::isValidInstruction(Instruction _inst) +{ + return !!c_instructionInfo.count(_inst); +} diff --git a/libevmcore/Instruction.h b/libevmcore/Instruction.h new file mode 100644 index 0000000000..2cc9770142 --- /dev/null +++ b/libevmcore/Instruction.h @@ -0,0 +1,281 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Instruction.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include +#include +#include "Exceptions.h" + +namespace dev +{ +namespace eth +{ + +/// Virtual machine bytecode instruction. +enum class Instruction: uint8_t +{ + STOP = 0x00, ///< halts execution + ADD, ///< addition operation + MUL, ///< mulitplication operation + SUB, ///< subtraction operation + DIV, ///< integer division operation + SDIV, ///< signed integer division operation + MOD, ///< modulo remainder operation + SMOD, ///< signed modulo remainder operation + ADDMOD, ///< unsigned modular addition + MULMOD, ///< unsigned modular multiplication + EXP, ///< exponential operation + SIGNEXTEND, ///< extend length of signed integer + + LT = 0x10, ///< less-than comparision + GT, ///< greater-than comparision + SLT, ///< signed less-than comparision + SGT, ///< signed greater-than comparision + EQ, ///< equality comparision + ISZERO, ///< simple not operator + AND, ///< bitwise AND operation + OR, ///< bitwise OR operation + XOR, ///< bitwise XOR operation + NOT, ///< bitwise NOT opertation + BYTE, ///< retrieve single byte from word + + SHA3 = 0x20, ///< compute SHA3-256 hash + + ADDRESS = 0x30, ///< get address of currently executing account + BALANCE, ///< get balance of the given account + ORIGIN, ///< get execution origination address + CALLER, ///< get caller address + CALLVALUE, ///< get deposited value by the instruction/transaction responsible for this execution + CALLDATALOAD, ///< get input data of current environment + CALLDATASIZE, ///< get size of input data in current environment + CALLDATACOPY, ///< copy input data in current environment to memory + CODESIZE, ///< get size of code running in current environment + CODECOPY, ///< copy code running in current environment to memory + GASPRICE, ///< get price of gas in current environment + EXTCODESIZE, ///< get external code size (from another contract) + EXTCODECOPY, ///< copy external code (from another contract) + + BLOCKHASH = 0x40, ///< get hash of most recent complete block + COINBASE, ///< get the block's coinbase address + TIMESTAMP, ///< get the block's timestamp + NUMBER, ///< get the block's number + DIFFICULTY, ///< get the block's difficulty + GASLIMIT, ///< get the block's gas limit + + JUMPTO = 0x4a, ///< alter the program counter to a jumpdest + JUMPIF, ///< conditionally alter the program counter + JUMPV, ///< alter the program counter to a jumpdest + JUMPSUB, ///< alter the program counter to a beginsub + JUMPSUBV, ///< alter the program counter to a beginsub + RETURNSUB, ///< return to subroutine jumped from + + POP = 0x50, ///< remove item from stack + MLOAD, ///< load word from memory + MSTORE, ///< save word to memory + MSTORE8, ///< save byte to memory + SLOAD, ///< load word from storage + SSTORE, ///< save word to storage + JUMP, ///< alter the program counter to a jumpdest + JUMPI, ///< conditionally alter the program counter + PC, ///< get the program counter + MSIZE, ///< get the size of active memory + GAS, ///< get the amount of available gas + JUMPDEST, ///< set a potential jump destination + BEGINSUB, ///< set a potential jumpsub destination + BEGINDATA, ///< begine the data section + + PUSH1 = 0x60, ///< place 1 byte item on stack + PUSH2, ///< place 2 byte item on stack + PUSH3, ///< place 3 byte item on stack + PUSH4, ///< place 4 byte item on stack + PUSH5, ///< place 5 byte item on stack + PUSH6, ///< place 6 byte item on stack + PUSH7, ///< place 7 byte item on stack + PUSH8, ///< place 8 byte item on stack + PUSH9, ///< place 9 byte item on stack + PUSH10, ///< place 10 byte item on stack + PUSH11, ///< place 11 byte item on stack + PUSH12, ///< place 12 byte item on stack + PUSH13, ///< place 13 byte item on stack + PUSH14, ///< place 14 byte item on stack + PUSH15, ///< place 15 byte item on stack + PUSH16, ///< place 16 byte item on stack + PUSH17, ///< place 17 byte item on stack + PUSH18, ///< place 18 byte item on stack + PUSH19, ///< place 19 byte item on stack + PUSH20, ///< place 20 byte item on stack + PUSH21, ///< place 21 byte item on stack + PUSH22, ///< place 22 byte item on stack + PUSH23, ///< place 23 byte item on stack + PUSH24, ///< place 24 byte item on stack + PUSH25, ///< place 25 byte item on stack + PUSH26, ///< place 26 byte item on stack + PUSH27, ///< place 27 byte item on stack + PUSH28, ///< place 28 byte item on stack + PUSH29, ///< place 29 byte item on stack + PUSH30, ///< place 30 byte item on stack + PUSH31, ///< place 31 byte item on stack + PUSH32, ///< place 32 byte item on stack + + DUP1 = 0x80, ///< copies the highest item in the stack to the top of the stack + DUP2, ///< copies the second highest item in the stack to the top of the stack + DUP3, ///< copies the third highest item in the stack to the top of the stack + DUP4, ///< copies the 4th highest item in the stack to the top of the stack + DUP5, ///< copies the 5th highest item in the stack to the top of the stack + DUP6, ///< copies the 6th highest item in the stack to the top of the stack + DUP7, ///< copies the 7th highest item in the stack to the top of the stack + DUP8, ///< copies the 8th highest item in the stack to the top of the stack + DUP9, ///< copies the 9th highest item in the stack to the top of the stack + DUP10, ///< copies the 10th highest item in the stack to the top of the stack + DUP11, ///< copies the 11th highest item in the stack to the top of the stack + DUP12, ///< copies the 12th highest item in the stack to the top of the stack + DUP13, ///< copies the 13th highest item in the stack to the top of the stack + DUP14, ///< copies the 14th highest item in the stack to the top of the stack + DUP15, ///< copies the 15th highest item in the stack to the top of the stack + DUP16, ///< copies the 16th highest item in the stack to the top of the stack + + SWAP1 = 0x90, ///< swaps the highest and second highest value on the stack + SWAP2, ///< swaps the highest and third highest value on the stack + SWAP3, ///< swaps the highest and 4th highest value on the stack + SWAP4, ///< swaps the highest and 5th highest value on the stack + SWAP5, ///< swaps the highest and 6th highest value on the stack + SWAP6, ///< swaps the highest and 7th highest value on the stack + SWAP7, ///< swaps the highest and 8th highest value on the stack + SWAP8, ///< swaps the highest and 9th highest value on the stack + SWAP9, ///< swaps the highest and 10th highest value on the stack + SWAP10, ///< swaps the highest and 11th highest value on the stack + SWAP11, ///< swaps the highest and 12th highest value on the stack + SWAP12, ///< swaps the highest and 13th highest value on the stack + SWAP13, ///< swaps the highest and 14th highest value on the stack + SWAP14, ///< swaps the highest and 15th highest value on the stack + SWAP15, ///< swaps the highest and 16th highest value on the stack + SWAP16, ///< swaps the highest and 17th highest value on the stack + + LOG0 = 0xa0, ///< Makes a log entry; no topics. + LOG1, ///< Makes a log entry; 1 topic. + LOG2, ///< Makes a log entry; 2 topics. + LOG3, ///< Makes a log entry; 3 topics. + LOG4, ///< Makes a log entry; 4 topics. + + // these are generated by the interpreter - should never be in user code + PUSHC = 0xac, ///< push value from constant pool + JUMPC, ///< alter the program counter - pre-verified + JUMPCI, ///< conditionally alter the program counter - pre-verified + BAD, ///< placed to force invalid instruction exception + + CREATE = 0xf0, ///< create a new account with associated code + CALL, ///< message-call into an account + CALLCODE, ///< message-call with another account's code only + RETURN, ///< halt execution returning output data + DELEGATECALL, ///< like CALLCODE but keeps caller's value and sender + SUICIDE = 0xff ///< halt execution and register account for later deletion +}; + +/// @returns the number of PUSH Instruction _inst +inline unsigned getPushNumber(Instruction _inst) +{ + return (byte)_inst - unsigned(Instruction::PUSH1) + 1; +} + +/// @returns the number of DUP Instruction _inst +inline unsigned getDupNumber(Instruction _inst) +{ + return (byte)_inst - unsigned(Instruction::DUP1) + 1; +} + +/// @returns the number of SWAP Instruction _inst +inline unsigned getSwapNumber(Instruction _inst) +{ + return (byte)_inst - unsigned(Instruction::SWAP1) + 1; +} + +/// @returns the PUSH<_number> instruction +inline Instruction pushInstruction(unsigned _number) +{ + assertThrow(1 <= _number && _number <= 32, InvalidOpcode, "Invalid PUSH instruction requested."); + return Instruction(unsigned(Instruction::PUSH1) + _number - 1); +} + +/// @returns the DUP<_number> instruction +inline Instruction dupInstruction(unsigned _number) +{ + assertThrow(1 <= _number && _number <= 16, InvalidOpcode, "Invalid DUP instruction requested."); + return Instruction(unsigned(Instruction::DUP1) + _number - 1); +} + +/// @returns the SWAP<_number> instruction +inline Instruction swapInstruction(unsigned _number) +{ + assertThrow(1 <= _number && _number <= 16, InvalidOpcode, "Invalid SWAP instruction requested."); + return Instruction(unsigned(Instruction::SWAP1) + _number - 1); +} + +/// @returns the LOG<_number> instruction +inline Instruction logInstruction(unsigned _number) +{ + assertThrow(_number <= 4, InvalidOpcode, "Invalid LOG instruction requested."); + return Instruction(unsigned(Instruction::LOG0) + _number); +} + +enum class Tier : unsigned +{ + Zero = 0, // 0, Zero + Base, // 2, Quick + VeryLow, // 3, Fastest + Low, // 5, Fast + Mid, // 8, Mid + High, // 10, Slow + Ext, // 20, Ext + Special, // multiparam or otherwise special + Invalid // Invalid. +}; + +/// Information structure for a particular instruction. +struct InstructionInfo +{ + std::string name; ///< The name of the instruction. + int additional; ///< Additional items required in memory for this instructions (only for PUSH). + int args; ///< Number of items required on the stack for this instruction (and, for the purposes of ret, the number taken from the stack). + int ret; ///< Number of items placed (back) on the stack by this instruction, assuming args items were removed. + bool sideEffects; ///< false if the only effect on the execution environment (apart from gas usage) is a change to a topmost segment of the stack + Tier gasPriceTier; ///< Tier for gas pricing. +}; + +/// Information on all the instructions. +InstructionInfo instructionInfo(Instruction _inst); + +/// check whether instructions exists +bool isValidInstruction(Instruction _inst); + +/// Convert from string mnemonic to Instruction type. +extern const std::map c_instructions; + +/// Iterate through EVM code and call a function on each instruction. +void eachInstruction(bytes const& _mem, std::function const& _onInstruction); + +/// Convert from EVM code to simple EVM assembly language. +std::string disassemble(bytes const& _mem); + +} +} + diff --git a/libodbc/CMakeLists.txt b/libodbc/CMakeLists.txt new file mode 100644 index 0000000000..7b2f49cee9 --- /dev/null +++ b/libodbc/CMakeLists.txt @@ -0,0 +1,38 @@ +#设置ODBC-PATH +set(ODBC_PATH /usr/local/app/sqlapi/lib64) + +#添加目录下所有源文件 +aux_source_directory(. ODBC_SRC_LIST) + +#递归寻找头文件 +file(GLOB_RECURSE HEADERS "*.h") + + +#静态库 +add_library(odbc STATIC ${ODBC_SRC_LIST} ${HEADERS}) + +find_package(Eth) +find_package(Dev) + +target_include_directories(odbc PRIVATE ..) +target_include_directories(odbc PRIVATE ./include + ./include/db2_linux + ./include/ibase + ./include/infomix + ./include/mysql + ./include/odbc_linux + ./include/pgsql + ./include/sqlbase + ./include/sqllite + ./include/ss_linux + ./include/sybase) + +target_include_directories(odbc PRIVATE ../utils) +link_directories(${ODBC_PATH}) +target_link_libraries(odbc ${Dev_DEVCORE_LIBRARIES}) +target_link_libraries(odbc ${Boost_REGEX_LIBRARIES} JsonCpp) +target_link_libraries(odbc kayakDBOp) +target_link_libraries(odbc dl) + + +install(TARGETS odbc RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib) diff --git a/libodbc/LMysql.cpp b/libodbc/LMysql.cpp new file mode 100644 index 0000000000..6648a7225a --- /dev/null +++ b/libodbc/LMysql.cpp @@ -0,0 +1,296 @@ +#include "LMysql.h" + +#include +#include +#include +#include +#include + +using namespace std; +using namespace leveldb; +using namespace dev; + +static void* EncodeValue(char* v) { return reinterpret_cast(v); } + +static void Deleter(const Slice&, void* v) { + + char * pch = reinterpret_cast(v); + delete pch; +// std::cout << "delete cache " << toHex(dev::bytesConstRef(key)) << std::endl; +} + +class MysqlWriterBatch : public leveldb::WriteBatch::Handler +{ +public: + + virtual void Put(leveldb::Slice const& _key, leveldb::Slice const& _value) + { + leveldb::OdbcWriteStruct odbcWrite(_key, _value); + //std::cout << "LMYSQL write " << _key.ToString() << "|" << _value.ToString() << std::endl; + //std::cout << "LMYSQL write hex " << odbcWrite._sKey << "|" << odbcWrite._sValue << std::endl; + + _vData.push_back(odbcWrite); + } + + virtual void Delete(leveldb::Slice const& _key) + { + std::cout << "Delete" << _key.ToString(); + //cnote << "Delete" << _key.ToString(); + } + + virtual void setCache(Cache *cc){ + if (cc == nullptr) + { + return; + } + + for (auto data : _vData) + { + std::string sHex = toHex(dev::bytesConstRef(data._sValue)); + char *cstr = new char[sHex.size() + 1]; + strcpy(cstr, sHex.c_str()); + cc->Release(cc->Insert(data._sKey, EncodeValue(cstr), sHex.size(), &Deleter)); + } + } + + std::string toWriteSqlString(std::string tableName) + { + if (_vData.size() == 0) + { + return ""; + } + + std::string retSql = "replace into " + tableName + " ( s_key,s_value) values "; + int i = 0; + for (auto data : _vData) + { + if (i > 0) + { + retSql += ","; + } + + retSql += " ('" + toHex(dev::bytesConstRef(data._sKey)) + "','" + toHex(dev::bytesConstRef(data._sValue)) + "')"; + i++; + } + + retSql += ";"; + //std::cout << "write sql is " << retSql < _vData; +}; + +LMysql::LMysql(const std::string &sDbConnInfo, const std::string &sDbName, const std::string &sTableName, const std::string &sUserName, const std::string &sPwd, int iCacheSize) +:LvlDbInterface(sDbConnInfo, sDbName, sTableName, sUserName, sPwd, DBEngineType::mysql, iCacheSize) +{ + std::cout << "MYsql init success."; + //LOG(TRACE) << "MYsql init success."; +} + +Status LMysql::Delete(const WriteOptions& , const Slice& key) +{ + std::cout << "mysql delete " << key.ToString(); + //LOG(TRACE) << "mysql delete " << key.ToString(); + + Status s; + _dataCc->Erase(key); + return s; +} + +Status LMysql::Write(const WriteOptions& , WriteBatch* batch) +{ + leveldb::Status s = Status::Corruption("batch write"); + bool bSucc = false; + int iTryTimes = 0; + do + { + try + { + MysqlWriterBatch n; + batch->Iterate(&n); + + std::string sql = n.toWriteSqlString(_sTableName); + if (sql == "") + { + //std::cout << "there is no data in write batch." << std::endl; + return Status::OK(); + } + + SACommand cmd(&con); + SAString saSql(sql.c_str()); + cmd.setCommandText(saSql); + + cmd.Execute(); + con.Commit(); + + n.setCache(_dataCc); + s = Status::OK(); + bSucc = true; + } + catch (SAException &x) + { + //DB쳣 sleep 50ms Ȼ + sleep(50); + // print error message + LOG(ERROR) << "SAException: " << x.ErrText().GetMultiByteChars() << std::endl; + // д + //ʱʧ 쳣δ + if (x.ErrNativeCode() == CR_SERVER_LOST || x.ErrNativeCode() == CR_SERVER_GONE_ERROR) + { + if (con.isConnected()) + { + con.Disconnect(); + } + + LvlDbInterface::Connect(); + std::cout << "SAException: lostServer writeData" << iTryTimes << "|" << x.ErrText().GetMultiByteChars() << "|" << x.ErrNativeCode() << std::endl; + continue; + } + else{ + std::cout << "SAException: other reason writeData" << iTryTimes << "|" << x.ErrText().GetMultiByteChars() << "|" << x.ErrNativeCode() << std::endl; + + } + iTryTimes++; + + } + catch (std::exception& e){ + //todo 쳣Ƿֱ˳迼 + LOG(ERROR) << "exception: " << e.what() << std::endl; + break; + } + catch (...){ + //todo 쳣Ƿֱ˳迼 + LOG(ERROR) << "unknown exception occured" << std::endl; + break; + } + + } while (!bSucc && iTryTimes <= 3); + return s; +} + +Status LMysql::Get(const ReadOptions& , const Slice& key, std::string* value) +{ + + leveldb::Status s = leveldb::Status::NotFound("get"); + ostringstream ossql; + try + { + Cache::Handle *handle = _dataCc->Lookup(key); + if (handle == NULL) { + + //ռλ ַ滻 + bool bBreak=false; + bool bFind = false; + int iTryTimes = 0; + do{ + try{ + ossql << "select s_value from " << _sTableName << " where s_key = '" << toHex(bytesConstRef(key)) << "';"; + SACommand cmd(&con); + SAString saSql(ossql.str().c_str()); + cmd.setCommandText(saSql); + cmd.Execute(); + //std::cout << "LMysql DB querysql GET: " << ossql.str() << std::endl; + + while (cmd.FetchNext()) + { + bFind = true; + // һֶ + for (int i = 1; i <= cmd.FieldCount(); ++i) + { + *value = cmd[i].asString(); + // std::cout << (const char*)cmd[i].Name() << "|" << (const char*)cmd[i].asBytes() << "|" << *value << endl; + } + } + bBreak = true; + } + catch (SAException &x) + { + sleep(100); + std::cout << "SAException: get data " << ossql.str() << "|" << x.ErrText().GetMultiByteChars() << "|" << x.ErrNativeCode() << std::endl; + iTryTimes++; + //ϣҪ + if (x.ErrNativeCode() == CR_SERVER_LOST || x.ErrNativeCode() == CR_SERVER_GONE_ERROR) + { + if (con.isConnected()) + { + con.Disconnect(); + } + + LvlDbInterface::Connect(); + std::cout << "SAException: lostServer getData: " <size() + 1]; + strcpy(cstr, value->c_str()); + //骸free + _dataCc->Release(_dataCc->Insert(key, EncodeValue(cstr), value->size(), &Deleter)); + *value = asString(fromHex(*value)); + } + + s = Status::OK(); + } + else{ + //std::cout << "LMYSQL CAHCE HAS DATA " << toHex(dev::bytesConstRef(key)) << std::endl; + char * ch = reinterpret_cast(_dataCc->Value(handle)); + *value = ch; + _dataCc->Release(handle); + //std::cout << "LMYSQL GET datacache is hex data is : " << toHex(dev::bytesConstRef(key)) << "|" << ch << "|" << value <<"|" << value->size()<< std::endl; + //std::cout << "LMYSQL GET datacache is " << key.ToString() << "|" << *value << std::endl; + *value = asString(fromHex(*value)); + + } + } + catch (SAException &x) + { + std::cout << "SAException: get data " << ossql.str() << "|" << x.ErrText().GetMultiByteChars() << "|" << x.ErrNativeCode ()<< std::endl; + } + catch (std::exception& e){ + std::cout << "exception: " << e.what() << std::endl; + } + catch (...){ + std::cout << "unknown exception occured" << std::endl; + } + + return s; +} + + +Status LMysql::Put(const WriteOptions& opt, const Slice& key, const Slice& value) +{ + leveldb::WriteBatch batch; + batch.Put(key, value); + + return Write(opt, &batch); +} \ No newline at end of file diff --git a/libodbc/LMysql.h b/libodbc/LMysql.h new file mode 100644 index 0000000000..15aae5bb6c --- /dev/null +++ b/libodbc/LMysql.h @@ -0,0 +1,20 @@ +#pragma once +#include "LvlDbInterface.h" +using namespace leveldb; + +namespace leveldb{ + class LMysql : public LvlDbInterface + { + public: + LMysql(const std::string &sDbConnInfo, const std::string &sDbName, const std::string &sTableName, const std::string &sUserName, const std::string &sPwd, int iCacheSize = 100 * 1048576); + + virtual Status Delete(const WriteOptions&, const Slice& key) override; + virtual Status Write(const WriteOptions& options, WriteBatch* updates) override; + virtual Status Get(const ReadOptions& options, const Slice& key, std::string* value) override; + virtual Status Put(const WriteOptions& opt, const Slice& key, const Slice& value) override; + + LMysql(){} + ~LMysql(){} + }; + +} \ No newline at end of file diff --git a/libodbc/LOracle.cpp b/libodbc/LOracle.cpp new file mode 100644 index 0000000000..9bdb1f52ca --- /dev/null +++ b/libodbc/LOracle.cpp @@ -0,0 +1,292 @@ +#include "LOracle.h" + +#include +#include +#include +#include +#include + +using namespace std; +using namespace leveldb; +using namespace dev; + +static void* EncodeValue(char* v) { return reinterpret_cast(v); } + +static void Deleter(const Slice&, void* v) { + + char * pch = reinterpret_cast(v); + delete pch; + // std::cout << "delete cache " << toHex(dev::bytesConstRef(key)) << std::endl; +} + +class OracleWriterBatch : public leveldb::WriteBatch::Handler +{ +public: + + virtual void Put(leveldb::Slice const& _key, leveldb::Slice const& _value) + { + leveldb::OdbcWriteStruct odbcWrite(_key, _value); + _vData.push_back(odbcWrite); + } + + virtual void Delete(leveldb::Slice const& _key) + { + std::cout << "Delete" << _key.ToString(); + } + + virtual void setCache(Cache *cc){ + if (cc == nullptr) + { + return; + } + + for (auto data : _vData) + { + std::string sHex = toHex(dev::bytesConstRef(data._sValue)); + char *cstr = new char[sHex.size() + 1]; + strcpy(cstr, sHex.c_str()); + cc->Release(cc->Insert(data._sKey, EncodeValue(cstr), sHex.size(), &Deleter)); + } + } + + std::string toWriteSqlString(std::string tableName) + { + if (_vData.size() == 0) + { + return ""; + } + + std::string retSql = "replace into " + tableName + " ( s_key,s_value) values "; + int i = 0; + for (auto data : _vData) + { + if (i > 0) + { + retSql += ","; + } + + retSql += " ('" + toHex(dev::bytesConstRef(data._sKey)) + "','" + toHex(dev::bytesConstRef(data._sValue)) + "')"; + i++; + } + + retSql += ";"; + + return retSql; + } + +private: + std::vector _vData; +}; + +LOracle::LOracle(const std::string &sDbConnInfo, const std::string &sDbName, const std::string &sTableName, const std::string &sUserName, const std::string &sPwd, int iCacheSize) +:LvlDbInterface(sDbConnInfo, sDbName, sTableName, sUserName, sPwd, DBEngineType::oracle, iCacheSize) +{ + std::cout << "LOracle init success."; +} + + +//暂时未用 +Status LOracle::Delete(const WriteOptions&, const Slice& key) +{ + std::cout << "LOracle delete " << key.ToString(); + + //清掉缓存 + Status s; + _dataCc->Erase(key); + return s; +} + +Status LOracle::Write(const WriteOptions&, WriteBatch* batch) +{ + leveldb::Status s = Status::Corruption("batch write"); + bool bSucc = false; + int iTryTimes = 0; + do + { + //std::cout << "writeData " << std::endl; + try + { + OracleWriterBatch n; + batch->Iterate(&n); + + std::string sql = n.toWriteSqlString(_sTableName); + if (sql == "") + { + LOG(ERROR) << "there is no data in write batch." << std::endl; + return Status::OK(); + } + + SACommand cmd(&con); + SAString saSql(sql.c_str()); + cmd.setCommandText(saSql); + + cmd.Execute(); + con.Commit(); + + n.setCache(_dataCc); + s = Status::OK(); + bSucc = true; + } + catch (SAException &x) + { + sleep(100); + // print error message + LOG(ERROR) << "SAException: " << x.ErrText().GetMultiByteChars() << std::endl; + if (x.ErrNativeCode() == CR_SERVER_LOST || x.ErrNativeCode() == CR_SERVER_GONE_ERROR) + { + if (con.isConnected()) + { + con.Disconnect(); + } + + LvlDbInterface::Connect(); + std::cout << "SAException: lostServer writeData:" << iTryTimes << "|" << x.ErrText().GetMultiByteChars() << "|" << x.ErrNativeCode() << std::endl; + continue; + } + else{ + std::cout << "SAException: other reason writeData:" << iTryTimes << "|" << x.ErrText().GetMultiByteChars() << "|" << x.ErrNativeCode() << std::endl; + + } + iTryTimes++; + + } + catch (std::exception& e){ + //todo 其他异常是否直接退出。需考虑 + LOG(ERROR) << "exception: " << e.what() << std::endl; + break; + } + catch (...){ + //todo 其他异常是否直接退出。需考虑 + LOG(ERROR) << "unknown exception occured" << std::endl; + break; + } + + } while (!bSucc && iTryTimes <= 3); + return s; +} + +Status LOracle::Get(const ReadOptions&, const Slice& key, std::string* value) +{ + + leveldb::Status s = leveldb::Status::NotFound("get"); + ostringstream ossql; + try + { + //std::cout << "getData |" << toHex(bytesConstRef(key)) << std::endl; + Cache::Handle *handle = _dataCc->Lookup(key); + if (handle == NULL) { + + //用占位符 字符串替换 + bool bBreak = false; + bool bFind = false; + int iTryTimes = 0; + do{ + try{ + ossql << "select s_value from " << _sTableName << " where s_key = '" << toHex(bytesConstRef(key)) << "';"; + SACommand cmd(&con); + //std::cout << "LOracle Get is |" << ossql.str() << std::endl; + SAString saSql(ossql.str().c_str()); + cmd.setCommandText(saSql); + cmd.Execute(); + //std::cout << "LOracle DB querysql GET: " << ossql.str() << std::endl; + + while (cmd.FetchNext()) + { + bFind = true; + // 最后一个字段 + for (int i = 1; i <= cmd.FieldCount(); ++i) + { + *value = cmd[i].asString(); + // std::cout << (const char*)cmd[i].Name() << "|" << (const char*)cmd[i].asBytes() << "|" << *value << endl; + } + } + bBreak = true; + } + catch (SAException &x) + { + sleep(100); + std::cout << "SAException: get data " << ossql.str() << "|" << x.ErrText().GetMultiByteChars() << "|" << x.ErrNativeCode() << std::endl; + iTryTimes++; + //可能连接闪断,需要尝试重新连接 + if (x.ErrNativeCode() == CR_SERVER_LOST || x.ErrNativeCode() == CR_SERVER_GONE_ERROR) + { + if (con.isConnected()) + { + con.Disconnect(); + } + + LvlDbInterface::Connect(); + std::cout << "SAException: lostServer getData: " << iTryTimes << "|" << ossql.str() << "|" << x.ErrText().GetMultiByteChars() << "|" << x.ErrNativeCode() << std::endl; + + continue; + } + else{ + + //其余异常不知这么处理是否OK + if (con.isConnected()) + { + con.Disconnect(); + } + + LvlDbInterface::Connect(); + std::cout << "SAException: Oracle other reason. getData: " << iTryTimes << "|" << ossql.str() << "|" << x.ErrText().GetMultiByteChars() << "|" << x.ErrNativeCode() << std::endl; + + } + } + catch (std::exception& e){ + //todo 其他异常是否直接退出。需考虑 + std::cout << "exception: " << e.what() << std::endl; + break; + } + catch (...){ + //todo 其他异常是否直接退出。需考虑 + std::cout << "unknown exception occured" << std::endl; + break; + } + //std::cout << " LOracle GET end :" << bFind << " |" << toHex(bytesConstRef(key)) << "|" << *value << endl; + } while (!bBreak && iTryTimes <= 3); + + if (bFind) + { + char *cstr = new char[value->size() + 1]; + strcpy(cstr, value->c_str()); + //交给楠哥free + _dataCc->Release(_dataCc->Insert(key, EncodeValue(cstr), value->size(), &Deleter)); + *value = asString(fromHex(*value)); + } + + s = Status::OK(); + } + else{ + //std::cout << "LOracle CAHCE HAS DATA " << toHex(dev::bytesConstRef(key)) << std::endl; + char * ch = reinterpret_cast(_dataCc->Value(handle)); + *value = ch; + _dataCc->Release(handle); + //std::cout << "LOracle GET datacache is hex data is : " << toHex(dev::bytesConstRef(key)) << "|" << ch << "|" << value <<"|" << value->size()<< std::endl; + //std::cout << "LOracle GET datacache is " << key.ToString() << "|" << *value << std::endl; + *value = asString(fromHex(*value)); + + } + } + catch (SAException &x) + { + std::cout << "SAException: get data " << ossql.str() << "|" << x.ErrText().GetMultiByteChars() << "|" << x.ErrNativeCode() << std::endl; + } + catch (std::exception& e){ + std::cout << "exception: " << e.what() << std::endl; + } + catch (...){ + std::cout << "unknown exception occured" << std::endl; + } + + return s; +} + + +Status LOracle::Put(const WriteOptions& opt, const Slice& key, const Slice& value) +{ + leveldb::WriteBatch batch; + batch.Put(key, value); + + return Write(opt, &batch); +} \ No newline at end of file diff --git a/libodbc/LOracle.h b/libodbc/LOracle.h new file mode 100644 index 0000000000..adc919282e --- /dev/null +++ b/libodbc/LOracle.h @@ -0,0 +1,20 @@ +#pragma once +#include "LvlDbInterface.h" +using namespace leveldb; + +namespace leveldb{ + class LOracle : public LvlDbInterface + { + public: + LOracle(const std::string &sDbConnInfo, const std::string &sDbName, const std::string &sTableName, const std::string &sUserName, const std::string &sPwd, int iCacheSize = 100 * 1048576); + + virtual Status Delete(const WriteOptions&, const Slice& key) override; + virtual Status Write(const WriteOptions& options, WriteBatch* updates) override; + virtual Status Get(const ReadOptions& options, const Slice& key, std::string* value) override; + virtual Status Put(const WriteOptions& opt, const Slice& key, const Slice& value) override; + + LOracle(){} + ~LOracle(){} + }; + +} \ No newline at end of file diff --git a/libodbc/LvlDbInterface.cpp b/libodbc/LvlDbInterface.cpp new file mode 100644 index 0000000000..36710e2dbf --- /dev/null +++ b/libodbc/LvlDbInterface.cpp @@ -0,0 +1,82 @@ +#include "LvlDbInterface.h" +#include "LMysql.h" +#include "LOracle.h" +#include +#include +#include + +namespace js = json_spirit; +using namespace std; +using namespace leveldb; + +LvlDbInterface* LvlDbInterfaceFactory::create(int dbUseType) +{ + + std::string dataJsStr = dev::contentsString(dev::getConfigPath()); + js::mValue val; + js::read_string(dataJsStr, val); + js::mObject obj = val.get_obj(); + js::mObject dbObj = obj["dbconf"].get_obj(); + js::mObject dbTypeObj; + switch(dbUseType) + { + case DBUseType::stateType: + { + dbTypeObj = dbObj["stateDbConf"].get_obj(); + } + break; + case DBUseType::blockType: + { + dbTypeObj = dbObj["blockDbConf"].get_obj(); + } + break; + case DBUseType::extrasType: + { + dbTypeObj = dbObj["extrasDbConf"].get_obj(); + } + break; + default: + { + LOG(ERROR) << "wrong db use type :" << dbUseType << std::endl; + exit(-1); + } + } + + std::string sDbInfo = dbTypeObj["dbInfo"].get_str(); + std::string sDbName = dbTypeObj["dbName"].get_str(); + std::string sTableName = dbTypeObj["tableName"].get_str(); + std::string sUserName = dbTypeObj["userName"].get_str(); + std::string sPwd = dbTypeObj["pwd"].get_str(); + int iDbEngineType = dbTypeObj["engineType"].get_int(); + if (iDbEngineType != DBEngineType::mysql && iDbEngineType != DBEngineType::oracle) + { + LOG(ERROR) << "Only Support mysql and oracle. Wrong db engine. "<< iDbEngineType << std::endl; + exit(-1); + } + + int iCacheSize = dbTypeObj["cacheSize"].get_int(); + + return create(sDbInfo, sDbName, sTableName, sUserName, sPwd, iDbEngineType, iCacheSize); +} + +LvlDbInterface* LvlDbInterfaceFactory::create(const std::string &sDbInfo, const std::string &sDbName, const std::string &sTableName, const std::string &username, const std::string &pwd, int dbEngineType, int iCacheSize) +{ + + LvlDbInterface *pLvlDb = nullptr; + switch (dbEngineType) + { + case DBEngineType::mysql: + { + pLvlDb = new LMysql(sDbInfo, sDbName, sTableName, username, pwd, iCacheSize); + } + break; + case DBEngineType::oracle: + { + pLvlDb = new LOracle(sDbInfo, sDbName, sTableName, username, pwd, iCacheSize); + } + break; + default: + break; + } + return pLvlDb; +} \ No newline at end of file diff --git a/libodbc/LvlDbInterface.h b/libodbc/LvlDbInterface.h new file mode 100644 index 0000000000..57323aad57 --- /dev/null +++ b/libodbc/LvlDbInterface.h @@ -0,0 +1,174 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace leveldb{ + + + enum DBUseType{ + stateType = 1, //statedb + blockType = 2, //blockdb + extrasType = 3 //extrasdb + }; + + enum DBEngineType{ + mysql = 1, //mysql + oracle = 2 //oracle + }; + + //static string DecodeValue(void* v) { return reinterpret_cast(v); } + class OdbcWriteStruct{ + public: + OdbcWriteStruct(leveldb::Slice const &sKey, leveldb::Slice const & sValue) + :_sKey(sKey), + _sValue(sValue) + {} + public: + leveldb::Slice _sKey; + leveldb::Slice _sValue; + }; + + class LvlDbInterface : public leveldb::DB + { + public: + friend class leveldb::DB; + + LvlDbInterface(const std::string &sDbConnInfo, const std::string &sDbName, const std::string &sTableName, const std::string &sUserName, const std::string &sPwd, int iDBEngineType, int iCacheSize = 100 * 1048576) + :_sDbConnInfo(sDbConnInfo), + _sDbName(sDbName), + _sTableName(sTableName), + _sUserName(sUserName), + _sPwd(sPwd) + { + std::cout << "LvlDbInterface init:" << _sDbConnInfo << "|" << _sDbName << "|" << _sTableName << "|" << _sUserName << "|" << _sPwd << "|" << iDBEngineType << "|" << iCacheSize << std::endl;; + //cnote << _sDbConnInfo << "|" << _sDbName << "|" << _sTableName << "|" << _sUserName << "|" << _sPwd; + + switch (iDBEngineType) + { + case DBEngineType::mysql: + { + _saClient = SA_MySQL_Client; + } + break; + case DBEngineType::oracle: + { + _saClient = SA_Oracle_Client; + } + break; + } + + if (!Connect()) + { + //cwarn << "db connect failed."; + exit(-1); + } + _dataCc = leveldb::NewLRUCache(iCacheSize);//100m = 100 * 1048576 + + } + + virtual bool Connect() + { + bool bRet = true; + try + { + SAString saDbInfo(_sDbConnInfo.c_str()); + SAString saDbUser(_sUserName.c_str()); + SAString saDbPwd(_sPwd.c_str()); + + con.Connect(saDbInfo, saDbUser, saDbPwd, _saClient); + + con.setOption(SAString("MYSQL_OPT_READ_TIMEOUT")) = SAString("1"); + con.setOption(SAString("MYSQL_OPT_CONNECT_TIMEOUT")) = SAString("86400"); + con.setAutoCommit(SA_AutoCommitOn); +// std::cout << "conn GetServerVersionString() :" << con.ServerVersionString().GetMultiByteChars() << std::endl; + } + catch (SAException &x){ + std::cerr << "SAException: " << x.ErrText().GetMultiByteChars() << std::endl; + bRet = false; + } + catch (std::exception& e){ + std::cerr << "exception: " << e.what() << std::endl; + bRet = false; + } + catch (...){ + std::cerr << "unknown exception occured" << std::endl; + bRet = false; + } + return bRet; + } + + virtual Status Delete(const WriteOptions&, const Slice& key) override = 0; + virtual Status Get(const ReadOptions& options, const Slice& key, std::string* value) override = 0; + virtual Status Write(const WriteOptions& options, WriteBatch* updates)override = 0; + + + virtual Status Put(const WriteOptions&, const Slice& key, const Slice& value) = 0; + + //����Ľӿ���ʱ�Ȳ���Ҫʵ�� �ȼ���־ ����Щ��Ҫ + virtual Iterator* NewIterator(const ReadOptions&) override{ + std::cout << "weodbc interface neet NewIterator "; + //cnote << "weodbc interface neet NewIterator "; + return nullptr; + //return leveldb::DB::NewIterator(ro); + } + virtual const Snapshot* GetSnapshot() override{ + std::cout << "weodbc interface neet GetSnapshot "; + //cnote << "weodbc interface neet GetSnapshot "; + return nullptr; + } + virtual void ReleaseSnapshot(const Snapshot*) override{ + std::cout << "weodbc interface neet ReleaseSnapshot."; + //cnote << "weodbc interface neet ReleaseSnapshot."; + } + + virtual bool GetProperty(const Slice&, std::string* value) override{ + std::cout << "weodbc interface neet GetProperty:" << *value; + //cnote << "weodbc interface neet GetProperty:" << *value; + return true; + } + + virtual void GetApproximateSizes(const Range*, int n, uint64_t* sizes)override{ + std::cout << "weodbc interface neet GetApproximateSizes." << n << "|" << sizes; + //cnote << "weodbc interface neet GetApproximateSizes." << n << "|" << sizes; + } + + virtual void CompactRange(const Slice* begin, const Slice* end)override{ + std::cout << "weodbc interface neet put " << begin->ToString() << "|" << end->ToString(); + //cnote << "weodbc interface neet put " << begin->ToString() << "|" << end->ToString(); + } + + + LvlDbInterface(){} + ~LvlDbInterface(){ delete(_dataCc); _dataCc = nullptr; } + + + public: + //sa���� + SAConnection con; + SAClient_t _saClient; + std::string _sDbConnInfo; + std::string _sDbName; + std::string _sTableName; + std::string _sUserName; + std::string _sPwd; + + leveldb::Cache *_dataCc = nullptr; + }; + + class LvlDbInterfaceFactory{ + public: + //static std::shared_ptr create(const std::string &sDbInfo, const std::string &sDbName, const std::string &sTableName, const std::string &username, const std::string &pwd); + static LvlDbInterface* create(const std::string &sDbInfo, const std::string &sDbName, const std::string &sTableName, const std::string &username, const std::string &pwd, int dbEngineType, int iCacheSize = 100 * 1048576); + static LvlDbInterface* create(int dbType); + }; + +} + + diff --git a/libodbc/include/SQLAPI.h b/libodbc/include/SQLAPI.h new file mode 100644 index 0000000000..4db36efdce --- /dev/null +++ b/libodbc/include/SQLAPI.h @@ -0,0 +1,1551 @@ +#if !defined(__SQLAPI_H__) +#define __SQLAPI_H__ + +#ifdef SQLAPI_EXPORTS +#define SQLAPI_API __declspec(dllexport) +#else +#define SQLAPI_API +#endif + +#ifdef SQLAPI_DECL_THROW +#define SQLAPI_THROW(x) throw(x) +#else +#define SQLAPI_THROW(x) +#endif + +#if defined(_WIN32) || defined(WIN32) || defined(_WIN64) || defined(WIN64) || defined(_WINDOWS) || defined(_WINDOWS_) +#define SQLAPI_WINDOWS +#include +#endif + +#if !defined(SQLAPI_WINDOWS) || defined (CYGWIN) +#include +#include +#endif + +#ifndef SQLAPI_WINDOWS +#include +#endif + +#ifdef UNDER_CE +#include +#else +#include +#include +#endif +#include +#include +#include + +#ifdef SQLAPI_WINDOWS +// 64-bit integer +typedef __int64 sa_int64_t; +typedef unsigned __int64 sa_uint64_t; +// SQLAPI callback naming +#define SQLAPI_CALLBACK __cdecl +#else +// 64-bit integer +typedef long long int sa_int64_t; +typedef unsigned long long int sa_uint64_t; +// SQLAPI callback naming +#define SQLAPI_CALLBACK +#endif // ! SQLAPI_WINDOWS + +#ifdef SA_USE_STL +#include +#endif + +#ifndef SIZE_MAX +#define SIZE_MAX UINT_MAX +#endif + +#define MAX_BATCH_NUM 5000 + +class ISAClient; +class ISAConnection; +class ISACursor; + +class SAMutex; + +class SAConnection; +class SACommand; +struct sa_Commands; +class saOptions; +class SAValue; +class SAParam; +class SAField; + +class SAException; + +class saPlaceHolder; + +class SABytes; +class SALongBinary; +class SALongChar; +class SABLob; +class SACLob; +class SAValueRead; + +//! \addtogroup enums SQLAPI++ defined enums +//! \{ + +typedef + enum eSAClient +{ + //! DBMS client is not specified + SA_Client_NotSpecified, + //! ODBC + SA_ODBC_Client, + //! Oracle + SA_Oracle_Client, + //! Microsoft SQL Server + SA_SQLServer_Client, + //! InterBase or Firebird + SA_InterBase_Client, + //! SQLBase + SA_SQLBase_Client, + //! IBM DB2 + SA_DB2_Client, + //! Informix + SA_Informix_Client, + //! Sybase ASE + SA_Sybase_Client, + //! MySQL + SA_MySQL_Client, + //! PostgreSQL + SA_PostgreSQL_Client, + //! SQLite + SA_SQLite_Client, + _SA_Client_Reserverd = (int)(((unsigned int)(-1))/2) +} SAClient_t; + +typedef + enum eSAErrorClass +{ + //! no error occurred + SA_No_Error, + //! user-generated error + SA_UserGenerated_Error, + //! the Library-generated error + SA_Library_Error, + //! DBMS API error occured + SA_DBMS_API_Error, + _SA_ErrorClass_Reserved = (int)(((unsigned int)(-1))/2) +} SAErrorClass_t; + +typedef + enum eSAIsolationLevel +{ + //! the default(unknown) isolation level + SA_LevelUnknown = -1, + //! standard ANSI isolation level 0 + SA_ANSILevel0, + //! standard ANSI isolation level 1 + SA_ANSILevel1, + //! standard ANSI isolation level 2 + SA_ANSILevel2, + //! standard ANSI isolation level 3 + SA_ANSILevel3, + //! isolation level 'Read Uncommitted' + SA_ReadUncommitted = SA_ANSILevel0, + //! isolation level 'Read Committed' + SA_ReadCommitted = SA_ANSILevel1, + //! isolation level 'Repeatable Read' + SA_RepeatableRead = SA_ANSILevel2, + //! isolation level 'Serializable' + SA_Serializable = SA_ANSILevel3, + _SA_IsolationLevel_Reserved = (int)(((unsigned int)(-1))/2) +} SAIsolationLevel_t; + +typedef + enum eSAAutoCommit +{ + //! the default(unknown) auto-commit mode + SA_AutoCommitUnknown = -1, + //! auto-commit mode is off + SA_AutoCommitOff, + //! auto-commit mode is on + SA_AutoCommitOn, + _SA_AutoCommit_Reserved = (int)(((unsigned int)(-1))/2) +} SAAutoCommit_t; + +typedef + enum eSADataType +{ + SA_dtUnknown, + SA_dtBool, + SA_dtShort, + SA_dtUShort, + SA_dtLong, + SA_dtULong, + SA_dtDouble, + SA_dtNumeric, + SA_dtDateTime, + SA_dtInterval, + SA_dtString, + SA_dtBytes, + SA_dtLongBinary, + SA_dtLongChar, + SA_dtBLob, + SA_dtCLob, + SA_dtCursor, + SA_dtSpecificToDBMS, + _SA_DataType_Reserved = (int)(((unsigned int)(-1))/2) +} SADataType_t; + +typedef + enum eSACommandType +{ + //! command type is not defined + SA_CmdUnknown, + //! command is an SQL statement (with or without parameters) + SA_CmdSQLStmt, + //! command is a raw SQL statement and not interpreted by SQLAPI++ + SA_CmdSQLStmtRaw, + //! command is a stored procedure or a function + SA_CmdStoredProc, + _SA_Cmd_Reserved = (int)(((unsigned int)(-1))/2) +} SACommandType_t; + +typedef + enum eSAParamDirType +{ + SA_ParamInput, + SA_ParamInputOutput, + SA_ParamOutput, + SA_ParamReturn, + _SA_ParamDirType_Reserved = (int)(((unsigned int)(-1))/2) +} SAParamDirType_t; + +typedef + enum eSALongOrLobReaderModes +{ + SA_LongOrLobReaderDefault, + SA_LongOrLobReaderManual, + _SA_LongOrLobReaderModes_Reserved = (int)(((unsigned int)(-1))/2) +} SALongOrLobReaderModes_t; + +typedef + enum eSAPieceType +{ + SA_FirstPiece = 1, + SA_NextPiece = 2, + SA_LastPiece = 3, + SA_OnePiece = 4, + _SA_Reserved_PieceType = (int)(((unsigned int)(-1))/2) +} SAPieceType_t; + +typedef + enum eSAConnectionHandlerType +{ + //! The handles is called after DBMS connection structures is allocated + SA_PreConnectHandler, + //! The handles is called after DBMS connection is esteblished + SA_PostConnectHandler +} SAConnectionHandlerType_t; + +//! \} + +//! \addtogroup typedefs SQLAPI++ defined types +//! \{ + +//! Callback for exception pre-handling +typedef bool (SQLAPI_CALLBACK *PreHandleException_t)(SAException &x); + +//! Long or LOB writer callback, use for parameter binding +typedef size_t (SQLAPI_CALLBACK *saLongOrLobWriter_t)(SAPieceType_t &ePieceType, void *pBuf, size_t nLen, void *pAddlData); + +//! Long or LOB reader callback, use for field fetching +typedef void (SQLAPI_CALLBACK *saLongOrLobReader_t)(SAPieceType_t ePieceType, void *pBuf, size_t nLen, size_t nBlobSize, void *pAddlData); + +//! DBMS connection handling callback +typedef void (SQLAPI_CALLBACK *saConnectionHandler_t)(SAConnection &con, SAConnectionHandlerType_t eHandlerType); + +//! \} + +typedef void (SQLAPI_CALLBACK *EnumCursors_t)(ISACursor *, void *); + +class SQLAPI_API saAPI +{ +protected: + saAPI(); +public: + virtual ~saAPI(); +}; + +class SQLAPI_API saConnectionHandles +{ +protected: + saConnectionHandles(); +public: + virtual ~saConnectionHandles(); +}; + +class SQLAPI_API saCommandHandles +{ +protected: + saCommandHandles(); +public: + virtual ~saCommandHandles(); +}; + +#if defined(SA_UNICODE) +#define _TSA(x) L ## x +typedef wchar_t SAChar; +#else +typedef char SAChar; +#define _TSA(x) x +#endif + +struct SAStringData; + +//! Provides support for manipulating character values +class SQLAPI_API SAString +{ +public: + // Constructors + //! Constructs an empty SAString + SAString(); + //! Copy constructor + SAString(const SAString &stringSrc); + //! Initializes SAString from a single character + SAString(SAChar ch, size_t nRepeat = 1); + //! Initializes SAString from an ANSI (multibyte) string (converts to SAChar) + SAString(const char *lpsz); + //! Initializes SAString from a UNICODE string (converts to SAChar) + SAString(const wchar_t *lpsz); + //! Initializes SAString from subset of characters from an ANSI (multibyte) string (converts to SAChar) + SAString(const char *lpch, size_t nLength); + //! Initializes SAString from subset of characters from a UNICODE string (converts to SAChar) + SAString(const wchar_t *lpch, size_t nLength); + //! Initializes SAString from unsigned characters (converts to SAChar) + SAString(const unsigned char *psz); + //! Special constructor for binary data (no converion to SAChar) + SAString(const void *pBuffer, size_t nLengthInBytes); + + // Attributes & Operations + + //! Get the data length (in characters). + size_t GetLength() const; + //! True if zero length + bool IsEmpty() const; + //! Clear contents to empty + void Empty(); + + //! Return pointer to const string + operator const SAChar *() const; + + // overloaded assignment + + //! Ref-counted copy from another SAString + const SAString &operator =(const SAString &sSrc); + //! Set string content to single character + const SAString &operator=(SAChar ch); +#ifdef SA_UNICODE + const SAString &operator=(char ch); +#endif + //! Copy string content from ANSI (multibyte) string (converts to SAChar) + const SAString &operator=(const char *lpsz); + //! Copy string content from UNICODE string (converts to SAChar) + const SAString &operator=(const wchar_t *lpsz); + //! Copy string content from unsigned chars + const SAString &operator=(const unsigned char *psz); + + // string concatenation + + //! Concatenate from another SAString + const SAString &operator+=(const SAString &string); + //! Concatenate a single character + const SAString &operator+=(SAChar ch); +#ifdef SA_UNICODE + // concatenate an ANSI character after converting it to SAChar + const SAString &operator+=(char ch); +#endif + //! Concatenate from a SAChar string + const SAString &operator+=(const SAChar *lpsz); + + friend SAString SQLAPI_API operator+(const SAString &string1, const SAString &string2); + friend SAString SQLAPI_API operator+(const SAString &string, SAChar ch); + friend SAString SQLAPI_API operator+(SAChar ch, const SAString &string); +#ifdef SA_UNICODE + friend SAString SQLAPI_API operator+(const SAString &string, char ch); + friend SAString SQLAPI_API operator+(char ch, const SAString &string); +#endif + friend SAString SQLAPI_API operator+(const SAString &string, const SAChar *lpsz); + friend SAString SQLAPI_API operator+(const SAChar *lpsz, const SAString &string); + + // string comparison + + //! Straight character comparison + int Compare(const SAChar *lpsz) const; + //! Compare ignoring case + int CompareNoCase(const SAChar *lpsz) const; +#ifndef UNDER_CE + //! NLS aware comparison, case sensitive + int Collate(const SAChar *lpsz) const; +#endif + + //! Convert the object to an uppercase + void MakeUpper(); + //! Convert the object to an lowercase + void MakeLower(); + + // simple sub-string extraction + + //! Return all characters starting at zero-based nFirst + SAString Mid(size_t nFirst) const; + //! Return nCount characters starting at zero-based nFirst + SAString Mid(size_t nFirst, size_t nCount) const; + //! Return first nCount characters in string + SAString Left(size_t nCount) const; + //! Return nCount characters from end of string + SAString Right(size_t nCount) const; + + // trimming whitespace (either side) + + //! Remove whitespace starting from right edge + void TrimRight(); + //! Remove whitespace starting from left side + void TrimLeft(); + + // trimming anything (either side) + + //! Remove continuous occurrences of chTarget starting from right + void TrimRight(SAChar chTarget); + //! Remove continuous occcurrences of characters in passed string, + // starting from right + void TrimRight(const SAChar *lpszTargets); + //! Remove continuous occurrences of chTarget starting from left + void TrimLeft(SAChar chTarget); + //! Remove continuous occcurrences of characters in + // passed string, starting from left + void TrimLeft(const SAChar *lpszTargets); + + // advanced manipulation + + // replace occurrences of substring lpszOld with lpszNew; + // empty lpszNew removes instances of lpszOld + size_t Replace(const SAChar *lpszOld, const SAChar *lpszNew); + // insert character at zero-based index; concatenates + // if index is past end of string + size_t Insert(size_t nIndex, SAChar ch); + // insert substring at zero-based index; concatenates + // if index is past end of string + size_t Insert(size_t nIndex, const SAChar *pstr); + // delete nCount characters starting at zero-based index + size_t Delete(size_t nIndex, size_t nCount = 1); + + // searching + + // find character starting at left, SIZ if not found + size_t Find(SAChar ch) const; + // find character starting at right + size_t ReverseFind(SAChar ch) const; + // find character starting at zero-based index and going right + size_t Find(SAChar ch, size_t nStart) const; + // find first instance of any character in passed string + size_t FindOneOf(const SAChar *lpszCharSet) const; + // find first instance of substring + size_t Find(const SAChar *lpszSub) const; + // find first instance of substring starting at zero-based index + size_t Find(const SAChar *lpszSub, size_t nStart) const; + + // simple formatting + + // printf-like formatting using passed string + void Format(const SAChar *lpszFormat, ...); + // printf-like formatting using variable arguments parameter + void FormatV(const SAChar *, va_list argList); + + // Access to string implementation buffer as "C" character array + + // get pointer to modifiable buffer at least as long as nMinBufLength + SAChar *GetBuffer(size_t nMinBufLength); + // release buffer, setting length to nNewLength (or to first null if SIZE_MAX) + void ReleaseBuffer(size_t nNewLength = SIZE_MAX); + + // Use LockBuffer/UnlockBuffer to turn refcounting off + + // turn refcounting off + SAChar *LockBuffer(); + // turn refcounting back on + void UnlockBuffer(); + + // Special buffer access routines to manipulate binary data + + // get binary data length (in bytes) + size_t GetBinaryLength() const; + // return pointer to const binary data buffer + operator const void *() const; + // get pointer to modifiable binary data buffer at least as long as nMinBufLengthInBytes + void *GetBinaryBuffer(size_t nMinBufLengthInBytes); + // release buffer, setting length to nNewLength (or to first nul if -1) + void ReleaseBinaryBuffer(size_t nNewLengthInBytes); + + // return pointer to const Unicode string, convert if needed + const wchar_t *GetWideChars() const; + // get string length (in Unicode characters) + size_t GetWideCharsLength() const; + // return pointer to const multibyte string, convert if needed + const char *GetMultiByteChars() const; + // get string length (in multibyte characters) + size_t GetMultiByteCharsLength() const; + + // Special conversion functions (multibyte <-> Unicode) +#ifdef SA_UNICODE + // return pointer to const UTF8 string + const char *GetUTF8Chars() const; + // get string length (in UTF8 characters) + size_t GetUTF8CharsLength() const; + // assing UTF8 data + void SetUTF8Chars(const char* szSrc, size_t nSrcLen = SIZE_MAX); +#endif // SA_UNICODE + // return pointer to const UTF16 string + const void *GetUTF16Chars() const; + // get string length (in UTF16 characters) + size_t GetUTF16CharsLength() const; + // assing UTF16 data + void SetUTF16Chars(const void* szSrc, size_t nSrcLen = SIZE_MAX); + + // Implementation +public: + ~SAString(); + +protected: + SAChar *m_pchData; // pointer to ref counted string data + + // implementation helpers + SAStringData *GetData() const; + void Init(); + void AllocBuffer(size_t nLen); +#ifdef SA_UNICODE + void AssignBinaryCopy(size_t nSrcLenInBytes, const void *pSrcData); + void ConcatBinaryCopy(size_t nSrc1LenInBytes, const void *pSrc1Data, size_t nSrc2LenInBytes, const void *pSrc2Data); + void ConcatBinaryInPlace(size_t nSrcLen, const void *pData); +#endif // SA_UNICODE + void AssignCopy(size_t nSrcLen, const SAChar *lpszSrcData); + void ConcatCopy(size_t nSrc1Len, const SAChar *lpszSrc1Data, size_t nSrc2Len, const SAChar *lpszSrc2Data); + void ConcatInPlace(size_t nSrcLen, const SAChar *lpszSrcData); + + void CopyBeforeWrite(); + void AllocBeforeWrite(size_t nLen); + void Release(); + static void Release(SAStringData *pData); + static size_t SafeStrlen(const SAChar *lpsz); + static void FreeData(SAStringData *pData); + +#ifdef SA_USE_STL +public: + SAString(const std::string &stringSrc); + SAString(const std::wstring &stringSrc); + const SAString &operator=(const std::string &stringSrc); + const SAString &operator=(const std::wstring &stringSrc); + const SAString &operator+=(const std::string &stringSrc); + const SAString &operator+=(const std::wstring &stringSrc); +#endif +}; + +// Compare helpers +bool SQLAPI_API operator==(const SAString &s1, const SAString &s2); +bool SQLAPI_API operator==(const SAString &s1, const SAChar *s2); +bool SQLAPI_API operator==(const SAChar *s1, const SAString &s2); +bool SQLAPI_API operator!=(const SAString &s1, const SAString &s2); +bool SQLAPI_API operator!=(const SAString &s1, const SAChar *s2); +bool SQLAPI_API operator!=(const SAChar *s1, const SAString &s2); +bool SQLAPI_API operator<(const SAString &s1, const SAString &s2); +bool SQLAPI_API operator<(const SAString &s1, const SAChar *s2); +bool SQLAPI_API operator<(const SAChar *s1, const SAString &s2); +bool SQLAPI_API operator>(const SAString &s1, const SAString &s2); +bool SQLAPI_API operator>(const SAString &s1, const SAChar *s2); +bool SQLAPI_API operator>(const SAChar *s1, const SAString &s2); +bool SQLAPI_API operator<=(const SAString &s1, const SAString &s2); +bool SQLAPI_API operator<=(const SAString &s1, const SAChar *s2); +bool SQLAPI_API operator<=(const SAChar *s1, const SAString &s2); +bool SQLAPI_API operator>=(const SAString &s1, const SAString &s2); +bool SQLAPI_API operator>=(const SAString &s1, const SAChar *s2); +bool SQLAPI_API operator>=(const SAChar *s1, const SAString &s2); + + +class SQLAPI_API SANull +{ +}; + +#define SA_NUMERIC_MANTISSA_SIZE 32 +class SQLAPI_API SANumeric +{ + void InitZero(); + bool setFromPlainString(const SAChar *sVal); + bool setFromExpString(const SAString &sVal); + +public: + SANumeric(); // default constructor, initializes to zero + + SANumeric(double dVal); // initializes from double + SANumeric &operator=(double); // reinitializes from double + operator double() const; // converts to double + + SANumeric(sa_int64_t iVal); // initializes from 64-bit integer + SANumeric(sa_uint64_t iVal); + SANumeric &operator=(sa_int64_t); // reinitializes from 64-bit integer + SANumeric &operator=(sa_uint64_t); + operator sa_int64_t() const; // converts to 64-bit integer + operator sa_uint64_t() const; + + SANumeric &operator=(const SAChar *sVal); // reinitializes from string + operator SAString() const; // converts to string + +public: + unsigned char precision; // the maximum number of digits in base 10 + unsigned char scale; // the number of digits to the right of the decimal point + unsigned char sign; // the sign: 1 for positive numbers, 0 for negative numbers + + // a number stored as SA_NUMERIC_MANTISSA_SIZE-byte scaled integer, with the least-significant byte on the left + unsigned char val[SA_NUMERIC_MANTISSA_SIZE]; +}; + +class SQLAPI_API SAInterval +{ +public: + SAInterval(); + SAInterval(double dVal); + SAInterval(long nDays, int nHours, int nMins, int nSecs); + + double GetTotalDays() const; + double GetTotalHours() const; + double GetTotalMinutes() const; + double GetTotalSeconds() const; + + long GetDays() const; + long GetHours() const; + long GetMinutes() const; + long GetSeconds() const; + + SAInterval& operator=(double dVal); + + SAInterval operator+(const SAInterval& interval) const; + SAInterval operator-(const SAInterval& interval) const; + SAInterval& operator+=(const SAInterval interval); + SAInterval& operator-=(const SAInterval interval); + SAInterval operator-() const; + + operator double() const; + + operator SAString() const; + + void SetInterval(long nDays, int nHours, int nMins, int nSecs); + +private: + double m_interval; +}; + +//! Provides support for manipulating date/time values +class SQLAPI_API SADateTime +{ + friend class SAValueRead; + + static int m_saMonthDays[13]; + +protected: + static bool DateFromTm( + unsigned short wYear, unsigned short wMonth, unsigned short wDay, + unsigned short wHour, unsigned short wMinute, unsigned short wSecond, + unsigned int nNanoSecond, + double &dtDest); + static bool TmFromDate( + double dtSrc, + struct tm &tmDest, unsigned int &nNanoSecond); + +protected: + void Init_Tm(); + struct tm m_tm; + unsigned int m_nFraction; // 0..999999999 + void setSADateTime(int nYear, int nMonth, int nDay, int nHour, int nMinute, int nSecond); +public: + SADateTime(); + SADateTime(int nYear, int nMonth, int nDay, int nHour, int nMin, int nSec); + SADateTime(char* dateTime); + SADateTime(const struct tm &tmValue); + SADateTime(double dt); +#ifndef UNDER_CE + SADateTime(const struct timeb &tmbValue); + SADateTime(const struct timeval &tmvValue); +#endif +#ifdef SQLAPI_WINDOWS + SADateTime(SYSTEMTIME &st); +#endif + SADateTime(const SADateTime &other); + + operator struct tm &(); + operator struct tm() const; + operator double() const; + operator SAString() const; + + int GetYear() const; // year, f.ex., 1999, 2000 + int GetMonth() const; // 1..12 + int GetDay() const; // 1..31 + int GetHour() const; // 0..23 + int GetMinute() const; // 0..59 + int GetSecond() const; // 0..59 + int GetDayOfWeek() const; // 1..7, 1=Sunday, 2=Monday, and so on + int GetDayOfYear() const; // 1..366, where January 1 = 1 + + unsigned int &Fraction(); + unsigned int Fraction() const; + +#ifndef UNDER_CE + void GetTimeValue(struct timeb &tmv); + void GetTimeValue(struct timeval &tmv); +#endif +#ifdef SQLAPI_WINDOWS + void GetTimeValue(SYSTEMTIME &st); +#endif + + //! Return the current date/time value + static SADateTime SQLAPI_CALLBACK currentDateTime(); + static SADateTime SQLAPI_CALLBACK currentDateTimeWithFraction(); + + SADateTime operator+(SAInterval interval) const; + SADateTime operator-(SAInterval interval) const; + SADateTime& operator+=(SAInterval interval); + SADateTime& operator-=(SAInterval interval); + + SAInterval operator-(const SADateTime& dt) const; +}; + +class SQLAPI_API SAPos +{ + friend class SACommand; + + SAString m_sName; + +public: + SAPos(int nByID); + SAPos(const SAString& sByName); +}; + +class SQLAPI_API saOptions +{ + int m_nOptionCount; + SAParam **m_ppOptions; + +private: + // disable copy constructor + saOptions(const saOptions &); + // disable assignment operator + saOptions &operator = (const saOptions &); + +public: + saOptions(); + virtual ~saOptions(); + + SAString &operator[](const SAString &sOptionName); + SAString operator[](const SAString &sOptionName) const; +}; + +//! Represents an unique session with a data source +class SQLAPI_API SAConnection +{ + friend class SACommand; + friend class SAField; + friend class SAParam; + friend class ISAConnection; + friend class Iora7Connection; + friend class Iora8Connection; + +private: + // disable copy constructor + SAConnection(const SAConnection &); + // disable assignment operator + SAConnection &operator = (const SAConnection &); + + SAClient_t m_eSAClient; + ISAConnection *m_pISAConnection; + SAMutex *m_pCommandsMutex; + sa_Commands *m_pCommands; + + SAIsolationLevel_t m_eIsolationLevel; + SAAutoCommit_t m_eAutoCommit; + + saOptions m_Options; + + int nReserved; + +protected: + void EnumCursors(EnumCursors_t fn, void *pAddlData); + void RegisterCommand(SACommand *pCommand); + void UnRegisterCommand(SACommand *pCommand); + ISACursor *GetISACursor(SACommand *pCommand); + +public: + SAConnection(); + virtual ~SAConnection(); + + void setClient(SAClient_t eSAClient) SQLAPI_THROW(SAException); + SAClient_t Client() const; + long ClientVersion() const SQLAPI_THROW(SAException); + long ServerVersion() const SQLAPI_THROW(SAException); + SAString ServerVersionString() const SQLAPI_THROW(SAException); + + bool isConnected() const; + bool isAlive() const; + void Connect( + const SAString &sDBString, + const SAString &sUserID, + const SAString &sPassword, + SAClient_t eSAClient = SA_Client_NotSpecified, + saConnectionHandler_t fHandler = NULL) SQLAPI_THROW(SAException); + void Disconnect() SQLAPI_THROW(SAException); + void Destroy(); + void Reset(); + + void setIsolationLevel(SAIsolationLevel_t eIsolationLevel) SQLAPI_THROW(SAException); + SAIsolationLevel_t IsolationLevel() const; + void setAutoCommit(SAAutoCommit_t eAutoCommit) SQLAPI_THROW(SAException); + SAAutoCommit_t AutoCommit() const; + void Commit() SQLAPI_THROW(SAException); + void Rollback() SQLAPI_THROW(SAException); + + SAString &setOption(const SAString &sOptionName); + SAString Option(const SAString &sOptionName) const; + + saAPI *NativeAPI() const SQLAPI_THROW(SAException); + saConnectionHandles *NativeHandles() SQLAPI_THROW(SAException); +}; + +// SAConnection options (common for at least several DBMS-es) +// Worksattion ID +#define SACON_OPTION_WSID _TSA("WSID") +// Application Name +#define SACON_OPTION_APPNAME _TSA("APPNAME") + +//! Defines a specific command that you intend to execute against a data source. +class SQLAPI_API SACommand +{ + friend class SAConnection; + friend class IibCursor; + friend class IsybCursor; + friend class IssDBLibCursor; + friend class IsbCursor; + friend class ImyCursor; + friend class IpgCursor; + friend class Iora8Connection; + friend class Iora8Cursor; + friend class Iora7Connection; + friend class Iora7Cursor; + //friend class SAValue; + +private: + // disable copy constructor + SACommand(const SACommand &); + // disable assignment operator + SACommand &operator = (const SACommand &); + + SAConnection *m_pConnection; + + SACommandType_t m_eCmdType; + SAString m_sCmd; + bool m_bPrepared; + bool m_bExecuted; + bool m_bFieldsDescribed; + bool m_bSelectBuffersSet; + + bool m_bParamsKnown; + int m_nPlaceHolderCount; + saPlaceHolder **m_ppPlaceHolders; + int m_nParamCount; + SAParam **m_ppParams; + int m_nMaxParamID; + SAParam **m_ppParamsID; + int m_nCurParamID; + SAString m_sCurParamName; + + int m_nFieldCount; + SAField **m_ppFields; + + saOptions m_Options; + + int nReserved; + + void Init(); + + static int CompareIdentifier( + const SAString &sIdentifier1, + const SAString &sIdentifier2); + SAParam &CreateParam( + const SAString &sName, + SADataType_t eParamType, + int nNativeType, + size_t nParamSize, + int nParamPrecision, + int nParamScale, + SAParamDirType_t eDirType, + const SAString &sFullName, + size_t nStart, // param position in SQL statement + size_t nEnd); // param end position in SQL statemen + void GetParamsSP(); + void UnDescribeParams(); + void ParseInputMarkers( + SAString &sCmd, + bool *pbSpacesInCmd); + + void DescribeFields() SQLAPI_THROW(SAException); + void CreateField( + const SAString &sName, + SADataType_t eFieldType, + int nNativeType, + size_t nFieldSize, + int nFieldPrecision, + int nFieldScale, + bool bFieldRequired); + void DestroyFields(); + + // parses sql statement and create bind parameters array if any (In) + // also cancels previous stsement if any + void ParseCmd( + const SAString &sSQL, + SACommandType_t eCmdType); + + void UnSetCommandText(); + void UnPrepare(); + void UnExecute(); + +public: + //! Construct command with no associated connection and SQL + SACommand(); + //! Construct command based on the given connection and SQL + SACommand( + SAConnection *pConnection, + const SAString &sCmd = SAString(), + SACommandType_t eCmdType = SA_CmdUnknown); + + virtual ~SACommand(); + + SAConnection *Connection() const; + void setConnection(SAConnection *pConnection); + + virtual void Open() SQLAPI_THROW(SAException); + virtual bool isOpened(); + virtual bool isExecuted(); + virtual void Close() SQLAPI_THROW(SAException); + virtual void Destroy(); + virtual void Reset(); + + void setCommandText( + const SAString &sSQL, + SACommandType_t eCmdType = SA_CmdUnknown); + SAString CommandText() const; + SACommandType_t CommandType() const; + virtual void Prepare() SQLAPI_THROW(SAException); + virtual void Execute() SQLAPI_THROW(SAException); + virtual void BatchExecute(char **pValues, int paramNum, int recNum) SQLAPI_THROW(SAException); + bool isResultSet() SQLAPI_THROW(SAException); + long RowsAffected() SQLAPI_THROW(SAException); // returns number of rows affected by last DML operation + bool FetchNext() SQLAPI_THROW(SAException); // returns true if new row is fetched + bool FetchPrior() SQLAPI_THROW(SAException); + bool FetchFirst() SQLAPI_THROW(SAException); + bool FetchLast() SQLAPI_THROW(SAException); + void Cancel() SQLAPI_THROW(SAException); + + SAParam &CreateParam( + const SAString &sName, + SADataType_t eParamType, + SAParamDirType_t eDirType = SA_ParamInput); + SAParam &CreateParam( + const SAString &sName, + SADataType_t eParamType, + int nNativeType, + size_t nParamSize, + int nParamPrecision, + int nParamScale, + SAParamDirType_t eDirType); + void DestroyParams(); + int ParamCount(); + SAParam &ParamByIndex(int i); // zero based index of C array + SAParam &Param(int nParamByID); // id in SQL statement, not in C array + SAParam &Param(const SAString& sParamByName); + SACommand &operator << (const SAPos &pos); + SACommand &operator << (const SANull &null); + SACommand &operator << (bool Value); + SACommand &operator << (short Value); + SACommand &operator << (unsigned short Value); + SACommand &operator << (long Value); + SACommand &operator << (unsigned long Value); + SACommand &operator << (double Value); + SACommand &operator << (const SANumeric &Value); + SACommand &operator << (sa_int64_t Value); + SACommand &operator << (sa_uint64_t Value); + SACommand &operator << (const SADateTime &Value); + SACommand &operator << (const SAChar *Value); // special overload for string constants + SACommand &operator << (const SAString &Value); + SACommand &operator << (const SABytes &Value); + SACommand &operator << (const SALongBinary &Value); + SACommand &operator << (const SALongChar &Value); + SACommand &operator << (const SABLob &Value); + SACommand &operator << (const SACLob &Value); + SACommand &operator << (const SAValueRead &Value); + + int FieldCount() SQLAPI_THROW(SAException); + SAField &Field(int nField) SQLAPI_THROW(SAException); // 1-based field number in result set + SAField &Field(const SAString &sField) SQLAPI_THROW(SAException); + SAField &operator[](int nField) SQLAPI_THROW(SAException); // 1-based field number in result set + SAField &operator[](const SAString &sField) SQLAPI_THROW(SAException); + + SAString &setOption(const SAString &sOptionName); + SAString Option(const SAString &sOptionName) const; + + saCommandHandles *NativeHandles() SQLAPI_THROW(SAException); + + void setBatchExceptionPreHandler(PreHandleException_t fnHandler); +}; + +// SACommand options (common for at least several DBMS-es) +// Prefertching rows +#define SACMD_PREFETCH_ROWS _TSA("PreFetchRows") +// Using scrollable cursor +#define SACMD_SCROLLABLE _TSA("Scrollable") + +class SQLAPI_API SAValueRead +{ + friend class ISACursor; + friend class IibCursor; + friend class Iora7Cursor; + friend class Iora8Cursor; + friend class IsbCursor; + friend class IodbcCursor; + friend class IssDBLibCursor; + friend class IssOleDbCursor; + friend class Idb2Cursor; + friend class IinfCursor; + friend class IsybCursor; + friend class ImyCursor; + friend class IpgCursor; + friend class Isl3Cursor; + friend class IssNCliCursor; + +protected: + SALongOrLobReaderModes_t m_eReaderMode; + + saLongOrLobReader_t m_fnReader; + size_t m_nReaderWantedPieceSize; + void *m_pReaderAddlData; + + unsigned char *m_pReaderBuf; + size_t m_nReaderAlloc; + size_t m_nExpectedSizeMax; + size_t m_nReaderRead; + size_t m_nPieceSize; + + size_t PrepareReader( + size_t nExpectedSizeMax, // to optimaze buf allocation for internal buffer, 0 = unknown + size_t nCallerMaxSize, // max Piece that can be proceeced by API + unsigned char *&pBuf, + saLongOrLobReader_t fnReader, + size_t nReaderWantedPieceSize, + void *pReaderAddlData, + bool bAddSpaceForNull = false); + void InvokeReader( + SAPieceType_t ePieceType, + unsigned char *&pBuf, + size_t nPieceLen); + SAString asLongOrLob() const; + +protected: + SADataType_t m_eDataType; + + // null indicator + bool *m_pbNull; + // scalar types + void *m_pScalar; + // an exact numeric value with a fixed precision and scale + SANumeric *m_pNumeric; + // Date time + SADateTime *m_pDateTime; + // Time interval + SAInterval *m_pInterval; + // variable length types (string, bytes, Longs and Lobs) + SAString *m_pString; + // Cursor + SACommand *m_pCursor; +private: + // null indicator + bool m_bInternalNull; + // scalar types + union uScalars + { + bool m_Bool; + short m_Short; + unsigned short m_uShort; + long m_Long; + unsigned long m_uLong; + double m_Double; + } m_InternalScalar; + SANumeric m_InternalNumeric; + SADateTime m_InternalDateTime; + SAInterval m_InternalInterval; + // variable length types (string, bytes, Longs and Lobs) + SAString m_InternalString; + // Cursor + SACommand m_InternalCursor; + +public: + SAValueRead(SADataType_t eDataType); + SAValueRead(const SAValueRead &vr); + virtual ~SAValueRead(); + + SAValueRead &operator =(const SAValueRead &vr); + +public: + SADataType_t DataType() const; + + // Null type + bool isNull() const; + + // scalar types + bool asBool() const; + short asShort() const; + unsigned short asUShort() const; + long asLong() const; + unsigned long asULong() const; + double asDouble() const; + + // numeric + SANumeric asNumeric() const; + + // date/time + SADateTime asDateTime() const; + + // Interval + SAInterval asInterval() const; + + // variable length types + SAString asString() const; + SAString asBytes() const; + SAString asLongBinary() const; + SAString asLongChar() const; + SAString asBLob() const; + SAString asCLob() const; + + // cursor + SACommand *asCursor() const; + + void setLongOrLobReaderMode(SALongOrLobReaderModes_t eMode); + SALongOrLobReaderModes_t LongOrLobReaderMode() const; + + // operators for quick accessing values + // do not inline to prevent varnings + operator bool() const; + operator short() const; + operator unsigned short() const; + operator long() const; + operator unsigned long() const; + operator double() const; + operator SANumeric() const; + operator SADateTime() const; + operator SAInterval() const; + operator SAString() const; + operator SACommand *() const; + + // data and indicator storage +public: + void setIndicatorStorage(bool *pStorage); + void setDataStorage(void *pStorage, SADataType_t eDataType); +}; + +class SQLAPI_API SAValue : public SAValueRead +{ + friend class ISACursor; + friend class IibCursor; + friend class IssDBLibCursor; + friend class Iora7Cursor; + friend class Iora8Cursor; + friend class IsbCursor; + friend class IodbcCursor; + friend class Idb2Cursor; + friend class IinfCursor; + friend class IsybCursor; + friend class ImyCursor; + friend class IpgCursor; + friend class Isl3Cursor; + friend class IssNCliCursor; + +private: + bool m_bInternalUseDefault; + +protected: + bool *m_pbUseDefault; + + saLongOrLobWriter_t m_fnWriter; + size_t m_nWriterSize; + void *m_pWriterAddlData; + void *m_pWriterBuf; + size_t m_nWriterAlloc; + size_t m_nWriterWritten; + + size_t InvokeWriter( + SAPieceType_t &ePieceType, + size_t nCallerMaxSize, + void *&pBuf); + +public: + SAValue(SADataType_t eDataType); + virtual ~SAValue(); + + // Sets NULL value + void setAsNull(); + // Sets a flag to use default value + void setAsDefault(); + // queries if "default value" flag is set + bool isDefault() const; + + void setAsUnknown(); + + // scalar types + bool &setAsBool(); + short &setAsShort(); + unsigned short &setAsUShort(); + long &setAsLong(); + unsigned long &setAsULong(); + double &setAsDouble(); + + // numeric + SANumeric &setAsNumeric(); + + // date/time + SADateTime &setAsDateTime(); + + // interval + SAInterval &setAsInterval(); + + // variable length types + SAString &setAsString(); + SAString &setAsBytes(); + SAString &setAsLongBinary( + saLongOrLobWriter_t fnWriter = NULL, + size_t nWriterSize = 0, void *pAddlData = NULL); + SAString &setAsLongChar( + saLongOrLobWriter_t fnWriter = NULL, + size_t nWriterSize = 0, void *pAddlData = NULL); + SAString &setAsBLob( + saLongOrLobWriter_t fnWriter = NULL, + size_t nWriterSize = 0, void *pAddlData = NULL); + SAString &setAsCLob( + saLongOrLobWriter_t fnWriter = NULL, + size_t nWriterSize = 0, void *pAddlData = NULL); + + // cursor + SACommand *&setAsCursor(); + + // special set function(s) + SAValueRead &setAsValueRead(); +}; + +class SQLAPI_API SAParam : public SAValue +{ + friend class SACommand; + friend class saPlaceHolder; + friend class saOptions; + + SACommand *m_pCommand; + + SAString m_sName; + SADataType_t m_eParamType; + int m_nNativeType; + size_t m_nParamSize; + int m_nParamPrecision; + int m_nParamScale; + SAParamDirType_t m_eDirType; + + saOptions m_Options; + +private: + // disable copy constructor + SAParam(const SAParam &); + // disable assignment operator + SAParam &operator = (const SAParam &); + +protected: + SAParam( + SACommand *pCommand, + const SAString &sName, + SADataType_t eParamType, + int nNativeType, + size_t nParamSize, + int nParamPrecision, + int nParamScale, + SAParamDirType_t eDirType); + virtual ~SAParam(); + +public: + const SAString &Name() const; + SADataType_t ParamType() const; + void setParamType(SADataType_t eParamType); + int ParamNativeType() const; + void setParamNativeType(int nNativeType); + size_t ParamSize() const; + void setParamSize(size_t nParamSize); + SAParamDirType_t ParamDirType() const; + void setParamDirType(SAParamDirType_t eParamDirType); + int ParamPrecision() const; + void setParamPrecision(int nParamPrecision); + int ParamScale() const; + void setParamScale(int nParamScale); + + void ReadLongOrLob( + saLongOrLobReader_t fnReader, + size_t nReaderWantedSize, + void *pAddlData); + + SAString &setOption(const SAString &sOptionName); + SAString Option(const SAString &sOptionName) const; +}; + +class SQLAPI_API saPlaceHolder +{ + friend class SACommand; + + SAString m_sFullName; + size_t m_nStart; + size_t m_nEnd; + + SAParam *m_pParamRef; + +private: + saPlaceHolder( + const SAString &sFullName, + size_t nStart, + size_t nEnd, + SAParam *pParamRef); + virtual ~saPlaceHolder(); + +public: + const SAString &getFullName() const; + size_t& getStart(); + size_t& getEnd(); + SAParam *getParam() const; +}; + +class SQLAPI_API SABytes : public SAString +{ +public: + SABytes(const SAString &sData); +}; + +class SQLAPI_API SALongOrLob : public SAString +{ + friend class SACommand; + +protected: + saLongOrLobWriter_t m_fnWriter; + size_t m_nWriterPieceSize; + void *m_pAddlData; + + SALongOrLob(const SAString &sData); + SALongOrLob( + saLongOrLobWriter_t fnWriter, + size_t nWriterPieceSize, + void *pAddlData); +}; + +class SQLAPI_API SALongBinary : public SALongOrLob +{ +public: + SALongBinary(const SAString &sData); + SALongBinary( + saLongOrLobWriter_t fnWriter, + size_t nWriterPieceSize, + void *pAddlData); +}; + +class SQLAPI_API SALongChar : public SALongOrLob +{ +public: + SALongChar(const SAString &sData); + SALongChar( + saLongOrLobWriter_t fnWriter, + size_t nWriterPieceSize, + void *pAddlData); +}; + +class SQLAPI_API SABLob : public SALongOrLob +{ +public: + SABLob(const SAString &sData); + SABLob( + saLongOrLobWriter_t fnWriter, + size_t nWriterPieceSize, + void *pAddlData); +}; + +class SQLAPI_API SACLob : public SALongOrLob +{ +public: + SACLob(const SAString &sData); + SACLob( + saLongOrLobWriter_t fnWriter, + unsigned int nWriterPieceSize, + void *pAddlData); +}; + +class SQLAPI_API SAField : public SAValueRead +{ + friend class SACommand; + + SACommand *m_pCommand; + + // as reported by describe API + int m_nPos; // 1-based + SAString m_sName; + SADataType_t m_eFieldType; + int m_nNativeType; + size_t m_nFieldSize; + int m_nFieldPrecision; + int m_nFieldScale; + bool m_bFieldRequired; + + saOptions m_Options; + +private: + // disable copy constructor + SAField(const SAField &); + // disable assignment operator + SAField &operator = (const SAField &); + +protected: + SAField( + SACommand *pCommand, + int nPos, // 1-based + const SAString &sName, + SADataType_t eFieldType, + int nNativeType, + size_t nFieldSize, + int nFieldPrecision, + int nFieldScale, + bool bFieldRequired); + virtual ~SAField(); + +public: + int Pos() const; + const SAString &Name() const; + SADataType_t FieldType() const; + int FieldNativeType() const; + size_t FieldSize() const; + int FieldPrecision() const; + int FieldScale() const; + bool isFieldRequired() const; + + // !!! + void setFieldSize(int nSize); + void setFieldType(SADataType_t eType); + + void ReadLongOrLob( + saLongOrLobReader_t fnReader, + size_t nReaderWantedSize, + void *pAddlData); + + SAString &setOption(const SAString &sOptionName); + SAString Option(const SAString &sOptionName) const; +}; + +class SQLAPI_API SAException +#ifdef SQLAPI_EXCEPTION_DELIVERED_FROM + : public SQLAPI_EXCEPTION_DELIVERED_FROM +#endif +{ + friend class SAConnection; + friend class SACommand; + friend class SAStoredProc; + friend class Iora7Connection; + friend class Iora8Connection; + friend class IibConnection; + friend class IodbcConnection; + friend class IsbConnection; + friend class Iss6Connection; + +public: + SAException( + SAErrorClass_t eError, + int nNativeError, + int nErrPos, + const SAString &sMsg); + SAException( + SAErrorClass_t eError, + int nNativeError, + int nErrPos, + const SAChar *lpszFormat, ...); + + SAException(const SAException &other); + +public: + virtual ~SAException(); + + static void SQLAPI_CALLBACK throwUserException( + int nUserCode, const SAChar *lpszFormat, ...); + + SAErrorClass_t ErrClass() const; + int ErrNativeCode() const; + int ErrPos() const; + SAString ErrText() const; + +#ifdef SQLAPI_EXCEPTION_HAS_CUSTOM_MEMBERS + SQLAPI_EXCEPTION_HAS_CUSTOM_MEMBERS +#endif + +protected: + SAErrorClass_t m_eErrorClass; + int m_nNativeError; + int m_nErrPos; + SAString m_sMsg; + + int nReserved; +}; + +class SQLAPI_API SAUserException : public SAException +{ + friend class SAException; + +protected: + SAUserException(int nUserCode, const SAString &sMsg); + +public: + virtual ~SAUserException(); +}; + +typedef enum eSATraceInfo +{ + SA_Trace_None = 0, + SA_Trace_QueryText = 1, //! trace real DBMS API query text SQLAPI++ sends +} SATraceInfo_t; + +//! Callback for tracing +typedef void (SQLAPI_CALLBACK *SATraceFunction_t)( + SATraceInfo_t traceInfo, //! tracing into label + SAConnection* pCon, //! related SAConnection or NULL + SACommand* pCmd, //! related SACommand or NULL + const SAChar* szTraceInfo, //! tracing text + void* pData); //! user provided data + +//! Global SQLAPI++ settings +class SQLAPI_API SAGlobals +{ +public: + static char * SQLAPI_CALLBACK setlocale(int category, const char *locale); + + static int GetVersionMajor(); + static int GetVersionMinor(); + static int GetVersionBuild(); + + static bool& UnloadAPI(); + + static const SAChar* ClientToString(SAClient_t eSAClient); + static SAClient_t StringToClient(const SAChar* szClientName); + + static void SetTraceFunction(SATraceInfo_t traceInfo, SATraceFunction_t traceFunc, void* pData); +}; + +#define SQLAPI_VER_MAJOR 4 +#define SQLAPI_VER_MINOR 1 +#define SQLAPI_VER_BUILD 2 + +#endif // !defined(__SQLAPI_H__) + + diff --git a/libodbc/include/db2API.h b/libodbc/include/db2API.h new file mode 100644 index 0000000000..e5a9b1bf6d --- /dev/null +++ b/libodbc/include/db2API.h @@ -0,0 +1,593 @@ +// db2API.h +// + +#if !defined(__DB2API_H__) +#define __DB2API_H__ + +#include "SQLAPI.h" +#include +#include + +extern long g_nDB2DLLVersionLoaded; + +extern void AddDB2Support(const SAConnection * pCon); +extern void ReleaseDB2Support(); + +typedef SQLRETURN (SQL_API_FN *SQLAllocConnect_t)(SQLHENV henv, + SQLHDBC FAR *phdbc); +typedef SQLRETURN (SQL_API_FN *SQLAllocEnv_t)(SQLHENV FAR *phenv); +typedef SQLRETURN (SQL_API_FN *SQLAllocHandle_t)( SQLSMALLINT fHandleType, + SQLHANDLE hInput, + SQLHANDLE * phOutput ); +typedef SQLRETURN (SQL_API_FN *SQLAllocStmt_t)(SQLHDBC hdbc, + SQLHSTMT FAR *phstmt); +typedef SQLRETURN (SQL_API_FN *SQLBindCol_t)(SQLHSTMT hstmt, + SQLUSMALLINT icol, + SQLSMALLINT fCType, + SQLPOINTER rgbValue, + SQLLEN cbValueMax, + SQLLEN FAR *pcbValue); +typedef SQLRETURN (SQL_API_FN *SQLBindFileToCol_t)(SQLHSTMT hstmt, + SQLUSMALLINT icol, + SQLCHAR FAR *FileName, + SQLSMALLINT FAR *FileNameLength, + SQLUINTEGER FAR *FileOptions, + SQLSMALLINT MaxFileNameLength, + SQLINTEGER FAR *StringLength, + SQLINTEGER FAR *IndicatorValue); +typedef SQLRETURN (SQL_API_FN *SQLBindFileToParam_t)(SQLHSTMT hstmt, + SQLUSMALLINT ipar, + SQLSMALLINT fSqlType, + SQLCHAR FAR *FileName, + SQLSMALLINT FAR *FileNameLength, + SQLUINTEGER FAR *FileOptions, + SQLSMALLINT MaxFileNameLength, + SQLINTEGER FAR *IndicatorValue); +typedef SQLRETURN (SQL_API *SQLBindParameter_t)( + SQLHSTMT hstmt, + SQLUSMALLINT ipar, + SQLSMALLINT fParamType, + SQLSMALLINT fCType, + SQLSMALLINT fSqlType, + SQLULEN cbColDef, + SQLSMALLINT ibScale, + SQLPOINTER rgbValue, + SQLLEN cbValueMax, + SQLLEN *pcbValue); + +typedef SQLRETURN (SQL_API *SQLBrowseConnect_t)( + SQLHDBC hdbc, + SQLTCHAR *szConnStrIn, + SQLSMALLINT cbConnStrIn, + SQLTCHAR *szConnStrOut, + SQLSMALLINT cbConnStrOutMax, + SQLSMALLINT *pcbConnStrOut); +typedef SQLRETURN (SQL_API_FN *SQLBuildDataLink_t)( SQLHSTMT hStmt, + SQLCHAR FAR * pszLinkType, + SQLINTEGER cbLinkType, + SQLCHAR FAR * pszDataLocation, + SQLINTEGER cbDataLocation, + SQLCHAR FAR * pszComment, + SQLINTEGER cbComment, + SQLCHAR FAR * pDataLink, + SQLINTEGER cbDataLinkMax, + SQLINTEGER FAR * pcbDataLink ); +typedef SQLRETURN (SQL_API *SQLBulkOperations_t)( + SQLHSTMT StatementHandle, + SQLSMALLINT Operation); +typedef SQLRETURN (SQL_API_FN *SQLCancel_t)(SQLHSTMT hstmt); +typedef SQLRETURN (SQL_API_FN *SQLCloseCursor_t)( SQLHSTMT hStmt ); +#ifdef ODBC64 +typedef SQLRETURN (SQL_API_FN *SQLColAttribute_t)(SQLHSTMT hstmt, + SQLUSMALLINT icol, + SQLUSMALLINT fDescType, + SQLPOINTER rgbDesc, + SQLSMALLINT cbDescMax, + SQLSMALLINT FAR *pcbDesc, + SQLLEN *pfDesc); +#else +typedef SQLRETURN (SQL_API_FN *SQLColAttribute_t)(SQLHSTMT hstmt, + SQLUSMALLINT icol, + SQLUSMALLINT fDescType, + SQLPOINTER rgbDesc, + SQLSMALLINT cbDescMax, + SQLSMALLINT FAR *pcbDesc, + SQLPOINTER pfDesc); +#endif +typedef SQLRETURN (SQL_API *SQLColAttributes_t)( + SQLHSTMT hstmt, + SQLUSMALLINT icol, + SQLUSMALLINT fDescType, + SQLPOINTER rgbDesc, + SQLSMALLINT cbDescMax, + SQLSMALLINT *pcbDesc, + SQLLEN *pfDesc); +typedef SQLRETURN (SQL_API *SQLColumnPrivileges_t)( + SQLHSTMT hstmt, + SQLTCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLTCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLTCHAR *szTableName, + SQLSMALLINT cbTableName, + SQLTCHAR *szColumnName, + SQLSMALLINT cbColumnName); +typedef SQLRETURN (SQL_API_FN *SQLColumns_t)(SQLHSTMT hstmt, + SQLTCHAR FAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLTCHAR FAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLTCHAR FAR *szTableName, + SQLSMALLINT cbTableName, + SQLTCHAR FAR *szColumnName, + SQLSMALLINT cbColumnName); +typedef SQLRETURN (SQL_API_FN *SQLConnect_t)(SQLHDBC hdbc, + SQLTCHAR FAR *szDSN, + SQLSMALLINT cbDSN, + SQLTCHAR FAR *szUID, + SQLSMALLINT cbUID, + SQLTCHAR FAR *szAuthStr, + SQLSMALLINT cbAuthStr); +typedef SQLRETURN (SQL_API_FN *SQLCopyDesc_t)( SQLHDESC hDescSource, + SQLHDESC hDescTarget ); +typedef SQLRETURN (SQL_API_FN *SQLDataSources_t)(SQLHENV henv, + SQLUSMALLINT fDirection, + SQLTCHAR FAR *szDSN, + SQLSMALLINT cbDSNMax, + SQLSMALLINT FAR *pcbDSN, + SQLTCHAR FAR *szDescription, + SQLSMALLINT cbDescriptionMax, + SQLSMALLINT FAR *pcbDescription); +typedef SQLRETURN (SQL_API *SQLDescribeCol_t)(SQLHSTMT StatementHandle, + SQLUSMALLINT ColumnNumber, SQLTCHAR *ColumnName, + SQLSMALLINT BufferLength, SQLSMALLINT *NameLength, + SQLSMALLINT *DataType, SQLULEN *ColumnSize, + SQLSMALLINT *DecimalDigits, SQLSMALLINT *Nullable); +typedef SQLRETURN (SQL_API *SQLDescribeParam_t)( + SQLHSTMT hstmt, + SQLUSMALLINT ipar, + SQLSMALLINT *pfSqlType, + SQLULEN *pcbParamDef, + SQLSMALLINT *pibScale, + SQLSMALLINT *pfNullable); +typedef SQLRETURN (SQL_API *SQLDisconnect_t)(SQLHDBC ConnectionHandle); +typedef SQLRETURN (SQL_API *SQLDriverConnect_t)( + SQLHDBC hdbc, + SQLHWND hwnd, + SQLTCHAR *szConnStrIn, + SQLSMALLINT cbConnStrIn, + SQLTCHAR *szConnStrOut, + SQLSMALLINT cbConnStrOutMax, + SQLSMALLINT *pcbConnStrOut, + SQLUSMALLINT fDriverCompletion); +typedef SQLRETURN (SQL_API *SQLEndTran_t)(SQLSMALLINT HandleType, SQLHANDLE Handle, + SQLSMALLINT CompletionType); +typedef SQLRETURN (SQL_API_FN *SQLError_t)(SQLHENV henv, + SQLHDBC hdbc, + SQLHSTMT hstmt, + SQLTCHAR FAR *szSqlState, + SQLINTEGER FAR *pfNativeError, + SQLTCHAR FAR *szErrorMsg, + SQLSMALLINT cbErrorMsgMax, + SQLSMALLINT FAR *pcbErrorMsg); + +typedef SQLRETURN (SQL_API_FN *SQLExecDirect_t)(SQLHSTMT hstmt, + SQLTCHAR FAR *szSqlStr, + SQLINTEGER cbSqlStr); +typedef SQLRETURN (SQL_API_FN *SQLExecute_t)(SQLHSTMT hstmt); +typedef SQLRETURN (SQL_API_FN *SQLExtendedBind_t)(SQLHSTMT hstmt, + SQLSMALLINT fBindCol, + SQLSMALLINT cRecords, + SQLSMALLINT * pfCType, + SQLPOINTER * rgbValue, + SQLINTEGER * cbValueMax, + SQLUINTEGER * puiPrecisionCType, + SQLSMALLINT * psScaleCType, + SQLINTEGER ** pcbValue, + SQLINTEGER ** piIndicatorPtr, + SQLSMALLINT * pfParamType, + SQLSMALLINT * pfSQLType, + SQLUINTEGER * pcbColDef, + SQLSMALLINT * pibScale ); +typedef SQLRETURN (SQL_API *SQLExtendedFetch_t)( + SQLHSTMT hstmt, + SQLUSMALLINT fFetchType, + SQLLEN irow, + SQLULEN *pcrow, + SQLUSMALLINT *rgfRowStatus); +typedef SQLRETURN (SQL_API_FN *SQLExtendedPrepare_t)( SQLHSTMT hstmt, + SQLTCHAR * pszSqlStmt, + SQLINTEGER cbSqlStmt, + SQLINTEGER cPars, + SQLSMALLINT sStmtType, + SQLINTEGER cStmtAttrs, + SQLINTEGER * piStmtAttr, + SQLINTEGER * pvParams ); +typedef SQLRETURN (SQL_API_FN *SQLFetch_t)(SQLHSTMT hstmt); +typedef SQLRETURN (SQL_API *SQLFetchScroll_t)( SQLHSTMT StatementHandle, + SQLSMALLINT FetchOrientation, + SQLLEN FetchOffset); +typedef SQLRETURN (SQL_API *SQLForeignKeys_t)( + SQLHSTMT hstmt, + SQLTCHAR *szPkCatalogName, + SQLSMALLINT cbPkCatalogName, + SQLTCHAR *szPkSchemaName, + SQLSMALLINT cbPkSchemaName, + SQLTCHAR *szPkTableName, + SQLSMALLINT cbPkTableName, + SQLTCHAR *szFkCatalogName, + SQLSMALLINT cbFkCatalogName, + SQLTCHAR *szFkSchemaName, + SQLSMALLINT cbFkSchemaName, + SQLTCHAR *szFkTableName, + SQLSMALLINT cbFkTableName); +typedef SQLRETURN (SQL_API_FN *SQLFreeConnect_t)(SQLHDBC hdbc); +typedef SQLRETURN (SQL_API_FN *SQLFreeEnv_t)(SQLHENV henv); +typedef SQLRETURN (SQL_API_FN *SQLFreeHandle_t)( SQLSMALLINT fHandleType, + SQLHANDLE hHandle ); +typedef SQLRETURN (SQL_API_FN *SQLFreeStmt_t)(SQLHSTMT hstmt, + SQLUSMALLINT fOption); +typedef SQLRETURN (SQL_API *SQLGetConnectAttr_t)( SQLHDBC ConnectionHandle, + SQLINTEGER Attribute, + SQLPOINTER Value, + SQLINTEGER BufferLength, + SQLINTEGER *StringLength); +typedef SQLRETURN (SQL_API_FN *SQLGetConnectOption_t)( + SQLHDBC hdbc, + SQLUSMALLINT fOption, + SQLPOINTER pvParam); +typedef SQLRETURN (SQL_API_FN *SQLGetCursorName_t)(SQLHSTMT hstmt, + SQLTCHAR FAR *szCursor, + SQLSMALLINT cbCursorMax, + SQLSMALLINT FAR *pcbCursor); +typedef SQLRETURN (SQL_API_FN *SQLGetData_t)(SQLHSTMT hstmt, + SQLUSMALLINT icol, + SQLSMALLINT fCType, + SQLPOINTER rgbValue, + SQLLEN cbValueMax, + SQLLEN FAR *pcbValue); +typedef SQLRETURN (SQL_API_FN *SQLGetDataLinkAttr_t)( SQLHSTMT hStmt, + SQLSMALLINT fAttrType, + SQLCHAR FAR * pDataLink, + SQLINTEGER cbDataLink, + SQLPOINTER pAttribute, + SQLINTEGER cbAttributeMax, + SQLINTEGER * pcbAttribute ); +typedef SQLRETURN (SQL_API_FN *SQLGetDescField_t)(SQLHDESC DescriptorHandle, + SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier, + SQLPOINTER Value, SQLINTEGER BufferLength, + SQLINTEGER *StringLength); +typedef SQLRETURN (SQL_API_FN *SQLGetDescRec_t)(SQLHDESC DescriptorHandle, + SQLSMALLINT RecNumber, SQLTCHAR *Name, + SQLSMALLINT BufferLength, SQLSMALLINT *StringLength, + SQLSMALLINT *Type, SQLSMALLINT *SubType, + SQLLEN *Length, SQLSMALLINT *Precision, + SQLSMALLINT *Scale, SQLSMALLINT *Nullable); +typedef SQLRETURN (SQL_API_FN *SQLGetDiagField_t)( SQLSMALLINT fHandleType, + SQLHANDLE hHandle, + SQLSMALLINT iRecNumber, + SQLSMALLINT fDiagIdentifier, + SQLPOINTER pDiagInfo, + SQLSMALLINT cbDiagInfoMax, + SQLSMALLINT * pcbDiagInfo ); +typedef SQLRETURN (SQL_API_FN *SQLGetDiagRec_t)( SQLSMALLINT fHandleType, + SQLHANDLE hHandle, + SQLSMALLINT iRecNumber, + SQLTCHAR * pszSqlState, + SQLINTEGER * pfNativeError, + SQLTCHAR * pszErrorMsg, + SQLSMALLINT cbErrorMsgMax, + SQLSMALLINT * pcbErrorMsg ); + +typedef SQLRETURN (SQL_API_FN *SQLGetEnvAttr_t)(SQLHENV henv, + SQLINTEGER Attribute, + SQLPOINTER Value, + SQLINTEGER BufferLength, + SQLINTEGER FAR *StringLength); +typedef SQLRETURN (SQL_API_FN *SQLGetFunctions_t)(SQLHDBC hdbc, + SQLUSMALLINT fFunction, + SQLUSMALLINT FAR *pfExists); +typedef SQLRETURN (SQL_API_FN *SQLGetInfo_t)(SQLHDBC hdbc, + SQLUSMALLINT fInfoType, + SQLPOINTER rgbInfoValue, + SQLSMALLINT cbInfoValueMax, + SQLSMALLINT FAR *pcbInfoValue); +typedef SQLRETURN (SQL_API_FN *SQLGetLength_t)(SQLHSTMT hstmt, + SQLSMALLINT LocatorCType, + SQLINTEGER Locator, + SQLINTEGER FAR *StringLength, + SQLINTEGER FAR *IndicatorValue); +typedef SQLRETURN (SQL_API_FN *SQLGetPosition_t)(SQLHSTMT hstmt, + SQLSMALLINT LocatorCType, + SQLINTEGER SourceLocator, + SQLINTEGER SearchLocator, + SQLCHAR FAR *SearchLiteral, + SQLINTEGER SearchLiteralLength, + SQLUINTEGER FromPosition, + SQLUINTEGER FAR *LocatedAt, + SQLINTEGER FAR *IndicatorValue); +typedef SQLRETURN (SQL_API_FN *SQLGetSQLCA_t)(SQLHENV henv, + SQLHDBC hdbc, + SQLHSTMT hstmt, + struct sqlca FAR *pSqlca ); +typedef SQLRETURN (SQL_API *SQLGetStmtAttr_t)( SQLHSTMT StatementHandle, + SQLINTEGER Attribute, + SQLPOINTER Value, + SQLINTEGER BufferLength, + SQLINTEGER *StringLength); +typedef SQLRETURN (SQL_API_FN *SQLGetStmtOption_t)(SQLHSTMT hstmt, + SQLUSMALLINT fOption, + SQLPOINTER pvParam); +typedef SQLRETURN (SQL_API_FN *SQLGetSubString_t)(SQLHSTMT hstmt, + SQLSMALLINT LocatorCType, + SQLINTEGER SourceLocator, + SQLUINTEGER FromPosition, + SQLUINTEGER ForLength, + SQLSMALLINT TargetCType, + SQLPOINTER rgbValue, + SQLINTEGER cbValueMax, + SQLINTEGER FAR *StringLength, + SQLINTEGER FAR *IndicatorValue); +typedef SQLRETURN (SQL_API_FN *SQLGetTypeInfo_t)(SQLHSTMT hstmt, + SQLSMALLINT fSqlType); +typedef SQLRETURN (SQL_API *SQLMoreResults_t)( + SQLHSTMT hstmt); +typedef SQLRETURN (SQL_API *SQLNativeSql_t)( + SQLHDBC hdbc, + SQLTCHAR *szSqlStrIn, + SQLINTEGER cbSqlStrIn, + SQLTCHAR *szSqlStr, + SQLINTEGER cbSqlStrMax, + SQLINTEGER *pcbSqlStr); +typedef SQLRETURN (SQL_API *SQLNumParams_t)( + SQLHSTMT hstmt, + SQLSMALLINT *pcpar); +typedef SQLRETURN (SQL_API_FN *SQLNumResultCols_t)(SQLHSTMT hstmt, + SQLSMALLINT FAR *pccol); +typedef SQLRETURN (SQL_API_FN *SQLParamData_t)(SQLHSTMT hstmt, + SQLPOINTER FAR *prgbValue); +typedef SQLRETURN (SQL_API *SQLParamOptions_t)( + SQLHSTMT hstmt, + SQLULEN crow, + SQLULEN *pirow); +typedef SQLRETURN (SQL_API_FN *SQLPrepare_t)(SQLHSTMT hstmt, + SQLTCHAR FAR *szSqlStr, + SQLINTEGER cbSqlStr); + +typedef SQLRETURN (SQL_API *SQLPrimaryKeys_t)( + SQLHSTMT hstmt, + SQLTCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLTCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLTCHAR *szTableName, + SQLSMALLINT cbTableName); +typedef SQLRETURN (SQL_API *SQLProcedureColumns_t)( + SQLHSTMT hstmt, + SQLTCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLTCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLTCHAR *szProcName, + SQLSMALLINT cbProcName, + SQLTCHAR *szColumnName, + SQLSMALLINT cbColumnName); +typedef SQLRETURN (SQL_API *SQLProcedures_t)( + SQLHSTMT hstmt, + SQLTCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLTCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLTCHAR *szProcName, + SQLSMALLINT cbProcName); +typedef SQLRETURN (SQL_API_FN *SQLPutData_t)(SQLHSTMT hstmt, + SQLPOINTER rgbValue, + SQLLEN cbValue); +typedef SQLRETURN (SQL_API_FN *SQLRowCount_t)(SQLHSTMT hstmt, + SQLLEN FAR *pcrow); +typedef SQLRETURN (SQL_API_FN *SQLSetColAttributes_t)(SQLHSTMT hstmt, + SQLUSMALLINT icol, + SQLCHAR FAR *pszColName, + SQLSMALLINT cbColName, + SQLSMALLINT fSQLType, + SQLUINTEGER cbColDef, + SQLSMALLINT ibScale, + SQLSMALLINT fNullable); +typedef SQLRETURN (SQL_API_FN *SQLSetConnectAttr_t)( + SQLHDBC hdbc, + SQLINTEGER fOption, + SQLPOINTER pvParam, + SQLINTEGER fStrLen); +typedef SQLRETURN (SQL_API_FN *SQLSetConnection_t)(SQLHDBC hdbc); +typedef SQLRETURN (SQL_API_FN *SQLSetConnectOption_t)( + SQLHDBC hdbc, + SQLUSMALLINT fOption, + SQLULEN vParam); +typedef SQLRETURN (SQL_API_FN *SQLSetCursorName_t)(SQLHSTMT hstmt, + SQLTCHAR FAR *szCursor, + SQLSMALLINT cbCursor); +typedef SQLRETURN (SQL_API_FN *SQLSetDescField_t)(SQLHDESC DescriptorHandle, + SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier, + SQLPOINTER Value, SQLINTEGER BufferLength); +typedef SQLRETURN (SQL_API_FN *SQLSetDescRec_t)(SQLHDESC DescriptorHandle, + SQLSMALLINT RecNumber, SQLSMALLINT Type, + SQLSMALLINT SubType, SQLLEN Length, + SQLSMALLINT Precision, SQLSMALLINT Scale, + SQLPOINTER Data, SQLLEN *StringLength, + SQLLEN *Indicator); +typedef SQLRETURN (SQL_API_FN *SQLSetEnvAttr_t)(SQLHENV henv, + SQLINTEGER Attribute, + SQLPOINTER Value, + SQLINTEGER StringLength); +typedef SQLRETURN (SQL_API_FN *SQLSetParam_t)(SQLHSTMT hstmt, + SQLUSMALLINT ipar, + SQLSMALLINT fCType, + SQLSMALLINT fSqlType, + SQLULEN cbParamDef, + SQLSMALLINT ibScale, + SQLPOINTER rgbValue, + SQLLEN FAR *pcbValue); +typedef SQLRETURN (SQL_API *SQLSetPos_t)( + SQLHSTMT hstmt, + SQLSETPOSIROW irow, + SQLUSMALLINT fOption, + SQLUSMALLINT fLock); +typedef SQLRETURN (SQL_API_FN *SQLSetStmtAttr_t)(SQLHSTMT hstmt, + SQLINTEGER fOption, + SQLPOINTER pvParam, + SQLINTEGER fStrLen); +typedef SQLRETURN (SQL_API_FN *SQLSetStmtOption_t)(SQLHSTMT hstmt, + SQLUSMALLINT fOption, + SQLULEN vParam); +typedef SQLRETURN (SQL_API_FN *SQLSpecialColumns_t)(SQLHSTMT hstmt, + SQLUSMALLINT fColType, + SQLTCHAR FAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLTCHAR FAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLTCHAR FAR *szTableName, + SQLSMALLINT cbTableName, + SQLUSMALLINT fScope, + SQLUSMALLINT fNullable); +typedef SQLRETURN (SQL_API_FN *SQLStatistics_t)(SQLHSTMT hstmt, + SQLTCHAR FAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLTCHAR FAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLTCHAR FAR *szTableName, + SQLSMALLINT cbTableName, + SQLUSMALLINT fUnique, + SQLUSMALLINT fAccuracy); +typedef SQLRETURN (SQL_API *SQLTablePrivileges_t)( + SQLHSTMT hstmt, + SQLTCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLTCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLTCHAR *szTableName, + SQLSMALLINT cbTableName); +typedef SQLRETURN (SQL_API_FN *SQLTables_t)(SQLHSTMT hstmt, + SQLTCHAR FAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLTCHAR FAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLTCHAR FAR *szTableName, + SQLSMALLINT cbTableName, + SQLTCHAR FAR *szTableType, + SQLSMALLINT cbTableType); +typedef SQLRETURN (SQL_API_FN *SQLTransact_t)(SQLHENV henv, + SQLHDBC hdbc, + SQLUSMALLINT fType); + + +class SQLAPI_API db2API : public saAPI +{ +public: + db2API(); + + SQLAllocConnect_t SQLAllocConnect; + SQLAllocEnv_t SQLAllocEnv; + SQLAllocHandle_t SQLAllocHandle; + SQLAllocStmt_t SQLAllocStmt; + SQLBindCol_t SQLBindCol; + SQLBindFileToCol_t SQLBindFileToCol; + SQLBindFileToParam_t SQLBindFileToParam; + SQLBindParameter_t SQLBindParameter; + SQLBrowseConnect_t SQLBrowseConnect; + SQLBulkOperations_t SQLBulkOperations; + SQLCancel_t SQLCancel; + SQLCloseCursor_t SQLCloseCursor; + SQLColAttribute_t SQLColAttribute; + SQLColAttributes_t SQLColAttributes; + SQLColumnPrivileges_t SQLColumnPrivileges; + SQLColumns_t SQLColumns; + SQLConnect_t SQLConnect; + SQLCopyDesc_t SQLCopyDesc; + SQLDataSources_t SQLDataSources; + SQLDescribeCol_t SQLDescribeCol; + SQLDescribeParam_t SQLDescribeParam; + SQLDisconnect_t SQLDisconnect; + SQLDriverConnect_t SQLDriverConnect; + SQLEndTran_t SQLEndTran; + SQLError_t SQLError; + SQLExecDirect_t SQLExecDirect; + SQLExecute_t SQLExecute; + SQLExtendedBind_t SQLExtendedBind; + SQLExtendedFetch_t SQLExtendedFetch; + SQLExtendedPrepare_t SQLExtendedPrepare; + SQLFetch_t SQLFetch; + SQLFetchScroll_t SQLFetchScroll; + SQLForeignKeys_t SQLForeignKeys; + SQLFreeConnect_t SQLFreeConnect; + SQLFreeEnv_t SQLFreeEnv; + SQLFreeHandle_t SQLFreeHandle; + SQLFreeStmt_t SQLFreeStmt; + SQLGetConnectAttr_t SQLGetConnectAttr; + SQLGetConnectOption_t SQLGetConnectOption; + SQLGetCursorName_t SQLGetCursorName; + SQLGetData_t SQLGetData; + SQLGetDescField_t SQLGetDescField; + SQLGetDescRec_t SQLGetDescRec; + SQLGetDiagField_t SQLGetDiagField; + SQLGetDiagRec_t SQLGetDiagRec; + SQLGetEnvAttr_t SQLGetEnvAttr; + SQLGetFunctions_t SQLGetFunctions; + SQLGetInfo_t SQLGetInfo; + SQLGetLength_t SQLGetLength; + SQLGetPosition_t SQLGetPosition; + SQLGetSQLCA_t SQLGetSQLCA; + SQLGetStmtAttr_t SQLGetStmtAttr; + SQLGetStmtOption_t SQLGetStmtOption; + SQLGetSubString_t SQLGetSubString; + SQLGetTypeInfo_t SQLGetTypeInfo; + SQLMoreResults_t SQLMoreResults; + SQLNativeSql_t SQLNativeSql; + SQLNumParams_t SQLNumParams; + SQLNumResultCols_t SQLNumResultCols; + SQLParamData_t SQLParamData; + SQLParamOptions_t SQLParamOptions; + SQLPrepare_t SQLPrepare; + SQLPrimaryKeys_t SQLPrimaryKeys; + SQLProcedureColumns_t SQLProcedureColumns; + SQLProcedures_t SQLProcedures; + SQLPutData_t SQLPutData; + SQLRowCount_t SQLRowCount; + SQLSetColAttributes_t SQLSetColAttributes; + SQLSetConnectAttr_t SQLSetConnectAttr; + SQLSetConnection_t SQLSetConnection; + SQLSetConnectOption_t SQLSetConnectOption; + SQLSetCursorName_t SQLSetCursorName; + SQLSetDescField_t SQLSetDescField; + SQLSetDescRec_t SQLSetDescRec; + SQLSetEnvAttr_t SQLSetEnvAttr; + SQLSetParam_t SQLSetParam; + SQLSetPos_t SQLSetPos; + SQLSetStmtAttr_t SQLSetStmtAttr; + SQLSetStmtOption_t SQLSetStmtOption; + SQLSpecialColumns_t SQLSpecialColumns; + SQLStatistics_t SQLStatistics; + SQLTablePrivileges_t SQLTablePrivileges; + SQLTables_t SQLTables; + SQLTransact_t SQLTransact; +}; + +class SQLAPI_API db2ConnectionHandles : public saConnectionHandles +{ +public: + db2ConnectionHandles(); + + SQLHENV m_hevn; + SQLHDBC m_hdbc; +}; + +class SQLAPI_API db2CommandHandles : public saCommandHandles +{ +public: + db2CommandHandles(); + + SQLHSTMT m_hstmt; +}; + +extern db2API g_db2API; + +#endif // !defined(__DB2API_H__) diff --git a/libodbc/include/db2_linux/sql.h b/libodbc/include/db2_linux/sql.h new file mode 100644 index 0000000000..9a9fd9fb2c --- /dev/null +++ b/libodbc/include/db2_linux/sql.h @@ -0,0 +1,2839 @@ +/****************************************************************************** +** +** Source File Name: SQL +** +** (C) COPYRIGHT International Business Machines Corp. 1987, 2006 +** All Rights Reserved +** Licensed Materials - Property of IBM +** +** US Government Users Restricted Rights - Use, duplication or +** disclosure restricted by GSA ADP Schedule Contract with IBM Corp. +** +** Function = Include File defining: +** System Constants +** National Language Support Information +** SQLCA / SQLDA Constants +** Interface to BINDER and PRECOMPILER +** Error Message Retrieval Interface +** Authorization Constants +** +** Operating System: LINUX +** +*******************************************************************************/ +#ifndef SQL_H_SQL +#define SQL_H_SQL + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Note: _SQLOLDCHAR defaults to 'char'. See sqlsystm.h for details. */ + +#include +#include "sqlsystm.h" /* System dependent defines */ + +#ifndef SQLCODE +#include "sqlca.h" /* Required include file */ +#endif + + +/* Release Identifier Constants */ + +#define SQL_RELPRE6 0 /* Pre Version 6.1.0.0 */ +#define SQL_REL6100 6010000 /* V6.1.0.0 */ +#define SQL_REL7100 7010000 /* V7.1.0.0 */ +#define SQL_REL7102 7010200 /* V7.1.2.0 */ +#define SQL_REL7200 7020100 /* V7.2.0.0 */ +#define SQL_REL7201 7020200 /* V7.2.1.0 */ +#define SQL_REL7204 7020400 /* V7.2.4.0 */ +#define SQL_REL8100 8010000 /* V8.1.0.0 */ +#define SQL_REL8101 8010100 /* V8.1.1.0 */ +#define SQL_REL8102 8010200 /* V8.1.2.0 */ +#define SQL_REL8103 8010300 /* V8.1.3.0 */ +#define SQL_REL8104 8010400 /* V8.1.4.0 */ +#define SQL_REL8105 8010500 /* V8.1.5.0 */ +#define SQL_REL8106 8010600 /* V8.1.6.0 */ +#define SQL_REL8200 8020000 /* V8.2.0.0 */ +#define SQL_REL8201 8020100 /* V8.2.1.0 */ +#define SQL_REL8202 8020200 /* V8.2.2.0 */ +#define SQL_REL9000 9000000 /* V9.0.0.0 */ +#define SQL_REL9100 9010000 /* V9.1.0.0 */ +#define SQL_FUTUREL 9999999 /* Future Release */ + +/* System Constants */ + +#ifndef SQL_RC_OK +#define SQL_RC_OK 0 /* successful execution */ +#endif + +#define SQL_KEYPMAX 64 /* Maximum nbr of key parts in Index */ +#define SQL_KEYLMAX 8192 /* Maximum key length */ +#define SQL_KEYLMAX_4KPAGE 1024 /* Maximum key length for 4K page */ +#define SQL_KEYLMAX_8KPAGE 2048 /* Maximum key length for 8K page */ +#define SQL_KEYLMAX_16KPAGE 4096 /* Maximum key length for 16K page */ +#define SQL_KEYLMAX_32KPAGE 8192 /* Maximum key length for 32K page */ +#define SQL_SORTFLDLMT 32677 /* Maximum size of field for sort */ +#define SQL_MAXRECL_4K 4005 /* Maximum record length on a 4K page */ +#define SQL_MAXRECL_8K 8101 /* Maximum record length on a 8K page */ +#define SQL_MAXRECL 32677 /* Maximum record length */ +#define SQL_MAXTABLES 15 /* Maximum nbr of tables in a SELECT */ +#define SQL_MAXVARS_STMT 32767 /* Maximum nbr of Host Vars per stmt */ +#define SQL_MAXCOLS 3000 /* Internal max nbr of columns in a */ + /* table */ +#define SQL_MAXCOLS_EXT 1012 /* External max nbr of columns in a */ + /* table */ +#define SQL_MAXSEL_ITEMS 1012 /* Maximum nbr of items in a SELECT */ +#define SQL_MAXPARMS 90 /* Maximum nbr of parms in a function */ +#define SQL_MAX_STMT_SIZ 2097152 /* Maximum statement size */ + +#define SQL_SMALL_LENGTH 2 /* Size of a SMALLINT */ +#define SQL_MAXSMALLVAL 32767 /* Maximum value of a SMALLINT */ +#define SQL_MINSMALLVAL (-(SQL_MAXSMALLVAL)-1) /* Minimum value of a SMALLINT */ +#define SQL_INT_LENGTH 4 /* Size of an INTEGER */ +#define SQL_MAXINTVAL 2147483647 /* Maximum value of an INTEGER */ +#define SQL_MININTVAL (-(SQL_MAXINTVAL)-1) /* Minimum value of an INTEGER */ + +#define SQL_BIGINT_LENGTH 8 /* Size of a BIGINT */ +#ifndef SQL_NO_NATIVE_BIGINT_SUPPORT +#define SQL_MAXBIGINTVAL DB2_CONSTRUCT_BIGINT_CONSTANT(9223372036854775807) /* Maximum value of a BIGINT */ +#define SQL_MINBIGINTVAL (-(SQL_MAXBIGINTVAL)-1) /* Minimum value of a BIGINT */ +#endif + +#define SQL_FLOAT_LENGTH 8 /* Size of a FLOAT */ +#define SQL_FLOAT4_LENGTH 4 /* Size of a 4-byte FLOAT */ +#define SQL_MAXSFLTPREC 24 /* Maximum prec for small float */ +#define SQL_MINSFLTPREC 1 /* Minimum prec for small float */ +#define SQL_MAXFLOATPREC 53 /* Minimum prec for any float */ +#define SQL_DEFDEC_PRECISION 5 /* Default precision for DECIMAL */ +#define SQL_DEFDEC_SCALE 0 /* Default scale for DECIMAL */ +#define SQL_MAXDECIMAL 31 /* Maximum scale/prec. for DECIMAL */ +#define SQL_DEFCHAR 1 /* Default length for a CHAR */ +#define SQL_DEFWCHAR 1 /* Default length for a graphic */ +#define SQL_MAXCHAR 254 /* Maximum length of a CHAR */ +#define SQL_MAXLSTR 255 /* Maximum length of an LSTRING */ +#define SQL_MAXVCHAR (SQL_MAXRECL - 5) /* Maximum length of a */ + /* VARCHAR */ +#define SQL_MAXVGRAPH SQL_MAXVCHAR/2 /* Maximum length of a */ + /* VARGRAPHIC */ +#define SQL_MAXBLOB 2147483647 /* Max. length of a BLOB host var */ +#define SQL_MAXCLOB 2147483647 /* Max. length of a CLOB host var */ +#define SQL_MAXDBCLOB 1073741823 /* Max. length of an DBCLOB host */ + /* var */ +#define SQL_LOBLOCATOR_LEN 4 /* Length of a LOB locator host var */ +#define SQL_LOBFILE_LEN 267 /* Length of a LOB file host var */ +#define SQL_VCHAROH 4 /* Overhead for VARCHAR in record */ +#define SQL_VARCOL_OH 4 /* Overhead for variable length type */ + /* in record */ +#define SQL_VARKEY_OH 2 /* Overhead for variable keyparts */ +#define SQL_LONGMAX 32700 /* Maximum length of a LONG VARCHAR */ +#define SQL_LONGGRMAX 16350 /* Max. length of a LONG VARGRAPHIC */ +#define SQL_LVCHAROH 24 /* Overhead for LONG VARCHAR in */ + /* record */ +#define SQL_LOBCHAROH 312 /* Overhead for LOB in record */ +#define SQL_BLOB_MAXLEN 2147483647 /* BLOB maximum length, in bytes */ +#define SQL_CLOB_MAXLEN 2147483647 /* CLOB maximum length, in chars */ +#define SQL_DBCLOB_MAXLEN 1073741823 /* maxlen for dbcs lobs */ +#define SQL_TIME_LENGTH 3 /* Size of a TIME field */ +#define SQL_TIME_STRLEN 8 /* Size of a TIME field output */ +#define SQL_TIME_MINSTRLEN 5 /* Size of a non-USA TIME field */ + /* output without seconds */ +#define SQL_DATE_LENGTH 4 /* Size of a DATE field */ +#define SQL_DATE_STRLEN 10 /* Size of a DATE field output */ +#define SQL_STAMP_LENGTH 10 /* Size of a TIMESTAMP field */ +#define SQL_STAMP_STRLEN 26 /* Size of a TIMESTAMP field output */ +#define SQL_STAMP_MINSTRLEN 19 /* Size of a TIMESTAMP field output */ + /* without microseconds */ +#define SQL_BOOLEAN_LENGTH 1 /* Size of a BOOLEAN field */ +#define SQL_DATALINK_LENGTH 254 /* Size of a DATALINK field */ +#define SQL_IND_LENGTH 2 /* Size of an indicator value */ + +#define SQL_DECFLOAT16_LENGTH 8 /* Size of a DECFLOAT16 field */ +#define SQL_DECFLOAT34_LENGTH 16 /* Size of a DECFLOAT34 field */ +#define SQL_MAXDECFLOAT 34 /* Maximum precision for DECFLOAT */ + +#define SQL_MAX_PNAME_LENGTH 254 /* Max size of Stored Proc Name */ +#define SQL_MAX_IDENT 128 /* Maximum length of Identifer */ +#define SQL_LG_IDENT 18 /* Maximum length of Long Identifer */ +#define SQL_SH_IDENT 8 /* Maximum length of Short Identifer */ +#define SQL_MN_IDENT 1 /* Minimum length of Identifiers */ +#define SQL_MAX_VAR_NAME 255 /* Max size of Host Variable Name */ +#define SQL_PDB_MAP_SIZE 4096 /* Number of partitions in a pmap */ +#define SQL_MAX_NUM_PART_KEYS 500 /* Max # of Partition Keys */ +#define SQL_ZONEDDECIMAL_FORMAT 0x20 /* decimal columns for sqlugrpn are */ + /* in zoneddecimal format */ +#define SQL_IMPLIEDDECIMAL_FORMAT 0x10 /* decimal columns for sqlugrpn are */ + /* in implieddecimal format */ +#define SQL_BINARYNUMERICS_FORMAT 0x4 /* numeric columns for sqlugrpn are */ + /* in binary format */ +#define SQL_PACKEDDECIMAL_FORMAT 0x8 /* decimal columns for sqlugrpn are */ + /* in packeddecimal format */ +#define SQL_CHARSTRING_FORMAT 0x0 /* numeric/decimal columns for */ + /* sqlugrpn are in character string */ + /* format */ +#define SQL_KILO_VALUE 1024 /* # of bytes in a kilobyte */ +#define SQL_MEGA_VALUE 1048576 /* # of bytes in a megabyte */ +#define SQL_GIGA_VALUE 1073741824 /* # of bytes in a gigabyte */ + +#define SQLB_MAX_CONTAIN_NAME_SZ 256 /* size of container name for api's */ + /* (includes 1 byte for C NULL */ + /* terminator) */ +/* System types */ +typedef signed short SQL_PDB_NODE_TYPE;/* Datatype of PDB node */ +typedef int SQL_PDB_PORT_TYPE;/* Datatype of PDB port */ +#define SQL_PDB_MAX_NUM_NODE 1000 /* limit for max. # of nodes */ +/* information related to logical node name */ +#define SQL_PDB_NODE_NUM_DIGIT 4 /* no. of digits for node number in */ + /* node name */ +#define SQL_PDB_NODE_NAME_LEN 8 /* length of logical node name */ +#define SQL_NODE_NUM_TO_NAME(name_p,node_num) \ + 0 <= node_num ? sprintf(name_p,"NODE%.*d", SQL_PDB_NODE_NUM_DIGIT, node_num) : \ + sprintf(name_p,"NODE%.*d", SQL_PDB_NODE_NUM_DIGIT-1, node_num) +/* Codepages */ +#define SQL_CP_367 367 /* Codepage 367 - EUC single byte */ +#define SQL_CP_420 420 /* CCSID x01A4, (CP420, ST4) */ +#define SQL_CP_424 424 /* CCSID x01A8, (CP424, ST4) */ +#define SQL_CP_425 425 /* CCSID x01A9, (CP420, ST5) */ +#define SQL_CP_437 437 /* Codepage 437 - US, Europe */ +#define SQL_CP_737 737 /* Codepage 737 - WIN Greece */ +#define SQL_CP_806 806 /* Codepage 806 - ISCII, India */ +#define SQL_CP_813 813 /* Codepage 813 - AIX Greece */ +#define SQL_CP_819 819 /* Codepage 819 - ISO 8859-1 */ +#define SQL_CP_850 850 /* Codepage 850 - International PC */ +#define SQL_CP_855 855 /* Codepage 855 - OS2 Cyrillic */ +#define SQL_CP_852 852 /* Codepage 852 - OS2 Latin2 */ +#define SQL_CP_856 856 /* Codepage 856 - Hebrew */ +#define SQL_CP_857 857 /* Codepage 857 - OS2 Turkey */ +#define SQL_CP_860 860 /* Codepage 860 - Portuguese */ +#define SQL_CP_862 862 /* Codepage 862 - OS2 Hebrew */ +#define SQL_CP_863 863 /* Codepage 863 - Canadian-French */ +#define SQL_CP_864 864 /* Codepage 864 - OS2 Arabic */ +#define SQL_CP_865 865 /* Codepage 865 - Norway, Denmark */ +#define SQL_CP_866 866 /* Codepage 866 - Russia */ +#define SQL_CP_867 867 /* Codepage 867 - OS2 Hebrew */ +#define SQL_CP_869 869 /* Codepage 869 - OS2 Greece */ +#define SQL_CP_874 874 /* Codepage 874 - OS2/AIX Thailand */ +#define SQL_CP_878 878 /* Codepage 878 - KOI-8R Russia */ +#define SQL_CP_891 891 /* Codepage 891 - Korean */ +#define SQL_CP_897 897 /* Codepage 897 - Japanese */ +#define SQL_CP_903 903 /* Codepage 903 - Chinese */ +#define SQL_CP_904 904 /* Codepage 904 - Taiwan */ +#define SQL_CP_912 912 /* Codepage 912 - AIX Latin2 */ +#define SQL_CP_915 915 /* Codepage 915 - AIX Cyrillic */ +#define SQL_CP_916 916 /* Codepage 916 - AIX Hebrew */ +#define SQL_CP_920 920 /* Codepage 920 - AIX Turkey */ +#define SQL_CP_921 921 /* Codepage 921 - Latvia, Lithuania */ +#define SQL_CP_922 922 /* Codepage 922 - Estonia */ +#define SQL_CP_923 923 /* Codepage 923 - ISO 8859-15 */ +#define SQL_CP_1004 1004 /* Codepage 1004 - MS-WINDOWS */ +#define SQL_CP_1040 1040 /* Codepage 1040 - Extended Korean */ +#define SQL_CP_1041 1041 /* Codepage 1041 - Extended Japanese */ +#define SQL_CP_1042 1042 /* Codepage 1042 - Extended Chinese */ +#define SQL_CP_1043 1043 /* Codepage 1043 - Extended Taiwan */ +#define SQL_CP_1046 1046 /* Codepage 1046 - AIX Arabic */ +#define SQL_CP_1051 1051 /* Codepage 1051 - HP Roman8 */ +#define SQL_CP_1088 1088 /* Codepage 1088 - Korea Std */ +#define SQL_CP_1089 1089 /* Codepage 1089 - AIX Arabic */ +#define SQL_CP_1114 1114 /* Codepage 1114 - Big-5 & GBK */ +#define SQL_CP_1115 1115 /* Codepage 1115 - China GB */ +#define SQL_CP_1124 1124 /* Codepage 1124 - AIX Ukraine */ +#define SQL_CP_1125 1125 /* Codepage 1125 - OS/2 Ukraine */ +#define SQL_CP_1126 1126 /* Codepage 1126 - Windows Korean Std */ +#define SQL_CP_1129 1129 /* Codepage 1129 - Vietnamese */ +#define SQL_CP_1131 1131 /* Codepage 1131 - OS/2 Belarus */ +#define SQL_CP_1163 1163 /* Codepage 1163 - Vietnamese */ +#define SQL_CP_1167 1167 /* KOI8-RU - Belarus */ +#define SQL_CP_1168 1168 /* KOI8-U - Ukraine */ +#define SQL_CP_1250 1250 /* Codepage 1250 - Windows Latin-2 */ +#define SQL_CP_1251 1251 /* Codepage 1251 - Windows Cyrillic */ +#define SQL_CP_1252 1252 /* Codepage 1252 - Windows Latin-1 */ +#define SQL_CP_1253 1253 /* Codepage 1253 - Windows Greek */ +#define SQL_CP_1254 1254 /* Codepage 1254 - Windows Turkish */ +#define SQL_CP_1255 1255 /* Codepage 1255 - Windows Hebrew */ +#define SQL_CP_1256 1256 /* Codepage 1256 - Windows Arabic */ +#define SQL_CP_1257 1257 /* Codepage 1257 - Windows Baltic */ +#define SQL_CP_1258 1258 /* Codepage 1258 - Windows Vietnamese */ +#define SQL_CP_1275 1275 /* Codepage 1275 - Mac Latin-1 */ +#define SQL_CP_1280 1280 /* Codepage 1280 - Mac Greek */ +#define SQL_CP_1281 1281 /* Codepage 1281 - Mac Turkish */ +#define SQL_CP_1282 1282 /* Codepage 1282 - Mac Latin-2 */ +#define SQL_CP_1283 1283 /* Codepage 1283 - Mac Cyrillic */ +#define SQL_CP_62208 62208 /* CCSID xF300, (CP856, ST4) */ +#define SQL_CP_62209 62209 /* CCSID xF301, (CP862, ST4) */ +#define SQL_CP_62210 62210 /* CCSID xF302, (CP916, ST4) */ +#define SQL_CP_62213 62213 /* CCSID xF305, (CP862, ST5) */ +#define SQL_CP_62220 62220 /* CCSID xF30C, (CP856, ST6) */ +#define SQL_CP_62221 62221 /* CCSID xF30D, (CP862, ST6) */ +#define SQL_CP_62222 62222 /* CCSID xF30E, (CP916, ST6) */ +#define SQL_CP_62223 62223 /* CCSID xF30F, (CP1255, ST6) */ +#define SQL_CP_62225 62225 /* CCSID xF311, (CP864, ST6) */ +#define SQL_CP_62226 62226 /* CCSID xF312, (CP1046, ST6) */ +#define SQL_CP_62227 62227 /* CCSID xF313, (CP1089, ST6) */ +#define SQL_CP_62228 62228 /* CCSID xF314, (CP1256, ST6) */ +#define SQL_CP_62230 62230 /* CCSID xF316, (CP856, ST8) */ +#define SQL_CP_62231 62231 /* CCSID xF317, (CP862, ST8) */ +#define SQL_CP_62232 62232 /* CCSID xF318, (CP916, ST8) */ +#define SQL_CP_62236 62236 /* CCSID xF31C, (CP856, ST10) */ +#define SQL_CP_62238 62238 /* CCSID xF31E, (CP916, ST10) */ +#define SQL_CP_62239 62239 /* CCSID xF31F, (CP1255, ST10) */ +#define SQL_CP_62241 62241 /* CCSID xF321, (CP856, ST11) */ +#define SQL_CP_62242 62242 /* CCSID xF322, (CP862, ST11) */ +#define SQL_CP_62243 62243 /* CCSID xF323, (CP916, ST11) */ +#define SQL_CP_62244 62244 /* CCSID xF324, (CP1255, ST11) */ +#define SQL_CP_UNKNOWN 57344 /* CCSID xE000, (Unknown or */ + /* unsupported) */ +#define SQL_CP_1162 1162 /* CCSID 1162 - Windows Thailand */ + /* (with Euro) */ +#define SQL_CP_5222 5222 /* CCSID 5222 - Windows Korea */ +#define SQL_CP_5346 5346 /* CCSID 5346 - Windows Latin-2 (v2 */ + /* with Euro) */ +#define SQL_CP_5347 5347 /* CCSID 5347 - Windows Cyrillic (v2 */ + /* with Euro) */ +#define SQL_CP_5348 5348 /* CCSID 5348 - Windows Latin-1 (v2 */ + /* with Euro) */ +#define SQL_CP_5349 5349 /* CCSID 5349 - Windows Greece (v2 */ + /* with Euro) */ +#define SQL_CP_5350 5350 /* CCSID 5350 - Windows Turkey (v2 */ + /* with Euro) */ +#define SQL_CP_5351 5351 /* CCSID 5351 - Windows Hebrew ST5 */ + /* (v2 with Euro) */ +#define SQL_CP_5352 5352 /* CCSID 5352 - Windows Arabic ST5 */ + /* (v2 with Euro) */ +#define SQL_CP_5353 5353 /* CCSID 5353 - Windows Baltic (v2 */ + /* with Euro) */ +#define SQL_CP_5354 5354 /* CCSID 5354 - Windows Vietnam (v2 */ + /* with Euro) */ +#define SQL_CP_62215 62215 /* CCSID 62215 - Windows Hebrew ST4 */ +#define SQL_CP_62237 62237 /* CCSID 62237 - Windows Hebrew ST8 */ +#define SQL_CP_895 895 /* CCSID 895 - Japan 7-bit Latin */ +#define SQL_CP_901 901 /* CCSID 901 - Baltic 8-bit (with */ + /* Euro) */ +#define SQL_CP_902 902 /* CCSID 902 - Estonia ISO-8 (with */ + /* Euro) */ +#define SQL_CP_1008 1008 /* CCSID 1008 - Arabic 8-bit ISO */ + /* ASCII */ +#define SQL_CP_1155 1155 /* CCSID 1155 - Turkey Latin-5 (with */ + /* Euro) */ +#define SQL_CP_4909 4909 /* CCSID 4909 - Greece, Latin ISO-8 */ + /* (with Euro) */ +#define SQL_CP_5104 5104 /* CCSID 5104 - Arabic 8-bit ISO */ + /* ASCII (with Euro) */ +#define SQL_CP_9005 9005 /* CCSID 9005 - Greece, Latin ISO */ + /* 8859-7:2003 (with Euro) */ +#define SQL_CP_21427 21427 /* CCSID 21427 - Taiwan IBM Big-5 */ + /* (with 13493 CNS, 566, 6204 UDC, */ + /* Euro) */ +#define SQL_CP_62212 62212 /* CCSID 62212 - CP867 Hebrew ST10 */ +#define SQL_CP_62214 62214 /* CCSID 62214 - CP867 Hebrew ST5 */ +#define SQL_CP_62216 62216 /* CCSID 62216 - CP867 Hebrew ST6 */ +#define SQL_CP_62217 62217 /* CCSID 62217 - CP867 Hebrew ST8 */ +#define SQL_CP_62219 62219 /* CCSID 62219 - CP867 Hebrew ST11 */ +#define SQL_CP_62240 62240 /* CCSID 62240 - CP856 Hebrew ST11 */ + +/* DBCS Codepages */ +#define SQL_CP_926 926 /* Codepage 926 - Korean */ +#define SQL_CP_951 951 /* Codepage 951 - New Korean */ +#define SQL_CP_301 301 /* Codepage 301 - Japanese */ +#define SQL_CP_928 928 /* Codepage 928 - Chinese */ +#define SQL_CP_927 927 /* Codepage 927 - Taiwan */ +#define SQL_CP_941 941 /* Codepage 941 - Japanese */ +#define SQL_CP_947 947 /* Codepage 947 - Taiwan Big-5 */ +#define SQL_CP_971 971 /* Codepage 971 - Korean 5601 */ +#define SQL_CP_1351 1351 /* Codepage 1351 - Japanese */ +#define SQL_CP_1362 1362 /* Codepage 1362 - Korean Windows */ +#define SQL_CP_1380 1380 /* Codepage1380 - China GB */ +#define SQL_CP_1382 1382 /* Codepage1382 - Simp Chinese GB */ +#define SQL_CP_1385 1385 /* Codepage1385 - Simp Chinese GBK */ +#define SQL_CP_1393 1393 /* Codepage 1393 - Japanese */ + +/* Combined Codepages */ +#define SQL_CP_934 934 /* Codepage 891 + 926 - Korean */ +#define SQL_CP_949 949 /* CP 1088 + 951 - Korean Std */ +#define SQL_CP_932 932 /* Codepage 897 + 301 - Japanese */ +#define SQL_CP_936 936 /* Codepage 903 + 928 - Chinese */ +#define SQL_CP_938 938 /* Codepage 904 + 927 - Taiwan */ +#define SQL_CP_944 944 /* Codepage 1040 + 926 - Ext.Korean */ +#define SQL_CP_942 942 /* Codepage 1041 + 301 - Ext.Japanese */ +#define SQL_CP_943 943 /* Codepage 897 + 941 - Ext.Japanese */ +#define SQL_CP_946 946 /* Codepage 1042 + 928 - Ext.Chinese */ +#define SQL_CP_948 948 /* Codepage 1043 + 927 - Ext.Taiwan */ +#define SQL_CP_950 950 /* Codepage 1114 + 947 - Taiwan Big5 */ +#define SQL_CP_954 954 /* Codepage 954 + 13488 - euc Japan */ +#define SQL_CP_964 964 /* Codepage 964 + 13488 - euc Taiwan */ +#define SQL_CP_970 970 /* Codepage 367 + 971 - Korean 5601 */ +#define SQL_CP_1363 1363 /* Codepage 1363 - Korean Windows */ +#define SQL_CP_1381 1381 /* Codepage 1115 +1380 - China GB */ +#define SQL_CP_1383 1383 /* Codepage 367 +1382 - Chinese GB */ +#define SQL_CP_1386 1386 /* Codepage 1114 +1385 - Chinese GBK */ +#define SQL_CP_5488 5488 /* Codepage - Chinese GB18030 */ +#define SQL_CP_1392 1392 /* Codepage - Chinese GB18030 */ +#define SQL_CP_1394 1394 /* Codepage - Japanese Shift */ + /* JISX0213 */ +#define SQL_CP_5039 5039 /* Codepage 1041 + 1351 - Japanese */ +#define SQL_CP_8612 8612 /* CCSID x21A4, (CP420, ST5) */ +#define SQL_CP_62218 62218 /* CCSID xF30A, (CP864, ST8) */ +#define SQL_CP_62224 62224 /* CCSID xF310, (CP420, ST6) */ +#define SQL_CP_62233 62233 /* CCSID xF319, (CP420, ST8) */ +#define SQL_CP_62234 62234 /* CCSID xF31A, (CP1255, ST9) */ +#define SQL_CP_62246 62246 /* CCSID xF326, (CP1046, ST8) */ +#define SQL_CP_62247 62247 /* CCSID xF327, (CP1046, ST9) */ +#define SQL_CP_62248 62248 /* CCSID xF328, (CP1046, ST4) */ +#define SQL_CP_62249 62249 /* CCSID xF329, (CP1046, ST2) */ +#define SQL_CP_62250 62250 /* CCSID xF32A, (CP420, ST12) */ + +/* Unicode CCSIDs */ +#define SQL_CP_1200 1200 /* Codepage1200 - UCS-2 (big-endian) */ +#define SQL_CP_1202 1202 /* Codepage1202 - UCS-2 (little */ + /* endian) */ +#define SQL_CP_1204 1204 /* Codepage1204 - UCS-2 (BOM) */ +#define SQL_CP_1208 1208 /* Codepage1208 - UTF-8 */ +#define SQL_CP_1232 1232 /* Codepage1232 - UTF-32 (big-endian) */ +#define SQL_CP_1234 1234 /* Codepage1234 - UTF-32 (little */ + /* endian) */ +#define SQL_CP_UTF32BE SQL_CP_1232 /* Big-endian UTF-32 */ +#define SQL_CP_UTF32LE SQL_CP_1234 /* Little-endian UTF-32 */ +#define SQL_CP_1236 1236 /* Codepage1236 - UTF-32 (BOM) */ +#define SQL_CP_13488 13488 /* Codepg13488 - UCS-2 (Unicode v2, */ + /* big-endian) */ +#define SQL_CP_13490 13490 /* Codepg13490 - UCS-2 (Unicode v2, */ + /* little-endiant) */ +#define SQL_CP_17584 17584 /* Codepg17584 - UCS-2 (Unicode v3, */ + /* big-endian) */ +#define SQL_CP_17586 17586 /* Codepg17586 - UCS-2 (Unicode v3, */ + /* little-endiant) */ +#define SQL_CP_UTF8 SQL_CP_1208 /* UTF-8 */ +#define SQL_CP_UTF16BE SQL_CP_1200 /* Big-endian UTF-16 */ +#define SQL_CP_UTF16LE SQL_CP_1202 /* Little-endian UTF-16 */ + +/* EBCDIC, PCDATA and ECECP CCSIDs */ +#define SQL_CP_37 37 /* CCSID 37 - EBCDIC - Common */ + /* European */ +#define SQL_CP_273 273 /* CCSID 273 - EBCDIC Austria, */ + /* Germany */ +#define SQL_CP_274 274 /* CCSID 274 - EBCDIC Belgium */ +#define SQL_CP_277 277 /* CCSID 277 - EBCDIC Denmark, Norway */ +#define SQL_CP_278 278 /* CCSID 278 - EBCDIC Finland, Sweden */ +#define SQL_CP_280 280 /* CCSID 280 - EBCDIC Italy */ +#define SQL_CP_284 284 /* CCSID 284 - EBCDIC Spain, Latin */ + /* America */ +#define SQL_CP_285 285 /* CCSID 285 - EBCDIC UK */ +#define SQL_CP_290 290 /* CCSID 290 - EBCDIC Japan */ +#define SQL_CP_297 297 /* CCSID 297 - EBCDIC France */ +#define SQL_CP_300 300 /* CCSID 300 - EBCDIC Japan DBCS */ +#define SQL_CP_423 423 /* CCSID 423 - EBCDIC Greece */ +#define SQL_CP_500 500 /* CCSID 500 - EBCDIC Latin-1 */ +#define SQL_CP_803 803 /* CCSID 803 - EBCDIC Hebrew Set-A, */ + /* ST4 */ +#define SQL_CP_833 833 /* CCSID 833 - EBCDIC Korea Extended */ + /* SBCS */ +#define SQL_CP_834 834 /* CCSID 834 - EBCDIC Korea DBCS */ + /* (with 1880 UDC) */ +#define SQL_CP_835 835 /* CCSID 835 - EBCDIC Taiwan DBCS */ + /* (with 6204 UDC) */ +#define SQL_CP_836 836 /* CCSID 836 - EBCDIC China SBCS */ +#define SQL_CP_837 837 /* CCSID 837 - EBCDIC China DBCS */ + /* (with 1880 UDC) */ +#define SQL_CP_838 838 /* CCSID 838 - EBCDIC Thailand */ + /* Extended SBCS */ +#define SQL_CP_870 870 /* CCSID 870 - EBCDIC Latin-2 */ +#define SQL_CP_871 871 /* CCSID 871 - EBCDIC Iceland */ +#define SQL_CP_875 875 /* CCSID 875 - EBCDIC Greece */ +#define SQL_CP_924 924 /* CCSID 924 - EBCDIC Latin-9 */ +#define SQL_CP_930 930 /* CCSID 930 - EBCDIC Japan mix (with */ + /* 4370 UDC, Extended SBCS) */ +#define SQL_CP_933 933 /* CCSID 933 - EBCDIC Korea mix (with */ + /* 1880 UDC, Extended SBCS) */ +#define SQL_CP_935 935 /* CCSID 935 - EBCDIC China mix (with */ + /* 1880 UDC, Extended SBCS) */ +#define SQL_CP_937 937 /* CCSID 937 - EBCDIC Taiwan mix */ + /* (with 6204 UDC, Extended SBCS) */ +#define SQL_CP_939 939 /* CCSID 939 - EBCDIC Japan mix (with */ + /* 4370 UDC, Extended SBCS) */ +#define SQL_CP_1025 1025 /* CCSID 1025 - EBCDIC Cyrillic */ +#define SQL_CP_1026 1026 /* CCSID 1026 - EBCDIC Turkey Latin-5 */ +#define SQL_CP_1027 1027 /* CCSID 1027 - EBCDIC Japan Extended */ + /* SBCS */ +#define SQL_CP_1047 1047 /* CCSID 1047 - EBCDIC Open Systems */ + /* Latin-1 */ +#define SQL_CP_1112 1112 /* CCSID 1112 - EBCDIC Baltic */ +#define SQL_CP_1122 1122 /* CCSID 1122 - EBCDIC Estonia */ +#define SQL_CP_1123 1123 /* CCSID 1123 - EBCDIC Ukraine */ +#define SQL_CP_1130 1130 /* CCSID 1130 - EBCDIC Vietnam */ +#define SQL_CP_1137 1137 /* CCSID 1137 - EBCDIC Devangari */ + /* (Based on Unicode) */ +#define SQL_CP_1153 1153 /* CCSID 1153 - EBCDIC Latin-2 (with */ + /* Euro) */ +#define SQL_CP_1154 1154 /* CCSID 1154 - EBCDIC Cyrillic (with */ + /* Euro) */ +#define SQL_CP_1156 1156 /* CCSID 1156 - EBCDIC Baltic */ +#define SQL_CP_1157 1157 /* CCSID 1157 - EBCDIC Estonia */ +#define SQL_CP_1158 1158 /* CCSID 1158 - EBCDIC Ukraine */ +#define SQL_CP_1159 1159 /* CCSID 1159 - EBCDIC Taiwan */ + /* Extended SBCS (with Euro) */ +#define SQL_CP_1160 1160 /* CCSID 1160 - EBCDIC Thailanf (with */ + /* Euro) */ +#define SQL_CP_1164 1164 /* CCSID 1164 - EBCDIC Vietnam (with */ + /* Euro) */ +#define SQL_CP_1364 1364 /* CCSID 1364 - EBCDIC Korea mix */ + /* (with Full Hangul) */ +#define SQL_CP_1371 1371 /* CCSID 1371 - EBCDIC Taiwan mix */ + /* (with 6204 UDC, Extended SBCS) */ +#define SQL_CP_1388 1388 /* CCSID 1388 - EBCDIC China mix */ +#define SQL_CP_1390 1390 /* CCSID 1390 - EBCDIC Japan mix */ + /* (with 6205 UDC, Extended SBCS, */ + /* Euro) */ +#define SQL_CP_1399 1399 /* CCSID 1399 - EBCDIC Japan max */ + /* (with 6205 UDC, Exnteded SBCS, */ + /* Euro) */ +#define SQL_CP_4369 4369 /* CCSID 4369 - EBCDIC Austria, */ + /* German (DP94) */ +#define SQL_CP_4396 4396 /* CCSID 4396 - EBCDIC Japan DBCS */ + /* (with 1880 UCD) */ +#define SQL_CP_4899 4899 /* CCSID 4899 - EBCDIC Hebrew Set-A, */ + /* ST4 (with Euro, Sheqel) */ +#define SQL_CP_4930 4930 /* CCSID 4930 - EBCDIC Korea DBCS */ + /* (with Full Hangul) */ +#define SQL_CP_4933 4933 /* CCSID 4933 - EBCDIC China DBCS */ + /* (with all GBK) */ +#define SQL_CP_4971 4971 /* CCSID 4971 - EBCDIC Greece (with */ + /* Euro) */ +#define SQL_CP_5026 5026 /* CCSID 5026 - EBCDIC Japan mix */ + /* (with 1880 UDC, Extended SBCS) */ +#define SQL_CP_5035 5035 /* CCSID 5035 - EBCDIC Japan mix */ + /* (with 1880 UDC, Extended SBCS) */ +#define SQL_CP_5123 5123 /* CCSID 5123 - EBCDIC Japan Latin */ + /* (with Extended SBCS, Euro) */ +#define SQL_CP_8482 8482 /* CCSID 8482 - EBCDIC Japan SBCS */ + /* (with Euro) */ +#define SQL_CP_8616 8616 /* CCSID 8616 - EBCDIC Hebrew subset */ + /* ST10 */ +#define SQL_CP_9027 9027 /* CCSID 9027 - EBCDIC Taiwan (with */ + /* 6204 UDC, Euro) */ +#define SQL_CP_12708 12708 /* CCSID 12708 - EBCDIC Arabic ST7 */ +#define SQL_CP_12712 12712 /* CCSID 12712 - EBCDIC Hebrew ST10 */ + /* (with Euro, Sheqel) */ +#define SQL_CP_13121 13121 /* CCSID 13121 - EBCDIC Korea (with */ + /* Extended SBCS) */ +#define SQL_CP_13124 13124 /* CCSID 13124 - EBCDIC China SBCS */ +#define SQL_CP_16684 16684 /* CCSID 16684 - EBCDIC Japan (with */ + /* 6295 UDC, Euro) */ +#define SQL_CP_16804 16804 /* CCSID 16804 - EBCDIC Arabic ST4 */ + /* (with Euro) */ +#define SQL_CP_28709 28709 /* CCSID 28709 - EBCDIC Taiwan SBCS */ +#define SQL_CP_62211 62211 /* CCSID 62211 - EBCDIC Hebrew ST5 */ +#define SQL_CP_62229 62229 /* CCSID 62229 - EBCDIC Hebrew ST8 */ +#define SQL_CP_62235 62235 /* CCSID 62235 - EBCDIC Hebrew ST6 */ +#define SQL_CP_62245 62245 /* CCSID 62245 - EBCDIC Hebrew ST10 */ +#define SQL_CP_62251 62251 /* CCSID 62251 - zOS Arabic/Latin ST6 */ +#define SQL_CP_808 808 /* CCSID 808 - PCDATA Cyrillic */ + /* (Russian with Euro) */ +#define SQL_CP_848 848 /* CCSID 848 - PCDATA Uktaine (with */ + /* Euro) */ +#define SQL_CP_849 849 /* CCSID 849 - PCDATA Belarus (with */ + /* Euro) */ +#define SQL_CP_858 858 /* CCSID 858 - PCDATA Latin-1E (with */ + /* Euro) */ +#define SQL_CP_872 872 /* CCSID 872 - PCDATA Cyrillic (with */ + /* Euro) */ +#define SQL_CP_1161 1161 /* CCSID 1161 - PCDATA Thailand (with */ + /* Euero) */ +#define SQL_CP_1370 1370 /* CCSID 1370 - PCDATA Taiwan mix */ + /* (with Euro) */ +#define SQL_CP_5210 5210 /* CCSID 5210 - PCDATA China SBCS */ +#define SQL_CP_9044 9044 /* CCSID 9044 - PCDATA Latin-2 (with */ + /* Euro) */ +#define SQL_CP_9048 9048 /* CCSID 9048 - PCDATA Hebrew ST5 */ + /* (with Euro, Sheqel) */ +#define SQL_CP_9049 9049 /* CCSID 9049 - PCDATA Turkey Latin-5 */ + /* (with Euro) */ +#define SQL_CP_9061 9061 /* CCSID 9061 - PCDATA Greece (with */ + /* Euro) */ +#define SQL_CP_9238 9238 /* CCSID 9238 - PCDATA Arabic ST5 */ + /* (with Euro) */ +#define SQL_CP_17248 17248 /* CCSID 17248 - PCDATA Arabic ST5 */ + /* (with Euro) */ +#define SQL_CP_1140 1140 /* CCSID 1140 - ECECP Common */ + /* European, US, Canada */ +#define SQL_CP_1141 1141 /* CCSID 1141 - ECECP Austria, */ + /* Germany */ +#define SQL_CP_1142 1142 /* CCSID 1142 - ECECP Denmakr, Norway */ +#define SQL_CP_1143 1143 /* CCSID 1143 - ECECP Finalnd, Sweden */ +#define SQL_CP_1144 1144 /* CCSID 1144 - ECECP Italy */ +#define SQL_CP_1145 1145 /* CCSID 1145 - ECECP Spanish, Latin */ + /* America */ +#define SQL_CP_1146 1146 /* CCSID 1146 - ECECP UK */ +#define SQL_CP_1147 1147 /* CCSID 1147 - ECECP France */ +#define SQL_CP_1148 1148 /* CCSID 1148 - ECECP International 1 */ +#define SQL_CP_1149 1149 /* CCSID 1149 - ECECP Iceland */ +#define SQL_CP_65535 65535 /* CCSID 65535 - Reserved */ + +/* Datastream Types */ +#define SQL_SBC_PC 0 /* Single byte PC */ +#define SQL_JPN_PC 1 /* Japanese-PC */ +#define SQL_CHN_PC 2 /* Chinese-PC */ +#define SQL_KOR_PC 3 /* Korean-PC */ +#define SQL_KSC_PC 4 /* New Korean-PC */ +#define SQL_KR5_PC 5 /* Korean 5601 */ +#define SQL_TWN_PC 6 /* Taiwan Big-5 */ +#define SQL_CGB_PC 7 /* China GB */ +#define SQL_CGBA_PC 8 /* China GB on AIX */ +#define SQL_EUCJP_PC 9 /* Japan euc */ +#define SQL_EUCTW_PC 10 /* Taiwan euc */ +#define SQL_UCS2_PC 11 /* UCS-2 */ +#define SQL_KSC2_PC 12 /* Korean Windows */ +#define SQL_CGBK_PC 13 /* China GBK */ +#define SQL_UTF8_PC 14 /* UTF-8 */ +#define SQL_CGB18030_PC 15 /* China GB18030 */ +#define SQL_UNKN_PC 255 /* Unknown */ + +/* OEM codeset & locale lengths */ +#define SQL_CODESET_LEN 17 +#define SQL_LOCALE_LEN 33 + +/* Codeset & locale lengths for sqle_db_territory_info struct */ +#define SQL_CODESET_SIZE 17 +#define SQL_LOCALE_SIZE 33 + +/* SQLCA Constants */ +#ifndef SQL_RC_INVALID_SQLCA +#endif + +/* Size of SQLCA */ +#define SQLCA_SIZE sizeof(struct sqlca) + +/* SQL Error message token delimiter */ +#define SQL_ERRMC_PRES ((char) 0xFF) /* delimiter for string entry */ + +/* Offset in SQLERRD - Diagnostic information */ +#define SQL_ERRD_RC 0 /* return code */ +#define SQL_ERRD_REAS 1 /* reason code */ +#define SQL_ERRD_CNT 2 /* nbr rows inserted/updated/deleted */ +#define SQL_ERRD_OPT_CARD 2 /* optimizer estimate of # rows */ +#define SQL_ERRD_OPTM 3 /* obsolete -- do not use -- */ +#define SQL_ERRD_OPT_TOTCOST 3 /* optimzer estimate of total cost */ +#define SQL_ERRD_DCNT 4 /* nbr of cascaded deletes/updates */ +#define SQL_ERRD_LINE 4 /* line number for recompile error */ +#define SQL_ERRD_AUTHTYPE 4 /* authentication type returned for */ + /* CONNECT/ATTACH */ +#define SQL_ERRD_DIAG 5 /* diagnostics */ + +/* Indexes in SQLWARN - Warning flags */ +#define SQL_WARN_ANY 0 /* composite - set if any warnings */ +#define SQL_WARN_TRUNC 1 /* string column truncated */ +#define SQL_WARN_NUL 2 /* null values eliminated */ +#define SQL_WARN_MISM 3 /* nbr of columns/host vars mismatch */ +#define SQL_WARN_ALLR 4 /* no WHERE clause in update/delete */ +#define SQL_WARN_ETO 5 /* error is tolerated */ +#define SQL_WARN_DATE 6 /* date has been truncated */ +#define SQL_WARN_SUB 8 /* character conversion substitution */ +#define SQL_WARN_NUL2 9 /* arithmetic error nulls eliminated */ +#define SQL_WARN_SQLCA 10 /* SQLCA conversion error */ + +/* Values for Warning flags in SQLWARN */ +#define SQL_WARNING 'W' /* warning indicator */ +#define SQL_NULL_TRN 'N' /* null terminator truncated warning */ +#define SQL_TRN_APP_LEN 'X' /* truncation warning with */ + /* application context length */ + /* returned in sqlind */ +#define SQL_NO_WARN ' ' /* no warning indicator */ +#define SQL_ETO 'E' /* error has been tolerated */ + +#define SQL_PREPARE_ESTIMATE_WARNING 'P' /* Compiler estimate warning */ + /* indicator */ +/* SQLDA Constants */ + +/* Increment for type with null indicator */ +#define SQL_TYP_NULINC 1 + +/* Variable Types */ +#define SQL_TYP_DATE 384 /* DATE */ +#define SQL_TYP_NDATE (SQL_TYP_DATE+SQL_TYP_NULINC) + +#define SQL_TYP_TIME 388 /* TIME */ +#define SQL_TYP_NTIME (SQL_TYP_TIME+SQL_TYP_NULINC) + +#define SQL_TYP_STAMP 392 /* TIMESTAMP */ +#define SQL_TYP_NSTAMP (SQL_TYP_STAMP+SQL_TYP_NULINC) + +#define SQL_TYP_DATALINK 396 /* DATALINK */ +#define SQL_TYP_NDATALINK (SQL_TYP_DATALINK+SQL_TYP_NULINC) + +#define SQL_TYP_CGSTR 400 /* C NUL-terminated graphic str */ +#define SQL_TYP_NCGSTR (SQL_TYP_CGSTR+SQL_TYP_NULINC) + +#define SQL_TYP_BLOB 404 /* BLOB - varying length string */ +#define SQL_TYP_NBLOB (SQL_TYP_BLOB+SQL_TYP_NULINC) + +#define SQL_TYP_CLOB 408 /* CLOB - varying length string */ +#define SQL_TYP_NCLOB (SQL_TYP_CLOB+SQL_TYP_NULINC) + +#define SQL_TYP_DBCLOB 412 /* DBCLOB - varying length string */ +#define SQL_TYP_NDBCLOB (SQL_TYP_DBCLOB+SQL_TYP_NULINC) + +#define SQL_TYP_VARCHAR 448 /* VARCHAR(i) - varying length string */ + /* (2 byte length) */ +#define SQL_TYP_NVARCHAR (SQL_TYP_VARCHAR+SQL_TYP_NULINC) + +#define SQL_TYP_CHAR 452 /* CHAR(i) - fixed length string */ +#define SQL_TYP_NCHAR (SQL_TYP_CHAR+SQL_TYP_NULINC) + +#define SQL_TYP_LONG 456 /* LONG VARCHAR - varying length */ + /* string */ +#define SQL_TYP_NLONG (SQL_TYP_LONG+SQL_TYP_NULINC) + +#define SQL_TYP_CSTR 460 /* varying length string for C (null */ + /* terminated) */ +#define SQL_TYP_NCSTR (SQL_TYP_CSTR+SQL_TYP_NULINC) + +#define SQL_TYP_VARGRAPH 464 /* VARGRAPHIC(i) - varying length */ + /* graphic string (2 byte length) */ +#define SQL_TYP_NVARGRAPH (SQL_TYP_VARGRAPH+SQL_TYP_NULINC) + +#define SQL_TYP_GRAPHIC 468 /* GRAPHIC(i) - fixed length graphic */ + /* string */ +#define SQL_TYP_NGRAPHIC (SQL_TYP_GRAPHIC+SQL_TYP_NULINC) + +#define SQL_TYP_LONGRAPH 472 /* LONG VARGRAPHIC(i) - varying */ + /* length graphic string */ +#define SQL_TYP_NLONGRAPH (SQL_TYP_LONGRAPH+SQL_TYP_NULINC) + +#define SQL_TYP_LSTR 476 /* varying length string for Pascal */ + /* (1-byte length) */ +#define SQL_TYP_NLSTR (SQL_TYP_LSTR+SQL_TYP_NULINC) + +#define SQL_TYP_FLOAT 480 /* FLOAT - 4 or 8 byte floating point */ +#define SQL_TYP_NFLOAT (SQL_TYP_FLOAT+SQL_TYP_NULINC) + +#define SQL_TYP_DECIMAL 484 /* DECIMAL (m,n) */ +#define SQL_TYP_NDECIMAL (SQL_TYP_DECIMAL+SQL_TYP_NULINC) + +#define SQL_TYP_ZONED 488 /* Zoned Decimal -> DECIMAL (m,n) */ +#define SQL_TYP_NZONED (SQL_TYP_ZONED+SQL_TYP_NULINC) + +#define SQL_TYP_BIGINT 492 /* BIGINT - 8-byte signed integer */ +#define SQL_TYP_NBIGINT (SQL_TYP_BIGINT+SQL_TYP_NULINC) + +#define SQL_TYP_INTEGER 496 /* INTEGER - 4-byte signed integer */ +#define SQL_TYP_NINTEGER (SQL_TYP_INTEGER+SQL_TYP_NULINC) + +#define SQL_TYP_SMALL 500 /* SMALLINT - 2-byte signed integer */ +#define SQL_TYP_NSMALL (SQL_TYP_SMALL+SQL_TYP_NULINC) + +#define SQL_TYP_NUMERIC 504 /* NUMERIC -> DECIMAL (m,n) */ +#define SQL_TYP_NNUMERIC (SQL_TYP_NUMERIC+SQL_TYP_NULINC) + +#define SQL_TYP_BLOB_FILE_OBSOLETE 804 /* Obsolete Value */ +#define SQL_TYP_NBLOB_FILE_OBSOLETE (SQL_TYP_BLOB_FILE_OBSOLETE+SQL_TYP_NULINC) + +#define SQL_TYP_CLOB_FILE_OBSOLETE 808 /* Obsolete Value */ +#define SQL_TYP_NCLOB_FILE_OBSOLETE (SQL_TYP_CLOB_FILE_OBSOLETE+SQL_TYP_NULINC) + +#define SQL_TYP_DBCLOB_FILE_OBSOLETE 812 /* Obsolete Value */ +#define SQL_TYP_NDBCLOB_FILE_OBSOLETE (SQL_TYP_DBCLOB_FILE_OBSOLETE+SQL_TYP_NULINC) + +#define SQL_TYP_VARBINARY 908 /* Variable Binary */ +#define SQL_TYP_NVARBINARY (SQL_TYP_VARBINARY+SQL_TYP_NULINC) + +#define SQL_TYP_BINARY 912 /* Fixed Binary */ +#define SQL_TYP_NBINARY (SQL_TYP_BINARY+SQL_TYP_NULINC) + +#define SQL_TYP_BLOB_FILE 916 /* BLOB File - Binary Large Object */ + /* File */ +#define SQL_TYP_NBLOB_FILE (SQL_TYP_BLOB_FILE+SQL_TYP_NULINC) + +#define SQL_TYP_CLOB_FILE 920 /* CLOB File - Char Large Object File */ +#define SQL_TYP_NCLOB_FILE (SQL_TYP_CLOB_FILE+SQL_TYP_NULINC) + +#define SQL_TYP_DBCLOB_FILE 924 /* DBCLOB File - Double Byte Char */ + /* Large Object File */ +#define SQL_TYP_NDBCLOB_FILE (SQL_TYP_DBCLOB_FILE+SQL_TYP_NULINC) + +#define SQL_TYP_BLOB_LOCATOR 960 /* BLOB locator */ +#define SQL_TYP_NBLOB_LOCATOR (SQL_TYP_BLOB_LOCATOR+SQL_TYP_NULINC) + +#define SQL_TYP_CLOB_LOCATOR 964 /* CLOB locator */ +#define SQL_TYP_NCLOB_LOCATOR (SQL_TYP_CLOB_LOCATOR+SQL_TYP_NULINC) + +#define SQL_TYP_DBCLOB_LOCATOR 968 /* DBCLOB locator */ +#define SQL_TYP_NDBCLOB_LOCATOR (SQL_TYP_DBCLOB_LOCATOR+SQL_TYP_NULINC) + +#define SQL_TYP_XML 988 /* XML */ +#define SQL_TYP_NXML (SQL_TYP_XML+SQL_TYP_NULINC) + +#define SQL_TYP_DECFLOAT 996 /* Decimal Float (16/34) */ +#define SQL_TYP_NDECFLOAT (SQL_TYP_DECFLOAT+SQL_TYP_NULINC) + +#define SQL_LOBTOKEN_LEN SQL_LOBLOCATOR_LEN +#define SQL_TYP_BLOB_TOKEN SQL_TYP_BLOB_LOCATOR +#define SQL_TYP_NBLOB_TOKEN SQL_TYP_NBLOB_LOCATOR +#define SQL_TYP_CLOB_TOKEN SQL_TYP_CLOB_LOCATOR +#define SQL_TYP_NCLOB_TOKEN SQL_TYP_NCLOB_LOCATOR +#define SQL_TYP_DBCLOB_TOKEN SQL_TYP_DBCLOB_LOCATOR +#define SQL_TYP_NDBCLOB_TOKEN SQL_TYP_NDBCLOB_LOCATOR +#define SQL_NCLOB_MAXLEN SQL_DBCLOB_MAXLEN +#define SQL_LOBHANDLE_LEN SQL_LOBTOKEN_LEN +#define SQL_TYP_BLOB_HANDLE SQL_TYP_BLOB_TOKEN +#define SQL_TYP_NBLOB_HANDLE SQL_TYP_NBLOB_TOKEN +#define SQL_TYP_CLOB_HANDLE SQL_TYP_CLOB_TOKEN +#define SQL_TYP_NCLOB_HANDLE SQL_TYP_NCLOB_TOKEN +#define SQL_TYP_DBCLOB_HANDLE SQL_TYP_DBCLOB_TOKEN +#define SQL_TYP_NDBCLOB_HANDLE SQL_TYP_NDBCLOB_TOKEN + +/* Values for 30th byte of sqlname */ +#define SQL_SQLNAME_SYSGEN ((char) 0xFF) /* sqlname is system generated */ +#define SQL_SQLNAME_NOT_SYSGEN ((char) 0x00) /* sqlname is directly derived */ + /* from a single column or */ + /* specified in the AS clause */ + +/* Return Codes for sqlabndx, sqlaprep and sqlarbnd */ +#define SQLA_RC_OPT_IGNORED 20 /* The option(s) specified are not */ + /* supported by the target database */ + /* and will be ignored */ +#define SQLA_RC_BINDWARN 25 /* Bind execution succeeded with */ + /* warnings. */ +#define SQLA_RC_PREPWARN 25 /* Precompilation succeeded with */ + /* warnings. */ +#define SQLA_RC_BINDERROR -1 /* Bind execution failed */ +#define SQLA_RC_PREPERROR -1 /* Precompilation failed */ +#define SQLA_RC_BAD_BINDNAME -2 /* Invalid bind file */ +#define SQLA_RC_BAD_DBNAME -3 /* Invalid database */ +#define SQLA_RC_BAD_MSGNAME -5 /* Invalid message file */ +#define SQLA_RC_BAD_FORMAT -6 /* Invalid format */ +#define SQLA_RC_OPEN_ERROR -31 /* Error opening list file */ +#define SQLA_RC_MFILE_OPEN_ERR -35 /* Error opening message file */ +#define SQLA_RC_FILE_NAME_BAD -36 /* Source file name is invalid */ +#define SQLA_RC_BAD_BNDFILE -39 /* Bind file corrupted */ +#define SQLA_RC_LIST_ERROR -40 /* Bind list errors */ +#define SQLA_RC_INTERRUPT -94 /* Interrupt */ +#define SQLA_RC_OSERROR -1086 /* System error */ +#define SQLA_RC_PREP_BIND_BUSY -1392 /* Prep/Bind already in use */ +#define SQLA_RC_OPTION_LEN_BAD -4903 /* Invalid parm. length */ +#define SQLA_RC_OPTION_PTR_BAD -4904 /* Invalid parm. ptr */ +#define SQLA_RC_OPTION_SIZE_BAD -4905 /* Invalid parm. size */ +#define SQLA_RC_OPTION_DATA_BAD -4917 /* Invalid parm. data */ +#define SQLA_RC_OPTION_INVALID -30104 /* Invalid option or option value */ +#define SQLA_RC_SDK_LICENSE -8005 /* No SDK/6000 license */ + +/* Values used for the date/time format parameter of sqlabind() ** OBSOLETE */ +/* ** */ +#define SQL_FMT_DEF "DEF" /* FORMAT = Default for Country Code */ +#define SQL_FMT_USA "USA" /* FORMAT = USA */ +#define SQL_FMT_EUR "EUR" /* FORMAT = EUR */ +#define SQL_FMT_ISO "ISO" /* FORMAT = ISO */ +#define SQL_FMT_JIS "JIS" /* FORMAT = JIS */ +#define SQL_FMT_LOC "LOC" /* FORMAT = LOCAL */ + +/* The size of a date/time format buffer */ +#define SQL_FMT_LENGTH 3 + +/* Structures used system wide */ + +#ifndef SQL_SQLDBCHAR_DEFN +#define SQL_SQLDBCHAR_DEFN + typedef unsigned short sqldbchar; +#endif + +/****************************************************************************** +** sqlchar data structure +** This structure is used to pass variable length data to the database manager. +** +** Table: Fields in the SQLCHAR Structure +** ---------------------------------------------------------------------------- +** |Field Name |Data Type |Description | +** |---------------------|---------------|------------------------------------| +** |LENGTH |SMALLINT |Length of the character string | +** | | |pointed to by DATA. | +** |---------------------|---------------|------------------------------------| +** |DATA |CHAR(n) |An array of characters of length | +** | | |LENGTH. | +** |---------------------|---------------|------------------------------------| +** +** COBOL Structure +** +** This is not defined in any header file. The following is an example that +** shows how to define the structure in COBOL: +** +** * Replace maxlen with the appropriate value: +** 01 SQLCHAR. +** 49 SQLCHAR-LEN PIC S9(4) COMP-5. +** 49 SQLCHAR-DATA PIC X(maxlen). +*******************************************************************************/ +SQL_STRUCTURE sqlchar /* General-purpose VARCHAR for */ + /* casting */ +{ + short length; + _SQLOLDCHAR data[1]; +}; + +/****************************************************************************** +** sqlgraphic data structure +*******************************************************************************/ +SQL_STRUCTURE sqlgraphic /* General-purpose VARGRAPHIC for */ + /* casting */ +{ + short length; +#ifdef SQL_WCHART_CONVERT + wchar_t data[1]; +#else + sqldbchar data[1]; +#endif +}; + +/****************************************************************************** +** sqllob data structure +** This structure is used to represent a LOB data type in a host +** programming language. +** +** Table: Fields in the sqllob structure +** ---------------------------------------------------------------- +** |Field name |Data type |Description | +** |--------------|-------------|---------------------------------| +** |length |sqluint32 |Length in bytes of the data | +** | | |parameter. | +** |--------------|-------------|---------------------------------| +** |data |char(1) |Data being passed in. | +** |--------------|-------------|---------------------------------| +** +*******************************************************************************/ +SQL_STRUCTURE sqllob /* General-purpose LOB for casting */ +{ + sqluint32 length; + char data[1]; +}; + +/****************************************************************************** +** sqldbclob data structure +*******************************************************************************/ +SQL_STRUCTURE sqldbclob /* General-purpose DBCLOB for casting */ +{ + sqluint32 length; +#ifdef SQL_WCHART_CONVERT + wchar_t data[1]; +#else + sqldbchar data[1]; +#endif +}; + +/****************************************************************************** +** sqlfile data structure +*******************************************************************************/ +SQL_STRUCTURE sqlfile /* File reference structure for LOBs */ +{ + sqluint32 name_length; + sqluint32 data_length; + sqluint32 file_options; + char name[255]; +}; + +SQL_STRUCTURE sqlfile2 /* Extended file reference structure */ + /* for LOBs */ +{ + sqluint32 name_length; + sqluint32 data_length; + sqluint32 file_options; + char name[255]; + char reserved[5]; + sqluint64 offset; +}; + +/* Values used for SQLVAR.SQLLEN with sqlfile structures */ +#define SQL_SQLFILE_LEN SQL_LOBFILE_LEN /* Length of an sqlfile LOB */ + /* file host var */ +#define SQL_SQLFILE2_LEN 280 /* Length of an sqlfile2 LOB file */ + /* host var */ + +/* Values used for file_options in the sqlfile structures */ +#define SQL_FILE_READ 2 /* Input file to read from */ +#define SQL_FILE_CREATE 8 /* Output file - new file to be */ + /* created */ +#define SQL_FILE_OVERWRITE 16 /* Output file - overwrite existing */ + /* file or create a new file if it */ + /* doesn't exist */ +#define SQL_FILE_APPEND 32 /* Output file - append to an */ + /* existing file or create a new file */ + /* if it doesn't exist */ + +/* Structure used to store binder options when calling sqlabndr() */ +/* or sqlabndx(), or to store precompile options when calling */ +/* sqlaprep(), or to store rebind options when calling sqlarbnd(). */ + +#define sqlbindopt sqloptions + +#ifndef SQL_BIND_OPTS + +/****************************************************************************** +** sqloptheader data structure +** Table: Fields in the SQLOPTHEADER Structure +** |----------------------------------------------------------------| +** |Field Name|Data Type|Description | +** |----------|---------|-------------------------------------------| +** |ALLOCATED |INTEGER |Number of elements in the option array | +** | | |of the sqlopt structure. | +** |----------|---------|-------------------------------------------| +** |USED |INTEGER |Number of elements in the option array | +** | | |of the sqlopt structure actually used. | +** | | |This is the number of option pairs (TYPE | +** | | |and VAL) supplied. | +** |----------|---------|-------------------------------------------| +*******************************************************************************/ +SQL_STRUCTURE sqloptheader /* Header for sqlopt structure */ +{ + sqluint32 allocated; /* Number of options allocated */ + sqluint32 used; /* Number of options used */ +}; + +/****************************************************************************** +** sqloptions data structure +** Table: Fields in the SQLOPTIONS Structure +** |----------------------------------------------------------------| +** |Field Name| Data Type | Description | +** |----------------------------------------------------------------| +** |TYPE | INTEGER | Bind/precompile/rebind option type. | +** |VAL | INTEGER | Bind/precompile/rebind option value. | +** |----------------------------------------------------------------| +** |Note: | +** |The TYPE and VAL fields are repeated for each bind/precompile/ | +** |rebind option specified. | +** |----------------------------------------------------------------| +*******************************************************************************/ +SQL_STRUCTURE sqloptions /* bind/prep/rebind option */ +{ + sqluint32 type; /* Type of bind/prep/rebind option */ + sqluintptr val; /* Value of bind/prep/rebind option */ +}; + +/****************************************************************************** +** sqlopt data structure +** This structure is used to pass bind options to the sqlabndx API, +** precompile options to the sqlaprep API, and rebind options to the +** sqlarbnd API. + +** Table: Fields in the SQLOPT Structure +** |----------------------------------------------------------------| +** |Field Name| Data Type|Description | +** |----------|----------|------------------------------------------| +** |HEADER | Structure|An sqloptheader structure. | +** |----------|----------|------------------------------------------| +** |OPTION | Array |An array of sqloptions structures. The | +** | | |number of elements in this array is | +** | | |determined by the value of the allocated | +** | | |field of the header. | +** |----------|----------|------------------------------------------| + +** COBOL Structure + +** * File: sql.cbl +** 01 SQLOPT. +** 05 SQLOPTHEADER. +** 10 ALLOCATED PIC 9(9) COMP-5. +** 10 USED PIC 9(9) COMP-5. +** 05 SQLOPTIONS OCCURS 1 TO 50 DEPENDING ON ALLOCATED. +** 10 SQLOPT-TYPE PIC 9(9) COMP-5. +** 10 SQLOPT-VAL PIC 9(9) COMP-5. +** 10 SQLOPT-VAL-PTR REDEFINES SQLOPT-VAL +** * +*******************************************************************************/ +SQL_STRUCTURE sqlopt +{ + SQL_STRUCTURE sqloptheader header; /* Header for sqlopt structure */ + SQL_STRUCTURE sqloptions option[1]; /* Array of bind/prep/rebind options */ +}; + +#define SQL_BIND_OPTS +#endif + +/* Values used for option[n].type in the sqloptions structure */ +/* of sqlabndx(), sqlaprep() and sqlarbnd(). */ +#define SQL_DATETIME_OPT 1 /* Option for date/time format - bind */ + /* and precompile option */ +#define SQL_STANDARDS_OPT 2 /* Option for standards level */ + /* compliance - precompile option */ + /* only */ +#define SQL_ISO_OPT 4 /* Option for isolation level - bind */ + /* and precompile option */ +#define SQL_BLOCK_OPT 5 /* Option for record blocking - bind */ + /* and precompile option */ +#define SQL_GRANT_OPT 6 /* Option for granting privileges - */ + /* bind option only */ +#define SQL_FLAG_OPT 8 /* Option for the Flagger - */ + /* precompile option only */ +#define SQL_GRANT_USER_OPT 9 /* Option for granting privileges to */ + /* a user - bind option only */ +#define SQL_GRANT_GROUP_OPT 10 /* Option for granting privileges to */ + /* a group - bind option only */ +#define SQL_CNULREQD_OPT 11 /* Option for adding NULLs to strings */ + /* - bind option only */ +#define SQL_GENERIC_OPT 12 /* Generic option for DRDA servers - */ + /* bind option only */ +#define SQL_DEFERRED_PREPARE_OPT 15 /* Option for Deferred Prepare - */ + /* precompile option only */ +#define SQL_CONNECT_OPT 16 /* Specifies whether one or multiple */ + /* connections are allowed */ + /* similtaneously within a unit of */ + /* work. */ +#define SQL_RULES_OPT 17 /* Specifies the set of rules used */ + /* for connection to multiple */ + /* databases within a single unit of */ + /* work */ +#define SQL_DISCONNECT_OPT 18 /* Specifies which of multiple */ + /* databases connected to will be */ + /* disconnected when a COMMIT or */ + /* ROLLBACK is issued. */ +#define SQL_SYNCPOINT_OPT 19 /* Specifies what syncpoint option */ + /* (for example one phase or two */ + /* phase) will be used */ +#define SQL_BIND_OPT 20 /* Option to create a bind file - */ + /* precompile option only */ +#define SQL_SAA_OPT 21 /* Option specifies SAA/non-SAA */ + /* compatibility - FORTRAN precompile */ + /* option only */ +#define SQL_PKG_OPT 23 /* Option to create a package with a */ + /* specific name - precompile option */ + /* only */ +#define SQL_OPTIM_OPT 24 /* Option to specify SQLDA */ + /* optimization - precompile option */ + /* only */ +#define SQL_SYNTAX_OPT 25 /* Option to not create a package or */ + /* bind file - precompile option only */ +#define SQL_SQLERROR_OPT SQL_SYNTAX_OPT /* Indicates under what */ + /* conditions a package will be be */ + /* created - bind and precompile */ + /* option */ +#define SQL_LINEMACRO_OPT 26 /* Option to suppress #line macro */ + /* generation in modified source file */ + /* - C precompile option only */ +#define SQL_NO_OPT 27 /* 'No-op' option - ignore this entry */ + /* in the option array - bind, */ + /* precompile and rebind option */ +#define SQL_LEVEL_OPT 30 /* Level of a module - precompile */ + /* option only */ +#define SQL_COLLECTION_OPT 31 /* Package collection identifier - */ + /* precompile option only */ +#define SQL_VERSION_OPT 32 /* Package version identifier - */ + /* precompile and rebind option only */ +#define SQL_OWNER_OPT 33 /* Package owner authorization */ + /* identifier - bind and precompile */ + /* option */ +#define SQL_SCHEMA_OPT SQL_OWNER_OPT /* Synonym for owner - bind and */ + /* precompile option */ +#define SQL_QUALIFIER_OPT 34 /* Authorization identifier that is */ + /* to be used as a qualifier for */ + /* unqualified objects - bind and */ + /* precompile option */ +#define SQL_CATALOG_OPT SQL_QUALIFIER_OPT /* Synonym for qualifier - */ + /* bind and precompile option */ +#define SQL_TEXT_OPT 35 /* Package description - bind and */ + /* precompile option */ +#define SQL_VALIDATE_OPT 40 /* Indicates when object validation */ + /* occurs - bind and precompile */ + /* option */ +#define SQL_EXPLAIN_OPT 41 /* Determines whether information */ + /* will be produced about how the SQL */ + /* statements in a package will be */ + /* executed - bind and precompile */ + /* option */ +#define SQL_ACTION_OPT 42 /* Indicates whether a package is to */ + /* be added or replaced - bind and */ + /* precompile option */ +#define SQL_REPLVER_OPT 44 /* Replaces a specific version of a */ + /* package - bind and precompile */ + /* option */ +#define SQL_RETAIN_OPT 45 /* Indicates whether EXECUTE */ + /* authorities are to be preserved */ + /* when a package is replaced - bind */ + /* and precompile option */ +#define SQL_RELEASE_OPT 46 /* Indicates whether resources are */ + /* released at each COMMIT or when */ + /* the application terminates - bind */ + /* and precompile option */ +#define SQL_DEGREE_OPT 47 /* Specifies whether or not the query */ + /* is executed using I/O parallelism */ + /* bind and precompile option */ +#define SQL_STRDEL_OPT 50 /* Designates whether an apostrophe */ + /* or quote will be used as a string */ + /* delimiter - bind and precompile */ + /* option */ +#define SQL_DECDEL_OPT 51 /* Designates whether a period or */ + /* comma will be used as a decimal */ + /* point indicator - bind and */ + /* precompile option */ +#define SQL_CHARSUB_OPT 55 /* Designates default character */ + /* subtype that is to be used for */ + /* column definitions in the CREATE */ + /* and ALTER TABLE SQL statements - */ + /* bind and precompile option */ +#define SQL_CCSIDS_OPT 56 /* Designates what CCSID will be used */ + /* for single byte characters for */ + /* character column definitions */ + /* without a specific CCSID clause in */ + /* the CREATE and ALTER TABLE SQL */ + /* statements - bind and precompile */ + /* option */ +#define SQL_CCSIDM_OPT 57 /* Designates what CCSID will be used */ + /* for mixed byte characters for */ + /* character column definitions */ + /* without a specific CCSID clause in */ + /* the CREATE and ALTER TABLE SQL */ + /* statements - bind and precompile */ + /* option */ +#define SQL_CCSIDG_OPT 58 /* Designates what CCSID will be used */ + /* for double byte characters for */ + /* character column definitions */ + /* without a specific CCSID clause in */ + /* the CREATE and ALTER TABLE SQL */ + /* statements - bind and precompile */ + /* option */ +#define SQL_DEC_OPT 59 /* Specifies maximum precision to be */ + /* used in decimal arithmetic */ + /* operations - bind and precompile */ + /* option */ +#define SQL_WCHAR_OPT 60 /* Specifies handling of graphic */ + /* vars. - precompile only */ +#define SQL_DYNAMICRULES_OPT 61 /* Specifies which authorization */ + /* identifier to use when dynamic SQL */ + /* in a package is executed - bind */ + /* and precompile option */ +#define SQL_INSERT_OPT 62 /* Buffers VALUE inserts - bind and */ + /* precompile option for DB2/PE */ + /* servers only */ +#define SQL_EXPLSNAP_OPT 63 /* Capture explain snapshot - bind */ + /* and precompile option */ +#define SQL_FUNCTION_PATH 64 /* Path for user-defined function */ + /* resolution - bind and precompile */ + /* option */ +#define SQL_SQLWARN_OPT 65 /* Disable prepare-time SQL warnings */ + /* bind and precompile option */ +#define SQL_QUERYOPT_OPT 66 /* Set query optimization class - */ + /* bind and precompile option */ +#define SQL_TARGET_OPT 67 /* Target compiler - precompile */ + /* option */ +#define SQL_PREP_OUTPUT_OPT 68 /* Name of precompiler output file - */ + /* precompile option */ +#define SQL_PREPROCESSOR_OPT 69 /* Preprocessor command - precompile */ + /* option only */ +#define SQL_RESOLVE_OPT 70 /* Indicates whether function and */ + /* type resolution should or should */ + /* not use conservative binding */ + /* semantics - rebind option only */ +#define SQL_CLIPKG_OPT 71 /* CLIPKG option - bind option only */ +#define SQL_FEDERATED_OPT 72 /* FEDERATED option - bind and */ + /* precompile option */ +#define SQL_TRANSFORMGROUP_OPT 73 /* Transform Group - precompile and */ + /* bind option */ +#define SQL_LONGERROR_OPT 74 /* Option to treat long host variable */ + /* declarations as errors - */ + /* precompile option only */ +#define SQL_DECTYPE_OPT 75 /* DECTYPE Option to convert decimals */ + /* precompile option only */ +#define SQL_KEEPDYNAMIC_OPT 76 /* Specifies whether dynamic SQL */ + /* statements are to be kept after */ + /* commit points - bind and */ + /* precompile option */ +#define SQL_DBPROTOCOL_OPT 77 /* Specifies what protocol to use */ + /* when connecting to a remote site */ + /* that is identified by a three-part */ + /* name statement - bind and */ + /* precompile option */ +#define SQL_OPTHINT_OPT 78 /* Controls whether query */ + /* optimization hints are used for */ + /* static SQL - bind and precompile */ + /* option */ +#define SQL_IMMEDWRITE_OPT 79 /* Tells whether immediate writes */ + /* will be done for updates made to */ + /* group buffer pool dependent */ + /* pagesets or partitions - bind and */ + /* precompile option */ +#define SQL_ENCODING_OPT 80 /* Specifies the encoding for all */ + /* host variables in static */ + /* statements in the plan or package */ + /* (bind and precompile option) */ +#define SQL_OS400NAMING_OPT 81 /* Specifies which naming option is */ + /* to be used when accessing DB2 UDB */ + /* for iSeries data - bind and */ + /* precompile option */ +#define SQL_SORTSEQ_OPT 82 /* Specifies which sort sequence */ + /* table to use on the iSeries system */ + /* - bind and precompile option */ +#define SQL_REOPT_OPT 83 /* Specifies whether to have DB2 */ + /* determine an access path at run */ + /* time using values for host */ + /* variables, parameter markers, and */ + /* special registers - bind and */ + /* precompile option */ +#define SQL_PSM_OPT 84 /* PSM option - bind option */ +#define SQL_CALL_RES_OPT 85 /* Specifies whether to use immediate */ + /* ordeferred procedure */ + /* resolutionprecompile option */ +#define SQL_TIMESTAMP_OPT 86 /* Option for date/time format - bind */ + /* and precompile option */ +#define SQL_STATICREADONLY_OPT 87 /* Specifies whether static cursors */ + /* will be treated as read-only if */ + /* they are ambiguous - precompile */ + /* and bind option */ +#define SQL_OPTPROFILE_OPT 88 /* Specifies a two-part name of the */ + /* form [schemaname.]basename where */ + /* basename is a character string of */ + /* up to 128 chars in length used to */ + /* uniquely identify the optimization */ + /* profile within a particular */ + /* schema. Schemaname is a character */ + /* string identifier of up to 30 */ + /* bytes used to explicitelyqualify */ + /* an optimization profile schema. */ +#define SQL_FEDASYNC_OPT 89 /* Specifies whether or not the query */ + /* is executed using asynchrony */ +#define SQL_NODB_OPT 90 /* Specifies that a database should */ + /* not be used during precompile. */ + /* The BINDFILE and VALIDATE RUN */ + /* options will be implicitely */ + /* specified. */ + +#define SQL_NUM_OPTS 90 /* # of PREP/BIND/REBIND options */ + +/* Values used for option[n].val when option[n].type is */ +/* SQL_DATETIME_OPT. These can also be used for the date/time */ +/* format parameter of sqlabind(). */ + +#define SQL_DATETIME_DEF 48 /* FORMAT = Default for Country Code */ +#define SQL_DATETIME_USA 49 /* FORMAT = USA */ +#define SQL_DATETIME_EUR 50 /* FORMAT = EUR */ +#define SQL_DATETIME_ISO 51 /* FORMAT = ISO */ +#define SQL_DATETIME_JIS 52 /* FORMAT = JIS */ +#define SQL_DATETIME_LOC 53 /* FORMAT = LOCAL */ + +/* The following constants are here for backwards compatbility with earlier */ +/* releases. */ + +#define SQL_FRMT_OPT SQL_DATETIME_OPT +#define SQL_FMT_0 SQL_DATETIME_DEF +#define SQL_FMT_1 SQL_DATETIME_USA +#define SQL_FMT_2 SQL_DATETIME_EUR +#define SQL_FMT_3 SQL_DATETIME_ISO +#define SQL_FMT_4 SQL_DATETIME_JIS +#define SQL_FMT_5 SQL_DATETIME_LOC + +/* Values used for option[n].val when option[n].type is SQL_STANDARDS_OPT. */ +#define SQL_SAA_COMP 0 /* SAA Level 1 Database CPI */ +#define SQL_MIA_COMP 1 /* MIA */ +#define SQL_SQL92E_COMP 2 /* SQL92 Entry */ + +/* Values used for option[n].val when option[n].type is SQL_ISO_OPT */ +#define SQL_REP_READ 0 /* Repeatable read level */ +#define SQL_CURSOR_STAB 1 /* Cursor stability level */ +#define SQL_UNCOM_READ 2 /* Uncommitted read level */ +#define SQL_READ_STAB 3 /* Read stability level */ +#define SQL_NO_COMMIT 4 /* No Commit level l */ + +/* Values used for option[n].val when option[n].type is SQL_BLOCK_OPT */ +#define SQL_BL_UNAMBIG 0 /* Block Unambiguous cursors */ +#define SQL_BL_ALL 1 /* Block All cursors */ +#define SQL_NO_BL 2 /* Block No cursors */ + +/* Values used for option[n].val when option[n].type is SQL_FLAG_OPT */ +#define SQL_MVSDB2V23_SYNTAX 4 /* Flagger check against MVS */ +#define SQL_MVSDB2V31_SYNTAX 5 /* DB2 V2.3, V3.1 or V4.1 SQL */ +#define SQL_MVSDB2V41_SYNTAX 6 /* syntax */ +#define SQL_SQL92E_SYNTAX 7 /* FIPS flagger SQL92E syntax */ + +/* Values used for option[n].val when option[n].type is SQL_CNULREQD_OPT */ +#define SQL_CNULREQD_NO 0 /* C NULL value not required */ +#define SQL_CNULREQD_YES 1 /* C NULL value required */ + +/* Maximum sqlchar length for option[n].val when option[n].type is SQL */ +/* GENERIC_OPT */ +#define SQL_MAX_GENERIC 1023 + +/* Values used for option[n].val when option[n].type is SQL_SAA_OPT. */ +#define SQL_SAA_NO 0 /* SQLCA definition not SAA */ + /* compatible */ +#define SQL_SAA_YES 1 /* SQLCA definition is SAA compatible */ + +/* Values used for option[n].val when option[n].type is SQL_OPTIM_OPT. */ +#define SQL_DONT_OPTIMIZE 0 /* Do not optimize SQLDA */ + /* initialization */ +#define SQL_OPTIMIZE 1 /* Optimize SQLDA initialization */ + +/* Values used for option[n].val when option[n].type is SQL_SYNTAX_OPT. */ +#define SQL_NO_SYNTAX_CHECK 0 /* Create a package and/or a bind */ + /* file */ +#define SQL_SYNTAX_CHECK 1 /* Do not create a package or bind */ + /* file */ + +/* Values used for option[n].val when option[n].type is SQL_LINEMACRO_OPT. */ +#define SQL_NO_LINE_MACROS 0 /* Do not generate #line macros in */ + /* modified source file */ +#define SQL_LINE_MACROS 1 /* Generate #line macros in modified */ + /* source file */ + +/* Values used for option[n].val when option[n].type is SQL_WCHAR_OPT. */ +#define SQL_WCHAR_NOCONVERT 0 /* graphic variable not converted */ +#define SQL_WCHAR_CONVERT 1 /* graphic variable converted */ + +/* Maximum sqlchar length for option[n].val when option[n].type is SQL_LEVEL */ +/* OPT */ +#define SQL_MAX_LEVEL 8 + +/* Values used for option[n].val when option[n].type is SQL_CONNECT_OPT */ +#define SQL_DEFERRED_PREPARE_YES 1 /* Dynamic SQL statements will be */ + /* chained. */ +#define SQL_DEFERRED_PREPARE_NO 2 /* Dynamic SQL statements will not be */ + /* chained. */ +#define SQL_DEFERRED_PREPARE_ALL 3 /* Dynamic SQL statements will be */ + /* chained in all cases. The */ + /* application must not allocate host */ + /* vars a FETCH SQLDA until after the */ + /* OPEN statement for the cursor. */ + +/* Maximum sqlchar length for option[n].val when option[n].type is SQL */ +/* COLLECTION_OPT */ +#define SQL_MAX_COLLECTION 30 + +/* Maximum sqlchar length for option[n].val when option[n].type is SQL */ +/* VERSION_OPT */ +#define SQL_MAX_VERSION 254 + +/* Maximum sqlchar length for option[n].val when option[n].type is SQL_OWNER */ +/* OPT */ +#define SQL_MAX_OWNER 30 + +/* Maximum sqlchar length for option[n].val when option[n].type is SQL */ +/* SCHEMA_OPT */ +#define SQL_MAX_SCHEMA SQL_MAX_OWNER + +/* Maximum sqlchar length for option[n].val when option[n].type is SQL */ +/* QUALIFIER_OPT */ +#define SQL_MAX_QUALIFIER 30 + +/* Maximum sqlchar length for option[n].val when option[n].type is SQL */ +/* CATALOG_OPT */ +#define SQL_MAX_CATALOG SQL_MAX_QUALIFIER + +/* Maximum sqlchar length for option[n].val when option[n].type is SQL_TEXT */ +/* OPT */ +#define SQL_MAX_TEXT 255 + +/* Maximum sqlchar length for option[n].val when option[n].type is SQL */ +/* PREPROCESSOR_OPT */ +#define SQL_MAX_PREPROCESSOR 1024 + +/* Maximum sqlchar length for option[n].val when option[n].type is SQL */ +/* TRANSFORMGROUP_OPT */ +#define SQL_MAX_TRANSFORMGROUP 18 + +/* Values used for option[n].val when option[n].type is SQL_VALIDATE_OPT */ +#define SQL_VALIDATE_BIND 0 /* Validate objects during BIND */ +#define SQL_VALIDATE_RUN 1 /* Validate objects during execution */ + +/* Values used for option[n].val when option[n].type is SQL_EXPLAIN_OPT */ +#define SQL_EXPLAIN_NO 0 /* No Explain output saved */ +#define SQL_EXPLAIN_YES 1 /* Explain output saved */ +#define SQL_EXPLAIN_ALL 2 /* Explain output saved for all */ + /* static and dynamic statements */ +#define SQL_EXPLAIN_REOPT 3 /* Explain output saved for static */ + /* reoptimizable statements */ + +/* Values used for option[n].val when option[n].type is SQL_ACTION_OPT */ +#define SQL_ACTION_ADD 0 /* Package is to be added */ +#define SQL_ACTION_REPLACE 1 /* Package is to be replaced */ + +/* Max/Min value of CLIPKG for option[n].val when option[n].type is SQL */ +/* CLIPKG_OPT */ +#define SQL_MIN_CLIPKG 3 +#define SQL_MAX_CLIPKG 30 + +/* Maximum sqlchar length for option[n].val when option[n].type is SQL */ +/* REPLVER_OPT */ +#define SQL_MAX_REPLVER 254 + +/* Values used for option[n].val when option[n].type is SQL_SQLERROR_OPT */ +#define SQL_SQLERROR_NOPACKAGE SQL_NO_SYNTAX_CHECK /* Do not create a */ + /* package if errors are encountered */ +#define SQL_SQLERROR_CHECK SQL_SYNTAX_CHECK /* Do not create a package */ +#define SQL_SQLERROR_CONTINUE 2 /* Create a package even if errors */ + /* are encountered */ + +/* Values used for option[n].val when option[n].type is SQL_RETAIN_OPT */ +#define SQL_RETAIN_NO 0 /* Do not preserve EXECUTE */ + /* authorities when a package is */ + /* replaced */ +#define SQL_RETAIN_YES 1 /* Preserve EXECUTE authorities when */ + /* a package is replaced */ + +/* Values used for option[n].val when option[n].type is SQL_RELEASE_OPT */ +#define SQL_RELEASE_COMMIT 0 /* Release resources at COMMIT */ +#define SQL_RELEASE_DEALLOCATE 1 /* Release resources when the program */ + /* terminates */ + +/* Values used for option[n].val when option[n].type is SQL_STRDEL_OPT */ +#define SQL_STRDEL_APOSTROPHE 0 /* Apostrophe string delimiter */ +#define SQL_STRDEL_QUOTE 1 /* Quote string delimiter */ + +/* Values used for option[n].val when option[n].type is SQL_DECDEL_OPT */ +#define SQL_DECDEL_PERIOD 0 /* Period is used as a decimal point */ + /* indicator in decimal and floating */ + /* point literals */ +#define SQL_DECDEL_COMMA 1 /* Comma is used as a decimal point */ + /* indicator in decimal and floating */ + /* point literals */ + +/* Values used for option[n].val when option[n].type is SQL_CHARSUB_OPT */ +#define SQL_CHARSUB_DEFAULT 0 /* Use the target system defined */ + /* default for all new character */ + /* columns for which an explicit */ + /* subtype is not specified */ +#define SQL_CHARSUB_BIT 1 /* Use the BIT character subtype for */ + /* all new character columns for */ + /* which an explicit subtype is not */ + /* specified */ +#define SQL_CHARSUB_SBCS 2 /* Use the SBCS character subtype for */ + /* all new character columns for */ + /* which an explicit subtype is not */ + /* specified */ +#define SQL_CHARSUB_MIXED 3 /* Use the mixed character subtype */ + /* for all new character columns for */ + /* which an explicit subtype is not */ + /* specified */ + +/* Values used for option[n].val when option[n].type is SQL_DEC_OPT */ +#define SQL_DEC_15 15 /* 15 bit precision is used in */ + /* decimal arithmetic operations */ +#define SQL_DEC_31 31 /* 31 bit precision is used in */ + /* decimal arithmetic operations */ + +/* Values used for option[n].val when option[n].type is SQL_DEGREE_OPT */ +#define SQL_DEGREE_1 1 /* Prohibits parallel I/O operations */ +#define SQL_DEGREE_ANY 0 /* Allows the target database system */ + /* to determine the degree of */ + /* parallel I/O operations */ +#define SQL_MAX_DEGREE_VAL 32767 /* Maximum value */ + +/* Values used for option[n].val when option[n].type is SQL_VERSION_OPT */ +#define SQL_VERSION_AUTO "AUTO" /* Use the timestamp to generate the */ + /* package VERSION */ + +/* The next four option values (for CONNECT type, SQLRULES, DISCONNECT and */ +/* SYNCPOINT) are used not only by the precompiler but also by the sqlesetc */ +/* and sqleqryc APIs. */ + +/* Values used for option[n].val when option[n].type is SQL_CONNECT_OPT */ +#define SQL_CONNECT_1 1 /* Indicates that only one connection */ + /* to a database can exist at any */ + /* given time. */ +#define SQL_CONNECT_2 2 /* Indicates that multiple */ + /* connections can exist */ + /* simultaneously, with one being */ + /* active and the others dormant. */ + +/* Values used for option[n].val when option[n].type is SQL_RULES_OPT */ +#define SQL_RULES_DB2 1 /* Indicates that CONNECT TO can be */ + /* used to make a dormant connection */ + /* the current connection. */ +#define SQL_RULES_STD 2 /* Indicates that CONNECT TO is not */ + /* valid for making a dormant */ + /* connection current, and SET */ + /* CONNECTION must be used instead. */ + +/* Values used for option[n].val when option[n].type is SQL_DISCONNECT_OPT */ +#define SQL_DISCONNECT_EXPL 1 /* Indicates that all connections */ + /* marked by the RELEASE statement */ + /* will be the only connections */ + /* released when a COMMIT is issued. */ +#define SQL_DISCONNECT_COND 2 /* Indicates that all connections */ + /* that do not have open WITH HOLD */ + /* cursors will be the only */ + /* connections released when a COMMIT */ + /* is issued. */ +#define SQL_DISCONNECT_AUTO 3 /* Indicates that all connections */ + /* will be released when a COMMIT is */ + /* issued. */ + +/* Values used for option[n].val when option[n].type is SQL_SYNCPOINT_OPT */ +#define SQL_SYNC_ONEPHASE 1 /* Do not use a transaction manager */ + /* to perform two phase commit, but */ + /* enforce that there is only one */ + /* database is updated when multiple */ + /* databases are accessed within a */ + /* single transaction. */ +#define SQL_SYNC_TWOPHASE 2 /* Use a transaction manager to */ + /* coordinate two phase commit. */ +#define SQL_SYNC_NONE 0 /* No update enforcement or two phase */ + /* commit protocol will be used. */ + +/* The next option value (for SQL_CONNECT_NODE) is used only by the sqlesetc */ +/* and sqleqryc APIs. */ +#define SQL_CONN_CATALOG_NODE 0xfffe /* Connect to the catalog node */ + +/* Values used for option[n].val when option[n].type is SQL_DYNAMICRULES_OPT */ +#define SQL_DYNAMICRULES_RUN 0 /* Dynamic SQL in package will use */ + /* authid of person running the */ + /* package */ +#define SQL_DYNAMICRULES_BIND 1 /* Dynamic SQL in package will use */ + /* authid of person who owns the */ + /* package */ +#define SQL_DYNAMICRULES_INVOKERUN 2 /* Dynamic SQL in a routine will use */ + /* authid of invoker of routine */ +#define SQL_DYNAMICRULES_DEFINERUN 3 /* Dynamic SQL in a routine will use */ + /* authid of definer of routine */ +#define SQL_DYNAMICRULES_INVOKEBIND 4 /* Dynamic SQL in a routine will use */ + /* authid of invoker of routine */ +#define SQL_DYNAMICRULES_DEFINEBIND 5 /* Dynamic SQL in a routine will use */ + /* authid of definer of routine */ + +/* Values used for option[n].val when option[n].type is SQL_INSERT_OPT */ +#define SQL_INSERT_DEF 0 /* Do not buffer VALUE inserts */ +#define SQL_INSERT_BUF 1 /* Buffer VALUE inserts */ + +/* Values used for option[n].val when option[n].type is SQL_EXPLSNAP_OPT */ +#define SQL_EXPLSNAP_NO 0 /* No Explain snapshot saved */ +#define SQL_EXPLSNAP_YES 1 /* Explain snapshot saved */ +#define SQL_EXPLSNAP_ALL 2 /* Explain snapshot saved for all */ + /* static and dynamic statements */ +#define SQL_EXPLSNAP_REOPT 3 /* Explain snapshot saved for static */ + /* reoptimizable statements */ + +/* Maximum sqlchar length for option[n].val when option[n].type is SQL */ +/* FUNCTION_PATH */ +#define SQL_MAX_FUNCPATH 254 + +/* Values used for option[n].val when option[n].type is SQL_SQLWARN_OPT */ +#define SQL_SQLWARN_NO 0 /* Suppress prepare-time warning */ + /* SQLCODEs */ +#define SQL_SQLWARN_YES 1 /* Permit prepare-time warning */ + /* SQLCODEs */ + +/* Values used for option[n].val when option[n].type is SQL_QUERYOPT_OPT */ +#define SQL_QUERYOPT_0 0 /* Class 0 query optimization */ +#define SQL_QUERYOPT_1 1 /* Class 1 query optimization */ +#define SQL_QUERYOPT_2 2 /* Class 2 query optimization */ +#define SQL_QUERYOPT_3 3 /* Class 3 query optimization */ +#define SQL_QUERYOPT_5 5 /* Class 5 query optimization */ +#define SQL_QUERYOPT_7 7 /* Class 7 query optimization */ +#define SQL_QUERYOPT_9 9 /* Class 9 query optimization */ + +/* Maximum sqlchar length for option[n].val when option[n].type is SQL */ +/* TARGET_OPT */ +#define SQL_MAX_TARGET_LEN 32 + +/* Values used for option[n].val when option[n].type is SQL_RESOLVE_OPT */ +#define SQL_RESOLVE_ANY 0 /* Conservative binding semantics are */ + /* not used */ +#define SQL_RESOLVE_CONSERVATIVE 1 /* Conservative binding semantics are */ + /* used */ + +/* Values used for option[n].val when option[n].type is SQL_FEDERATED_OPT */ +#define SQL_FEDERATED_NO 0 /* Federated systems are not */ + /* supported */ +#define SQL_FEDERATED_YES 1 /* Federated systems are supported */ +/* Values used for option[n].val when option[n].type is SQL_PSM_OPT */ +#define SQL_PSM_NO 0 /* PSM no */ +#define SQL_PSM_YES 1 /* PSM yes */ + +/* Values used for option[n].val when option[n].type is SQL_LONGERROR_OPT. */ +#define SQL_LONGERROR_NO 0 /* Do not generate errors for the use */ + /* of long host variable declarations */ +#define SQL_LONGERROR_YES 1 /* Generate errors for the use of */ + /* long host variable declarations */ + +/* Values used for option[n].val when option[n].type is SQL_DECTYPE_OPT. */ +#define SQL_DECTYPE_NOCONVERT 0 /* Decimal type not converted */ +#define SQL_DECTYPE_CONVERT 1 /* Decimal type converted */ + +/* Values used for option[n].val when option[n].type is SQL_KEEPDYNAMIC_OPT */ +#define SQL_KEEPDYNAMIC_NO 0 /* Do not keep dynamic SQL statements */ + /* after commit points */ +#define SQL_KEEPDYNAMIC_YES 1 /* Keep dynamic SQL statements after */ + /* commit points */ + +/* Values used for option[n].val when option[n].type is SQL_DBPROTOCOL_OPT */ +#define SQL_DBPROTOCOL_DRDA 0 /* Use DRDA protocol when connecting */ + /* to a remote site that is */ + /* identified by a three-part name */ + /* statement */ +#define SQL_DBPROTOCOL_PRIVATE 1 /* Use a private protocol when */ + /* connecting to a remote site that */ + /* is identified by a three-part name */ + /* statement */ + +/* Values used for option[n].val when option[n].type is SQL_IMMEDWRITE_OPT */ +#define SQL_IMMEDWRITE_NO 0 /* Updated pages are written at or */ + /* before phase two of commit */ +#define SQL_IMMEDWRITE_YES 1 /* Updated pages are written as soon */ + /* as the buffer update completes */ +#define SQL_IMMEDWRITE_PH1 2 /* Updated pages are written at or */ + /* before phase one of commit */ + +/* Values used for option[n].val when option[n].type is SQL_ENCODING_OPT */ +#define SQL_ENCODING_ASCII 0 /* Host variables in static */ + /* statements are encoded in ascii */ +#define SQL_ENCODING_EBCDIC 1 /* Host variables in static */ + /* statements are encoded in ebcdic */ +#define SQL_ENCODING_UNICODE 2 /* Host variables in static */ + /* statements are encoded in unicode */ + +/* Values used for option[n].val when option[n].type is SQL_OS400NAMING_OPT */ +#define SQL_OS400NAMING_SYSTEM 0 /* Use the iSeries system naming */ + /* option when accessing DB2 UDB for */ + /* iSeries data */ +#define SQL_OS400NAMING_SQL 1 /* Use the SQL naming option when */ + /* accessing DB2 UDB for iSeries data */ + +/* Values used for option[n].val when option[n].type is SQL_SORTSEQ_OPT */ +#define SQL_SORTSEQ_JOBRUN 0 /* Use the NLSS sort sequence table */ + /* of the DRDA job on the iSeries */ + /* system */ +#define SQL_SORTSEQ_HEX 1 /* Use the EBCDIC sort sequence table */ + /* of the DRDA job on the iSeries */ + /* system */ + +/* Values used for option[n].val when option[n].type is SQL_REOPT_OPT */ +#define SQL_REOPT_NO 0 /* Do not determine an access path at */ + /* run time using values for host */ + /* variables, parameter markers, and */ + /* special registers */ +#define SQL_REOPT_YES 1 /* Re-determine an access path at run */ + /* time using values for host */ + /* variables, parameter markers, and */ + /* special registers */ +#define SQL_REOPT_NONE 2 /* The access path is determined */ + /* based on the default estimates for */ + /* host variables, parameter markers, */ + /* and special registers */ +#define SQL_REOPT_ONCE 3 /* Re-determine an access path only */ + /* once at run time using values for */ + /* host variables, parameter markers, */ + /* and special registers */ +#define SQL_REOPT_ALWAYS 4 /* Re-determine an access path at */ + /* every execution values for host */ + /* variables, parameter markers, and */ + /* special registers */ + +/* Values used for option[n].val when option[n].type is SQL_CALL_RES_OPT */ +#define SQL_CALL_RES_IMMED 0 /* Immediate SP call resolution */ +#define SQL_CALL_RES_DEFERRED 1 /* Deferred SP call resolution */ + +/* Values used for option[n].val when option[n].type is SQL_STATICREADONLY */ +/* OPT */ +#define SQL_STATICRO_NO 0 /* Static cursors take on attributes */ + /* as wouldnormally be generated */ + /* given the statementtext and */ + /* setting of the LANGLEVEL option. */ +#define SQL_STATICRO_YES 1 /* Any static cursor that does not */ + /* contain theFOR UPDATE or FOR READ */ + /* ONLY clause will beconsidered READ */ + /* ONLY. */ + +/* Values used for option[n].val when option[n].type is SQL_NODB_OPT. */ +#define SQL_USEDB 0 /* Use a database to precompiler. */ +#define SQL_NODB 1 /* Do not use a database to */ + /* precompile. */ + +/* Values used for option[n].val when option[n].type is SQL_FEDASYNC_OPT */ +#define SQL_FEDASYNC_MIN 0 /* No asynchrony is used */ +#define SQL_FEDASYNC_ANY -1 /* Allows the optimizer to determine */ + /* the level of asynchrony */ +#define SQL_FEDASYNC_MAX 64000 /* Maximum value */ + +/* Binder Interface Parameters/Return Codes */ + +/****************************************************************************** +** sqlabndx API +** Invokes the bind utility, which prepares SQL statements stored in the +** bind file generated by the precompiler, and creates a package that is +** stored in the database. +** +** Scope +** +** This API can be called from any database partition server in db2nodes.cfg. It +** updates the database catalogs on the catalog partition. Its effects are +** visible to all database partition servers. +** +** Authorization +** +** One of the following: +** - sysadm or dbadm authority +** - BINDADD privilege if a package does not exist and one of: +** -- IMPLICIT_SCHEMA authority on the database if the schema name +** of the package does not exist +** -- CREATEIN privilege on the schema if the schema name of the +** package exists +** - ALTERIN privilege on the schema if the package exists +** - BIND privilege on the package if it exists. +** +** The user also needs all privileges required to compile any static SQL +** statements in the application. Privileges granted to groups are not used for +** authorization checking of static statements. If the user has sysadm +** authority, but not explicit privileges to complete the bind, the database +** manager grants explicit dbadm authority automatically. +** +** Required connection +** +** Database +** +** API include file +** +** sql.h +** +** sqlabndx API parameters +** +** pBindFileName +** Input. A string containing the name of the bind file, or the name of a file +** containing a list of bind file names. The bind file names must contain the +** extension .bnd. A path for these files can be specified. +** +** Precede the name of a bind list file with the at sign (@). For example, a +** fully qualified bind list file name might be: /u/user1/bnd/@all.lst +** +** The bind list file should contain one or more bind file names, and must have +** the extension .lst. +** +** Precede all but the first bind file name with a plus symbol (+). The bind +** file names may be on one or more lines. For example, the bind list file +** all.lst might contain: +** mybind1.bnd+mybind2.bnd+ +** mybind3.bnd+ +** mybind4.bnd +** +** Path specifications on bind file names in the list file can be used. +** If no path is specified, the database manager takes path information +** from the bind list file. +** +** pMsgFileName +** Input. A string containing the destination for error, warning, and +** informational messages. Can be the path and the name of an operating system +** file, or a standard device. If a file already exists, it is overwritten. +** If it does not exist, a file is created. +** +** pBindOptions +** Input. A structure used to pass bind options to the API. For more information +** about this structure, see SQLOPT. +** +** pSqlca +** Output. A pointer to the sqlca structure. +** +** Usage notes +** +** Binding can be done as part of the precompile process for an application +** program source file, or as a separate step at a later time. Use BIND when +** binding is performed as a separate process. +** +** The name used to create the package is stored in the bind file, and is +** based on the source file name from which it was generated (existing paths +** or extensions are discarded). For example, a precompiled source file +** called myapp.sqc generates a default bind file called myapp.bnd and a +** default package name of MYAPP. (However, +** the bind file name and the +** package name can be overridden at precompile time by using the +** SQL_BIND_OPT and the SQL_PKG_OPT options of sqlaprep.) +** +** BIND executes under the transaction that the user has started. After +** performing the bind, BIND issues a COMMIT (if bind is successful) or a +** ROLLBACK (if bind is unsuccessful) operation to terminate the current +** transaction and start another one. +** +** Binding halts if a fatal error or more than 100 errors occur. If a +** fatal error occurs during binding, BIND stops binding, attempts to +** close all files, and discards the package. +** +** Binding application programs have prerequisite requirements and restrictions +** beyond the scope of this manual. For example, an application cannot be bound +** from a V8 client to a V8 server, and then executed against a V7 server. +** +** The Bind option types and values are defined in sql. +** +** REXX API syntax +** +** This API can be called from REXX through the SQLDB2 interface. +*******************************************************************************/ +SQL_API_RC SQL_API_FN /* Bind */ + sqlabndx ( + _SQLOLDCHAR * pBindFileName, /* bind file name */ + _SQLOLDCHAR * pMsgFileName, /* message file */ + struct sqlopt * pBindOptions, /* bind options */ + struct sqlca * pSqlca); /* SQLCA */ + +/****************************************************************************** +** sqlarbnd API +** Allows the user to recreate a package stored in the database without the need +** for a bind file. +** +** Authorization +** +** One of the following: +** - sysadm or dbadm authority +** - ALTERIN privilege on the schema +** - BIND privilege on the package. +** +** The authorization ID logged in the BOUNDBY column of the SYSCAT.PACKAGES +** system catalog table, which is the ID of the most recent binder of the +** package, is used as the binder authorization ID for the rebind, and for +** the default schema for table references in the package. Note that this +** default qualifier may be different from the authorization ID of the +** user executing the rebind request. REBIND will use the same bind +** options that were specified when the package was created. +** +** Required connection +** +** Database +** +** API include file +** +** sql.h +** +** sqlarbnd API parameters +** +** pPackageName +** Input. A string containing the qualified or unqualified name that designates +** the package to be rebound. An unqualified package-name is implicitly +** qualified by the current authorization ID. This name does not include the +** package version. When specifying a package that has a version that is not +** the empty string, then the version-id must be specified using the +** SQL_VERSION_OPT rebind option. +** +** pSqlca +** Output. A pointer to the sqlca structure. +** +** pRebindOptions +** Input. A pointer to the SQLOPT structure, used to pass rebind options to the +** API. For more information about this structure, see SQLOPT. +** +** Usage notes +** +** REBIND does not automatically commit the transaction following a successful +** rebind. The user must explicitly commit the transaction. This enables +** "what if " analysis, in which the user updates certain statistics, and +** then tries to rebind the package to see what changes. It also permits +** multiple rebinds within a unit of work. +** +** This API: +** +** - Provides a quick way to recreate a package. This enables the user to take +** advantage of a change in the system without a need for the original +** bind file.fs. For example, if it is likely that a particular SQL +** statement can take advantage of a newly created index, REBIND can be +** used to recreate the package. REBIND can also be used to recreate +** packages after db2Runstats has been executed, thereby taking advantage +** of the new statistics. +** +** - Provides a method to recreate inoperative packages. Inoperative packages +** must be explicitly rebound by invoking either the bind utility or the rebind +** utility. A package will be marked inoperative (the VALID column of the +** SYSCAT.PACKAGES system catalog will be set to X) if a function instance on +** which the package depends is dropped. The rebind conservative option is +** not supported for inoperative packages. +** +** - Gives users control over the rebinding of invalid packages. Invalid +** packages will be automatically (or implicitly) rebound by the database +** manager when they are executed. This may result in a noticeable delay +** in the execution of the first SQL request for the invalid package. It +** may be desirable to explicitly rebind invalid packages, rather than +** allow the system to automatically rebind them, in order to eliminate +** the initial delay and to prevent unexpected SQL error messages which +** may be returned in case the implicit rebind fails. For example, +** following migration, all packages stored in the database will be +** invalidated by the DB2 Version 5 migration process. Given that this +** may involve a large number of packages, it may be desirable to +** explicitly rebind all of the invalid packages at one time. This +** explicit rebinding can be accomplished using BIND, REBIND, or the +** db2rbind tool. +** +** The choice of whether to use BIND or REBIND to explicitly rebind a package +** depends on the circumstances. It is recommended that REBIND be used +** whenever the situation does not specifically require the use of BIND, +** since the performance of REBIND is significantly better than that of +** BIND. BIND must be used, however: +** +** - When there have been modifications to the program (for example, when +** SQL statements have been added or deleted, or when the package does +** not match the executable for the program). +** +** - When the user wishes to modify any of the bind options as part of the +** rebind. REBIND does not support any bind options. For example, if the user +** wishes to have privileges on the package granted as part of the bind +** process, BIND must be used, since it has an SQL_GRANT_OPT option. +** +** - When the package does not currently exist in the database. +** +** - When detection of all bind errors is desired. REBIND only returns the first +** error it detects, and then ends, whereas the BIND command returns the +** first 100 errors that occur during binding. +** +** REBIND is supported by DB2 Connect. +** +** If REBIND is executed on a package that is in use by another user, the rebind +** will not occur until the other user's logical unit of work ends, because an +** exclusive lock is held on the package's record in the SYSCAT.PACKAGES system +** catalog table during the rebind. +** +** When REBIND is executed, the database manager recreates the package from +** the SQL statements stored in the SYSCAT.STATEMENTS system catalog table. +** If many versions with the same package number and creator exist, only one +** version can be bound at once. If not specified using the SQL_VERSION_OPT +** rebind option, the VERSION defaults to be "". Even if there is only one +** package with a name and creator that matches the name and creator specified +** in the rebind request, it will not rebound unless its VERSION matches the +** VERSION specified explicitly or implicitly. +** +** If REBIND encounters an error, processing stops, and an error message is +** returned. +** +** The Explain tables are populated during REBIND if either SQL_EXPLSNAP_OPT +** or SQL_EXPLAIN_OPT have been set to YES or ALL (check +** EXPLAIN_SNAPSHOT and EXPLAIN_MODE columns in the catalog). The Explain +** tables used are those of the REBIND requester, not the original binder. +** The Rebind option types and values are defined in sql.h. +** +** REXX API syntax +** +** This API can be called from REXX through the SQLDB2 interface. +*******************************************************************************/ +SQL_API_RC SQL_API_FN /* Rebind */ + sqlarbnd ( + char * pPackageName, /* package name */ + struct sqlca * pSqlca, /* SQLCA */ + struct sqlopt * pRebindOptions); /* rebind options */ + +/****************************************************************************** +** sqlaprep API +** Processes an application program source file containing embedded SQL +** statements. A modified source file is produced containing host language calls +** for the SQL statements and, by default, a package is created in the database. +** +** Scope +** +** This API can be called from any database partition server in db2nodes.cfg. It +** updates the database catalogs on the catalog partition. Its effects +** are visible to all database partition servers. +** +** Authorization +** +** One of the following: +** - sysadm or dbadm authority +** - BINDADD privilege if a package does not exist and one of: +** -- IMPLICIT_SCHEMA authority on the database if the schema name +** of the package does not exist +** -- CREATEIN privilege on the schema if the schema name of the +** package exists +** - ALTERIN privilege on the schema if the package exists +** - BIND privilege on the package if it exists. +** +** The user also needs all privileges required to compile any static SQL +** statements in the application. Privileges granted to groups are not +** used for authorization checking of static statements. If the user +** has sysadm authority, but not explicit privileges to complete the +** bind, the database manager grants explicit dbadm authority +** automatically. +** +** Required connection +** +** Database +** +** API include file +** +** sql.h +** +** sqlaprep API parameters +** +** pProgramName +** Input. A string containing the name of the application to be precompiled. Use +** the following extensions: +** - .sqb - for COBOL applications +** - .sqc - for C applications +** - .sqC - for UNIX C++ applications +** - .sqf - for FORTRAN applications +** - .sqx - for C++ applications +** +** When the TARGET option is used, the input file name extension does not have +** to be from this predefined list. +** +** The preferred extension for C++ applications containing embedded SQL on UNIX +** based systems is sqC; however, the sqx convention, which was invented for +** systems that are not case sensitive, is tolerated by UNIX based systems. +** +** pMsgFileName +** Input. A string containing the destination for error, warning, and +** informational messages. Can be the path and the name of an operating +** system file, or a standard device. If a file already exists, it is +** overwritten. If it does not exist, a file is created. +** +** pPrepOptions +** Input. A structure used to pass precompile options to the API. For more +** information about this structure, see SQLOPT. +** +** pSqlca +** Output. A pointer to the sqlca structure. +** +** Usage notes +** +** A modified source file is produced, which contains host language +** equivalents to the SQL statements. By default, a package is created +** in the database to which a connection has been established. The name +** of the package is the same as the program file name (minus the +** extension and folded to uppercase), up to a maximum of 8 characters. +** +** Following connection to a database, sqlaprep executes under the +** transaction that was started. PRECOMPILE PROGRAM then issues a COMMIT +** or a ROLLBACK operation to terminate the current transaction and start +** another one. +** +** Precompiling stops if a fatal error or more than 100 errors occur. If a fatal +** error does occur, PRECOMPILE PROGRAM stops precompiling, attempts to +** close all files, and discards the package. +** +** The Precompile option types and values are defined in sql.h. +** +** REXX API syntax +** +** This API can be called from REXX through the SQLDB2 interface. +*******************************************************************************/ +SQL_API_RC SQL_API_FN /* Precompile Program */ + sqlaprep ( + _SQLOLDCHAR * pProgramName, /* source file name */ + _SQLOLDCHAR * pMsgFileName, /* message file name */ + struct sqlopt * pPrepOptions, /* precompile options */ + struct sqlca * pSqlca); /* SQLCA */ + +/* Generic Interfaces to the Binder and Precompiler */ + +/****************************************************************************** +** sqlgbndx API +** sqlgbndx API-specific parameters +** +** pMsgFileName +** Input. A string containing the destination for error, warning, and +** informational messages. Can be the path and the name of an operating +** system file, or a standard device. If a file already exists, it is +** overwritten. If it does not exist, a file is created. +** +** BindFileNameLen +** Input. Length in bytes of the pBindFileName parameter. +*******************************************************************************/ +SQL_API_RC SQL_API_FN /* Bind */ + sqlgbndx ( + unsigned short MsgFileNameLen, /* message file name length */ + unsigned short BindFileNameLen, /* bind file name length */ + struct sqlca * pSqlca, /* SQLCA */ + struct sqlopt * pBindOptions, /* binder options */ + _SQLOLDCHAR * pMsgFileName, /* message file */ + _SQLOLDCHAR * pBindFileName); /* bind file name */ + +/****************************************************************************** +** sqlgrbnd API +** sqlgrbnd API-specific parameters +** +** PackageNameLen +** Input. Length in bytes of the pPackageName parameter. +*******************************************************************************/ +SQL_API_RC SQL_API_FN /* Rebind */ + sqlgrbnd ( + unsigned short PackageNameLen, /* package name length */ + char * pPackageName, /* package name */ + struct sqlca * pSqlca, /* SQLCA */ + struct sqlopt * pRebindOptions); /* rebind options */ + +/****************************************************************************** +** sqlgprep API +** sqlgprep API-specific parameters +** +** MsgFileNameLen +** Input. Length in bytes of the pMsgFileName parameter. +** +** ProgramNameLen +** Input. Length in bytes of the pProgramName parameter. +*******************************************************************************/ +SQL_API_RC SQL_API_FN /* Precompile Program */ + sqlgprep ( + unsigned short MsgFileNameLen, /* message file name length */ + unsigned short ProgramNameLen, /* source file name length */ + struct sqlca * pSqlca, /* SQLCA */ + struct sqlopt * pPrepOptions, /* precompile options */ + _SQLOLDCHAR * pMsgFileName, /* message file name */ + _SQLOLDCHAR * pProgramName); /* source file name */ + +/* Application Context apis */ + + +#define SQL_CTX_ORIGINAL 0 /* serial access */ +#define SQL_CTX_MULTI_MANUAL 1 /* concurrent access */ +#define SQL_CTX_TRUSTED_ROUTINE 2 /* trusted routine (internal) */ +/****************************************************************************** +** sqleSetTypeCtx API +** Sets the application context type. This API should be the first database API +** called inside an application. +** +** Scope +** +** The scope of this API is limited to the immediate process. +** +** Authorization +** +** None +** +** Required connection +** +** None +** +** API include file +** +** sql.h +** +** sqleSetTypeCtx API parameters +** +** lOptions +** Input. Valid values are: +** +** - SQL_CTX_ORIGINAL +** All threads will use the same context, and concurrent access will be blocked. +** This is the default if none of these APIs is called. +** +** - SQL_CTX_MULTI_MANUAL +** All threads will use separate contexts, and it is up to the application to +** manage the context for each thread. See +** - sqleBeginCtx API +** - sqleAttachToCtx API +** - sqleDetachFromCtx API +** - sqleEndCtx API +** +** The following restrictions/changes apply when this option is used: +** - When termination is normal, automatic COMMIT at process termination is +** disabled. All outstanding transactions are rolled back, and all COMMITs must +** be done explicitly. +** - sqleintr API interrupts all contexts. To interrupt a specific context, use +** sqleInterruptCtx. +** +** Usage notes +** +** This API must be called before any other database call, and only the +** first call is effective. +*******************************************************************************/ +SQL_API_RC SQL_API_FN /* Set Application Context */ + sqleSetTypeCtx ( + sqlint32 lOptions); /* options */ + + +#define SQL_CTX_BEGIN_ALL 0 /* create & attach */ +#define SQL_CTX_CREATE_ONLY 1 /* create only */ +/****************************************************************************** +** sqleBeginCtx API +** Creates an application context, or creates and then attaches to an +** application context. More than one application context can be +** created. Each context has its own commit scope. Different threads +** can attach to different contexts (see the sqleAttachToCtx API). +** Any database API calls made by such threads will not be serialized +** with one another. +** +** Scope +** +** The scope of this API is limited to the immediate process. +** +** Authorization +** +** None +** +** Required connection +** +** None +** +** API include file +** +** sql.h +** +** sqleBeginCtx API parameters +** +** ppCtx +** Output. A data area allocated out of private memory for the storage +** of context information. +** +** lOptions +** Input. Valid values are: +** - SQL_CTX_CREATE_ONLY +** The context memory will be allocated, but there will be no attachment. +** - SQL_CTX_BEGIN_ALL +** The context memory will be allocated, and then a call to sqleAttachToCtx will +** be made for the current thread. If this option is used, the ppCtx +** parameter can be NULL. If the thread is already attached to a context, +** the call will fail. +** +** reserved +** Reserved for future use. Must be set to NULL. +** +** pSqlca +** Output. A pointer to the sqlca structure. +*******************************************************************************/ +SQL_API_RC SQL_API_FN /* Create Application Context */ + sqleBeginCtx ( + void ** ppCtx, /* pointer to a pointer to ctx */ + sqlint32 lOptions, /* lOptions */ + void * reserved, /* reserved */ + struct sqlca * pSqlca); /* SQLCA */ + + +#define SQL_CTX_END_ALL 0 /* detach & free */ +#define SQL_CTX_FREE_ONLY 1 /* free only */ +/****************************************************************************** +** sqleEndCtx API +** Frees all memory associated with a given context. +** +** Scope +** +** The scope of this API is limited to the immediate process. +** +** Authorization +** +** None +** +** Required connection +** +** None +** +** API include file +** +** sql.h +** +** sqleEndCtx API parameters +** +** ppCtx +** Output. A data area in private memory (used for the storage of context +** information) that is freed. +** +** lOptions +** Input. Valid values are: +** - SQL_CTX_FREE_ONLY +** The context memory will be freed only if a prior detach has been done. +** Note: +** pCtx must be a valid context previously allocated by sqleBeginCtx. +** - SQL_CTX_END_ALL +** If necessary, a call to sqleDetachFromCtx will be made before the memory is +** freed. +** Note: +** A detach will be done even if the context is still in use. If this option is +** used, the ppCtx parameter can be NULL, but if passed, it must be a valid +** context previously allocated by sqleBeginCtx. A call to +** sqleGetCurrentCtx will be made, and the current context freed from there. +** +** reserved +** Reserved for future use. Must be set to NULL. +** +** pSqlca +** Output. A pointer to the sqlca structure. +** +** Usage notes +** +** If a database connection exists, or the context has been attached by another +** thread, this call will fail. +** Note: +** If a context calls an API that establishes an instance attachment +** (for example, db2CfgGet, it is necessary to detach from the instance +** using sqledtin before calling sqleEndCtx. +*******************************************************************************/ +SQL_API_RC SQL_API_FN /* Destroy Application Context */ + sqleEndCtx ( + void ** ppCtx, /* pointer to a pointer to ctx */ + sqlint32 lOptions, /* lOptions */ + void * reserved, /* reserved */ + struct sqlca * pSqlca); /* SQLCA */ + + +/****************************************************************************** +** sqleAttachToCtx API +** Makes the current thread use a specified context. All subsequent +** database calls made on this thread will use this context. If more +** than one thread is attached to a given context, access is serialized +** for these threads, and they share a commit scope. +** +** Scope +** +** The scope of this API is limited to the immediate process. +** +** Authorization +** +** None +** +** Required connection +** +** None +** +** API include file +** +** sql.h +** +** sqleAttachToCtx API parameters +** +** pCtx +** Input. A valid context previously allocated by sqleBeginCtx. +** +** reserved +** Reserved for future use. Must be set to NULL. +** +** pSqlca +** Output. A pointer to the sqlca structure. +*******************************************************************************/ +SQL_API_RC SQL_API_FN /* Attach to Application Context */ + sqleAttachToCtx ( + void * pCtx, /* pointer to ctx */ + void * reserved, /* reserved */ + struct sqlca * pSqlca); /* SQLCA */ + + +/****************************************************************************** +** sqleDetachFromCtx API +** Detaches the context being used by the current thread. The context will be +** detached only if an attach to that context has previously been made. +** +** Scope +** +** The scope of this API is limited to the immediate process. +** +** Authorization +** +** None +** +** Required connection +** +** None +** +** API include file +** +** sql.h +** +** sqleDetachFromCtx API parameters +** +** pCtx +** Input. A valid context previously allocated by sqleBeginCtx. +** +** reserved +** Reserved for future use. Must be set to NULL. +** +** pSqlca +** Output. A pointer to the sqlca structure. +*******************************************************************************/ +SQL_API_RC SQL_API_FN /* Detach Application Context */ + sqleDetachFromCtx ( + void * pCtx, /* pointer to ctx */ + void * reserved, /* reserved */ + struct sqlca * pSqlca); /* SQLCA */ + + +/****************************************************************************** +** sqleGetCurrentCtx API +** Returns the current context associated with a thread. +** +** Scope +** +** The scope of this API is limited to the immediate process. +** +** Authorization +** +** None +** +** Required connection +** +** None +** +** API include file +** +** sql.h +** +** sqleGetCurrentCtx API parameters +** +** ppCtx +** Output. A data area allocated out of private memory for the storage +** of context information. +** +** reserved +** Reserved for future use. Must be set to NULL. +** +** pSqlca +** Output. A pointer to the sqlca structure. +*******************************************************************************/ +SQL_API_RC SQL_API_FN /* Return Application Context */ + sqleGetCurrentCtx ( + void ** ppCtx, /* pointer to a pointer to ctx */ + void * reserved, /* reserved */ + struct sqlca * pSqlca); /* SQLCA */ + + +/****************************************************************************** +** sqleInterruptCtx API +** Interrupts the specified context. +** +** Scope +** +** The scope of this API is limited to the immediate process. +** +** Authorization +** +** None +** +** Required connection +** +** Database +** +** API include file +** +** sql.h +** +** sqleInterruptCtx API parameters +** +** pCtx +** Input. A valid context previously allocated by sqleBeginCtx. +** +** reserved +** Reserved for future use. Must be set to NULL. +** +** pSqlca +** Output. A pointer to the sqlca structure. +** +** Usage notes +** +** During processing, this API: +** - Switches to the context that has been passed in +** - Sends an interrupt +** - Switches to the original context +** - Exits. +*******************************************************************************/ +SQL_API_RC SQL_API_FN /* Interrupt Context */ + sqleInterruptCtx ( + void * pCtx, /* pointer to ctx */ + void * reserved, /* reserved */ + struct sqlca * pSqlca); /* SQLCA */ + + +/****************************************************************************** +** Error/SQLSTATE Message Retrieval Interface Parameters/Return Codes +*******************************************************************************/ + +/* Get Error Message Macro */ +#define sqlaintp(msgbuf,bufsize,linesize,sqlcaptr) \ +sqlaintp_api(msgbuf,bufsize,linesize, \ +(char *)"db2sql.mo", sqlcaptr) +/****************************************************************************** +** sqlaintp API +** Retrieves the message associated with an error condition specified by the +** sqlcode field of the sqlca structure. +** +** Authorization +** +** None +** +** Required connection +** +** None +** +** API include file +** +** sql.h +** +** sqlaintp API parameters +** +** pBuffer +** Output. A pointer to a string buffer where the message text is placed. If the +** message must be truncated to fit in the buffer, the truncation allows for the +** null string terminator character. +** +** BufferSize +** Input. Size, in bytes, of a string buffer to hold the retrieved message text. +** +** LineWidth +** Input. The maximum line width for each line of message text. Lines are broken +** on word boundaries. A value of zero indicates that the message text +** is returned without line breaks. +** +** pSqlca +** Output. A pointer to the sqlca structure. +** +** Usage notes +** +** One message is returned per call. +** +** A new line (line feed, LF, or carriage return/line feed, CR/LF) sequence is +** placed at the end of each message. +** +** If a positive line width is specified, new line sequences are inserted +** between words so that the lines do not exceed the line width. +** +** If a word is longer than a line width, the line is filled with as many +** characters as will fit, a new line is inserted, and the remaining characters +** are placed on the next line. +** +** In a multi-threaded application, sqlaintp must be attached to a +** valid context; otherwise, the message text for SQLCODE - 1445 cannot +** be obtained +** +** Return codes +** +** Code +** +** Message +** +** +i +** Positive integer indicating the number of bytes in the formatted message. If +** this is greater than the buffer size input by the caller, the message is +** truncated. +** +** -1 +** Insufficient memory available for message formatting services to +** function. The requested message is not returned. +** +** -2 +** No error. The sqlca did not contain an error code (SQLCODE = 0). +** +** -3 +** Message file inaccessible or incorrect. +** +** -4 +** Line width is less than zero. +** +** -5 +** Invalid sqlca, bad buffer address, or bad buffer length. +** +** If the return code is -1 or -3, the message buffer will contain additional +** information about the problem. +** +** REXX API syntax +** +** GET MESSAGE INTO :msg [LINEWIDTH width] +** +** REXX API parameters +** +** msg +** REXX variable into which the text message is placed. +** +** width +** Maximum line width for each line in the text message. The line is broken on +** word boundaries. If width is not given or set to 0, the message text returns +** without line breaks. +*******************************************************************************/ +SQL_API_RC SQL_API_FN /* Get Error Message */ + sqlaintp_api ( + char * pBuffer, /* buffer for message text */ + short BufferSize, /* buffer size */ + short LineWidth, /* line width */ + const char * pMsgFileName, /* message file */ + struct sqlca * pSqlca); /* SQLCA */ + +/* Generic Interface to Error Message Retrieval */ +/****************************************************************************** +** sqlgintp API +*******************************************************************************/ +SQL_API_RC SQL_API_FN /* Get Error Message */ + sqlgintp ( + short BufferSize, /* buffer size */ + short LineWidth, /* line width */ + struct sqlca * pSqlca, /* SQLCA */ + _SQLOLDCHAR * pBuffer); /* buffer */ + +/****************************************************************************** +** sqlogstt API +** Retrieves the message text associated with an SQLSTATE value. +** +** Authorization +** +** None +** +** Required connection +** +** None +** +** API include file +** +** sql.h +** +** sqlogstt API parameters +** +** pBuffer +** Output. A pointer to a string buffer where the message text is to be +** placed. If the message must be truncated to fit in the buffer, the +** truncation allows for the null string terminator character. +** +** BufferSize +** Input. Size, in bytes, of a string buffer to hold the retrieved message text. +** +** LineWidth +** Input. The maximum line width for each line of message text. Lines are broken +** on word boundaries. A value of zero indicates that the message text is +** returned without line breaks. +** +** pSqlstate +** Input. A string containing the SQLSTATE for which the message text is to be +** retrieved. This field is alphanumeric and must be either five-digit (specific +** SQLSTATE) or two-digit (SQLSTATE class, first two digits of an +** SQLSTATE). This field does not need to be NULL-terminated if 5 digits +** are being passed in, but must be NULL-terminated if 2 digits are being +** passed. +** +** Usage notes +** +** One message is returned per call. +** +** A LF/NULL sequence is placed at the end of each message. +** +** If a positive line width is specified, LF/NULL sequences are inserted between +** words so that the lines do not exceed the line width. +** +** If a word is longer than a line width, the line is filled with as many +** characters as will fit, a LF/NULL is inserted, and the remaining +** characters are placed on the next line. +** +** Return codes +** +** Code +** +** Message +** +** +i +** Positive integer indicating the number of bytes in the formatted message. If +** this is greater than the buffer size input by the caller, the message is +** truncated. +** +** -1 +** Insufficient memory available for message formatting services to +** function. The requested message is not returned. +** +** -2 +** The SQLSTATE is in the wrong format. It must be alphanumeric and be +** either 2 or 5 digits in length. +** +** -3 +** Message file inaccessible or incorrect. +** +** -4 +** Line width is less than zero. +** +** -5 +** Invalid sqlca, bad buffer address, or bad buffer length. +** +** If the return code is -1 or -3, the message buffer will contain further +** information about the problem. +** +** REXX API syntax +** +** GET MESSAGE FOR SQLSTATE sqlstate INTO :msg [LINEWIDTH width] +** +** REXX API parameters +** +** sqlstate +** The SQLSTATE for which the message text is to be retrieved. +** +** msg +** REXX variable into which the message is placed. +** +** width +** Maximum line width for each line of the message text. The line is broken on +** word boundaries. If a value is not specified, or this parameter is set to 0, +** the message text returns without line breaks. +*******************************************************************************/ +SQL_API_RC SQL_API_FN /* Sqlstate Message Retrieval */ + sqlogstt ( + char * pBuffer, /* buffer for message text */ + short BufferSize, /* buffer size */ + short LineWidth, /* line width */ + char * pSqlstate); /* sqlstate */ + +/* Generic Interface to SQLSTATE Message Retrieval */ +/****************************************************************************** +** sqlggstt API +*******************************************************************************/ +SQL_API_RC SQL_API_FN /* Sqlstate Message Retrieval */ + sqlggstt ( + short BufferSize, /* buffer size */ + short LineWidth, /* line width */ + char * pSqlstate, /* sqlstate */ + char * pBuffer); /* buffer */ + +/* Return Codes for sqlaintp/sqlogstt */ +#define SQLA_ERR_BADCC -1 /* insufficient memory for msg file */ +#define SQLA_ERR_NOCOD -2 /* no error code in SQLCA */ +#define SQLA_ERR_NOMSG -3 /* message file inaccessible or */ + /* incorrect */ +#define SQLA_ERR_BADLL -4 /* specified line length negative */ +#define SQLA_ERR_BADCA -5 /* invalid sqlca/buffer addr/length */ + +/* Administrative/Database Authorizations returned from Get Administrative */ +/* Authorizations function */ +/* Authorizations granted explicitly to user */ +#define SQL_SYSADM 0x1 /* SYSADM Authority */ +#define SQL_DBADM 0x2 /* DBADM Authority */ +#define SQL_CREATETAB 0x4 /* CREATETAB Privilege */ +#define SQL_BINDADD 0x8 /* BINDADD Privilege */ +#define SQL_CONNECT 0x10 /* CONNECT Privilege */ +#define SQL_CREATE_NOT_FENC 0x20 /* CREATE_NOT_FENCED Privilege */ +#define SQL_SYSCTRL 0x40 /* SYSCTRL Authority */ +#define SQL_SYSMAINT 0x80 /* SYSMAINT Authority */ +#define SQL_IMPLICIT_SCHEMA 0x10000 /* IMPLICIT_SCHEMA Privilege */ +#define SQL_LOAD 0x20000 /* LOAD Privilege */ +#define SQL_CREATE_EXT_RT 0x40000 /* CREATE_EXTERNAL_ROUTINE Privilege */ +#define SQL_LIBADM 0x80000 /* LIBRARYADM Privilege */ +#define SQL_QUIESCE_CONN 0x100000 /* QUIESCE_CONNECT Privilege */ +#define SQL_SECADM 0x200000 /* SECURITYADM Privilege */ +#define SQL_SYSQUIESCE 0x400000 /* SYSQUIESCE Authority */ +#define SQL_SYSMON 0x800000 /* SYSMON Authority */ + +/* Composite of authorizations granted explicitly to user, to groups of */ +/* which user is a member, and to PUBLIC */ +#define SQL_SYSADM_GRP 0x100 +#define SQL_DBADM_GRP 0x200 +#define SQL_CREATETAB_GRP 0x400 +#define SQL_BINDADD_GRP 0x800 +#define SQL_CONNECT_GRP 0x1000 +#define SQL_CREATE_NOT_FENC_GRP 0x2000 +#define SQL_SYSCTRL_GRP 0x4000 +#define SQL_SYSMAINT_GRP 0x8000 +#define SQL_IMPLICIT_SCHEMA_GRP 0x1000000 +#define SQL_LOAD_GRP 0x2000000 +#define SQL_CREATE_EXT_RT_GRP 0x4000000 +#define SQL_LIBADM_GRP 0x8000000 +#define SQL_QUIESCE_CONN_GRP 0x10000000 +#define SQL_SECADM_GRP 0x20000000 +#define SQL_SYSQUIESCE_GRP 0x40000000 +#define SQL_SYSMON_GRP 0x80000000 + +/* Table/View Authorizations/Dependencies Bit definitions in */ +/* SYSTABAUTH.TABAUTH and SYSPLANDEP.TABAUTH */ +#define SQL_TAB_CTL 0x1 /* Control Authority */ +#define SQL_TAB_ALT 0x2 /* Alter Privilege */ +#define SQL_TAB_DEL 0x4 /* Delete Privilege/Dependency */ +#define SQL_TAB_IDX 0x8 /* Index Privilege */ +#define SQL_TAB_INS 0x10 /* Insert Privilege/Dependency */ +#define SQL_TAB_SEL 0x20 /* Select Privilege/Dependency */ +#define SQL_TAB_UPD 0x40 /* Update Privilege/Dependency */ +#define SQL_TAB_REF 0x80 /* Reference Privilege */ +#define SQL_TAB_KEY 0x2000 /* Key Dependency */ +#define SQL_TAB_CAS 0x4000 /* Cascade Dependency */ + +/* Bit definitions for SYSTABAUTH.TABAUTH indicating the specified table or */ +/* view privilege is grantable. */ +#define SQL_TAB_ALT_G 0x200 /* Alter Privilege Grantable */ +#define SQL_TAB_DEL_G 0x400 /* Delete Privilege Grantable */ +#define SQL_TAB_IDX_G 0x800 /* Index Privilege Grantable */ +#define SQL_TAB_INS_G 0x1000 /* Insert Privilege Grantable */ +#define SQL_TAB_SEL_G 0x2000 /* Select Privilege Grantable */ +#define SQL_TAB_UPD_G 0x4000 /* Update Privilege Grantable */ +#define SQL_TAB_REF_G 0x8000 /* References Privilege Grantable */ + +/* Definitions for application remote interface */ +#define SQLZ_DISCONNECT_PROC 1 /* Unload Progam */ +#define SQLZ_HOLD_PROC 2 /* Keep program loaded */ +/* The following functions and symbols are obsolete and may not be supported */ +/* in future releases. The obsolete functions are provided for backward */ +/* compatibility and exported from DB2API.LIB. All applications should be */ +/* migrated to use new APIs. */ +#define SQLA_RC_BAD_PASSWD -4 /* Invalid password */ +#define SQL_MAXSTMTS 32767 /* Maximum statements (see SQL */ + /* reference) */ +#define SQL_MAXVARS 32767 /* Maximum host variables per */ + /* precompile unit (see SQL */ + /* reference) */ +#define SQL_DYNAMICRULES_INVOKE SQL_DYNAMICRULES_INVOKERUN /* Dynamic SQL in */ + /* UDF or stored procedure will use */ + /* authid of invoker of UDF or stored */ + /* procedure */ +#define SQL_DYNAMICRULES_DEFINE SQL_DYNAMICRULES_DEFINERUN /* Dynamic SQL in */ + /* UDF or stored procedure will use */ + /* authid of definer of UDF or stored */ + /* procedure */ + +#ifdef __cplusplus +} +#endif + +#endif /* SQL_H_SQL */ diff --git a/libodbc/include/db2_linux/sqlca.h b/libodbc/include/db2_linux/sqlca.h new file mode 100644 index 0000000000..a016ea0bfe --- /dev/null +++ b/libodbc/include/db2_linux/sqlca.h @@ -0,0 +1,119 @@ +/****************************************************************************** + * + * Source File Name = SQLCA.H + * + * (C) COPYRIGHT International Business Machines Corp. 1987, 1997 + * All Rights Reserved + * Licensed Materials - Property of IBM + * + * US Government Users Restricted Rights - Use, duplication or + * disclosure restricted by GSA ADP Schedule Contract with IBM Corp. + * + * Function = Include File defining: + * SQL Communications Area + * + * Operating System = Common C Include File + * + *****************************************************************************/ + + +#if !(defined(SQLCODE) || defined(SQLCADE)) /* Permit Duplicate Includes */ + +#include "sqlsystm.h" /* System dependent defines */ + +#if defined(DB2NT) +#if defined _WIN64 +#pragma pack(8) +#else +#pragma pack(4) +#endif +#elif (defined(DB2AIX) && defined(__64BIT__)) +#pragma options align=natural +#elif (defined(DB2AIX)) +#pragma options align=power +#endif + +/* SQL Communication Area - SQLCA */ +/* _SQLOLDCHAR defaults to 'char'. See sqlsystm.h for details. */ + +SQL_STRUCTURE sqlca +{ + _SQLOLDCHAR sqlcaid[8]; /* Eyecatcher = 'SQLCA ' */ + sqlint32 sqlcabc; /* SQLCA size in bytes = 136 */ +#ifdef DB2_SQL92E + sqlint32 sqlcade; /* SQL return code */ +#else + sqlint32 sqlcode; /* SQL return code */ +#endif + short sqlerrml; /* Length for SQLERRMC */ + _SQLOLDCHAR sqlerrmc[70]; /* Error message tokens */ + + _SQLOLDCHAR sqlerrp[8]; /* Diagnostic information */ + + sqlint32 sqlerrd[6]; /* Diagnostic information */ + _SQLOLDCHAR sqlwarn[11]; /* Warning flags */ + +#ifdef DB2_SQL92E + _SQLOLDCHAR sqlstat[5]; /* State corresponding to SQLCODE */ +#else + _SQLOLDCHAR sqlstate[5]; /* State corresponding to SQLCODE */ +#endif + +}; + +#ifdef DB2_SQL92E +#define SQLCADE sqlca.sqlcade +#else +#define SQLCODE sqlca.sqlcode +#endif +#define SQLWARN0 sqlca.sqlwarn[0] +#define SQLWARN1 sqlca.sqlwarn[1] +#define SQLWARN2 sqlca.sqlwarn[2] +#define SQLWARN3 sqlca.sqlwarn[3] +#define SQLWARN4 sqlca.sqlwarn[4] +#define SQLWARN5 sqlca.sqlwarn[5] +#define SQLWARN6 sqlca.sqlwarn[6] +#define SQLWARN7 sqlca.sqlwarn[7] +#define SQLWARN8 sqlca.sqlwarn[8] +#define SQLWARN9 sqlca.sqlwarn[9] +#define SQLWARNA sqlca.sqlwarn[10] + + +/* sqlerrd tokens updated when compound SQL statements processed */ + +#define SQL_CMP_NA_ERRORS 1 +#define SQL_CMP_ROWS_AFFECTED 2 +#define SQL_CMP_STMTS_COMPLETED 3 +#define SQL_CMP_REF_INT_ROWS 4 + + +/* sqlerrd tokens updated when CONNECT statements processed */ + +#define SQL_CONNECT_DB_APP2DB_CONVFACTOR 0 +#define SQL_CONNECT_DB_DB2APP_CONVFACTOR 1 +#define SQL_CONNECT_DB_UPDATEABILITY_IN_UOW 2 +#define SQL_CONNECT_DB_COMMIT_TYPE 3 + + +/* Values returned for sqlerrd[SQL_CONNECT_DB_UPDATEABILITY_IN_UOW] */ + +#define SQL_DB_UPDATEABLE 1 +#define SQL_DB_READ_ONLY 2 + + +/* Values returned for sqlerrd[SQL_CONNECT_DB_COMMIT_TYPE] */ + +#define SQL_DB_ONE_PHASE_COMMIT 1 +#define SQL_DB_ONE_PHASE_READ_ONLY 2 +#define SQL_DB_TWO_PHASE_COMMIT 3 + +/* sqlerrd tokens updated when MPP statements processed */ +#define SQL_ERRD_NODE_NUM 1 + +#if defined(DB2NT) +#pragma pack() +#elif defined(DB2AIX) +#pragma options align=reset +#endif + +#endif /* SQLCODE */ diff --git a/libodbc/include/db2_linux/sqlcli.h b/libodbc/include/db2_linux/sqlcli.h new file mode 100644 index 0000000000..633545625f --- /dev/null +++ b/libodbc/include/db2_linux/sqlcli.h @@ -0,0 +1,807 @@ +/****************************************************************************** + * + * Source File Name = sqlcli.h + * + * (C) COPYRIGHT International Business Machines Corp. 1993, 1999 + * All Rights Reserved + * Licensed Materials - Property of IBM + * + * US Government Users Restricted Rights - Use, duplication or + * disclosure restricted by GSA ADP Schedule Contract with IBM Corp. + * + * Function = Include File defining: + * DB2 CLI Interface - Constants + * DB2 CLI Interface - Data Structures + * DB2 CLI Interface - Function Prototypes + * + * Operating System = Common C Include File + * + *****************************************************************************/ + +#ifndef SQL_H_SQLCLI +#define SQL_H_SQLCLI /* Permit duplicate Includes */ + +/* Prevent inclusion of winsock.h in windows.h */ +#ifndef _WINSOCKAPI_ +#define _WINSOCKAPI_ +#define DB2_WINSOCKAPI_ +#endif + +/* DB2CLI_VER DB2 Call Level Interface Version Number (0x0210). + * To revert to Version 1.0 definitions, + * issue #define DB2CLI_VER 0x0110 before including + * sqlcli.h and sqlcli1.h + */ + +/* If DB2CLI_VER is not defined, assume version 2.10 */ +#ifndef DB2CLI_VER +#define DB2CLI_VER 0x0310 +#endif + +/* ODBC64 should be used instead of CLI_WIN64 for linking with libdb2o.dll */ +#ifndef ODBC64 +#ifdef CLI_WIN64 +#define ODBC64 +#endif +#endif + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#include "sqlsystm.h" /* System dependent defines */ + +#if defined(DB2NT) +#include +#else +#define FAR +#endif + +#define SQL_API SQL_API_FN + + +/* generally useful constants */ +#define SQL_MAX_MESSAGE_LENGTH 1024 /* message buffer size */ +#define SQL_MAX_ID_LENGTH 128 /* maximum identifier name size, + e.g. cursor names */ + +/* date/time length constants */ +#define SQL_DATE_LEN 10 +#define SQL_TIME_LEN 8 /* add P+1 if precision is nonzero */ +#define SQL_TIMESTAMP_LEN 19 /* add P+1 if precision is nonzero */ + +/* handle type identifiers */ +#define SQL_HANDLE_ENV 1 +#define SQL_HANDLE_DBC 2 +#define SQL_HANDLE_STMT 3 +#define SQL_HANDLE_DESC 4 + +/* RETCODE values */ +#define SQL_SUCCESS 0 +#define SQL_SUCCESS_WITH_INFO 1 +#define SQL_NEED_DATA 99 +#define SQL_NO_DATA 100 +#define SQL_STILL_EXECUTING 2 +#define SQL_ERROR -1 +#define SQL_INVALID_HANDLE -2 + +/* test for SQL_SUCCESS or SQL_SUCCESS_WITH_INFO */ +#define SQL_SUCCEEDED(rc) (((rc)&(~1))==0) + +/* SQLFreeStmt option values */ +#define SQL_CLOSE 0 +#define SQL_DROP 1 +#define SQL_UNBIND 2 +#define SQL_RESET_PARAMS 3 + +/* SQLTransact option values */ +#define SQL_COMMIT 0 +#define SQL_ROLLBACK 1 + +/* Standard SQL data types */ +#define SQL_UNKNOWN_TYPE 0 +#define SQL_CHAR 1 +#define SQL_NUMERIC 2 +#define SQL_DECIMAL 3 +#define SQL_INTEGER 4 +#define SQL_SMALLINT 5 +#define SQL_FLOAT 6 +#define SQL_REAL 7 +#define SQL_DOUBLE 8 +#define SQL_DATETIME 9 +#define SQL_VARCHAR 12 +#define SQL_WCHAR (-8) +#define SQL_WVARCHAR (-9) +#define SQL_WLONGVARCHAR (-10) +#define SQL_DECFLOAT (-360) +/* One-parameter shortcuts for date/time data types */ +#define SQL_TYPE_DATE 91 +#define SQL_TYPE_TIME 92 +#define SQL_TYPE_TIMESTAMP 93 + +/* Statement attribute values for cursor sensitivity */ +#define SQL_UNSPECIFIED 0 +#define SQL_INSENSITIVE 1 +#define SQL_SENSITIVE 2 + +/* Default conversion code for SQLBindCol(), SQLBindParam() and SQLGetData() */ +#define SQL_DEFAULT 99 + +/* SQLGetData() code indicating that the application row descriptor + * specifies the data type + */ +#define SQL_ARD_TYPE (-99) + +/* SQL date/time type subcodes */ +#define SQL_CODE_DATE 1 +#define SQL_CODE_TIME 2 +#define SQL_CODE_TIMESTAMP 3 + +/* SQL extended data types */ +#define SQL_GRAPHIC -95 +#define SQL_VARGRAPHIC -96 +#define SQL_LONGVARGRAPHIC -97 +#define SQL_BLOB -98 +#define SQL_CLOB -99 +#define SQL_DBCLOB -350 +#define SQL_XML -370 +#define SQL_DATALINK -400 +#define SQL_USER_DEFINED_TYPE -450 + +/* C data type to SQL data type mapping */ +#define SQL_C_DBCHAR SQL_DBCLOB +#define SQL_C_DECIMAL_IBM SQL_DECIMAL +#define SQL_C_DATALINK SQL_C_CHAR +#define SQL_C_PTR 2463 +#define SQL_C_DECIMAL_OLEDB 2514 +#define SQL_C_DECIMAL64 SQL_DECFLOAT +#define SQL_C_DECIMAL128 -361 + +/* + * locator type identifier + */ + +#define SQL_BLOB_LOCATOR 31 +#define SQL_CLOB_LOCATOR 41 +#define SQL_DBCLOB_LOCATOR -351 + +/* + * C Data Type for the LOB locator types + */ +#define SQL_C_BLOB_LOCATOR SQL_BLOB_LOCATOR +#define SQL_C_CLOB_LOCATOR SQL_CLOB_LOCATOR +#define SQL_C_DBCLOB_LOCATOR SQL_DBCLOB_LOCATOR + +/* + * NULL status defines; these are used in SQLColAttributes, SQLDescribeCol, + * to describe the nullability of a column in a table. + */ + +#define SQL_NO_NULLS 0 +#define SQL_NULLABLE 1 +#define SQL_NULLABLE_UNKNOWN 2 + +/* values of UNNAMED field in descriptor used in SQLColAttribute */ +#define SQL_NAMED 0 +#define SQL_UNNAMED 1 + +/* values of ALLOC_TYPE field in descriptor */ +#define SQL_DESC_ALLOC_AUTO 1 +#define SQL_DESC_ALLOC_USER 2 + +/* values of USER_DEFINED_TYPE_CODE */ +#define SQL_TYPE_BASE 0 +#define SQL_TYPE_DISTINCT 1 +#define SQL_TYPE_STRUCTURED 2 +#define SQL_TYPE_REFERENCE 3 + +/* Special length values */ +#define SQL_NULL_DATA -1 +#define SQL_DATA_AT_EXEC -2 +#define SQL_NTS -3 /* NTS = Null Terminated String */ +#define SQL_NTSL -3L /* NTS = Null Terminated String */ + +/* SQLColAttributes defines */ +#define SQL_COLUMN_SCHEMA_NAME 16 +#define SQL_COLUMN_CATALOG_NAME 17 +#define SQL_COLUMN_DISTINCT_TYPE 1250 +#define SQL_DESC_DISTINCT_TYPE SQL_COLUMN_DISTINCT_TYPE +#define SQL_COLUMN_REFERENCE_TYPE 1251 +#define SQL_DESC_REFERENCE_TYPE SQL_COLUMN_REFERENCE_TYPE +#define SQL_DESC_STRUCTURED_TYPE 1252 +#define SQL_DESC_USER_TYPE 1253 +#define SQL_DESC_BASE_TYPE 1254 +#define SQL_DESC_KEY_TYPE 1255 +#define SQL_DESC_KEY_MEMBER 1266 + +/* identifiers of fields in the SQL descriptor */ +#define SQL_DESC_COUNT 1001 +#define SQL_DESC_TYPE 1002 +#define SQL_DESC_LENGTH 1003 +#define SQL_DESC_OCTET_LENGTH_PTR 1004 +#define SQL_DESC_PRECISION 1005 +#define SQL_DESC_SCALE 1006 +#define SQL_DESC_DATETIME_INTERVAL_CODE 1007 +#define SQL_DESC_NULLABLE 1008 +#define SQL_DESC_INDICATOR_PTR 1009 +#define SQL_DESC_DATA_PTR 1010 +#define SQL_DESC_NAME 1011 +#define SQL_DESC_UNNAMED 1012 +#define SQL_DESC_OCTET_LENGTH 1013 +#define SQL_DESC_ALLOC_TYPE 1099 +#define SQL_DESC_USER_DEFINED_TYPE_CODE 1098 + + +/* Defines for SQL_DESC_KEY_TYPE */ +#define SQL_KEYTYPE_NONE 0 +#define SQL_KEYTYPE_PRIMARYKEY 1 +#define SQL_KEYTYPE_UNIQUEINDEX 2 + + +/* SQLColAttribute defines for SQL_COLUMN_UPDATABLE condition */ +#define SQL_UPDT_READONLY 0 +#define SQL_UPDT_WRITE 1 +#define SQL_UPDT_READWRITE_UNKNOWN 2 + +/* + * SQLColAttribute defines for SQL_COLUMN_SEARCHABLE condition. + */ +#define SQL_PRED_NONE 0 +#define SQL_PRED_CHAR 1 +#define SQL_PRED_BASIC 2 + +/* NULL handle defines */ +#define SQL_NULL_HENV 0L +#define SQL_NULL_HDBC 0L +#define SQL_NULL_HSTMT 0L +#define SQL_NULL_HDESC 0L +#define SQL_NULL_HANDLE 0L + +/* identifiers of fields in the diagnostics area */ +#define SQL_DIAG_RETURNCODE 1 +#define SQL_DIAG_NUMBER 2 +#define SQL_DIAG_ROW_COUNT 3 +#define SQL_DIAG_SQLSTATE 4 +#define SQL_DIAG_NATIVE 5 +#define SQL_DIAG_MESSAGE_TEXT 6 +#define SQL_DIAG_DYNAMIC_FUNCTION 7 +#define SQL_DIAG_CLASS_ORIGIN 8 +#define SQL_DIAG_SUBCLASS_ORIGIN 9 +#define SQL_DIAG_CONNECTION_NAME 10 +#define SQL_DIAG_SERVER_NAME 11 +#define SQL_DIAG_DYNAMIC_FUNCTION_CODE 12 + +/* dynamic function codes */ +#define SQL_DIAG_ALTER_TABLE 4 +#define SQL_DIAG_CALL 7 +#define SQL_DIAG_CREATE_INDEX (-1) +#define SQL_DIAG_CREATE_TABLE 77 +#define SQL_DIAG_CREATE_VIEW 84 +#define SQL_DIAG_DELETE_WHERE 19 +#define SQL_DIAG_DROP_INDEX (-2) +#define SQL_DIAG_DROP_TABLE 32 +#define SQL_DIAG_DROP_VIEW 36 +#define SQL_DIAG_DYNAMIC_DELETE_CURSOR 38 +#define SQL_DIAG_DYNAMIC_UPDATE_CURSOR 81 +#define SQL_DIAG_GRANT 48 +#define SQL_DIAG_INSERT 50 +#define SQL_DIAG_MERGE 128 +#define SQL_DIAG_REVOKE 59 +#define SQL_DIAG_SELECT_CURSOR 85 +#define SQL_DIAG_UNKNOWN_STATEMENT 0 +#define SQL_DIAG_UPDATE_WHERE 82 + +/* + * IBM specific SQLGetDiagField values. + */ + +#define SQL_DIAG_DEFERRED_PREPARE_ERROR 1279 + +/* SQL_DIAG_ROW_NUMBER values */ +#define SQL_ROW_NO_ROW_NUMBER (-1) +#define SQL_ROW_NUMBER_UNKNOWN (-2) + +/* SQL_DIAG_COLUMN_NUMBER values */ +#define SQL_COLUMN_NO_COLUMN_NUMBER (-1) +#define SQL_COLUMN_NUMBER_UNKNOWN (-2) + +/* + * The following are provided to enhance portability and compatibility + * with ODBC + */ + +typedef signed char SCHAR; +typedef unsigned char UCHAR; + +typedef short int SWORD; +typedef unsigned short USHORT; + +typedef signed short SSHORT; +typedef unsigned short int UWORD; + +#if defined(DB2NT) + typedef long SDWORD; + typedef unsigned long ULONG; + typedef unsigned long UDWORD; + typedef long SLONG; +#else + typedef sqlint32 SDWORD; + typedef sqluint32 ULONG; + typedef sqluint32 UDWORD; + typedef sqlint32 SLONG; +#endif +typedef double SDOUBLE; +typedef float SFLOAT; +typedef unsigned char SQLDATE; +typedef unsigned char SQLTIME; +typedef unsigned char SQLTIMESTAMP; +typedef unsigned char SQLDECIMAL; +typedef unsigned char SQLNUMERIC; + + + +#if defined(WINDOWS) +typedef long double LDOUBLE; +#else +typedef double LDOUBLE; +#endif + +typedef void FAR * PTR; +typedef void FAR * HENV; +typedef void FAR * HDBC; +typedef void FAR * HSTMT; + +typedef signed short RETCODE; + + + +/* SQL portable types for C */ +typedef UCHAR SQLCHAR; +typedef UCHAR SQLVARCHAR; +typedef SCHAR SQLSCHAR; +typedef SDWORD SQLINTEGER; +typedef SWORD SQLSMALLINT; +typedef SDOUBLE SQLDOUBLE; +typedef SDOUBLE SQLFLOAT; +typedef SFLOAT SQLREAL; + +typedef SQLSMALLINT SQLRETURN; + +#if (DB2CLI_VER >= 0x0200) +typedef UDWORD SQLUINTEGER; +typedef UWORD SQLUSMALLINT; +#else +typedef SQLINTEGER SQLUINTEGER; +typedef SQLSMALLINT SQLUSMALLINT; +#endif + +/* 64-bit Length Defines */ +#ifdef ODBC64 +typedef sqlint64 SQLLEN; +typedef sqluint64 SQLULEN; +typedef sqluint64 SQLSETPOSIROW; +#else +#define SQLLEN SQLINTEGER +#define SQLULEN SQLUINTEGER +#define SQLSETPOSIROW SQLUSMALLINT +#endif + +typedef PTR SQLPOINTER; + +/* + * Double Byte Character Set support + */ + +/* + * Do not support SQL_WCHART_CONVERT in UNICODE + */ +#ifdef UNICODE +#undef SQL_WCHART_CONVERT +#endif + +#ifdef SQL_WCHART_CONVERT +typedef wchar_t SQLDBCHAR; +#else +typedef unsigned short SQLDBCHAR; +#endif + +#ifdef DB2WIN +typedef wchar_t SQLWCHAR; +#else +typedef unsigned short SQLWCHAR; +#endif + +#ifdef DB2WIN + +typedef SQLINTEGER SQLHANDLE; +typedef HENV SQLHENV; +typedef HDBC SQLHDBC; +typedef HSTMT SQLHSTMT; +typedef HWND SQLHWND; + +#else +#if ((defined DB2NT && defined _WIN64) || defined ODBC64) +typedef void * SQLHANDLE; +typedef SQLHANDLE SQLHENV; +typedef SQLHANDLE SQLHDBC; +typedef SQLHANDLE SQLHSTMT; +#else + +#ifndef __SQLTYPES +typedef SQLINTEGER SQLHANDLE; +typedef SQLINTEGER SQLHENV; +typedef SQLINTEGER SQLHDBC; +typedef SQLINTEGER SQLHSTMT; +#endif +#endif + +#if defined (DB2NT) +typedef HWND SQLHWND; +#else +typedef SQLPOINTER SQLHWND; +#endif + +#endif +typedef SQLHANDLE SQLHDESC; + +#ifndef __SQLTYPES + +/* + * SQL_NO_NATIVE_BIGINT_SUPPORT and SQL_BIGINT_TYPE are defined in sqlsystm.h + * + */ + +#if defined(SQL_NO_NATIVE_BIGINT_SUPPORT) +typedef struct SQLBIGINT +{ + SQLUINTEGER dwLowWord; + SQLINTEGER dwHighWord; +} SQLBIGINT; +typedef struct SQLUBIGINT +{ + SQLUINTEGER dwLowWord; + SQLUINTEGER dwHighWord; +} SQLUBIGINT; +#elif defined(SQL_BIGINT_TYPE) +typedef SQL_BIGINT_TYPE SQLBIGINT; +typedef SQL_BIGUINT_TYPE SQLUBIGINT; +#endif + +typedef struct DATE_STRUCT + { + SQLSMALLINT year; + SQLUSMALLINT month; + SQLUSMALLINT day; + } DATE_STRUCT; + +typedef DATE_STRUCT SQL_DATE_STRUCT; + +typedef struct TIME_STRUCT + { + SQLUSMALLINT hour; + SQLUSMALLINT minute; + SQLUSMALLINT second; + } TIME_STRUCT; + +typedef TIME_STRUCT SQL_TIME_STRUCT; + +typedef struct TIMESTAMP_STRUCT + { + SQLSMALLINT year; + SQLUSMALLINT month; + SQLUSMALLINT day; + SQLUSMALLINT hour; + SQLUSMALLINT minute; + SQLUSMALLINT second; + SQLUINTEGER fraction; /* fraction of a second */ + } TIMESTAMP_STRUCT; + + +typedef TIMESTAMP_STRUCT SQL_TIMESTAMP_STRUCT; + +typedef enum +{ + SQL_IS_YEAR = 1, + SQL_IS_MONTH = 2, + SQL_IS_DAY = 3, + SQL_IS_HOUR = 4, + SQL_IS_MINUTE = 5, + SQL_IS_SECOND = 6, + SQL_IS_YEAR_TO_MONTH = 7, + SQL_IS_DAY_TO_HOUR = 8, + SQL_IS_DAY_TO_MINUTE = 9, + SQL_IS_DAY_TO_SECOND = 10, + SQL_IS_HOUR_TO_MINUTE = 11, + SQL_IS_HOUR_TO_SECOND = 12, + SQL_IS_MINUTE_TO_SECOND = 13 +} SQLINTERVAL; + +typedef struct tagSQL_YEAR_MONTH +{ + SQLUINTEGER year; + SQLUINTEGER month; +} SQL_YEAR_MONTH_STRUCT; + +typedef struct tagSQL_DAY_SECOND +{ + SQLUINTEGER day; + SQLUINTEGER hour; + SQLUINTEGER minute; + SQLUINTEGER second; + SQLUINTEGER fraction; +} SQL_DAY_SECOND_STRUCT; + +typedef struct tagSQL_INTERVAL_STRUCT +{ + SQLINTERVAL interval_type; + SQLSMALLINT interval_sign; + union { + SQL_YEAR_MONTH_STRUCT year_month; + SQL_DAY_SECOND_STRUCT day_second; + } intval; + +} SQL_INTERVAL_STRUCT; + +/* Maximum precision (in base 10) of an SQL_C_NUMERIC value */ +#define SQL_MAX_C_NUMERIC_PRECISION 38 + +/* internal representation of numeric data type */ +#define SQL_MAX_NUMERIC_LEN 16 +typedef struct tagSQL_NUMERIC_STRUCT +{ + SQLCHAR precision; + SQLSCHAR scale; + SQLCHAR sign; /* 1 if positive, 0 if negative */ + SQLCHAR val[SQL_MAX_NUMERIC_LEN]; +} SQL_NUMERIC_STRUCT; + +#endif + + +#define SQL_DECIMAL64_LEN 8 +#define SQL_DECIMAL128_LEN 16 + +typedef struct tagSQLDECIMAL64 { + union { + SQLDOUBLE dummy; /* Dummy member for alignment purposes */ + SQLCHAR dec64[SQL_DECIMAL64_LEN]; + } udec64; +} SQLDECIMAL64; + +typedef struct tagSQLDECIMAL128 { + union { + SQLDOUBLE dummy; /* Dummy member for alignment purposes */ + SQLCHAR dec128[SQL_DECIMAL128_LEN]; + } udec128; +} SQLDECIMAL128; + +/* Core Function Prototypes */ + + + + +SQLRETURN SQL_API_FN SQLAllocConnect (SQLHENV henv, + SQLHDBC FAR *phdbc); + + +SQLRETURN SQL_API_FN SQLAllocEnv (SQLHENV FAR *phenv); + +SQLRETURN SQL_API_FN SQLAllocStmt (SQLHDBC hdbc, + SQLHSTMT FAR *phstmt); + +SQLRETURN SQL_API_FN SQLAllocHandle( SQLSMALLINT fHandleType, + SQLHANDLE hInput, + SQLHANDLE * phOutput ); + +SQLRETURN SQL_API_FN SQLBindCol (SQLHSTMT hstmt, + SQLUSMALLINT icol, + SQLSMALLINT fCType, + SQLPOINTER rgbValue, + SQLLEN cbValueMax, + SQLLEN FAR *pcbValue); + +SQLRETURN SQL_API_FN SQLCancel (SQLHSTMT hstmt); + + +#ifdef ODBC64 +SQLRETURN SQL_API_FN SQLColAttribute (SQLHSTMT hstmt, + SQLUSMALLINT icol, + SQLUSMALLINT fDescType, + SQLPOINTER rgbDesc, + SQLSMALLINT cbDescMax, + SQLSMALLINT FAR *pcbDesc, + SQLLEN *pfDesc); +#else +SQLRETURN SQL_API_FN SQLColAttribute (SQLHSTMT hstmt, + SQLUSMALLINT icol, + SQLUSMALLINT fDescType, + SQLPOINTER rgbDesc, + SQLSMALLINT cbDescMax, + SQLSMALLINT FAR *pcbDesc, + SQLPOINTER pfDesc); +#endif + + + +SQLRETURN SQL_API_FN SQLConnect (SQLHDBC hdbc, + SQLCHAR FAR *szDSN, + SQLSMALLINT cbDSN, + SQLCHAR FAR *szUID, + SQLSMALLINT cbUID, + SQLCHAR FAR *szAuthStr, + SQLSMALLINT cbAuthStr); + +SQLRETURN SQL_API_FN SQLDescribeCol (SQLHSTMT hstmt, + SQLUSMALLINT icol, + SQLCHAR FAR *szColName, + SQLSMALLINT cbColNameMax, + SQLSMALLINT FAR *pcbColName, + SQLSMALLINT FAR *pfSqlType, + SQLULEN FAR *pcbColDef, + SQLSMALLINT FAR *pibScale, + SQLSMALLINT FAR *pfNullable); + +SQLRETURN SQL_API_FN SQLDisconnect (SQLHDBC hdbc); + +SQLRETURN SQL_API_FN SQLError (SQLHENV henv, + SQLHDBC hdbc, + SQLHSTMT hstmt, + SQLCHAR FAR *szSqlState, + SQLINTEGER FAR *pfNativeError, + SQLCHAR FAR *szErrorMsg, + SQLSMALLINT cbErrorMsgMax, + SQLSMALLINT FAR *pcbErrorMsg); + +SQLRETURN SQL_API_FN SQLExecDirect (SQLHSTMT hstmt, + SQLCHAR FAR *szSqlStr, + SQLINTEGER cbSqlStr); + +SQLRETURN SQL_API_FN SQLExecute (SQLHSTMT hstmt); + +SQLRETURN SQL_API_FN SQLFetch (SQLHSTMT hstmt); + +SQLRETURN SQL_API_FN SQLFreeConnect (SQLHDBC hdbc); + +SQLRETURN SQL_API_FN SQLFreeEnv (SQLHENV henv); + +SQLRETURN SQL_API_FN SQLFreeStmt (SQLHSTMT hstmt, + SQLUSMALLINT fOption); + +SQLRETURN SQL_API_FN SQLCloseCursor( SQLHSTMT hStmt ); + +SQLRETURN SQL_API_FN SQLGetCursorName (SQLHSTMT hstmt, + SQLCHAR FAR *szCursor, + SQLSMALLINT cbCursorMax, + SQLSMALLINT FAR *pcbCursor); + +SQLRETURN SQL_API_FN SQLGetData (SQLHSTMT hstmt, + SQLUSMALLINT icol, + SQLSMALLINT fCType, + SQLPOINTER rgbValue, + SQLLEN cbValueMax, + SQLLEN FAR *pcbValue); + +SQLRETURN SQL_API_FN SQLNumResultCols (SQLHSTMT hstmt, + SQLSMALLINT FAR *pccol); + +SQLRETURN SQL_API_FN SQLPrepare (SQLHSTMT hstmt, + SQLCHAR FAR *szSqlStr, + SQLINTEGER cbSqlStr); + +SQLRETURN SQL_API_FN SQLRowCount (SQLHSTMT hstmt, + SQLLEN FAR *pcrow); + +SQLRETURN SQL_API_FN SQLSetCursorName (SQLHSTMT hstmt, + SQLCHAR FAR *szCursor, + SQLSMALLINT cbCursor); + +SQLRETURN SQL_API_FN SQLSetParam (SQLHSTMT hstmt, + SQLUSMALLINT ipar, + SQLSMALLINT fCType, + SQLSMALLINT fSqlType, + SQLULEN cbParamDef, + SQLSMALLINT ibScale, + SQLPOINTER rgbValue, + SQLLEN FAR *pcbValue); + +SQLRETURN SQL_API_FN SQLTransact (SQLHENV henv, + SQLHDBC hdbc, + SQLUSMALLINT fType); + +SQLRETURN SQL_API_FN SQLEndTran( SQLSMALLINT fHandleType, + SQLHANDLE hHandle, + SQLSMALLINT fType ); + +SQLRETURN SQL_API_FN SQLFreeHandle( SQLSMALLINT fHandleType, + SQLHANDLE hHandle ); + +SQLRETURN SQL_API_FN SQLGetDiagRec( SQLSMALLINT fHandleType, + SQLHANDLE hHandle, + SQLSMALLINT iRecNumber, + SQLCHAR * pszSqlState, + SQLINTEGER * pfNativeError, + SQLCHAR * pszErrorMsg, + SQLSMALLINT cbErrorMsgMax, + SQLSMALLINT * pcbErrorMsg ); + +SQLRETURN SQL_API_FN SQLGetDiagField( SQLSMALLINT fHandleType, + SQLHANDLE hHandle, + SQLSMALLINT iRecNumber, + SQLSMALLINT fDiagIdentifier, + SQLPOINTER pDiagInfo, + SQLSMALLINT cbDiagInfoMax, + SQLSMALLINT * pcbDiagInfo ); + +SQLRETURN SQL_API_FN SQLCopyDesc( SQLHDESC hDescSource, + SQLHDESC hDescTarget ); + +SQLRETURN SQL_API_FN SQLGetDescField( SQLHDESC DescriptorHandle, + SQLSMALLINT RecNumber, + SQLSMALLINT FieldIdentifier, + SQLPOINTER Value, + SQLINTEGER BufferLength, + SQLINTEGER *StringLength); + +SQLRETURN SQL_API_FN SQLGetDescRec( SQLHDESC DescriptorHandle, + SQLSMALLINT RecNumber, + SQLCHAR *Name, + SQLSMALLINT BufferLength, + SQLSMALLINT *StringLength, + SQLSMALLINT *Type, + SQLSMALLINT *SubType, + SQLLEN *Length, + SQLSMALLINT *Precision, + SQLSMALLINT *Scale, + SQLSMALLINT *Nullable); + +SQLRETURN SQL_API_FN SQLSetDescField( SQLHDESC DescriptorHandle, + SQLSMALLINT RecNumber, + SQLSMALLINT FieldIdentifier, + SQLPOINTER Value, + SQLINTEGER BufferLength); + +SQLRETURN SQL_API_FN SQLSetDescRec( SQLHDESC DescriptorHandle, + SQLSMALLINT RecNumber, + SQLSMALLINT Type, + SQLSMALLINT SubType, + SQLLEN Length, + SQLSMALLINT Precision, + SQLSMALLINT Scale, + SQLPOINTER Data, + SQLLEN *StringLength, + SQLLEN *Indicator); + + + +#ifdef __cplusplus +} +#endif + +/* + * Include ODBC header files for + * functions that are not specified in the X/Open Call Level Interface. + * This is included with permission from Microsoft. + * Do not modify (i.e. must not add, remove, rearrange) any part of the + * contents of sqlext.h + * Note: SQLDrivers is not supported by DB2 CLI. + */ +#ifndef __SQL +#define __SQL +#define ODBCVER 0x0351 +#endif +#if !defined(WINDOWS) && !defined(WIN32) && !defined(SQLWINT) +typedef SQLWCHAR * LPWSTR; +typedef sqluint32 DWORD; +#endif + +#include "sqlext.h" + + +#ifdef DB2_WINSOCKAPI_ +#undef _WINSOCKAPI_ +#undef DB2_WINSOCKAPI_ +#endif + +#endif /* SQL_H_SQLCLI */ diff --git a/libodbc/include/db2_linux/sqlcli1.h b/libodbc/include/db2_linux/sqlcli1.h new file mode 100644 index 0000000000..39d6c01b2b --- /dev/null +++ b/libodbc/include/db2_linux/sqlcli1.h @@ -0,0 +1,1549 @@ +/****************************************************************************** + * + * Source File Name = sqlcli1.h + * + * (C) COPYRIGHT International Business Machines Corp. 1993, 2004 + * All Rights Reserved + * Licensed Materials - Property of IBM + * + * US Government Users Restricted Rights - Use, duplication or + * disclosure restricted by GSA ADP Schedule Contract with IBM Corp. + * + * Function = Include File defining: + * DB2 CLI Interface - Constants + * DB2 CLI Interface - Function Prototypes + * + * Operating System = Common C Include File + * + *****************************************************************************/ + +#ifndef SQL_H_SQLCLI1 + #define SQL_H_SQLCLI1 /* Permit duplicate Includes */ + +/* Prevent inclusion of winsock.h in windows.h */ +#ifndef _WINSOCKAPI_ +#define _WINSOCKAPI_ +#define DB2_WINSOCKAPI_ +#endif + +/* ODBC64 should be used instead of CLI_WIN64 for linking with libdb2o.dll */ +#ifndef ODBC64 +#ifdef CLI_WIN64 +#define ODBC64 +#endif +#endif + +#include "sqlsystm.h" /* System dependent defines */ + + +#if defined(DB2NT) +#include +#endif + +#include "sqlca.h" +#include "sqlcli.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* SQLGetFunction defines - supported functions */ +#define SQL_API_SQLALLOCCONNECT 1 +#define SQL_API_SQLALLOCENV 2 +#define SQL_API_SQLALLOCSTMT 3 +#define SQL_API_SQLBINDCOL 4 +#define SQL_API_SQLBINDPARAM 1002 +#define SQL_API_SQLCANCEL 5 +#define SQL_API_SQLCONNECT 7 +#define SQL_API_SQLCOPYDESC 1004 +#define SQL_API_SQLDESCRIBECOL 8 +#define SQL_API_SQLDISCONNECT 9 +#define SQL_API_SQLERROR 10 +#define SQL_API_SQLEXECDIRECT 11 +#define SQL_API_SQLEXECUTE 12 +#define SQL_API_SQLFETCH 13 +#define SQL_API_SQLFREECONNECT 14 +#define SQL_API_SQLFREEENV 15 +#define SQL_API_SQLFREESTMT 16 +#define SQL_API_SQLGETCURSORNAME 17 +#define SQL_API_SQLNUMRESULTCOLS 18 +#define SQL_API_SQLPREPARE 19 +#define SQL_API_SQLROWCOUNT 20 +#define SQL_API_SQLSETCURSORNAME 21 +#define SQL_API_SQLSETDESCFIELD 1017 +#define SQL_API_SQLSETDESCREC 1018 +#define SQL_API_SQLSETENVATTR 1019 +#define SQL_API_SQLSETPARAM 22 +#define SQL_API_SQLTRANSACT 23 + +#define SQL_API_SQLCOLUMNS 40 +#define SQL_API_SQLGETCONNECTOPTION 42 +#define SQL_API_SQLGETDATA 43 +#define SQL_API_SQLGETDATAINTERNAL 174 +#define SQL_API_SQLGETDESCFIELD 1008 +#define SQL_API_SQLGETDESCREC 1009 +#define SQL_API_SQLGETDIAGFIELD 1010 +#define SQL_API_SQLGETDIAGREC 1011 +#define SQL_API_SQLGETENVATTR 1012 +#define SQL_API_SQLGETFUNCTIONS 44 +#define SQL_API_SQLGETINFO 45 +#define SQL_API_SQLGETSTMTOPTION 46 +#define SQL_API_SQLGETTYPEINFO 47 +#define SQL_API_SQLPARAMDATA 48 +#define SQL_API_SQLPUTDATA 49 +#define SQL_API_SQLSETCONNECTOPTION 50 +#define SQL_API_SQLSETSTMTOPTION 51 +#define SQL_API_SQLSPECIALCOLUMNS 52 +#define SQL_API_SQLSTATISTICS 53 +#define SQL_API_SQLTABLES 54 +#define SQL_API_SQLDATASOURCES 57 +#define SQL_API_SQLSETCONNECTATTR 1016 +#define SQL_API_SQLSETSTMTATTR 1020 + +#define SQL_API_SQLBINDFILETOCOL 1250 +#define SQL_API_SQLBINDFILETOPARAM 1251 +#define SQL_API_SQLSETCOLATTRIBUTES 1252 +#define SQL_API_SQLGETSQLCA 1253 +#define SQL_API_SQLSETCONNECTION 1254 +#define SQL_API_SQLGETDATALINKATTR 1255 +#define SQL_API_SQLBUILDDATALINK 1256 +#define SQL_API_SQLNEXTRESULT 1257 +#define SQL_API_SQLEXTENDEDPREPARE 1296 +#define SQL_API_SQLEXTENDEDBIND 1297 + +#define SQL_API_SQLFETCHSCROLL 1021 +#define SQL_API_SQLGETLENGTH 1022 +#define SQL_API_SQLGETPOSITION 1023 +#define SQL_API_SQLGETSUBSTRING 1024 + + +#define SQL_API_SQLALLOCHANDLE 1001 +#define SQL_API_SQLFREEHANDLE 1006 +#define SQL_API_SQLCLOSECURSOR 1003 +#define SQL_API_SQLENDTRAN 1005 +#define SQL_API_SQLCOLATTRIBUTE 6 +#define SQL_API_SQLGETSTMTATTR 1014 +#define SQL_API_SQLGETCONNECTATTR 1007 + +/* SQLGetFunction defines - unsupported functions */ +#define SQL_EXT_API_LAST 72 + +/* Information requested by SQLGetInfo() */ +#define SQL_MAX_DRIVER_CONNECTIONS 0 +#define SQL_MAXIMUM_DRIVER_CONNECTIONS SQL_MAX_DRIVER_CONNECTIONS +#define SQL_MAX_CONCURRENT_ACTIVITIES 1 +#define SQL_MAXIMUM_CONCURRENT_ACTIVITIES SQL_MAX_CONCURRENT_ACTIVITIES +#define SQL_ATTR_ANSI_APP 115 + + +/* + * Defines for SQLGetDataLinkAttr. + */ +#define SQL_DATALINK_URL "URL" + +/* + * Datalink attribute values for SQLGetDataLinkAttr. + */ + +#define SQL_ATTR_DATALINK_COMMENT 1 +#define SQL_ATTR_DATALINK_LINKTYPE 2 +#define SQL_ATTR_DATALINK_URLCOMPLETE 3 +#define SQL_ATTR_DATALINK_URLPATH 4 +#define SQL_ATTR_DATALINK_URLPATHONLY 5 +#define SQL_ATTR_DATALINK_URLSCHEME 6 +#define SQL_ATTR_DATALINK_URLSERVER 7 + + +/* SQLGetInfo defines - Info Type */ +#define SQL_DATA_SOURCE_NAME 2 +#define SQL_FETCH_DIRECTION 8 +#define SQL_SERVER_NAME 13 +#define SQL_SEARCH_PATTERN_ESCAPE 14 +#define SQL_DBMS_NAME 17 +#define SQL_DBMS_VER 18 +#define SQL_ACCESSIBLE_TABLES 19 +#define SQL_ACCESSIBLE_PROCEDURES 20 +#define SQL_CURSOR_COMMIT_BEHAVIOR 23 +#define SQL_DATA_SOURCE_READ_ONLY 25 +#define SQL_DEFAULT_TXN_ISOLATION 26 +#define SQL_IDENTIFIER_CASE 28 +#define SQL_IDENTIFIER_QUOTE_CHAR 29 +#define SQL_MAX_COLUMN_NAME_LEN 30 +#define SQL_MAXIMUM_COLUMN_NAME_LENGTH SQL_MAX_COLUMN_NAME_LEN +#define SQL_MAX_CURSOR_NAME_LEN 31 +#define SQL_MAXIMUM_CURSOR_NAME_LENGTH SQL_MAX_CURSOR_NAME_LEN +#define SQL_MAX_TABLE_NAME_LEN 35 +#define SQL_SCROLL_CONCURRENCY 43 +#define SQL_TXN_CAPABLE 46 +#define SQL_TRANSACTION_CAPABLE SQL_TXN_CAPABLE +#define SQL_USER_NAME 47 +#define SQL_TXN_ISOLATION_OPTION 72 +#define SQL_TRANSACTION_ISOLATION_OPTION SQL_TXN_ISOLATION_OPTION +#define SQL_GETDATA_EXTENSIONS 81 +#define SQL_NULL_COLLATION 85 +#define SQL_ALTER_TABLE 86 +#define SQL_ORDER_BY_COLUMNS_IN_SELECT 90 +#define SQL_SPECIAL_CHARACTERS 94 +#define SQL_MAX_COLUMNS_IN_GROUP_BY 97 +#define SQL_MAXIMUM_COLUMNS_IN_GROUP_BY SQL_MAX_COLUMNS_IN_GROUP_BY +#define SQL_MAX_COLUMNS_IN_INDEX 98 +#define SQL_MAXIMUM_COLUMNS_IN_INDEX SQL_MAX_COLUMNS_IN_INDEX +#define SQL_MAX_COLUMNS_IN_ORDER_BY 99 +#define SQL_MAXIMUM_COLUMNS_IN_ORDER_BY SQL_MAX_COLUMNS_IN_ORDER_BY +#define SQL_MAX_COLUMNS_IN_SELECT 100 +#define SQL_MAXIMUM_COLUMNS_IN_SELECT SQL_MAX_COLUMNS_IN_SELECT +#define SQL_MAX_COLUMNS_IN_TABLE 101 +#define SQL_MAX_INDEX_SIZE 102 +#define SQL_MAXIMUM_INDEX_SIZE SQL_MAX_INDEX_SIZE +#define SQL_MAX_ROW_SIZE 104 +#define SQL_MAXIMUM_ROW_SIZE SQL_MAX_ROW_SIZE +#define SQL_MAX_STATEMENT_LEN 105 +#define SQL_MAXIMUM_STATEMENT_LENGTH SQL_MAX_STATEMENT_LEN +#define SQL_MAX_TABLES_IN_SELECT 106 +#define SQL_MAXIMUM_TABLES_IN_SELECT SQL_MAX_TABLES_IN_SELECT +#define SQL_MAX_USER_NAME_LEN 107 +#define SQL_MAXIMUM_USER_NAME_LENGTH SQL_MAX_USER_NAME_LEN +#define SQL_MAX_SCHEMA_NAME_LEN SQL_MAX_OWNER_NAME_LEN +#define SQL_MAXIMUM_SCHEMA_NAME_LENGTH SQL_MAX_SCHEMA_NAME_LEN +#define SQL_MAX_CATALOG_NAME_LEN SQL_MAX_QUALIFIER_NAME_LEN +#define SQL_MAXIMUM_CATALOG_NAME_LENGTH SQL_MAX_CATALOG_NAME_LEN +#define SQL_OJ_CAPABILITIES 115 +#define SQL_OUTER_JOIN_CAPABILITIES SQL_OJ_CAPABILITIES +#define SQL_XOPEN_CLI_YEAR 10000 +#define SQL_CURSOR_SENSITIVITY 10001 +#define SQL_DESCRIBE_PARAMETER 10002 +#define SQL_CATALOG_NAME 10003 +#define SQL_COLLATION_SEQ 10004 +#define SQL_MAX_IDENTIFIER_LEN 10005 +#define SQL_MAXIMUM_IDENTIFIER_LENGTH SQL_MAX_IDENTIFIER_LEN +#define SQL_INTEGRITY 73 +#define SQL_DATABASE_CODEPAGE 2519 +#define SQL_APPLICATION_CODEPAGE 2520 +#define SQL_CONNECT_CODEPAGE 2521 +#define SQL_ATTR_DB2_APPLICATION_ID 2532 +#define SQL_ATTR_DB2_APPLICATION_HANDLE 2533 +#define SQL_ATTR_HANDLE_XA_ASSOCIATED 2535 +#define SQL_DB2_DRIVER_VER 2550 +#define SQL_ATTR_XML_DECLARATION 2552 +#define SQL_ATTR_CURRENT_IMPLICIT_XMLPARSE_OPTION 2553 +#define SQL_ATTR_XQUERY_STATEMENT 2557 +#define SQL_DB2_DRIVER_TYPE 2567 + + +#define SQL_INFO_LAST 114 +#define SQL_INFO_DRIVER_START 1000 + +/* + * SQLExtendedPrepare statement types. + */ + +#define SQL_CLI_STMT_UNDEFINED 0 +#define SQL_CLI_STMT_ALTER_TABLE 1 +#define SQL_CLI_STMT_CREATE_INDEX 5 +#define SQL_CLI_STMT_CREATE_TABLE 6 +#define SQL_CLI_STMT_CREATE_VIEW 7 +#define SQL_CLI_STMT_DELETE_SEARCHED 8 +#define SQL_CLI_STMT_DELETE_POSITIONED 9 +#define SQL_CLI_STMT_DROP_PACKAGE 10 +#define SQL_CLI_STMT_DROP_INDEX 11 +#define SQL_CLI_STMT_DROP_TABLE 12 +#define SQL_CLI_STMT_DROP_VIEW 13 +#define SQL_CLI_STMT_GRANT 14 +#define SQL_CLI_STMT_INSERT 15 +#define SQL_CLI_STMT_REVOKE 16 +#define SQL_CLI_STMT_SELECT 18 +#define SQL_CLI_STMT_UPDATE_SEARCHED 19 +#define SQL_CLI_STMT_UPDATE_POSITIONED 20 +#define SQL_CLI_STMT_CALL 24 +#define SQL_CLI_STMT_SELECT_FOR_UPDATE 29 +#define SQL_CLI_STMT_WITH 30 +#define SQL_CLI_STMT_SELECT_FOR_FETCH 31 +#define SQL_CLI_STMT_VALUES 32 +#define SQL_CLI_STMT_CREATE_TRIGGER 34 +#define SQL_CLI_STMT_SELECT_OPTIMIZE_FOR_NROWS 39 +#define SQL_CLI_STMT_SELECT_INTO 40 +#define SQL_CLI_STMT_CREATE_PROCEDURE 41 +#define SQL_CLI_STMT_CREATE_FUNCTION 42 +#define SQL_CLI_STMT_INSERT_VALUES 45 +#define SQL_CLI_STMT_SET_CURRENT_QUERY_OPT 46 +#define SQL_CLI_STMT_MERGE 56 +#define SQL_CLI_STMT_XQUERY 59 + +/* + * IBM specific SQLGetInfo values. + */ + +#define SQL_IBM_ALTERTABLEVARCHAR 1000 + +/* SQL_ALTER_TABLE bitmasks */ +#define SQL_AT_ADD_COLUMN 0x00000001L +#define SQL_AT_DROP_COLUMN 0x00000002L +#define SQL_AT_ADD_CONSTRAINT 0x00000008L + +/* SQL_CURSOR_COMMIT_BEHAVIOR and SQL_CURSOR_ROLLBACK_BEHAVIOR values */ + +#define SQL_CB_DELETE 0x0000 +#define SQL_CB_CLOSE 0x0001 +#define SQL_CB_PRESERVE 0x0002 + +/* SQL_IDENTIFIER_CASE values */ + +#define SQL_IC_UPPER 0x0001 +#define SQL_IC_LOWER 0x0002 +#define SQL_IC_SENSITIVE 0x0003 +#define SQL_IC_MIXED 0x0004 + +/* SQL_TXN_CAPABLE values */ + +#define SQL_TC_NONE 0x0000 +#define SQL_TC_DML 0x0001 +#define SQL_TC_ALL 0x0002 +#define SQL_TC_DDL_COMMIT 0x0003 +#define SQL_TC_DDL_IGNORE 0x0004 + +/* SQL_SCROLL_CONCURRENCY masks */ + +#define SQL_SCCO_READ_ONLY 0x00000001L +#define SQL_SCCO_LOCK 0x00000002L +#define SQL_SCCO_OPT_ROWVER 0x00000004L +#define SQL_SCCO_OPT_VALUES 0x00000008L + +/* SQL_FETCH_DIRECTION masks */ + +#define SQL_FD_FETCH_NEXT 0x00000001L +#define SQL_FD_FETCH_FIRST 0x00000002L +#define SQL_FD_FETCH_LAST 0x00000004L +#define SQL_FD_FETCH_PRIOR 0x00000008L +#define SQL_FD_FETCH_ABSOLUTE 0x00000010L +#define SQL_FD_FETCH_RELATIVE 0x00000020L +#define SQL_FD_FETCH_RESUME 0x00000040L + +/* SQL_TXN_ISOLATION_OPTION masks */ +#define SQL_TXN_READ_UNCOMMITTED 0x00000001L +#define SQL_TRANSACTION_READ_UNCOMMITTED SQL_TXN_READ_UNCOMMITTED +#define SQL_TXN_READ_COMMITTED 0x00000002L +#define SQL_TRANSACTION_READ_COMMITTED SQL_TXN_READ_COMMITTED +#define SQL_TXN_REPEATABLE_READ 0x00000004L +#define SQL_TRANSACTION_REPEATABLE_READ SQL_TXN_REPEATABLE_READ +#define SQL_TXN_SERIALIZABLE 0x00000008L +#define SQL_TRANSACTION_SERIALIZABLE SQL_TXN_SERIALIZABLE +#define SQL_TXN_NOCOMMIT 0x00000020L +#define SQL_TRANSACTION_NOCOMMIT SQL_TXN_NOCOMMIT + +/* SQL_GETDATA_EXTENSIONS values */ + +#define SQL_GD_ANY_COLUMN 0x00000001L +#define SQL_GD_ANY_ORDER 0x00000002L + +/* SQL_OJ_CAPABILITIES values */ + +#define SQL_OJ_LEFT 0x00000001L +#define SQL_OJ_RIGHT 0x00000002L +#define SQL_OJ_FULL 0x00000004L +#define SQL_OJ_NESTED 0x00000008L +#define SQL_OJ_NOT_ORDERED 0x00000010L +#define SQL_OJ_INNER 0x00000020L +#define SQL_OJ_ALL_COMPARISON_OPS 0x00000040L + +/* SQL_DB2_DRIVER_TYPE values */ +#define SQL_CLI_DRIVER_TYPE_UNDEFINED 0 +#define SQL_CLI_DRIVER_RUNTIME_CLIENT 1 +#define SQL_CLI_DRIVER_CLI_DRIVER 2 + + +/* SQLGetTypeInfo define */ +#define SQL_ALL_TYPES 0 + +/* Options for SQLGetStmtOption/SQLSetStmtOption */ + +#define SQL_ATTR_AUTO_IPD 10001 +#define SQL_ATTR_APP_ROW_DESC 10010 +#define SQL_ATTR_APP_PARAM_DESC 10011 +#define SQL_ATTR_IMP_ROW_DESC 10012 +#define SQL_ATTR_IMP_PARAM_DESC 10013 +#define SQL_ATTR_METADATA_ID 10014 +#define SQL_ATTR_CURSOR_SCROLLABLE (-1) +#define SQL_ATTR_CURSOR_SENSITIVITY (-2) + +/* SQL_ATTR_CURSOR_SCROLLABLE values */ +#define SQL_NONSCROLLABLE 0 +#define SQL_SCROLLABLE 1 + + +/* Options for SQLGetStmtOption/SQLSetStmtOption extensions */ +#define SQL_CURSOR_HOLD 1250 +#define SQL_ATTR_CURSOR_HOLD 1250 +#define SQL_NODESCRIBE_OUTPUT 1251 +#define SQL_ATTR_NODESCRIBE_OUTPUT 1251 + +#define SQL_NODESCRIBE_INPUT 1264 +#define SQL_ATTR_NODESCRIBE_INPUT 1264 +#define SQL_NODESCRIBE SQL_NODESCRIBE_OUTPUT +#define SQL_ATTR_NODESCRIBE SQL_NODESCRIBE_OUTPUT +#define SQL_CLOSE_BEHAVIOR 1257 +#define SQL_ATTR_CLOSE_BEHAVIOR 1257 +#define SQL_ATTR_CLOSE_BEHAVIOR 1257 +#define SQL_ATTR_CLOSEOPEN 1265 +#define SQL_ATTR_CURRENT_PACKAGE_SET 1276 +#define SQL_ATTR_DEFERRED_PREPARE 1277 +#define SQL_ATTR_EARLYCLOSE 1268 +#define SQL_ATTR_PROCESSCTL 1278 +#define SQL_ATTR_PREFETCH 1285 +#define SQL_ATTR_ENABLE_IPD_SETTING 1286 +/* + * Descriptor value for setting the descriptor type. + */ + +#define SQL_DESC_DESCRIPTOR_TYPE 1287 + +#define SQL_ATTR_OPTIMIZE_SQLCOLUMNS 1288 +#define SQL_ATTR_MEM_DEBUG_DUMP 1289 +#define SQL_ATTR_CONNECT_NODE 1290 +#define SQL_ATTR_CONNECT_WITH_XA 1291 +#define SQL_ATTR_GET_XA_RESOURCE 1292 +#define SQL_ATTR_DB2_SQLERRP 2451 +#define SQL_ATTR_SERVER_MSGTXT_SP 2452 +#define SQL_ATTR_OPTIMIZE_FOR_NROWS 2450 +#define SQL_ATTR_QUERY_OPTIMIZATION_LEVEL 1293 +#define SQL_ATTR_USE_LIGHT_OUTPUT_SQLDA 1298 +#define SQL_ATTR_CURSOR_BLOCK_NUM_ROWS 2453 +#define SQL_ATTR_CURSOR_BLOCK_EARLY_CLOSE 2454 +#define SQL_ATTR_SERVER_MSGTXT_MASK 2455 +#define SQL_ATTR_USE_LIGHT_INPUT_SQLDA 2458 +#define SQL_ATTR_BLOCK_FOR_NROWS 2459 +#define SQL_ATTR_OPTIMIZE_ROWS_FOR_BLOCKING 2460 +#define SQL_ATTR_STATICMODE 2467 +#define SQL_ATTR_DB2_MESSAGE_PREFIX 2468 +#define SQL_ATTR_CALL_RETVAL_AS_PARM 2469 +#define SQL_ATTR_CALL_RETURN 2470 +#define SQL_ATTR_RETURN_USER_DEFINED_TYPES 2471 +#define SQL_ATTR_ENABLE_EXTENDED_PARAMDATA 2472 +#define SQL_ATTR_APP_TYPE 2473 +#define SQL_ATTR_TRANSFORM_GROUP 2474 +#define SQL_ATTR_DESCRIBE_CALL 2476 +#define SQL_ATTR_AUTOCOMMCLEANUP 2477 +#define SQL_ATTR_USEMALLOC 2478 +#define SQL_ATTR_PRESERVE_LOCALE 2479 +#define SQL_ATTR_MAPGRAPHIC 2480 +#define SQL_ATTR_INSERT_BUFFERING 2481 + +#define SQL_ATTR_USE_LOAD_API 2482 +#define SQL_ATTR_LOAD_RECOVERABLE 2483 +#define SQL_ATTR_LOAD_COPY_LOCATION 2484 +#define SQL_ATTR_LOAD_MESSAGE_FILE 2485 +#define SQL_ATTR_LOAD_SAVECOUNT 2486 +#define SQL_ATTR_LOAD_CPU_PARALLELISM 2487 +#define SQL_ATTR_LOAD_DISK_PARALLELISM 2488 +#define SQL_ATTR_LOAD_INDEXING_MODE 2489 +#define SQL_ATTR_LOAD_STATS_MODE 2490 +#define SQL_ATTR_LOAD_TEMP_FILES_PATH 2491 +#define SQL_ATTR_LOAD_DATA_BUFFER_SIZE 2492 +#define SQL_ATTR_LOAD_MODIFIED_BY 2493 +#define SQL_ATTR_DB2_RESERVED_2494 2494 +#define SQL_ATTR_DESCRIBE_BEHAVIOR 2495 +#define SQL_ATTR_FETCH_SENSITIVITY 2496 +#define SQL_ATTR_DB2_RESERVED_2497 2497 +#define SQL_ATTR_CLIENT_LOB_BUFFERING 2498 +#define SQL_ATTR_SKIP_TRACE 2499 +#define SQL_ATTR_LOAD_INFO 2501 +#define SQL_ATTR_DESCRIBE_INPUT_ON_PREPARE 2505 +#define SQL_ATTR_DESCRIBE_OUTPUT_LEVEL 2506 +#define SQL_ATTR_CURRENT_PACKAGE_PATH 2509 +#define SQL_ATTR_INFO_PROGRAMID 2511 +#define SQL_ATTR_INFO_PROGRAMNAME 2516 +#define SQL_ATTR_FREE_LOCATORS_ON_FETCH 2518 +#define SQL_ATTR_KEEP_DYNAMIC 2522 +#define SQL_ATTR_LOAD_ROWS_READ_PTR 2524 +#define SQL_ATTR_LOAD_ROWS_SKIPPED_PTR 2525 +#define SQL_ATTR_LOAD_ROWS_COMMITTED_PTR 2526 +#define SQL_ATTR_LOAD_ROWS_LOADED_PTR 2527 +#define SQL_ATTR_LOAD_ROWS_REJECTED_PTR 2528 +#define SQL_ATTR_LOAD_ROWS_DELETED_PTR 2529 +#define SQL_ATTR_LOAD_INFO_VER 2530 +#define SQL_ATTR_SET_SSA 2531 +#define SQL_ATTR_BLOCK_LOBS 2534 +#define SQL_ATTR_LOAD_ACCESS_LEVEL 2536 +#define SQL_ATTR_MAPCHAR 2546 +#define SQL_ATTR_ARM_CORRELATOR 2554 +#define SQL_ATTR_CLIENT_DEBUGINFO 2556 + +/* + * SQL_ATTR_DESCRIBE_INPUT / SQL_ATTR_DESCRIBE_OUTPUT values + */ +#define SQL_DESCRIBE_NONE 0 +#define SQL_DESCRIBE_LIGHT 1 +#define SQL_DESCRIBE_REGULAR 2 +#define SQL_DESCRIBE_EXTENDED 3 + +/* + * Use load values. + */ + +#define SQL_USE_LOAD_OFF 0 +#define SQL_USE_LOAD_INSERT 1 +#define SQL_USE_LOAD_REPLACE 2 +#define SQL_USE_LOAD_RESTART 3 +#define SQL_USE_LOAD_TERMINATE 4 + +/* + * SQL_ATTR_PREFETCH_ENABLE values. + */ + +#define SQL_PREFETCH_ON 1 +#define SQL_PREFETCH_OFF 0 +#define SQL_PREFETCH_DEFAULT SQL_PREFETCH_OFF + +/* SQL_CLOSE_BEHAVIOR values. */ + +#define SQL_CC_NO_RELEASE 0 +#define SQL_CC_RELEASE 1 +#define SQL_CC_DEFAULT SQL_CC_NO_RELEASE + +/* SQL_ATTR_DEFERRED_PREPARE values */ + +#define SQL_DEFERRED_PREPARE_ON 1 +#define SQL_DEFERRED_PREPARE_OFF 0 +#define SQL_DEFERRED_PREPARE_DEFAULT SQL_DEFERRED_PREPARE_ON + +/* SQL_ATTR_EARLYCLOSE values */ + +#define SQL_EARLYCLOSE_ON 1 +#define SQL_EARLYCLOSE_OFF 0 +#define SQL_EARLYCLOSE_SERVER 2 +#define SQL_EARLYCLOSE_DEFAULT SQL_EARLYCLOSE_ON + +/* SQL_ATTR_APP_TYPE values */ + +#define SQL_APP_TYPE_ODBC 1 +#define SQL_APP_TYPE_OLEDB 2 +#define SQL_APP_TYPE_JDBC 3 +#define SQL_APP_TYPE_ADONET 4 +#define SQL_APP_TYPE_DEFAULT SQL_APP_TYPE_ODBC + +/* SQL_ATTR_PROCESSCTL masks */ + +#define SQL_PROCESSCTL_NOTHREAD 0x00000001L +#define SQL_PROCESSCTL_NOFORK 0x00000002L +#define SQL_PROCESSCTL_SHARESTMTDESC 0x00000004L + +/* CLI attribute/option values */ +#define SQL_FALSE 0 +#define SQL_TRUE 1 + +/* Options for SQL_CURSOR_HOLD */ +#define SQL_CURSOR_HOLD_ON 1 +#define SQL_CURSOR_HOLD_OFF 0 +#define SQL_CURSOR_HOLD_DEFAULT SQL_CURSOR_HOLD_ON + + +/* Options for SQL_NODESCRIBE_INPUT/SQL_NODESCRIBE_OUTPUT */ +#define SQL_NODESCRIBE_ON 1 +#define SQL_NODESCRIBE_OFF 0 +#define SQL_NODESCRIBE_DEFAULT SQL_NODESCRIBE_OFF + +/* Options for SQL_ATTR_DESCRIBE_CALL */ +#define SQL_DESCRIBE_CALL_NEVER 0 +#define SQL_DESCRIBE_CALL_BEFORE 1 +#define SQL_DESCRIBE_CALL_ON_ERROR 2 +#define SQL_DESCRIBE_CALL_DEFAULT (-1) + +/* Options for SQL_ATTR_CLIENT_LOB_BUFFERING */ +#define SQL_CLIENTLOB_USE_LOCATORS 0 +#define SQL_CLIENTLOB_BUFFER_UNBOUND_LOBS 1 +#define SQL_CLIENTLOB_DEFAULT SQL_CLIENTLOB_USE_LOCATORS + +/* Options for SQL_ATTR_PREPDESC_BEHAVIOR */ +/* To be determined */ + +/* Options for SQLGetConnectOption/SQLSetConnectOption extensions */ +#define SQL_WCHARTYPE 1252 +#define SQL_LONGDATA_COMPAT 1253 +#define SQL_CURRENT_SCHEMA 1254 +#define SQL_DB2EXPLAIN 1258 +#define SQL_DB2ESTIMATE 1259 +#define SQL_PARAMOPT_ATOMIC 1260 +#define SQL_STMTTXN_ISOLATION 1261 +#define SQL_MAXCONN 1262 +#define SQL_ATTR_CLISCHEMA 1280 +#define SQL_ATTR_INFO_USERID 1281 +#define SQL_ATTR_INFO_WRKSTNNAME 1282 +#define SQL_ATTR_INFO_APPLNAME 1283 +#define SQL_ATTR_INFO_ACCTSTR 1284 +#define SQL_ATTR_AUTOCOMMIT_NOCOMMIT 2462 +#define SQL_ATTR_QUERY_PATROLLER 2466 +#define SQL_ATTR_CHAINING_BEGIN 2464 +#define SQL_ATTR_CHAINING_END 2465 +#define SQL_ATTR_EXTENDEDBIND 2475 +#define SQL_ATTR_GRAPHIC_UNICODESERVER 2503 +#define SQL_ATTR_RETURN_CHAR_AS_WCHAR_OLEDB 2517 +#define SQL_ATTR_GATEWAY_CONNECTED 2537 +#define SQL_ATTR_SQLCOLUMNS_SORT_BY_ORDINAL_OLEDB 2542 +#define SQL_ATTR_REPORT_ISLONG_FOR_LONGTYPES_OLEDB 2543 +#define SQL_ATTR_PING_DB 2545 +#define SQL_ATTR_RECEIVE_TIMEOUT 2547 +#define SQL_ATTR_REOPT 2548 +#define SQL_ATTR_LOB_CACHE_SIZE 2555 +#define SQL_ATTR_STREAM_GETDATA 2558 +#define SQL_ATTR_APP_USES_LOB_LOCATOR 2559 +#define SQL_ATTR_MAX_LOB_BLOCK_SIZE 2560 +#define SQL_ATTR_USE_TRUSTED_CONTEXT 2561 +#define SQL_ATTR_TRUSTED_CONTEXT_USERID 2562 +#define SQL_ATTR_TRUSTED_CONTEXT_PASSWORD 2563 +#define SQL_ATTR_USER_REGISTRY_NAME 2564 +#define SQL_ATTR_DECFLOAT_ROUNDING_MODE 2565 +#define SQL_ATTR_APPEND_FOR_FETCH_ONLY 2573 +#define SQL_ATTR_ONLY_USE_BIG_PACKAGES 2577 + +#define SQL_ATTR_WCHARTYPE SQL_WCHARTYPE +#define SQL_ATTR_LONGDATA_COMPAT SQL_LONGDATA_COMPAT +#define SQL_ATTR_CURRENT_SCHEMA SQL_CURRENT_SCHEMA +#define SQL_ATTR_DB2EXPLAIN SQL_DB2EXPLAIN +#define SQL_ATTR_DB2ESTIMATE SQL_DB2ESTIMATE +#define SQL_ATTR_PARAMOPT_ATOMIC SQL_PARAMOPT_ATOMIC +#define SQL_ATTR_STMTTXN_ISOLATION SQL_STMTTXN_ISOLATION +#define SQL_ATTR_MAXCONN SQL_MAXCONN + +/* Options for SQLSetConnectOption, SQLSetEnvAttr */ +#define SQL_CONNECTTYPE 1255 +#define SQL_SYNC_POINT 1256 +#define SQL_MINMEMORY_USAGE 1263 +#define SQL_CONN_CONTEXT 1269 +#define SQL_ATTR_INHERIT_NULL_CONNECT 1270 +#define SQL_ATTR_FORCE_CONVERSION_ON_CLIENT 1275 +#define SQL_ATTR_INFO_KEYWORDLIST 2500 + +#define SQL_ATTR_CONNECTTYPE SQL_CONNECTTYPE +#define SQL_ATTR_SYNC_POINT SQL_SYNC_POINT +#define SQL_ATTR_MINMEMORY_USAGE SQL_MINMEMORY_USAGE +#define SQL_ATTR_CONN_CONTEXT SQL_CONN_CONTEXT + +/* Options for SQL_LONGDATA_COMPAT */ +#define SQL_LD_COMPAT_YES 1 +#define SQL_LD_COMPAT_NO 0 +#define SQL_LD_COMPAT_DEFAULT SQL_LD_COMPAT_NO + +/* Options for SQL_ATTR_EXTENDEDBIND */ +#define SQL_ATTR_EXTENDEDBIND_COPY 1 +#define SQL_ATTR_EXTENDEDBIND_NOCOPY 0 +#define SQL_ATTR_EXTENDEDBIND_DEFAULT SQL_ATTR_EXTENDEDBIND_NOCOPY + +/* SQL_NULL_COLLATION values */ +#define SQL_NC_HIGH 0 +#define SQL_NC_LOW 1 + +/* Options for SQLGetInfo extentions */ +#define CLI_MAX_LONGVARCHAR 1250 +#define CLI_MAX_VARCHAR 1251 +#define CLI_MAX_CHAR 1252 +#define CLI_MAX_LONGVARGRAPHIC 1253 +#define CLI_MAX_VARGRAPHIC 1254 +#define CLI_MAX_GRAPHIC 1255 + +/* + * Private SQLGetDiagField extensions. + */ + +#define SQL_DIAG_MESSAGE_TEXT_PTR 2456 +#define SQL_DIAG_LINE_NUMBER 2461 +#define SQL_DIAG_ERRMC 2467 +#define SQL_DIAG_BYTES_PROCESSED 2477 +#define SQL_DIAG_RELATIVE_COST_ESTIMATE 2504 +#define SQL_DIAG_ROW_COUNT_ESTIMATE 2507 +#define SQL_DIAG_ELAPSED_SERVER_TIME 2538 +#define SQL_DIAG_ELAPSED_NETWORK_TIME 2539 +#define SQL_DIAG_ACCUMULATED_SERVER_TIME 2540 +#define SQL_DIAG_ACCUMULATED_NETWORK_TIME 2541 +#define SQL_DIAG_QUIESCE 2549 +#define SQL_DIAG_TOLERATED_ERROR 2559 + +/* + * Values for SQL_DIAG_QUIESCE + */ + +#define SQL_DIAG_QUIESCE_NO 0 +#define SQL_DIAG_QUIESCE_DATABASE 1 +#define SQL_DIAG_QUIESCE_INSTANCE 2 + +/* + * Private SQLSetEnvAttr extensions. + */ + +#define SQL_ATTR_LITTLE_ENDIAN_UNICODE 2457 +#define SQL_ATTR_DIAGLEVEL 2574 +#define SQL_ATTR_NOTIFYLEVEL 2575 +#define SQL_ATTR_DIAGPATH 2576 + +/* + * Options for SQL_PARAMOPT_ATOMIC + */ + +#define SQL_ATOMIC_YES 1 +#define SQL_ATOMIC_NO 0 +#define SQL_ATOMIC_DEFAULT SQL_ATOMIC_YES + +/* Options for SQL_CONNECT_TYPE */ +#define SQL_CONCURRENT_TRANS 1 +#define SQL_COORDINATED_TRANS 2 +#define SQL_CONNECTTYPE_DEFAULT SQL_CONCURRENT_TRANS + +/* Options for SQL_SYNCPOINT */ +#define SQL_ONEPHASE 1 +#define SQL_TWOPHASE 2 +#define SQL_SYNCPOINT_DEFAULT SQL_ONEPHASE + +/* Options for SQL_DB2ESTIMATE */ +#define SQL_DB2ESTIMATE_ON 1 +#define SQL_DB2ESTIMATE_OFF 0 +#define SQL_DB2ESTIMATE_DEFAULT SQL_DB2ESTIMATE_OFF + +/* Options for SQL_DB2EXPLAIN */ +#define SQL_DB2EXPLAIN_OFF 0x00000000L +#define SQL_DB2EXPLAIN_SNAPSHOT_ON 0x00000001L +#define SQL_DB2EXPLAIN_MODE_ON 0x00000002L +#define SQL_DB2EXPLAIN_SNAPSHOT_MODE_ON SQL_DB2EXPLAIN_SNAPSHOT_ON+SQL_DB2EXPLAIN_MODE_ON +#define SQL_DB2EXPLAIN_ON SQL_DB2EXPLAIN_SNAPSHOT_ON +#define SQL_DB2EXPLAIN_DEFAULT SQL_DB2EXPLAIN_OFF + +/* Options for SQL_WCHARTYPE + * Note that you can only specify SQL_WCHARTYPE_CONVERT if you have an + * external compile flag SQL_WCHART_CONVERT defined + */ +#ifdef SQL_WCHART_CONVERT +#define SQL_WCHARTYPE_CONVERT 1 +#endif +#define SQL_WCHARTYPE_NOCONVERT 0 +#define SQL_WCHARTYPE_DEFAULT SQL_WCHARTYPE_NOCONVERT + +/* Options for SQL_ATTR_OPTIMIZE_SQLCOLUMNS + * + */ +#define SQL_OPTIMIZE_SQLCOLUMNS_OFF 0 +#define SQL_OPTIMIZE_SQLCOLUMNS_ON 1 +#define SQL_OPTIMIZE_SQLCOLUMNS_DEFAULT SQL_OPTIMIZE_SQLCOLUMNS_OFF + +/* Options for SQL_ATTR_CONNECT_WITH_XA + * + */ +#define SQL_CONNECT_WITH_XA_OFF 0 +#define SQL_CONNECT_WITH_XA_ON 1 +#define SQL_CONNECT_WITH_XA_DEFAULT SQL_CONNECT_WITH_XA_OFF + +/* + * Options for SQL_ATTR_SERVER_MSGTXT_MASK + */ +#define SQL_ATTR_SERVER_MSGTXT_MASK_LOCAL_FIRST 0x00000000 +#define SQL_ATTR_SERVER_MSGTXT_MASK_WARNINGS 0x00000001 +#define SQL_ATTR_SERVER_MSGTXT_MASK_ERRORS 0xFFFFFFFE +#define SQL_ATTR_SERVER_MSGTXT_MASK_ALL 0xFFFFFFFF +#define SQL_ATTR_SERVER_MSGTXT_MASK_DEFAULT SQL_ATTR_SERVER_MSGTXT_MASK_LOCAL_FIRST + +/* + * Options for SQL_ATTR_QUERY_PATROLLER + */ +#define SQL_ATTR_QUERY_PATROLLER_DISABLE 1 +#define SQL_ATTR_QUERY_PATROLLER_ENABLE 2 +#define SQL_ATTR_QUERY_PATROLLER_BYPASS 3 + +/* + * Options for SQL_ATTR_STATICMODE + */ +#define SQL_STATICMODE_DISABLED 0 +#define SQL_STATICMODE_CAPTURE 1 +#define SQL_STATICMODE_MATCH 2 + +/* + * Options for SQL_ATTR_DB2_MESSAGE_PREFIX + */ +#define SQL_ATTR_DB2_MESSAGE_PREFIX_OFF 0 +#define SQL_ATTR_DB2_MESSAGE_PREFIX_ON 1 +#define SQL_ATTR_DB2_MESSAGE_PREFIX_DEFAULT SQL_ATTR_DB2_MESSAGE_PREFIX_ON + +/* + * Options for SQL_ATTR_INSERT_BUFFERING + */ +#define SQL_ATTR_INSERT_BUFFERING_OFF 0 +#define SQL_ATTR_INSERT_BUFFERING_ON 1 +#define SQL_ATTR_INSERT_BUFFERING_IGD 2 + +/* Column types and scopes in SQLSpecialColumns */ + +#define SQL_SCOPE_CURROW 0 +#define SQL_SCOPE_TRANSACTION 1 +#define SQL_SCOPE_SESSION 2 + +/* Defines for SQLStatistics */ +#define SQL_INDEX_UNIQUE 0 +#define SQL_INDEX_ALL 1 + +/* Defines for SQLStatistics (returned in the result set) */ +#define SQL_INDEX_CLUSTERED 1 +#define SQL_INDEX_HASHED 2 +#define SQL_INDEX_OTHER 3 + +/* Defines for SQLSpecialColumns (returned in the result set) */ +#define SQL_PC_UNKNOWN 0 +#define SQL_PC_NON_PSEUDO 1 +#define SQL_PC_PSEUDO 2 + +/* Reserved value for the IdentifierType argument of SQLSpecialColumns() */ +#define SQL_ROW_IDENTIFIER 1 + +/* Options for SQL_ATTR_MAPGRAPHIC */ +#define SQL_MAPGRAPHIC_DEFAULT -1 +#define SQL_MAPGRAPHIC_GRAPHIC 0 +#define SQL_MAPGRAPHIC_WCHAR 1 + +/* Options for SQL_ATTR_MAPCHAR */ +#define SQL_MAPCHAR_DEFAULT 0 +#define SQL_MAPCHAR_WCHAR 1 + +/* SQLDataSources "fDirection" values, also used on SQLExtendedFetch() */ +/* See sqlext.h for additional SQLExtendedFetch fetch direction defines */ +#define SQL_FETCH_NEXT 1 +#define SQL_FETCH_FIRST 2 + +/* OTHER CODES USED FOR FETCHORIENTATION IN SQLFETCHSCROLL() */ +#define SQL_FETCH_LAST 3 +#define SQL_FETCH_PRIOR 4 +#define SQL_FETCH_ABSOLUTE 5 +#define SQL_FETCH_RELATIVE 6 + +/* SQL_ATTR_XML_DECLARATION bitmask values */ +#define SQL_XML_DECLARATION_NONE 0x00000000 +#define SQL_XML_DECLARATION_BOM 0x00000001 +#define SQL_XML_DECLARATION_BASE 0x00000002 +#define SQL_XML_DECLARATION_ENCATTR 0x00000004 + +/* + * Environment attributes; note SQL_CONNECTTYPE, SQL_SYNC_POINT are also + * environment attributes that are settable at the connection level + */ + +#define SQL_ATTR_OUTPUT_NTS 10001 + + +/* LOB file reference options */ +#ifndef SQL_H_SQL /* if sql.h is not included, then... */ +#define SQL_FILE_READ 2 /* Input file to read from */ +#define SQL_FILE_CREATE 8 /* Output file - new file to be */ + /* created */ +#define SQL_FILE_OVERWRITE 16 /* Output file - overwrite existing */ + /* file or create a new file if it */ + /* doesn't exist */ +#define SQL_FILE_APPEND 32 /* Output file - append to an */ + /* existing file or create a new file */ + /* if it doesn't exist */ +#endif + +/* + * Source of string for SQLGetLength(), SQLGetPosition(), + * and SQLGetSubstring(). + */ +#define SQL_FROM_LOCATOR 2 +#define SQL_FROM_LITERAL 3 + +/* + * Options for Rounding Modes. These numeric values can + * be set with SQLSetConnectAttr() API for the attribute + * SQL_ATTR_DECFLOAT_ROUNDING_MODE. The SQLGetConnectAttr() + * API will return these values for the + * SQL_ATTR_DECFLOAT_ROUNDING_MODE attribute. + */ +#define SQL_ROUND_HALF_EVEN 0 +#define SQL_ROUND_HALF_UP 1 +#define SQL_ROUND_DOWN 2 +#define SQL_ROUND_CEILING 3 +#define SQL_ROUND_FLOOR 4 +#define SQL_ROUND_HALF_DOWN 5 +#define SQL_ROUND_UP 6 + +/* + * Function definitions of APIs in both X/Open CLI and ODBC + */ + +SQLRETURN SQL_API_FN SQLColumns (SQLHSTMT hstmt, + SQLCHAR FAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR FAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR FAR *szTableName, + SQLSMALLINT cbTableName, + SQLCHAR FAR *szColumnName, + SQLSMALLINT cbColumnName); + +SQLRETURN SQL_API_FN SQLDataSources (SQLHENV henv, + SQLUSMALLINT fDirection, + SQLCHAR FAR *szDSN, + SQLSMALLINT cbDSNMax, + SQLSMALLINT FAR *pcbDSN, + SQLCHAR FAR *szDescription, + SQLSMALLINT cbDescriptionMax, + SQLSMALLINT FAR *pcbDescription); +SQLRETURN SQL_API SQLFetchScroll( SQLHSTMT StatementHandle, + SQLSMALLINT FetchOrientation, + SQLLEN FetchOffset); +SQLRETURN SQL_API SQLGetConnectAttr( SQLHDBC ConnectionHandle, + SQLINTEGER Attribute, + SQLPOINTER Value, + SQLINTEGER BufferLength, + SQLINTEGER *StringLength); + +SQLRETURN SQL_API_FN SQLGetConnectOption ( + SQLHDBC hdbc, + SQLUSMALLINT fOption, + SQLPOINTER pvParam); + +SQLRETURN SQL_API_FN SQLGetFunctions (SQLHDBC hdbc, + SQLUSMALLINT fFunction, + SQLUSMALLINT FAR *pfExists); + +SQLRETURN SQL_API_FN SQLGetInfo (SQLHDBC hdbc, + SQLUSMALLINT fInfoType, + SQLPOINTER rgbInfoValue, + SQLSMALLINT cbInfoValueMax, + SQLSMALLINT FAR *pcbInfoValue); + +SQLRETURN SQL_API SQLGetStmtAttr( SQLHSTMT StatementHandle, + SQLINTEGER Attribute, + SQLPOINTER Value, + SQLINTEGER BufferLength, + SQLINTEGER *StringLength); + +SQLRETURN SQL_API_FN SQLGetStmtOption (SQLHSTMT hstmt, + SQLUSMALLINT fOption, + SQLPOINTER pvParam); + +SQLRETURN SQL_API_FN SQLGetTypeInfo (SQLHSTMT hstmt, + SQLSMALLINT fSqlType); + + +SQLRETURN SQL_API_FN SQLParamData (SQLHSTMT hstmt, + SQLPOINTER FAR *prgbValue); + +SQLRETURN SQL_API_FN SQLPutData (SQLHSTMT hstmt, + SQLPOINTER rgbValue, + SQLLEN cbValue); + +SQLRETURN SQL_API_FN SQLSetConnectAttr( + SQLHDBC hdbc, + SQLINTEGER fOption, + SQLPOINTER pvParam, + SQLINTEGER fStrLen); + +SQLRETURN SQL_API_FN SQLSetConnectOption( + SQLHDBC hdbc, + SQLUSMALLINT fOption, + SQLULEN vParam); + +SQLRETURN SQL_API_FN SQLSetStmtAttr (SQLHSTMT hstmt, + SQLINTEGER fOption, + SQLPOINTER pvParam, + SQLINTEGER fStrLen); + +SQLRETURN SQL_API_FN SQLSetStmtOption (SQLHSTMT hstmt, + SQLUSMALLINT fOption, + SQLULEN vParam); + +SQLRETURN SQL_API_FN SQLSpecialColumns(SQLHSTMT hstmt, + SQLUSMALLINT fColType, + SQLCHAR FAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR FAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR FAR *szTableName, + SQLSMALLINT cbTableName, + SQLUSMALLINT fScope, + SQLUSMALLINT fNullable); + +SQLRETURN SQL_API_FN SQLStatistics (SQLHSTMT hstmt, + SQLCHAR FAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR FAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR FAR *szTableName, + SQLSMALLINT cbTableName, + SQLUSMALLINT fUnique, + + SQLUSMALLINT fAccuracy); + +SQLRETURN SQL_API_FN SQLTables (SQLHSTMT hstmt, + SQLCHAR FAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR FAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR FAR *szTableName, + SQLSMALLINT cbTableName, + SQLCHAR FAR *szTableType, + SQLSMALLINT cbTableType); + +SQLRETURN SQL_API SQLNextResult (SQLHSTMT hstmtSource, + SQLHSTMT hstmtTarget); +/* UNICODE versions */ + +#ifdef ODBC64 +SQLRETURN SQL_API SQLColAttributeW( + SQLHSTMT hstmt, + SQLUSMALLINT iCol, + SQLUSMALLINT iField, + SQLPOINTER pCharAttr, + SQLSMALLINT cbCharAttrMax, + SQLSMALLINT *pcbCharAttr, + SQLLEN *pNumAttr); +#else + SQLRETURN SQL_API SQLColAttributeW( + SQLHSTMT hstmt, + SQLUSMALLINT iCol, + SQLUSMALLINT iField, + SQLPOINTER pCharAttr, + SQLSMALLINT cbCharAttrMax, + SQLSMALLINT *pcbCharAttr, + SQLPOINTER pNumAttr); +#endif + +SQLRETURN SQL_API SQLColAttributesW( + SQLHSTMT hstmt, + SQLUSMALLINT icol, + SQLUSMALLINT fDescType, + SQLPOINTER rgbDesc, + SQLSMALLINT cbDescMax, + SQLSMALLINT *pcbDesc, + SQLLEN *pfDesc); + +SQLRETURN SQL_API SQLConnectW( + SQLHDBC hdbc, + SQLWCHAR *szDSN, + SQLSMALLINT cbDSN, + SQLWCHAR *szUID, + SQLSMALLINT cbUID, + SQLWCHAR *szAuthStr, + SQLSMALLINT cbAuthStr); + +SQLRETURN SQL_API SQLConnectWInt( + SQLHDBC hdbc, + SQLWCHAR *szDSN, + SQLSMALLINT cbDSN, + SQLWCHAR *szUID, + SQLSMALLINT cbUID, + SQLWCHAR *szAuthStr, + SQLSMALLINT cbAuthStr); + + +SQLRETURN SQL_API SQLDescribeColW( + SQLHSTMT hstmt, + SQLUSMALLINT icol, + SQLWCHAR *szColName, + SQLSMALLINT cbColNameMax, + SQLSMALLINT *pcbColName, + SQLSMALLINT *pfSqlType, + SQLULEN *pcbColDef, + SQLSMALLINT *pibScale, + SQLSMALLINT *pfNullable); + + +SQLRETURN SQL_API SQLErrorW( + SQLHENV henv, + SQLHDBC hdbc, + SQLHSTMT hstmt, + SQLWCHAR *szSqlState, + SQLINTEGER *pfNativeError, + SQLWCHAR *szErrorMsg, + SQLSMALLINT cbErrorMsgMax, + SQLSMALLINT *pcbErrorMsg); + +SQLRETURN SQL_API SQLExecDirectW( + SQLHSTMT hstmt, + SQLWCHAR *szSqlStr, + SQLINTEGER cbSqlStr); + +SQLRETURN SQL_API SQLGetConnectAttrW( + SQLHDBC hdbc, + SQLINTEGER fAttribute, + SQLPOINTER rgbValue, + SQLINTEGER cbValueMax, + SQLINTEGER *pcbValue); + +SQLRETURN SQL_API SQLGetCursorNameW( + SQLHSTMT hstmt, + SQLWCHAR *szCursor, + SQLSMALLINT cbCursorMax, + SQLSMALLINT *pcbCursor); + +SQLRETURN SQL_API SQLSetDescFieldW(SQLHDESC DescriptorHandle, + SQLSMALLINT RecNumber, + SQLSMALLINT FieldIdentifier, + SQLPOINTER Value, + SQLINTEGER BufferLength); + + + +SQLRETURN SQL_API SQLGetDescFieldW( + SQLHDESC hdesc, + SQLSMALLINT iRecord, + SQLSMALLINT iField, + SQLPOINTER rgbValue, + SQLINTEGER cbValueMax, + SQLINTEGER *pcbValue); + +SQLRETURN SQL_API SQLGetDescRecW( + SQLHDESC hdesc, + SQLSMALLINT iRecord, + SQLWCHAR *szName, + SQLSMALLINT cbNameMax, + SQLSMALLINT *pcbName, + SQLSMALLINT *pfType, + SQLSMALLINT *pfSubType, + SQLLEN *pLength, + SQLSMALLINT *pPrecision, + SQLSMALLINT *pScale, + SQLSMALLINT *pNullable); + +SQLRETURN SQL_API SQLGetDiagFieldW( + SQLSMALLINT fHandleType, + SQLHANDLE handle, + SQLSMALLINT iRecord, + SQLSMALLINT fDiagField, + SQLPOINTER rgbDiagInfo, + SQLSMALLINT cbDiagInfoMax, + SQLSMALLINT *pcbDiagInfo); + +SQLRETURN SQL_API SQLGetDiagRecW( + SQLSMALLINT fHandleType, + SQLHANDLE handle, + SQLSMALLINT iRecord, + SQLWCHAR *szSqlState, + SQLINTEGER *pfNativeError, + SQLWCHAR *szErrorMsg, + SQLSMALLINT cbErrorMsgMax, + SQLSMALLINT *pcbErrorMsg); + +SQLRETURN SQL_API_FN SQLGetEnvAttrW( + SQLHENV hEnv, + SQLINTEGER fAttribute, + SQLPOINTER pParam, + SQLINTEGER cbParamMax, + SQLINTEGER * pcbParam ); + +SQLRETURN SQL_API SQLPrepareW( + SQLHSTMT hstmt, + SQLWCHAR *szSqlStr, + SQLINTEGER cbSqlStr); + +SQLRETURN SQL_API_FN SQLExtendedPrepareW( SQLHSTMT hStmt, + SQLWCHAR * pszSqlStrIn, + SQLINTEGER cbSqlStr, + SQLINTEGER cPars, + SQLSMALLINT sStmtType, + SQLINTEGER cStmtAttrs, + SQLINTEGER * piStmtAttr, + SQLINTEGER * pvParams ); + +SQLRETURN SQL_API SQLSetConnectAttrW( + SQLHDBC hdbc, + SQLINTEGER fAttribute, + SQLPOINTER rgbValue, + SQLINTEGER cbValue); + +SQLRETURN SQL_API SQLSetCursorNameW( + SQLHSTMT hstmt, + SQLWCHAR *szCursor, + SQLSMALLINT cbCursor); + +SQLRETURN SQL_API_FN SQLSetEnvAttrW( + SQLHENV hEnv, + SQLINTEGER fAttribute, + SQLPOINTER pParam, + SQLINTEGER cbParam ); + +SQLRETURN SQL_API SQLColumnsW( + SQLHSTMT hstmt, + SQLWCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLWCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLWCHAR *szTableName, + SQLSMALLINT cbTableName, + SQLWCHAR *szColumnName, + SQLSMALLINT cbColumnName); + +SQLRETURN SQL_API SQLGetInfoW( + SQLHDBC hdbc, + SQLUSMALLINT fInfoType, + SQLPOINTER rgbInfoValue, + SQLSMALLINT cbInfoValueMax, + SQLSMALLINT *pcbInfoValue); + +SQLRETURN SQL_API_FN SQLGetConnectOptionW( + SQLHDBC hDbc, + SQLUSMALLINT fOptionIn, + SQLPOINTER pvParam ); + +SQLRETURN SQL_API_FN SQLSetConnectOptionW( + SQLHDBC hDbc, + SQLUSMALLINT fOptionIn, + SQLULEN vParam ); + +SQLRETURN SQL_API_FN SQLGetTypeInfoW( + SQLHSTMT hstmt, + SQLSMALLINT fSqlType); + +SQLRETURN SQL_API SQLSpecialColumnsW( + SQLHSTMT hstmt, + SQLUSMALLINT fColType, + SQLWCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLWCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLWCHAR *szTableName, + SQLSMALLINT cbTableName, + SQLUSMALLINT fScope, + SQLUSMALLINT fNullable); + +SQLRETURN SQL_API SQLStatisticsW( + SQLHSTMT hstmt, + SQLWCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLWCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLWCHAR *szTableName, + SQLSMALLINT cbTableName, + SQLUSMALLINT fUnique, + SQLUSMALLINT fAccuracy); + +SQLRETURN SQL_API SQLTablesW( + SQLHSTMT hstmt, + SQLWCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLWCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLWCHAR *szTableName, + SQLSMALLINT cbTableName, + SQLWCHAR *szTableType, + SQLSMALLINT cbTableType); + + + +SQLRETURN SQL_API SQLDataSourcesW( + SQLHENV henv, + SQLUSMALLINT fDirection, + SQLWCHAR *szDSN, + SQLSMALLINT cbDSNMax, + SQLSMALLINT *pcbDSN, + SQLWCHAR *szDescription, + SQLSMALLINT cbDescriptionMax, + SQLSMALLINT *pcbDescription); + + + + +SQLRETURN SQL_API SQLDriverConnectW( + SQLHDBC hdbc, + SQLHWND hwnd, + SQLWCHAR *szConnStrIn, + SQLSMALLINT cbConnStrIn, + SQLWCHAR *szConnStrOut, + SQLSMALLINT cbConnStrOutMax, + SQLSMALLINT *pcbConnStrOut, + SQLUSMALLINT fDriverCompletion); + + +SQLRETURN SQL_API SQLBrowseConnectW( + SQLHDBC hdbc, + SQLWCHAR *szConnStrIn, + SQLSMALLINT cbConnStrIn, + SQLWCHAR *szConnStrOut, + SQLSMALLINT cbConnStrOutMax, + SQLSMALLINT *pcbConnStrOut); + +SQLRETURN SQL_API SQLColumnPrivilegesW( + SQLHSTMT hstmt, + SQLWCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLWCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLWCHAR *szTableName, + SQLSMALLINT cbTableName, + SQLWCHAR *szColumnName, + SQLSMALLINT cbColumnName); + +SQLRETURN SQL_API SQLGetStmtAttrW( + SQLHSTMT hstmt, + SQLINTEGER fAttribute, + SQLPOINTER rgbValue, + SQLINTEGER cbValueMax, + SQLINTEGER *pcbValue); + +SQLRETURN SQL_API SQLSetStmtAttrW( + SQLHSTMT hstmt, + SQLINTEGER fAttribute, + SQLPOINTER rgbValue, + SQLINTEGER cbValueMax); + +SQLRETURN SQL_API SQLForeignKeysW( + SQLHSTMT hstmt, + SQLWCHAR *szPkCatalogName, + SQLSMALLINT cbPkCatalogName, + SQLWCHAR *szPkSchemaName, + SQLSMALLINT cbPkSchemaName, + SQLWCHAR *szPkTableName, + SQLSMALLINT cbPkTableName, + SQLWCHAR *szFkCatalogName, + SQLSMALLINT cbFkCatalogName, + SQLWCHAR *szFkSchemaName, + SQLSMALLINT cbFkSchemaName, + SQLWCHAR *szFkTableName, + SQLSMALLINT cbFkTableName); + + +SQLRETURN SQL_API SQLNativeSqlW( + SQLHDBC hdbc, + SQLWCHAR *szSqlStrIn, + SQLINTEGER cbSqlStrIn, + SQLWCHAR *szSqlStr, + SQLINTEGER cbSqlStrMax, + SQLINTEGER *pcbSqlStr); + + +SQLRETURN SQL_API SQLPrimaryKeysW( + SQLHSTMT hstmt, + SQLWCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLWCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLWCHAR *szTableName, + SQLSMALLINT cbTableName); + +SQLRETURN SQL_API SQLProcedureColumnsW( + SQLHSTMT hstmt, + SQLWCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLWCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLWCHAR *szProcName, + SQLSMALLINT cbProcName, + SQLWCHAR *szColumnName, + SQLSMALLINT cbColumnName); + +SQLRETURN SQL_API SQLProceduresW( + SQLHSTMT hstmt, + SQLWCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLWCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLWCHAR *szProcName, + SQLSMALLINT cbProcName); + + +SQLRETURN SQL_API SQLTablePrivilegesW( + SQLHSTMT hstmt, + SQLWCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLWCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLWCHAR *szTableName, + SQLSMALLINT cbTableName); + + +/* + * DB2 specific CLI APIs + */ + +SQLRETURN SQL_API_FN SQLBindFileToCol (SQLHSTMT hstmt, + SQLUSMALLINT icol, + SQLCHAR FAR *FileName, + SQLSMALLINT FAR *FileNameLength, + SQLUINTEGER FAR *FileOptions, + SQLSMALLINT MaxFileNameLength, + SQLINTEGER FAR *StringLength, + SQLINTEGER FAR *IndicatorValue); + +SQLRETURN SQL_API_FN SQLBindFileToParam(SQLHSTMT hstmt, + SQLUSMALLINT ipar, + SQLSMALLINT fSqlType, + SQLCHAR FAR *FileName, + SQLSMALLINT FAR *FileNameLength, + SQLUINTEGER FAR *FileOptions, + SQLSMALLINT MaxFileNameLength, + SQLINTEGER FAR *IndicatorValue); + +SQLRETURN SQL_API_FN SQLGetLength (SQLHSTMT hstmt, + SQLSMALLINT LocatorCType, + SQLINTEGER Locator, + SQLINTEGER FAR *StringLength, + SQLINTEGER FAR *IndicatorValue); + +SQLRETURN SQL_API_FN SQLGetPosition (SQLHSTMT hstmt, + SQLSMALLINT LocatorCType, + SQLINTEGER SourceLocator, + SQLINTEGER SearchLocator, + SQLCHAR FAR *SearchLiteral, + SQLINTEGER SearchLiteralLength, + SQLUINTEGER FromPosition, + SQLUINTEGER FAR *LocatedAt, + SQLINTEGER FAR *IndicatorValue); + + +SQLRETURN SQL_API_FN SQLGetSQLCA (SQLHENV henv, + SQLHDBC hdbc, + SQLHSTMT hstmt, + struct sqlca FAR *pSqlca ); + +SQLRETURN SQL_API_FN SQLGetSubString (SQLHSTMT hstmt, + SQLSMALLINT LocatorCType, + SQLINTEGER SourceLocator, + SQLUINTEGER FromPosition, + SQLUINTEGER ForLength, + SQLSMALLINT TargetCType, + SQLPOINTER rgbValue, + SQLINTEGER cbValueMax, + SQLINTEGER FAR *StringLength, + SQLINTEGER FAR *IndicatorValue); + +SQLRETURN SQL_API_FN SQLSetColAttributes (SQLHSTMT hstmt, + SQLUSMALLINT icol, + SQLCHAR FAR *pszColName, + SQLSMALLINT cbColName, + SQLSMALLINT fSQLType, + SQLUINTEGER cbColDef, + SQLSMALLINT ibScale, + SQLSMALLINT fNullable); + +/* + * Set active connection API, for use in conjunction with embedded + * SQL programming only. + */ +SQLRETURN SQL_API_FN SQLSetConnection (SQLHDBC hdbc); + +/* + * APIs defined only by X/Open CLI + */ + +SQLRETURN SQL_API_FN SQLGetEnvAttr (SQLHENV henv, + SQLINTEGER Attribute, + SQLPOINTER Value, + SQLINTEGER BufferLength, + SQLINTEGER FAR *StringLength); + +SQLRETURN SQL_API_FN SQLSetEnvAttr (SQLHENV henv, + SQLINTEGER Attribute, + SQLPOINTER Value, + SQLINTEGER StringLength); + +SQLRETURN SQL_API_FN SQLBindParam( SQLHSTMT StatementHandle, + SQLUSMALLINT ParameterNumber, + SQLSMALLINT ValueType, + SQLSMALLINT ParameterType, + SQLULEN LengthPrecision, + SQLSMALLINT ParameterScale, + SQLPOINTER ParameterValue, + SQLLEN *StrLen_or_Ind); + +/* + * Data link functions. + */ + +SQLRETURN SQL_API_FN SQLBuildDataLink( SQLHSTMT hStmt, + SQLCHAR FAR * pszLinkType, + SQLINTEGER cbLinkType, + SQLCHAR FAR * pszDataLocation, + SQLINTEGER cbDataLocation, + SQLCHAR FAR * pszComment, + SQLINTEGER cbComment, + SQLCHAR FAR * pDataLink, + SQLINTEGER cbDataLinkMax, + SQLINTEGER FAR * pcbDataLink ); + +SQLRETURN SQL_API_FN SQLGetDataLinkAttr( SQLHSTMT hStmt, + SQLSMALLINT fAttrType, + SQLCHAR FAR * pDataLink, + SQLINTEGER cbDataLink, + SQLPOINTER pAttribute, + SQLINTEGER cbAttributeMax, + SQLINTEGER * pcbAttribute ); + +/* + * DB2 CLI APIs + */ + +SQLRETURN SQL_API_FN SQLExtendedPrepare( SQLHSTMT hstmt, + SQLCHAR * pszSqlStmt, + SQLINTEGER cbSqlStmt, + SQLINTEGER cPars, + SQLSMALLINT sStmtType, + SQLINTEGER cStmtAttrs, + SQLINTEGER * piStmtAttr, + SQLINTEGER * pvParams ); + +SQLRETURN SQL_API_FN SQLExtendedBind (SQLHSTMT hstmt, + SQLSMALLINT fBindCol, + SQLSMALLINT cRecords, + SQLSMALLINT * pfCType, + SQLPOINTER * rgbValue, + SQLINTEGER * cbValueMax, + SQLUINTEGER * puiPrecisionCType, + SQLSMALLINT * psScaleCType, + SQLINTEGER ** pcbValue, + SQLINTEGER ** piIndicatorPtr, + SQLSMALLINT * pfParamType, + SQLSMALLINT * pfSQLType, + SQLUINTEGER * pcbColDef, + SQLSMALLINT * pibScale ); + +#ifdef __cplusplus +} +#endif + +#define SQL_C_WCHAR SQL_WCHAR +#ifdef UNICODE +#define SQL_C_TCHAR SQL_C_WCHAR +typedef SQLWCHAR SQLTCHAR; +#else +#define SQL_C_TCHAR SQL_C_CHAR +typedef SQLCHAR SQLTCHAR; +#endif + +#define SQLConnectWInt SQLConnectW + +#ifdef UNICODE +#define SQLColAttribute SQLColAttributeW +#define SQLColAttributes SQLColAttributesW +#define SQLConnect SQLConnectW +#define SQLDescribeCol SQLDescribeColW +#define SQLError SQLErrorW +#define SQLExecDirect SQLExecDirectW +#define SQLGetConnectAttr SQLGetConnectAttrW +#define SQLGetCursorName SQLGetCursorNameW +#define SQLGetDescField SQLGetDescFieldW +#define SQLGetDescRec SQLGetDescRecW +#define SQLGetDiagField SQLGetDiagFieldW +#define SQLGetDiagRec SQLGetDiagRecW +#define SQLGetEnvAttr SQLGetEnvAttrW +#define SQLPrepare SQLPrepareW +#define SQLSetConnectAttr SQLSetConnectAttrW +#define SQLSetCursorName SQLSetCursorNameW +#define SQLSetDescField SQLSetDescFieldW +#define SQLSetEnvAttr SQLSetEnvAttrW +#define SQLSetStmtAttr SQLSetStmtAttrW +#define SQLGetStmtAttr SQLGetStmtAttrW +#define SQLColumns SQLColumnsW +#define SQLGetInfo SQLGetInfoW +#define SQLSpecialColumns SQLSpecialColumnsW +#define SQLStatistics SQLStatisticsW +#define SQLTables SQLTablesW +#define SQLDataSources SQLDataSourcesW +#define SQLDriverConnect SQLDriverConnectW +#define SQLBrowseConnect SQLBrowseConnectW +#define SQLColumnPrivileges SQLColumnPrivilegesW +#define SQLForeignKeys SQLForeignKeysW +#define SQLNativeSql SQLNativeSqlW +#define SQLPrimaryKeys SQLPrimaryKeysW +#define SQLProcedureColumns SQLProcedureColumnsW +#define SQLProcedures SQLProceduresW +#define SQLTablePrivileges SQLTablePrivilegesW +#endif /* UNICODE */ + +#ifdef DB2_WINSOCKAPI_ +#undef _WINSOCKAPI_ +#undef DB2_WINSOCKAPI_ +#endif + +#endif /* SQL_H_SQLCLI1 */ diff --git a/libodbc/include/db2_linux/sqlext.h b/libodbc/include/db2_linux/sqlext.h new file mode 100644 index 0000000000..1dcf5d7e4a --- /dev/null +++ b/libodbc/include/db2_linux/sqlext.h @@ -0,0 +1,2065 @@ +/***************************************************************** +** SQLEXT.H - This is the include for applications using +** the Microsoft SQL Extensions +** +** (C) Copyright 1990 - 1998 By Microsoft Corp. +** +** Updated 05/12/93 for 2.00 specification +** Updated 05/23/94 for 2.01 specification +** Updated 10/27/94 for 2.10 specification +** Updated 04/10/95 for 2.50 specification +** Updated 07/25/95 for 3.00 specification +** Updated 01/12/96 for 3.00 preliminary release +** Updated 10/22/97 for 3.51 specification +*********************************************************************/ + +#ifndef __SQLEXT +#define __SQLEXT + +/* ODBC64 should be used instead of CLI_WIN64 for linking with libdb2o.dll */ +#ifndef ODBC64 +#ifdef CLI_WIN64 +#define ODBC64 +#endif +#endif + +#ifndef __SQL +#include "sql.h" +#endif + +#ifdef __cplusplus +extern "C" { /* Assume C declarations for C++ */ +#endif /* __cplusplus */ + +/* generally useful constants */ +#define SQL_SPEC_MAJOR 3 /* Major version of specification */ +#define SQL_SPEC_MINOR 51 /* Minor version of specification */ +#define SQL_SPEC_STRING "03.51" /* String constant for version */ + +#define SQL_SQLSTATE_SIZE 5 /* size of SQLSTATE */ +#define SQL_MAX_DSN_LENGTH 32 /* maximum data source name size */ + +#define SQL_MAX_OPTION_STRING_LENGTH 256 + +/* return code SQL_NO_DATA_FOUND is the same as SQL_NO_DATA */ +#if (ODBCVER < 0x0300) +#define SQL_NO_DATA_FOUND 100 +#else +#define SQL_NO_DATA_FOUND SQL_NO_DATA +#endif + +/* an end handle type */ +#if (ODBCVER >= 0x0300) +#define SQL_HANDLE_SENV 5 +#endif /* ODBCVER >= 0x0300 */ + +/* env attribute */ +#if (ODBCVER >= 0x0300) +#define SQL_ATTR_ODBC_VERSION 200 +#define SQL_ATTR_CONNECTION_POOLING 201 +#define SQL_ATTR_CP_MATCH 202 +#endif /* ODBCVER >= 0x0300 */ + +#if (ODBCVER >= 0x0300) +/* values for SQL_ATTR_CONNECTION_POOLING */ +#define SQL_CP_OFF 0UL +#define SQL_CP_ONE_PER_DRIVER 1UL +#define SQL_CP_ONE_PER_HENV 2UL +#define SQL_CP_DEFAULT SQL_CP_OFF + +/* values for SQL_ATTR_CP_MATCH */ +#define SQL_CP_STRICT_MATCH 0UL +#define SQL_CP_RELAXED_MATCH 1UL +#define SQL_CP_MATCH_DEFAULT SQL_CP_STRICT_MATCH + +/* values for SQL_ATTR_ODBC_VERSION */ +#define SQL_OV_ODBC2 2UL +#define SQL_OV_ODBC3 3UL +#endif /* ODBCVER >= 0x0300 */ + +/* connection attributes */ +#define SQL_ACCESS_MODE 101 +#define SQL_AUTOCOMMIT 102 +#define SQL_LOGIN_TIMEOUT 103 +#define SQL_OPT_TRACE 104 +#define SQL_OPT_TRACEFILE 105 +#define SQL_TRANSLATE_DLL 106 +#define SQL_TRANSLATE_OPTION 107 +#define SQL_TXN_ISOLATION 108 +#define SQL_CURRENT_QUALIFIER 109 +#define SQL_ODBC_CURSORS 110 +#define SQL_QUIET_MODE 111 +#define SQL_PACKET_SIZE 112 + +/* connection attributes with new names */ +#if (ODBCVER >= 0x0300) +#define SQL_ATTR_ACCESS_MODE SQL_ACCESS_MODE +#define SQL_ATTR_AUTOCOMMIT SQL_AUTOCOMMIT +#define SQL_ATTR_CONNECTION_TIMEOUT 113 +#define SQL_ATTR_CURRENT_CATALOG SQL_CURRENT_QUALIFIER +#define SQL_ATTR_DISCONNECT_BEHAVIOR 114 +#define SQL_ATTR_ENLIST_IN_DTC 1207 +#define SQL_ATTR_ENLIST_IN_XA 1208 +#define SQL_ATTR_LOGIN_TIMEOUT SQL_LOGIN_TIMEOUT +#define SQL_ATTR_ODBC_CURSORS SQL_ODBC_CURSORS +#define SQL_ATTR_PACKET_SIZE SQL_PACKET_SIZE +#define SQL_ATTR_QUIET_MODE SQL_QUIET_MODE +#define SQL_ATTR_TRACE SQL_OPT_TRACE +#define SQL_ATTR_TRACEFILE SQL_OPT_TRACEFILE +#define SQL_ATTR_TRANSLATE_LIB SQL_TRANSLATE_DLL +#define SQL_ATTR_TRANSLATE_OPTION SQL_TRANSLATE_OPTION +#define SQL_ATTR_TXN_ISOLATION SQL_TXN_ISOLATION +#endif /* ODBCVER >= 0x0300 */ + +#define SQL_ATTR_CONNECTION_DEAD 1209 /* GetConnectAttr only */ + +#if (ODBCVER >= 0x0351) +/* ODBC Driver Manager sets this connection attribute to a unicode driver + (which supports SQLConnectW) when the application is an ANSI application + (which calls SQLConnect, SQLDriverConnect, or SQLBrowseConnect). + This is SetConnectAttr only and application does not set this attribute + This attribute was introduced because some unicode driver's some APIs may + need to behave differently on ANSI or Unicode applications. A unicode + driver, which has same behavior for both ANSI or Unicode applications, + should return SQL_ERROR when the driver manager sets this connection + attribute. When a unicode driver returns SQL_SUCCESS on this attribute, + the driver manager treates ANSI and Unicode connections differently in + connection pooling. +*/ +#define SQL_ATTR_ANSI_APP 115 +#endif + +/* SQL_CONNECT_OPT_DRVR_START is not meaningful for 3.0 driver */ +#if (ODBCVER < 0x0300) +#define SQL_CONNECT_OPT_DRVR_START 1000 +#endif /* ODBCVER < 0x0300 */ + +#if (ODBCVER < 0x0300) +#define SQL_CONN_OPT_MAX SQL_PACKET_SIZE +#define SQL_CONN_OPT_MIN SQL_ACCESS_MODE +#endif /* ODBCVER < 0x0300 */ + +/* SQL_ACCESS_MODE options */ +#define SQL_MODE_READ_WRITE 0UL +#define SQL_MODE_READ_ONLY 1UL +#define SQL_MODE_DEFAULT SQL_MODE_READ_WRITE + +/* SQL_AUTOCOMMIT options */ +#define SQL_AUTOCOMMIT_OFF 0UL +#define SQL_AUTOCOMMIT_ON 1UL +#define SQL_AUTOCOMMIT_DEFAULT SQL_AUTOCOMMIT_ON + +/* SQL_LOGIN_TIMEOUT options */ +#define SQL_LOGIN_TIMEOUT_DEFAULT 15UL + +/* SQL_OPT_TRACE options */ +#define SQL_OPT_TRACE_OFF 0UL +#define SQL_OPT_TRACE_ON 1UL +#define SQL_OPT_TRACE_DEFAULT SQL_OPT_TRACE_OFF +#define SQL_OPT_TRACE_FILE_DEFAULT "\\SQL.LOG" + +/* SQL_ODBC_CURSORS options */ +#define SQL_CUR_USE_IF_NEEDED 0UL +#define SQL_CUR_USE_ODBC 1UL +#define SQL_CUR_USE_DRIVER 2UL +#define SQL_CUR_DEFAULT SQL_CUR_USE_DRIVER + +#if (ODBCVER >= 0x0300) +/* values for SQL_ATTR_DISCONNECT_BEHAVIOR */ +#define SQL_DB_RETURN_TO_POOL 0UL +#define SQL_DB_DISCONNECT 1UL +#define SQL_DB_DEFAULT SQL_DB_RETURN_TO_POOL + +/* values for SQL_ATTR_ENLIST_IN_DTC */ +#define SQL_DTC_DONE 0L +#endif /* ODBCVER >= 0x0300 */ + +/* values for SQL_ATTR_CONNECTION_DEAD */ +#define SQL_CD_TRUE 1L /* Connection is closed/dead */ +#define SQL_CD_FALSE 0L /* Connection is open/available */ + +/* values for SQL_ATTR_ANSI_APP */ +#if (ODBCVER >= 0x0351) +#define SQL_AA_TRUE 1L /* the application is an ANSI app */ +#define SQL_AA_FALSE 0L /* the application is a Unicode app */ +#endif + +/* statement attributes */ +#define SQL_QUERY_TIMEOUT 0 +#define SQL_MAX_ROWS 1 +#define SQL_NOSCAN 2 +#define SQL_MAX_LENGTH 3 +#define SQL_ASYNC_ENABLE 4 /* same as SQL_ATTR_ASYNC_ENABLE */ +#define SQL_BIND_TYPE 5 +#define SQL_CURSOR_TYPE 6 +#define SQL_CONCURRENCY 7 +#define SQL_KEYSET_SIZE 8 +#define SQL_ROWSET_SIZE 9 +#define SQL_SIMULATE_CURSOR 10 +#define SQL_RETRIEVE_DATA 11 +#define SQL_USE_BOOKMARKS 12 +#define SQL_GET_BOOKMARK 13 /* GetStmtOption Only */ +#define SQL_ROW_NUMBER 14 /* GetStmtOption Only */ + +/* statement attributes for ODBC 3.0 */ +#if (ODBCVER >= 0x0300) +#define SQL_ATTR_ASYNC_ENABLE 4 +#define SQL_ATTR_CONCURRENCY SQL_CONCURRENCY +#define SQL_ATTR_CURSOR_TYPE SQL_CURSOR_TYPE +#define SQL_ATTR_ENABLE_AUTO_IPD 15 +#define SQL_ATTR_FETCH_BOOKMARK_PTR 16 +#define SQL_ATTR_KEYSET_SIZE SQL_KEYSET_SIZE +#define SQL_ATTR_MAX_LENGTH SQL_MAX_LENGTH +#define SQL_ATTR_MAX_ROWS SQL_MAX_ROWS +#define SQL_ATTR_NOSCAN SQL_NOSCAN +#define SQL_ATTR_PARAM_BIND_OFFSET_PTR 17 +#define SQL_ATTR_PARAM_BIND_TYPE 18 +#define SQL_ATTR_PARAM_OPERATION_PTR 19 +#define SQL_ATTR_PARAM_STATUS_PTR 20 +#define SQL_ATTR_PARAMS_PROCESSED_PTR 21 +#define SQL_ATTR_PARAMSET_SIZE 22 +#define SQL_ATTR_QUERY_TIMEOUT SQL_QUERY_TIMEOUT +#define SQL_ATTR_RETRIEVE_DATA SQL_RETRIEVE_DATA +#define SQL_ATTR_ROW_BIND_OFFSET_PTR 23 +#define SQL_ATTR_ROW_BIND_TYPE SQL_BIND_TYPE +#define SQL_ATTR_ROW_NUMBER SQL_ROW_NUMBER /*GetStmtAttr*/ +#define SQL_ATTR_ROW_OPERATION_PTR 24 +#define SQL_ATTR_ROW_STATUS_PTR 25 +#define SQL_ATTR_ROWS_FETCHED_PTR 26 +#define SQL_ATTR_ROW_ARRAY_SIZE 27 +#define SQL_ATTR_SIMULATE_CURSOR SQL_SIMULATE_CURSOR +#define SQL_ATTR_USE_BOOKMARKS SQL_USE_BOOKMARKS + +#endif /* ODBCVER >= 0x0300 */ + +#if (ODBCVER < 0x0300) +#define SQL_STMT_OPT_MAX SQL_ROW_NUMBER +#define SQL_STMT_OPT_MIN SQL_QUERY_TIMEOUT +#endif /* ODBCVER < 0x0300 */ + +/* New defines for SEARCHABLE column in SQLGetTypeInfo */ + +#if (ODBCVER >= 0x0300) +#define SQL_COL_PRED_CHAR SQL_LIKE_ONLY +#define SQL_COL_PRED_BASIC SQL_ALL_EXCEPT_LIKE +#endif /* ODBCVER >= 0x0300 */ + + + +/* whether an attribute is a pointer or not */ +#if (ODBCVER >= 0x0300) +#define SQL_IS_POINTER (-4) +#define SQL_IS_UINTEGER (-5) +#define SQL_IS_INTEGER (-6) +#define SQL_IS_USMALLINT (-7) +#define SQL_IS_SMALLINT (-8) +#endif /* ODBCVER >= 0x0300 */ + +/* the value of SQL_ATTR_PARAM_BIND_TYPE */ +#if (ODBCVER >= 0x0300) +#define SQL_PARAM_BIND_BY_COLUMN 0UL +#define SQL_PARAM_BIND_TYPE_DEFAULT SQL_PARAM_BIND_BY_COLUMN +#endif /* ODBCVER >= 0x0300 */ + +/* SQL_QUERY_TIMEOUT options */ +#define SQL_QUERY_TIMEOUT_DEFAULT 0UL + +/* SQL_MAX_ROWS options */ +#define SQL_MAX_ROWS_DEFAULT 0UL + +/* SQL_NOSCAN options */ +#define SQL_NOSCAN_OFF 0UL /* 1.0 FALSE */ +#define SQL_NOSCAN_ON 1UL /* 1.0 TRUE */ +#define SQL_NOSCAN_DEFAULT SQL_NOSCAN_OFF + +/* SQL_MAX_LENGTH options */ +#define SQL_MAX_LENGTH_DEFAULT 0UL + +/* values for SQL_ATTR_ASYNC_ENABLE */ +#define SQL_ASYNC_ENABLE_OFF 0UL +#define SQL_ASYNC_ENABLE_ON 1UL +#define SQL_ASYNC_ENABLE_DEFAULT SQL_ASYNC_ENABLE_OFF + +/* SQL_BIND_TYPE options */ +#define SQL_BIND_BY_COLUMN 0UL +#define SQL_BIND_TYPE_DEFAULT SQL_BIND_BY_COLUMN /* Default value */ + +/* SQL_CONCURRENCY options */ +#define SQL_CONCUR_READ_ONLY 1 +#define SQL_CONCUR_LOCK 2 +#define SQL_CONCUR_ROWVER 3 +#define SQL_CONCUR_VALUES 4 +#define SQL_CONCUR_DEFAULT SQL_CONCUR_READ_ONLY /* Default value */ + +/* SQL_CURSOR_TYPE options */ +#define SQL_CURSOR_FORWARD_ONLY 0UL +#define SQL_CURSOR_KEYSET_DRIVEN 1UL +#define SQL_CURSOR_DYNAMIC 2UL +#define SQL_CURSOR_STATIC 3UL +#define SQL_CURSOR_TYPE_DEFAULT SQL_CURSOR_FORWARD_ONLY /* Default value */ + +/* SQL_ROWSET_SIZE options */ +#define SQL_ROWSET_SIZE_DEFAULT 1UL + +/* SQL_KEYSET_SIZE options */ +#define SQL_KEYSET_SIZE_DEFAULT 0UL + +/* SQL_SIMULATE_CURSOR options */ +#define SQL_SC_NON_UNIQUE 0UL +#define SQL_SC_TRY_UNIQUE 1UL +#define SQL_SC_UNIQUE 2UL + +/* SQL_RETRIEVE_DATA options */ +#define SQL_RD_OFF 0UL +#define SQL_RD_ON 1UL +#define SQL_RD_DEFAULT SQL_RD_ON + +/* SQL_USE_BOOKMARKS options */ +#define SQL_UB_OFF 0UL +#define SQL_UB_ON 01UL +#define SQL_UB_DEFAULT SQL_UB_OFF + +/* New values for SQL_USE_BOOKMARKS attribute */ +#if (ODBCVER >= 0x0300) +#define SQL_UB_FIXED SQL_UB_ON +#define SQL_UB_VARIABLE 2UL +#endif /* ODBCVER >= 0x0300 */ + +/* extended descriptor field */ +#if (ODBCVER >= 0x0300) +#define SQL_DESC_ARRAY_SIZE 20 +#define SQL_DESC_ARRAY_STATUS_PTR 21 +#define SQL_DESC_AUTO_UNIQUE_VALUE SQL_COLUMN_AUTO_INCREMENT +#define SQL_DESC_BASE_COLUMN_NAME 22 +#define SQL_DESC_BASE_TABLE_NAME 23 +#define SQL_DESC_BIND_OFFSET_PTR 24 +#define SQL_DESC_BIND_TYPE 25 +#define SQL_DESC_CASE_SENSITIVE SQL_COLUMN_CASE_SENSITIVE +#define SQL_DESC_CATALOG_NAME SQL_COLUMN_QUALIFIER_NAME +#define SQL_DESC_CONCISE_TYPE SQL_COLUMN_TYPE +#define SQL_DESC_DATETIME_INTERVAL_PRECISION 26 +#define SQL_DESC_DISPLAY_SIZE SQL_COLUMN_DISPLAY_SIZE +#define SQL_DESC_FIXED_PREC_SCALE SQL_COLUMN_MONEY +#define SQL_DESC_LABEL SQL_COLUMN_LABEL +#define SQL_DESC_LITERAL_PREFIX 27 +#define SQL_DESC_LITERAL_SUFFIX 28 +#define SQL_DESC_LOCAL_TYPE_NAME 29 +#define SQL_DESC_MAXIMUM_SCALE 30 +#define SQL_DESC_MINIMUM_SCALE 31 +#define SQL_DESC_NUM_PREC_RADIX 32 +#define SQL_DESC_PARAMETER_TYPE 33 +#define SQL_DESC_ROWS_PROCESSED_PTR 34 +#if (ODBCVER >= 0x0350) +#define SQL_DESC_ROWVER 35 +#endif /* ODBCVER >= 0x0350 */ +#define SQL_DESC_SCHEMA_NAME SQL_COLUMN_OWNER_NAME +#define SQL_DESC_SEARCHABLE SQL_COLUMN_SEARCHABLE +#define SQL_DESC_TYPE_NAME SQL_COLUMN_TYPE_NAME +#define SQL_DESC_TABLE_NAME SQL_COLUMN_TABLE_NAME +#define SQL_DESC_UNSIGNED SQL_COLUMN_UNSIGNED +#define SQL_DESC_UPDATABLE SQL_COLUMN_UPDATABLE +#endif /* ODBCVER >= 0x0300 */ + + +/* defines for diagnostics fields */ +#if (ODBCVER >= 0x0300) +#define SQL_DIAG_CURSOR_ROW_COUNT (-1249) +#define SQL_DIAG_ROW_NUMBER (-1248) +#define SQL_DIAG_COLUMN_NUMBER (-1247) +#endif /* ODBCVER >= 0x0300 */ + +/* SQL extended datatypes */ +#define SQL_DATE 9 +#if (ODBCVER >= 0x0300) +#define SQL_INTERVAL 10 +#endif /* ODBCVER >= 0x0300 */ +#define SQL_TIME 10 +#define SQL_TIMESTAMP 11 +#define SQL_LONGVARCHAR (-1) +#define SQL_BINARY (-2) +#define SQL_VARBINARY (-3) +#define SQL_LONGVARBINARY (-4) +#define SQL_BIGINT (-5) +#define SQL_TINYINT (-6) +#define SQL_BIT (-7) +#if (ODBCVER >= 0x0350) +#define SQL_GUID (-11) +#endif /* ODBCVER >= 0x0350 */ + +#if (ODBCVER >= 0x0300) +/* interval code */ +#define SQL_CODE_YEAR 1 +#define SQL_CODE_MONTH 2 +#define SQL_CODE_DAY 3 +#define SQL_CODE_HOUR 4 +#define SQL_CODE_MINUTE 5 +#define SQL_CODE_SECOND 6 +#define SQL_CODE_YEAR_TO_MONTH 7 +#define SQL_CODE_DAY_TO_HOUR 8 +#define SQL_CODE_DAY_TO_MINUTE 9 +#define SQL_CODE_DAY_TO_SECOND 10 +#define SQL_CODE_HOUR_TO_MINUTE 11 +#define SQL_CODE_HOUR_TO_SECOND 12 +#define SQL_CODE_MINUTE_TO_SECOND 13 + +#define SQL_INTERVAL_YEAR (100 + SQL_CODE_YEAR) +#define SQL_INTERVAL_MONTH (100 + SQL_CODE_MONTH) +#define SQL_INTERVAL_DAY (100 + SQL_CODE_DAY) +#define SQL_INTERVAL_HOUR (100 + SQL_CODE_HOUR) +#define SQL_INTERVAL_MINUTE (100 + SQL_CODE_MINUTE) +#define SQL_INTERVAL_SECOND (100 + SQL_CODE_SECOND) +#define SQL_INTERVAL_YEAR_TO_MONTH (100 + SQL_CODE_YEAR_TO_MONTH) +#define SQL_INTERVAL_DAY_TO_HOUR (100 + SQL_CODE_DAY_TO_HOUR) +#define SQL_INTERVAL_DAY_TO_MINUTE (100 + SQL_CODE_DAY_TO_MINUTE) +#define SQL_INTERVAL_DAY_TO_SECOND (100 + SQL_CODE_DAY_TO_SECOND) +#define SQL_INTERVAL_HOUR_TO_MINUTE (100 + SQL_CODE_HOUR_TO_MINUTE) +#define SQL_INTERVAL_HOUR_TO_SECOND (100 + SQL_CODE_HOUR_TO_SECOND) +#define SQL_INTERVAL_MINUTE_TO_SECOND (100 + SQL_CODE_MINUTE_TO_SECOND) + +#else +#define SQL_INTERVAL_YEAR (-80) +#define SQL_INTERVAL_MONTH (-81) +#define SQL_INTERVAL_YEAR_TO_MONTH (-82) +#define SQL_INTERVAL_DAY (-83) +#define SQL_INTERVAL_HOUR (-84) +#define SQL_INTERVAL_MINUTE (-85) +#define SQL_INTERVAL_SECOND (-86) +#define SQL_INTERVAL_DAY_TO_HOUR (-87) +#define SQL_INTERVAL_DAY_TO_MINUTE (-88) +#define SQL_INTERVAL_DAY_TO_SECOND (-89) +#define SQL_INTERVAL_HOUR_TO_MINUTE (-90) +#define SQL_INTERVAL_HOUR_TO_SECOND (-91) +#define SQL_INTERVAL_MINUTE_TO_SECOND (-92) +#endif /* ODBCVER >= 0x0300 */ + + +#if (ODBCVER <= 0x0300) +#define SQL_UNICODE (-95) +#define SQL_UNICODE_VARCHAR (-96) +#define SQL_UNICODE_LONGVARCHAR (-97) +#define SQL_UNICODE_CHAR SQL_UNICODE +#else +/* The previous definitions for SQL_UNICODE_ are historical and obsolete */ + +#define SQL_UNICODE SQL_WCHAR +#define SQL_UNICODE_VARCHAR SQL_WVARCHAR +#define SQL_UNICODE_LONGVARCHAR SQL_WLONGVARCHAR +#define SQL_UNICODE_CHAR SQL_WCHAR +#endif + +#if (ODBCVER < 0x0300) +#define SQL_TYPE_DRIVER_START SQL_INTERVAL_YEAR +#define SQL_TYPE_DRIVER_END SQL_UNICODE_LONGVARCHAR +#endif /* ODBCVER < 0x0300 */ + +/* C datatype to SQL datatype mapping SQL types + ------------------- */ +#define SQL_C_CHAR SQL_CHAR /* CHAR, VARCHAR, DECIMAL, NUMERIC */ +#define SQL_C_LONG SQL_INTEGER /* INTEGER */ +#define SQL_C_SHORT SQL_SMALLINT /* SMALLINT */ +#define SQL_C_FLOAT SQL_REAL /* REAL */ +#define SQL_C_DOUBLE SQL_DOUBLE /* FLOAT, DOUBLE */ +#if (ODBCVER >= 0x0300) +#define SQL_C_NUMERIC SQL_NUMERIC +#endif /* ODBCVER >= 0x0300 */ +#define SQL_C_DEFAULT 99 + +#define SQL_SIGNED_OFFSET (-20) +#define SQL_UNSIGNED_OFFSET (-22) + +/* C datatype to SQL datatype mapping */ +#define SQL_C_DATE SQL_DATE +#define SQL_C_TIME SQL_TIME +#define SQL_C_TIMESTAMP SQL_TIMESTAMP +#if (ODBCVER >= 0x0300) +#define SQL_C_TYPE_DATE SQL_TYPE_DATE +#define SQL_C_TYPE_TIME SQL_TYPE_TIME +#define SQL_C_TYPE_TIMESTAMP SQL_TYPE_TIMESTAMP +#define SQL_C_INTERVAL_YEAR SQL_INTERVAL_YEAR +#define SQL_C_INTERVAL_MONTH SQL_INTERVAL_MONTH +#define SQL_C_INTERVAL_DAY SQL_INTERVAL_DAY +#define SQL_C_INTERVAL_HOUR SQL_INTERVAL_HOUR +#define SQL_C_INTERVAL_MINUTE SQL_INTERVAL_MINUTE +#define SQL_C_INTERVAL_SECOND SQL_INTERVAL_SECOND +#define SQL_C_INTERVAL_YEAR_TO_MONTH SQL_INTERVAL_YEAR_TO_MONTH +#define SQL_C_INTERVAL_DAY_TO_HOUR SQL_INTERVAL_DAY_TO_HOUR +#define SQL_C_INTERVAL_DAY_TO_MINUTE SQL_INTERVAL_DAY_TO_MINUTE +#define SQL_C_INTERVAL_DAY_TO_SECOND SQL_INTERVAL_DAY_TO_SECOND +#define SQL_C_INTERVAL_HOUR_TO_MINUTE SQL_INTERVAL_HOUR_TO_MINUTE +#define SQL_C_INTERVAL_HOUR_TO_SECOND SQL_INTERVAL_HOUR_TO_SECOND +#define SQL_C_INTERVAL_MINUTE_TO_SECOND SQL_INTERVAL_MINUTE_TO_SECOND +#endif /* ODBCVER >= 0x0300 */ +#define SQL_C_BINARY SQL_BINARY +#define SQL_C_BIT SQL_BIT +#if (ODBCVER >= 0x0300) +#define SQL_C_SBIGINT (SQL_BIGINT+SQL_SIGNED_OFFSET) /* SIGNED BIGINT */ +#define SQL_C_UBIGINT (SQL_BIGINT+SQL_UNSIGNED_OFFSET) /* UNSIGNED BIGINT */ +#endif /* ODBCVER >= 0x0300 */ +#define SQL_C_TINYINT SQL_TINYINT +#define SQL_C_SLONG (SQL_C_LONG+SQL_SIGNED_OFFSET) /* SIGNED INTEGER */ +#define SQL_C_SSHORT (SQL_C_SHORT+SQL_SIGNED_OFFSET) /* SIGNED SMALLINT */ +#define SQL_C_STINYINT (SQL_TINYINT+SQL_SIGNED_OFFSET) /* SIGNED TINYINT */ +#define SQL_C_ULONG (SQL_C_LONG+SQL_UNSIGNED_OFFSET) /* UNSIGNED INTEGER*/ +#define SQL_C_USHORT (SQL_C_SHORT+SQL_UNSIGNED_OFFSET) /* UNSIGNED SMALLINT*/ +#define SQL_C_UTINYINT (SQL_TINYINT+SQL_UNSIGNED_OFFSET) /* UNSIGNED TINYINT*/ + +#ifdef ODBC64 +#define SQL_C_BOOKMARK SQL_C_UBIGINT /* BOOKMARK */ +#else +#define SQL_C_BOOKMARK SQL_C_ULONG /* BOOKMARK */ +#endif + +#if (ODBCVER >= 0x0350) +#define SQL_C_GUID SQL_GUID +#endif /* ODBCVER >= 0x0350 */ + +#define SQL_TYPE_NULL 0 +#if (ODBCVER < 0x0300) +#define SQL_TYPE_MIN SQL_BIT +#define SQL_TYPE_MAX SQL_VARCHAR +#endif + +#if (ODBCVER >= 0x0300) +#define SQL_C_VARBOOKMARK SQL_C_BINARY +#endif /* ODBCVER >= 0x0300 */ + +/* define for SQL_DIAG_ROW_NUMBER and SQL_DIAG_COLUMN_NUMBER */ +#if (ODBCVER >= 0x0300) +#define SQL_NO_ROW_NUMBER (-1) +#define SQL_NO_COLUMN_NUMBER (-1) +#define SQL_ROW_NUMBER_UNKNOWN (-2) +#define SQL_COLUMN_NUMBER_UNKNOWN (-2) +#endif + +/* SQLBindParameter extensions */ +#define SQL_DEFAULT_PARAM (-5) +#define SQL_IGNORE (-6) +#if (ODBCVER >= 0x0300) +#define SQL_COLUMN_IGNORE SQL_IGNORE +#endif /* ODBCVER >= 0x0300 */ +#define SQL_LEN_DATA_AT_EXEC_OFFSET (-100) +#define SQL_LEN_DATA_AT_EXEC(length) (-(length)+SQL_LEN_DATA_AT_EXEC_OFFSET) + +/* binary length for driver specific attributes */ +#define SQL_LEN_BINARY_ATTR_OFFSET (-100) +#define SQL_LEN_BINARY_ATTR(length) (-(length)+SQL_LEN_BINARY_ATTR_OFFSET) + +/* Defines used by Driver Manager when mapping SQLSetParam to SQLBindParameter +*/ +#define SQL_PARAM_TYPE_DEFAULT SQL_PARAM_INPUT_OUTPUT +#define SQL_SETPARAM_VALUE_MAX (-1L) + +/* SQLColAttributes defines */ +#define SQL_COLUMN_COUNT 0 +#define SQL_COLUMN_NAME 1 +#define SQL_COLUMN_TYPE 2 +#define SQL_COLUMN_LENGTH 3 +#define SQL_COLUMN_PRECISION 4 +#define SQL_COLUMN_SCALE 5 +#define SQL_COLUMN_DISPLAY_SIZE 6 +#define SQL_COLUMN_NULLABLE 7 +#define SQL_COLUMN_UNSIGNED 8 +#define SQL_COLUMN_MONEY 9 +#define SQL_COLUMN_UPDATABLE 10 +#define SQL_COLUMN_AUTO_INCREMENT 11 +#define SQL_COLUMN_CASE_SENSITIVE 12 +#define SQL_COLUMN_SEARCHABLE 13 +#define SQL_COLUMN_TYPE_NAME 14 +#define SQL_COLUMN_TABLE_NAME 15 +#define SQL_COLUMN_OWNER_NAME 16 +#define SQL_COLUMN_QUALIFIER_NAME 17 +#define SQL_COLUMN_LABEL 18 +#define SQL_COLATT_OPT_MAX SQL_COLUMN_LABEL +#if (ODBCVER < 0x0300) +#define SQL_COLUMN_DRIVER_START 1000 +#endif /* ODBCVER < 0x0300 */ + +#define SQL_COLATT_OPT_MIN SQL_COLUMN_COUNT + +/* SQLColAttributes subdefines for SQL_COLUMN_UPDATABLE */ +#define SQL_ATTR_READONLY 0 +#define SQL_ATTR_WRITE 1 +#define SQL_ATTR_READWRITE_UNKNOWN 2 + +/* SQLColAttributes subdefines for SQL_COLUMN_SEARCHABLE */ +/* These are also used by SQLGetInfo */ +#define SQL_UNSEARCHABLE 0 +#define SQL_LIKE_ONLY 1 +#define SQL_ALL_EXCEPT_LIKE 2 +#define SQL_SEARCHABLE 3 +#define SQL_PRED_SEARCHABLE SQL_SEARCHABLE + + +/* Special return values for SQLGetData */ +#define SQL_NO_TOTAL (-4) + +/********************************************/ +/* SQLGetFunctions: additional values for */ +/* fFunction to represent functions that */ +/* are not in the X/Open spec. */ +/********************************************/ + +#if (ODBCVER >= 0x0300) +#define SQL_API_SQLALLOCHANDLESTD 73 +#define SQL_API_SQLBULKOPERATIONS 24 +#endif /* ODBCVER >= 0x0300 */ +#define SQL_API_SQLBINDPARAMETER 72 +#define SQL_API_SQLBROWSECONNECT 55 +#define SQL_API_SQLCOLATTRIBUTES 6 +#define SQL_API_SQLCOLUMNPRIVILEGES 56 +#define SQL_API_SQLDESCRIBEPARAM 58 +#define SQL_API_SQLDRIVERCONNECT 41 +#define SQL_API_SQLDRIVERS 71 +#define SQL_API_SQLEXTENDEDFETCH 59 +#define SQL_API_SQLFOREIGNKEYS 60 +#define SQL_API_SQLMORERESULTS 61 +#define SQL_API_SQLNATIVESQL 62 +#define SQL_API_SQLNUMPARAMS 63 +#define SQL_API_SQLPARAMOPTIONS 64 +#define SQL_API_SQLPRIMARYKEYS 65 +#define SQL_API_SQLPROCEDURECOLUMNS 66 +#define SQL_API_SQLPROCEDURES 67 +#define SQL_API_SQLSETPOS 68 +#define SQL_API_SQLSETSCROLLOPTIONS 69 +#define SQL_API_SQLTABLEPRIVILEGES 70 + +/*-------------------------------------------*/ +/* SQL_EXT_API_LAST is not useful with ODBC */ +/* version 3.0 because some of the values */ +/* from X/Open are in the 10000 range. */ +/*-------------------------------------------*/ + +#if (ODBCVER < 0x0300) +#define SQL_EXT_API_LAST SQL_API_SQLBINDPARAMETER +#define SQL_NUM_FUNCTIONS 23 +#define SQL_EXT_API_START 40 +#define SQL_NUM_EXTENSIONS (SQL_EXT_API_LAST-SQL_EXT_API_START+1) +#endif + +/*--------------------------------------------*/ +/* SQL_API_ALL_FUNCTIONS returns an array */ +/* of 'booleans' representing whether a */ +/* function is implemented by the driver. */ +/* */ +/* CAUTION: Only functions defined in ODBC */ +/* version 2.0 and earlier are returned, the */ +/* new high-range function numbers defined by */ +/* X/Open break this scheme. See the new */ +/* method -- SQL_API_ODBC3_ALL_FUNCTIONS */ +/*--------------------------------------------*/ + +#define SQL_API_ALL_FUNCTIONS 0 /* See CAUTION above */ + +/*----------------------------------------------*/ +/* 2.X drivers export a dummy function with */ +/* ordinal number SQL_API_LOADBYORDINAL to speed*/ +/* loading under the windows operating system. */ +/* */ +/* CAUTION: Loading by ordinal is not supported */ +/* for 3.0 and above drivers. */ +/*----------------------------------------------*/ + +#define SQL_API_LOADBYORDINAL 199 /* See CAUTION above */ + +/*----------------------------------------------*/ +/* SQL_API_ODBC3_ALL_FUNCTIONS */ +/* This returns a bitmap, which allows us to */ +/* handle the higher-valued function numbers. */ +/* Use SQL_FUNC_EXISTS(bitmap,function_number) */ +/* to determine if the function exists. */ +/*----------------------------------------------*/ + + +#if (ODBCVER >= 0x0300) +#define SQL_API_ODBC3_ALL_FUNCTIONS 999 +#define SQL_API_ODBC3_ALL_FUNCTIONS_SIZE 250 /* array of 250 words */ + +#define SQL_FUNC_EXISTS(pfExists, uwAPI) \ + ((*(((UWORD*) (pfExists)) + ((uwAPI) >> 4)) \ + & (1 << ((uwAPI) & 0x000F)) \ + ) ? SQL_TRUE : SQL_FALSE \ + ) +#endif /* ODBCVER >= 0x0300 */ + + +/************************************************/ +/* Extended definitions for SQLGetInfo */ +/************************************************/ + +/*---------------------------------*/ +/* Values in ODBC 2.0 that are not */ +/* in the X/Open spec */ +/*---------------------------------*/ + +#define SQL_INFO_FIRST 0 +#define SQL_ACTIVE_CONNECTIONS 0 /* MAX_DRIVER_CONNECTIONS */ +#define SQL_ACTIVE_STATEMENTS 1 /* MAX_CONCURRENT_ACTIVITIES */ +#define SQL_DRIVER_HDBC 3 +#define SQL_DRIVER_HENV 4 +#define SQL_DRIVER_HSTMT 5 +#define SQL_DRIVER_NAME 6 +#define SQL_DRIVER_VER 7 +#define SQL_ODBC_API_CONFORMANCE 9 +#define SQL_ODBC_VER 10 +#define SQL_ROW_UPDATES 11 +#define SQL_ODBC_SAG_CLI_CONFORMANCE 12 +#define SQL_ODBC_SQL_CONFORMANCE 15 +#define SQL_PROCEDURES 21 +#define SQL_CONCAT_NULL_BEHAVIOR 22 +#define SQL_CURSOR_ROLLBACK_BEHAVIOR 24 +#define SQL_EXPRESSIONS_IN_ORDERBY 27 +#define SQL_MAX_OWNER_NAME_LEN 32 /* MAX_SCHEMA_NAME_LEN */ +#define SQL_MAX_PROCEDURE_NAME_LEN 33 +#define SQL_MAX_QUALIFIER_NAME_LEN 34 /* MAX_CATALOG_NAME_LEN */ +#define SQL_MULT_RESULT_SETS 36 +#define SQL_MULTIPLE_ACTIVE_TXN 37 +#define SQL_OUTER_JOINS 38 +#define SQL_OWNER_TERM 39 +#define SQL_PROCEDURE_TERM 40 +#define SQL_QUALIFIER_NAME_SEPARATOR 41 +#define SQL_QUALIFIER_TERM 42 +#define SQL_SCROLL_OPTIONS 44 +#define SQL_TABLE_TERM 45 +#define SQL_CONVERT_FUNCTIONS 48 +#define SQL_NUMERIC_FUNCTIONS 49 +#define SQL_STRING_FUNCTIONS 50 +#define SQL_SYSTEM_FUNCTIONS 51 +#define SQL_TIMEDATE_FUNCTIONS 52 +#define SQL_CONVERT_BIGINT 53 +#define SQL_CONVERT_BINARY 54 +#define SQL_CONVERT_BIT 55 +#define SQL_CONVERT_CHAR 56 +#define SQL_CONVERT_DATE 57 +#define SQL_CONVERT_DECIMAL 58 +#define SQL_CONVERT_DOUBLE 59 +#define SQL_CONVERT_FLOAT 60 +#define SQL_CONVERT_INTEGER 61 +#define SQL_CONVERT_LONGVARCHAR 62 +#define SQL_CONVERT_NUMERIC 63 +#define SQL_CONVERT_REAL 64 +#define SQL_CONVERT_SMALLINT 65 +#define SQL_CONVERT_TIME 66 +#define SQL_CONVERT_TIMESTAMP 67 +#define SQL_CONVERT_TINYINT 68 +#define SQL_CONVERT_VARBINARY 69 +#define SQL_CONVERT_VARCHAR 70 +#define SQL_CONVERT_LONGVARBINARY 71 +#define SQL_ODBC_SQL_OPT_IEF 73 /* SQL_INTEGRITY */ +#define SQL_CORRELATION_NAME 74 +#define SQL_NON_NULLABLE_COLUMNS 75 +#define SQL_DRIVER_HLIB 76 +#define SQL_DRIVER_ODBC_VER 77 +#define SQL_LOCK_TYPES 78 +#define SQL_POS_OPERATIONS 79 +#define SQL_POSITIONED_STATEMENTS 80 +#define SQL_BOOKMARK_PERSISTENCE 82 +#define SQL_STATIC_SENSITIVITY 83 +#define SQL_FILE_USAGE 84 +#define SQL_COLUMN_ALIAS 87 +#define SQL_GROUP_BY 88 +#define SQL_KEYWORDS 89 +#define SQL_OWNER_USAGE 91 +#define SQL_QUALIFIER_USAGE 92 +#define SQL_QUOTED_IDENTIFIER_CASE 93 +#define SQL_SUBQUERIES 95 +#define SQL_UNION 96 +#define SQL_MAX_ROW_SIZE_INCLUDES_LONG 103 +#define SQL_MAX_CHAR_LITERAL_LEN 108 +#define SQL_TIMEDATE_ADD_INTERVALS 109 +#define SQL_TIMEDATE_DIFF_INTERVALS 110 +#define SQL_NEED_LONG_DATA_LEN 111 +#define SQL_MAX_BINARY_LITERAL_LEN 112 +#define SQL_LIKE_ESCAPE_CLAUSE 113 +#define SQL_QUALIFIER_LOCATION 114 + +#if (ODBCVER >= 0x0201 && ODBCVER < 0x0300) +#define SQL_OJ_CAPABILITIES 65003 /* Temp value until ODBC 3.0 */ +#endif /* ODBCVER >= 0x0201 && ODBCVER < 0x0300 */ + +/*----------------------------------------------*/ +/* SQL_INFO_LAST and SQL_INFO_DRIVER_START are */ +/* not useful anymore, because X/Open has */ +/* values in the 10000 range. You */ +/* must contact X/Open directly to get a range */ +/* of numbers for driver-specific values. */ +/*----------------------------------------------*/ + +#if (ODBCVER < 0x0300) +#define SQL_INFO_LAST SQL_QUALIFIER_LOCATION +#define SQL_INFO_DRIVER_START 1000 +#endif /* ODBCVER < 0x0300 */ + +/*-----------------------------------------------*/ +/* ODBC 3.0 SQLGetInfo values that are not part */ +/* of the X/Open standard at this time. X/Open */ +/* standard values are in sql.h. */ +/*-----------------------------------------------*/ + +#if (ODBCVER >= 0x0300) +#define SQL_ACTIVE_ENVIRONMENTS 116 +#define SQL_ALTER_DOMAIN 117 + +#define SQL_SQL_CONFORMANCE 118 +#define SQL_DATETIME_LITERALS 119 + +#define SQL_ASYNC_MODE 10021 /* new X/Open spec */ +#define SQL_BATCH_ROW_COUNT 120 +#define SQL_BATCH_SUPPORT 121 +#define SQL_CATALOG_LOCATION SQL_QUALIFIER_LOCATION +#define SQL_CATALOG_NAME_SEPARATOR SQL_QUALIFIER_NAME_SEPARATOR +#define SQL_CATALOG_TERM SQL_QUALIFIER_TERM +#define SQL_CATALOG_USAGE SQL_QUALIFIER_USAGE +#define SQL_CONVERT_WCHAR 122 +#define SQL_CONVERT_INTERVAL_DAY_TIME 123 +#define SQL_CONVERT_INTERVAL_YEAR_MONTH 124 +#define SQL_CONVERT_WLONGVARCHAR 125 +#define SQL_CONVERT_WVARCHAR 126 +#define SQL_CREATE_ASSERTION 127 +#define SQL_CREATE_CHARACTER_SET 128 +#define SQL_CREATE_COLLATION 129 +#define SQL_CREATE_DOMAIN 130 +#define SQL_CREATE_SCHEMA 131 +#define SQL_CREATE_TABLE 132 +#define SQL_CREATE_TRANSLATION 133 +#define SQL_CREATE_VIEW 134 +#define SQL_DRIVER_HDESC 135 +#define SQL_DROP_ASSERTION 136 +#define SQL_DROP_CHARACTER_SET 137 +#define SQL_DROP_COLLATION 138 +#define SQL_DROP_DOMAIN 139 +#define SQL_DROP_SCHEMA 140 +#define SQL_DROP_TABLE 141 +#define SQL_DROP_TRANSLATION 142 +#define SQL_DROP_VIEW 143 +#define SQL_DYNAMIC_CURSOR_ATTRIBUTES1 144 +#define SQL_DYNAMIC_CURSOR_ATTRIBUTES2 145 +#define SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1 146 +#define SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2 147 +#define SQL_INDEX_KEYWORDS 148 +#define SQL_INFO_SCHEMA_VIEWS 149 +#define SQL_KEYSET_CURSOR_ATTRIBUTES1 150 +#define SQL_KEYSET_CURSOR_ATTRIBUTES2 151 +#define SQL_MAX_ASYNC_CONCURRENT_STATEMENTS 10022 /* new X/Open spec */ +#define SQL_ODBC_INTERFACE_CONFORMANCE 152 +#define SQL_PARAM_ARRAY_ROW_COUNTS 153 +#define SQL_PARAM_ARRAY_SELECTS 154 +#define SQL_SCHEMA_TERM SQL_OWNER_TERM +#define SQL_SCHEMA_USAGE SQL_OWNER_USAGE +#define SQL_SQL92_DATETIME_FUNCTIONS 155 +#define SQL_SQL92_FOREIGN_KEY_DELETE_RULE 156 +#define SQL_SQL92_FOREIGN_KEY_UPDATE_RULE 157 +#define SQL_SQL92_GRANT 158 +#define SQL_SQL92_NUMERIC_VALUE_FUNCTIONS 159 +#define SQL_SQL92_PREDICATES 160 +#define SQL_SQL92_RELATIONAL_JOIN_OPERATORS 161 +#define SQL_SQL92_REVOKE 162 +#define SQL_SQL92_ROW_VALUE_CONSTRUCTOR 163 +#define SQL_SQL92_STRING_FUNCTIONS 164 +#define SQL_SQL92_VALUE_EXPRESSIONS 165 +#define SQL_STANDARD_CLI_CONFORMANCE 166 +#define SQL_STATIC_CURSOR_ATTRIBUTES1 167 +#define SQL_STATIC_CURSOR_ATTRIBUTES2 168 + +#define SQL_AGGREGATE_FUNCTIONS 169 +#define SQL_DDL_INDEX 170 +#define SQL_DM_VER 171 +#define SQL_INSERT_STATEMENT 172 +#define SQL_UNION_STATEMENT SQL_UNION +#endif /* ODBCVER >= 0x0300 */ + +#define SQL_DTC_TRANSITION_COST 1750 + +/* SQL_ALTER_TABLE bitmasks */ +#if (ODBCVER >= 0x0300) +/* the following 5 bitmasks are defined in sql.h +*#define SQL_AT_ADD_COLUMN 0x00000001L +*#define SQL_AT_DROP_COLUMN 0x00000002L +*#define SQL_AT_ADD_CONSTRAINT 0x00000008L +*/ +#define SQL_AT_ADD_COLUMN_SINGLE 0x00000020L +#define SQL_AT_ADD_COLUMN_DEFAULT 0x00000040L +#define SQL_AT_ADD_COLUMN_COLLATION 0x00000080L +#define SQL_AT_SET_COLUMN_DEFAULT 0x00000100L +#define SQL_AT_DROP_COLUMN_DEFAULT 0x00000200L +#define SQL_AT_DROP_COLUMN_CASCADE 0x00000400L +#define SQL_AT_DROP_COLUMN_RESTRICT 0x00000800L +#define SQL_AT_ADD_TABLE_CONSTRAINT 0x00001000L +#define SQL_AT_DROP_TABLE_CONSTRAINT_CASCADE 0x00002000L +#define SQL_AT_DROP_TABLE_CONSTRAINT_RESTRICT 0x00004000L +#define SQL_AT_CONSTRAINT_NAME_DEFINITION 0x00008000L +#define SQL_AT_CONSTRAINT_INITIALLY_DEFERRED 0x00010000L +#define SQL_AT_CONSTRAINT_INITIALLY_IMMEDIATE 0x00020000L +#define SQL_AT_CONSTRAINT_DEFERRABLE 0x00040000L +#define SQL_AT_CONSTRAINT_NON_DEFERRABLE 0x00080000L +#endif /* ODBCVER >= 0x0300 */ + +/* SQL_CONVERT_* return value bitmasks */ + +#define SQL_CVT_CHAR 0x00000001L +#define SQL_CVT_NUMERIC 0x00000002L +#define SQL_CVT_DECIMAL 0x00000004L +#define SQL_CVT_INTEGER 0x00000008L +#define SQL_CVT_SMALLINT 0x00000010L +#define SQL_CVT_FLOAT 0x00000020L +#define SQL_CVT_REAL 0x00000040L +#define SQL_CVT_DOUBLE 0x00000080L +#define SQL_CVT_VARCHAR 0x00000100L +#define SQL_CVT_LONGVARCHAR 0x00000200L +#define SQL_CVT_BINARY 0x00000400L +#define SQL_CVT_VARBINARY 0x00000800L +#define SQL_CVT_BIT 0x00001000L +#define SQL_CVT_TINYINT 0x00002000L +#define SQL_CVT_BIGINT 0x00004000L +#define SQL_CVT_DATE 0x00008000L +#define SQL_CVT_TIME 0x00010000L +#define SQL_CVT_TIMESTAMP 0x00020000L +#define SQL_CVT_LONGVARBINARY 0x00040000L +#if (ODBCVER >= 0x0300) +#define SQL_CVT_INTERVAL_YEAR_MONTH 0x00080000L +#define SQL_CVT_INTERVAL_DAY_TIME 0x00100000L +#define SQL_CVT_WCHAR 0x00200000L +#define SQL_CVT_WLONGVARCHAR 0x00400000L +#define SQL_CVT_WVARCHAR 0x00800000L + +#endif /* ODBCVER >= 0x0300 */ + + +/* SQL_CONVERT_FUNCTIONS functions */ +#define SQL_FN_CVT_CONVERT 0x00000001L +#if (ODBCVER >= 0x0300) +#define SQL_FN_CVT_CAST 0x00000002L +#endif /* ODBCVER >= 0x0300 */ + + +/* SQL_STRING_FUNCTIONS functions */ + +#define SQL_FN_STR_CONCAT 0x00000001L +#define SQL_FN_STR_INSERT 0x00000002L +#define SQL_FN_STR_LEFT 0x00000004L +#define SQL_FN_STR_LTRIM 0x00000008L +#define SQL_FN_STR_LENGTH 0x00000010L +#define SQL_FN_STR_LOCATE 0x00000020L +#define SQL_FN_STR_LCASE 0x00000040L +#define SQL_FN_STR_REPEAT 0x00000080L +#define SQL_FN_STR_REPLACE 0x00000100L +#define SQL_FN_STR_RIGHT 0x00000200L +#define SQL_FN_STR_RTRIM 0x00000400L +#define SQL_FN_STR_SUBSTRING 0x00000800L +#define SQL_FN_STR_UCASE 0x00001000L +#define SQL_FN_STR_ASCII 0x00002000L +#define SQL_FN_STR_CHAR 0x00004000L +#define SQL_FN_STR_DIFFERENCE 0x00008000L +#define SQL_FN_STR_LOCATE_2 0x00010000L +#define SQL_FN_STR_SOUNDEX 0x00020000L +#define SQL_FN_STR_SPACE 0x00040000L +#if (ODBCVER >= 0x0300) +#define SQL_FN_STR_BIT_LENGTH 0x00080000L +#define SQL_FN_STR_CHAR_LENGTH 0x00100000L +#define SQL_FN_STR_CHARACTER_LENGTH 0x00200000L +#define SQL_FN_STR_OCTET_LENGTH 0x00400000L +#define SQL_FN_STR_POSITION 0x00800000L +#endif /* ODBCVER >= 0x0300 */ + +/* SQL_SQL92_STRING_FUNCTIONS */ +#if (ODBCVER >= 0x0300) +#define SQL_SSF_CONVERT 0x00000001L +#define SQL_SSF_LOWER 0x00000002L +#define SQL_SSF_UPPER 0x00000004L +#define SQL_SSF_SUBSTRING 0x00000008L +#define SQL_SSF_TRANSLATE 0x00000010L +#define SQL_SSF_TRIM_BOTH 0x00000020L +#define SQL_SSF_TRIM_LEADING 0x00000040L +#define SQL_SSF_TRIM_TRAILING 0x00000080L +#endif /* ODBCVER >= 0x0300 */ + +/* SQL_NUMERIC_FUNCTIONS functions */ + +#define SQL_FN_NUM_ABS 0x00000001L +#define SQL_FN_NUM_ACOS 0x00000002L +#define SQL_FN_NUM_ASIN 0x00000004L +#define SQL_FN_NUM_ATAN 0x00000008L +#define SQL_FN_NUM_ATAN2 0x00000010L +#define SQL_FN_NUM_CEILING 0x00000020L +#define SQL_FN_NUM_COS 0x00000040L +#define SQL_FN_NUM_COT 0x00000080L +#define SQL_FN_NUM_EXP 0x00000100L +#define SQL_FN_NUM_FLOOR 0x00000200L +#define SQL_FN_NUM_LOG 0x00000400L +#define SQL_FN_NUM_MOD 0x00000800L +#define SQL_FN_NUM_SIGN 0x00001000L +#define SQL_FN_NUM_SIN 0x00002000L +#define SQL_FN_NUM_SQRT 0x00004000L +#define SQL_FN_NUM_TAN 0x00008000L +#define SQL_FN_NUM_PI 0x00010000L +#define SQL_FN_NUM_RAND 0x00020000L +#define SQL_FN_NUM_DEGREES 0x00040000L +#define SQL_FN_NUM_LOG10 0x00080000L +#define SQL_FN_NUM_POWER 0x00100000L +#define SQL_FN_NUM_RADIANS 0x00200000L +#define SQL_FN_NUM_ROUND 0x00400000L +#define SQL_FN_NUM_TRUNCATE 0x00800000L + +/* SQL_SQL92_NUMERIC_VALUE_FUNCTIONS */ +#if (ODBCVER >= 0x0300) +#define SQL_SNVF_BIT_LENGTH 0x00000001L +#define SQL_SNVF_CHAR_LENGTH 0x00000002L +#define SQL_SNVF_CHARACTER_LENGTH 0x00000004L +#define SQL_SNVF_EXTRACT 0x00000008L +#define SQL_SNVF_OCTET_LENGTH 0x00000010L +#define SQL_SNVF_POSITION 0x00000020L +#endif /* ODBCVER >= 0x0300 */ + +/* SQL_TIMEDATE_FUNCTIONS functions */ + +#define SQL_FN_TD_NOW 0x00000001L +#define SQL_FN_TD_CURDATE 0x00000002L +#define SQL_FN_TD_DAYOFMONTH 0x00000004L +#define SQL_FN_TD_DAYOFWEEK 0x00000008L +#define SQL_FN_TD_DAYOFYEAR 0x00000010L +#define SQL_FN_TD_MONTH 0x00000020L +#define SQL_FN_TD_QUARTER 0x00000040L +#define SQL_FN_TD_WEEK 0x00000080L +#define SQL_FN_TD_YEAR 0x00000100L +#define SQL_FN_TD_CURTIME 0x00000200L +#define SQL_FN_TD_HOUR 0x00000400L +#define SQL_FN_TD_MINUTE 0x00000800L +#define SQL_FN_TD_SECOND 0x00001000L +#define SQL_FN_TD_TIMESTAMPADD 0x00002000L +#define SQL_FN_TD_TIMESTAMPDIFF 0x00004000L +#define SQL_FN_TD_DAYNAME 0x00008000L +#define SQL_FN_TD_MONTHNAME 0x00010000L +#if (ODBCVER >= 0x0300) +#define SQL_FN_TD_CURRENT_DATE 0x00020000L +#define SQL_FN_TD_CURRENT_TIME 0x00040000L +#define SQL_FN_TD_CURRENT_TIMESTAMP 0x00080000L +#define SQL_FN_TD_EXTRACT 0x00100000L +#endif /* ODBCVER >= 0x0300 */ + +/* SQL_SQL92_DATETIME_FUNCTIONS */ +#if (ODBCVER >= 0x0300) +#define SQL_SDF_CURRENT_DATE 0x00000001L +#define SQL_SDF_CURRENT_TIME 0x00000002L +#define SQL_SDF_CURRENT_TIMESTAMP 0x00000004L +#endif /* ODBCVER >= 0x0300 */ + +/* SQL_SYSTEM_FUNCTIONS functions */ + +#define SQL_FN_SYS_USERNAME 0x00000001L +#define SQL_FN_SYS_DBNAME 0x00000002L +#define SQL_FN_SYS_IFNULL 0x00000004L + +/* SQL_TIMEDATE_ADD_INTERVALS and SQL_TIMEDATE_DIFF_INTERVALS functions */ + +#define SQL_FN_TSI_FRAC_SECOND 0x00000001L +#define SQL_FN_TSI_SECOND 0x00000002L +#define SQL_FN_TSI_MINUTE 0x00000004L +#define SQL_FN_TSI_HOUR 0x00000008L +#define SQL_FN_TSI_DAY 0x00000010L +#define SQL_FN_TSI_WEEK 0x00000020L +#define SQL_FN_TSI_MONTH 0x00000040L +#define SQL_FN_TSI_QUARTER 0x00000080L +#define SQL_FN_TSI_YEAR 0x00000100L + +/* bitmasks for SQL_DYNAMIC_CURSOR_ATTRIBUTES1, + * SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1, + * SQL_KEYSET_CURSOR_ATTRIBUTES1, and SQL_STATIC_CURSOR_ATTRIBUTES1 + */ +#if (ODBCVER >= 0x0300) +/* supported SQLFetchScroll FetchOrientation's */ +#define SQL_CA1_NEXT 0x00000001L +#define SQL_CA1_ABSOLUTE 0x00000002L +#define SQL_CA1_RELATIVE 0x00000004L +#define SQL_CA1_BOOKMARK 0x00000008L + +/* supported SQLSetPos LockType's */ +#define SQL_CA1_LOCK_NO_CHANGE 0x00000040L +#define SQL_CA1_LOCK_EXCLUSIVE 0x00000080L +#define SQL_CA1_LOCK_UNLOCK 0x00000100L + +/* supported SQLSetPos Operations */ +#define SQL_CA1_POS_POSITION 0x00000200L +#define SQL_CA1_POS_UPDATE 0x00000400L +#define SQL_CA1_POS_DELETE 0x00000800L +#define SQL_CA1_POS_REFRESH 0x00001000L + +/* positioned updates and deletes */ +#define SQL_CA1_POSITIONED_UPDATE 0x00002000L +#define SQL_CA1_POSITIONED_DELETE 0x00004000L +#define SQL_CA1_SELECT_FOR_UPDATE 0x00008000L + +/* supported SQLBulkOperations operations */ +#define SQL_CA1_BULK_ADD 0x00010000L +#define SQL_CA1_BULK_UPDATE_BY_BOOKMARK 0x00020000L +#define SQL_CA1_BULK_DELETE_BY_BOOKMARK 0x00040000L +#define SQL_CA1_BULK_FETCH_BY_BOOKMARK 0x00080000L +#endif /* ODBCVER >= 0x0300 */ + +/* bitmasks for SQL_DYNAMIC_CURSOR_ATTRIBUTES2, + * SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2, + * SQL_KEYSET_CURSOR_ATTRIBUTES2, and SQL_STATIC_CURSOR_ATTRIBUTES2 + */ +#if (ODBCVER >= 0x0300) +/* supported values for SQL_ATTR_SCROLL_CONCURRENCY */ +#define SQL_CA2_READ_ONLY_CONCURRENCY 0x00000001L +#define SQL_CA2_LOCK_CONCURRENCY 0x00000002L +#define SQL_CA2_OPT_ROWVER_CONCURRENCY 0x00000004L +#define SQL_CA2_OPT_VALUES_CONCURRENCY 0x00000008L + +/* sensitivity of the cursor to its own inserts, deletes, and updates */ +#define SQL_CA2_SENSITIVITY_ADDITIONS 0x00000010L +#define SQL_CA2_SENSITIVITY_DELETIONS 0x00000020L +#define SQL_CA2_SENSITIVITY_UPDATES 0x00000040L + +/* semantics of SQL_ATTR_MAX_ROWS */ +#define SQL_CA2_MAX_ROWS_SELECT 0x00000080L +#define SQL_CA2_MAX_ROWS_INSERT 0x00000100L +#define SQL_CA2_MAX_ROWS_DELETE 0x00000200L +#define SQL_CA2_MAX_ROWS_UPDATE 0x00000400L +#define SQL_CA2_MAX_ROWS_CATALOG 0x00000800L +#define SQL_CA2_MAX_ROWS_AFFECTS_ALL (SQL_CA2_MAX_ROWS_SELECT | \ + SQL_CA2_MAX_ROWS_INSERT | SQL_CA2_MAX_ROWS_DELETE | \ + SQL_CA2_MAX_ROWS_UPDATE | SQL_CA2_MAX_ROWS_CATALOG) + +/* semantics of SQL_DIAG_CURSOR_ROW_COUNT */ +#define SQL_CA2_CRC_EXACT 0x00001000L +#define SQL_CA2_CRC_APPROXIMATE 0x00002000L + +/* the kinds of positioned statements that can be simulated */ +#define SQL_CA2_SIMULATE_NON_UNIQUE 0x00004000L +#define SQL_CA2_SIMULATE_TRY_UNIQUE 0x00008000L +#define SQL_CA2_SIMULATE_UNIQUE 0x00010000L +#endif /* ODBCVER >= 0x0300 */ + +/* SQL_ODBC_API_CONFORMANCE values */ + +#define SQL_OAC_NONE 0x0000 +#define SQL_OAC_LEVEL1 0x0001 +#define SQL_OAC_LEVEL2 0x0002 + +/* SQL_ODBC_SAG_CLI_CONFORMANCE values */ + +#define SQL_OSCC_NOT_COMPLIANT 0x0000 +#define SQL_OSCC_COMPLIANT 0x0001 + +/* SQL_ODBC_SQL_CONFORMANCE values */ + +#define SQL_OSC_MINIMUM 0x0000 +#define SQL_OSC_CORE 0x0001 +#define SQL_OSC_EXTENDED 0x0002 + + +/* SQL_CONCAT_NULL_BEHAVIOR values */ + +#define SQL_CB_NULL 0x0000 +#define SQL_CB_NON_NULL 0x0001 + +/* SQL_SCROLL_OPTIONS masks */ + +#define SQL_SO_FORWARD_ONLY 0x00000001L +#define SQL_SO_KEYSET_DRIVEN 0x00000002L +#define SQL_SO_DYNAMIC 0x00000004L +#define SQL_SO_MIXED 0x00000008L +#define SQL_SO_STATIC 0x00000010L + +/* SQL_FETCH_DIRECTION masks */ + +/* SQL_FETCH_RESUME is no longer supported +#define SQL_FD_FETCH_RESUME 0x00000040L +*/ +#define SQL_FD_FETCH_BOOKMARK 0x00000080L + +/* SQL_TXN_ISOLATION_OPTION masks */ +/* SQL_TXN_VERSIONING is no longer supported +#define SQL_TXN_VERSIONING 0x00000010L +*/ + +/* SQL_CORRELATION_NAME values */ + +#define SQL_CN_NONE 0x0000 +#define SQL_CN_DIFFERENT 0x0001 +#define SQL_CN_ANY 0x0002 + +/* SQL_NON_NULLABLE_COLUMNS values */ + +#define SQL_NNC_NULL 0x0000 +#define SQL_NNC_NON_NULL 0x0001 + +/* SQL_NULL_COLLATION values */ + +#define SQL_NC_START 0x0002 +#define SQL_NC_END 0x0004 + +/* SQL_FILE_USAGE values */ + +#define SQL_FILE_NOT_SUPPORTED 0x0000 +#define SQL_FILE_TABLE 0x0001 +#define SQL_FILE_QUALIFIER 0x0002 +#define SQL_FILE_CATALOG SQL_FILE_QUALIFIER // ODBC 3.0 + + +/* SQL_GETDATA_EXTENSIONS values */ + +#define SQL_GD_BLOCK 0x00000004L +#define SQL_GD_BOUND 0x00000008L + +/* SQL_POSITIONED_STATEMENTS masks */ + +#define SQL_PS_POSITIONED_DELETE 0x00000001L +#define SQL_PS_POSITIONED_UPDATE 0x00000002L +#define SQL_PS_SELECT_FOR_UPDATE 0x00000004L + +/* SQL_GROUP_BY values */ + +#define SQL_GB_NOT_SUPPORTED 0x0000 +#define SQL_GB_GROUP_BY_EQUALS_SELECT 0x0001 +#define SQL_GB_GROUP_BY_CONTAINS_SELECT 0x0002 +#define SQL_GB_NO_RELATION 0x0003 +#if (ODBCVER >= 0x0300) +#define SQL_GB_COLLATE 0x0004 + +#endif /* ODBCVER >= 0x0300 */ + +/* SQL_OWNER_USAGE masks */ + +#define SQL_OU_DML_STATEMENTS 0x00000001L +#define SQL_OU_PROCEDURE_INVOCATION 0x00000002L +#define SQL_OU_TABLE_DEFINITION 0x00000004L +#define SQL_OU_INDEX_DEFINITION 0x00000008L +#define SQL_OU_PRIVILEGE_DEFINITION 0x00000010L + +/* SQL_SCHEMA_USAGE masks */ +#if (ODBCVER >= 0x0300) +#define SQL_SU_DML_STATEMENTS SQL_OU_DML_STATEMENTS +#define SQL_SU_PROCEDURE_INVOCATION SQL_OU_PROCEDURE_INVOCATION +#define SQL_SU_TABLE_DEFINITION SQL_OU_TABLE_DEFINITION +#define SQL_SU_INDEX_DEFINITION SQL_OU_INDEX_DEFINITION +#define SQL_SU_PRIVILEGE_DEFINITION SQL_OU_PRIVILEGE_DEFINITION +#endif /* ODBCVER >= 0x0300 */ + +/* SQL_QUALIFIER_USAGE masks */ + +#define SQL_QU_DML_STATEMENTS 0x00000001L +#define SQL_QU_PROCEDURE_INVOCATION 0x00000002L +#define SQL_QU_TABLE_DEFINITION 0x00000004L +#define SQL_QU_INDEX_DEFINITION 0x00000008L +#define SQL_QU_PRIVILEGE_DEFINITION 0x00000010L + +#if (ODBCVER >= 0x0300) +/* SQL_CATALOG_USAGE masks */ +#define SQL_CU_DML_STATEMENTS SQL_QU_DML_STATEMENTS +#define SQL_CU_PROCEDURE_INVOCATION SQL_QU_PROCEDURE_INVOCATION +#define SQL_CU_TABLE_DEFINITION SQL_QU_TABLE_DEFINITION +#define SQL_CU_INDEX_DEFINITION SQL_QU_INDEX_DEFINITION +#define SQL_CU_PRIVILEGE_DEFINITION SQL_QU_PRIVILEGE_DEFINITION +#endif /* ODBCVER >= 0x0300 */ + +/* SQL_SUBQUERIES masks */ + +#define SQL_SQ_COMPARISON 0x00000001L +#define SQL_SQ_EXISTS 0x00000002L +#define SQL_SQ_IN 0x00000004L +#define SQL_SQ_QUANTIFIED 0x00000008L +#define SQL_SQ_CORRELATED_SUBQUERIES 0x00000010L + +/* SQL_UNION masks */ + +#define SQL_U_UNION 0x00000001L +#define SQL_U_UNION_ALL 0x00000002L + +/* SQL_BOOKMARK_PERSISTENCE values */ + +#define SQL_BP_CLOSE 0x00000001L +#define SQL_BP_DELETE 0x00000002L +#define SQL_BP_DROP 0x00000004L +#define SQL_BP_TRANSACTION 0x00000008L +#define SQL_BP_UPDATE 0x00000010L +#define SQL_BP_OTHER_HSTMT 0x00000020L +#define SQL_BP_SCROLL 0x00000040L + +/* SQL_STATIC_SENSITIVITY values */ + +#define SQL_SS_ADDITIONS 0x00000001L +#define SQL_SS_DELETIONS 0x00000002L +#define SQL_SS_UPDATES 0x00000004L + +/* SQL_VIEW values */ +#define SQL_CV_CREATE_VIEW 0x00000001L +#define SQL_CV_CHECK_OPTION 0x00000002L +#define SQL_CV_CASCADED 0x00000004L +#define SQL_CV_LOCAL 0x00000008L + +/* SQL_LOCK_TYPES masks */ + +#define SQL_LCK_NO_CHANGE 0x00000001L +#define SQL_LCK_EXCLUSIVE 0x00000002L +#define SQL_LCK_UNLOCK 0x00000004L + +/* SQL_POS_OPERATIONS masks */ + +#define SQL_POS_POSITION 0x00000001L +#define SQL_POS_REFRESH 0x00000002L +#define SQL_POS_UPDATE 0x00000004L +#define SQL_POS_DELETE 0x00000008L +#define SQL_POS_ADD 0x00000010L + +/* SQL_QUALIFIER_LOCATION values */ + +#define SQL_QL_START 0x0001 +#define SQL_QL_END 0x0002 + +/* Here start return values for ODBC 3.0 SQLGetInfo */ + +#if (ODBCVER >= 0x0300) +/* SQL_AGGREGATE_FUNCTIONS bitmasks */ +#define SQL_AF_AVG 0x00000001L +#define SQL_AF_COUNT 0x00000002L +#define SQL_AF_MAX 0x00000004L +#define SQL_AF_MIN 0x00000008L +#define SQL_AF_SUM 0x00000010L +#define SQL_AF_DISTINCT 0x00000020L +#define SQL_AF_ALL 0x00000040L + +/* SQL_SQL_CONFORMANCE bit masks */ +#define SQL_SC_SQL92_ENTRY 0x00000001L +#define SQL_SC_FIPS127_2_TRANSITIONAL 0x00000002L +#define SQL_SC_SQL92_INTERMEDIATE 0x00000004L +#define SQL_SC_SQL92_FULL 0x00000008L + +/* SQL_DATETIME_LITERALS masks */ +#define SQL_DL_SQL92_DATE 0x00000001L +#define SQL_DL_SQL92_TIME 0x00000002L +#define SQL_DL_SQL92_TIMESTAMP 0x00000004L +#define SQL_DL_SQL92_INTERVAL_YEAR 0x00000008L +#define SQL_DL_SQL92_INTERVAL_MONTH 0x00000010L +#define SQL_DL_SQL92_INTERVAL_DAY 0x00000020L +#define SQL_DL_SQL92_INTERVAL_HOUR 0x00000040L +#define SQL_DL_SQL92_INTERVAL_MINUTE 0x00000080L +#define SQL_DL_SQL92_INTERVAL_SECOND 0x00000100L +#define SQL_DL_SQL92_INTERVAL_YEAR_TO_MONTH 0x00000200L +#define SQL_DL_SQL92_INTERVAL_DAY_TO_HOUR 0x00000400L +#define SQL_DL_SQL92_INTERVAL_DAY_TO_MINUTE 0x00000800L +#define SQL_DL_SQL92_INTERVAL_DAY_TO_SECOND 0x00001000L +#define SQL_DL_SQL92_INTERVAL_HOUR_TO_MINUTE 0x00002000L +#define SQL_DL_SQL92_INTERVAL_HOUR_TO_SECOND 0x00004000L +#define SQL_DL_SQL92_INTERVAL_MINUTE_TO_SECOND 0x00008000L + +/* SQL_CATALOG_LOCATION values */ +#define SQL_CL_START SQL_QL_START +#define SQL_CL_END SQL_QL_END + +/* values for SQL_BATCH_ROW_COUNT */ +#define SQL_BRC_PROCEDURES 0x0000001 +#define SQL_BRC_EXPLICIT 0x0000002 +#define SQL_BRC_ROLLED_UP 0x0000004 + +/* bitmasks for SQL_BATCH_SUPPORT */ +#define SQL_BS_SELECT_EXPLICIT 0x00000001L +#define SQL_BS_ROW_COUNT_EXPLICIT 0x00000002L +#define SQL_BS_SELECT_PROC 0x00000004L +#define SQL_BS_ROW_COUNT_PROC 0x00000008L + +/* Values for SQL_PARAM_ARRAY_ROW_COUNTS getinfo */ +#define SQL_PARC_BATCH 1 +#define SQL_PARC_NO_BATCH 2 + +/* values for SQL_PARAM_ARRAY_SELECTS */ +#define SQL_PAS_BATCH 1 +#define SQL_PAS_NO_BATCH 2 +#define SQL_PAS_NO_SELECT 3 + +/* Bitmasks for SQL_INDEX_KEYWORDS */ +#define SQL_IK_NONE 0x00000000L +#define SQL_IK_ASC 0x00000001L +#define SQL_IK_DESC 0x00000002L +#define SQL_IK_ALL (SQL_IK_ASC | SQL_IK_DESC) + +/* Bitmasks for SQL_INFO_SCHEMA_VIEWS */ + +#define SQL_ISV_ASSERTIONS 0x00000001L +#define SQL_ISV_CHARACTER_SETS 0x00000002L +#define SQL_ISV_CHECK_CONSTRAINTS 0x00000004L +#define SQL_ISV_COLLATIONS 0x00000008L +#define SQL_ISV_COLUMN_DOMAIN_USAGE 0x00000010L +#define SQL_ISV_COLUMN_PRIVILEGES 0x00000020L +#define SQL_ISV_COLUMNS 0x00000040L +#define SQL_ISV_CONSTRAINT_COLUMN_USAGE 0x00000080L +#define SQL_ISV_CONSTRAINT_TABLE_USAGE 0x00000100L +#define SQL_ISV_DOMAIN_CONSTRAINTS 0x00000200L +#define SQL_ISV_DOMAINS 0x00000400L +#define SQL_ISV_KEY_COLUMN_USAGE 0x00000800L +#define SQL_ISV_REFERENTIAL_CONSTRAINTS 0x00001000L +#define SQL_ISV_SCHEMATA 0x00002000L +#define SQL_ISV_SQL_LANGUAGES 0x00004000L +#define SQL_ISV_TABLE_CONSTRAINTS 0x00008000L +#define SQL_ISV_TABLE_PRIVILEGES 0x00010000L +#define SQL_ISV_TABLES 0x00020000L +#define SQL_ISV_TRANSLATIONS 0x00040000L +#define SQL_ISV_USAGE_PRIVILEGES 0x00080000L +#define SQL_ISV_VIEW_COLUMN_USAGE 0x00100000L +#define SQL_ISV_VIEW_TABLE_USAGE 0x00200000L +#define SQL_ISV_VIEWS 0x00400000L + +/* Bitmasks for SQL_ASYNC_MODE */ + +#define SQL_AM_NONE 0 +#define SQL_AM_CONNECTION 1 +#define SQL_AM_STATEMENT 2 + +/* Bitmasks for SQL_ALTER_DOMAIN */ +#define SQL_AD_CONSTRAINT_NAME_DEFINITION 0x00000001L +#define SQL_AD_ADD_DOMAIN_CONSTRAINT 0x00000002L +#define SQL_AD_DROP_DOMAIN_CONSTRAINT 0x00000004L +#define SQL_AD_ADD_DOMAIN_DEFAULT 0x00000008L +#define SQL_AD_DROP_DOMAIN_DEFAULT 0x00000010L +#define SQL_AD_ADD_CONSTRAINT_INITIALLY_DEFERRED 0x00000020L +#define SQL_AD_ADD_CONSTRAINT_INITIALLY_IMMEDIATE 0x00000040L +#define SQL_AD_ADD_CONSTRAINT_DEFERRABLE 0x00000080L +#define SQL_AD_ADD_CONSTRAINT_NON_DEFERRABLE 0x00000100L + + +/* SQL_CREATE_SCHEMA bitmasks */ +#define SQL_CS_CREATE_SCHEMA 0x00000001L +#define SQL_CS_AUTHORIZATION 0x00000002L +#define SQL_CS_DEFAULT_CHARACTER_SET 0x00000004L + +/* SQL_CREATE_TRANSLATION bitmasks */ +#define SQL_CTR_CREATE_TRANSLATION 0x00000001L + +/* SQL_CREATE_ASSERTION bitmasks */ +#define SQL_CA_CREATE_ASSERTION 0x00000001L +#define SQL_CA_CONSTRAINT_INITIALLY_DEFERRED 0x00000010L +#define SQL_CA_CONSTRAINT_INITIALLY_IMMEDIATE 0x00000020L +#define SQL_CA_CONSTRAINT_DEFERRABLE 0x00000040L +#define SQL_CA_CONSTRAINT_NON_DEFERRABLE 0x00000080L + +/* SQL_CREATE_CHARACTER_SET bitmasks */ +#define SQL_CCS_CREATE_CHARACTER_SET 0x00000001L +#define SQL_CCS_COLLATE_CLAUSE 0x00000002L +#define SQL_CCS_LIMITED_COLLATION 0x00000004L + +/* SQL_CREATE_COLLATION bitmasks */ +#define SQL_CCOL_CREATE_COLLATION 0x00000001L + +/* SQL_CREATE_DOMAIN bitmasks */ +#define SQL_CDO_CREATE_DOMAIN 0x00000001L +#define SQL_CDO_DEFAULT 0x00000002L +#define SQL_CDO_CONSTRAINT 0x00000004L +#define SQL_CDO_COLLATION 0x00000008L +#define SQL_CDO_CONSTRAINT_NAME_DEFINITION 0x00000010L +#define SQL_CDO_CONSTRAINT_INITIALLY_DEFERRED 0x00000020L +#define SQL_CDO_CONSTRAINT_INITIALLY_IMMEDIATE 0x00000040L +#define SQL_CDO_CONSTRAINT_DEFERRABLE 0x00000080L +#define SQL_CDO_CONSTRAINT_NON_DEFERRABLE 0x00000100L + +/* SQL_CREATE_TABLE bitmasks */ +#define SQL_CT_CREATE_TABLE 0x00000001L +#define SQL_CT_COMMIT_PRESERVE 0x00000002L +#define SQL_CT_COMMIT_DELETE 0x00000004L +#define SQL_CT_GLOBAL_TEMPORARY 0x00000008L +#define SQL_CT_LOCAL_TEMPORARY 0x00000010L +#define SQL_CT_CONSTRAINT_INITIALLY_DEFERRED 0x00000020L +#define SQL_CT_CONSTRAINT_INITIALLY_IMMEDIATE 0x00000040L +#define SQL_CT_CONSTRAINT_DEFERRABLE 0x00000080L +#define SQL_CT_CONSTRAINT_NON_DEFERRABLE 0x00000100L +#define SQL_CT_COLUMN_CONSTRAINT 0x00000200L +#define SQL_CT_COLUMN_DEFAULT 0x00000400L +#define SQL_CT_COLUMN_COLLATION 0x00000800L +#define SQL_CT_TABLE_CONSTRAINT 0x00001000L +#define SQL_CT_CONSTRAINT_NAME_DEFINITION 0x00002000L + +/* SQL_DDL_INDEX bitmasks */ +#define SQL_DI_CREATE_INDEX 0x00000001L +#define SQL_DI_DROP_INDEX 0x00000002L + +/* SQL_DROP_COLLATION bitmasks */ +#define SQL_DC_DROP_COLLATION 0x00000001L + +/* SQL_DROP_DOMAIN bitmasks */ +#define SQL_DD_DROP_DOMAIN 0x00000001L +#define SQL_DD_RESTRICT 0x00000002L +#define SQL_DD_CASCADE 0x00000004L + +/* SQL_DROP_SCHEMA bitmasks */ +#define SQL_DS_DROP_SCHEMA 0x00000001L +#define SQL_DS_RESTRICT 0x00000002L +#define SQL_DS_CASCADE 0x00000004L + +/* SQL_DROP_CHARACTER_SET bitmasks */ +#define SQL_DCS_DROP_CHARACTER_SET 0x00000001L + +/* SQL_DROP_ASSERTION bitmasks */ +#define SQL_DA_DROP_ASSERTION 0x00000001L + +/* SQL_DROP_TABLE bitmasks */ +#define SQL_DT_DROP_TABLE 0x00000001L +#define SQL_DT_RESTRICT 0x00000002L +#define SQL_DT_CASCADE 0x00000004L + +/* SQL_DROP_TRANSLATION bitmasks */ +#define SQL_DTR_DROP_TRANSLATION 0x00000001L + +/* SQL_DROP_VIEW bitmasks */ +#define SQL_DV_DROP_VIEW 0x00000001L +#define SQL_DV_RESTRICT 0x00000002L +#define SQL_DV_CASCADE 0x00000004L + +/* SQL_INSERT_STATEMENT bitmasks */ +#define SQL_IS_INSERT_LITERALS 0x00000001L +#define SQL_IS_INSERT_SEARCHED 0x00000002L +#define SQL_IS_SELECT_INTO 0x00000004L + +/* SQL_ODBC_INTERFACE_CONFORMANCE values */ +#define SQL_OIC_CORE 1UL +#define SQL_OIC_LEVEL1 2UL +#define SQL_OIC_LEVEL2 3UL + +/* SQL_SQL92_FOREIGN_KEY_DELETE_RULE bitmasks */ +#define SQL_SFKD_CASCADE 0x00000001L +#define SQL_SFKD_NO_ACTION 0x00000002L +#define SQL_SFKD_SET_DEFAULT 0x00000004L +#define SQL_SFKD_SET_NULL 0x00000008L + +/* SQL_SQL92_FOREIGN_KEY_UPDATE_RULE bitmasks */ +#define SQL_SFKU_CASCADE 0x00000001L +#define SQL_SFKU_NO_ACTION 0x00000002L +#define SQL_SFKU_SET_DEFAULT 0x00000004L +#define SQL_SFKU_SET_NULL 0x00000008L + +/* SQL_SQL92_GRANT bitmasks */ +#define SQL_SG_USAGE_ON_DOMAIN 0x00000001L +#define SQL_SG_USAGE_ON_CHARACTER_SET 0x00000002L +#define SQL_SG_USAGE_ON_COLLATION 0x00000004L +#define SQL_SG_USAGE_ON_TRANSLATION 0x00000008L +#define SQL_SG_WITH_GRANT_OPTION 0x00000010L +#define SQL_SG_DELETE_TABLE 0x00000020L +#define SQL_SG_INSERT_TABLE 0x00000040L +#define SQL_SG_INSERT_COLUMN 0x00000080L +#define SQL_SG_REFERENCES_TABLE 0x00000100L +#define SQL_SG_REFERENCES_COLUMN 0x00000200L +#define SQL_SG_SELECT_TABLE 0x00000400L +#define SQL_SG_UPDATE_TABLE 0x00000800L +#define SQL_SG_UPDATE_COLUMN 0x00001000L + +/* SQL_SQL92_PREDICATES bitmasks */ +#define SQL_SP_EXISTS 0x00000001L +#define SQL_SP_ISNOTNULL 0x00000002L +#define SQL_SP_ISNULL 0x00000004L +#define SQL_SP_MATCH_FULL 0x00000008L +#define SQL_SP_MATCH_PARTIAL 0x00000010L +#define SQL_SP_MATCH_UNIQUE_FULL 0x00000020L +#define SQL_SP_MATCH_UNIQUE_PARTIAL 0x00000040L +#define SQL_SP_OVERLAPS 0x00000080L +#define SQL_SP_UNIQUE 0x00000100L +#define SQL_SP_LIKE 0x00000200L +#define SQL_SP_IN 0x00000400L +#define SQL_SP_BETWEEN 0x00000800L +#define SQL_SP_COMPARISON 0x00001000L +#define SQL_SP_QUANTIFIED_COMPARISON 0x00002000L + +/* SQL_SQL92_RELATIONAL_JOIN_OPERATORS bitmasks */ +#define SQL_SRJO_CORRESPONDING_CLAUSE 0x00000001L +#define SQL_SRJO_CROSS_JOIN 0x00000002L +#define SQL_SRJO_EXCEPT_JOIN 0x00000004L +#define SQL_SRJO_FULL_OUTER_JOIN 0x00000008L +#define SQL_SRJO_INNER_JOIN 0x00000010L +#define SQL_SRJO_INTERSECT_JOIN 0x00000020L +#define SQL_SRJO_LEFT_OUTER_JOIN 0x00000040L +#define SQL_SRJO_NATURAL_JOIN 0x00000080L +#define SQL_SRJO_RIGHT_OUTER_JOIN 0x00000100L +#define SQL_SRJO_UNION_JOIN 0x00000200L + +/* SQL_SQL92_REVOKE bitmasks */ +#define SQL_SR_USAGE_ON_DOMAIN 0x00000001L +#define SQL_SR_USAGE_ON_CHARACTER_SET 0x00000002L +#define SQL_SR_USAGE_ON_COLLATION 0x00000004L +#define SQL_SR_USAGE_ON_TRANSLATION 0x00000008L +#define SQL_SR_GRANT_OPTION_FOR 0x00000010L +#define SQL_SR_CASCADE 0x00000020L +#define SQL_SR_RESTRICT 0x00000040L +#define SQL_SR_DELETE_TABLE 0x00000080L +#define SQL_SR_INSERT_TABLE 0x00000100L +#define SQL_SR_INSERT_COLUMN 0x00000200L +#define SQL_SR_REFERENCES_TABLE 0x00000400L +#define SQL_SR_REFERENCES_COLUMN 0x00000800L +#define SQL_SR_SELECT_TABLE 0x00001000L +#define SQL_SR_UPDATE_TABLE 0x00002000L +#define SQL_SR_UPDATE_COLUMN 0x00004000L + +/* SQL_SQL92_ROW_VALUE_CONSTRUCTOR bitmasks */ +#define SQL_SRVC_VALUE_EXPRESSION 0x00000001L +#define SQL_SRVC_NULL 0x00000002L +#define SQL_SRVC_DEFAULT 0x00000004L +#define SQL_SRVC_ROW_SUBQUERY 0x00000008L + +/* SQL_SQL92_VALUE_EXPRESSIONS bitmasks */ +#define SQL_SVE_CASE 0x00000001L +#define SQL_SVE_CAST 0x00000002L +#define SQL_SVE_COALESCE 0x00000004L +#define SQL_SVE_NULLIF 0x00000008L + +/* SQL_STANDARD_CLI_CONFORMANCE bitmasks */ +#define SQL_SCC_XOPEN_CLI_VERSION1 0x00000001L +#define SQL_SCC_ISO92_CLI 0x00000002L + +/* SQL_UNION_STATEMENT bitmasks */ +#define SQL_US_UNION SQL_U_UNION +#define SQL_US_UNION_ALL SQL_U_UNION_ALL + +#endif /* ODBCVER >= 0x0300 */ + +/* SQL_DTC_TRANSITION_COST bitmasks */ +#define SQL_DTC_ENLIST_EXPENSIVE 0x00000001L +#define SQL_DTC_UNENLIST_EXPENSIVE 0x00000002L + +/* additional SQLDataSources fetch directions */ +#if (ODBCVER >= 0x0300) +#define SQL_FETCH_FIRST_USER 31 +#define SQL_FETCH_FIRST_SYSTEM 32 +#endif /* ODBCVER >= 0x0300 */ + + +/* Defines for SQLSetPos */ +#define SQL_ENTIRE_ROWSET 0 + +/* Operations in SQLSetPos */ +#define SQL_POSITION 0 /* 1.0 FALSE */ +#define SQL_REFRESH 1 /* 1.0 TRUE */ +#define SQL_UPDATE 2 +#define SQL_DELETE 3 + +/* Operations in SQLBulkOperations */ +#define SQL_ADD 4 +#define SQL_SETPOS_MAX_OPTION_VALUE SQL_ADD +#if (ODBCVER >= 0x0300) +#define SQL_UPDATE_BY_BOOKMARK 5 +#define SQL_DELETE_BY_BOOKMARK 6 +#define SQL_FETCH_BY_BOOKMARK 7 + +#endif /* ODBCVER >= 0x0300 */ + +/* Lock options in SQLSetPos */ +#define SQL_LOCK_NO_CHANGE 0 /* 1.0 FALSE */ +#define SQL_LOCK_EXCLUSIVE 1 /* 1.0 TRUE */ +#define SQL_LOCK_UNLOCK 2 + +#define SQL_SETPOS_MAX_LOCK_VALUE SQL_LOCK_UNLOCK + +/* Macros for SQLSetPos */ +#define SQL_POSITION_TO(hstmt,irow) SQLSetPos(hstmt,irow,SQL_POSITION,SQL_LOCK_NO_CHANGE) +#define SQL_LOCK_RECORD(hstmt,irow,fLock) SQLSetPos(hstmt,irow,SQL_POSITION,fLock) +#define SQL_REFRESH_RECORD(hstmt,irow,fLock) SQLSetPos(hstmt,irow,SQL_REFRESH,fLock) +#define SQL_UPDATE_RECORD(hstmt,irow) SQLSetPos(hstmt,irow,SQL_UPDATE,SQL_LOCK_NO_CHANGE) +#define SQL_DELETE_RECORD(hstmt,irow) SQLSetPos(hstmt,irow,SQL_DELETE,SQL_LOCK_NO_CHANGE) +#define SQL_ADD_RECORD(hstmt,irow) SQLSetPos(hstmt,irow,SQL_ADD,SQL_LOCK_NO_CHANGE) + +/* Column types and scopes in SQLSpecialColumns. */ +#define SQL_BEST_ROWID 1 +#define SQL_ROWVER 2 + +/* Defines for SQLSpecialColumns (returned in the result set) + SQL_PC_UNKNOWN and SQL_PC_PSEUDO are defined in sql.h */ +#define SQL_PC_NOT_PSEUDO 1 + +/* Defines for SQLStatistics */ +#define SQL_QUICK 0 +#define SQL_ENSURE 1 + +/* Defines for SQLStatistics (returned in the result set) + SQL_INDEX_CLUSTERED, SQL_INDEX_HASHED, and SQL_INDEX_OTHER are + defined in sql.h */ +#define SQL_TABLE_STAT 0 + + +/* Defines for SQLTables */ +#if (ODBCVER >= 0x0300) +#define SQL_ALL_CATALOGS "%" +#define SQL_ALL_SCHEMAS "%" +#define SQL_ALL_TABLE_TYPES "%" +#endif /* ODBCVER >= 0x0300 */ + +/* Options for SQLDriverConnect */ +#define SQL_DRIVER_NOPROMPT 0 +#define SQL_DRIVER_COMPLETE 1 +#define SQL_DRIVER_PROMPT 2 +#define SQL_DRIVER_COMPLETE_REQUIRED 3 + +#ifndef RC_INVOKED + +SQLRETURN SQL_API SQLDriverConnect( + SQLHDBC hdbc, + SQLHWND hwnd, + SQLCHAR *szConnStrIn, + SQLSMALLINT cbConnStrIn, + SQLCHAR *szConnStrOut, + SQLSMALLINT cbConnStrOutMax, + SQLSMALLINT *pcbConnStrOut, + SQLUSMALLINT fDriverCompletion); + +#endif /* RC_INVOKED */ + +/* Level 2 Functions */ + +/* SQLExtendedFetch "fFetchType" values */ +#define SQL_FETCH_BOOKMARK 8 + +/* SQLExtendedFetch "rgfRowStatus" element values */ +#define SQL_ROW_SUCCESS 0 +#define SQL_ROW_DELETED 1 +#define SQL_ROW_UPDATED 2 +#define SQL_ROW_NOROW 3 +#define SQL_ROW_ADDED 4 +#define SQL_ROW_ERROR 5 +#if (ODBCVER >= 0x0300) +#define SQL_ROW_SUCCESS_WITH_INFO 6 +#define SQL_ROW_PROCEED 0 +#define SQL_ROW_IGNORE 1 +#endif + +/* value for SQL_DESC_ARRAY_STATUS_PTR */ +#if (ODBCVER >= 0x0300) +#define SQL_PARAM_SUCCESS 0 +#define SQL_PARAM_SUCCESS_WITH_INFO 6 +#define SQL_PARAM_ERROR 5 +#define SQL_PARAM_UNUSED 7 +#define SQL_PARAM_DIAG_UNAVAILABLE 1 + +#define SQL_PARAM_PROCEED 0 +#define SQL_PARAM_IGNORE 1 +#endif /* ODBCVER >= 0x0300 */ + +/* Defines for SQLForeignKeys (UPDATE_RULE and DELETE_RULE) */ +#define SQL_CASCADE 0 +#define SQL_RESTRICT 1 +#define SQL_SET_NULL 2 +#if (ODBCVER >= 0x0250) +#define SQL_NO_ACTION 3 +#define SQL_SET_DEFAULT 4 +#endif /* ODBCVER >= 0x0250 */ + +#if (ODBCVER >= 0x0300) +/* Note that the following are in a different column of SQLForeignKeys than */ +/* the previous #defines. These are for DEFERRABILITY. */ + +#define SQL_INITIALLY_DEFERRED 5 +#define SQL_INITIALLY_IMMEDIATE 6 +#define SQL_NOT_DEFERRABLE 7 + +#endif /* ODBCVER >= 0x0300 */ + +/* Defines for SQLBindParameter and + SQLProcedureColumns (returned in the result set) */ +#define SQL_PARAM_TYPE_UNKNOWN 0 +#define SQL_PARAM_INPUT 1 +#define SQL_PARAM_INPUT_OUTPUT 2 +#define SQL_RESULT_COL 3 +#define SQL_PARAM_OUTPUT 4 +#define SQL_RETURN_VALUE 5 + +/* Defines for SQLProcedures (returned in the result set) */ +#define SQL_PT_UNKNOWN 0 +#define SQL_PT_PROCEDURE 1 +#define SQL_PT_FUNCTION 2 + +#ifndef RC_INVOKED + +/* This define is too large for RC */ +#define SQL_ODBC_KEYWORDS \ +"ABSOLUTE,ACTION,ADA,ADD,ALL,ALLOCATE,ALTER,AND,ANY,ARE,AS,"\ +"ASC,ASSERTION,AT,AUTHORIZATION,AVG,"\ +"BEGIN,BETWEEN,BIT,BIT_LENGTH,BOTH,BY,CASCADE,CASCADED,CASE,CAST,CATALOG,"\ +"CHAR,CHAR_LENGTH,CHARACTER,CHARACTER_LENGTH,CHECK,CLOSE,COALESCE,"\ +"COLLATE,COLLATION,COLUMN,COMMIT,CONNECT,CONNECTION,CONSTRAINT,"\ +"CONSTRAINTS,CONTINUE,CONVERT,CORRESPONDING,COUNT,CREATE,CROSS,CURRENT,"\ +"CURRENT_DATE,CURRENT_TIME,CURRENT_TIMESTAMP,CURRENT_USER,CURSOR,"\ +"DATE,DAY,DEALLOCATE,DEC,DECIMAL,DECLARE,DEFAULT,DEFERRABLE,"\ +"DEFERRED,DELETE,DESC,DESCRIBE,DESCRIPTOR,DIAGNOSTICS,DISCONNECT,"\ +"DISTINCT,DOMAIN,DOUBLE,DROP,"\ +"ELSE,END,END-EXEC,ESCAPE,EXCEPT,EXCEPTION,EXEC,EXECUTE,"\ +"EXISTS,EXTERNAL,EXTRACT,"\ +"FALSE,FETCH,FIRST,FLOAT,FOR,FOREIGN,FORTRAN,FOUND,FROM,FULL,"\ +"GET,GLOBAL,GO,GOTO,GRANT,GROUP,HAVING,HOUR,"\ +"IDENTITY,IMMEDIATE,IN,INCLUDE,INDEX,INDICATOR,INITIALLY,INNER,"\ +"INPUT,INSENSITIVE,INSERT,INT,INTEGER,INTERSECT,INTERVAL,INTO,IS,ISOLATION,"\ +"JOIN,KEY,LANGUAGE,LAST,LEADING,LEFT,LEVEL,LIKE,LOCAL,LOWER,"\ +"MATCH,MAX,MIN,MINUTE,MODULE,MONTH,"\ +"NAMES,NATIONAL,NATURAL,NCHAR,NEXT,NO,NONE,NOT,NULL,NULLIF,NUMERIC,"\ +"OCTET_LENGTH,OF,ON,ONLY,OPEN,OPTION,OR,ORDER,OUTER,OUTPUT,OVERLAPS,"\ +"PAD,PARTIAL,PASCAL,PLI,POSITION,PRECISION,PREPARE,PRESERVE,"\ +"PRIMARY,PRIOR,PRIVILEGES,PROCEDURE,PUBLIC,"\ +"READ,REAL,REFERENCES,RELATIVE,RESTRICT,REVOKE,RIGHT,ROLLBACK,ROWS"\ +"SCHEMA,SCROLL,SECOND,SECTION,SELECT,SESSION,SESSION_USER,SET,SIZE,"\ +"SMALLINT,SOME,SPACE,SQL,SQLCA,SQLCODE,SQLERROR,SQLSTATE,SQLWARNING,"\ +"SUBSTRING,SUM,SYSTEM_USER,"\ +"TABLE,TEMPORARY,THEN,TIME,TIMESTAMP,TIMEZONE_HOUR,TIMEZONE_MINUTE,"\ +"TO,TRAILING,TRANSACTION,TRANSLATE,TRANSLATION,TRIM,TRUE,"\ +"UNION,UNIQUE,UNKNOWN,UPDATE,UPPER,USAGE,USER,USING,"\ +"VALUE,VALUES,VARCHAR,VARYING,VIEW,WHEN,WHENEVER,WHERE,WITH,WORK,WRITE,"\ +"YEAR,ZONE" + +SQLRETURN SQL_API SQLBrowseConnect( + SQLHDBC hdbc, + SQLCHAR *szConnStrIn, + SQLSMALLINT cbConnStrIn, + SQLCHAR *szConnStrOut, + SQLSMALLINT cbConnStrOutMax, + SQLSMALLINT *pcbConnStrOut); + +#if (ODBCVER >= 0x0300) +SQLRETURN SQL_API SQLBulkOperations( + SQLHSTMT StatementHandle, + SQLSMALLINT Operation); +#endif /* ODBCVER >= 0x0300 */ + +SQLRETURN SQL_API SQLColAttributes( + SQLHSTMT hstmt, + SQLUSMALLINT icol, + SQLUSMALLINT fDescType, + SQLPOINTER rgbDesc, + SQLSMALLINT cbDescMax, + SQLSMALLINT *pcbDesc, + SQLLEN *pfDesc); + +SQLRETURN SQL_API SQLColumnPrivileges( + SQLHSTMT hstmt, + SQLCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR *szTableName, + SQLSMALLINT cbTableName, + SQLCHAR *szColumnName, + SQLSMALLINT cbColumnName); + +SQLRETURN SQL_API SQLDescribeParam( + SQLHSTMT hstmt, + SQLUSMALLINT ipar, + SQLSMALLINT *pfSqlType, + SQLULEN *pcbParamDef, + SQLSMALLINT *pibScale, + SQLSMALLINT *pfNullable); + +SQLRETURN SQL_API SQLExtendedFetch( + SQLHSTMT hstmt, + SQLUSMALLINT fFetchType, + SQLLEN irow, + SQLULEN *pcrow, + SQLUSMALLINT *rgfRowStatus); + +SQLRETURN SQL_API SQLForeignKeys( + SQLHSTMT hstmt, + SQLCHAR *szPkCatalogName, + SQLSMALLINT cbPkCatalogName, + SQLCHAR *szPkSchemaName, + SQLSMALLINT cbPkSchemaName, + SQLCHAR *szPkTableName, + SQLSMALLINT cbPkTableName, + SQLCHAR *szFkCatalogName, + SQLSMALLINT cbFkCatalogName, + SQLCHAR *szFkSchemaName, + SQLSMALLINT cbFkSchemaName, + SQLCHAR *szFkTableName, + SQLSMALLINT cbFkTableName); + +SQLRETURN SQL_API SQLMoreResults( + SQLHSTMT hstmt); + +SQLRETURN SQL_API SQLNativeSql( + SQLHDBC hdbc, + SQLCHAR *szSqlStrIn, + SQLINTEGER cbSqlStrIn, + SQLCHAR *szSqlStr, + SQLINTEGER cbSqlStrMax, + SQLINTEGER *pcbSqlStr); + +SQLRETURN SQL_API SQLNumParams( + SQLHSTMT hstmt, + SQLSMALLINT *pcpar); + +SQLRETURN SQL_API SQLParamOptions( + SQLHSTMT hstmt, + SQLULEN crow, + SQLULEN *pirow); + +SQLRETURN SQL_API SQLPrimaryKeys( + SQLHSTMT hstmt, + SQLCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR *szTableName, + SQLSMALLINT cbTableName); + +SQLRETURN SQL_API SQLProcedureColumns( + SQLHSTMT hstmt, + SQLCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR *szProcName, + SQLSMALLINT cbProcName, + SQLCHAR *szColumnName, + SQLSMALLINT cbColumnName); + +SQLRETURN SQL_API SQLProcedures( + SQLHSTMT hstmt, + SQLCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR *szProcName, + SQLSMALLINT cbProcName); + +SQLRETURN SQL_API SQLSetPos( + SQLHSTMT hstmt, + SQLSETPOSIROW irow, + SQLUSMALLINT fOption, + SQLUSMALLINT fLock); + +SQLRETURN SQL_API SQLTablePrivileges( + SQLHSTMT hstmt, + SQLCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR *szTableName, + SQLSMALLINT cbTableName); + +SQLRETURN SQL_API SQLDrivers( + SQLHENV henv, + SQLUSMALLINT fDirection, + SQLCHAR *szDriverDesc, + SQLSMALLINT cbDriverDescMax, + SQLSMALLINT *pcbDriverDesc, + SQLCHAR *szDriverAttributes, + SQLSMALLINT cbDrvrAttrMax, + SQLSMALLINT *pcbDrvrAttr); + +SQLRETURN SQL_API SQLBindParameter( + SQLHSTMT hstmt, + SQLUSMALLINT ipar, + SQLSMALLINT fParamType, + SQLSMALLINT fCType, + SQLSMALLINT fSqlType, + SQLULEN cbColDef, + SQLSMALLINT ibScale, + SQLPOINTER rgbValue, + SQLLEN cbValueMax, + SQLLEN *pcbValue); + + +#endif /* RC_INVOKED */ + +/*---------------------------------------------------------*/ +/* SQLAllocHandleStd is implemented to make SQLAllocHandle */ +/* compatible with X/Open standard. an application should */ +/* not call SQLAllocHandleStd directly */ +/*---------------------------------------------------------*/ +#ifdef ODBC_STD +#define SQLAllocHandle SQLAllocHandleStd +#define SQLAllocEnv(phenv) SQLAllocHandleStd(SQL_HANDLE_ENV, SQL_NULL_HANDLE, phenv) + +/* Internal type subcodes */ +#define SQL_YEAR SQL_CODE_YEAR +#define SQL_MONTH SQL_CODE_MONTH +#define SQL_DAY SQL_CODE_DAY +#define SQL_HOUR SQL_CODE_HOUR +#define SQL_MINUTE SQL_CODE_MINUTE +#define SQL_SECOND SQL_CODE_SECOND +#define SQL_YEAR_TO_MONTH SQL_CODE_YEAR_TO_MONTH +#define SQL_DAY_TO_HOUR SQL_CODE_DAY_TO_HOUR +#define SQL_DAY_TO_MINUTE SQL_CODE_DAY_TO_MINUTE +#define SQL_DAY_TO_SECOND SQL_CODE_DAY_TO_SECOND +#define SQL_HOUR_TO_MINUTE SQL_CODE_HOUR_TO_MINUTE +#define SQL_HOUR_TO_SECOND SQL_CODE_HOUR_TO_SECOND +#define SQL_MINUTE_TO_SECOND SQL_CODE_MINUTE_TO_SECOND +#endif /* ODBC_STD */ + +#if (ODBCVER >= 0x0300) +#ifndef RC_INVOKED +SQLRETURN SQL_API SQLAllocHandleStd( + SQLSMALLINT fHandleType, + SQLHANDLE hInput, + SQLHANDLE *phOutput); +#endif /* RC_INVOKED */ +#endif + +/* Deprecated defines from prior versions of ODBC */ +#define SQL_DATABASE_NAME 16 /* Use SQLGetConnectOption/SQL_CURRENT_QUALIFIER */ +#define SQL_FD_FETCH_PREV SQL_FD_FETCH_PRIOR +#define SQL_FETCH_PREV SQL_FETCH_PRIOR +#define SQL_CONCUR_TIMESTAMP SQL_CONCUR_ROWVER +#define SQL_SCCO_OPT_TIMESTAMP SQL_SCCO_OPT_ROWVER +#define SQL_CC_DELETE SQL_CB_DELETE +#define SQL_CR_DELETE SQL_CB_DELETE +#define SQL_CC_CLOSE SQL_CB_CLOSE +#define SQL_CR_CLOSE SQL_CB_CLOSE +#define SQL_CC_PRESERVE SQL_CB_PRESERVE +#define SQL_CR_PRESERVE SQL_CB_PRESERVE +/* SQL_FETCH_RESUME is not supported by 2.0+ drivers +#define SQL_FETCH_RESUME 7 +*/ +#define SQL_SCROLL_FORWARD_ONLY 0L /*-SQL_CURSOR_FORWARD_ONLY */ +#define SQL_SCROLL_KEYSET_DRIVEN (-1L) /*-SQL_CURSOR_KEYSET_DRIVEN */ +#define SQL_SCROLL_DYNAMIC (-2L) /*-SQL_CURSOR_DYNAMIC */ +#define SQL_SCROLL_STATIC (-3L) /*-SQL_CURSOR_STATIC */ + +/* Deprecated functions from prior versions of ODBC */ +#ifndef RC_INVOKED + +SQLRETURN SQL_API SQLSetScrollOptions( /* Use SQLSetStmtOptions */ + SQLHSTMT hstmt, + SQLUSMALLINT fConcurrency, + SQLLEN crowKeyset, + SQLUSMALLINT crowRowset); +#if 0 +/* Tracing section */ + +#define TRACE_VERSION 1000 /* Version of trace API */ + +RETCODE SQL_API TraceOpenLogFile(LPWSTR,LPWSTR,DWORD);// open a trace log file +RETCODE SQL_API TraceCloseLogFile(); // Request to close a trace log +VOID SQL_API TraceReturn(RETCODE,RETCODE); // Processes trace after FN is called +DWORD SQL_API TraceVersion(); // Returns trace API version + +/* Functions for Visual Studio Analyzer*/ +/* to turn on/off tracing or VS events, call TraceVSControl by setting or clearing the following bits */ +#define TRACE_ON 0x00000001L +#define TRACE_VS_EVENT_ON 0x00000002L + +RETCODE SQL_API TraceVSControl(DWORD); + +/* the flags in ODBC_VS_ARGS */ +#define ODBC_VS_FLAG_UNICODE_ARG 0x00000001L /* the argument is unicode */ +#define ODBC_VS_FLAG_UNICODE_COR 0x00000002L /* the correlation is unicode */ +#define ODBC_VS_FLAG_RETCODE 0x00000004L /* RetCode field is set */ +#define ODBC_VS_FLAG_STOP 0x00000008L /* Stop firing visual studio analyzer events */ + +typedef struct tagODBC_VS_ARGS { + const GUID *pguidEvent; /* the GUID for event */ + DWORD dwFlags; /* flags for the call */ + union { + WCHAR *wszArg; + CHAR *szArg; + }; + union { + WCHAR *wszCorrelation; + CHAR *szCorrelation; + }; + RETCODE RetCode; +} ODBC_VS_ARGS, *PODBC_VS_ARGS; +VOID SQL_API FireVSDebugEvent(PODBC_VS_ARGS); +#endif +#endif /* RC_INVOKED */ + + +#ifdef __cplusplus +} /* End of extern "C" { */ +#endif /* __cplusplus */ + +#if defined(WIN32) || defined(ODBC64) +#if 0 +#include "sqlucode.h" +#endif +#endif + +#endif /* __SQLEXT */ diff --git a/libodbc/include/db2_linux/sqlsystm.h b/libodbc/include/db2_linux/sqlsystm.h new file mode 100644 index 0000000000..225c21c960 --- /dev/null +++ b/libodbc/include/db2_linux/sqlsystm.h @@ -0,0 +1,119 @@ +/****************************************************************************** + * + * Source File Name = SQLSYSTM.H + * + * (C) COPYRIGHT International Business Machines Corp. 1993, 1998 + * All Rights Reserved + * Licensed Materials - Property of IBM + * + * US Government Users Restricted Rights - Use, duplication or + * disclosure restricted by GSA ADP Schedule Contract with IBM Corp. + * + * Function = Include File defining: + * Operating System Specific Information + * + * Operating System = Linux + * + *****************************************************************************/ + +#if !defined SQL_H_SQLSYSTM +#define SQL_H_SQLSYSTM /* Permit duplicate Includes */ + +#if !defined DB2LINUX + #define DB2LINUX 1 +#endif + +/* Operating System Control Parameters */ + +#if !defined SQL_API_RC + #define SQL_API_RC int + #define SQL_STRUCTURE struct + #define PSQL_API_FN * + #define SQL_API_FN + #define SQL_POINTER + #define SQL_API_INTR +#endif + +/****************************************************************************** +** +** The SQLOLDCHAR macro may be used to maintain compatibility between +** version 1 applications and version 2 header files. In version 1, many +** strings were declared as 'unsigned char'. In keeping with the spirit +** of ANSI C, all character data, structure members and function +** parameters with string semantics have been changed to 'char' in version 2. +** This change may produce type conflicts with some compilers. Adding +** -DSQLOLDCHAR to the compile command will cause the changed items to +** revert to their version 1 types. Note that this should be used for +** compatibility purposes only. New code should be written using plain +** 'char' where indicated in the documentation. +******************************************************************************/ + +#undef _SQLOLDCHAR +#if defined SQLOLDCHAR + #define _SQLOLDCHAR unsigned char +#else + #define _SQLOLDCHAR char +#endif + +/****************************************************************************** +** +** Define fixed size integer types. +** +******************************************************************************/ + +typedef char sqlint8; +typedef unsigned char sqluint8; + +typedef short sqlint16; +typedef unsigned short sqluint16; + + +#if defined __LP64__ || defined __PPC64__ || defined __x86_64__ || defined __s390x__ + #define db2Is64bit +#endif + +#if defined db2Is64bit || defined DB2_FORCE_INT32_TYPES_TO_INT + typedef int sqlint32; + typedef unsigned int sqluint32; +#else + typedef long sqlint32; + typedef unsigned long sqluint32; +#endif + +#if !defined SQL_BIGINT_TYPE + #if defined db2Is64bit + #define SQL_BIGINT_TYPE long + #define DB2_CONSTRUCT_BIGINT_CONSTANT(db2BigIntConstantValue) db2BigIntConstantValue##L + #else + #define SQL_BIGINT_TYPE long long + #define DB2_CONSTRUCT_BIGINT_CONSTANT(db2BigIntConstantValue) db2BigIntConstantValue##LL + #endif +#endif + +#if !defined SQL_BIGUINT_TYPE + #if defined db2Is64bit + #define SQL_BIGUINT_TYPE unsigned long + #else + #define SQL_BIGUINT_TYPE unsigned long long + #endif +#endif + +typedef SQL_BIGINT_TYPE sqlint64; +typedef SQL_BIGUINT_TYPE sqluint64; + +/****************************************************************************** +** +** The sqlintptr and sqluintptr are defined as integer types large enough +** to contain pointer values on this platform. +** +******************************************************************************/ + +#if defined db2Is64bit + typedef sqlint64 sqlintptr; + typedef sqluint64 sqluintptr; +#else + typedef sqlint32 sqlintptr; + typedef sqluint32 sqluintptr; +#endif + +#endif /* SQL_H_SQLSYSTM */ diff --git a/libodbc/include/ibAPI.h b/libodbc/include/ibAPI.h new file mode 100644 index 0000000000..82bbfb21d4 --- /dev/null +++ b/libodbc/include/ibAPI.h @@ -0,0 +1,991 @@ +/*! + * interface for the IibClient class. + * + * Copyright (c) 2005 by + */ + +#if !defined(__IBAPI_H__) +#define __IBAPI_H__ + +#include "SQLAPI.h" + +#ifdef __SUNPRO_CC +#include +#define _INTPTR_T_DEFINED +#endif + +#include + +#ifdef SA_64BIT +#define ISC_NULL_HANDLE 0 +#else +#define ISC_NULL_HANDLE NULL +#endif + +extern long g_nIB_DLLVersionLoaded; + +extern void AddIBSupport(const SAConnection *pCon); +extern void ReleaseIBSupport(); + +typedef ISC_STATUS (ISC_EXPORT *isc_attach_database_t) (ISC_STATUS ISC_FAR *, + short, + char ISC_FAR *, + isc_db_handle ISC_FAR *, + short, + char ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_array_gen_sdl_t) (ISC_STATUS ISC_FAR *, + ISC_ARRAY_DESC ISC_FAR *, + short ISC_FAR *, + char ISC_FAR *, + short ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_array_get_slice_t) (ISC_STATUS ISC_FAR *, + isc_db_handle ISC_FAR *, + isc_tr_handle ISC_FAR *, + ISC_QUAD ISC_FAR *, + ISC_ARRAY_DESC ISC_FAR *, + void ISC_FAR *, + ISC_LONG ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_array_lookup_bounds_t) (ISC_STATUS ISC_FAR *, + isc_db_handle ISC_FAR *, + isc_tr_handle ISC_FAR *, + char ISC_FAR *, + char ISC_FAR *, + ISC_ARRAY_DESC ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_array_lookup_desc_t) (ISC_STATUS ISC_FAR *, + isc_db_handle ISC_FAR *, + isc_tr_handle ISC_FAR *, + char ISC_FAR *, + char ISC_FAR *, + ISC_ARRAY_DESC ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_array_set_desc_t) (ISC_STATUS ISC_FAR *, + char ISC_FAR *, + char ISC_FAR *, + short ISC_FAR *, + short ISC_FAR *, + short ISC_FAR *, + ISC_ARRAY_DESC ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_array_put_slice_t) (ISC_STATUS ISC_FAR *, + isc_db_handle ISC_FAR *, + isc_tr_handle ISC_FAR *, + ISC_QUAD ISC_FAR *, + ISC_ARRAY_DESC ISC_FAR *, + void ISC_FAR *, + ISC_LONG ISC_FAR *); + +typedef void (ISC_EXPORT *isc_blob_default_desc_t) (ISC_BLOB_DESC ISC_FAR *, + unsigned char ISC_FAR *, + unsigned char ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_blob_gen_bpb_t) (ISC_STATUS ISC_FAR *, + ISC_BLOB_DESC ISC_FAR *, + ISC_BLOB_DESC ISC_FAR *, + unsigned short, + unsigned char ISC_FAR *, + unsigned short ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_blob_info_t) (ISC_STATUS ISC_FAR *, + isc_blob_handle ISC_FAR *, + short, + char ISC_FAR *, + short, + char ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_blob_lookup_desc_t) (ISC_STATUS ISC_FAR *, + isc_db_handle ISC_FAR *, + isc_tr_handle ISC_FAR *, + unsigned char ISC_FAR *, + unsigned char ISC_FAR *, + ISC_BLOB_DESC ISC_FAR *, + unsigned char ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_blob_set_desc_t) (ISC_STATUS ISC_FAR *, + unsigned char ISC_FAR *, + unsigned char ISC_FAR *, + short, + short, + short, + ISC_BLOB_DESC ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_cancel_blob_t) (ISC_STATUS ISC_FAR *, + isc_blob_handle ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_cancel_events_t) (ISC_STATUS ISC_FAR *, + isc_db_handle ISC_FAR *, + ISC_LONG ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_close_blob_t) (ISC_STATUS ISC_FAR *, + isc_blob_handle ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_commit_retaining_t) (ISC_STATUS ISC_FAR *, + isc_tr_handle ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_commit_transaction_t) (ISC_STATUS ISC_FAR *, + isc_tr_handle ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_create_blob_t) (ISC_STATUS ISC_FAR *, + isc_db_handle ISC_FAR *, + isc_tr_handle ISC_FAR *, + isc_blob_handle ISC_FAR *, + ISC_QUAD ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_create_blob2_t) (ISC_STATUS ISC_FAR *, + isc_db_handle ISC_FAR *, + isc_tr_handle ISC_FAR *, + isc_blob_handle ISC_FAR *, + ISC_QUAD ISC_FAR *, + short, + char ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_create_database_t) (ISC_STATUS ISC_FAR *, + short, + char ISC_FAR *, + isc_db_handle ISC_FAR *, + short, + char ISC_FAR *, + short); + +typedef ISC_STATUS (ISC_EXPORT *isc_database_info_t) (ISC_STATUS ISC_FAR *, + isc_db_handle ISC_FAR *, + short, + char ISC_FAR *, + short, + char ISC_FAR *); + +typedef void (ISC_EXPORT *isc_decode_date_t) (ISC_QUAD ISC_FAR *, + void ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_detach_database_t) (ISC_STATUS ISC_FAR *, + isc_db_handle ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_drop_database_t) (ISC_STATUS ISC_FAR *, + isc_db_handle ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_dsql_allocate_statement_t) (ISC_STATUS ISC_FAR *, + isc_db_handle ISC_FAR *, + isc_stmt_handle ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_dsql_alloc_statement2_t) (ISC_STATUS ISC_FAR *, + isc_db_handle ISC_FAR *, + isc_stmt_handle ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_dsql_describe_t) (ISC_STATUS ISC_FAR *, + isc_stmt_handle ISC_FAR *, + unsigned short, + XSQLDA ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_dsql_describe_bind_t) (ISC_STATUS ISC_FAR *, + isc_stmt_handle ISC_FAR *, + unsigned short, + XSQLDA ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_dsql_exec_immed2_t) (ISC_STATUS ISC_FAR *, + isc_db_handle ISC_FAR *, + isc_tr_handle ISC_FAR *, + unsigned short, + char ISC_FAR *, + unsigned short, + XSQLDA ISC_FAR *, + XSQLDA ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_dsql_execute_t) (ISC_STATUS ISC_FAR *, + isc_tr_handle ISC_FAR *, + isc_stmt_handle ISC_FAR *, + unsigned short, + XSQLDA ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_dsql_execute2_t) (ISC_STATUS ISC_FAR *, + isc_tr_handle ISC_FAR *, + isc_stmt_handle ISC_FAR *, + unsigned short, + XSQLDA ISC_FAR *, + XSQLDA ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_dsql_execute_immediate_t) (ISC_STATUS ISC_FAR *, + isc_db_handle ISC_FAR *, + isc_tr_handle ISC_FAR *, + unsigned short, + char ISC_FAR *, + unsigned short, + XSQLDA ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_dsql_fetch_t) (ISC_STATUS ISC_FAR *, + isc_stmt_handle ISC_FAR *, + unsigned short, + XSQLDA ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_dsql_finish_t) (isc_db_handle ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_dsql_free_statement_t) (ISC_STATUS ISC_FAR *, + isc_stmt_handle ISC_FAR *, + unsigned short); + +typedef ISC_STATUS (ISC_EXPORT *isc_dsql_insert_t) (ISC_STATUS ISC_FAR *, + isc_stmt_handle ISC_FAR *, + unsigned short, + XSQLDA ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_dsql_prepare_t) (ISC_STATUS ISC_FAR *, + isc_tr_handle ISC_FAR *, + isc_stmt_handle ISC_FAR *, + unsigned short, + char ISC_FAR *, + unsigned short, + XSQLDA ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_dsql_set_cursor_name_t) (ISC_STATUS ISC_FAR *, + isc_stmt_handle ISC_FAR *, + char ISC_FAR *, + unsigned short); + +typedef ISC_STATUS (ISC_EXPORT *isc_dsql_sql_info_t) (ISC_STATUS ISC_FAR *, + isc_stmt_handle ISC_FAR *, + short, + char ISC_FAR *, + short, + char ISC_FAR *); + +typedef void (ISC_EXPORT *isc_encode_date_t) (void ISC_FAR *, + ISC_QUAD ISC_FAR *); + +typedef ISC_LONG (ISC_EXPORT_VARARG *isc_event_block_t) (char ISC_FAR * ISC_FAR *, + char ISC_FAR * ISC_FAR *, + unsigned short, ...); + +typedef void (ISC_EXPORT *isc_event_counts_t) (ISC_ULONG ISC_FAR *, + short, + char ISC_FAR *, + char ISC_FAR *); + +typedef void (ISC_EXPORT_VARARG *isc_expand_dpb_t) (char ISC_FAR * ISC_FAR *, + short ISC_FAR *, ...); + +typedef int (ISC_EXPORT *isc_modify_dpb_t) (char ISC_FAR * ISC_FAR *, + short ISC_FAR *, unsigned short, + char ISC_FAR *, short ); + +typedef ISC_LONG (ISC_EXPORT *isc_free_t) (char ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_get_segment_t) (ISC_STATUS ISC_FAR *, + isc_blob_handle ISC_FAR *, + unsigned short ISC_FAR *, + unsigned short, + char ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_get_slice_t) (ISC_STATUS ISC_FAR *, + isc_db_handle ISC_FAR *, + isc_tr_handle ISC_FAR *, + ISC_QUAD ISC_FAR *, + short, + char ISC_FAR *, + short, + ISC_LONG ISC_FAR *, + ISC_LONG, + void ISC_FAR *, + ISC_LONG ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_interprete_t) (char ISC_FAR *, + ISC_STATUS ISC_FAR * ISC_FAR *); + +/* Firebird safe string verison of isc_interprete */ +typedef ISC_STATUS (ISC_EXPORT *fb_interpret_t)(char ISC_FAR *, + unsigned int, + ISC_STATUS ISC_FAR * ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_open_blob_t) (ISC_STATUS ISC_FAR *, + isc_db_handle ISC_FAR *, + isc_tr_handle ISC_FAR *, + isc_blob_handle ISC_FAR *, + ISC_QUAD ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_open_blob2_t) (ISC_STATUS ISC_FAR *, + isc_db_handle ISC_FAR *, + isc_tr_handle ISC_FAR *, + isc_blob_handle ISC_FAR *, + ISC_QUAD ISC_FAR *, + short, + char ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_prepare_transaction2_t) (ISC_STATUS ISC_FAR *, + isc_tr_handle ISC_FAR *, + short, + char ISC_FAR *); + +typedef void (ISC_EXPORT *isc_print_sqlerror_t) (short, + ISC_STATUS ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_print_status_t) (ISC_STATUS ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_put_segment_t) (ISC_STATUS ISC_FAR *, + isc_blob_handle ISC_FAR *, + unsigned short, + char ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_put_slice_t) (ISC_STATUS ISC_FAR *, + isc_db_handle ISC_FAR *, + isc_tr_handle ISC_FAR *, + ISC_QUAD ISC_FAR *, + short, + char ISC_FAR *, + short, + ISC_LONG ISC_FAR *, + ISC_LONG, + void ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_que_events_t) (ISC_STATUS ISC_FAR *, + isc_db_handle ISC_FAR *, + ISC_LONG ISC_FAR *, + short, + char ISC_FAR *, + isc_callback, + void ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_rollback_transaction_t) (ISC_STATUS ISC_FAR *, + isc_tr_handle ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_start_multiple_t) (ISC_STATUS ISC_FAR *, + isc_tr_handle ISC_FAR *, + short, + void ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT_VARARG *isc_start_transaction_t) (ISC_STATUS ISC_FAR *, + isc_tr_handle ISC_FAR *, + short, ...); + +typedef ISC_LONG (ISC_EXPORT *isc_sqlcode_t) (ISC_STATUS ISC_FAR *); + +typedef void (ISC_EXPORT *isc_sql_interprete_t) (short, + char ISC_FAR *, + short); + +typedef ISC_STATUS (ISC_EXPORT *isc_transaction_info_t) (ISC_STATUS ISC_FAR *, + isc_tr_handle ISC_FAR *, + short, + char ISC_FAR *, + short, + char ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_transact_request_t) (ISC_STATUS ISC_FAR *, + isc_db_handle ISC_FAR *, + isc_tr_handle ISC_FAR *, + unsigned short, + char ISC_FAR *, + unsigned short, + char ISC_FAR *, + unsigned short, + char ISC_FAR *); + +typedef ISC_LONG (ISC_EXPORT *isc_vax_integer_t) (char ISC_FAR *, + short); + + +typedef int (ISC_EXPORT *isc_add_user_t) (ISC_STATUS ISC_FAR *, USER_SEC_DATA *); + +typedef int (ISC_EXPORT *isc_delete_user_t) (ISC_STATUS ISC_FAR *, USER_SEC_DATA *); + +typedef int (ISC_EXPORT *isc_modify_user_t) (ISC_STATUS ISC_FAR *, USER_SEC_DATA *); + + +typedef ISC_STATUS (ISC_EXPORT *isc_compile_request_t) (ISC_STATUS ISC_FAR *, + isc_db_handle ISC_FAR *, + isc_req_handle ISC_FAR *, + short, + char ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_compile_request2_t) (ISC_STATUS ISC_FAR *, + isc_db_handle ISC_FAR *, + isc_req_handle ISC_FAR *, + short, + char ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_ddl_t) (ISC_STATUS ISC_FAR *, + isc_db_handle ISC_FAR *, + isc_tr_handle ISC_FAR *, + short, + char ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_prepare_transaction_t) (ISC_STATUS ISC_FAR *, + isc_tr_handle ISC_FAR *); + + +typedef ISC_STATUS (ISC_EXPORT *isc_receive_t) (ISC_STATUS ISC_FAR *, + isc_req_handle ISC_FAR *, + short, + short, + void ISC_FAR *, + short); + +typedef ISC_STATUS (ISC_EXPORT *isc_reconnect_transaction_t) (ISC_STATUS ISC_FAR *, + isc_db_handle ISC_FAR *, + isc_tr_handle ISC_FAR *, + short, + char ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_release_request_t) (ISC_STATUS ISC_FAR *, + isc_req_handle ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_request_info_t) (ISC_STATUS ISC_FAR *, + isc_req_handle ISC_FAR *, + short, + short, + char ISC_FAR *, + short, + char ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_seek_blob_t) (ISC_STATUS ISC_FAR *, + isc_blob_handle ISC_FAR *, + short, + ISC_LONG, + ISC_LONG ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_send_t) (ISC_STATUS ISC_FAR *, + isc_req_handle ISC_FAR *, + short, + short, + void ISC_FAR *, + short); + +typedef ISC_STATUS (ISC_EXPORT *isc_start_and_send_t) (ISC_STATUS ISC_FAR *, + isc_req_handle ISC_FAR *, + isc_tr_handle ISC_FAR *, + short, + short, + void ISC_FAR *, + short); + +typedef ISC_STATUS (ISC_EXPORT *isc_start_request_t) (ISC_STATUS ISC_FAR *, + isc_req_handle ISC_FAR *, + isc_tr_handle ISC_FAR *, + short); + +typedef ISC_STATUS (ISC_EXPORT *isc_unwind_request_t) (ISC_STATUS ISC_FAR *, + isc_tr_handle ISC_FAR *, + short); + +typedef ISC_STATUS (ISC_EXPORT *isc_wait_for_event_t) (ISC_STATUS ISC_FAR *, + isc_db_handle ISC_FAR *, + short, + char ISC_FAR *, + char ISC_FAR *); + + +typedef ISC_STATUS (ISC_EXPORT *isc_close_t) (ISC_STATUS ISC_FAR *, + char ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_declare_t) (ISC_STATUS ISC_FAR *, + char ISC_FAR *, + char ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_execute_immediate_t) (ISC_STATUS ISC_FAR *, + isc_db_handle ISC_FAR *, + isc_tr_handle ISC_FAR *, + short ISC_FAR *, + char ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_dsql_execute_m_t) (ISC_STATUS ISC_FAR *, + isc_tr_handle ISC_FAR *, + isc_stmt_handle ISC_FAR *, + unsigned short, + char ISC_FAR *, + unsigned short, + unsigned short, + char ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_dsql_execute2_m_t) (ISC_STATUS ISC_FAR *, + isc_tr_handle ISC_FAR *, + isc_stmt_handle ISC_FAR *, + unsigned short, + char ISC_FAR *, + unsigned short, + unsigned short, + char ISC_FAR *, + unsigned short, + char ISC_FAR *, + unsigned short, + unsigned short, + char ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_dsql_execute_immediate_m_t) (ISC_STATUS ISC_FAR *, + isc_db_handle ISC_FAR *, + isc_tr_handle ISC_FAR *, + unsigned short, + char ISC_FAR *, + unsigned short, + unsigned short, + char ISC_FAR *, + unsigned short, + unsigned short, + char ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_dsql_exec_immed3_m_t) (ISC_STATUS ISC_FAR *, + isc_db_handle ISC_FAR *, + isc_tr_handle ISC_FAR *, + unsigned short, + char ISC_FAR *, + unsigned short, + unsigned short, + char ISC_FAR *, + unsigned short, + unsigned short, + char ISC_FAR *, + unsigned short, + char ISC_FAR *, + unsigned short, + unsigned short, + char ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_dsql_fetch_m_t) (ISC_STATUS ISC_FAR *, + isc_stmt_handle ISC_FAR *, + unsigned short, + char ISC_FAR *, + unsigned short, + unsigned short, + char ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_dsql_insert_m_t) (ISC_STATUS ISC_FAR *, + isc_stmt_handle ISC_FAR *, + unsigned short, + char ISC_FAR *, + unsigned short, + unsigned short, + char ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_dsql_prepare_m_t) (ISC_STATUS ISC_FAR *, + isc_tr_handle ISC_FAR *, + isc_stmt_handle ISC_FAR *, + unsigned short, + char ISC_FAR *, + unsigned short, + unsigned short, + char ISC_FAR *, + unsigned short, + char ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_dsql_release_t) (ISC_STATUS ISC_FAR *, + char ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_embed_dsql_close_t) (ISC_STATUS ISC_FAR *, + char ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_embed_dsql_declare_t) (ISC_STATUS ISC_FAR *, + char ISC_FAR *, + char ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_embed_dsql_describe_t) (ISC_STATUS ISC_FAR *, + char ISC_FAR *, + unsigned short, + XSQLDA ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_embed_dsql_describe_bind_t) (ISC_STATUS ISC_FAR *, + char ISC_FAR *, + unsigned short, + XSQLDA ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_embed_dsql_execute_t) (ISC_STATUS ISC_FAR *, + isc_tr_handle ISC_FAR *, + char ISC_FAR *, + unsigned short, + XSQLDA ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_embed_dsql_execute2_t) (ISC_STATUS ISC_FAR *, + isc_tr_handle ISC_FAR *, + char ISC_FAR *, + unsigned short, + XSQLDA ISC_FAR *, + XSQLDA ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_embed_dsql_execute_immed_t) (ISC_STATUS ISC_FAR *, + isc_db_handle ISC_FAR *, + isc_tr_handle ISC_FAR *, + unsigned short, + char ISC_FAR *, + unsigned short, + XSQLDA ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_embed_dsql_fetch_t) (ISC_STATUS ISC_FAR *, + char ISC_FAR *, + unsigned short, + XSQLDA ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_embed_dsql_open_t) (ISC_STATUS ISC_FAR *, + isc_tr_handle ISC_FAR *, + char ISC_FAR *, + unsigned short, + XSQLDA ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_embed_dsql_open2_t) (ISC_STATUS ISC_FAR *, + isc_tr_handle ISC_FAR *, + char ISC_FAR *, + unsigned short, + XSQLDA ISC_FAR *, + XSQLDA ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_embed_dsql_insert_t) (ISC_STATUS ISC_FAR *, + char ISC_FAR *, + unsigned short, + XSQLDA ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_embed_dsql_prepare_t) (ISC_STATUS ISC_FAR *, + isc_db_handle ISC_FAR *, + isc_tr_handle ISC_FAR *, + char ISC_FAR *, + unsigned short, + char ISC_FAR *, + unsigned short, + XSQLDA ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_embed_dsql_release_t) (ISC_STATUS ISC_FAR *, + char ISC_FAR *); + +typedef BSTREAM ISC_FAR * (ISC_EXPORT *BLOB_open_t) (isc_blob_handle, + char ISC_FAR *, + int); + +typedef int (ISC_EXPORT *BLOB_put_t) (char, + BSTREAM ISC_FAR *); + +typedef int (ISC_EXPORT *BLOB_close_t) (BSTREAM ISC_FAR *); + +typedef int (ISC_EXPORT *BLOB_get_t) (BSTREAM ISC_FAR *); + +typedef int (ISC_EXPORT *BLOB_display_t) (ISC_QUAD ISC_FAR *, + isc_db_handle, + isc_tr_handle, + char ISC_FAR *); + +typedef int (ISC_EXPORT *BLOB_dump_t) (ISC_QUAD ISC_FAR *, + isc_db_handle, + isc_tr_handle, + char ISC_FAR *); + +typedef int (ISC_EXPORT *BLOB_edit_t) (ISC_QUAD ISC_FAR *, + isc_db_handle, + isc_tr_handle, + char ISC_FAR *); + +typedef int (ISC_EXPORT *BLOB_load_t) (ISC_QUAD ISC_FAR *, + isc_db_handle, + isc_tr_handle, + char ISC_FAR *); + +typedef int (ISC_EXPORT *BLOB_text_dump_t) (ISC_QUAD ISC_FAR *, + isc_db_handle, + isc_tr_handle, + char ISC_FAR *); + +typedef int (ISC_EXPORT *BLOB_text_load_t) (ISC_QUAD ISC_FAR *, + isc_db_handle, + isc_tr_handle, + char ISC_FAR *); + +typedef BSTREAM ISC_FAR * (ISC_EXPORT *Bopen_t) (ISC_QUAD ISC_FAR *, + isc_db_handle, + isc_tr_handle, + char ISC_FAR *); + +typedef BSTREAM ISC_FAR * (ISC_EXPORT *Bopen2_t) (ISC_QUAD ISC_FAR *, + isc_db_handle, + isc_tr_handle, + char ISC_FAR *, + unsigned short); + + +typedef ISC_LONG (ISC_EXPORT *isc_ftof_t) (char ISC_FAR *, + unsigned short, + char ISC_FAR *, + unsigned short); + +typedef ISC_STATUS (ISC_EXPORT *isc_print_blr_t) (char ISC_FAR *, + isc_callback, + void ISC_FAR *, + short); + +typedef void (ISC_EXPORT *isc_set_debug_t) (int); + +typedef void (ISC_EXPORT *isc_qtoq_t) (ISC_QUAD ISC_FAR *, + ISC_QUAD ISC_FAR *); + +typedef void (ISC_EXPORT *isc_vtof_t) (char ISC_FAR *, + char ISC_FAR *, + unsigned short); + +typedef void (ISC_EXPORT *isc_vtov_t) (char ISC_FAR *, + char ISC_FAR *, + short); + +typedef int (ISC_EXPORT *isc_version_t) (isc_db_handle ISC_FAR *, + isc_callback, + void ISC_FAR *); + +typedef ISC_LONG (ISC_EXPORT *isc_reset_fpe_t) (unsigned short); + + +typedef ISC_STATUS (ISC_EXPORT *isc_attach_service_t) (ISC_STATUS ISC_FAR *, + unsigned short, + char ISC_FAR *, + isc_svc_handle ISC_FAR *, + unsigned short, + char ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_detach_service_t) (ISC_STATUS ISC_FAR *, + isc_svc_handle ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_query_service_t) (ISC_STATUS ISC_FAR *, + isc_svc_handle ISC_FAR *, + unsigned short, + char ISC_FAR *, + unsigned short, + char ISC_FAR *, + unsigned short, + char ISC_FAR *); + +/* InterBase API +typedef ISC_STATUS (ISC_EXPORT *isc_compile_map_t) (ISC_STATUS ISC_FAR *, + isc_form_handle ISC_FAR *, + isc_req_handle ISC_FAR *, + short ISC_FAR *, + char ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_compile_menu_t) (ISC_STATUS ISC_FAR *, + isc_form_handle ISC_FAR *, + isc_req_handle ISC_FAR *, + short ISC_FAR *, + char ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_compile_sub_map_t) (ISC_STATUS ISC_FAR *, + isc_win_handle ISC_FAR *, + isc_req_handle ISC_FAR *, + short ISC_FAR *, + char ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_create_window_t) (ISC_STATUS ISC_FAR *, + isc_win_handle ISC_FAR *, + short ISC_FAR *, + char ISC_FAR *, + short ISC_FAR *, + short ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_delete_window_t) (ISC_STATUS ISC_FAR *, + isc_win_handle ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_drive_form_t) (ISC_STATUS ISC_FAR *, + isc_db_handle ISC_FAR *, + isc_tr_handle ISC_FAR *, + isc_win_handle ISC_FAR *, + isc_req_handle ISC_FAR *, + unsigned char ISC_FAR *, + unsigned char ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_drive_menu_t) (ISC_STATUS ISC_FAR *, + isc_win_handle ISC_FAR *, + isc_req_handle ISC_FAR *, + short ISC_FAR *, + char ISC_FAR *, + short ISC_FAR *, + char ISC_FAR *, + short ISC_FAR *, + short ISC_FAR *, + char ISC_FAR *, + ISC_LONG ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_form_delete_t) (ISC_STATUS ISC_FAR *, + isc_form_handle ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_form_fetch_t) (ISC_STATUS ISC_FAR *, + isc_db_handle ISC_FAR *, + isc_tr_handle ISC_FAR *, + isc_req_handle ISC_FAR *, + unsigned char ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_form_insert_t) (ISC_STATUS ISC_FAR *, + isc_db_handle ISC_FAR *, + isc_tr_handle ISC_FAR *, + isc_req_handle ISC_FAR *, + unsigned char ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_get_entree_t) (ISC_STATUS ISC_FAR *, + isc_req_handle ISC_FAR *, + short ISC_FAR *, + char ISC_FAR *, + ISC_LONG ISC_FAR *, + short ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_initialize_menu_t) (ISC_STATUS ISC_FAR *, + isc_req_handle ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_menu_t) (ISC_STATUS ISC_FAR *, + isc_win_handle ISC_FAR *, + isc_req_handle ISC_FAR *, + short ISC_FAR *, + char ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_load_form_t) (ISC_STATUS ISC_FAR *, + isc_db_handle ISC_FAR *, + isc_tr_handle ISC_FAR *, + isc_form_handle ISC_FAR *, + short ISC_FAR *, + char ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_pop_window_t) (ISC_STATUS ISC_FAR *, + isc_win_handle ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_put_entree_t) (ISC_STATUS ISC_FAR *, + isc_req_handle ISC_FAR *, + short ISC_FAR *, + char ISC_FAR *, + ISC_LONG ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_reset_form_t) (ISC_STATUS ISC_FAR *, + isc_req_handle ISC_FAR *); + +typedef ISC_STATUS (ISC_EXPORT *isc_suspend_window_t) (ISC_STATUS ISC_FAR *, + isc_win_handle ISC_FAR *); +*/ + +// API declarations +class SQLAPI_API ibAPI : public saAPI +{ +public: + ibAPI(); + + isc_add_user_t isc_add_user; + isc_array_gen_sdl_t isc_array_gen_sdl; + isc_array_get_slice_t isc_array_get_slice; + isc_array_lookup_bounds_t isc_array_lookup_bounds; + isc_array_lookup_desc_t isc_array_lookup_desc; + isc_array_put_slice_t isc_array_put_slice; + isc_array_set_desc_t isc_array_set_desc; + isc_attach_database_t isc_attach_database; + isc_blob_default_desc_t isc_blob_default_desc; + isc_blob_gen_bpb_t isc_blob_gen_bpb; + isc_blob_info_t isc_blob_info; + isc_blob_lookup_desc_t isc_blob_lookup_desc; + isc_blob_set_desc_t isc_blob_set_desc; + isc_cancel_blob_t isc_cancel_blob; + isc_cancel_events_t isc_cancel_events; + isc_close_blob_t isc_close_blob; + isc_commit_retaining_t isc_commit_retaining; + isc_commit_transaction_t isc_commit_transaction; + isc_create_blob_t isc_create_blob; + isc_create_blob2_t isc_create_blob2; + isc_create_database_t isc_create_database; + isc_database_info_t isc_database_info; + isc_decode_date_t isc_decode_date; + isc_detach_database_t isc_detach_database; + isc_drop_database_t isc_drop_database; + isc_dsql_allocate_statement_t isc_dsql_allocate_statement; + isc_dsql_alloc_statement2_t isc_dsql_alloc_statement2; + isc_dsql_describe_t isc_dsql_describe; + isc_dsql_describe_bind_t isc_dsql_describe_bind; + isc_dsql_exec_immed2_t isc_dsql_exec_immed2; + isc_dsql_execute_t isc_dsql_execute; + isc_dsql_execute2_t isc_dsql_execute2; + isc_dsql_execute_immediate_t isc_dsql_execute_immediate; + isc_dsql_fetch_t isc_dsql_fetch; + isc_dsql_finish_t isc_dsql_finish; + isc_dsql_free_statement_t isc_dsql_free_statement; + isc_dsql_insert_t isc_dsql_insert; + isc_dsql_prepare_t isc_dsql_prepare; + isc_dsql_set_cursor_name_t isc_dsql_set_cursor_name; + isc_dsql_sql_info_t isc_dsql_sql_info; + isc_encode_date_t isc_encode_date; + isc_event_block_t isc_event_block; + isc_event_counts_t isc_event_counts; + isc_expand_dpb_t isc_expand_dpb; + isc_modify_dpb_t isc_modify_dpb; + isc_free_t isc_free; + isc_get_segment_t isc_get_segment; + isc_get_slice_t isc_get_slice; + isc_interprete_t isc_interprete; + isc_open_blob_t isc_open_blob; + isc_open_blob2_t isc_open_blob2; + isc_prepare_transaction2_t isc_prepare_transaction2; + isc_print_sqlerror_t isc_print_sqlerror; + isc_print_status_t isc_print_status; + isc_put_segment_t isc_put_segment; + isc_put_slice_t isc_put_slice; + isc_que_events_t isc_que_events; + isc_rollback_transaction_t isc_rollback_transaction; + isc_start_multiple_t isc_start_multiple; + isc_start_transaction_t isc_start_transaction; + isc_sqlcode_t isc_sqlcode; + isc_sql_interprete_t isc_sql_interprete; + isc_transaction_info_t isc_transaction_info; + isc_transact_request_t isc_transact_request; + isc_vax_integer_t isc_vax_integer; + isc_delete_user_t isc_delete_user; + isc_modify_user_t isc_modify_user; + isc_compile_request_t isc_compile_request; + isc_compile_request2_t isc_compile_request2; + isc_ddl_t isc_ddl; + isc_prepare_transaction_t isc_prepare_transaction; + isc_receive_t isc_receive; + isc_reconnect_transaction_t isc_reconnect_transaction; + isc_release_request_t isc_release_request; + isc_request_info_t isc_request_info; + isc_seek_blob_t isc_seek_blob; + isc_send_t isc_send; + isc_start_and_send_t isc_start_and_send; + isc_start_request_t isc_start_request; + isc_unwind_request_t isc_unwind_request; + isc_wait_for_event_t isc_wait_for_event; + isc_close_t isc_close; + isc_declare_t isc_declare; + isc_execute_immediate_t isc_execute_immediate; + isc_dsql_execute_m_t isc_dsql_execute_m; + isc_dsql_execute2_m_t isc_dsql_execute2_m; + isc_dsql_execute_immediate_m_t isc_dsql_execute_immediate_m; + isc_dsql_exec_immed3_m_t isc_dsql_exec_immed3_m; + isc_dsql_fetch_m_t isc_dsql_fetch_m; + isc_dsql_insert_m_t isc_dsql_insert_m; + isc_dsql_prepare_m_t isc_dsql_prepare_m; + isc_dsql_release_t isc_dsql_release; + isc_embed_dsql_close_t isc_embed_dsql_close; + isc_embed_dsql_declare_t isc_embed_dsql_declare; + isc_embed_dsql_describe_t isc_embed_dsql_describe; + isc_embed_dsql_describe_bind_t isc_embed_dsql_describe_bind; + isc_embed_dsql_execute_t isc_embed_dsql_execute; + isc_embed_dsql_execute2_t isc_embed_dsql_execute2; + isc_embed_dsql_execute_immed_t isc_embed_dsql_execute_immed; + isc_embed_dsql_fetch_t isc_embed_dsql_fetch; + isc_embed_dsql_open_t isc_embed_dsql_open; + isc_embed_dsql_open2_t isc_embed_dsql_open2; + isc_embed_dsql_insert_t isc_embed_dsql_insert; + isc_embed_dsql_prepare_t isc_embed_dsql_prepare; + isc_embed_dsql_release_t isc_embed_dsql_release; + isc_ftof_t isc_ftof; + isc_print_blr_t isc_print_blr; + isc_set_debug_t isc_set_debug; + isc_qtoq_t isc_qtoq; + isc_vtof_t isc_vtof; + isc_vtov_t isc_vtov; + isc_version_t isc_version; + fb_interpret_t fb_interpret; + +}; + +class SQLAPI_API ibConnectionHandles : public saConnectionHandles +{ +public: + ibConnectionHandles(); + + isc_db_handle m_db_handle; // Database handle + isc_tr_handle m_tr_handle; // Transaction handle +}; + +class SQLAPI_API ibCommandHandles : public saCommandHandles +{ +public: + ibCommandHandles(); + + isc_stmt_handle m_stmt_handle; +}; + +extern ibAPI g_ibAPI; + +#endif // !defined(__IBAPI_H__) diff --git a/libodbc/include/ibase/ib_util.h b/libodbc/include/ibase/ib_util.h new file mode 100644 index 0000000000..b6bafcfbc9 --- /dev/null +++ b/libodbc/include/ibase/ib_util.h @@ -0,0 +1,37 @@ +/* + * PROGRAM: UDF and Blob filter Utilities library + * MODULE: ib_util.h + * DESCRIPTION: Prototype header file for ib_util.c + * + * The contents of this file are subject to the Interbase Public + * License Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy + * of the License at http://www.Inprise.com/IPL.html + * + * Software distributed under the License is distributed on an + * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express + * or implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code was created by Inprise Corporation + * and its predecessors. Portions created by Inprise Corporation are + * Copyright (C) Inprise Corporation. + * + * All Rights Reserved. + * Contributor(s): ______________________________________. + */ + +#ifndef _IB_UTIL_H +#define _IB_UTIL_H + +#ifdef __cplusplus +extern "C" { +#endif + +extern void *ib_util_malloc(long); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* _IB_UTIL_H */ diff --git a/libodbc/include/ibase/ibase.h b/libodbc/include/ibase/ibase.h new file mode 100644 index 0000000000..1ff1342532 --- /dev/null +++ b/libodbc/include/ibase/ibase.h @@ -0,0 +1,2549 @@ +/* + * MODULE: ibase.h + * DESCRIPTION: OSRI entrypoints and defines + * + * The contents of this file are subject to the Interbase Public + * License Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy + * of the License at http://www.Inprise.com/IPL.html + * + * Software distributed under the License is distributed on an + * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express + * or implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code was created by Inprise Corporation + * and its predecessors. Portions created by Inprise Corporation are + * Copyright (C) Inprise Corporation. + * + * All Rights Reserved. + * Contributor(s): ______________________________________. + * + * 2001.07.28: John Bellardo: Added blr_skip + * 2001.09.18: Ann Harrison: New info codes + * 17-Oct-2001 Mike Nordell: CPU affinity + * 2001-04-16 Paul Beach: ISC_TIME_SECONDS_PRECISION_SCALE modified for HP10 + * Compiler Compatibility + * 2002.02.15 Sean Leyne - Code Cleanup, removed obsolete ports: + * - EPSON, XENIX, MAC (MAC_AUX), Cray and OS/2 + * 2002.10.29 Nickolay Samofatov: Added support for savepoints + * + * 2002.10.29 Sean Leyne - Removed support for obsolete IPX/SPX Protocol + * + * 2006.09.06 Steve Boyd - Added various prototypes required by Cobol ESQL + * isc_embed_dsql_length + * isc_event_block_a + * isc_sqlcode_s + * isc_embed_dsql_fetch_a + * isc_event_block_s + * isc_baddress + * isc_baddress_s + * + */ + +#ifndef JRD_IBASE_H +#define JRD_IBASE_H + +#define FB_API_VER 20 +#define isc_version4 + +#define ISC_TRUE 1 +#define ISC_FALSE 0 +#if !(defined __cplusplus) +#define ISC__TRUE ISC_TRUE +#define ISC__FALSE ISC_FALSE +#endif + +#define ISC_FAR + +#if defined _MSC_VER && _MSC_VER >= 1300 +#define FB_API_DEPRECATED __declspec(deprecated) +#elif defined __GNUC__ && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 2)) +#define FB_API_DEPRECATED __attribute__((__deprecated__)) +#else +#define FB_API_DEPRECATED +#endif + + +#ifndef INCLUDE_TYPES_PUB_H +#define INCLUDE_TYPES_PUB_H + +#include + +#if defined(__GNUC__) +#include +#else + +#if !defined(_INTPTR_T_DEFINED) +#if defined(_WIN64) +typedef __int64 intptr_t; +typedef unsigned __int64 uintptr_t; +#else +typedef long intptr_t; +typedef unsigned long uintptr_t; +#endif +#endif + +#endif + +#if defined(_LP64) || defined(__LP64__) || defined(__arch64__) || defined(_WIN64) +typedef unsigned int FB_API_HANDLE; +#else +typedef void* FB_API_HANDLE; +#endif + +typedef intptr_t ISC_STATUS; + +#define ISC_STATUS_LENGTH 20 +typedef ISC_STATUS ISC_STATUS_ARRAY[ISC_STATUS_LENGTH]; + +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) + #define ISC_EXPORT __stdcall + #define ISC_EXPORT_VARARG __cdecl +#else + #define ISC_EXPORT + #define ISC_EXPORT_VARARG +#endif + +#if defined(_LP64) || defined(__LP64__) || defined(__arch64__) +typedef int ISC_LONG; +typedef unsigned int ISC_ULONG; +#else +typedef signed long ISC_LONG; +typedef unsigned long ISC_ULONG; +#endif + +typedef signed short ISC_SHORT; +typedef unsigned short ISC_USHORT; + +typedef unsigned char ISC_UCHAR; +typedef char ISC_SCHAR; + +#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__)) && !defined(__GNUC__) +typedef __int64 ISC_INT64; +typedef unsigned __int64 ISC_UINT64; +#else +typedef long long int ISC_INT64; +typedef unsigned long long int ISC_UINT64; +#endif + +#ifndef ISC_TIMESTAMP_DEFINED +typedef int ISC_DATE; +typedef unsigned int ISC_TIME; +typedef struct +{ + ISC_DATE timestamp_date; + ISC_TIME timestamp_time; +} ISC_TIMESTAMP; +#define ISC_TIMESTAMP_DEFINED +#endif + +struct GDS_QUAD_t { + ISC_LONG gds_quad_high; + ISC_ULONG gds_quad_low; +}; + +typedef struct GDS_QUAD_t GDS_QUAD; +typedef struct GDS_QUAD_t ISC_QUAD; + +#define isc_quad_high gds_quad_high +#define isc_quad_low gds_quad_low + +#endif + +/********************************/ +/* Firebird Handle Definitions */ +/********************************/ + +typedef FB_API_HANDLE isc_att_handle; +typedef FB_API_HANDLE isc_blob_handle; +typedef FB_API_HANDLE isc_db_handle; +typedef FB_API_HANDLE isc_req_handle; +typedef FB_API_HANDLE isc_stmt_handle; +typedef FB_API_HANDLE isc_svc_handle; +typedef FB_API_HANDLE isc_tr_handle; +typedef void (* isc_callback) (); +typedef ISC_LONG isc_resv_handle; + +typedef void (*ISC_PRINT_CALLBACK) (void*, ISC_SHORT, const char*); +typedef void (*ISC_VERSION_CALLBACK)(void*, const char*); +typedef void (*ISC_EVENT_CALLBACK)(void*, ISC_USHORT, const ISC_UCHAR*); + +/*******************************************************************/ +/* Blob id structure */ +/*******************************************************************/ + +#if !(defined __cplusplus) +typedef GDS_QUAD GDS__QUAD; +#endif /* !(defined __cplusplus) */ + +typedef struct +{ + short array_bound_lower; + short array_bound_upper; +} ISC_ARRAY_BOUND; + +typedef struct +{ + ISC_UCHAR array_desc_dtype; + ISC_SCHAR array_desc_scale; + unsigned short array_desc_length; + ISC_SCHAR array_desc_field_name[32]; + ISC_SCHAR array_desc_relation_name[32]; + short array_desc_dimensions; + short array_desc_flags; + ISC_ARRAY_BOUND array_desc_bounds[16]; +} ISC_ARRAY_DESC; + +typedef struct +{ + short blob_desc_subtype; + short blob_desc_charset; + short blob_desc_segment_size; + ISC_UCHAR blob_desc_field_name[32]; + ISC_UCHAR blob_desc_relation_name[32]; +} ISC_BLOB_DESC; + +/***************************/ +/* Blob control structure */ +/***************************/ + +typedef struct isc_blob_ctl +{ + ISC_STATUS (* ctl_source)(); /* Source filter */ + struct isc_blob_ctl* ctl_source_handle; /* Argument to pass to source filter */ + short ctl_to_sub_type; /* Target type */ + short ctl_from_sub_type; /* Source type */ + unsigned short ctl_buffer_length; /* Length of buffer */ + unsigned short ctl_segment_length; /* Length of current segment */ + unsigned short ctl_bpb_length; /* Length of blob parameter block */ + /* Internally, this is const UCHAR*, but this public struct probably can't change. */ + ISC_SCHAR* ctl_bpb; /* Address of blob parameter block */ + ISC_UCHAR* ctl_buffer; /* Address of segment buffer */ + ISC_LONG ctl_max_segment; /* Length of longest segment */ + ISC_LONG ctl_number_segments; /* Total number of segments */ + ISC_LONG ctl_total_length; /* Total length of blob */ + ISC_STATUS* ctl_status; /* Address of status vector */ + long ctl_data[8]; /* Application specific data */ +} * ISC_BLOB_CTL; + +/***************************/ +/* Blob stream definitions */ +/***************************/ + +typedef struct bstream +{ + isc_blob_handle bstr_blob; /* Blob handle */ + ISC_SCHAR * bstr_buffer; /* Address of buffer */ + ISC_SCHAR * bstr_ptr; /* Next character */ + short bstr_length; /* Length of buffer */ + short bstr_cnt; /* Characters in buffer */ + char bstr_mode; /* (mode) ? OUTPUT : INPUT */ +} BSTREAM; + +/* Three ugly macros, one even using octal radix... sigh... */ +#define getb(p) (--(p)->bstr_cnt >= 0 ? *(p)->bstr_ptr++ & 0377: BLOB_get (p)) +#define putb(x,p) (((x) == '\n' || (!(--(p)->bstr_cnt))) ? BLOB_put ((x),p) : ((int) (*(p)->bstr_ptr++ = (unsigned) (x)))) +#define putbx(x,p) ((!(--(p)->bstr_cnt)) ? BLOB_put ((x),p) : ((int) (*(p)->bstr_ptr++ = (unsigned) (x)))) + +/********************************************************************/ +/* CVC: Public blob interface definition held in val.h. */ +/* For some unknown reason, it was only documented in langRef */ +/* and being the structure passed by the engine to UDFs it never */ +/* made its way into this public definitions file. */ +/* Being its original name "blob", I renamed it blobcallback here. */ +/* I did the full definition with the proper parameters instead of */ +/* the weak C declaration with any number and type of parameters. */ +/* Since the first parameter -BLB- is unknown outside the engine, */ +/* it's more accurate to use void* than int* as the blob pointer */ +/********************************************************************/ + +#if !defined(JRD_VAL_H) && !defined(REQUESTER) +/* Blob passing structure */ + +/* This enum applies to parameter "mode" in blob_lseek */ +enum blob_lseek_mode {blb_seek_relative = 1, blb_seek_from_tail = 2}; +/* This enum applies to the value returned by blob_get_segment */ +enum blob_get_result {blb_got_fragment = -1, blb_got_eof = 0, blb_got_full_segment = 1}; + +typedef struct blobcallback { + short (*blob_get_segment) + (void* hnd, ISC_UCHAR* buffer, ISC_USHORT buf_size, ISC_USHORT* result_len); + void* blob_handle; + ISC_LONG blob_number_segments; + ISC_LONG blob_max_segment; + ISC_LONG blob_total_length; + void (*blob_put_segment) + (void* hnd, const ISC_UCHAR* buffer, ISC_USHORT buf_size); + ISC_LONG (*blob_lseek) + (void* hnd, ISC_USHORT mode, ISC_LONG offset); +} *BLOBCALLBACK; +#endif /* !defined(JRD_VAL_H) && !defined(REQUESTER) */ + + +/********************************************************************/ +/* CVC: Public descriptor interface held in dsc2.h. */ +/* We need it documented to be able to recognize NULL in UDFs. */ +/* Being its original name "dsc", I renamed it paramdsc here. */ +/* Notice that I adjust to the original definition: contrary to */ +/* other cases, the typedef is the same struct not the pointer. */ +/* I included the enumeration of dsc_dtype possible values. */ +/* Ultimately, dsc2.h should be part of the public interface. */ +/********************************************************************/ + +#if !defined(JRD_DSC_H) +/* This is the famous internal descriptor that UDFs can use, too. */ +typedef struct paramdsc { + ISC_UCHAR dsc_dtype; + signed char dsc_scale; + ISC_USHORT dsc_length; + short dsc_sub_type; + ISC_USHORT dsc_flags; + ISC_UCHAR *dsc_address; +} PARAMDSC; + +#if !defined(JRD_VAL_H) +/* This is a helper struct to work with varchars. */ +typedef struct paramvary { + ISC_USHORT vary_length; + ISC_UCHAR vary_string[1]; +} PARAMVARY; +#endif /* !defined(JRD_VAL_H) */ + + +#ifndef JRD_DSC_PUB_H +#define JRD_DSC_PUB_H + +#define DSC_null 1 +#define DSC_no_subtype 2 +#define DSC_nullable 4 + +#define dtype_unknown 0 +#define dtype_text 1 +#define dtype_cstring 2 +#define dtype_varying 3 + +#define dtype_packed 6 +#define dtype_byte 7 +#define dtype_short 8 +#define dtype_long 9 +#define dtype_quad 10 +#define dtype_real 11 +#define dtype_double 12 +#define dtype_d_float 13 +#define dtype_sql_date 14 +#define dtype_sql_time 15 +#define dtype_timestamp 16 +#define dtype_blob 17 +#define dtype_array 18 +#define dtype_int64 19 +#define DTYPE_TYPE_MAX 20 + +#define ISC_TIME_SECONDS_PRECISION 10000 +#define ISC_TIME_SECONDS_PRECISION_SCALE (-4) + +#endif + + +#endif /* !defined(JRD_DSC_H) */ + +/***************************/ +/* Dynamic SQL definitions */ +/***************************/ + + +#ifndef DSQL_SQLDA_PUB_H +#define DSQL_SQLDA_PUB_H + +#define DSQL_close 1 +#define DSQL_drop 2 + +typedef struct +{ + ISC_SHORT sqltype; + ISC_SHORT sqlscale; + ISC_SHORT sqlsubtype; + ISC_SHORT sqllen; + ISC_SCHAR* sqldata; + ISC_SHORT* sqlind; + ISC_SHORT sqlname_length; + ISC_SCHAR sqlname[32]; + ISC_SHORT relname_length; + ISC_SCHAR relname[32]; + ISC_SHORT ownname_length; + ISC_SCHAR ownname[32]; + ISC_SHORT aliasname_length; + ISC_SCHAR aliasname[32]; +} XSQLVAR; + +#define SQLDA_VERSION1 1 + +typedef struct +{ + ISC_SHORT version; + ISC_SCHAR sqldaid[8]; + ISC_LONG sqldabc; + ISC_SHORT sqln; + ISC_SHORT sqld; + XSQLVAR sqlvar[1]; +} XSQLDA; + +#define XSQLDA_LENGTH(n) (sizeof (XSQLDA) + (n - 1) * sizeof (XSQLVAR)) + +#define SQL_TEXT 452 +#define SQL_VARYING 448 +#define SQL_SHORT 500 +#define SQL_LONG 496 +#define SQL_FLOAT 482 +#define SQL_DOUBLE 480 +#define SQL_D_FLOAT 530 +#define SQL_TIMESTAMP 510 +#define SQL_BLOB 520 +#define SQL_ARRAY 540 +#define SQL_QUAD 550 +#define SQL_TYPE_TIME 560 +#define SQL_TYPE_DATE 570 +#define SQL_INT64 580 + +#define SQL_DATE SQL_TIMESTAMP + +#define SQL_DIALECT_V5 1 +#define SQL_DIALECT_V6_TRANSITION 2 +#define SQL_DIALECT_V6 3 +#define SQL_DIALECT_CURRENT SQL_DIALECT_V6 + +#endif + + +/***************************/ +/* OSRI database functions */ +/***************************/ + +#ifdef __cplusplus +extern "C" { +#endif + +ISC_STATUS ISC_EXPORT isc_attach_database(ISC_STATUS*, + short, + const ISC_SCHAR*, + isc_db_handle*, + short, + const ISC_SCHAR*); + +ISC_STATUS ISC_EXPORT isc_array_gen_sdl(ISC_STATUS*, + const ISC_ARRAY_DESC*, + ISC_SHORT*, + ISC_UCHAR*, + ISC_SHORT*); + +ISC_STATUS ISC_EXPORT isc_array_get_slice(ISC_STATUS*, + isc_db_handle*, + isc_tr_handle*, + ISC_QUAD*, + const ISC_ARRAY_DESC*, + void*, + ISC_LONG*); + +ISC_STATUS ISC_EXPORT isc_array_lookup_bounds(ISC_STATUS*, + isc_db_handle*, + isc_tr_handle*, + const ISC_SCHAR*, + const ISC_SCHAR*, + ISC_ARRAY_DESC*); + +ISC_STATUS ISC_EXPORT isc_array_lookup_desc(ISC_STATUS*, + isc_db_handle*, + isc_tr_handle*, + const ISC_SCHAR*, + const ISC_SCHAR*, + ISC_ARRAY_DESC*); + +ISC_STATUS ISC_EXPORT isc_array_set_desc(ISC_STATUS*, + const ISC_SCHAR*, + const ISC_SCHAR*, + const short*, + const short*, + const short*, + ISC_ARRAY_DESC*); + +ISC_STATUS ISC_EXPORT isc_array_put_slice(ISC_STATUS*, + isc_db_handle*, + isc_tr_handle*, + ISC_QUAD*, + const ISC_ARRAY_DESC*, + void*, + ISC_LONG *); + +void ISC_EXPORT isc_blob_default_desc(ISC_BLOB_DESC*, + const ISC_UCHAR*, + const ISC_UCHAR*); + +ISC_STATUS ISC_EXPORT isc_blob_gen_bpb(ISC_STATUS*, + const ISC_BLOB_DESC*, + const ISC_BLOB_DESC*, + unsigned short, + ISC_UCHAR*, + unsigned short*); + +ISC_STATUS ISC_EXPORT isc_blob_info(ISC_STATUS*, + isc_blob_handle*, + short, + const ISC_SCHAR*, + short, + ISC_SCHAR*); + +ISC_STATUS ISC_EXPORT isc_blob_lookup_desc(ISC_STATUS*, + isc_db_handle*, + isc_tr_handle*, + const ISC_UCHAR*, + const ISC_UCHAR*, + ISC_BLOB_DESC*, + ISC_UCHAR*); + +ISC_STATUS ISC_EXPORT isc_blob_set_desc(ISC_STATUS*, + const ISC_UCHAR*, + const ISC_UCHAR*, + short, + short, + short, + ISC_BLOB_DESC*); + +ISC_STATUS ISC_EXPORT isc_cancel_blob(ISC_STATUS *, + isc_blob_handle *); + +ISC_STATUS ISC_EXPORT isc_cancel_events(ISC_STATUS *, + isc_db_handle *, + ISC_LONG *); + +ISC_STATUS ISC_EXPORT isc_close_blob(ISC_STATUS *, + isc_blob_handle *); + +ISC_STATUS ISC_EXPORT isc_commit_retaining(ISC_STATUS *, + isc_tr_handle *); + +ISC_STATUS ISC_EXPORT isc_commit_transaction(ISC_STATUS *, + isc_tr_handle *); + +ISC_STATUS ISC_EXPORT isc_create_blob(ISC_STATUS*, + isc_db_handle*, + isc_tr_handle*, + isc_blob_handle*, + ISC_QUAD*); + +ISC_STATUS ISC_EXPORT isc_create_blob2(ISC_STATUS*, + isc_db_handle*, + isc_tr_handle*, + isc_blob_handle*, + ISC_QUAD*, + short, + const ISC_SCHAR*); + +ISC_STATUS ISC_EXPORT isc_create_database(ISC_STATUS*, + short, + const ISC_SCHAR*, + isc_db_handle*, + short, + const ISC_SCHAR*, + short); + +ISC_STATUS ISC_EXPORT isc_database_info(ISC_STATUS*, + isc_db_handle*, + short, + const ISC_SCHAR*, + short, + ISC_SCHAR*); + +void ISC_EXPORT isc_decode_date(const ISC_QUAD*, + void*); + +void ISC_EXPORT isc_decode_sql_date(const ISC_DATE*, + void*); + +void ISC_EXPORT isc_decode_sql_time(const ISC_TIME*, + void*); + +void ISC_EXPORT isc_decode_timestamp(const ISC_TIMESTAMP*, + void*); + +ISC_STATUS ISC_EXPORT isc_detach_database(ISC_STATUS *, + isc_db_handle *); + +ISC_STATUS ISC_EXPORT isc_drop_database(ISC_STATUS *, + isc_db_handle *); + +ISC_STATUS ISC_EXPORT isc_dsql_allocate_statement(ISC_STATUS *, + isc_db_handle *, + isc_stmt_handle *); + +ISC_STATUS ISC_EXPORT isc_dsql_alloc_statement2(ISC_STATUS *, + isc_db_handle *, + isc_stmt_handle *); + +ISC_STATUS ISC_EXPORT isc_dsql_describe(ISC_STATUS *, + isc_stmt_handle *, + unsigned short, + XSQLDA *); + +ISC_STATUS ISC_EXPORT isc_dsql_describe_bind(ISC_STATUS *, + isc_stmt_handle *, + unsigned short, + XSQLDA *); + +ISC_STATUS ISC_EXPORT isc_dsql_exec_immed2(ISC_STATUS*, + isc_db_handle*, + isc_tr_handle*, + unsigned short, + const ISC_SCHAR*, + unsigned short, + XSQLDA*, + XSQLDA*); + +ISC_STATUS ISC_EXPORT isc_dsql_execute(ISC_STATUS*, + isc_tr_handle*, + isc_stmt_handle*, + unsigned short, + XSQLDA*); + +ISC_STATUS ISC_EXPORT isc_dsql_execute2(ISC_STATUS*, + isc_tr_handle*, + isc_stmt_handle*, + unsigned short, + XSQLDA*, + XSQLDA*); + +ISC_STATUS ISC_EXPORT isc_dsql_execute_immediate(ISC_STATUS*, + isc_db_handle*, + isc_tr_handle*, + unsigned short, + const ISC_SCHAR*, + unsigned short, + XSQLDA*); + +ISC_STATUS ISC_EXPORT isc_dsql_fetch(ISC_STATUS *, + isc_stmt_handle *, + unsigned short, + XSQLDA *); + +ISC_STATUS ISC_EXPORT isc_dsql_finish(isc_db_handle *); + +ISC_STATUS ISC_EXPORT isc_dsql_free_statement(ISC_STATUS *, + isc_stmt_handle *, + unsigned short); + +ISC_STATUS ISC_EXPORT isc_dsql_insert(ISC_STATUS*, + isc_stmt_handle*, + unsigned short, + XSQLDA*); + +ISC_STATUS ISC_EXPORT isc_dsql_prepare(ISC_STATUS*, + isc_tr_handle*, + isc_stmt_handle*, + unsigned short, + const ISC_SCHAR*, + unsigned short, + XSQLDA*); + +ISC_STATUS ISC_EXPORT isc_dsql_set_cursor_name(ISC_STATUS*, + isc_stmt_handle*, + const ISC_SCHAR*, + unsigned short); + +ISC_STATUS ISC_EXPORT isc_dsql_sql_info(ISC_STATUS*, + isc_stmt_handle*, + short, + const ISC_SCHAR*, + short, + ISC_SCHAR*); + +void ISC_EXPORT isc_encode_date(const void*, + ISC_QUAD*); + +void ISC_EXPORT isc_encode_sql_date(const void*, + ISC_DATE*); + +void ISC_EXPORT isc_encode_sql_time(const void*, + ISC_TIME*); + +void ISC_EXPORT isc_encode_timestamp(const void*, + ISC_TIMESTAMP*); + +ISC_LONG ISC_EXPORT_VARARG isc_event_block(ISC_UCHAR**, + ISC_UCHAR**, + ISC_USHORT, ...); + +ISC_USHORT ISC_EXPORT isc_event_block_a(ISC_SCHAR**, + ISC_SCHAR**, + ISC_USHORT, + ISC_SCHAR**); + +void ISC_EXPORT isc_event_block_s(ISC_SCHAR**, + ISC_SCHAR**, + ISC_USHORT, + ISC_SCHAR**, + ISC_USHORT*); + +void ISC_EXPORT isc_event_counts(ISC_ULONG*, + short, + ISC_UCHAR*, + const ISC_UCHAR *); + +/* 17 May 2001 - isc_expand_dpb is DEPRECATED */ +void FB_API_DEPRECATED ISC_EXPORT_VARARG isc_expand_dpb(ISC_SCHAR**, + short*, ...); + +int ISC_EXPORT isc_modify_dpb(ISC_SCHAR**, + short*, + unsigned short, + const ISC_SCHAR*, + short); + +ISC_LONG ISC_EXPORT isc_free(ISC_SCHAR *); + +ISC_STATUS ISC_EXPORT isc_get_segment(ISC_STATUS *, + isc_blob_handle *, + unsigned short *, + unsigned short, + ISC_SCHAR *); + +ISC_STATUS ISC_EXPORT isc_get_slice(ISC_STATUS*, + isc_db_handle*, + isc_tr_handle*, + ISC_QUAD*, + short, + const ISC_SCHAR*, + short, + const ISC_LONG*, + ISC_LONG, + void*, + ISC_LONG*); + +/* CVC: This non-const signature is needed for compatibility, see gds.cpp. */ +ISC_LONG FB_API_DEPRECATED ISC_EXPORT isc_interprete(ISC_SCHAR*, + ISC_STATUS**); + +/* This const params version used in the engine and other places. */ +ISC_LONG ISC_EXPORT fb_interpret(ISC_SCHAR*, + unsigned int, + const ISC_STATUS**); + +ISC_STATUS ISC_EXPORT isc_open_blob(ISC_STATUS*, + isc_db_handle*, + isc_tr_handle*, + isc_blob_handle*, + ISC_QUAD*); + +ISC_STATUS ISC_EXPORT isc_open_blob2(ISC_STATUS*, + isc_db_handle*, + isc_tr_handle*, + isc_blob_handle*, + ISC_QUAD*, + ISC_USHORT, + const ISC_UCHAR*); + +ISC_STATUS ISC_EXPORT isc_prepare_transaction2(ISC_STATUS*, + isc_tr_handle*, + ISC_USHORT, + const ISC_UCHAR*); + +void ISC_EXPORT isc_print_sqlerror(ISC_SHORT, + const ISC_STATUS*); + +ISC_STATUS ISC_EXPORT isc_print_status(const ISC_STATUS*); + +ISC_STATUS ISC_EXPORT isc_put_segment(ISC_STATUS*, + isc_blob_handle*, + unsigned short, + const ISC_SCHAR*); + +ISC_STATUS ISC_EXPORT isc_put_slice(ISC_STATUS*, + isc_db_handle*, + isc_tr_handle*, + ISC_QUAD*, + short, + const ISC_SCHAR*, + short, + const ISC_LONG*, + ISC_LONG, + void*); + +ISC_STATUS ISC_EXPORT isc_que_events(ISC_STATUS*, + isc_db_handle*, + ISC_LONG*, + short, + const ISC_UCHAR*, + ISC_EVENT_CALLBACK, + void*); + +ISC_STATUS ISC_EXPORT isc_rollback_retaining(ISC_STATUS *, + isc_tr_handle *); + +ISC_STATUS ISC_EXPORT isc_rollback_transaction(ISC_STATUS *, + isc_tr_handle *); + +ISC_STATUS ISC_EXPORT isc_start_multiple(ISC_STATUS *, + isc_tr_handle *, + short, + void *); + +ISC_STATUS ISC_EXPORT_VARARG isc_start_transaction(ISC_STATUS *, + isc_tr_handle *, + short, ...); + +ISC_LONG ISC_EXPORT isc_sqlcode(const ISC_STATUS*); + +void ISC_EXPORT isc_sqlcode_s(const ISC_STATUS*, + ISC_ULONG*); + +void ISC_EXPORT isc_sql_interprete(short, + ISC_SCHAR*, + short); + +ISC_STATUS ISC_EXPORT isc_transaction_info(ISC_STATUS*, + isc_tr_handle*, + short, + const ISC_SCHAR*, + short, + ISC_SCHAR*); + +ISC_STATUS ISC_EXPORT isc_transact_request(ISC_STATUS*, + isc_db_handle*, + isc_tr_handle*, + unsigned short, + const ISC_SCHAR*, + unsigned short, + ISC_SCHAR*, + unsigned short, + ISC_SCHAR*); + +ISC_LONG ISC_EXPORT isc_vax_integer(const ISC_SCHAR*, + short); + +ISC_INT64 ISC_EXPORT isc_portable_integer(const ISC_UCHAR*, + short); + +/*************************************/ +/* Security Functions and structures */ +/*************************************/ + +#define sec_uid_spec 0x01 +#define sec_gid_spec 0x02 +#define sec_server_spec 0x04 +#define sec_password_spec 0x08 +#define sec_group_name_spec 0x10 +#define sec_first_name_spec 0x20 +#define sec_middle_name_spec 0x40 +#define sec_last_name_spec 0x80 +#define sec_dba_user_name_spec 0x100 +#define sec_dba_password_spec 0x200 + +#define sec_protocol_tcpip 1 +#define sec_protocol_netbeui 2 +#define sec_protocol_spx 3 /* -- Deprecated Protocol. Declaration retained for compatibility */ +#define sec_protocol_local 4 + +typedef struct { + short sec_flags; /* which fields are specified */ + int uid; /* the user's id */ + int gid; /* the user's group id */ + int protocol; /* protocol to use for connection */ + ISC_SCHAR *server; /* server to administer */ + ISC_SCHAR *user_name; /* the user's name */ + ISC_SCHAR *password; /* the user's password */ + ISC_SCHAR *group_name; /* the group name */ + ISC_SCHAR *first_name; /* the user's first name */ + ISC_SCHAR *middle_name; /* the user's middle name */ + ISC_SCHAR *last_name; /* the user's last name */ + ISC_SCHAR *dba_user_name; /* the dba user name */ + ISC_SCHAR *dba_password; /* the dba password */ +} USER_SEC_DATA; + +ISC_STATUS ISC_EXPORT isc_add_user(ISC_STATUS*, const USER_SEC_DATA*); + +ISC_STATUS ISC_EXPORT isc_delete_user(ISC_STATUS*, const USER_SEC_DATA*); + +ISC_STATUS ISC_EXPORT isc_modify_user(ISC_STATUS*, const USER_SEC_DATA*); + +/**********************************/ +/* Other OSRI functions */ +/**********************************/ + +ISC_STATUS ISC_EXPORT isc_compile_request(ISC_STATUS*, + isc_db_handle*, + isc_req_handle*, + short, + const ISC_SCHAR*); + +ISC_STATUS ISC_EXPORT isc_compile_request2(ISC_STATUS*, + isc_db_handle*, + isc_req_handle*, + short, + const ISC_SCHAR*); + +ISC_STATUS ISC_EXPORT isc_ddl(ISC_STATUS*, + isc_db_handle*, + isc_tr_handle*, + short, + const ISC_SCHAR*); + +ISC_STATUS ISC_EXPORT isc_prepare_transaction(ISC_STATUS*, + isc_tr_handle*); + + +ISC_STATUS ISC_EXPORT isc_receive(ISC_STATUS*, + isc_req_handle*, + short, + short, + void*, + short); + +ISC_STATUS ISC_EXPORT isc_reconnect_transaction(ISC_STATUS*, + isc_db_handle*, + isc_tr_handle*, + short, + const ISC_SCHAR*); + +ISC_STATUS ISC_EXPORT isc_release_request(ISC_STATUS*, + isc_req_handle*); + +ISC_STATUS ISC_EXPORT isc_request_info(ISC_STATUS*, + isc_req_handle*, + short, + short, + const ISC_SCHAR*, + short, + ISC_SCHAR*); + +ISC_STATUS ISC_EXPORT isc_seek_blob(ISC_STATUS*, + isc_blob_handle*, + short, + ISC_LONG, + ISC_LONG*); + +ISC_STATUS ISC_EXPORT isc_send(ISC_STATUS*, + isc_req_handle*, + short, + short, + const void*, + short); + +ISC_STATUS ISC_EXPORT isc_start_and_send(ISC_STATUS*, + isc_req_handle*, + isc_tr_handle*, + short, + short, + const void*, + short); + +ISC_STATUS ISC_EXPORT isc_start_request(ISC_STATUS *, + isc_req_handle *, + isc_tr_handle *, + short); + +ISC_STATUS ISC_EXPORT isc_unwind_request(ISC_STATUS *, + isc_tr_handle *, + short); + +ISC_STATUS ISC_EXPORT isc_wait_for_event(ISC_STATUS*, + isc_db_handle*, + short, + const ISC_UCHAR*, + ISC_UCHAR*); + + +/*****************************/ +/* Other Sql functions */ +/*****************************/ + +ISC_STATUS ISC_EXPORT isc_close(ISC_STATUS*, + const ISC_SCHAR*); + +ISC_STATUS ISC_EXPORT isc_declare(ISC_STATUS*, + const ISC_SCHAR*, + const ISC_SCHAR*); + +ISC_STATUS ISC_EXPORT isc_describe(ISC_STATUS*, + const ISC_SCHAR*, + XSQLDA *); + +ISC_STATUS ISC_EXPORT isc_describe_bind(ISC_STATUS*, + const ISC_SCHAR*, + XSQLDA*); + +ISC_STATUS ISC_EXPORT isc_execute(ISC_STATUS*, + isc_tr_handle*, + const ISC_SCHAR*, + XSQLDA*); + +ISC_STATUS ISC_EXPORT isc_execute_immediate(ISC_STATUS*, + isc_db_handle*, + isc_tr_handle*, + short*, + const ISC_SCHAR*); + +ISC_STATUS ISC_EXPORT isc_fetch(ISC_STATUS*, + const ISC_SCHAR*, + XSQLDA*); + +ISC_STATUS ISC_EXPORT isc_open(ISC_STATUS*, + isc_tr_handle*, + const ISC_SCHAR*, + XSQLDA*); + +ISC_STATUS ISC_EXPORT isc_prepare(ISC_STATUS*, + isc_db_handle*, + isc_tr_handle*, + const ISC_SCHAR*, + short*, + const ISC_SCHAR*, + XSQLDA*); + + +/*************************************/ +/* Other Dynamic sql functions */ +/*************************************/ + +ISC_STATUS ISC_EXPORT isc_dsql_execute_m(ISC_STATUS*, + isc_tr_handle*, + isc_stmt_handle*, + unsigned short, + const ISC_SCHAR*, + unsigned short, + unsigned short, + ISC_SCHAR*); + +ISC_STATUS ISC_EXPORT isc_dsql_execute2_m(ISC_STATUS*, + isc_tr_handle*, + isc_stmt_handle*, + unsigned short, + const ISC_SCHAR*, + unsigned short, + unsigned short, + const ISC_SCHAR*, + unsigned short, + ISC_SCHAR*, + unsigned short, + unsigned short, + ISC_SCHAR*); + +ISC_STATUS ISC_EXPORT isc_dsql_execute_immediate_m(ISC_STATUS*, + isc_db_handle*, + isc_tr_handle*, + unsigned short, + const ISC_SCHAR*, + unsigned short, + unsigned short, + const ISC_SCHAR*, + unsigned short, + unsigned short, + ISC_SCHAR*); + +ISC_STATUS ISC_EXPORT isc_dsql_exec_immed3_m(ISC_STATUS*, + isc_db_handle*, + isc_tr_handle*, + unsigned short, + const ISC_SCHAR*, + unsigned short, + unsigned short, + const ISC_SCHAR*, + unsigned short, + unsigned short, + ISC_SCHAR*, + unsigned short, + ISC_SCHAR*, + unsigned short, + unsigned short, + ISC_SCHAR*); + +ISC_STATUS ISC_EXPORT isc_dsql_fetch_m(ISC_STATUS*, + isc_stmt_handle*, + unsigned short, + const ISC_SCHAR*, + unsigned short, + unsigned short, + ISC_SCHAR*); + +ISC_STATUS ISC_EXPORT isc_dsql_insert_m(ISC_STATUS*, + isc_stmt_handle*, + unsigned short, + const ISC_SCHAR*, + unsigned short, + unsigned short, + const ISC_SCHAR*); + +ISC_STATUS ISC_EXPORT isc_dsql_prepare_m(ISC_STATUS*, + isc_tr_handle*, + isc_stmt_handle*, + unsigned short, + const ISC_SCHAR*, + unsigned short, + unsigned short, + const ISC_SCHAR*, + unsigned short, + ISC_SCHAR*); + +ISC_STATUS ISC_EXPORT isc_dsql_release(ISC_STATUS*, + const ISC_SCHAR*); + +ISC_STATUS ISC_EXPORT isc_embed_dsql_close(ISC_STATUS*, + const ISC_SCHAR*); + +ISC_STATUS ISC_EXPORT isc_embed_dsql_declare(ISC_STATUS*, + const ISC_SCHAR*, + const ISC_SCHAR*); + +ISC_STATUS ISC_EXPORT isc_embed_dsql_describe(ISC_STATUS*, + const ISC_SCHAR*, + unsigned short, + XSQLDA*); + +ISC_STATUS ISC_EXPORT isc_embed_dsql_describe_bind(ISC_STATUS*, + const ISC_SCHAR*, + unsigned short, + XSQLDA*); + +ISC_STATUS ISC_EXPORT isc_embed_dsql_execute(ISC_STATUS*, + isc_tr_handle*, + const ISC_SCHAR*, + unsigned short, + XSQLDA*); + +ISC_STATUS ISC_EXPORT isc_embed_dsql_execute2(ISC_STATUS*, + isc_tr_handle*, + const ISC_SCHAR*, + unsigned short, + XSQLDA*, + XSQLDA*); + +ISC_STATUS ISC_EXPORT isc_embed_dsql_execute_immed(ISC_STATUS*, + isc_db_handle*, + isc_tr_handle*, + unsigned short, + const ISC_SCHAR*, + unsigned short, + XSQLDA*); + +ISC_STATUS ISC_EXPORT isc_embed_dsql_fetch(ISC_STATUS*, + const ISC_SCHAR*, + unsigned short, + XSQLDA*); + +ISC_STATUS ISC_EXPORT isc_embed_dsql_fetch_a(ISC_STATUS*, + int*, + const ISC_SCHAR*, + ISC_USHORT, + XSQLDA*); + +void ISC_EXPORT isc_embed_dsql_length(const ISC_UCHAR*, + ISC_USHORT*); + +ISC_STATUS ISC_EXPORT isc_embed_dsql_open(ISC_STATUS*, + isc_tr_handle*, + const ISC_SCHAR*, + unsigned short, + XSQLDA*); + +ISC_STATUS ISC_EXPORT isc_embed_dsql_open2(ISC_STATUS*, + isc_tr_handle*, + const ISC_SCHAR*, + unsigned short, + XSQLDA*, + XSQLDA*); + +ISC_STATUS ISC_EXPORT isc_embed_dsql_insert(ISC_STATUS*, + const ISC_SCHAR*, + unsigned short, + XSQLDA*); + +ISC_STATUS ISC_EXPORT isc_embed_dsql_prepare(ISC_STATUS*, + isc_db_handle*, + isc_tr_handle*, + const ISC_SCHAR*, + unsigned short, + const ISC_SCHAR*, + unsigned short, + XSQLDA*); + +ISC_STATUS ISC_EXPORT isc_embed_dsql_release(ISC_STATUS*, + const ISC_SCHAR*); + + +/******************************/ +/* Other Blob functions */ +/******************************/ + +BSTREAM* ISC_EXPORT BLOB_open(isc_blob_handle, + ISC_SCHAR*, + int); + +int ISC_EXPORT BLOB_put(ISC_SCHAR, + BSTREAM*); + +int ISC_EXPORT BLOB_close(BSTREAM*); + +int ISC_EXPORT BLOB_get(BSTREAM*); + +int ISC_EXPORT BLOB_display(ISC_QUAD*, + isc_db_handle, + isc_tr_handle, + const ISC_SCHAR*); + +int ISC_EXPORT BLOB_dump(ISC_QUAD*, + isc_db_handle, + isc_tr_handle, + const ISC_SCHAR*); + +int ISC_EXPORT BLOB_edit(ISC_QUAD*, + isc_db_handle, + isc_tr_handle, + const ISC_SCHAR*); + +int ISC_EXPORT BLOB_load(ISC_QUAD*, + isc_db_handle, + isc_tr_handle, + const ISC_SCHAR*); + +int ISC_EXPORT BLOB_text_dump(ISC_QUAD*, + isc_db_handle, + isc_tr_handle, + const ISC_SCHAR*); + +int ISC_EXPORT BLOB_text_load(ISC_QUAD*, + isc_db_handle, + isc_tr_handle, + const ISC_SCHAR*); + +BSTREAM* ISC_EXPORT Bopen(ISC_QUAD*, + isc_db_handle, + isc_tr_handle, + const ISC_SCHAR*); + +/* Disabled, not found anywhere. +BSTREAM* ISC_EXPORT Bopen2(ISC_QUAD*, + isc_db_handle, + isc_tr_handle, + const ISC_SCHAR*, + unsigned short); +*/ + + +/******************************/ +/* Other Misc functions */ +/******************************/ + +ISC_LONG ISC_EXPORT isc_ftof(const ISC_SCHAR*, + const unsigned short, + ISC_SCHAR*, + const unsigned short); + +ISC_STATUS ISC_EXPORT isc_print_blr(const ISC_SCHAR*, + ISC_PRINT_CALLBACK, + void*, + short); + +void ISC_EXPORT isc_set_debug(int); + +void ISC_EXPORT isc_qtoq(const ISC_QUAD*, + ISC_QUAD*); + +void ISC_EXPORT isc_vtof(const ISC_SCHAR*, + ISC_SCHAR*, + unsigned short); + +void ISC_EXPORT isc_vtov(const ISC_SCHAR*, + ISC_SCHAR*, + short); + +int ISC_EXPORT isc_version(isc_db_handle*, + ISC_VERSION_CALLBACK, + void*); + +ISC_LONG ISC_EXPORT isc_reset_fpe(ISC_USHORT); + +uintptr_t ISC_EXPORT isc_baddress(ISC_SCHAR*); +void ISC_EXPORT isc_baddress_s(const ISC_SCHAR*, + uintptr_t*); + +/*****************************************/ +/* Service manager functions */ +/*****************************************/ + +#define ADD_SPB_LENGTH(p, length) {*(p)++ = (length); \ + *(p)++ = (length) >> 8;} + +#define ADD_SPB_NUMERIC(p, data) {*(p)++ = (ISC_SCHAR) (data); \ + *(p)++ = (ISC_SCHAR) ((data) >> 8); \ + *(p)++ = (ISC_SCHAR) ((data) >> 16); \ + *(p)++ = (ISC_SCHAR) ((data) >> 24);} + +ISC_STATUS ISC_EXPORT isc_service_attach(ISC_STATUS*, + unsigned short, + const ISC_SCHAR*, + isc_svc_handle*, + unsigned short, + const ISC_SCHAR*); + +ISC_STATUS ISC_EXPORT isc_service_detach(ISC_STATUS *, + isc_svc_handle *); + +ISC_STATUS ISC_EXPORT isc_service_query(ISC_STATUS*, + isc_svc_handle*, + isc_resv_handle*, + unsigned short, + const ISC_SCHAR*, + unsigned short, + const ISC_SCHAR*, + unsigned short, + ISC_SCHAR*); + +ISC_STATUS ISC_EXPORT isc_service_start(ISC_STATUS*, + isc_svc_handle*, + isc_resv_handle*, + unsigned short, + const ISC_SCHAR*); + + +/********************************/ +/* Client information functions */ +/********************************/ + +void ISC_EXPORT isc_get_client_version ( ISC_SCHAR *); +int ISC_EXPORT isc_get_client_major_version (); +int ISC_EXPORT isc_get_client_minor_version (); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +/***************************************************/ +/* Actions to pass to the blob filter (ctl_source) */ +/***************************************************/ + +#define isc_blob_filter_open 0 +#define isc_blob_filter_get_segment 1 +#define isc_blob_filter_close 2 +#define isc_blob_filter_create 3 +#define isc_blob_filter_put_segment 4 +#define isc_blob_filter_alloc 5 +#define isc_blob_filter_free 6 +#define isc_blob_filter_seek 7 + +/*******************/ +/* Blr definitions */ +/*******************/ + + +#ifndef JRD_BLR_H +#define JRD_BLR_H + +#define blr_text (unsigned char)14 +#define blr_text2 (unsigned char)15 +#define blr_short (unsigned char)7 +#define blr_long (unsigned char)8 +#define blr_quad (unsigned char)9 +#define blr_float (unsigned char)10 +#define blr_double (unsigned char)27 +#define blr_d_float (unsigned char)11 +#define blr_timestamp (unsigned char)35 +#define blr_varying (unsigned char)37 +#define blr_varying2 (unsigned char)38 +#define blr_blob (unsigned short)261 +#define blr_cstring (unsigned char)40 +#define blr_cstring2 (unsigned char)41 +#define blr_blob_id (unsigned char)45 +#define blr_sql_date (unsigned char)12 +#define blr_sql_time (unsigned char)13 +#define blr_int64 (unsigned char)16 +#define blr_blob2 (unsigned char)17 +#define blr_domain_name (unsigned char)18 +#define blr_domain_name2 (unsigned char)19 +#define blr_not_nullable (unsigned char)20 + +#define blr_domain_type_of (unsigned char)0 +#define blr_domain_full (unsigned char)1 + +#define blr_date blr_timestamp + +#define blr_inner (unsigned char)0 +#define blr_left (unsigned char)1 +#define blr_right (unsigned char)2 +#define blr_full (unsigned char)3 + +#define blr_gds_code (unsigned char)0 +#define blr_sql_code (unsigned char)1 +#define blr_exception (unsigned char)2 +#define blr_trigger_code (unsigned char)3 +#define blr_default_code (unsigned char)4 +#define blr_raise (unsigned char)5 +#define blr_exception_msg (unsigned char)6 + +#define blr_version4 (unsigned char)4 +#define blr_version5 (unsigned char)5 +#define blr_eoc (unsigned char)76 +#define blr_end (unsigned char)255 + +#define blr_assignment (unsigned char)1 +#define blr_begin (unsigned char)2 +#define blr_dcl_variable (unsigned char)3 +#define blr_message (unsigned char)4 +#define blr_erase (unsigned char)5 +#define blr_fetch (unsigned char)6 +#define blr_for (unsigned char)7 +#define blr_if (unsigned char)8 +#define blr_loop (unsigned char)9 +#define blr_modify (unsigned char)10 +#define blr_handler (unsigned char)11 +#define blr_receive (unsigned char)12 +#define blr_select (unsigned char)13 +#define blr_send (unsigned char)14 +#define blr_store (unsigned char)15 +#define blr_label (unsigned char)17 +#define blr_leave (unsigned char)18 +#define blr_store2 (unsigned char)19 +#define blr_post (unsigned char)20 +#define blr_literal (unsigned char)21 +#define blr_dbkey (unsigned char)22 +#define blr_field (unsigned char)23 +#define blr_fid (unsigned char)24 +#define blr_parameter (unsigned char)25 +#define blr_variable (unsigned char)26 +#define blr_average (unsigned char)27 +#define blr_count (unsigned char)28 +#define blr_maximum (unsigned char)29 +#define blr_minimum (unsigned char)30 +#define blr_total (unsigned char)31 + +#define blr_add (unsigned char)34 +#define blr_subtract (unsigned char)35 +#define blr_multiply (unsigned char)36 +#define blr_divide (unsigned char)37 +#define blr_negate (unsigned char)38 +#define blr_concatenate (unsigned char)39 +#define blr_substring (unsigned char)40 +#define blr_parameter2 (unsigned char)41 +#define blr_from (unsigned char)42 +#define blr_via (unsigned char)43 +#define blr_parameter2_old (unsigned char)44 +#define blr_user_name (unsigned char)44 +#define blr_null (unsigned char)45 + +#define blr_equiv (unsigned char)46 +#define blr_eql (unsigned char)47 +#define blr_neq (unsigned char)48 +#define blr_gtr (unsigned char)49 +#define blr_geq (unsigned char)50 +#define blr_lss (unsigned char)51 +#define blr_leq (unsigned char)52 +#define blr_containing (unsigned char)53 +#define blr_matching (unsigned char)54 +#define blr_starting (unsigned char)55 +#define blr_between (unsigned char)56 +#define blr_or (unsigned char)57 +#define blr_and (unsigned char)58 +#define blr_not (unsigned char)59 +#define blr_any (unsigned char)60 +#define blr_missing (unsigned char)61 +#define blr_unique (unsigned char)62 +#define blr_like (unsigned char)63 + +#define blr_rse (unsigned char)67 +#define blr_first (unsigned char)68 +#define blr_project (unsigned char)69 +#define blr_sort (unsigned char)70 +#define blr_boolean (unsigned char)71 +#define blr_ascending (unsigned char)72 +#define blr_descending (unsigned char)73 +#define blr_relation (unsigned char)74 +#define blr_rid (unsigned char)75 +#define blr_union (unsigned char)76 +#define blr_map (unsigned char)77 +#define blr_group_by (unsigned char)78 +#define blr_aggregate (unsigned char)79 +#define blr_join_type (unsigned char)80 + +#define blr_agg_count (unsigned char)83 +#define blr_agg_max (unsigned char)84 +#define blr_agg_min (unsigned char)85 +#define blr_agg_total (unsigned char)86 +#define blr_agg_average (unsigned char)87 +#define blr_parameter3 (unsigned char)88 +#define blr_run_max (unsigned char)89 +#define blr_run_min (unsigned char)90 +#define blr_run_total (unsigned char)91 +#define blr_run_average (unsigned char)92 +#define blr_agg_count2 (unsigned char)93 +#define blr_agg_count_distinct (unsigned char)94 +#define blr_agg_total_distinct (unsigned char)95 +#define blr_agg_average_distinct (unsigned char)96 + +#define blr_function (unsigned char)100 +#define blr_gen_id (unsigned char)101 +#define blr_prot_mask (unsigned char)102 +#define blr_upcase (unsigned char)103 +#define blr_lock_state (unsigned char)104 +#define blr_value_if (unsigned char)105 +#define blr_matching2 (unsigned char)106 +#define blr_index (unsigned char)107 +#define blr_ansi_like (unsigned char)108 + +#define blr_seek (unsigned char)112 + +#define blr_continue (unsigned char)0 +#define blr_forward (unsigned char)1 +#define blr_backward (unsigned char)2 +#define blr_bof_forward (unsigned char)3 +#define blr_eof_backward (unsigned char)4 + +#define blr_run_count (unsigned char)118 +#define blr_rs_stream (unsigned char)119 +#define blr_exec_proc (unsigned char)120 + +#define blr_procedure (unsigned char)124 +#define blr_pid (unsigned char)125 +#define blr_exec_pid (unsigned char)126 +#define blr_singular (unsigned char)127 +#define blr_abort (unsigned char)128 +#define blr_block (unsigned char)129 +#define blr_error_handler (unsigned char)130 + +#define blr_cast (unsigned char)131 + +#define blr_start_savepoint (unsigned char)134 +#define blr_end_savepoint (unsigned char)135 + +#define blr_plan (unsigned char)139 +#define blr_merge (unsigned char)140 +#define blr_join (unsigned char)141 +#define blr_sequential (unsigned char)142 +#define blr_navigational (unsigned char)143 +#define blr_indices (unsigned char)144 +#define blr_retrieve (unsigned char)145 + +#define blr_relation2 (unsigned char)146 +#define blr_rid2 (unsigned char)147 + +#define blr_set_generator (unsigned char)150 + +#define blr_ansi_any (unsigned char)151 +#define blr_exists (unsigned char)152 + +#define blr_record_version (unsigned char)154 +#define blr_stall (unsigned char)155 + +#define blr_ansi_all (unsigned char)158 + +#define blr_extract (unsigned char)159 + +#define blr_extract_year (unsigned char)0 +#define blr_extract_month (unsigned char)1 +#define blr_extract_day (unsigned char)2 +#define blr_extract_hour (unsigned char)3 +#define blr_extract_minute (unsigned char)4 +#define blr_extract_second (unsigned char)5 +#define blr_extract_weekday (unsigned char)6 +#define blr_extract_yearday (unsigned char)7 +#define blr_extract_millisecond (unsigned char)8 +#define blr_extract_week (unsigned char)9 + +#define blr_current_date (unsigned char)160 +#define blr_current_timestamp (unsigned char)161 +#define blr_current_time (unsigned char)162 + +#define blr_post_arg (unsigned char)163 +#define blr_exec_into (unsigned char)164 +#define blr_user_savepoint (unsigned char)165 +#define blr_dcl_cursor (unsigned char)166 +#define blr_cursor_stmt (unsigned char)167 +#define blr_current_timestamp2 (unsigned char)168 +#define blr_current_time2 (unsigned char)169 +#define blr_agg_list (unsigned char)170 +#define blr_agg_list_distinct (unsigned char)171 +#define blr_modify2 (unsigned char)172 + +#define blr_current_role (unsigned char)174 +#define blr_skip (unsigned char)175 + +#define blr_exec_sql (unsigned char)176 +#define blr_internal_info (unsigned char)177 +#define blr_nullsfirst (unsigned char)178 +#define blr_writelock (unsigned char)179 +#define blr_nullslast (unsigned char)180 + +#define blr_lowcase (unsigned char)181 +#define blr_strlen (unsigned char)182 + +#define blr_strlen_bit (unsigned char)0 +#define blr_strlen_char (unsigned char)1 +#define blr_strlen_octet (unsigned char)2 + +#define blr_trim (unsigned char)183 + +#define blr_trim_both (unsigned char)0 +#define blr_trim_leading (unsigned char)1 +#define blr_trim_trailing (unsigned char)2 + +#define blr_trim_spaces (unsigned char)0 +#define blr_trim_characters (unsigned char)1 + +#define blr_savepoint_set (unsigned char)0 +#define blr_savepoint_release (unsigned char)1 +#define blr_savepoint_undo (unsigned char)2 +#define blr_savepoint_release_single (unsigned char)3 + +#define blr_cursor_open (unsigned char)0 +#define blr_cursor_close (unsigned char)1 +#define blr_cursor_fetch (unsigned char)2 + +#define blr_init_variable (unsigned char)184 +#define blr_recurse (unsigned char)185 +#define blr_sys_function (unsigned char)186 + +#endif + + +#ifndef INCLUDE_CONSTS_PUB_H +#define INCLUDE_CONSTS_PUB_H + +#define isc_dpb_version1 1 +#define isc_dpb_cdd_pathname 1 +#define isc_dpb_allocation 2 +#define isc_dpb_journal 3 +#define isc_dpb_page_size 4 +#define isc_dpb_num_buffers 5 +#define isc_dpb_buffer_length 6 +#define isc_dpb_debug 7 +#define isc_dpb_garbage_collect 8 +#define isc_dpb_verify 9 +#define isc_dpb_sweep 10 +#define isc_dpb_enable_journal 11 +#define isc_dpb_disable_journal 12 +#define isc_dpb_dbkey_scope 13 +#define isc_dpb_number_of_users 14 +#define isc_dpb_trace 15 +#define isc_dpb_no_garbage_collect 16 +#define isc_dpb_damaged 17 +#define isc_dpb_license 18 +#define isc_dpb_sys_user_name 19 +#define isc_dpb_encrypt_key 20 +#define isc_dpb_activate_shadow 21 +#define isc_dpb_sweep_interval 22 +#define isc_dpb_delete_shadow 23 +#define isc_dpb_force_write 24 +#define isc_dpb_begin_log 25 +#define isc_dpb_quit_log 26 +#define isc_dpb_no_reserve 27 +#define isc_dpb_user_name 28 +#define isc_dpb_password 29 +#define isc_dpb_password_enc 30 +#define isc_dpb_sys_user_name_enc 31 +#define isc_dpb_interp 32 +#define isc_dpb_online_dump 33 +#define isc_dpb_old_file_size 34 +#define isc_dpb_old_num_files 35 +#define isc_dpb_old_file 36 +#define isc_dpb_old_start_page 37 +#define isc_dpb_old_start_seqno 38 +#define isc_dpb_old_start_file 39 +#define isc_dpb_drop_walfile 40 +#define isc_dpb_old_dump_id 41 +#define isc_dpb_wal_backup_dir 42 +#define isc_dpb_wal_chkptlen 43 +#define isc_dpb_wal_numbufs 44 +#define isc_dpb_wal_bufsize 45 +#define isc_dpb_wal_grp_cmt_wait 46 +#define isc_dpb_lc_messages 47 +#define isc_dpb_lc_ctype 48 +#define isc_dpb_cache_manager 49 +#define isc_dpb_shutdown 50 +#define isc_dpb_online 51 +#define isc_dpb_shutdown_delay 52 +#define isc_dpb_reserved 53 +#define isc_dpb_overwrite 54 +#define isc_dpb_sec_attach 55 +#define isc_dpb_disable_wal 56 +#define isc_dpb_connect_timeout 57 +#define isc_dpb_dummy_packet_interval 58 +#define isc_dpb_gbak_attach 59 +#define isc_dpb_sql_role_name 60 +#define isc_dpb_set_page_buffers 61 +#define isc_dpb_working_directory 62 +#define isc_dpb_sql_dialect 63 +#define isc_dpb_set_db_readonly 64 +#define isc_dpb_set_db_sql_dialect 65 +#define isc_dpb_gfix_attach 66 +#define isc_dpb_gstat_attach 67 +#define isc_dpb_set_db_charset 68 +#define isc_dpb_gsec_attach 69 +#define isc_dpb_address_path 70 +#define isc_dpb_process_id 71 +#define isc_dpb_no_db_triggers 72 +#define isc_dpb_trusted_auth 73 +#define isc_dpb_process_name 74 + +#define isc_dpb_address 1 + +#define isc_dpb_addr_protocol 1 +#define isc_dpb_addr_endpoint 2 + +#define isc_dpb_pages 1 +#define isc_dpb_records 2 +#define isc_dpb_indices 4 +#define isc_dpb_transactions 8 +#define isc_dpb_no_update 16 +#define isc_dpb_repair 32 +#define isc_dpb_ignore 64 + +#define isc_dpb_shut_cache 0x1 +#define isc_dpb_shut_attachment 0x2 +#define isc_dpb_shut_transaction 0x4 +#define isc_dpb_shut_force 0x8 +#define isc_dpb_shut_mode_mask 0x70 + +#define isc_dpb_shut_default 0x0 +#define isc_dpb_shut_normal 0x10 +#define isc_dpb_shut_multi 0x20 +#define isc_dpb_shut_single 0x30 +#define isc_dpb_shut_full 0x40 + +#define RDB_system 1 +#define RDB_id_assigned 2 + +#define isc_tpb_version1 1 +#define isc_tpb_version3 3 +#define isc_tpb_consistency 1 +#define isc_tpb_concurrency 2 +#define isc_tpb_shared 3 +#define isc_tpb_protected 4 +#define isc_tpb_exclusive 5 +#define isc_tpb_wait 6 +#define isc_tpb_nowait 7 +#define isc_tpb_read 8 +#define isc_tpb_write 9 +#define isc_tpb_lock_read 10 +#define isc_tpb_lock_write 11 +#define isc_tpb_verb_time 12 +#define isc_tpb_commit_time 13 +#define isc_tpb_ignore_limbo 14 +#define isc_tpb_read_committed 15 +#define isc_tpb_autocommit 16 +#define isc_tpb_rec_version 17 +#define isc_tpb_no_rec_version 18 +#define isc_tpb_restart_requests 19 +#define isc_tpb_no_auto_undo 20 +#define isc_tpb_lock_timeout 21 + +#define isc_bpb_version1 1 +#define isc_bpb_source_type 1 +#define isc_bpb_target_type 2 +#define isc_bpb_type 3 +#define isc_bpb_source_interp 4 +#define isc_bpb_target_interp 5 +#define isc_bpb_filter_parameter 6 +#define isc_bpb_storage 7 + +#define isc_bpb_type_segmented 0x0 +#define isc_bpb_type_stream 0x1 +#define isc_bpb_storage_main 0x0 +#define isc_bpb_storage_temp 0x2 + +#define isc_spb_version1 1 +#define isc_spb_current_version 2 +#define isc_spb_version isc_spb_current_version +#define isc_spb_user_name isc_dpb_user_name +#define isc_spb_sys_user_name isc_dpb_sys_user_name +#define isc_spb_sys_user_name_enc isc_dpb_sys_user_name_enc +#define isc_spb_password isc_dpb_password +#define isc_spb_password_enc isc_dpb_password_enc +#define isc_spb_command_line 105 +#define isc_spb_dbname 106 +#define isc_spb_verbose 107 +#define isc_spb_options 108 +#define isc_spb_address_path 109 +#define isc_spb_process_id 110 +#define isc_spb_trusted_auth 111 +#define isc_spb_process_name 112 + +#define isc_spb_connect_timeout isc_dpb_connect_timeout +#define isc_spb_dummy_packet_interval isc_dpb_dummy_packet_interval +#define isc_spb_sql_role_name isc_dpb_sql_role_name + +#define isc_action_svc_backup 1 +#define isc_action_svc_restore 2 +#define isc_action_svc_repair 3 +#define isc_action_svc_add_user 4 +#define isc_action_svc_delete_user 5 +#define isc_action_svc_modify_user 6 +#define isc_action_svc_display_user 7 +#define isc_action_svc_properties 8 +#define isc_action_svc_add_license 9 +#define isc_action_svc_remove_license 10 +#define isc_action_svc_db_stats 11 +#define isc_action_svc_get_ib_log 12 +#define isc_action_svc_get_fb_log 12 + +#define isc_info_svc_svr_db_info 50 +#define isc_info_svc_get_license 51 +#define isc_info_svc_get_license_mask 52 +#define isc_info_svc_get_config 53 +#define isc_info_svc_version 54 +#define isc_info_svc_server_version 55 +#define isc_info_svc_implementation 56 +#define isc_info_svc_capabilities 57 +#define isc_info_svc_user_dbpath 58 +#define isc_info_svc_get_env 59 +#define isc_info_svc_get_env_lock 60 +#define isc_info_svc_get_env_msg 61 +#define isc_info_svc_line 62 +#define isc_info_svc_to_eof 63 +#define isc_info_svc_timeout 64 +#define isc_info_svc_get_licensed_users 65 +#define isc_info_svc_limbo_trans 66 +#define isc_info_svc_running 67 +#define isc_info_svc_get_users 68 + +#define isc_spb_sec_userid 5 +#define isc_spb_sec_groupid 6 +#define isc_spb_sec_username 7 +#define isc_spb_sec_password 8 +#define isc_spb_sec_groupname 9 +#define isc_spb_sec_firstname 10 +#define isc_spb_sec_middlename 11 +#define isc_spb_sec_lastname 12 + +#define isc_spb_lic_key 5 +#define isc_spb_lic_id 6 +#define isc_spb_lic_desc 7 + +#define isc_spb_bkp_file 5 +#define isc_spb_bkp_factor 6 +#define isc_spb_bkp_length 7 +#define isc_spb_bkp_ignore_checksums 0x01 +#define isc_spb_bkp_ignore_limbo 0x02 +#define isc_spb_bkp_metadata_only 0x04 +#define isc_spb_bkp_no_garbage_collect 0x08 +#define isc_spb_bkp_old_descriptions 0x10 +#define isc_spb_bkp_non_transportable 0x20 +#define isc_spb_bkp_convert 0x40 +#define isc_spb_bkp_expand 0x80 + +#define isc_spb_prp_page_buffers 5 +#define isc_spb_prp_sweep_interval 6 +#define isc_spb_prp_shutdown_db 7 +#define isc_spb_prp_deny_new_attachments 9 +#define isc_spb_prp_deny_new_transactions 10 +#define isc_spb_prp_reserve_space 11 +#define isc_spb_prp_write_mode 12 +#define isc_spb_prp_access_mode 13 +#define isc_spb_prp_set_sql_dialect 14 +#define isc_spb_prp_activate 0x0100 +#define isc_spb_prp_db_online 0x0200 + +#define isc_spb_prp_res_use_full 35 +#define isc_spb_prp_res 36 + +#define isc_spb_prp_wm_async 37 +#define isc_spb_prp_wm_sync 38 + +#define isc_spb_prp_am_readonly 39 +#define isc_spb_prp_am_readwrite 40 + +#define isc_spb_rpr_commit_trans 15 +#define isc_spb_rpr_rollback_trans 34 +#define isc_spb_rpr_recover_two_phase 17 +#define isc_spb_tra_id 18 +#define isc_spb_single_tra_id 19 +#define isc_spb_multi_tra_id 20 +#define isc_spb_tra_state 21 +#define isc_spb_tra_state_limbo 22 +#define isc_spb_tra_state_commit 23 +#define isc_spb_tra_state_rollback 24 +#define isc_spb_tra_state_unknown 25 +#define isc_spb_tra_host_site 26 +#define isc_spb_tra_remote_site 27 +#define isc_spb_tra_db_path 28 +#define isc_spb_tra_advise 29 +#define isc_spb_tra_advise_commit 30 +#define isc_spb_tra_advise_rollback 31 +#define isc_spb_tra_advise_unknown 33 + +#define isc_spb_rpr_validate_db 0x01 +#define isc_spb_rpr_sweep_db 0x02 +#define isc_spb_rpr_mend_db 0x04 +#define isc_spb_rpr_list_limbo_trans 0x08 +#define isc_spb_rpr_check_db 0x10 +#define isc_spb_rpr_ignore_checksum 0x20 +#define isc_spb_rpr_kill_shadows 0x40 +#define isc_spb_rpr_full 0x80 + +#define isc_spb_res_buffers 9 +#define isc_spb_res_page_size 10 +#define isc_spb_res_length 11 +#define isc_spb_res_access_mode 12 +#define isc_spb_res_deactivate_idx 0x0100 +#define isc_spb_res_no_shadow 0x0200 +#define isc_spb_res_no_validity 0x0400 +#define isc_spb_res_one_at_a_time 0x0800 +#define isc_spb_res_replace 0x1000 +#define isc_spb_res_create 0x2000 +#define isc_spb_res_use_all_space 0x4000 + +#define isc_spb_res_am_readonly isc_spb_prp_am_readonly +#define isc_spb_res_am_readwrite isc_spb_prp_am_readwrite + +#define isc_spb_num_att 5 +#define isc_spb_num_db 6 + +#define isc_spb_sts_data_pages 0x01 +#define isc_spb_sts_db_log 0x02 +#define isc_spb_sts_hdr_pages 0x04 +#define isc_spb_sts_idx_pages 0x08 +#define isc_spb_sts_sys_relations 0x10 +#define isc_spb_sts_record_versions 0x20 +#define isc_spb_sts_table 0x40 +#define isc_spb_sts_nocreation 0x80 + +#define isc_dyn_version_1 1 +#define isc_dyn_eoc 255 + +#define isc_dyn_begin 2 +#define isc_dyn_end 3 +#define isc_dyn_if 4 +#define isc_dyn_def_database 5 +#define isc_dyn_def_global_fld 6 +#define isc_dyn_def_local_fld 7 +#define isc_dyn_def_idx 8 +#define isc_dyn_def_rel 9 +#define isc_dyn_def_sql_fld 10 +#define isc_dyn_def_view 12 +#define isc_dyn_def_trigger 15 +#define isc_dyn_def_security_class 120 +#define isc_dyn_def_dimension 140 +#define isc_dyn_def_generator 24 +#define isc_dyn_def_function 25 +#define isc_dyn_def_filter 26 +#define isc_dyn_def_function_arg 27 +#define isc_dyn_def_shadow 34 +#define isc_dyn_def_trigger_msg 17 +#define isc_dyn_def_file 36 +#define isc_dyn_mod_database 39 +#define isc_dyn_mod_rel 11 +#define isc_dyn_mod_global_fld 13 +#define isc_dyn_mod_idx 102 +#define isc_dyn_mod_local_fld 14 +#define isc_dyn_mod_sql_fld 216 +#define isc_dyn_mod_view 16 +#define isc_dyn_mod_security_class 122 +#define isc_dyn_mod_trigger 113 +#define isc_dyn_mod_trigger_msg 28 +#define isc_dyn_delete_database 18 +#define isc_dyn_delete_rel 19 +#define isc_dyn_delete_global_fld 20 +#define isc_dyn_delete_local_fld 21 +#define isc_dyn_delete_idx 22 +#define isc_dyn_delete_security_class 123 +#define isc_dyn_delete_dimensions 143 +#define isc_dyn_delete_trigger 23 +#define isc_dyn_delete_trigger_msg 29 +#define isc_dyn_delete_filter 32 +#define isc_dyn_delete_function 33 +#define isc_dyn_delete_shadow 35 +#define isc_dyn_grant 30 +#define isc_dyn_revoke 31 +#define isc_dyn_def_primary_key 37 +#define isc_dyn_def_foreign_key 38 +#define isc_dyn_def_unique 40 +#define isc_dyn_def_procedure 164 +#define isc_dyn_delete_procedure 165 +#define isc_dyn_def_parameter 135 +#define isc_dyn_delete_parameter 136 +#define isc_dyn_mod_procedure 175 + +#define isc_dyn_def_exception 181 +#define isc_dyn_mod_exception 182 +#define isc_dyn_del_exception 183 + +#define isc_dyn_def_difference 220 +#define isc_dyn_drop_difference 221 +#define isc_dyn_begin_backup 222 +#define isc_dyn_end_backup 223 +#define isc_dyn_debug_info 240 + +#define isc_dyn_view_blr 43 +#define isc_dyn_view_source 44 +#define isc_dyn_view_relation 45 +#define isc_dyn_view_context 46 +#define isc_dyn_view_context_name 47 + +#define isc_dyn_rel_name 50 +#define isc_dyn_fld_name 51 +#define isc_dyn_new_fld_name 215 +#define isc_dyn_idx_name 52 +#define isc_dyn_description 53 +#define isc_dyn_security_class 54 +#define isc_dyn_system_flag 55 +#define isc_dyn_update_flag 56 +#define isc_dyn_prc_name 166 +#define isc_dyn_prm_name 137 +#define isc_dyn_sql_object 196 +#define isc_dyn_fld_character_set_name 174 + +#define isc_dyn_rel_dbkey_length 61 +#define isc_dyn_rel_store_trig 62 +#define isc_dyn_rel_modify_trig 63 +#define isc_dyn_rel_erase_trig 64 +#define isc_dyn_rel_store_trig_source 65 +#define isc_dyn_rel_modify_trig_source 66 +#define isc_dyn_rel_erase_trig_source 67 +#define isc_dyn_rel_ext_file 68 +#define isc_dyn_rel_sql_protection 69 +#define isc_dyn_rel_constraint 162 +#define isc_dyn_delete_rel_constraint 163 + +#define isc_dyn_rel_temporary 238 +#define isc_dyn_rel_temp_global_preserve 1 +#define isc_dyn_rel_temp_global_delete 2 + +#define isc_dyn_fld_type 70 +#define isc_dyn_fld_length 71 +#define isc_dyn_fld_scale 72 +#define isc_dyn_fld_sub_type 73 +#define isc_dyn_fld_segment_length 74 +#define isc_dyn_fld_query_header 75 +#define isc_dyn_fld_edit_string 76 +#define isc_dyn_fld_validation_blr 77 +#define isc_dyn_fld_validation_source 78 +#define isc_dyn_fld_computed_blr 79 +#define isc_dyn_fld_computed_source 80 +#define isc_dyn_fld_missing_value 81 +#define isc_dyn_fld_default_value 82 +#define isc_dyn_fld_query_name 83 +#define isc_dyn_fld_dimensions 84 +#define isc_dyn_fld_not_null 85 +#define isc_dyn_fld_precision 86 +#define isc_dyn_fld_char_length 172 +#define isc_dyn_fld_collation 173 +#define isc_dyn_fld_default_source 193 +#define isc_dyn_del_default 197 +#define isc_dyn_del_validation 198 +#define isc_dyn_single_validation 199 +#define isc_dyn_fld_character_set 203 + +#define isc_dyn_fld_source 90 +#define isc_dyn_fld_base_fld 91 +#define isc_dyn_fld_position 92 +#define isc_dyn_fld_update_flag 93 + +#define isc_dyn_idx_unique 100 +#define isc_dyn_idx_inactive 101 +#define isc_dyn_idx_type 103 +#define isc_dyn_idx_foreign_key 104 +#define isc_dyn_idx_ref_column 105 +#define isc_dyn_idx_statistic 204 + +#define isc_dyn_trg_type 110 +#define isc_dyn_trg_blr 111 +#define isc_dyn_trg_source 112 +#define isc_dyn_trg_name 114 +#define isc_dyn_trg_sequence 115 +#define isc_dyn_trg_inactive 116 +#define isc_dyn_trg_msg_number 117 +#define isc_dyn_trg_msg 118 + +#define isc_dyn_scl_acl 121 +#define isc_dyn_grant_user 130 +#define isc_dyn_grant_user_explicit 219 +#define isc_dyn_grant_proc 186 +#define isc_dyn_grant_trig 187 +#define isc_dyn_grant_view 188 +#define isc_dyn_grant_options 132 +#define isc_dyn_grant_user_group 205 +#define isc_dyn_grant_role 218 + +#define isc_dyn_dim_lower 141 +#define isc_dyn_dim_upper 142 + +#define isc_dyn_file_name 125 +#define isc_dyn_file_start 126 +#define isc_dyn_file_length 127 +#define isc_dyn_shadow_number 128 +#define isc_dyn_shadow_man_auto 129 +#define isc_dyn_shadow_conditional 130 + +#define isc_dyn_function_name 145 +#define isc_dyn_function_type 146 +#define isc_dyn_func_module_name 147 +#define isc_dyn_func_entry_point 148 +#define isc_dyn_func_return_argument 149 +#define isc_dyn_func_arg_position 150 +#define isc_dyn_func_mechanism 151 +#define isc_dyn_filter_in_subtype 152 +#define isc_dyn_filter_out_subtype 153 + +#define isc_dyn_description2 154 +#define isc_dyn_fld_computed_source2 155 +#define isc_dyn_fld_edit_string2 156 +#define isc_dyn_fld_query_header2 157 +#define isc_dyn_fld_validation_source2 158 +#define isc_dyn_trg_msg2 159 +#define isc_dyn_trg_source2 160 +#define isc_dyn_view_source2 161 +#define isc_dyn_xcp_msg2 184 + +#define isc_dyn_generator_name 95 +#define isc_dyn_generator_id 96 + +#define isc_dyn_prc_inputs 167 +#define isc_dyn_prc_outputs 168 +#define isc_dyn_prc_source 169 +#define isc_dyn_prc_blr 170 +#define isc_dyn_prc_source2 171 +#define isc_dyn_prc_type 239 + +#define isc_dyn_prc_t_selectable 1 +#define isc_dyn_prc_t_executable 2 + +#define isc_dyn_prm_number 138 +#define isc_dyn_prm_type 139 +#define isc_dyn_prm_mechanism 241 + +#define isc_dyn_xcp_msg 185 + +#define isc_dyn_foreign_key_update 205 +#define isc_dyn_foreign_key_delete 206 +#define isc_dyn_foreign_key_cascade 207 +#define isc_dyn_foreign_key_default 208 +#define isc_dyn_foreign_key_null 209 +#define isc_dyn_foreign_key_none 210 + +#define isc_dyn_def_sql_role 211 +#define isc_dyn_sql_role_name 212 +#define isc_dyn_grant_admin_options 213 +#define isc_dyn_del_sql_role 214 + +#define isc_dyn_delete_generator 217 + +#define isc_dyn_mod_function 224 +#define isc_dyn_mod_filter 225 +#define isc_dyn_mod_generator 226 +#define isc_dyn_mod_sql_role 227 +#define isc_dyn_mod_charset 228 +#define isc_dyn_mod_collation 229 +#define isc_dyn_mod_prc_parameter 230 + +#define isc_dyn_def_collation 231 +#define isc_dyn_coll_for_charset 232 +#define isc_dyn_coll_from 233 +#define isc_dyn_coll_from_external 239 +#define isc_dyn_coll_attribute 234 +#define isc_dyn_coll_specific_attributes_charset 235 +#define isc_dyn_coll_specific_attributes 236 +#define isc_dyn_del_collation 237 + +#define isc_dyn_last_dyn_value 242 + +#define isc_sdl_version1 1 +#define isc_sdl_eoc 255 +#define isc_sdl_relation 2 +#define isc_sdl_rid 3 +#define isc_sdl_field 4 +#define isc_sdl_fid 5 +#define isc_sdl_struct 6 +#define isc_sdl_variable 7 +#define isc_sdl_scalar 8 +#define isc_sdl_tiny_integer 9 +#define isc_sdl_short_integer 10 +#define isc_sdl_long_integer 11 +#define isc_sdl_literal 12 +#define isc_sdl_add 13 +#define isc_sdl_subtract 14 +#define isc_sdl_multiply 15 +#define isc_sdl_divide 16 +#define isc_sdl_negate 17 +#define isc_sdl_eql 18 +#define isc_sdl_neq 19 +#define isc_sdl_gtr 20 +#define isc_sdl_geq 21 +#define isc_sdl_lss 22 +#define isc_sdl_leq 23 +#define isc_sdl_and 24 +#define isc_sdl_or 25 +#define isc_sdl_not 26 +#define isc_sdl_while 27 +#define isc_sdl_assignment 28 +#define isc_sdl_label 29 +#define isc_sdl_leave 30 +#define isc_sdl_begin 31 +#define isc_sdl_end 32 +#define isc_sdl_do3 33 +#define isc_sdl_do2 34 +#define isc_sdl_do1 35 +#define isc_sdl_element 36 + +#define isc_interp_eng_ascii 0 +#define isc_interp_jpn_sjis 5 +#define isc_interp_jpn_euc 6 + +#define isc_blob_untyped 0 + +#define isc_blob_text 1 +#define isc_blob_blr 2 +#define isc_blob_acl 3 +#define isc_blob_ranges 4 +#define isc_blob_summary 5 +#define isc_blob_format 6 +#define isc_blob_tra 7 +#define isc_blob_extfile 8 +#define isc_blob_debug_info 9 +#define isc_blob_max_predefined_subtype 10 + +#define isc_blob_formatted_memo 20 +#define isc_blob_paradox_ole 21 +#define isc_blob_graphic 22 +#define isc_blob_dbase_ole 23 +#define isc_blob_typed_binary 24 + +#define isc_info_db_SQL_dialect 62 +#define isc_dpb_SQL_dialect 63 +#define isc_dpb_set_db_SQL_dialect 65 + +#define fb_dbg_version 1 +#define fb_dbg_end 255 +#define fb_dbg_map_src2blr 2 +#define fb_dbg_map_varname 3 +#define fb_dbg_map_argument 4 + +#define fb_dbg_arg_input 0 +#define fb_dbg_arg_output 1 + +#endif + +/*********************************/ +/* Information call declarations */ +/*********************************/ + + +#ifndef JRD_INF_PUB_H +#define JRD_INF_PUB_H + +#define isc_info_end 1 +#define isc_info_truncated 2 +#define isc_info_error 3 +#define isc_info_data_not_ready 4 +#define isc_info_length 126 +#define isc_info_flag_end 127 + +enum db_info_types +{ + isc_info_db_id = 4, + isc_info_reads = 5, + isc_info_writes = 6, + isc_info_fetches = 7, + isc_info_marks = 8, + + isc_info_implementation = 11, + isc_info_isc_version = 12, + isc_info_base_level = 13, + isc_info_page_size = 14, + isc_info_num_buffers = 15, + isc_info_limbo = 16, + isc_info_current_memory = 17, + isc_info_max_memory = 18, + isc_info_window_turns = 19, + isc_info_license = 20, + + isc_info_allocation = 21, + isc_info_attachment_id = 22, + isc_info_read_seq_count = 23, + isc_info_read_idx_count = 24, + isc_info_insert_count = 25, + isc_info_update_count = 26, + isc_info_delete_count = 27, + isc_info_backout_count = 28, + isc_info_purge_count = 29, + isc_info_expunge_count = 30, + + isc_info_sweep_interval = 31, + isc_info_ods_version = 32, + isc_info_ods_minor_version = 33, + isc_info_no_reserve = 34, + + isc_info_logfile = 35, + isc_info_cur_logfile_name = 36, + isc_info_cur_log_part_offset = 37, + isc_info_num_wal_buffers = 38, + isc_info_wal_buffer_size = 39, + isc_info_wal_ckpt_length = 40, + + isc_info_wal_cur_ckpt_interval = 41, + isc_info_wal_prv_ckpt_fname = 42, + isc_info_wal_prv_ckpt_poffset = 43, + isc_info_wal_recv_ckpt_fname = 44, + isc_info_wal_recv_ckpt_poffset = 45, + isc_info_wal_grpc_wait_usecs = 47, + isc_info_wal_num_io = 48, + isc_info_wal_avg_io_size = 49, + isc_info_wal_num_commits = 50, + isc_info_wal_avg_grpc_size = 51, + + isc_info_forced_writes = 52, + isc_info_user_names = 53, + isc_info_page_errors = 54, + isc_info_record_errors = 55, + isc_info_bpage_errors = 56, + isc_info_dpage_errors = 57, + isc_info_ipage_errors = 58, + isc_info_ppage_errors = 59, + isc_info_tpage_errors = 60, + + isc_info_set_page_buffers = 61, + isc_info_db_sql_dialect = 62, + isc_info_db_read_only = 63, + isc_info_db_size_in_pages = 64, + + frb_info_att_charset = 101, + isc_info_db_class = 102, + isc_info_firebird_version = 103, + isc_info_oldest_transaction = 104, + isc_info_oldest_active = 105, + isc_info_oldest_snapshot = 106, + isc_info_next_transaction = 107, + isc_info_db_provider = 108, + isc_info_active_transactions = 109, + isc_info_active_tran_count = 110, + isc_info_creation_date = 111, + isc_info_db_file_size = 112, + + isc_info_db_last_value +}; + +#define isc_info_version isc_info_isc_version + +enum info_db_implementations +{ + isc_info_db_impl_rdb_vms = 1, + isc_info_db_impl_rdb_eln = 2, + isc_info_db_impl_rdb_eln_dev = 3, + isc_info_db_impl_rdb_vms_y = 4, + isc_info_db_impl_rdb_eln_y = 5, + isc_info_db_impl_jri = 6, + isc_info_db_impl_jsv = 7, + + isc_info_db_impl_isc_apl_68K = 25, + isc_info_db_impl_isc_vax_ultr = 26, + isc_info_db_impl_isc_vms = 27, + isc_info_db_impl_isc_sun_68k = 28, + isc_info_db_impl_isc_os2 = 29, + isc_info_db_impl_isc_sun4 = 30, + + isc_info_db_impl_isc_hp_ux = 31, + isc_info_db_impl_isc_sun_386i = 32, + isc_info_db_impl_isc_vms_orcl = 33, + isc_info_db_impl_isc_mac_aux = 34, + isc_info_db_impl_isc_rt_aix = 35, + isc_info_db_impl_isc_mips_ult = 36, + isc_info_db_impl_isc_xenix = 37, + isc_info_db_impl_isc_dg = 38, + isc_info_db_impl_isc_hp_mpexl = 39, + isc_info_db_impl_isc_hp_ux68K = 40, + + isc_info_db_impl_isc_sgi = 41, + isc_info_db_impl_isc_sco_unix = 42, + isc_info_db_impl_isc_cray = 43, + isc_info_db_impl_isc_imp = 44, + isc_info_db_impl_isc_delta = 45, + isc_info_db_impl_isc_next = 46, + isc_info_db_impl_isc_dos = 47, + isc_info_db_impl_m88K = 48, + isc_info_db_impl_unixware = 49, + isc_info_db_impl_isc_winnt_x86 = 50, + + isc_info_db_impl_isc_epson = 51, + isc_info_db_impl_alpha_osf = 52, + isc_info_db_impl_alpha_vms = 53, + isc_info_db_impl_netware_386 = 54, + isc_info_db_impl_win_only = 55, + isc_info_db_impl_ncr_3000 = 56, + isc_info_db_impl_winnt_ppc = 57, + isc_info_db_impl_dg_x86 = 58, + isc_info_db_impl_sco_ev = 59, + isc_info_db_impl_i386 = 60, + + isc_info_db_impl_freebsd = 61, + isc_info_db_impl_netbsd = 62, + isc_info_db_impl_darwin_ppc = 63, + isc_info_db_impl_sinixz = 64, + + isc_info_db_impl_linux_sparc = 65, + isc_info_db_impl_linux_amd64 = 66, + + isc_info_db_impl_freebsd_amd64 = 67, + + isc_info_db_impl_winnt_amd64 = 68, + + isc_info_db_impl_linux_ppc = 69, + isc_info_db_impl_darwin_x86 = 70, + isc_info_db_impl_linux_mipsel = 71, + isc_info_db_impl_linux_mips = 72, + isc_info_db_impl_darwin_x64 = 73, + + isc_info_db_impl_last_value +}; + +#define isc_info_db_impl_isc_a isc_info_db_impl_isc_apl_68K +#define isc_info_db_impl_isc_u isc_info_db_impl_isc_vax_ultr +#define isc_info_db_impl_isc_v isc_info_db_impl_isc_vms +#define isc_info_db_impl_isc_s isc_info_db_impl_isc_sun_68k + +enum info_db_class +{ + isc_info_db_class_access = 1, + isc_info_db_class_y_valve = 2, + isc_info_db_class_rem_int = 3, + isc_info_db_class_rem_srvr = 4, + isc_info_db_class_pipe_int = 7, + isc_info_db_class_pipe_srvr = 8, + isc_info_db_class_sam_int = 9, + isc_info_db_class_sam_srvr = 10, + isc_info_db_class_gateway = 11, + isc_info_db_class_cache = 12, + isc_info_db_class_classic_access = 13, + isc_info_db_class_server_access = 14, + + isc_info_db_class_last_value +}; + +enum info_db_provider +{ + isc_info_db_code_rdb_eln = 1, + isc_info_db_code_rdb_vms = 2, + isc_info_db_code_interbase = 3, + isc_info_db_code_firebird = 4, + + isc_info_db_code_last_value +}; + +#define isc_info_number_messages 4 +#define isc_info_max_message 5 +#define isc_info_max_send 6 +#define isc_info_max_receive 7 +#define isc_info_state 8 +#define isc_info_message_number 9 +#define isc_info_message_size 10 +#define isc_info_request_cost 11 +#define isc_info_access_path 12 +#define isc_info_req_select_count 13 +#define isc_info_req_insert_count 14 +#define isc_info_req_update_count 15 +#define isc_info_req_delete_count 16 + +#define isc_info_rsb_end 0 +#define isc_info_rsb_begin 1 +#define isc_info_rsb_type 2 +#define isc_info_rsb_relation 3 +#define isc_info_rsb_plan 4 + +#define isc_info_rsb_unknown 1 +#define isc_info_rsb_indexed 2 +#define isc_info_rsb_navigate 3 +#define isc_info_rsb_sequential 4 +#define isc_info_rsb_cross 5 +#define isc_info_rsb_sort 6 +#define isc_info_rsb_first 7 +#define isc_info_rsb_boolean 8 +#define isc_info_rsb_union 9 +#define isc_info_rsb_aggregate 10 +#define isc_info_rsb_merge 11 +#define isc_info_rsb_ext_sequential 12 +#define isc_info_rsb_ext_indexed 13 +#define isc_info_rsb_ext_dbkey 14 +#define isc_info_rsb_left_cross 15 +#define isc_info_rsb_select 16 +#define isc_info_rsb_sql_join 17 +#define isc_info_rsb_simulate 18 +#define isc_info_rsb_sim_cross 19 +#define isc_info_rsb_once 20 +#define isc_info_rsb_procedure 21 +#define isc_info_rsb_skip 22 +#define isc_info_rsb_virt_sequential 23 +#define isc_info_rsb_recursive 24 + +#define isc_info_rsb_and 1 +#define isc_info_rsb_or 2 +#define isc_info_rsb_dbkey 3 +#define isc_info_rsb_index 4 + +#define isc_info_req_active 2 +#define isc_info_req_inactive 3 +#define isc_info_req_send 4 +#define isc_info_req_receive 5 +#define isc_info_req_select 6 +#define isc_info_req_sql_stall 7 + +#define isc_info_blob_num_segments 4 +#define isc_info_blob_max_segment 5 +#define isc_info_blob_total_length 6 +#define isc_info_blob_type 7 + +#define isc_info_tra_id 4 +#define isc_info_tra_oldest_interesting 5 +#define isc_info_tra_oldest_snapshot 6 +#define isc_info_tra_oldest_active 7 +#define isc_info_tra_isolation 8 +#define isc_info_tra_access 9 +#define isc_info_tra_lock_timeout 10 + +#define isc_info_tra_consistency 1 +#define isc_info_tra_concurrency 2 +#define isc_info_tra_read_committed 3 + +#define isc_info_tra_no_rec_version 0 +#define isc_info_tra_rec_version 1 + +#define isc_info_tra_readonly 0 +#define isc_info_tra_readwrite 1 + +#define isc_info_sql_select 4 +#define isc_info_sql_bind 5 +#define isc_info_sql_num_variables 6 +#define isc_info_sql_describe_vars 7 +#define isc_info_sql_describe_end 8 +#define isc_info_sql_sqlda_seq 9 +#define isc_info_sql_message_seq 10 +#define isc_info_sql_type 11 +#define isc_info_sql_sub_type 12 +#define isc_info_sql_scale 13 +#define isc_info_sql_length 14 +#define isc_info_sql_null_ind 15 +#define isc_info_sql_field 16 +#define isc_info_sql_relation 17 +#define isc_info_sql_owner 18 +#define isc_info_sql_alias 19 +#define isc_info_sql_sqlda_start 20 +#define isc_info_sql_stmt_type 21 +#define isc_info_sql_get_plan 22 +#define isc_info_sql_records 23 +#define isc_info_sql_batch_fetch 24 +#define isc_info_sql_relation_alias 25 + +#define isc_info_sql_stmt_select 1 +#define isc_info_sql_stmt_insert 2 +#define isc_info_sql_stmt_update 3 +#define isc_info_sql_stmt_delete 4 +#define isc_info_sql_stmt_ddl 5 +#define isc_info_sql_stmt_get_segment 6 +#define isc_info_sql_stmt_put_segment 7 +#define isc_info_sql_stmt_exec_procedure 8 +#define isc_info_sql_stmt_start_trans 9 +#define isc_info_sql_stmt_commit 10 +#define isc_info_sql_stmt_rollback 11 +#define isc_info_sql_stmt_select_for_upd 12 +#define isc_info_sql_stmt_set_generator 13 +#define isc_info_sql_stmt_savepoint 14 + +#endif + + +#include "iberror.h" + +#endif /* JRD_IBASE_H */ + diff --git a/libodbc/include/ibase/iberror.h b/libodbc/include/ibase/iberror.h new file mode 100644 index 0000000000..a38ff3e3b1 --- /dev/null +++ b/libodbc/include/ibase/iberror.h @@ -0,0 +1,1739 @@ + +#ifndef JRD_GEN_IBERROR_H +#define JRD_GEN_IBERROR_H +/* + * The contents of this file are subject to the Interbase Public + * License Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy + * of the License at http://www.Inprise.com/IPL.html + * + * Software distributed under the License is distributed on an + * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express + * or implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The content of this file was generated by the Firebird project + * using the program jrd/codes.epp + */ +/* + * + * *** WARNING *** - This file is automatically generated by codes.epp - do not edit! + * + */ +/* + * MODULE: iberror.h + * DESCRIPTION: ISC error codes + * + */ + + + +/***********************/ +/* ISC Error Codes */ +/***********************/ + + +#ifdef __cplusplus /* c++ definitions */ + +const ISC_LONG isc_facility = 20; +const ISC_LONG isc_base = 335544320L; +const ISC_LONG isc_factor = 1; +const ISC_LONG isc_arg_end = 0; // end of argument list +const ISC_LONG isc_arg_gds = 1; // generic DSRI status value +const ISC_LONG isc_arg_string = 2; // string argument +const ISC_LONG isc_arg_cstring = 3; // count & string argument +const ISC_LONG isc_arg_number = 4; // numeric argument (long) +const ISC_LONG isc_arg_interpreted = 5; // interpreted status code (string) +const ISC_LONG isc_arg_vms = 6; // VAX/VMS status code (long) +const ISC_LONG isc_arg_unix = 7; // UNIX error code +const ISC_LONG isc_arg_domain = 8; // Apollo/Domain error code +const ISC_LONG isc_arg_dos = 9; // MSDOS/OS2 error code +const ISC_LONG isc_arg_mpexl = 10; // HP MPE/XL error code +const ISC_LONG isc_arg_mpexl_ipc = 11; // HP MPE/XL IPC error code +const ISC_LONG isc_arg_next_mach = 15; // NeXT/Mach error code +const ISC_LONG isc_arg_netware = 16; // NetWare error code +const ISC_LONG isc_arg_win32 = 17; // Win32 error code +const ISC_LONG isc_arg_warning = 18; // warning argument + +const ISC_LONG isc_arith_except = 335544321L; +const ISC_LONG isc_bad_dbkey = 335544322L; +const ISC_LONG isc_bad_db_format = 335544323L; +const ISC_LONG isc_bad_db_handle = 335544324L; +const ISC_LONG isc_bad_dpb_content = 335544325L; +const ISC_LONG isc_bad_dpb_form = 335544326L; +const ISC_LONG isc_bad_req_handle = 335544327L; +const ISC_LONG isc_bad_segstr_handle = 335544328L; +const ISC_LONG isc_bad_segstr_id = 335544329L; +const ISC_LONG isc_bad_tpb_content = 335544330L; +const ISC_LONG isc_bad_tpb_form = 335544331L; +const ISC_LONG isc_bad_trans_handle = 335544332L; +const ISC_LONG isc_bug_check = 335544333L; +const ISC_LONG isc_convert_error = 335544334L; +const ISC_LONG isc_db_corrupt = 335544335L; +const ISC_LONG isc_deadlock = 335544336L; +const ISC_LONG isc_excess_trans = 335544337L; +const ISC_LONG isc_from_no_match = 335544338L; +const ISC_LONG isc_infinap = 335544339L; +const ISC_LONG isc_infona = 335544340L; +const ISC_LONG isc_infunk = 335544341L; +const ISC_LONG isc_integ_fail = 335544342L; +const ISC_LONG isc_invalid_blr = 335544343L; +const ISC_LONG isc_io_error = 335544344L; +const ISC_LONG isc_lock_conflict = 335544345L; +const ISC_LONG isc_metadata_corrupt = 335544346L; +const ISC_LONG isc_not_valid = 335544347L; +const ISC_LONG isc_no_cur_rec = 335544348L; +const ISC_LONG isc_no_dup = 335544349L; +const ISC_LONG isc_no_finish = 335544350L; +const ISC_LONG isc_no_meta_update = 335544351L; +const ISC_LONG isc_no_priv = 335544352L; +const ISC_LONG isc_no_recon = 335544353L; +const ISC_LONG isc_no_record = 335544354L; +const ISC_LONG isc_no_segstr_close = 335544355L; +const ISC_LONG isc_obsolete_metadata = 335544356L; +const ISC_LONG isc_open_trans = 335544357L; +const ISC_LONG isc_port_len = 335544358L; +const ISC_LONG isc_read_only_field = 335544359L; +const ISC_LONG isc_read_only_rel = 335544360L; +const ISC_LONG isc_read_only_trans = 335544361L; +const ISC_LONG isc_read_only_view = 335544362L; +const ISC_LONG isc_req_no_trans = 335544363L; +const ISC_LONG isc_req_sync = 335544364L; +const ISC_LONG isc_req_wrong_db = 335544365L; +const ISC_LONG isc_segment = 335544366L; +const ISC_LONG isc_segstr_eof = 335544367L; +const ISC_LONG isc_segstr_no_op = 335544368L; +const ISC_LONG isc_segstr_no_read = 335544369L; +const ISC_LONG isc_segstr_no_trans = 335544370L; +const ISC_LONG isc_segstr_no_write = 335544371L; +const ISC_LONG isc_segstr_wrong_db = 335544372L; +const ISC_LONG isc_sys_request = 335544373L; +const ISC_LONG isc_stream_eof = 335544374L; +const ISC_LONG isc_unavailable = 335544375L; +const ISC_LONG isc_unres_rel = 335544376L; +const ISC_LONG isc_uns_ext = 335544377L; +const ISC_LONG isc_wish_list = 335544378L; +const ISC_LONG isc_wrong_ods = 335544379L; +const ISC_LONG isc_wronumarg = 335544380L; +const ISC_LONG isc_imp_exc = 335544381L; +const ISC_LONG isc_random = 335544382L; +const ISC_LONG isc_fatal_conflict = 335544383L; +const ISC_LONG isc_badblk = 335544384L; +const ISC_LONG isc_invpoolcl = 335544385L; +const ISC_LONG isc_nopoolids = 335544386L; +const ISC_LONG isc_relbadblk = 335544387L; +const ISC_LONG isc_blktoobig = 335544388L; +const ISC_LONG isc_bufexh = 335544389L; +const ISC_LONG isc_syntaxerr = 335544390L; +const ISC_LONG isc_bufinuse = 335544391L; +const ISC_LONG isc_bdbincon = 335544392L; +const ISC_LONG isc_reqinuse = 335544393L; +const ISC_LONG isc_badodsver = 335544394L; +const ISC_LONG isc_relnotdef = 335544395L; +const ISC_LONG isc_fldnotdef = 335544396L; +const ISC_LONG isc_dirtypage = 335544397L; +const ISC_LONG isc_waifortra = 335544398L; +const ISC_LONG isc_doubleloc = 335544399L; +const ISC_LONG isc_nodnotfnd = 335544400L; +const ISC_LONG isc_dupnodfnd = 335544401L; +const ISC_LONG isc_locnotmar = 335544402L; +const ISC_LONG isc_badpagtyp = 335544403L; +const ISC_LONG isc_corrupt = 335544404L; +const ISC_LONG isc_badpage = 335544405L; +const ISC_LONG isc_badindex = 335544406L; +const ISC_LONG isc_dbbnotzer = 335544407L; +const ISC_LONG isc_tranotzer = 335544408L; +const ISC_LONG isc_trareqmis = 335544409L; +const ISC_LONG isc_badhndcnt = 335544410L; +const ISC_LONG isc_wrotpbver = 335544411L; +const ISC_LONG isc_wroblrver = 335544412L; +const ISC_LONG isc_wrodpbver = 335544413L; +const ISC_LONG isc_blobnotsup = 335544414L; +const ISC_LONG isc_badrelation = 335544415L; +const ISC_LONG isc_nodetach = 335544416L; +const ISC_LONG isc_notremote = 335544417L; +const ISC_LONG isc_trainlim = 335544418L; +const ISC_LONG isc_notinlim = 335544419L; +const ISC_LONG isc_traoutsta = 335544420L; +const ISC_LONG isc_connect_reject = 335544421L; +const ISC_LONG isc_dbfile = 335544422L; +const ISC_LONG isc_orphan = 335544423L; +const ISC_LONG isc_no_lock_mgr = 335544424L; +const ISC_LONG isc_ctxinuse = 335544425L; +const ISC_LONG isc_ctxnotdef = 335544426L; +const ISC_LONG isc_datnotsup = 335544427L; +const ISC_LONG isc_badmsgnum = 335544428L; +const ISC_LONG isc_badparnum = 335544429L; +const ISC_LONG isc_virmemexh = 335544430L; +const ISC_LONG isc_blocking_signal = 335544431L; +const ISC_LONG isc_lockmanerr = 335544432L; +const ISC_LONG isc_journerr = 335544433L; +const ISC_LONG isc_keytoobig = 335544434L; +const ISC_LONG isc_nullsegkey = 335544435L; +const ISC_LONG isc_sqlerr = 335544436L; +const ISC_LONG isc_wrodynver = 335544437L; +const ISC_LONG isc_funnotdef = 335544438L; +const ISC_LONG isc_funmismat = 335544439L; +const ISC_LONG isc_bad_msg_vec = 335544440L; +const ISC_LONG isc_bad_detach = 335544441L; +const ISC_LONG isc_noargacc_read = 335544442L; +const ISC_LONG isc_noargacc_write = 335544443L; +const ISC_LONG isc_read_only = 335544444L; +const ISC_LONG isc_ext_err = 335544445L; +const ISC_LONG isc_non_updatable = 335544446L; +const ISC_LONG isc_no_rollback = 335544447L; +const ISC_LONG isc_bad_sec_info = 335544448L; +const ISC_LONG isc_invalid_sec_info = 335544449L; +const ISC_LONG isc_misc_interpreted = 335544450L; +const ISC_LONG isc_update_conflict = 335544451L; +const ISC_LONG isc_unlicensed = 335544452L; +const ISC_LONG isc_obj_in_use = 335544453L; +const ISC_LONG isc_nofilter = 335544454L; +const ISC_LONG isc_shadow_accessed = 335544455L; +const ISC_LONG isc_invalid_sdl = 335544456L; +const ISC_LONG isc_out_of_bounds = 335544457L; +const ISC_LONG isc_invalid_dimension = 335544458L; +const ISC_LONG isc_rec_in_limbo = 335544459L; +const ISC_LONG isc_shadow_missing = 335544460L; +const ISC_LONG isc_cant_validate = 335544461L; +const ISC_LONG isc_cant_start_journal = 335544462L; +const ISC_LONG isc_gennotdef = 335544463L; +const ISC_LONG isc_cant_start_logging = 335544464L; +const ISC_LONG isc_bad_segstr_type = 335544465L; +const ISC_LONG isc_foreign_key = 335544466L; +const ISC_LONG isc_high_minor = 335544467L; +const ISC_LONG isc_tra_state = 335544468L; +const ISC_LONG isc_trans_invalid = 335544469L; +const ISC_LONG isc_buf_invalid = 335544470L; +const ISC_LONG isc_indexnotdefined = 335544471L; +const ISC_LONG isc_login = 335544472L; +const ISC_LONG isc_invalid_bookmark = 335544473L; +const ISC_LONG isc_bad_lock_level = 335544474L; +const ISC_LONG isc_relation_lock = 335544475L; +const ISC_LONG isc_record_lock = 335544476L; +const ISC_LONG isc_max_idx = 335544477L; +const ISC_LONG isc_jrn_enable = 335544478L; +const ISC_LONG isc_old_failure = 335544479L; +const ISC_LONG isc_old_in_progress = 335544480L; +const ISC_LONG isc_old_no_space = 335544481L; +const ISC_LONG isc_no_wal_no_jrn = 335544482L; +const ISC_LONG isc_num_old_files = 335544483L; +const ISC_LONG isc_wal_file_open = 335544484L; +const ISC_LONG isc_bad_stmt_handle = 335544485L; +const ISC_LONG isc_wal_failure = 335544486L; +const ISC_LONG isc_walw_err = 335544487L; +const ISC_LONG isc_logh_small = 335544488L; +const ISC_LONG isc_logh_inv_version = 335544489L; +const ISC_LONG isc_logh_open_flag = 335544490L; +const ISC_LONG isc_logh_open_flag2 = 335544491L; +const ISC_LONG isc_logh_diff_dbname = 335544492L; +const ISC_LONG isc_logf_unexpected_eof = 335544493L; +const ISC_LONG isc_logr_incomplete = 335544494L; +const ISC_LONG isc_logr_header_small = 335544495L; +const ISC_LONG isc_logb_small = 335544496L; +const ISC_LONG isc_wal_illegal_attach = 335544497L; +const ISC_LONG isc_wal_invalid_wpb = 335544498L; +const ISC_LONG isc_wal_err_rollover = 335544499L; +const ISC_LONG isc_no_wal = 335544500L; +const ISC_LONG isc_drop_wal = 335544501L; +const ISC_LONG isc_stream_not_defined = 335544502L; +const ISC_LONG isc_wal_subsys_error = 335544503L; +const ISC_LONG isc_wal_subsys_corrupt = 335544504L; +const ISC_LONG isc_no_archive = 335544505L; +const ISC_LONG isc_shutinprog = 335544506L; +const ISC_LONG isc_range_in_use = 335544507L; +const ISC_LONG isc_range_not_found = 335544508L; +const ISC_LONG isc_charset_not_found = 335544509L; +const ISC_LONG isc_lock_timeout = 335544510L; +const ISC_LONG isc_prcnotdef = 335544511L; +const ISC_LONG isc_prcmismat = 335544512L; +const ISC_LONG isc_wal_bugcheck = 335544513L; +const ISC_LONG isc_wal_cant_expand = 335544514L; +const ISC_LONG isc_codnotdef = 335544515L; +const ISC_LONG isc_xcpnotdef = 335544516L; +const ISC_LONG isc_except = 335544517L; +const ISC_LONG isc_cache_restart = 335544518L; +const ISC_LONG isc_bad_lock_handle = 335544519L; +const ISC_LONG isc_jrn_present = 335544520L; +const ISC_LONG isc_wal_err_rollover2 = 335544521L; +const ISC_LONG isc_wal_err_logwrite = 335544522L; +const ISC_LONG isc_wal_err_jrn_comm = 335544523L; +const ISC_LONG isc_wal_err_expansion = 335544524L; +const ISC_LONG isc_wal_err_setup = 335544525L; +const ISC_LONG isc_wal_err_ww_sync = 335544526L; +const ISC_LONG isc_wal_err_ww_start = 335544527L; +const ISC_LONG isc_shutdown = 335544528L; +const ISC_LONG isc_existing_priv_mod = 335544529L; +const ISC_LONG isc_primary_key_ref = 335544530L; +const ISC_LONG isc_primary_key_notnull = 335544531L; +const ISC_LONG isc_ref_cnstrnt_notfound = 335544532L; +const ISC_LONG isc_foreign_key_notfound = 335544533L; +const ISC_LONG isc_ref_cnstrnt_update = 335544534L; +const ISC_LONG isc_check_cnstrnt_update = 335544535L; +const ISC_LONG isc_check_cnstrnt_del = 335544536L; +const ISC_LONG isc_integ_index_seg_del = 335544537L; +const ISC_LONG isc_integ_index_seg_mod = 335544538L; +const ISC_LONG isc_integ_index_del = 335544539L; +const ISC_LONG isc_integ_index_mod = 335544540L; +const ISC_LONG isc_check_trig_del = 335544541L; +const ISC_LONG isc_check_trig_update = 335544542L; +const ISC_LONG isc_cnstrnt_fld_del = 335544543L; +const ISC_LONG isc_cnstrnt_fld_rename = 335544544L; +const ISC_LONG isc_rel_cnstrnt_update = 335544545L; +const ISC_LONG isc_constaint_on_view = 335544546L; +const ISC_LONG isc_invld_cnstrnt_type = 335544547L; +const ISC_LONG isc_primary_key_exists = 335544548L; +const ISC_LONG isc_systrig_update = 335544549L; +const ISC_LONG isc_not_rel_owner = 335544550L; +const ISC_LONG isc_grant_obj_notfound = 335544551L; +const ISC_LONG isc_grant_fld_notfound = 335544552L; +const ISC_LONG isc_grant_nopriv = 335544553L; +const ISC_LONG isc_nonsql_security_rel = 335544554L; +const ISC_LONG isc_nonsql_security_fld = 335544555L; +const ISC_LONG isc_wal_cache_err = 335544556L; +const ISC_LONG isc_shutfail = 335544557L; +const ISC_LONG isc_check_constraint = 335544558L; +const ISC_LONG isc_bad_svc_handle = 335544559L; +const ISC_LONG isc_shutwarn = 335544560L; +const ISC_LONG isc_wrospbver = 335544561L; +const ISC_LONG isc_bad_spb_form = 335544562L; +const ISC_LONG isc_svcnotdef = 335544563L; +const ISC_LONG isc_no_jrn = 335544564L; +const ISC_LONG isc_transliteration_failed = 335544565L; +const ISC_LONG isc_start_cm_for_wal = 335544566L; +const ISC_LONG isc_wal_ovflow_log_required = 335544567L; +const ISC_LONG isc_text_subtype = 335544568L; +const ISC_LONG isc_dsql_error = 335544569L; +const ISC_LONG isc_dsql_command_err = 335544570L; +const ISC_LONG isc_dsql_constant_err = 335544571L; +const ISC_LONG isc_dsql_cursor_err = 335544572L; +const ISC_LONG isc_dsql_datatype_err = 335544573L; +const ISC_LONG isc_dsql_decl_err = 335544574L; +const ISC_LONG isc_dsql_cursor_update_err = 335544575L; +const ISC_LONG isc_dsql_cursor_open_err = 335544576L; +const ISC_LONG isc_dsql_cursor_close_err = 335544577L; +const ISC_LONG isc_dsql_field_err = 335544578L; +const ISC_LONG isc_dsql_internal_err = 335544579L; +const ISC_LONG isc_dsql_relation_err = 335544580L; +const ISC_LONG isc_dsql_procedure_err = 335544581L; +const ISC_LONG isc_dsql_request_err = 335544582L; +const ISC_LONG isc_dsql_sqlda_err = 335544583L; +const ISC_LONG isc_dsql_var_count_err = 335544584L; +const ISC_LONG isc_dsql_stmt_handle = 335544585L; +const ISC_LONG isc_dsql_function_err = 335544586L; +const ISC_LONG isc_dsql_blob_err = 335544587L; +const ISC_LONG isc_collation_not_found = 335544588L; +const ISC_LONG isc_collation_not_for_charset = 335544589L; +const ISC_LONG isc_dsql_dup_option = 335544590L; +const ISC_LONG isc_dsql_tran_err = 335544591L; +const ISC_LONG isc_dsql_invalid_array = 335544592L; +const ISC_LONG isc_dsql_max_arr_dim_exceeded = 335544593L; +const ISC_LONG isc_dsql_arr_range_error = 335544594L; +const ISC_LONG isc_dsql_trigger_err = 335544595L; +const ISC_LONG isc_dsql_subselect_err = 335544596L; +const ISC_LONG isc_dsql_crdb_prepare_err = 335544597L; +const ISC_LONG isc_specify_field_err = 335544598L; +const ISC_LONG isc_num_field_err = 335544599L; +const ISC_LONG isc_col_name_err = 335544600L; +const ISC_LONG isc_where_err = 335544601L; +const ISC_LONG isc_table_view_err = 335544602L; +const ISC_LONG isc_distinct_err = 335544603L; +const ISC_LONG isc_key_field_count_err = 335544604L; +const ISC_LONG isc_subquery_err = 335544605L; +const ISC_LONG isc_expression_eval_err = 335544606L; +const ISC_LONG isc_node_err = 335544607L; +const ISC_LONG isc_command_end_err = 335544608L; +const ISC_LONG isc_index_name = 335544609L; +const ISC_LONG isc_exception_name = 335544610L; +const ISC_LONG isc_field_name = 335544611L; +const ISC_LONG isc_token_err = 335544612L; +const ISC_LONG isc_union_err = 335544613L; +const ISC_LONG isc_dsql_construct_err = 335544614L; +const ISC_LONG isc_field_aggregate_err = 335544615L; +const ISC_LONG isc_field_ref_err = 335544616L; +const ISC_LONG isc_order_by_err = 335544617L; +const ISC_LONG isc_return_mode_err = 335544618L; +const ISC_LONG isc_extern_func_err = 335544619L; +const ISC_LONG isc_alias_conflict_err = 335544620L; +const ISC_LONG isc_procedure_conflict_error = 335544621L; +const ISC_LONG isc_relation_conflict_err = 335544622L; +const ISC_LONG isc_dsql_domain_err = 335544623L; +const ISC_LONG isc_idx_seg_err = 335544624L; +const ISC_LONG isc_node_name_err = 335544625L; +const ISC_LONG isc_table_name = 335544626L; +const ISC_LONG isc_proc_name = 335544627L; +const ISC_LONG isc_idx_create_err = 335544628L; +const ISC_LONG isc_wal_shadow_err = 335544629L; +const ISC_LONG isc_dependency = 335544630L; +const ISC_LONG isc_idx_key_err = 335544631L; +const ISC_LONG isc_dsql_file_length_err = 335544632L; +const ISC_LONG isc_dsql_shadow_number_err = 335544633L; +const ISC_LONG isc_dsql_token_unk_err = 335544634L; +const ISC_LONG isc_dsql_no_relation_alias = 335544635L; +const ISC_LONG isc_indexname = 335544636L; +const ISC_LONG isc_no_stream_plan = 335544637L; +const ISC_LONG isc_stream_twice = 335544638L; +const ISC_LONG isc_stream_not_found = 335544639L; +const ISC_LONG isc_collation_requires_text = 335544640L; +const ISC_LONG isc_dsql_domain_not_found = 335544641L; +const ISC_LONG isc_index_unused = 335544642L; +const ISC_LONG isc_dsql_self_join = 335544643L; +const ISC_LONG isc_stream_bof = 335544644L; +const ISC_LONG isc_stream_crack = 335544645L; +const ISC_LONG isc_db_or_file_exists = 335544646L; +const ISC_LONG isc_invalid_operator = 335544647L; +const ISC_LONG isc_conn_lost = 335544648L; +const ISC_LONG isc_bad_checksum = 335544649L; +const ISC_LONG isc_page_type_err = 335544650L; +const ISC_LONG isc_ext_readonly_err = 335544651L; +const ISC_LONG isc_sing_select_err = 335544652L; +const ISC_LONG isc_psw_attach = 335544653L; +const ISC_LONG isc_psw_start_trans = 335544654L; +const ISC_LONG isc_invalid_direction = 335544655L; +const ISC_LONG isc_dsql_var_conflict = 335544656L; +const ISC_LONG isc_dsql_no_blob_array = 335544657L; +const ISC_LONG isc_dsql_base_table = 335544658L; +const ISC_LONG isc_duplicate_base_table = 335544659L; +const ISC_LONG isc_view_alias = 335544660L; +const ISC_LONG isc_index_root_page_full = 335544661L; +const ISC_LONG isc_dsql_blob_type_unknown = 335544662L; +const ISC_LONG isc_req_max_clones_exceeded = 335544663L; +const ISC_LONG isc_dsql_duplicate_spec = 335544664L; +const ISC_LONG isc_unique_key_violation = 335544665L; +const ISC_LONG isc_srvr_version_too_old = 335544666L; +const ISC_LONG isc_drdb_completed_with_errs = 335544667L; +const ISC_LONG isc_dsql_procedure_use_err = 335544668L; +const ISC_LONG isc_dsql_count_mismatch = 335544669L; +const ISC_LONG isc_blob_idx_err = 335544670L; +const ISC_LONG isc_array_idx_err = 335544671L; +const ISC_LONG isc_key_field_err = 335544672L; +const ISC_LONG isc_no_delete = 335544673L; +const ISC_LONG isc_del_last_field = 335544674L; +const ISC_LONG isc_sort_err = 335544675L; +const ISC_LONG isc_sort_mem_err = 335544676L; +const ISC_LONG isc_version_err = 335544677L; +const ISC_LONG isc_inval_key_posn = 335544678L; +const ISC_LONG isc_no_segments_err = 335544679L; +const ISC_LONG isc_crrp_data_err = 335544680L; +const ISC_LONG isc_rec_size_err = 335544681L; +const ISC_LONG isc_dsql_field_ref = 335544682L; +const ISC_LONG isc_req_depth_exceeded = 335544683L; +const ISC_LONG isc_no_field_access = 335544684L; +const ISC_LONG isc_no_dbkey = 335544685L; +const ISC_LONG isc_jrn_format_err = 335544686L; +const ISC_LONG isc_jrn_file_full = 335544687L; +const ISC_LONG isc_dsql_open_cursor_request = 335544688L; +const ISC_LONG isc_ib_error = 335544689L; +const ISC_LONG isc_cache_redef = 335544690L; +const ISC_LONG isc_cache_too_small = 335544691L; +const ISC_LONG isc_log_redef = 335544692L; +const ISC_LONG isc_log_too_small = 335544693L; +const ISC_LONG isc_partition_too_small = 335544694L; +const ISC_LONG isc_partition_not_supp = 335544695L; +const ISC_LONG isc_log_length_spec = 335544696L; +const ISC_LONG isc_precision_err = 335544697L; +const ISC_LONG isc_scale_nogt = 335544698L; +const ISC_LONG isc_expec_short = 335544699L; +const ISC_LONG isc_expec_long = 335544700L; +const ISC_LONG isc_expec_ushort = 335544701L; +const ISC_LONG isc_like_escape_invalid = 335544702L; +const ISC_LONG isc_svcnoexe = 335544703L; +const ISC_LONG isc_net_lookup_err = 335544704L; +const ISC_LONG isc_service_unknown = 335544705L; +const ISC_LONG isc_host_unknown = 335544706L; +const ISC_LONG isc_grant_nopriv_on_base = 335544707L; +const ISC_LONG isc_dyn_fld_ambiguous = 335544708L; +const ISC_LONG isc_dsql_agg_ref_err = 335544709L; +const ISC_LONG isc_complex_view = 335544710L; +const ISC_LONG isc_unprepared_stmt = 335544711L; +const ISC_LONG isc_expec_positive = 335544712L; +const ISC_LONG isc_dsql_sqlda_value_err = 335544713L; +const ISC_LONG isc_invalid_array_id = 335544714L; +const ISC_LONG isc_extfile_uns_op = 335544715L; +const ISC_LONG isc_svc_in_use = 335544716L; +const ISC_LONG isc_err_stack_limit = 335544717L; +const ISC_LONG isc_invalid_key = 335544718L; +const ISC_LONG isc_net_init_error = 335544719L; +const ISC_LONG isc_loadlib_failure = 335544720L; +const ISC_LONG isc_network_error = 335544721L; +const ISC_LONG isc_net_connect_err = 335544722L; +const ISC_LONG isc_net_connect_listen_err = 335544723L; +const ISC_LONG isc_net_event_connect_err = 335544724L; +const ISC_LONG isc_net_event_listen_err = 335544725L; +const ISC_LONG isc_net_read_err = 335544726L; +const ISC_LONG isc_net_write_err = 335544727L; +const ISC_LONG isc_integ_index_deactivate = 335544728L; +const ISC_LONG isc_integ_deactivate_primary = 335544729L; +const ISC_LONG isc_cse_not_supported = 335544730L; +const ISC_LONG isc_tra_must_sweep = 335544731L; +const ISC_LONG isc_unsupported_network_drive = 335544732L; +const ISC_LONG isc_io_create_err = 335544733L; +const ISC_LONG isc_io_open_err = 335544734L; +const ISC_LONG isc_io_close_err = 335544735L; +const ISC_LONG isc_io_read_err = 335544736L; +const ISC_LONG isc_io_write_err = 335544737L; +const ISC_LONG isc_io_delete_err = 335544738L; +const ISC_LONG isc_io_access_err = 335544739L; +const ISC_LONG isc_udf_exception = 335544740L; +const ISC_LONG isc_lost_db_connection = 335544741L; +const ISC_LONG isc_no_write_user_priv = 335544742L; +const ISC_LONG isc_token_too_long = 335544743L; +const ISC_LONG isc_max_att_exceeded = 335544744L; +const ISC_LONG isc_login_same_as_role_name = 335544745L; +const ISC_LONG isc_reftable_requires_pk = 335544746L; +const ISC_LONG isc_usrname_too_long = 335544747L; +const ISC_LONG isc_password_too_long = 335544748L; +const ISC_LONG isc_usrname_required = 335544749L; +const ISC_LONG isc_password_required = 335544750L; +const ISC_LONG isc_bad_protocol = 335544751L; +const ISC_LONG isc_dup_usrname_found = 335544752L; +const ISC_LONG isc_usrname_not_found = 335544753L; +const ISC_LONG isc_error_adding_sec_record = 335544754L; +const ISC_LONG isc_error_modifying_sec_record = 335544755L; +const ISC_LONG isc_error_deleting_sec_record = 335544756L; +const ISC_LONG isc_error_updating_sec_db = 335544757L; +const ISC_LONG isc_sort_rec_size_err = 335544758L; +const ISC_LONG isc_bad_default_value = 335544759L; +const ISC_LONG isc_invalid_clause = 335544760L; +const ISC_LONG isc_too_many_handles = 335544761L; +const ISC_LONG isc_optimizer_blk_exc = 335544762L; +const ISC_LONG isc_invalid_string_constant = 335544763L; +const ISC_LONG isc_transitional_date = 335544764L; +const ISC_LONG isc_read_only_database = 335544765L; +const ISC_LONG isc_must_be_dialect_2_and_up = 335544766L; +const ISC_LONG isc_blob_filter_exception = 335544767L; +const ISC_LONG isc_exception_access_violation = 335544768L; +const ISC_LONG isc_exception_datatype_missalignment = 335544769L; +const ISC_LONG isc_exception_array_bounds_exceeded = 335544770L; +const ISC_LONG isc_exception_float_denormal_operand = 335544771L; +const ISC_LONG isc_exception_float_divide_by_zero = 335544772L; +const ISC_LONG isc_exception_float_inexact_result = 335544773L; +const ISC_LONG isc_exception_float_invalid_operand = 335544774L; +const ISC_LONG isc_exception_float_overflow = 335544775L; +const ISC_LONG isc_exception_float_stack_check = 335544776L; +const ISC_LONG isc_exception_float_underflow = 335544777L; +const ISC_LONG isc_exception_integer_divide_by_zero = 335544778L; +const ISC_LONG isc_exception_integer_overflow = 335544779L; +const ISC_LONG isc_exception_unknown = 335544780L; +const ISC_LONG isc_exception_stack_overflow = 335544781L; +const ISC_LONG isc_exception_sigsegv = 335544782L; +const ISC_LONG isc_exception_sigill = 335544783L; +const ISC_LONG isc_exception_sigbus = 335544784L; +const ISC_LONG isc_exception_sigfpe = 335544785L; +const ISC_LONG isc_ext_file_delete = 335544786L; +const ISC_LONG isc_ext_file_modify = 335544787L; +const ISC_LONG isc_adm_task_denied = 335544788L; +const ISC_LONG isc_extract_input_mismatch = 335544789L; +const ISC_LONG isc_insufficient_svc_privileges = 335544790L; +const ISC_LONG isc_file_in_use = 335544791L; +const ISC_LONG isc_service_att_err = 335544792L; +const ISC_LONG isc_ddl_not_allowed_by_db_sql_dial = 335544793L; +const ISC_LONG isc_cancelled = 335544794L; +const ISC_LONG isc_unexp_spb_form = 335544795L; +const ISC_LONG isc_sql_dialect_datatype_unsupport = 335544796L; +const ISC_LONG isc_svcnouser = 335544797L; +const ISC_LONG isc_depend_on_uncommitted_rel = 335544798L; +const ISC_LONG isc_svc_name_missing = 335544799L; +const ISC_LONG isc_too_many_contexts = 335544800L; +const ISC_LONG isc_datype_notsup = 335544801L; +const ISC_LONG isc_dialect_reset_warning = 335544802L; +const ISC_LONG isc_dialect_not_changed = 335544803L; +const ISC_LONG isc_database_create_failed = 335544804L; +const ISC_LONG isc_inv_dialect_specified = 335544805L; +const ISC_LONG isc_valid_db_dialects = 335544806L; +const ISC_LONG isc_sqlwarn = 335544807L; +const ISC_LONG isc_dtype_renamed = 335544808L; +const ISC_LONG isc_extern_func_dir_error = 335544809L; +const ISC_LONG isc_date_range_exceeded = 335544810L; +const ISC_LONG isc_inv_client_dialect_specified = 335544811L; +const ISC_LONG isc_valid_client_dialects = 335544812L; +const ISC_LONG isc_optimizer_between_err = 335544813L; +const ISC_LONG isc_service_not_supported = 335544814L; +const ISC_LONG isc_generator_name = 335544815L; +const ISC_LONG isc_udf_name = 335544816L; +const ISC_LONG isc_bad_limit_param = 335544817L; +const ISC_LONG isc_bad_skip_param = 335544818L; +const ISC_LONG isc_io_32bit_exceeded_err = 335544819L; +const ISC_LONG isc_invalid_savepoint = 335544820L; +const ISC_LONG isc_dsql_column_pos_err = 335544821L; +const ISC_LONG isc_dsql_agg_where_err = 335544822L; +const ISC_LONG isc_dsql_agg_group_err = 335544823L; +const ISC_LONG isc_dsql_agg_column_err = 335544824L; +const ISC_LONG isc_dsql_agg_having_err = 335544825L; +const ISC_LONG isc_dsql_agg_nested_err = 335544826L; +const ISC_LONG isc_exec_sql_invalid_arg = 335544827L; +const ISC_LONG isc_exec_sql_invalid_req = 335544828L; +const ISC_LONG isc_exec_sql_invalid_var = 335544829L; +const ISC_LONG isc_exec_sql_max_call_exceeded = 335544830L; +const ISC_LONG isc_conf_access_denied = 335544831L; +const ISC_LONG isc_wrong_backup_state = 335544832L; +const ISC_LONG isc_wal_backup_err = 335544833L; +const ISC_LONG isc_cursor_not_open = 335544834L; +const ISC_LONG isc_bad_shutdown_mode = 335544835L; +const ISC_LONG isc_concat_overflow = 335544836L; +const ISC_LONG isc_bad_substring_offset = 335544837L; +const ISC_LONG isc_foreign_key_target_doesnt_exist = 335544838L; +const ISC_LONG isc_foreign_key_references_present = 335544839L; +const ISC_LONG isc_no_update = 335544840L; +const ISC_LONG isc_cursor_already_open = 335544841L; +const ISC_LONG isc_stack_trace = 335544842L; +const ISC_LONG isc_ctx_var_not_found = 335544843L; +const ISC_LONG isc_ctx_namespace_invalid = 335544844L; +const ISC_LONG isc_ctx_too_big = 335544845L; +const ISC_LONG isc_ctx_bad_argument = 335544846L; +const ISC_LONG isc_identifier_too_long = 335544847L; +const ISC_LONG isc_except2 = 335544848L; +const ISC_LONG isc_malformed_string = 335544849L; +const ISC_LONG isc_prc_out_param_mismatch = 335544850L; +const ISC_LONG isc_command_end_err2 = 335544851L; +const ISC_LONG isc_partner_idx_incompat_type = 335544852L; +const ISC_LONG isc_bad_substring_length = 335544853L; +const ISC_LONG isc_charset_not_installed = 335544854L; +const ISC_LONG isc_collation_not_installed = 335544855L; +const ISC_LONG isc_att_shutdown = 335544856L; +const ISC_LONG isc_blobtoobig = 335544857L; +const ISC_LONG isc_must_have_phys_field = 335544858L; +const ISC_LONG isc_invalid_time_precision = 335544859L; +const ISC_LONG isc_blob_convert_error = 335544860L; +const ISC_LONG isc_array_convert_error = 335544861L; +const ISC_LONG isc_record_lock_not_supp = 335544862L; +const ISC_LONG isc_partner_idx_not_found = 335544863L; +const ISC_LONG isc_tra_num_exc = 335544864L; +const ISC_LONG isc_field_disappeared = 335544865L; +const ISC_LONG isc_met_wrong_gtt_scope = 335544866L; +const ISC_LONG isc_subtype_for_internal_use = 335544867L; +const ISC_LONG isc_illegal_prc_type = 335544868L; +const ISC_LONG isc_invalid_sort_datatype = 335544869L; +const ISC_LONG isc_collation_name = 335544870L; +const ISC_LONG isc_domain_name = 335544871L; +const ISC_LONG isc_domnotdef = 335544872L; +const ISC_LONG isc_array_max_dimensions = 335544873L; +const ISC_LONG isc_max_db_per_trans_allowed = 335544874L; +const ISC_LONG isc_bad_debug_format = 335544875L; +const ISC_LONG isc_bad_proc_BLR = 335544876L; +const ISC_LONG isc_key_too_big = 335544877L; +const ISC_LONG isc_concurrent_transaction = 335544878L; +const ISC_LONG isc_not_valid_for_var = 335544879L; +const ISC_LONG isc_not_valid_for = 335544880L; +const ISC_LONG isc_need_difference = 335544881L; +const ISC_LONG isc_long_login = 335544882L; +const ISC_LONG isc_fldnotdef2 = 335544883L; +const ISC_LONG isc_gfix_db_name = 335740929L; +const ISC_LONG isc_gfix_invalid_sw = 335740930L; +const ISC_LONG isc_gfix_incmp_sw = 335740932L; +const ISC_LONG isc_gfix_replay_req = 335740933L; +const ISC_LONG isc_gfix_pgbuf_req = 335740934L; +const ISC_LONG isc_gfix_val_req = 335740935L; +const ISC_LONG isc_gfix_pval_req = 335740936L; +const ISC_LONG isc_gfix_trn_req = 335740937L; +const ISC_LONG isc_gfix_full_req = 335740940L; +const ISC_LONG isc_gfix_usrname_req = 335740941L; +const ISC_LONG isc_gfix_pass_req = 335740942L; +const ISC_LONG isc_gfix_subs_name = 335740943L; +const ISC_LONG isc_gfix_wal_req = 335740944L; +const ISC_LONG isc_gfix_sec_req = 335740945L; +const ISC_LONG isc_gfix_nval_req = 335740946L; +const ISC_LONG isc_gfix_type_shut = 335740947L; +const ISC_LONG isc_gfix_retry = 335740948L; +const ISC_LONG isc_gfix_retry_db = 335740951L; +const ISC_LONG isc_gfix_exceed_max = 335740991L; +const ISC_LONG isc_gfix_corrupt_pool = 335740992L; +const ISC_LONG isc_gfix_mem_exhausted = 335740993L; +const ISC_LONG isc_gfix_bad_pool = 335740994L; +const ISC_LONG isc_gfix_trn_not_valid = 335740995L; +const ISC_LONG isc_gfix_unexp_eoi = 335741012L; +const ISC_LONG isc_gfix_recon_fail = 335741018L; +const ISC_LONG isc_gfix_trn_unknown = 335741036L; +const ISC_LONG isc_gfix_mode_req = 335741038L; +const ISC_LONG isc_gfix_opt_SQL_dialect = 335741039L; +const ISC_LONG isc_gfix_pzval_req = 335741042L; +const ISC_LONG isc_dsql_dbkey_from_non_table = 336003074L; +const ISC_LONG isc_dsql_transitional_numeric = 336003075L; +const ISC_LONG isc_dsql_dialect_warning_expr = 336003076L; +const ISC_LONG isc_sql_db_dialect_dtype_unsupport = 336003077L; +const ISC_LONG isc_isc_sql_dialect_conflict_num = 336003079L; +const ISC_LONG isc_dsql_warning_number_ambiguous = 336003080L; +const ISC_LONG isc_dsql_warning_number_ambiguous1 = 336003081L; +const ISC_LONG isc_dsql_warn_precision_ambiguous = 336003082L; +const ISC_LONG isc_dsql_warn_precision_ambiguous1 = 336003083L; +const ISC_LONG isc_dsql_warn_precision_ambiguous2 = 336003084L; +const ISC_LONG isc_dsql_ambiguous_field_name = 336003085L; +const ISC_LONG isc_dsql_udf_return_pos_err = 336003086L; +const ISC_LONG isc_dsql_invalid_label = 336003087L; +const ISC_LONG isc_dsql_datatypes_not_comparable = 336003088L; +const ISC_LONG isc_dsql_cursor_invalid = 336003089L; +const ISC_LONG isc_dsql_cursor_redefined = 336003090L; +const ISC_LONG isc_dsql_cursor_not_found = 336003091L; +const ISC_LONG isc_dsql_cursor_exists = 336003092L; +const ISC_LONG isc_dsql_cursor_rel_ambiguous = 336003093L; +const ISC_LONG isc_dsql_cursor_rel_not_found = 336003094L; +const ISC_LONG isc_dsql_cursor_not_open = 336003095L; +const ISC_LONG isc_dsql_type_not_supp_ext_tab = 336003096L; +const ISC_LONG isc_dsql_feature_not_supported_ods = 336003097L; +const ISC_LONG isc_primary_key_required = 336003098L; +const ISC_LONG isc_upd_ins_doesnt_match_pk = 336003099L; +const ISC_LONG isc_upd_ins_doesnt_match_matching = 336003100L; +const ISC_LONG isc_upd_ins_with_complex_view = 336003101L; +const ISC_LONG isc_dsql_incompatible_trigger_type = 336003102L; +const ISC_LONG isc_dsql_db_trigger_type_cant_change = 336003103L; +const ISC_LONG isc_dyn_role_does_not_exist = 336068796L; +const ISC_LONG isc_dyn_no_grant_admin_opt = 336068797L; +const ISC_LONG isc_dyn_user_not_role_member = 336068798L; +const ISC_LONG isc_dyn_delete_role_failed = 336068799L; +const ISC_LONG isc_dyn_grant_role_to_user = 336068800L; +const ISC_LONG isc_dyn_inv_sql_role_name = 336068801L; +const ISC_LONG isc_dyn_dup_sql_role = 336068802L; +const ISC_LONG isc_dyn_kywd_spec_for_role = 336068803L; +const ISC_LONG isc_dyn_roles_not_supported = 336068804L; +const ISC_LONG isc_dyn_domain_name_exists = 336068812L; +const ISC_LONG isc_dyn_field_name_exists = 336068813L; +const ISC_LONG isc_dyn_dependency_exists = 336068814L; +const ISC_LONG isc_dyn_dtype_invalid = 336068815L; +const ISC_LONG isc_dyn_char_fld_too_small = 336068816L; +const ISC_LONG isc_dyn_invalid_dtype_conversion = 336068817L; +const ISC_LONG isc_dyn_dtype_conv_invalid = 336068818L; +const ISC_LONG isc_dyn_zero_len_id = 336068820L; +const ISC_LONG isc_max_coll_per_charset = 336068829L; +const ISC_LONG isc_invalid_coll_attr = 336068830L; +const ISC_LONG isc_dyn_wrong_gtt_scope = 336068840L; +const ISC_LONG isc_dyn_scale_too_big = 336068852L; +const ISC_LONG isc_dyn_precision_too_small = 336068853L; +const ISC_LONG isc_dyn_miss_priv_warning = 336068855L; +const ISC_LONG isc_dyn_ods_not_supp_feature = 336068856L; +const ISC_LONG isc_gbak_unknown_switch = 336330753L; +const ISC_LONG isc_gbak_page_size_missing = 336330754L; +const ISC_LONG isc_gbak_page_size_toobig = 336330755L; +const ISC_LONG isc_gbak_redir_ouput_missing = 336330756L; +const ISC_LONG isc_gbak_switches_conflict = 336330757L; +const ISC_LONG isc_gbak_unknown_device = 336330758L; +const ISC_LONG isc_gbak_no_protection = 336330759L; +const ISC_LONG isc_gbak_page_size_not_allowed = 336330760L; +const ISC_LONG isc_gbak_multi_source_dest = 336330761L; +const ISC_LONG isc_gbak_filename_missing = 336330762L; +const ISC_LONG isc_gbak_dup_inout_names = 336330763L; +const ISC_LONG isc_gbak_inv_page_size = 336330764L; +const ISC_LONG isc_gbak_db_specified = 336330765L; +const ISC_LONG isc_gbak_db_exists = 336330766L; +const ISC_LONG isc_gbak_unk_device = 336330767L; +const ISC_LONG isc_gbak_blob_info_failed = 336330772L; +const ISC_LONG isc_gbak_unk_blob_item = 336330773L; +const ISC_LONG isc_gbak_get_seg_failed = 336330774L; +const ISC_LONG isc_gbak_close_blob_failed = 336330775L; +const ISC_LONG isc_gbak_open_blob_failed = 336330776L; +const ISC_LONG isc_gbak_put_blr_gen_id_failed = 336330777L; +const ISC_LONG isc_gbak_unk_type = 336330778L; +const ISC_LONG isc_gbak_comp_req_failed = 336330779L; +const ISC_LONG isc_gbak_start_req_failed = 336330780L; +const ISC_LONG isc_gbak_rec_failed = 336330781L; +const ISC_LONG isc_gbak_rel_req_failed = 336330782L; +const ISC_LONG isc_gbak_db_info_failed = 336330783L; +const ISC_LONG isc_gbak_no_db_desc = 336330784L; +const ISC_LONG isc_gbak_db_create_failed = 336330785L; +const ISC_LONG isc_gbak_decomp_len_error = 336330786L; +const ISC_LONG isc_gbak_tbl_missing = 336330787L; +const ISC_LONG isc_gbak_blob_col_missing = 336330788L; +const ISC_LONG isc_gbak_create_blob_failed = 336330789L; +const ISC_LONG isc_gbak_put_seg_failed = 336330790L; +const ISC_LONG isc_gbak_rec_len_exp = 336330791L; +const ISC_LONG isc_gbak_inv_rec_len = 336330792L; +const ISC_LONG isc_gbak_exp_data_type = 336330793L; +const ISC_LONG isc_gbak_gen_id_failed = 336330794L; +const ISC_LONG isc_gbak_unk_rec_type = 336330795L; +const ISC_LONG isc_gbak_inv_bkup_ver = 336330796L; +const ISC_LONG isc_gbak_missing_bkup_desc = 336330797L; +const ISC_LONG isc_gbak_string_trunc = 336330798L; +const ISC_LONG isc_gbak_cant_rest_record = 336330799L; +const ISC_LONG isc_gbak_send_failed = 336330800L; +const ISC_LONG isc_gbak_no_tbl_name = 336330801L; +const ISC_LONG isc_gbak_unexp_eof = 336330802L; +const ISC_LONG isc_gbak_db_format_too_old = 336330803L; +const ISC_LONG isc_gbak_inv_array_dim = 336330804L; +const ISC_LONG isc_gbak_xdr_len_expected = 336330807L; +const ISC_LONG isc_gbak_open_bkup_error = 336330817L; +const ISC_LONG isc_gbak_open_error = 336330818L; +const ISC_LONG isc_gbak_missing_block_fac = 336330934L; +const ISC_LONG isc_gbak_inv_block_fac = 336330935L; +const ISC_LONG isc_gbak_block_fac_specified = 336330936L; +const ISC_LONG isc_gbak_missing_username = 336330940L; +const ISC_LONG isc_gbak_missing_password = 336330941L; +const ISC_LONG isc_gbak_missing_skipped_bytes = 336330952L; +const ISC_LONG isc_gbak_inv_skipped_bytes = 336330953L; +const ISC_LONG isc_gbak_err_restore_charset = 336330965L; +const ISC_LONG isc_gbak_err_restore_collation = 336330967L; +const ISC_LONG isc_gbak_read_error = 336330972L; +const ISC_LONG isc_gbak_write_error = 336330973L; +const ISC_LONG isc_gbak_db_in_use = 336330985L; +const ISC_LONG isc_gbak_sysmemex = 336330990L; +const ISC_LONG isc_gbak_restore_role_failed = 336331002L; +const ISC_LONG isc_gbak_role_op_missing = 336331005L; +const ISC_LONG isc_gbak_page_buffers_missing = 336331010L; +const ISC_LONG isc_gbak_page_buffers_wrong_param = 336331011L; +const ISC_LONG isc_gbak_page_buffers_restore = 336331012L; +const ISC_LONG isc_gbak_inv_size = 336331014L; +const ISC_LONG isc_gbak_file_outof_sequence = 336331015L; +const ISC_LONG isc_gbak_join_file_missing = 336331016L; +const ISC_LONG isc_gbak_stdin_not_supptd = 336331017L; +const ISC_LONG isc_gbak_stdout_not_supptd = 336331018L; +const ISC_LONG isc_gbak_bkup_corrupt = 336331019L; +const ISC_LONG isc_gbak_unk_db_file_spec = 336331020L; +const ISC_LONG isc_gbak_hdr_write_failed = 336331021L; +const ISC_LONG isc_gbak_disk_space_ex = 336331022L; +const ISC_LONG isc_gbak_size_lt_min = 336331023L; +const ISC_LONG isc_gbak_svc_name_missing = 336331025L; +const ISC_LONG isc_gbak_not_ownr = 336331026L; +const ISC_LONG isc_gbak_mode_req = 336331031L; +const ISC_LONG isc_gbak_just_data = 336331033L; +const ISC_LONG isc_gbak_data_only = 336331034L; +const ISC_LONG isc_dsql_too_old_ods = 336397205L; +const ISC_LONG isc_dsql_table_not_found = 336397206L; +const ISC_LONG isc_dsql_view_not_found = 336397207L; +const ISC_LONG isc_dsql_line_col_error = 336397208L; +const ISC_LONG isc_dsql_unknown_pos = 336397209L; +const ISC_LONG isc_dsql_no_dup_name = 336397210L; +const ISC_LONG isc_dsql_too_many_values = 336397211L; +const ISC_LONG isc_dsql_no_array_computed = 336397212L; +const ISC_LONG isc_dsql_implicit_domain_name = 336397213L; +const ISC_LONG isc_dsql_only_can_subscript_array = 336397214L; +const ISC_LONG isc_dsql_max_sort_items = 336397215L; +const ISC_LONG isc_dsql_max_group_items = 336397216L; +const ISC_LONG isc_dsql_conflicting_sort_field = 336397217L; +const ISC_LONG isc_dsql_derived_table_more_columns = 336397218L; +const ISC_LONG isc_dsql_derived_table_less_columns = 336397219L; +const ISC_LONG isc_dsql_derived_field_unnamed = 336397220L; +const ISC_LONG isc_dsql_derived_field_dup_name = 336397221L; +const ISC_LONG isc_dsql_derived_alias_select = 336397222L; +const ISC_LONG isc_dsql_derived_alias_field = 336397223L; +const ISC_LONG isc_dsql_auto_field_bad_pos = 336397224L; +const ISC_LONG isc_dsql_cte_wrong_reference = 336397225L; +const ISC_LONG isc_dsql_cte_cycle = 336397226L; +const ISC_LONG isc_dsql_cte_outer_join = 336397227L; +const ISC_LONG isc_dsql_cte_mult_references = 336397228L; +const ISC_LONG isc_dsql_cte_not_a_union = 336397229L; +const ISC_LONG isc_dsql_cte_nonrecurs_after_recurs = 336397230L; +const ISC_LONG isc_dsql_cte_wrong_clause = 336397231L; +const ISC_LONG isc_dsql_cte_union_all = 336397232L; +const ISC_LONG isc_dsql_cte_miss_nonrecursive = 336397233L; +const ISC_LONG isc_dsql_cte_nested_with = 336397234L; +const ISC_LONG isc_dsql_col_more_than_once_using = 336397235L; +const ISC_LONG isc_dsql_unsupp_feature_dialect = 336397236L; +const ISC_LONG isc_gsec_cant_open_db = 336723983L; +const ISC_LONG isc_gsec_switches_error = 336723984L; +const ISC_LONG isc_gsec_no_op_spec = 336723985L; +const ISC_LONG isc_gsec_no_usr_name = 336723986L; +const ISC_LONG isc_gsec_err_add = 336723987L; +const ISC_LONG isc_gsec_err_modify = 336723988L; +const ISC_LONG isc_gsec_err_find_mod = 336723989L; +const ISC_LONG isc_gsec_err_rec_not_found = 336723990L; +const ISC_LONG isc_gsec_err_delete = 336723991L; +const ISC_LONG isc_gsec_err_find_del = 336723992L; +const ISC_LONG isc_gsec_err_find_disp = 336723996L; +const ISC_LONG isc_gsec_inv_param = 336723997L; +const ISC_LONG isc_gsec_op_specified = 336723998L; +const ISC_LONG isc_gsec_pw_specified = 336723999L; +const ISC_LONG isc_gsec_uid_specified = 336724000L; +const ISC_LONG isc_gsec_gid_specified = 336724001L; +const ISC_LONG isc_gsec_proj_specified = 336724002L; +const ISC_LONG isc_gsec_org_specified = 336724003L; +const ISC_LONG isc_gsec_fname_specified = 336724004L; +const ISC_LONG isc_gsec_mname_specified = 336724005L; +const ISC_LONG isc_gsec_lname_specified = 336724006L; +const ISC_LONG isc_gsec_inv_switch = 336724008L; +const ISC_LONG isc_gsec_amb_switch = 336724009L; +const ISC_LONG isc_gsec_no_op_specified = 336724010L; +const ISC_LONG isc_gsec_params_not_allowed = 336724011L; +const ISC_LONG isc_gsec_incompat_switch = 336724012L; +const ISC_LONG isc_gsec_inv_username = 336724044L; +const ISC_LONG isc_gsec_inv_pw_length = 336724045L; +const ISC_LONG isc_gsec_db_specified = 336724046L; +const ISC_LONG isc_gsec_db_admin_specified = 336724047L; +const ISC_LONG isc_gsec_db_admin_pw_specified = 336724048L; +const ISC_LONG isc_gsec_sql_role_specified = 336724049L; +const ISC_LONG isc_license_no_file = 336789504L; +const ISC_LONG isc_license_op_specified = 336789523L; +const ISC_LONG isc_license_op_missing = 336789524L; +const ISC_LONG isc_license_inv_switch = 336789525L; +const ISC_LONG isc_license_inv_switch_combo = 336789526L; +const ISC_LONG isc_license_inv_op_combo = 336789527L; +const ISC_LONG isc_license_amb_switch = 336789528L; +const ISC_LONG isc_license_inv_parameter = 336789529L; +const ISC_LONG isc_license_param_specified = 336789530L; +const ISC_LONG isc_license_param_req = 336789531L; +const ISC_LONG isc_license_syntx_error = 336789532L; +const ISC_LONG isc_license_dup_id = 336789534L; +const ISC_LONG isc_license_inv_id_key = 336789535L; +const ISC_LONG isc_license_err_remove = 336789536L; +const ISC_LONG isc_license_err_update = 336789537L; +const ISC_LONG isc_license_err_convert = 336789538L; +const ISC_LONG isc_license_err_unk = 336789539L; +const ISC_LONG isc_license_svc_err_add = 336789540L; +const ISC_LONG isc_license_svc_err_remove = 336789541L; +const ISC_LONG isc_license_eval_exists = 336789563L; +const ISC_LONG isc_gstat_unknown_switch = 336920577L; +const ISC_LONG isc_gstat_retry = 336920578L; +const ISC_LONG isc_gstat_wrong_ods = 336920579L; +const ISC_LONG isc_gstat_unexpected_eof = 336920580L; +const ISC_LONG isc_gstat_open_err = 336920605L; +const ISC_LONG isc_gstat_read_err = 336920606L; +const ISC_LONG isc_gstat_sysmemex = 336920607L; +const ISC_LONG isc_fbsvcmgr_bad_am = 336986113L; +const ISC_LONG isc_fbsvcmgr_bad_wm = 336986114L; +const ISC_LONG isc_fbsvcmgr_bad_rs = 336986115L; +const ISC_LONG isc_fbsvcmgr_info_err = 336986116L; +const ISC_LONG isc_fbsvcmgr_query_err = 336986117L; +const ISC_LONG isc_fbsvcmgr_switch_unknown = 336986118L; +const ISC_LONG isc_err_max = 826; + +#else /* c definitions */ + +#define isc_facility 20 +#define isc_base 335544320L +#define isc_factor 1 + +#define isc_arg_end 0 /* end of argument list */ +#define isc_arg_gds 1 /* generic DSRI status value */ +#define isc_arg_string 2 /* string argument */ +#define isc_arg_cstring 3 /* count & string argument */ +#define isc_arg_number 4 /* numeric argument (long) */ +#define isc_arg_interpreted 5 /* interpreted status code (string) */ +#define isc_arg_vms 6 /* VAX/VMS status code (long) */ +#define isc_arg_unix 7 /* UNIX error code */ +#define isc_arg_domain 8 /* Apollo/Domain error code */ +#define isc_arg_dos 9 /* MSDOS/OS2 error code */ +#define isc_arg_mpexl 10 /* HP MPE/XL error code */ +#define isc_arg_mpexl_ipc 11 /* HP MPE/XL IPC error code */ +#define isc_arg_next_mach 15 /* NeXT/Mach error code */ +#define isc_arg_netware 16 /* NetWare error code */ +#define isc_arg_win32 17 /* Win32 error code */ +#define isc_arg_warning 18 /* warning argument */ + +#define isc_arith_except 335544321L +#define isc_bad_dbkey 335544322L +#define isc_bad_db_format 335544323L +#define isc_bad_db_handle 335544324L +#define isc_bad_dpb_content 335544325L +#define isc_bad_dpb_form 335544326L +#define isc_bad_req_handle 335544327L +#define isc_bad_segstr_handle 335544328L +#define isc_bad_segstr_id 335544329L +#define isc_bad_tpb_content 335544330L +#define isc_bad_tpb_form 335544331L +#define isc_bad_trans_handle 335544332L +#define isc_bug_check 335544333L +#define isc_convert_error 335544334L +#define isc_db_corrupt 335544335L +#define isc_deadlock 335544336L +#define isc_excess_trans 335544337L +#define isc_from_no_match 335544338L +#define isc_infinap 335544339L +#define isc_infona 335544340L +#define isc_infunk 335544341L +#define isc_integ_fail 335544342L +#define isc_invalid_blr 335544343L +#define isc_io_error 335544344L +#define isc_lock_conflict 335544345L +#define isc_metadata_corrupt 335544346L +#define isc_not_valid 335544347L +#define isc_no_cur_rec 335544348L +#define isc_no_dup 335544349L +#define isc_no_finish 335544350L +#define isc_no_meta_update 335544351L +#define isc_no_priv 335544352L +#define isc_no_recon 335544353L +#define isc_no_record 335544354L +#define isc_no_segstr_close 335544355L +#define isc_obsolete_metadata 335544356L +#define isc_open_trans 335544357L +#define isc_port_len 335544358L +#define isc_read_only_field 335544359L +#define isc_read_only_rel 335544360L +#define isc_read_only_trans 335544361L +#define isc_read_only_view 335544362L +#define isc_req_no_trans 335544363L +#define isc_req_sync 335544364L +#define isc_req_wrong_db 335544365L +#define isc_segment 335544366L +#define isc_segstr_eof 335544367L +#define isc_segstr_no_op 335544368L +#define isc_segstr_no_read 335544369L +#define isc_segstr_no_trans 335544370L +#define isc_segstr_no_write 335544371L +#define isc_segstr_wrong_db 335544372L +#define isc_sys_request 335544373L +#define isc_stream_eof 335544374L +#define isc_unavailable 335544375L +#define isc_unres_rel 335544376L +#define isc_uns_ext 335544377L +#define isc_wish_list 335544378L +#define isc_wrong_ods 335544379L +#define isc_wronumarg 335544380L +#define isc_imp_exc 335544381L +#define isc_random 335544382L +#define isc_fatal_conflict 335544383L +#define isc_badblk 335544384L +#define isc_invpoolcl 335544385L +#define isc_nopoolids 335544386L +#define isc_relbadblk 335544387L +#define isc_blktoobig 335544388L +#define isc_bufexh 335544389L +#define isc_syntaxerr 335544390L +#define isc_bufinuse 335544391L +#define isc_bdbincon 335544392L +#define isc_reqinuse 335544393L +#define isc_badodsver 335544394L +#define isc_relnotdef 335544395L +#define isc_fldnotdef 335544396L +#define isc_dirtypage 335544397L +#define isc_waifortra 335544398L +#define isc_doubleloc 335544399L +#define isc_nodnotfnd 335544400L +#define isc_dupnodfnd 335544401L +#define isc_locnotmar 335544402L +#define isc_badpagtyp 335544403L +#define isc_corrupt 335544404L +#define isc_badpage 335544405L +#define isc_badindex 335544406L +#define isc_dbbnotzer 335544407L +#define isc_tranotzer 335544408L +#define isc_trareqmis 335544409L +#define isc_badhndcnt 335544410L +#define isc_wrotpbver 335544411L +#define isc_wroblrver 335544412L +#define isc_wrodpbver 335544413L +#define isc_blobnotsup 335544414L +#define isc_badrelation 335544415L +#define isc_nodetach 335544416L +#define isc_notremote 335544417L +#define isc_trainlim 335544418L +#define isc_notinlim 335544419L +#define isc_traoutsta 335544420L +#define isc_connect_reject 335544421L +#define isc_dbfile 335544422L +#define isc_orphan 335544423L +#define isc_no_lock_mgr 335544424L +#define isc_ctxinuse 335544425L +#define isc_ctxnotdef 335544426L +#define isc_datnotsup 335544427L +#define isc_badmsgnum 335544428L +#define isc_badparnum 335544429L +#define isc_virmemexh 335544430L +#define isc_blocking_signal 335544431L +#define isc_lockmanerr 335544432L +#define isc_journerr 335544433L +#define isc_keytoobig 335544434L +#define isc_nullsegkey 335544435L +#define isc_sqlerr 335544436L +#define isc_wrodynver 335544437L +#define isc_funnotdef 335544438L +#define isc_funmismat 335544439L +#define isc_bad_msg_vec 335544440L +#define isc_bad_detach 335544441L +#define isc_noargacc_read 335544442L +#define isc_noargacc_write 335544443L +#define isc_read_only 335544444L +#define isc_ext_err 335544445L +#define isc_non_updatable 335544446L +#define isc_no_rollback 335544447L +#define isc_bad_sec_info 335544448L +#define isc_invalid_sec_info 335544449L +#define isc_misc_interpreted 335544450L +#define isc_update_conflict 335544451L +#define isc_unlicensed 335544452L +#define isc_obj_in_use 335544453L +#define isc_nofilter 335544454L +#define isc_shadow_accessed 335544455L +#define isc_invalid_sdl 335544456L +#define isc_out_of_bounds 335544457L +#define isc_invalid_dimension 335544458L +#define isc_rec_in_limbo 335544459L +#define isc_shadow_missing 335544460L +#define isc_cant_validate 335544461L +#define isc_cant_start_journal 335544462L +#define isc_gennotdef 335544463L +#define isc_cant_start_logging 335544464L +#define isc_bad_segstr_type 335544465L +#define isc_foreign_key 335544466L +#define isc_high_minor 335544467L +#define isc_tra_state 335544468L +#define isc_trans_invalid 335544469L +#define isc_buf_invalid 335544470L +#define isc_indexnotdefined 335544471L +#define isc_login 335544472L +#define isc_invalid_bookmark 335544473L +#define isc_bad_lock_level 335544474L +#define isc_relation_lock 335544475L +#define isc_record_lock 335544476L +#define isc_max_idx 335544477L +#define isc_jrn_enable 335544478L +#define isc_old_failure 335544479L +#define isc_old_in_progress 335544480L +#define isc_old_no_space 335544481L +#define isc_no_wal_no_jrn 335544482L +#define isc_num_old_files 335544483L +#define isc_wal_file_open 335544484L +#define isc_bad_stmt_handle 335544485L +#define isc_wal_failure 335544486L +#define isc_walw_err 335544487L +#define isc_logh_small 335544488L +#define isc_logh_inv_version 335544489L +#define isc_logh_open_flag 335544490L +#define isc_logh_open_flag2 335544491L +#define isc_logh_diff_dbname 335544492L +#define isc_logf_unexpected_eof 335544493L +#define isc_logr_incomplete 335544494L +#define isc_logr_header_small 335544495L +#define isc_logb_small 335544496L +#define isc_wal_illegal_attach 335544497L +#define isc_wal_invalid_wpb 335544498L +#define isc_wal_err_rollover 335544499L +#define isc_no_wal 335544500L +#define isc_drop_wal 335544501L +#define isc_stream_not_defined 335544502L +#define isc_wal_subsys_error 335544503L +#define isc_wal_subsys_corrupt 335544504L +#define isc_no_archive 335544505L +#define isc_shutinprog 335544506L +#define isc_range_in_use 335544507L +#define isc_range_not_found 335544508L +#define isc_charset_not_found 335544509L +#define isc_lock_timeout 335544510L +#define isc_prcnotdef 335544511L +#define isc_prcmismat 335544512L +#define isc_wal_bugcheck 335544513L +#define isc_wal_cant_expand 335544514L +#define isc_codnotdef 335544515L +#define isc_xcpnotdef 335544516L +#define isc_except 335544517L +#define isc_cache_restart 335544518L +#define isc_bad_lock_handle 335544519L +#define isc_jrn_present 335544520L +#define isc_wal_err_rollover2 335544521L +#define isc_wal_err_logwrite 335544522L +#define isc_wal_err_jrn_comm 335544523L +#define isc_wal_err_expansion 335544524L +#define isc_wal_err_setup 335544525L +#define isc_wal_err_ww_sync 335544526L +#define isc_wal_err_ww_start 335544527L +#define isc_shutdown 335544528L +#define isc_existing_priv_mod 335544529L +#define isc_primary_key_ref 335544530L +#define isc_primary_key_notnull 335544531L +#define isc_ref_cnstrnt_notfound 335544532L +#define isc_foreign_key_notfound 335544533L +#define isc_ref_cnstrnt_update 335544534L +#define isc_check_cnstrnt_update 335544535L +#define isc_check_cnstrnt_del 335544536L +#define isc_integ_index_seg_del 335544537L +#define isc_integ_index_seg_mod 335544538L +#define isc_integ_index_del 335544539L +#define isc_integ_index_mod 335544540L +#define isc_check_trig_del 335544541L +#define isc_check_trig_update 335544542L +#define isc_cnstrnt_fld_del 335544543L +#define isc_cnstrnt_fld_rename 335544544L +#define isc_rel_cnstrnt_update 335544545L +#define isc_constaint_on_view 335544546L +#define isc_invld_cnstrnt_type 335544547L +#define isc_primary_key_exists 335544548L +#define isc_systrig_update 335544549L +#define isc_not_rel_owner 335544550L +#define isc_grant_obj_notfound 335544551L +#define isc_grant_fld_notfound 335544552L +#define isc_grant_nopriv 335544553L +#define isc_nonsql_security_rel 335544554L +#define isc_nonsql_security_fld 335544555L +#define isc_wal_cache_err 335544556L +#define isc_shutfail 335544557L +#define isc_check_constraint 335544558L +#define isc_bad_svc_handle 335544559L +#define isc_shutwarn 335544560L +#define isc_wrospbver 335544561L +#define isc_bad_spb_form 335544562L +#define isc_svcnotdef 335544563L +#define isc_no_jrn 335544564L +#define isc_transliteration_failed 335544565L +#define isc_start_cm_for_wal 335544566L +#define isc_wal_ovflow_log_required 335544567L +#define isc_text_subtype 335544568L +#define isc_dsql_error 335544569L +#define isc_dsql_command_err 335544570L +#define isc_dsql_constant_err 335544571L +#define isc_dsql_cursor_err 335544572L +#define isc_dsql_datatype_err 335544573L +#define isc_dsql_decl_err 335544574L +#define isc_dsql_cursor_update_err 335544575L +#define isc_dsql_cursor_open_err 335544576L +#define isc_dsql_cursor_close_err 335544577L +#define isc_dsql_field_err 335544578L +#define isc_dsql_internal_err 335544579L +#define isc_dsql_relation_err 335544580L +#define isc_dsql_procedure_err 335544581L +#define isc_dsql_request_err 335544582L +#define isc_dsql_sqlda_err 335544583L +#define isc_dsql_var_count_err 335544584L +#define isc_dsql_stmt_handle 335544585L +#define isc_dsql_function_err 335544586L +#define isc_dsql_blob_err 335544587L +#define isc_collation_not_found 335544588L +#define isc_collation_not_for_charset 335544589L +#define isc_dsql_dup_option 335544590L +#define isc_dsql_tran_err 335544591L +#define isc_dsql_invalid_array 335544592L +#define isc_dsql_max_arr_dim_exceeded 335544593L +#define isc_dsql_arr_range_error 335544594L +#define isc_dsql_trigger_err 335544595L +#define isc_dsql_subselect_err 335544596L +#define isc_dsql_crdb_prepare_err 335544597L +#define isc_specify_field_err 335544598L +#define isc_num_field_err 335544599L +#define isc_col_name_err 335544600L +#define isc_where_err 335544601L +#define isc_table_view_err 335544602L +#define isc_distinct_err 335544603L +#define isc_key_field_count_err 335544604L +#define isc_subquery_err 335544605L +#define isc_expression_eval_err 335544606L +#define isc_node_err 335544607L +#define isc_command_end_err 335544608L +#define isc_index_name 335544609L +#define isc_exception_name 335544610L +#define isc_field_name 335544611L +#define isc_token_err 335544612L +#define isc_union_err 335544613L +#define isc_dsql_construct_err 335544614L +#define isc_field_aggregate_err 335544615L +#define isc_field_ref_err 335544616L +#define isc_order_by_err 335544617L +#define isc_return_mode_err 335544618L +#define isc_extern_func_err 335544619L +#define isc_alias_conflict_err 335544620L +#define isc_procedure_conflict_error 335544621L +#define isc_relation_conflict_err 335544622L +#define isc_dsql_domain_err 335544623L +#define isc_idx_seg_err 335544624L +#define isc_node_name_err 335544625L +#define isc_table_name 335544626L +#define isc_proc_name 335544627L +#define isc_idx_create_err 335544628L +#define isc_wal_shadow_err 335544629L +#define isc_dependency 335544630L +#define isc_idx_key_err 335544631L +#define isc_dsql_file_length_err 335544632L +#define isc_dsql_shadow_number_err 335544633L +#define isc_dsql_token_unk_err 335544634L +#define isc_dsql_no_relation_alias 335544635L +#define isc_indexname 335544636L +#define isc_no_stream_plan 335544637L +#define isc_stream_twice 335544638L +#define isc_stream_not_found 335544639L +#define isc_collation_requires_text 335544640L +#define isc_dsql_domain_not_found 335544641L +#define isc_index_unused 335544642L +#define isc_dsql_self_join 335544643L +#define isc_stream_bof 335544644L +#define isc_stream_crack 335544645L +#define isc_db_or_file_exists 335544646L +#define isc_invalid_operator 335544647L +#define isc_conn_lost 335544648L +#define isc_bad_checksum 335544649L +#define isc_page_type_err 335544650L +#define isc_ext_readonly_err 335544651L +#define isc_sing_select_err 335544652L +#define isc_psw_attach 335544653L +#define isc_psw_start_trans 335544654L +#define isc_invalid_direction 335544655L +#define isc_dsql_var_conflict 335544656L +#define isc_dsql_no_blob_array 335544657L +#define isc_dsql_base_table 335544658L +#define isc_duplicate_base_table 335544659L +#define isc_view_alias 335544660L +#define isc_index_root_page_full 335544661L +#define isc_dsql_blob_type_unknown 335544662L +#define isc_req_max_clones_exceeded 335544663L +#define isc_dsql_duplicate_spec 335544664L +#define isc_unique_key_violation 335544665L +#define isc_srvr_version_too_old 335544666L +#define isc_drdb_completed_with_errs 335544667L +#define isc_dsql_procedure_use_err 335544668L +#define isc_dsql_count_mismatch 335544669L +#define isc_blob_idx_err 335544670L +#define isc_array_idx_err 335544671L +#define isc_key_field_err 335544672L +#define isc_no_delete 335544673L +#define isc_del_last_field 335544674L +#define isc_sort_err 335544675L +#define isc_sort_mem_err 335544676L +#define isc_version_err 335544677L +#define isc_inval_key_posn 335544678L +#define isc_no_segments_err 335544679L +#define isc_crrp_data_err 335544680L +#define isc_rec_size_err 335544681L +#define isc_dsql_field_ref 335544682L +#define isc_req_depth_exceeded 335544683L +#define isc_no_field_access 335544684L +#define isc_no_dbkey 335544685L +#define isc_jrn_format_err 335544686L +#define isc_jrn_file_full 335544687L +#define isc_dsql_open_cursor_request 335544688L +#define isc_ib_error 335544689L +#define isc_cache_redef 335544690L +#define isc_cache_too_small 335544691L +#define isc_log_redef 335544692L +#define isc_log_too_small 335544693L +#define isc_partition_too_small 335544694L +#define isc_partition_not_supp 335544695L +#define isc_log_length_spec 335544696L +#define isc_precision_err 335544697L +#define isc_scale_nogt 335544698L +#define isc_expec_short 335544699L +#define isc_expec_long 335544700L +#define isc_expec_ushort 335544701L +#define isc_like_escape_invalid 335544702L +#define isc_svcnoexe 335544703L +#define isc_net_lookup_err 335544704L +#define isc_service_unknown 335544705L +#define isc_host_unknown 335544706L +#define isc_grant_nopriv_on_base 335544707L +#define isc_dyn_fld_ambiguous 335544708L +#define isc_dsql_agg_ref_err 335544709L +#define isc_complex_view 335544710L +#define isc_unprepared_stmt 335544711L +#define isc_expec_positive 335544712L +#define isc_dsql_sqlda_value_err 335544713L +#define isc_invalid_array_id 335544714L +#define isc_extfile_uns_op 335544715L +#define isc_svc_in_use 335544716L +#define isc_err_stack_limit 335544717L +#define isc_invalid_key 335544718L +#define isc_net_init_error 335544719L +#define isc_loadlib_failure 335544720L +#define isc_network_error 335544721L +#define isc_net_connect_err 335544722L +#define isc_net_connect_listen_err 335544723L +#define isc_net_event_connect_err 335544724L +#define isc_net_event_listen_err 335544725L +#define isc_net_read_err 335544726L +#define isc_net_write_err 335544727L +#define isc_integ_index_deactivate 335544728L +#define isc_integ_deactivate_primary 335544729L +#define isc_cse_not_supported 335544730L +#define isc_tra_must_sweep 335544731L +#define isc_unsupported_network_drive 335544732L +#define isc_io_create_err 335544733L +#define isc_io_open_err 335544734L +#define isc_io_close_err 335544735L +#define isc_io_read_err 335544736L +#define isc_io_write_err 335544737L +#define isc_io_delete_err 335544738L +#define isc_io_access_err 335544739L +#define isc_udf_exception 335544740L +#define isc_lost_db_connection 335544741L +#define isc_no_write_user_priv 335544742L +#define isc_token_too_long 335544743L +#define isc_max_att_exceeded 335544744L +#define isc_login_same_as_role_name 335544745L +#define isc_reftable_requires_pk 335544746L +#define isc_usrname_too_long 335544747L +#define isc_password_too_long 335544748L +#define isc_usrname_required 335544749L +#define isc_password_required 335544750L +#define isc_bad_protocol 335544751L +#define isc_dup_usrname_found 335544752L +#define isc_usrname_not_found 335544753L +#define isc_error_adding_sec_record 335544754L +#define isc_error_modifying_sec_record 335544755L +#define isc_error_deleting_sec_record 335544756L +#define isc_error_updating_sec_db 335544757L +#define isc_sort_rec_size_err 335544758L +#define isc_bad_default_value 335544759L +#define isc_invalid_clause 335544760L +#define isc_too_many_handles 335544761L +#define isc_optimizer_blk_exc 335544762L +#define isc_invalid_string_constant 335544763L +#define isc_transitional_date 335544764L +#define isc_read_only_database 335544765L +#define isc_must_be_dialect_2_and_up 335544766L +#define isc_blob_filter_exception 335544767L +#define isc_exception_access_violation 335544768L +#define isc_exception_datatype_missalignment 335544769L +#define isc_exception_array_bounds_exceeded 335544770L +#define isc_exception_float_denormal_operand 335544771L +#define isc_exception_float_divide_by_zero 335544772L +#define isc_exception_float_inexact_result 335544773L +#define isc_exception_float_invalid_operand 335544774L +#define isc_exception_float_overflow 335544775L +#define isc_exception_float_stack_check 335544776L +#define isc_exception_float_underflow 335544777L +#define isc_exception_integer_divide_by_zero 335544778L +#define isc_exception_integer_overflow 335544779L +#define isc_exception_unknown 335544780L +#define isc_exception_stack_overflow 335544781L +#define isc_exception_sigsegv 335544782L +#define isc_exception_sigill 335544783L +#define isc_exception_sigbus 335544784L +#define isc_exception_sigfpe 335544785L +#define isc_ext_file_delete 335544786L +#define isc_ext_file_modify 335544787L +#define isc_adm_task_denied 335544788L +#define isc_extract_input_mismatch 335544789L +#define isc_insufficient_svc_privileges 335544790L +#define isc_file_in_use 335544791L +#define isc_service_att_err 335544792L +#define isc_ddl_not_allowed_by_db_sql_dial 335544793L +#define isc_cancelled 335544794L +#define isc_unexp_spb_form 335544795L +#define isc_sql_dialect_datatype_unsupport 335544796L +#define isc_svcnouser 335544797L +#define isc_depend_on_uncommitted_rel 335544798L +#define isc_svc_name_missing 335544799L +#define isc_too_many_contexts 335544800L +#define isc_datype_notsup 335544801L +#define isc_dialect_reset_warning 335544802L +#define isc_dialect_not_changed 335544803L +#define isc_database_create_failed 335544804L +#define isc_inv_dialect_specified 335544805L +#define isc_valid_db_dialects 335544806L +#define isc_sqlwarn 335544807L +#define isc_dtype_renamed 335544808L +#define isc_extern_func_dir_error 335544809L +#define isc_date_range_exceeded 335544810L +#define isc_inv_client_dialect_specified 335544811L +#define isc_valid_client_dialects 335544812L +#define isc_optimizer_between_err 335544813L +#define isc_service_not_supported 335544814L +#define isc_generator_name 335544815L +#define isc_udf_name 335544816L +#define isc_bad_limit_param 335544817L +#define isc_bad_skip_param 335544818L +#define isc_io_32bit_exceeded_err 335544819L +#define isc_invalid_savepoint 335544820L +#define isc_dsql_column_pos_err 335544821L +#define isc_dsql_agg_where_err 335544822L +#define isc_dsql_agg_group_err 335544823L +#define isc_dsql_agg_column_err 335544824L +#define isc_dsql_agg_having_err 335544825L +#define isc_dsql_agg_nested_err 335544826L +#define isc_exec_sql_invalid_arg 335544827L +#define isc_exec_sql_invalid_req 335544828L +#define isc_exec_sql_invalid_var 335544829L +#define isc_exec_sql_max_call_exceeded 335544830L +#define isc_conf_access_denied 335544831L +#define isc_wrong_backup_state 335544832L +#define isc_wal_backup_err 335544833L +#define isc_cursor_not_open 335544834L +#define isc_bad_shutdown_mode 335544835L +#define isc_concat_overflow 335544836L +#define isc_bad_substring_offset 335544837L +#define isc_foreign_key_target_doesnt_exist 335544838L +#define isc_foreign_key_references_present 335544839L +#define isc_no_update 335544840L +#define isc_cursor_already_open 335544841L +#define isc_stack_trace 335544842L +#define isc_ctx_var_not_found 335544843L +#define isc_ctx_namespace_invalid 335544844L +#define isc_ctx_too_big 335544845L +#define isc_ctx_bad_argument 335544846L +#define isc_identifier_too_long 335544847L +#define isc_except2 335544848L +#define isc_malformed_string 335544849L +#define isc_prc_out_param_mismatch 335544850L +#define isc_command_end_err2 335544851L +#define isc_partner_idx_incompat_type 335544852L +#define isc_bad_substring_length 335544853L +#define isc_charset_not_installed 335544854L +#define isc_collation_not_installed 335544855L +#define isc_att_shutdown 335544856L +#define isc_blobtoobig 335544857L +#define isc_must_have_phys_field 335544858L +#define isc_invalid_time_precision 335544859L +#define isc_blob_convert_error 335544860L +#define isc_array_convert_error 335544861L +#define isc_record_lock_not_supp 335544862L +#define isc_partner_idx_not_found 335544863L +#define isc_tra_num_exc 335544864L +#define isc_field_disappeared 335544865L +#define isc_met_wrong_gtt_scope 335544866L +#define isc_subtype_for_internal_use 335544867L +#define isc_illegal_prc_type 335544868L +#define isc_invalid_sort_datatype 335544869L +#define isc_collation_name 335544870L +#define isc_domain_name 335544871L +#define isc_domnotdef 335544872L +#define isc_array_max_dimensions 335544873L +#define isc_max_db_per_trans_allowed 335544874L +#define isc_bad_debug_format 335544875L +#define isc_bad_proc_BLR 335544876L +#define isc_key_too_big 335544877L +#define isc_concurrent_transaction 335544878L +#define isc_not_valid_for_var 335544879L +#define isc_not_valid_for 335544880L +#define isc_need_difference 335544881L +#define isc_long_login 335544882L +#define isc_fldnotdef2 335544883L +#define isc_gfix_db_name 335740929L +#define isc_gfix_invalid_sw 335740930L +#define isc_gfix_incmp_sw 335740932L +#define isc_gfix_replay_req 335740933L +#define isc_gfix_pgbuf_req 335740934L +#define isc_gfix_val_req 335740935L +#define isc_gfix_pval_req 335740936L +#define isc_gfix_trn_req 335740937L +#define isc_gfix_full_req 335740940L +#define isc_gfix_usrname_req 335740941L +#define isc_gfix_pass_req 335740942L +#define isc_gfix_subs_name 335740943L +#define isc_gfix_wal_req 335740944L +#define isc_gfix_sec_req 335740945L +#define isc_gfix_nval_req 335740946L +#define isc_gfix_type_shut 335740947L +#define isc_gfix_retry 335740948L +#define isc_gfix_retry_db 335740951L +#define isc_gfix_exceed_max 335740991L +#define isc_gfix_corrupt_pool 335740992L +#define isc_gfix_mem_exhausted 335740993L +#define isc_gfix_bad_pool 335740994L +#define isc_gfix_trn_not_valid 335740995L +#define isc_gfix_unexp_eoi 335741012L +#define isc_gfix_recon_fail 335741018L +#define isc_gfix_trn_unknown 335741036L +#define isc_gfix_mode_req 335741038L +#define isc_gfix_opt_SQL_dialect 335741039L +#define isc_gfix_pzval_req 335741042L +#define isc_dsql_dbkey_from_non_table 336003074L +#define isc_dsql_transitional_numeric 336003075L +#define isc_dsql_dialect_warning_expr 336003076L +#define isc_sql_db_dialect_dtype_unsupport 336003077L +#define isc_isc_sql_dialect_conflict_num 336003079L +#define isc_dsql_warning_number_ambiguous 336003080L +#define isc_dsql_warning_number_ambiguous1 336003081L +#define isc_dsql_warn_precision_ambiguous 336003082L +#define isc_dsql_warn_precision_ambiguous1 336003083L +#define isc_dsql_warn_precision_ambiguous2 336003084L +#define isc_dsql_ambiguous_field_name 336003085L +#define isc_dsql_udf_return_pos_err 336003086L +#define isc_dsql_invalid_label 336003087L +#define isc_dsql_datatypes_not_comparable 336003088L +#define isc_dsql_cursor_invalid 336003089L +#define isc_dsql_cursor_redefined 336003090L +#define isc_dsql_cursor_not_found 336003091L +#define isc_dsql_cursor_exists 336003092L +#define isc_dsql_cursor_rel_ambiguous 336003093L +#define isc_dsql_cursor_rel_not_found 336003094L +#define isc_dsql_cursor_not_open 336003095L +#define isc_dsql_type_not_supp_ext_tab 336003096L +#define isc_dsql_feature_not_supported_ods 336003097L +#define isc_primary_key_required 336003098L +#define isc_upd_ins_doesnt_match_pk 336003099L +#define isc_upd_ins_doesnt_match_matching 336003100L +#define isc_upd_ins_with_complex_view 336003101L +#define isc_dsql_incompatible_trigger_type 336003102L +#define isc_dsql_db_trigger_type_cant_change 336003103L +#define isc_dyn_role_does_not_exist 336068796L +#define isc_dyn_no_grant_admin_opt 336068797L +#define isc_dyn_user_not_role_member 336068798L +#define isc_dyn_delete_role_failed 336068799L +#define isc_dyn_grant_role_to_user 336068800L +#define isc_dyn_inv_sql_role_name 336068801L +#define isc_dyn_dup_sql_role 336068802L +#define isc_dyn_kywd_spec_for_role 336068803L +#define isc_dyn_roles_not_supported 336068804L +#define isc_dyn_domain_name_exists 336068812L +#define isc_dyn_field_name_exists 336068813L +#define isc_dyn_dependency_exists 336068814L +#define isc_dyn_dtype_invalid 336068815L +#define isc_dyn_char_fld_too_small 336068816L +#define isc_dyn_invalid_dtype_conversion 336068817L +#define isc_dyn_dtype_conv_invalid 336068818L +#define isc_dyn_zero_len_id 336068820L +#define isc_max_coll_per_charset 336068829L +#define isc_invalid_coll_attr 336068830L +#define isc_dyn_wrong_gtt_scope 336068840L +#define isc_dyn_scale_too_big 336068852L +#define isc_dyn_precision_too_small 336068853L +#define isc_dyn_miss_priv_warning 336068855L +#define isc_dyn_ods_not_supp_feature 336068856L +#define isc_gbak_unknown_switch 336330753L +#define isc_gbak_page_size_missing 336330754L +#define isc_gbak_page_size_toobig 336330755L +#define isc_gbak_redir_ouput_missing 336330756L +#define isc_gbak_switches_conflict 336330757L +#define isc_gbak_unknown_device 336330758L +#define isc_gbak_no_protection 336330759L +#define isc_gbak_page_size_not_allowed 336330760L +#define isc_gbak_multi_source_dest 336330761L +#define isc_gbak_filename_missing 336330762L +#define isc_gbak_dup_inout_names 336330763L +#define isc_gbak_inv_page_size 336330764L +#define isc_gbak_db_specified 336330765L +#define isc_gbak_db_exists 336330766L +#define isc_gbak_unk_device 336330767L +#define isc_gbak_blob_info_failed 336330772L +#define isc_gbak_unk_blob_item 336330773L +#define isc_gbak_get_seg_failed 336330774L +#define isc_gbak_close_blob_failed 336330775L +#define isc_gbak_open_blob_failed 336330776L +#define isc_gbak_put_blr_gen_id_failed 336330777L +#define isc_gbak_unk_type 336330778L +#define isc_gbak_comp_req_failed 336330779L +#define isc_gbak_start_req_failed 336330780L +#define isc_gbak_rec_failed 336330781L +#define isc_gbak_rel_req_failed 336330782L +#define isc_gbak_db_info_failed 336330783L +#define isc_gbak_no_db_desc 336330784L +#define isc_gbak_db_create_failed 336330785L +#define isc_gbak_decomp_len_error 336330786L +#define isc_gbak_tbl_missing 336330787L +#define isc_gbak_blob_col_missing 336330788L +#define isc_gbak_create_blob_failed 336330789L +#define isc_gbak_put_seg_failed 336330790L +#define isc_gbak_rec_len_exp 336330791L +#define isc_gbak_inv_rec_len 336330792L +#define isc_gbak_exp_data_type 336330793L +#define isc_gbak_gen_id_failed 336330794L +#define isc_gbak_unk_rec_type 336330795L +#define isc_gbak_inv_bkup_ver 336330796L +#define isc_gbak_missing_bkup_desc 336330797L +#define isc_gbak_string_trunc 336330798L +#define isc_gbak_cant_rest_record 336330799L +#define isc_gbak_send_failed 336330800L +#define isc_gbak_no_tbl_name 336330801L +#define isc_gbak_unexp_eof 336330802L +#define isc_gbak_db_format_too_old 336330803L +#define isc_gbak_inv_array_dim 336330804L +#define isc_gbak_xdr_len_expected 336330807L +#define isc_gbak_open_bkup_error 336330817L +#define isc_gbak_open_error 336330818L +#define isc_gbak_missing_block_fac 336330934L +#define isc_gbak_inv_block_fac 336330935L +#define isc_gbak_block_fac_specified 336330936L +#define isc_gbak_missing_username 336330940L +#define isc_gbak_missing_password 336330941L +#define isc_gbak_missing_skipped_bytes 336330952L +#define isc_gbak_inv_skipped_bytes 336330953L +#define isc_gbak_err_restore_charset 336330965L +#define isc_gbak_err_restore_collation 336330967L +#define isc_gbak_read_error 336330972L +#define isc_gbak_write_error 336330973L +#define isc_gbak_db_in_use 336330985L +#define isc_gbak_sysmemex 336330990L +#define isc_gbak_restore_role_failed 336331002L +#define isc_gbak_role_op_missing 336331005L +#define isc_gbak_page_buffers_missing 336331010L +#define isc_gbak_page_buffers_wrong_param 336331011L +#define isc_gbak_page_buffers_restore 336331012L +#define isc_gbak_inv_size 336331014L +#define isc_gbak_file_outof_sequence 336331015L +#define isc_gbak_join_file_missing 336331016L +#define isc_gbak_stdin_not_supptd 336331017L +#define isc_gbak_stdout_not_supptd 336331018L +#define isc_gbak_bkup_corrupt 336331019L +#define isc_gbak_unk_db_file_spec 336331020L +#define isc_gbak_hdr_write_failed 336331021L +#define isc_gbak_disk_space_ex 336331022L +#define isc_gbak_size_lt_min 336331023L +#define isc_gbak_svc_name_missing 336331025L +#define isc_gbak_not_ownr 336331026L +#define isc_gbak_mode_req 336331031L +#define isc_gbak_just_data 336331033L +#define isc_gbak_data_only 336331034L +#define isc_dsql_too_old_ods 336397205L +#define isc_dsql_table_not_found 336397206L +#define isc_dsql_view_not_found 336397207L +#define isc_dsql_line_col_error 336397208L +#define isc_dsql_unknown_pos 336397209L +#define isc_dsql_no_dup_name 336397210L +#define isc_dsql_too_many_values 336397211L +#define isc_dsql_no_array_computed 336397212L +#define isc_dsql_implicit_domain_name 336397213L +#define isc_dsql_only_can_subscript_array 336397214L +#define isc_dsql_max_sort_items 336397215L +#define isc_dsql_max_group_items 336397216L +#define isc_dsql_conflicting_sort_field 336397217L +#define isc_dsql_derived_table_more_columns 336397218L +#define isc_dsql_derived_table_less_columns 336397219L +#define isc_dsql_derived_field_unnamed 336397220L +#define isc_dsql_derived_field_dup_name 336397221L +#define isc_dsql_derived_alias_select 336397222L +#define isc_dsql_derived_alias_field 336397223L +#define isc_dsql_auto_field_bad_pos 336397224L +#define isc_dsql_cte_wrong_reference 336397225L +#define isc_dsql_cte_cycle 336397226L +#define isc_dsql_cte_outer_join 336397227L +#define isc_dsql_cte_mult_references 336397228L +#define isc_dsql_cte_not_a_union 336397229L +#define isc_dsql_cte_nonrecurs_after_recurs 336397230L +#define isc_dsql_cte_wrong_clause 336397231L +#define isc_dsql_cte_union_all 336397232L +#define isc_dsql_cte_miss_nonrecursive 336397233L +#define isc_dsql_cte_nested_with 336397234L +#define isc_dsql_col_more_than_once_using 336397235L +#define isc_dsql_unsupp_feature_dialect 336397236L +#define isc_gsec_cant_open_db 336723983L +#define isc_gsec_switches_error 336723984L +#define isc_gsec_no_op_spec 336723985L +#define isc_gsec_no_usr_name 336723986L +#define isc_gsec_err_add 336723987L +#define isc_gsec_err_modify 336723988L +#define isc_gsec_err_find_mod 336723989L +#define isc_gsec_err_rec_not_found 336723990L +#define isc_gsec_err_delete 336723991L +#define isc_gsec_err_find_del 336723992L +#define isc_gsec_err_find_disp 336723996L +#define isc_gsec_inv_param 336723997L +#define isc_gsec_op_specified 336723998L +#define isc_gsec_pw_specified 336723999L +#define isc_gsec_uid_specified 336724000L +#define isc_gsec_gid_specified 336724001L +#define isc_gsec_proj_specified 336724002L +#define isc_gsec_org_specified 336724003L +#define isc_gsec_fname_specified 336724004L +#define isc_gsec_mname_specified 336724005L +#define isc_gsec_lname_specified 336724006L +#define isc_gsec_inv_switch 336724008L +#define isc_gsec_amb_switch 336724009L +#define isc_gsec_no_op_specified 336724010L +#define isc_gsec_params_not_allowed 336724011L +#define isc_gsec_incompat_switch 336724012L +#define isc_gsec_inv_username 336724044L +#define isc_gsec_inv_pw_length 336724045L +#define isc_gsec_db_specified 336724046L +#define isc_gsec_db_admin_specified 336724047L +#define isc_gsec_db_admin_pw_specified 336724048L +#define isc_gsec_sql_role_specified 336724049L +#define isc_license_no_file 336789504L +#define isc_license_op_specified 336789523L +#define isc_license_op_missing 336789524L +#define isc_license_inv_switch 336789525L +#define isc_license_inv_switch_combo 336789526L +#define isc_license_inv_op_combo 336789527L +#define isc_license_amb_switch 336789528L +#define isc_license_inv_parameter 336789529L +#define isc_license_param_specified 336789530L +#define isc_license_param_req 336789531L +#define isc_license_syntx_error 336789532L +#define isc_license_dup_id 336789534L +#define isc_license_inv_id_key 336789535L +#define isc_license_err_remove 336789536L +#define isc_license_err_update 336789537L +#define isc_license_err_convert 336789538L +#define isc_license_err_unk 336789539L +#define isc_license_svc_err_add 336789540L +#define isc_license_svc_err_remove 336789541L +#define isc_license_eval_exists 336789563L +#define isc_gstat_unknown_switch 336920577L +#define isc_gstat_retry 336920578L +#define isc_gstat_wrong_ods 336920579L +#define isc_gstat_unexpected_eof 336920580L +#define isc_gstat_open_err 336920605L +#define isc_gstat_read_err 336920606L +#define isc_gstat_sysmemex 336920607L +#define isc_fbsvcmgr_bad_am 336986113L +#define isc_fbsvcmgr_bad_wm 336986114L +#define isc_fbsvcmgr_bad_rs 336986115L +#define isc_fbsvcmgr_info_err 336986116L +#define isc_fbsvcmgr_query_err 336986117L +#define isc_fbsvcmgr_switch_unknown 336986118L +#define isc_err_max 826 + +#endif + +#endif /* JRD_GEN_IBERROR_H */ diff --git a/libodbc/include/infAPI.h b/libodbc/include/infAPI.h new file mode 100644 index 0000000000..15ead30dbd --- /dev/null +++ b/libodbc/include/infAPI.h @@ -0,0 +1,432 @@ +// infAPI.h +// +////////////////////////////////////////////////////////////////////// + +#if !defined(__INFAPI_H__) +#define __INFAPI_H__ + +#include "SQLAPI.h" + +// API header(s) +#include + +extern long g_nInfDLLVersionLoaded; + +extern void AddInfSupport(const SAConnection * pCon); +extern void ReleaseInfSupport(); + +typedef SQLRETURN (SQL_API *SQLAllocConnect_t)(SQLHENV EnvironmentHandle, + SQLHDBC *ConnectionHandle); +typedef SQLRETURN (SQL_API *SQLAllocEnv_t)(SQLHENV *EnvironmentHandle); +typedef SQLRETURN (SQL_API *SQLAllocHandle_t)(SQLSMALLINT HandleType, + SQLHANDLE InputHandle, SQLHANDLE *OutputHandle); +typedef SQLRETURN (SQL_API *SQLAllocStmt_t)(SQLHDBC ConnectionHandle, + SQLHSTMT *StatementHandle); +typedef SQLRETURN (SQL_API *SQLBindCol_t)(SQLHSTMT StatementHandle, + SQLUSMALLINT ColumnNumber, SQLSMALLINT TargetType, + SQLPOINTER TargetValue, SQLLEN BufferLength, + SQLLEN *StrLen_or_Ind); +typedef SQLRETURN (SQL_API *SQLBindParameter_t)( + SQLHSTMT hstmt, + SQLUSMALLINT ipar, + SQLSMALLINT fParamType, + SQLSMALLINT fCType, + SQLSMALLINT fSqlType, + SQLULEN cbColDef, + SQLSMALLINT ibScale, + SQLPOINTER rgbValue, + SQLLEN cbValueMax, + SQLLEN *pcbValue); +typedef SQLRETURN (SQL_API *SQLBrowseConnect_t)( + SQLHDBC hdbc, + SQLTCHAR *szConnStrIn, + SQLSMALLINT cbConnStrIn, + SQLTCHAR *szConnStrOut, + SQLSMALLINT cbConnStrOutMax, + SQLSMALLINT *pcbConnStrOut); +typedef SQLRETURN (SQL_API *SQLBulkOperations_t)( + SQLHSTMT StatementHandle, + SQLSMALLINT Operation); +typedef SQLRETURN (SQL_API *SQLCancel_t)(SQLHSTMT StatementHandle); +typedef SQLRETURN (SQL_API *SQLCloseCursor_t)(SQLHSTMT StatementHandle); +#if defined(SA_UNICODE) && (defined(SA_64BIT) || defined(WIN64) || defined(ODBC64)) +typedef SQLRETURN (SQL_API *SQLColAttribute_t)(SQLHSTMT StatementHandle, + SQLUSMALLINT ColumnNumber, SQLUSMALLINT FieldIdentifier, + SQLPOINTER CharacterAttribute, SQLSMALLINT BufferLength, + SQLSMALLINT *StringLength, SQLLEN* NumericAttribute); +#else +typedef SQLRETURN (SQL_API *SQLColAttribute_t)(SQLHSTMT StatementHandle, + SQLUSMALLINT ColumnNumber, SQLUSMALLINT FieldIdentifier, + SQLPOINTER CharacterAttribute, SQLSMALLINT BufferLength, + SQLSMALLINT *StringLength, SQLPOINTER NumericAttribute); +#endif +typedef SQLRETURN (SQL_API *SQLColAttributes_t)( + SQLHSTMT hstmt, + SQLUSMALLINT icol, + SQLUSMALLINT fDescType, + SQLPOINTER rgbDesc, + SQLSMALLINT cbDescMax, + SQLSMALLINT *pcbDesc, + SQLLEN *pfDesc); +typedef SQLRETURN (SQL_API *SQLColumnPrivileges_t)( + SQLHSTMT hstmt, + SQLTCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLTCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLTCHAR *szTableName, + SQLSMALLINT cbTableName, + SQLTCHAR *szColumnName, + SQLSMALLINT cbColumnName); +typedef SQLRETURN (SQL_API *SQLColumns_t)(SQLHSTMT StatementHandle, + SQLTCHAR *CatalogName, SQLSMALLINT NameLength1, + SQLTCHAR *SchemaName, SQLSMALLINT NameLength2, + SQLTCHAR *TableName, SQLSMALLINT NameLength3, + SQLTCHAR *ColumnName, SQLSMALLINT NameLength4); +typedef SQLRETURN (SQL_API *SQLConnect_t)(SQLHDBC ConnectionHandle, + SQLTCHAR *ServerName, SQLSMALLINT NameLength1, + SQLTCHAR *UserName, SQLSMALLINT NameLength2, + SQLTCHAR *Authentication, SQLSMALLINT NameLength3); +typedef SQLRETURN (SQL_API *SQLCopyDesc_t)(SQLHDESC SourceDescHandle, + SQLHDESC TargetDescHandle); +typedef SQLRETURN (SQL_API *SQLDataSources_t)(SQLHENV EnvironmentHandle, + SQLUSMALLINT Direction, SQLTCHAR *ServerName, + SQLSMALLINT BufferLength1, SQLSMALLINT *NameLength1, + SQLTCHAR *Description, SQLSMALLINT BufferLength2, + SQLSMALLINT *NameLength2); +typedef SQLRETURN (SQL_API *SQLDescribeCol_t)(SQLHSTMT StatementHandle, + SQLUSMALLINT ColumnNumber, SQLTCHAR *ColumnName, + SQLSMALLINT BufferLength, SQLSMALLINT *NameLength, + SQLSMALLINT *DataType, SQLULEN *ColumnSize, + SQLSMALLINT *DecimalDigits, SQLSMALLINT *Nullable); +typedef SQLRETURN (SQL_API *SQLDescribeParam_t)( + SQLHSTMT hstmt, + SQLUSMALLINT ipar, + SQLSMALLINT *pfSqlType, + SQLULEN *pcbParamDef, + SQLSMALLINT *pibScale, + SQLSMALLINT *pfNullable); +typedef SQLRETURN (SQL_API *SQLDisconnect_t)(SQLHDBC ConnectionHandle); +typedef SQLRETURN (SQL_API *SQLDriverConnect_t)( + SQLHDBC hdbc, + SQLHWND hwnd, + SQLTCHAR *szConnStrIn, + SQLSMALLINT cbConnStrIn, + SQLTCHAR *szConnStrOut, + SQLSMALLINT cbConnStrOutMax, + SQLSMALLINT *pcbConnStrOut, + SQLUSMALLINT fDriverCompletion); +typedef SQLRETURN (SQL_API *SQLDrivers_t)( + SQLHENV henv, + SQLUSMALLINT fDirection, + SQLTCHAR *szDriverDesc, + SQLSMALLINT cbDriverDescMax, + SQLSMALLINT *pcbDriverDesc, + SQLTCHAR *szDriverAttributes, + SQLSMALLINT cbDrvrAttrMax, + SQLSMALLINT *pcbDrvrAttr); +typedef SQLRETURN (SQL_API *SQLEndTran_t)(SQLSMALLINT HandleType, SQLHANDLE Handle, + SQLSMALLINT CompletionType); +typedef SQLRETURN (SQL_API *SQLError_t)(SQLHENV EnvironmentHandle, + SQLHDBC ConnectionHandle, SQLHSTMT StatementHandle, + SQLTCHAR *Sqlstate, SQLINTEGER *NativeError, + SQLTCHAR *MessageText, SQLSMALLINT BufferLength, + SQLSMALLINT *TextLength); +typedef SQLRETURN (SQL_API *SQLExecDirect_t)(SQLHSTMT StatementHandle, + SQLTCHAR *StatementText, SQLINTEGER TextLength); +typedef SQLRETURN (SQL_API *SQLExecute_t)(SQLHSTMT StatementHandle); +typedef SQLRETURN (SQL_API *SQLExtendedFetch_t)( + SQLHSTMT hstmt, + SQLUSMALLINT fFetchType, + SQLINTEGER irow, + SQLUINTEGER *pcrow, + SQLUSMALLINT *rgfRowStatus); +typedef SQLRETURN (SQL_API *SQLFetch_t)(SQLHSTMT StatementHandle); +typedef SQLRETURN (SQL_API *SQLFetchScroll_t)(SQLHSTMT StatementHandle, + SQLSMALLINT FetchOrientation, SQLLEN FetchOffset); +typedef SQLRETURN (SQL_API *SQLForeignKeys_t)( + SQLHSTMT hstmt, + SQLTCHAR *szPkCatalogName, + SQLSMALLINT cbPkCatalogName, + SQLTCHAR *szPkSchemaName, + SQLSMALLINT cbPkSchemaName, + SQLTCHAR *szPkTableName, + SQLSMALLINT cbPkTableName, + SQLTCHAR *szFkCatalogName, + SQLSMALLINT cbFkCatalogName, + SQLTCHAR *szFkSchemaName, + SQLSMALLINT cbFkSchemaName, + SQLTCHAR *szFkTableName, + SQLSMALLINT cbFkTableName); +typedef SQLRETURN (SQL_API *SQLFreeConnect_t)(SQLHDBC ConnectionHandle); +typedef SQLRETURN (SQL_API *SQLFreeEnv_t)(SQLHENV EnvironmentHandle); +typedef SQLRETURN (SQL_API *SQLFreeHandle_t)(SQLSMALLINT HandleType, SQLHANDLE Handle); +typedef SQLRETURN (SQL_API *SQLFreeStmt_t)(SQLHSTMT StatementHandle, + SQLUSMALLINT Option); +typedef SQLRETURN (SQL_API *SQLGetConnectAttr_t)(SQLHDBC ConnectionHandle, + SQLINTEGER Attribute, SQLPOINTER Value, + SQLINTEGER BufferLength, SQLINTEGER *StringLength); +typedef SQLRETURN (SQL_API *SQLGetConnectOption_t)(SQLHDBC ConnectionHandle, + SQLUSMALLINT Option, SQLPOINTER Value); +typedef SQLRETURN (SQL_API *SQLGetCursorName_t)(SQLHSTMT StatementHandle, + SQLTCHAR *CursorName, SQLSMALLINT BufferLength, + SQLSMALLINT *NameLength); +typedef SQLRETURN (SQL_API *SQLGetData_t)(SQLHSTMT StatementHandle, + SQLUSMALLINT ColumnNumber, SQLSMALLINT TargetType, + SQLPOINTER TargetValue, SQLLEN BufferLength, + SQLLEN *StrLen_or_Ind); +typedef SQLRETURN (SQL_API *SQLGetDescField_t)(SQLHDESC DescriptorHandle, + SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier, + SQLPOINTER Value, SQLINTEGER BufferLength, + SQLINTEGER *StringLength); +typedef SQLRETURN (SQL_API *SQLGetDescRec_t)(SQLHDESC DescriptorHandle, + SQLSMALLINT RecNumber, SQLTCHAR *Name, + SQLSMALLINT BufferLength, SQLSMALLINT *StringLength, + SQLSMALLINT *Type, SQLSMALLINT *SubType, + SQLLEN *Length, SQLSMALLINT *Precision, + SQLSMALLINT *Scale, SQLSMALLINT *Nullable); +typedef SQLRETURN (SQL_API *SQLGetDiagRec_t)(SQLSMALLINT HandleType, SQLHANDLE Handle, + SQLSMALLINT RecNumber, SQLTCHAR *Sqlstate, + SQLINTEGER *NativeError, SQLTCHAR *MessageText, + SQLSMALLINT BufferLength, SQLSMALLINT *TextLength); +typedef SQLRETURN (SQL_API *SQLGetDiagField_t)(SQLSMALLINT HandleType, SQLHANDLE Handle, + SQLSMALLINT RecNumber, SQLSMALLINT DiagIdentifier, + SQLPOINTER DiagInfo, SQLSMALLINT BufferLength, + SQLSMALLINT *StringLength); +typedef SQLRETURN (SQL_API *SQLGetEnvAttr_t)(SQLHENV EnvironmentHandle, + SQLINTEGER Attribute, SQLPOINTER Value, + SQLINTEGER BufferLength, SQLINTEGER *StringLength); +typedef SQLRETURN (SQL_API *SQLGetFunctions_t)(SQLHDBC ConnectionHandle, + SQLUSMALLINT FunctionId, SQLUSMALLINT *Supported); +typedef SQLRETURN (SQL_API *SQLGetInfo_t)(SQLHDBC ConnectionHandle, + SQLUSMALLINT InfoType, SQLPOINTER InfoValue, + SQLSMALLINT BufferLength, SQLSMALLINT *StringLength); +typedef SQLRETURN (SQL_API *SQLGetStmtAttr_t)(SQLHSTMT StatementHandle, + SQLINTEGER Attribute, SQLPOINTER Value, + SQLINTEGER BufferLength, SQLINTEGER *StringLength); +typedef SQLRETURN (SQL_API *SQLGetStmtOption_t)(SQLHSTMT StatementHandle, + SQLUSMALLINT Option, SQLPOINTER Value); +typedef SQLRETURN (SQL_API *SQLGetTypeInfo_t)(SQLHSTMT StatementHandle, + SQLSMALLINT DataType); +typedef SQLRETURN (SQL_API *SQLMoreResults_t)( + SQLHSTMT hstmt); +typedef SQLRETURN (SQL_API *SQLNativeSql_t)( + SQLHDBC hdbc, + SQLTCHAR *szSqlStrIn, + SQLINTEGER cbSqlStrIn, + SQLTCHAR *szSqlStr, + SQLINTEGER cbSqlStrMax, + SQLINTEGER *pcbSqlStr); +typedef SQLRETURN (SQL_API *SQLNumParams_t)( + SQLHSTMT hstmt, + SQLSMALLINT *pcpar); +typedef SQLRETURN (SQL_API *SQLNumResultCols_t)(SQLHSTMT StatementHandle, + SQLSMALLINT *ColumnCount); +typedef SQLRETURN (SQL_API *SQLParamData_t)(SQLHSTMT StatementHandle, + SQLPOINTER *Value); +typedef SQLRETURN (SQL_API *SQLParamOptions_t)( + SQLHSTMT hstmt, + SQLULEN crow, + SQLULEN *pirow); +typedef SQLRETURN (SQL_API *SQLPrepare_t)(SQLHSTMT StatementHandle, + SQLTCHAR *StatementText, SQLINTEGER TextLength); +typedef SQLRETURN (SQL_API *SQLPrimaryKeys_t)( + SQLHSTMT hstmt, + SQLTCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLTCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLTCHAR *szTableName, + SQLSMALLINT cbTableName); +typedef SQLRETURN (SQL_API *SQLProcedureColumns_t)( + SQLHSTMT hstmt, + SQLTCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLTCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLTCHAR *szProcName, + SQLSMALLINT cbProcName, + SQLTCHAR *szColumnName, + SQLSMALLINT cbColumnName); +typedef SQLRETURN (SQL_API *SQLProcedures_t)( + SQLHSTMT hstmt, + SQLTCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLTCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLTCHAR *szProcName, + SQLSMALLINT cbProcName); +typedef SQLRETURN (SQL_API *SQLPutData_t)(SQLHSTMT StatementHandle, + SQLPOINTER Data, SQLLEN StrLen_or_Ind); +typedef SQLRETURN (SQL_API *SQLRowCount_t)(SQLHSTMT StatementHandle, + SQLLEN *RowCount); +typedef SQLRETURN (SQL_API *SQLSetConnectAttr_t)(SQLHDBC ConnectionHandle, + SQLINTEGER Attribute, SQLPOINTER Value, + SQLINTEGER StringLength); +typedef SQLRETURN (SQL_API *SQLSetConnectOption_t)(SQLHDBC ConnectionHandle, + SQLUSMALLINT Option, SQLULEN Value); +typedef SQLRETURN (SQL_API *SQLSetCursorName_t)(SQLHSTMT StatementHandle, + SQLTCHAR *CursorName, SQLSMALLINT NameLength); +typedef SQLRETURN (SQL_API *SQLSetDescField_t)(SQLHDESC DescriptorHandle, + SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier, + SQLPOINTER Value, SQLINTEGER BufferLength); +typedef SQLRETURN (SQL_API *SQLSetDescRec_t)(SQLHDESC DescriptorHandle, + SQLSMALLINT RecNumber, SQLSMALLINT Type, + SQLSMALLINT SubType, SQLLEN Length, + SQLSMALLINT Precision, SQLSMALLINT Scale, + SQLPOINTER Data, SQLLEN *StringLength, + SQLLEN *Indicator); +typedef SQLRETURN (SQL_API *SQLSetEnvAttr_t)(SQLHENV EnvironmentHandle, + SQLINTEGER Attribute, SQLPOINTER Value, + SQLINTEGER StringLength); +typedef SQLRETURN (SQL_API *SQLSetParam_t)(SQLHSTMT StatementHandle, + SQLUSMALLINT ParameterNumber, SQLSMALLINT ValueType, + SQLSMALLINT ParameterType, SQLULEN LengthPrecision, + SQLSMALLINT ParameterScale, SQLPOINTER ParameterValue, + SQLLEN *StrLen_or_Ind); +typedef SQLRETURN (SQL_API *SQLSetPos_t)( + SQLHSTMT hstmt, + SQLSETPOSIROW irow, + SQLUSMALLINT fOption, + SQLUSMALLINT fLock); +typedef SQLRETURN (SQL_API *SQLSetScrollOptions_t)( /* Use SQLSetStmtOptions */ + SQLHSTMT hstmt, + SQLUSMALLINT fConcurrency, + SQLINTEGER crowKeyset, + SQLUSMALLINT crowRowset); +typedef SQLRETURN (SQL_API *SQLSetStmtAttr_t)(SQLHSTMT StatementHandle, + SQLINTEGER Attribute, SQLPOINTER Value, + SQLINTEGER StringLength); +typedef SQLRETURN (SQL_API *SQLSetStmtOption_t)(SQLHSTMT StatementHandle, + SQLUSMALLINT Option, SQLULEN Value); +typedef SQLRETURN (SQL_API *SQLSpecialColumns_t)(SQLHSTMT StatementHandle, + SQLUSMALLINT IdentifierType, SQLTCHAR *CatalogName, + SQLSMALLINT NameLength1, SQLTCHAR *SchemaName, + SQLSMALLINT NameLength2, SQLTCHAR *TableName, + SQLSMALLINT NameLength3, SQLUSMALLINT Scope, + SQLUSMALLINT Nullable); +typedef SQLRETURN (SQL_API *SQLStatistics_t)(SQLHSTMT StatementHandle, + SQLTCHAR *CatalogName, SQLSMALLINT NameLength1, + SQLTCHAR *SchemaName, SQLSMALLINT NameLength2, + SQLTCHAR *TableName, SQLSMALLINT NameLength3, + SQLUSMALLINT Unique, SQLUSMALLINT Reserved); +typedef SQLRETURN (SQL_API *SQLTablePrivileges_t)( + SQLHSTMT hstmt, + SQLTCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLTCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLTCHAR *szTableName, + SQLSMALLINT cbTableName); +typedef SQLRETURN (SQL_API *SQLTables_t)(SQLHSTMT StatementHandle, + SQLTCHAR *CatalogName, SQLSMALLINT NameLength1, + SQLTCHAR *SchemaName, SQLSMALLINT NameLength2, + SQLTCHAR *TableName, SQLSMALLINT NameLength3, + SQLTCHAR *TableType, SQLSMALLINT NameLength4); +typedef SQLRETURN (SQL_API *SQLTransact_t)(SQLHENV EnvironmentHandle, + SQLHDBC ConnectionHandle, SQLUSMALLINT CompletionType); + + +class SQLAPI_API infAPI : public saAPI +{ +public: + infAPI(); + + SQLAllocConnect_t SQLAllocConnect; // 1.0 + SQLAllocEnv_t SQLAllocEnv; // 1.0 + SQLAllocHandle_t SQLAllocHandle; // 3.0 + SQLAllocStmt_t SQLAllocStmt; // 1.0 + SQLBindCol_t SQLBindCol; // 1.0 + SQLBindParameter_t SQLBindParameter; // 2.0 + SQLBrowseConnect_t SQLBrowseConnect; // 1.0 + SQLBulkOperations_t SQLBulkOperations; // 3.0 + SQLCancel_t SQLCancel; // 1.0 + SQLCloseCursor_t SQLCloseCursor; // 3.0 + SQLColAttribute_t SQLColAttribute; // 3.0 + SQLColAttributes_t SQLColAttributes; // 1.0 + SQLColumnPrivileges_t SQLColumnPrivileges;// 1.0 + SQLColumns_t SQLColumns; // 1.0 + SQLConnect_t SQLConnect; // 1.0 + SQLCopyDesc_t SQLCopyDesc; // 3.0 + SQLDataSources_t SQLDataSources; // 1.0 + SQLDescribeCol_t SQLDescribeCol; // 1.0 + SQLDescribeParam_t SQLDescribeParam; // 1.0 + SQLDisconnect_t SQLDisconnect; // 1.0 + SQLDriverConnect_t SQLDriverConnect; // 1.0 + SQLDrivers_t SQLDrivers; // 2.0 + SQLEndTran_t SQLEndTran; // 3.0 + SQLError_t SQLError; // 1.0 + SQLExecDirect_t SQLExecDirect; // 1.0 + SQLExecute_t SQLExecute; // 1.0 + SQLExtendedFetch_t SQLExtendedFetch; // 1.0 + SQLFetch_t SQLFetch; // 1.0 + SQLFetchScroll_t SQLFetchScroll; // 1.0 + SQLForeignKeys_t SQLForeignKeys; // 1.0 + SQLFreeConnect_t SQLFreeConnect; // 1.0 + SQLFreeEnv_t SQLFreeEnv; // 1.0 + SQLFreeHandle_t SQLFreeHandle; // 3.0 + SQLFreeStmt_t SQLFreeStmt; // 1.0 + SQLGetConnectAttr_t SQLGetConnectAttr; // 3.0 + SQLGetConnectOption_t SQLGetConnectOption;// 1.0 + SQLGetCursorName_t SQLGetCursorName; // 1.0 + SQLGetData_t SQLGetData; // 1.0 + SQLGetDescField_t SQLGetDescField; // 3.0 + SQLGetDescRec_t SQLGetDescRec; // 3.0 + SQLGetDiagField_t SQLGetDiagField; // 3.0 + SQLGetDiagRec_t SQLGetDiagRec; // 3.0 + SQLGetEnvAttr_t SQLGetEnvAttr; // 3.0 + SQLGetFunctions_t SQLGetFunctions; // 1.0 + SQLGetInfo_t SQLGetInfo; // 1.0 + SQLGetStmtAttr_t SQLGetStmtAttr; // 3.0 + SQLGetStmtOption_t SQLGetStmtOption; // 1.0 + SQLGetTypeInfo_t SQLGetTypeInfo; // 1.0 + SQLMoreResults_t SQLMoreResults; // 1.0 + SQLNativeSql_t SQLNativeSql; // 1.0 + SQLNumParams_t SQLNumParams; // 1.0 + SQLNumResultCols_t SQLNumResultCols; // 1.0 + SQLParamData_t SQLParamData; // 1.0 + SQLParamOptions_t SQLParamOptions; // 1.0 + SQLPrepare_t SQLPrepare; // 1.0 + SQLPrimaryKeys_t SQLPrimaryKeys; // 1.0 + SQLProcedureColumns_t SQLProcedureColumns;// 1.0 + SQLProcedures_t SQLProcedures; // 1.0 + SQLPutData_t SQLPutData; // 1.0 + SQLRowCount_t SQLRowCount; // 1.0 + SQLSetConnectAttr_t SQLSetConnectAttr; // 3.0 + SQLSetConnectOption_t SQLSetConnectOption;// 1.0 + SQLSetCursorName_t SQLSetCursorName; // 1.0 + SQLSetDescField_t SQLSetDescField; // 3.0 + SQLSetDescRec_t SQLSetDescRec; // 3.0 + SQLSetEnvAttr_t SQLSetEnvAttr; // 3.0 + SQLSetParam_t SQLSetParam; // 1.0 + SQLSetPos_t SQLSetPos; // 1.0 + SQLSetScrollOptions_t SQLSetScrollOptions;// 1.0 + SQLSetStmtAttr_t SQLSetStmtAttr; // 3.0 + SQLSetStmtOption_t SQLSetStmtOption; // 1.0 + SQLSpecialColumns_t SQLSpecialColumns; // 1.0 + SQLStatistics_t SQLStatistics; // 1.0 + SQLTablePrivileges_t SQLTablePrivileges; // 1.0 + SQLTables_t SQLTables; // 1.0 + SQLTransact_t SQLTransact; // 1.0 +}; + +class SQLAPI_API infConnectionHandles : public saConnectionHandles +{ +public: + infConnectionHandles(); + + SQLHENV m_hevn; + SQLHDBC m_hdbc; +}; + +class SQLAPI_API infCommandHandles : public saCommandHandles +{ +public: + infCommandHandles(); + + SQLHSTMT m_hstmt; +}; + +extern infAPI g_infAPI; + +#endif // !defined(__INFAPI_H__) diff --git a/libodbc/include/informix/infxcli.h b/libodbc/include/informix/infxcli.h new file mode 100644 index 0000000000..d73a95bca7 --- /dev/null +++ b/libodbc/include/informix/infxcli.h @@ -0,0 +1,310 @@ +/**************************************************************************** + * + * IBM CORP. + * + * PROPRIETARY DATA + * + * Licensed Material - Property Of IBM + * + * "Restricted Materials of IBM" + * + * IBM Informix Client SDK + * + * (c) Copyright IBM Corporation 1997, 2011. All rights reserved. + * +** INFXCLI.H - This is the the main include for IBM Informix-CLI +** applications. +** +** Preconditions: +** for Windows environment: +** #include "windows.h" +** +*********************************************************************/ + +#ifndef __INFXCLI_H +#define __INFXCLI_H + +#ifdef __cplusplus +extern "C" { /* Assume C declarations for C++ */ +#endif /* __cplusplus */ + +/* +** include sql.h and sqlext.h +*/ +#ifdef _WINDOWS_ +#include "sql.h" +#include "sqlext.h" +#else +#include +#include "infxsql.h" +#endif /*_WINDOWS_*/ + +#define SQL_TXN_LAST_COMMITTED 0x00000010L +#define SQL_TRANSACTION_LAST_COMMITTED SQL_TXN_LAST_COMMITTED + +/* For extended errors */ + +#define SQL_DIAG_ISAM_ERROR 13 +#define SQL_DIAG_XA_ERROR 14 + +/* START -- Q+E Software's SQLSetStmtOption extensions (1040 to 1139) */ +/* defines here for backwards compatibility */ + +#define SQL_STMTOPT_START 1040 + +/* Get the rowid for the last row inserted */ +#define SQL_GET_ROWID (SQL_STMTOPT_START+8) + +/* Get the value for the serial column in the last row inserted */ +#define SQL_GET_SERIAL_VALUE (SQL_STMTOPT_START+9) + +/* END -- Q+E Software's SQLSetStmtOption extensions (1040 to 1139) */ + +/* +** Informix extensions +*/ + +/* Informix Column Attributes Flags Definitions */ +#define FDNULLABLE 0x0001 /* null allowed in field */ +#define FDDISTINCT 0x0002 /* distinct of all */ +#define FDDISTLVARCHAR 0x0004 /* distinct of SQLLVARCHAR */ +#define FDDISTBOOLEAN 0x0008 /* distinct of SQLBOOL */ +#define FDDISTSIMP 0x0010 /* distinct of simple type */ +#define FDCSTTYPE 0x0020 /* constructor type */ +#define FDNAMED 0x0040 /* named row type */ + +#define ISNULLABLE( flags ) ( flags & FDNULLABLE ? 1 : 0) +#define ISDISTINCT( flags ) ( flags & FDDISTINCT ? 1 : 0) + +/* Informix Type Estensions */ +#define SQL_INFX_UDT_FIXED -100 +#define SQL_INFX_UDT_VARYING -101 +#define SQL_INFX_UDT_BLOB -102 +#define SQL_INFX_UDT_CLOB -103 +#define SQL_INFX_UDT_LVARCHAR -104 +#define SQL_INFX_RC_ROW -105 +#define SQL_INFX_RC_COLLECTION -106 +#define SQL_INFX_RC_LIST -107 +#define SQL_INFX_RC_SET -108 +#define SQL_INFX_RC_MULTISET -109 +#define SQL_INFX_UNSUPPORTED -110 +#define SQL_INFX_C_SMARTLOB_LOCATOR -111 +#define SQL_INFX_QUALIFIER -112 +#define SQL_INFX_DECIMAL -113 +#define SQL_INFX_BIGINT -114 + +typedef void * HINFX_RC; /* row & collection handle */ + +/* Informix Connect Attributes Extensions */ +#define SQL_OPT_LONGID 2251 +#define SQL_INFX_ATTR_LONGID SQL_OPT_LONGID +#define SQL_INFX_ATTR_LEAVE_TRAILING_SPACES 2252 +#define SQL_INFX_ATTR_DEFAULT_UDT_FETCH_TYPE 2253 +#define SQL_INFX_ATTR_ENABLE_SCROLL_CURSORS 2254 +#define SQL_ENABLE_INSERT_CURSOR 2255 +#define SQL_INFX_ATTR_ENABLE_INSERT_CURSORS SQL_ENABLE_INSERT_CURSOR +#define SQL_INFX_ATTR_OPTIMIZE_AUTOCOMMIT 2256 +#define SQL_INFX_ATTR_ODBC_TYPES_ONLY 2257 +#define SQL_INFX_ATTR_FETCH_BUFFER_SIZE 2258 +#define SQL_INFX_ATTR_OPTOFC 2259 +#define SQL_INFX_ATTR_OPTMSG 2260 +#define SQL_INFX_ATTR_REPORT_KEYSET_CURSORS 2261 +#define SQL_INFX_ATTR_LO_AUTOMATIC 2262 +#define SQL_INFX_ATTR_AUTO_FREE 2263 +#define SQL_INFX_ATTR_DEFERRED_PREPARE 2265 + +#define SQL_INFX_ATTR_PAM_FUNCTION 2266 /* void pamCallback + (int msgStyle, + void *responseBuf, + int responseBufLen, + int *responseLenPtr, + void *challengeBuf, + int challengeBufLen, + int *challengeLenPtr) */ +#define SQL_INFX_ATTR_PAM_RESPONSE_BUF 2267 /* SQLPOINTER */ +#define SQL_INFX_ATTR_PAM_RESPONSE_BUF_LEN 2268 /* SQLINTEGER */ +#define SQL_INFX_ATTR_PAM_RESPONSE_LEN_PTR 2269 /* SQLPOINTER */ +#define SQL_INFX_ATTR_PAM_CHALLENGE_BUF 2270 /* SQLPOINTER */ +#define SQL_INFX_ATTR_PAM_CHALLENGE_BUF_LEN 2271 /* SQLINTEGER */ +#define SQL_INFX_ATTR_PAM_CHALLENGE_LEN_PTR 2272 /* SQLINTEGER * - number of bytes in challenge */ +#define SQL_INFX_ATTR_DELIMIDENT 2273 /* As of now this attribute is only being used + in .NET Provider since it is sitting on top + of ODBC.*/ +#define SQL_INFX_ATTR_DBLOCALE 2275 +#define SQL_INFX_ATTR_LOCALIZE_DECIMALS 2276 +#define SQL_INFX_ATTR_DEFAULT_DECIMAL 2277 +#define SQL_INFX_ATTR_SKIP_PARSING 2278 +#define SQL_INFX_ATTR_CALL_FROM_DOTNET 2279 +#define SQL_INFX_ATTR_LENGTHINCHARFORDIAGRECW 2280 +#define SQL_INFX_ATTR_SENDTIMEOUT 2281 +#define SQL_INFX_ATTR_RECVTIMEOUT 2282 +#define SQL_INFX_ATTR_IDSISAMERRMSG 2283 + +/*Attributes same as cli*/ +#define SQL_ATTR_USE_TRUSTED_CONTEXT 2561 + +/* Informix Descriptor Extensions */ +#define SQL_INFX_ATTR_FLAGS 1900 /* UDWORD */ +#define SQL_INFX_ATTR_EXTENDED_TYPE_CODE 1901 /* UDWORD */ +#define SQL_INFX_ATTR_EXTENDED_TYPE_NAME 1902 /* UCHAR ptr */ +#define SQL_INFX_ATTR_EXTENDED_TYPE_OWNER 1903 /* UCHAR ptr */ +#define SQL_INFX_ATTR_EXTENDED_TYPE_ALIGNMENT 1904 /* UDWORD */ +#define SQL_INFX_ATTR_SOURCE_TYPE_CODE 1905 /* UDWORD */ + +/* Informix Statement Attributes Extensions */ +#define SQL_VMB_CHAR_LEN 2325 +#define SQL_INFX_ATTR_VMB_CHAR_LEN SQL_VMB_CHAR_LEN +#define SQL_INFX_ATTR_MAX_FET_ARR_SIZE 2326 + +/* Informix fOption, SQL_VMB_CHAR_LEN vParam */ +#define SQL_VMB_CHAR_EXACT 0 +#define SQL_VMB_CHAR_ESTIMATE 1 + +/* Informix row/collection traversal constants */ +#define SQL_INFX_RC_NEXT 1 +#define SQL_INFX_RC_PRIOR 2 +#define SQL_INFX_RC_FIRST 3 +#define SQL_INFX_RC_LAST 4 +#define SQL_INFX_RC_ABSOLUTE 5 +#define SQL_INFX_RC_RELATIVE 6 +#define SQL_INFX_RC_CURRENT 7 + +/******************************************************************************* + * Large Object (LO) related structures + * + * LO_SPEC: Large object spec structure + * It is used for creating smartblobs. The user may examin and/or set certain + * fields of LO_SPEC by using ifx_lo_spec[set|get]_* accessor functions. + * + * LO_PTR: Large object pointer structure + * Identifies the LO and provides ancillary, security-related information. + * + * LO_STAT: Large object stat structure + * It is used in querying attribtes of smartblobs. The user may examin fields + * herein by using ifx_lo_stat[set|get]_* accessor functions. + * + * These structures are opaque to the user. Accessor functions are provided + * for these structures. + ******************************************************************************/ + +/* Informix GetInfo Extensions to obtain length of LO related structures */ +#define SQL_INFX_LO_SPEC_LENGTH 2250 /* UWORD */ +#define SQL_INFX_LO_PTR_LENGTH 2251 /* UWORD */ +#define SQL_INFX_LO_STAT_LENGTH 2252 /* UWORD */ + +/****************************************************************************** + * LO Open flags: (see documentation for further explanation) + * + * LO_APPEND - Positions the seek position to end-of-file + 1. By itself, + * it is equivalent to write only mode followed by a seek to the + * end of large object. Read opeartions will fail. + * You can OR the LO_APPEND flag with another access mode. + * LO_WRONLY - Only write operations are valid on the data. + * LO_RDONLY - Only read operations are valid on the data. + * LO_RDWR - Both read and write operations are valid on the data. + * + * LO_RANDOM - If set overrides optimizer decision. Indicates that I/O is + * random and that the system should not read-ahead. + * LO_SEQUENTIAL - If set overrides optimizer decision. Indicates that + * reads are sequential in either forward or reverse direction. + * + * LO_FORWARD - Only used for sequential access. Indicates that the sequential + * access will be in a forward direction, i.e. from low offset + * to higher offset. + * LO_REVERSE - Only used for sequential access. Indicates that the sequential + * access will be in a reverse direction. + * + * LO_BUFFER - If set overrides optimizer decision. I/O goes through the + * buffer pool. + * LO_NOBUFFER - If set then I/O does not use the buffer pool. + ******************************************************************************/ + +#define LO_APPEND 0x1 +#define LO_WRONLY 0x2 +#define LO_RDONLY 0x4 /* default */ +#define LO_RDWR 0x8 + +#define LO_RANDOM 0x20 /* default is determined by optimizer */ +#define LO_SEQUENTIAL 0x40 /* default is determined by optimizer */ + +#define LO_FORWARD 0x80 /* default */ +#define LO_REVERSE 0x100 + +#define LO_BUFFER 0x200 /* default is determined by optimizer */ +#define LO_NOBUFFER 0x400 /* default is determined by optimizer */ + +#define LO_DIRTY_READ 0x10 +#define LO_NODIRTY_READ 0x800 + +#define LO_LOCKALL 0x1000 /* default */ +#define LO_LOCKRANGE 0x2000 + +/******************************************************************************* + * LO create-time flags: + * + * Bitmask - Set/Get via ifx_lo_specset_flags() on LO_SPEC. + ******************************************************************************/ + +#define LO_ATTR_LOG 0x0001 +#define LO_ATTR_NOLOG 0x0002 +#define LO_ATTR_DELAY_LOG 0x0004 +#define LO_ATTR_KEEP_LASTACCESS_TIME 0x0008 +#define LO_ATTR_NOKEEP_LASTACCESS_TIME 0x0010 +#define LO_ATTR_HIGH_INTEG 0x0020 +#define LO_ATTR_MODERATE_INTEG 0x0040 + +/******************************************************************************* + * Symbolic constants for the "lseek" routine + ******************************************************************************/ + +#define LO_SEEK_SET 0 /* Set curr. pos. to "offset" */ +#define LO_SEEK_CUR 1 /* Set curr. pos. to current + "offset" */ +#define LO_SEEK_END 2 /* Set curr. pos. to EOF + "offset" */ + +/******************************************************************************* + * Symbolic constants for lo_lock and lo_unlock routines. +******************************************************************************/ + +#define LO_SHARED_MODE 1 +#define LO_EXCLUSIVE_MODE 2 + +/******************************************************************************* + * Intersolv specific infoTypes for SQLGetInfo + ******************************************************************************/ + +#define SQL_RESERVED_WORDS 1011 +#define SQL_PSEUDO_COLUMNS 1012 +#define SQL_FROM_RESERVED_WORDS 1013 +#define SQL_WHERE_CLAUSE_TERMINATORS 1014 +#define SQL_COLUMN_FIRST_CHARS 1015 +#define SQL_COLUMN_MIDDLE_CHARS 1016 +#define SQL_TABLE_FIRST_CHARS 1018 +#define SQL_TABLE_MIDDLE_CHARS 1019 +#define SQL_FAST_SPECIAL_COLUMNS 1021 +#define SQL_ACCESS_CONFLICTS 1022 +#define SQL_LOCKING_SYNTAX 1023 +#define SQL_LOCKING_DURATION 1024 +#define SQL_RECORD_OPERATIONS 1025 +#define SQL_QUALIFIER_SYNTAX 1026 + + +/* Function for acquiring the xa_switch structure defined by Informix RM */ + +struct xa_switch_t * _fninfx_xa_switch( void ); + + +/* Function for obtaining the Environment handle associated with an XA +Connection */ + +RETCODE IFMX_SQLGetXaHenv(int, HENV *); + + +/*Function for obtaining the Database handle associated with an XA Connection */ + +RETCODE IFMX_SQLGetXaHdbc(int, HDBC *); + +#ifdef __cplusplus +} /* End of extern "C" { */ +#endif /* __cplusplus */ + +#endif /* __INFXCLI_H */ diff --git a/libodbc/include/informix/infxsql.h b/libodbc/include/informix/infxsql.h new file mode 100644 index 0000000000..0443d23966 --- /dev/null +++ b/libodbc/include/informix/infxsql.h @@ -0,0 +1,1505 @@ +/**************************************************************************** + * + * IBM CORP. + * + * PROPRIETARY DATA + * + * Licensed Material - Property Of IBM + * + * "Restricted Materials of IBM" + * + * IBM Informix Client SDK + * + * Copyright IBM Corporation 2012 + * +** INFXSQL.H - This is the the include file for IBM Informix-CLI +** applications with sqlcli.h, sqlcli1.h and SQLEXT.H +** +*********************************************************************/ + +#ifndef __INFXSQL +#define __INFXSQL + + +#ifdef __cplusplus +extern "C" { /* Assume C declarations for C++ */ +#endif /* __cplusplus */ + +#ifndef ODBCVER +#define ODBCVER 0x0300 +#endif + +#define FAR + +/* environment specific definitions */ +#ifndef EXPORT +#define EXPORT +#endif + +#if !defined SQL_API_RC + #define SQL_API_RC int + #define SQL_STRUCTURE struct + #define PSQL_API_FN * +#if defined(WIN32) || defined(WIN64) + #define SQL_API_FN __stdcall +#else + #define SQL_API_FN +#endif /* WIN32 || WIN64 */ + #define SQL_POINTER + #define SQL_API_INTR +#endif /* !SQL_API_RC */ + +#define SQL_API SQL_API_FN + +#ifndef RC_INVOKED + +/* + * The following are provided to enhance portability and compatibility + * with ODBC taken from sqlcli.h, sqlcli1.h and sqlsystm.h + */ +typedef char sqlint8; +typedef unsigned char sqluint8; +typedef short sqlint16; +typedef unsigned short sqluint16; +typedef int sqlint32; +typedef unsigned int sqluint32; + +typedef signed char SCHAR; +typedef unsigned char UCHAR; +typedef short int SWORD; +typedef unsigned short USHORT; +typedef signed short SSHORT; +typedef unsigned short int UWORD; + +typedef sqlint32 SDWORD; +typedef unsigned long ULONG; +typedef sqluint32 UDWORD; +typedef signed long SLONG; + +typedef double LDOUBLE; +typedef double SDOUBLE; +typedef float SFLOAT; +typedef unsigned char SQLDATE; +typedef unsigned char SQLTIME; +typedef unsigned char SQLTIMESTAMP; +typedef unsigned char SQLDECIMAL; +typedef unsigned char SQLNUMERIC; + +typedef UCHAR SQLCHAR; +typedef UCHAR SQLVARCHAR; +typedef SCHAR SQLSCHAR; +typedef SDWORD SQLINTEGER; +typedef UDWORD SQLUINTEGER; +typedef SWORD SQLSMALLINT; +typedef SDOUBLE SQLDOUBLE; +typedef SDOUBLE SQLFLOAT; +typedef SFLOAT SQLREAL; + +typedef void FAR * PTR; +typedef PTR SQLPOINTER; +typedef UWORD SQLUSMALLINT; + +typedef void FAR * HENV; +typedef void FAR * HDBC; +typedef void FAR * HSTMT; + +typedef signed short RETCODE; + +/* 64-bit Length Defines */ +#define SQLLEN SQLINTEGER +#define SQLULEN SQLUINTEGER +#define SQLSETPOSIROW SQLUSMALLINT + +/* Windows/NT specific DataTypes and defines */ +#if !defined(WIN32) && !defined(WIN64) + +#define CALLBACK +#define PASCAL +#define _cdecl +#define TRUE 1 +#define FALSE 0 +#define VOID void +#ifndef BOOL +#define BOOL int +#endif + +typedef int HWND; +typedef unsigned int UINT; +typedef VOID *HANDLE; +typedef char *LPSTR; +typedef const char *LPCSTR; +typedef char *LPWSTR; +typedef char WCHAR; +typedef SQLUINTEGER DWORD; +typedef unsigned short WORD; +typedef unsigned char BYTE; +typedef BYTE *LPBYTE; +typedef SQLINTEGER LONG; +typedef VOID *LPVOID; +typedef VOID *PVOID; +typedef VOID *HMODULE; +typedef int GLOBALHANDLE; +typedef int (*FARPROC)(void); +typedef VOID *HINSTANCE; +typedef unsigned int WPARAM; +typedef SQLUINTEGER LPARAM; +typedef VOID *HKEY; +typedef VOID *PHKEY; +typedef char CHAR; +typedef BOOL *LPBOOL; +typedef DWORD *LPDWORD; +typedef const char *LPCWSTR; +typedef char TCHAR; +typedef char VCHAR; +typedef TCHAR *LPTSTR; +typedef const TCHAR *LPCTSTR; + +#endif /*!WIN32 */ + + +typedef SQLSMALLINT SQLRETURN; + +typedef void * SQLHANDLE; +typedef SQLHANDLE SQLHENV; +typedef SQLHANDLE SQLHDBC; +typedef SQLHANDLE SQLHSTMT; +typedef SQLHANDLE SQLHDESC; +typedef SQLPOINTER SQLHWND; + + + +typedef struct DATE_STRUCT + { + SQLSMALLINT year; + SQLUSMALLINT month; + SQLUSMALLINT day; + } DATE_STRUCT; + +typedef DATE_STRUCT SQL_DATE_STRUCT; + +typedef struct TIME_STRUCT + { + SQLUSMALLINT hour; + SQLUSMALLINT minute; + SQLUSMALLINT second; + } TIME_STRUCT; + +typedef TIME_STRUCT SQL_TIME_STRUCT; + +typedef struct TIMESTAMP_STRUCT + { + SQLSMALLINT year; + SQLUSMALLINT month; + SQLUSMALLINT day; + SQLUSMALLINT hour; + SQLUSMALLINT minute; + SQLUSMALLINT second; + SQLUINTEGER fraction; /* fraction of a second */ + } TIMESTAMP_STRUCT; + + +typedef TIMESTAMP_STRUCT SQL_TIMESTAMP_STRUCT; + +typedef enum +{ + SQL_IS_YEAR = 1, + SQL_IS_MONTH = 2, + SQL_IS_DAY = 3, + SQL_IS_HOUR = 4, + SQL_IS_MINUTE = 5, + SQL_IS_SECOND = 6, + SQL_IS_YEAR_TO_MONTH = 7, + SQL_IS_DAY_TO_HOUR = 8, + SQL_IS_DAY_TO_MINUTE = 9, + SQL_IS_DAY_TO_SECOND = 10, + SQL_IS_HOUR_TO_MINUTE = 11, + SQL_IS_HOUR_TO_SECOND = 12, + SQL_IS_MINUTE_TO_SECOND = 13 +} SQLINTERVAL; + +typedef struct tagSQL_YEAR_MONTH +{ + SQLUINTEGER year; + SQLUINTEGER month; +} SQL_YEAR_MONTH_STRUCT; + +typedef struct tagSQL_DAY_SECOND +{ + SQLUINTEGER day; + SQLUINTEGER hour; + SQLUINTEGER minute; + SQLUINTEGER second; + SQLUINTEGER fraction; +} SQL_DAY_SECOND_STRUCT; + +typedef struct tagSQL_INTERVAL_STRUCT +{ + SQLINTERVAL interval_type; + SQLSMALLINT interval_sign; + union { + SQL_YEAR_MONTH_STRUCT year_month; + SQL_DAY_SECOND_STRUCT day_second; + } intval; + +} SQL_INTERVAL_STRUCT; + +/* Maximum precision (in base 10) of an SQL_C_NUMERIC value */ +#define SQL_MAX_C_NUMERIC_PRECISION 38 + +/* internal representation of numeric data type */ +#define SQL_MAX_NUMERIC_LEN 16 +typedef struct tagSQL_NUMERIC_STRUCT +{ + SQLCHAR precision; + SQLSCHAR scale; + SQLCHAR sign; /* 1 if positive, 0 if negative */ + SQLCHAR val[SQL_MAX_NUMERIC_LEN]; +} SQL_NUMERIC_STRUCT; + +#define SQL_BIGINT_TYPE long long +#define SQL_BIGUINT_TYPE unsigned long long +typedef SQL_BIGINT_TYPE SQLBIGINT; +typedef SQL_BIGUINT_TYPE SQLUBIGINT; + +typedef SQLUINTEGER BOOKMARK; + + +#ifdef UCS2 +typedef unsigned short SQLWCHAR; +#else +#ifdef UTF8 +typedef char SQLWCHAR; +#else +typedef wchar_t SQLWCHAR; +#endif /* !UTF-8 and !UCS-2 */ +#endif /* UCS-2 */ + +#define SQL_C_WCHAR SQL_WCHAR +#ifdef UNICODE +#define SQL_C_TCHAR SQL_C_WCHAR +typedef SQLWCHAR SQLTCHAR; +#else +#define SQL_C_TCHAR SQL_C_CHAR +typedef SQLCHAR SQLTCHAR; +#endif + +/* Special length values */ +#define SQL_NULL_DATA -1 +#define SQL_DATA_AT_EXEC -2 +#define SQL_NTS -3 /* NTS = Null Terminated String */ +#define SQL_NTSL -3L /* NTS = Null Terminated String */ + +/* RETCODE values */ +#define SQL_SUCCESS 0 +#define SQL_SUCCESS_WITH_INFO 1 +#define SQL_NEED_DATA 99 +#define SQL_NO_DATA 100 +#define SQL_STILL_EXECUTING 2 +#define SQL_ERROR -1 +#define SQL_INVALID_HANDLE -2 + +/* test for SQL_SUCCESS or SQL_SUCCESS_WITH_INFO */ +#define SQL_SUCCEEDED(rc) (((rc)&(~1))==0) + +/* Special length values */ +#define SQL_NULL_DATA -1 +#define SQL_DATA_AT_EXEC -2 +#define SQL_NTS -3 /* NTS = Null Terminated String */ +#define SQL_NTSL -3L /* NTS = Null Terminated String */ + +/* generally useful constants */ +#define SQL_MAX_MESSAGE_LENGTH 512 /* message buffer size */ +#define SQL_MAX_ID_LENGTH 128 /* maximum identifier name size, + e.g. cursor names */ + +/* date/time length constants */ +#define SQL_DATE_LEN 10 +#define SQL_TIME_LEN 8 /* add P+1 if precision is nonzero */ +#define SQL_TIMESTAMP_LEN 19 /* add P+1 if precision is nonzero */ + +/* handle type identifiers */ +#define SQL_HANDLE_ENV 1 +#define SQL_HANDLE_DBC 2 +#define SQL_HANDLE_STMT 3 +#define SQL_HANDLE_DESC 4 + +/* + * Environment attributes; note SQL_CONNECTTYPE, SQL_SYNC_POINT are also + * environment attributes that are settable at the connection level + */ + +#define SQL_ATTR_OUTPUT_NTS 10001 + +/* Options for SQLGetStmtOption/SQLSetStmtOption */ + +#define SQL_ATTR_AUTO_IPD 10001 +#define SQL_ATTR_APP_ROW_DESC 10010 +#define SQL_ATTR_APP_PARAM_DESC 10011 +#define SQL_ATTR_IMP_ROW_DESC 10012 +#define SQL_ATTR_IMP_PARAM_DESC 10013 +#define SQL_ATTR_METADATA_ID 10014 +#define SQL_ATTR_CURSOR_SCROLLABLE (-1) +#define SQL_ATTR_CURSOR_SENSITIVITY (-2) + +/* SQL_ATTR_CURSOR_SCROLLABLE values */ +#define SQL_NONSCROLLABLE 0 +#define SQL_SCROLLABLE 1 + +/* SQL_ATTR_CURSOR_SCROLLABLE values */ +#define SQL_NONSCROLLABLE 0 +#define SQL_SCROLLABLE 1 + +/* identifiers of fields in the SQL descriptor */ +#define SQL_DESC_COUNT 1001 +#define SQL_DESC_TYPE 1002 +#define SQL_DESC_LENGTH 1003 +#define SQL_DESC_OCTET_LENGTH_PTR 1004 +#define SQL_DESC_PRECISION 1005 +#define SQL_DESC_SCALE 1006 +#define SQL_DESC_DATETIME_INTERVAL_CODE 1007 +#define SQL_DESC_NULLABLE 1008 +#define SQL_DESC_INDICATOR_PTR 1009 +#define SQL_DESC_DATA_PTR 1010 +#define SQL_DESC_NAME 1011 +#define SQL_DESC_UNNAMED 1012 +#define SQL_DESC_OCTET_LENGTH 1013 +#define SQL_DESC_ALLOC_TYPE 1099 +#define SQL_DESC_USER_DEFINED_TYPE_CODE 1098 +#define SQL_DESC_CARDINALITY 1040 +#define SQL_DESC_CARDINALITY_PTR 1043 + +/* identifiers of fields in the diagnostics area */ +#define SQL_DIAG_RETURNCODE 1 +#define SQL_DIAG_NUMBER 2 +#define SQL_DIAG_ROW_COUNT 3 +#define SQL_DIAG_SQLSTATE 4 +#define SQL_DIAG_NATIVE 5 +#define SQL_DIAG_MESSAGE_TEXT 6 +#define SQL_DIAG_DYNAMIC_FUNCTION 7 +#define SQL_DIAG_CLASS_ORIGIN 8 +#define SQL_DIAG_SUBCLASS_ORIGIN 9 +#define SQL_DIAG_CONNECTION_NAME 10 +#define SQL_DIAG_SERVER_NAME 11 +#define SQL_DIAG_DYNAMIC_FUNCTION_CODE 12 + +/* dynamic function codes */ +#define SQL_DIAG_ALTER_TABLE 4 +#define SQL_DIAG_CALL 7 +#define SQL_DIAG_CREATE_INDEX (-1) +#define SQL_DIAG_CREATE_TABLE 77 +#define SQL_DIAG_CREATE_VIEW 84 +#define SQL_DIAG_DELETE_WHERE 19 +#define SQL_DIAG_DROP_INDEX (-2) +#define SQL_DIAG_DROP_TABLE 32 +#define SQL_DIAG_DROP_VIEW 36 +#define SQL_DIAG_DYNAMIC_DELETE_CURSOR 38 +#define SQL_DIAG_DYNAMIC_UPDATE_CURSOR 81 +#define SQL_DIAG_GRANT 48 +#define SQL_DIAG_INSERT 50 +#define SQL_DIAG_MERGE 128 +#define SQL_DIAG_REVOKE 59 +#define SQL_DIAG_SELECT_CURSOR 85 +#define SQL_DIAG_UNKNOWN_STATEMENT 0 +#define SQL_DIAG_UPDATE_WHERE 82 + +/* Standard SQL data types */ +#define SQL_UNKNOWN_TYPE 0 +#define SQL_CHAR 1 +#define SQL_NUMERIC 2 +#define SQL_DECIMAL 3 +#define SQL_INTEGER 4 +#define SQL_SMALLINT 5 +#define SQL_FLOAT 6 +#define SQL_REAL 7 +#define SQL_DOUBLE 8 +#define SQL_DATETIME 9 +#define SQL_VARCHAR 12 +#define SQL_WCHAR (-8) +#define SQL_WVARCHAR (-9) +#define SQL_WLONGVARCHAR (-10) +#define SQL_DECFLOAT (-360) +/* One-parameter shortcuts for date/time data types */ +#define SQL_TYPE_DATE 91 +#define SQL_TYPE_TIME 92 +#define SQL_TYPE_TIMESTAMP 93 + +/* Statement attribute values for cursor sensitivity */ +#define SQL_UNSPECIFIED 0 +#define SQL_INSENSITIVE 1 +#define SQL_SENSITIVE 2 + +/* SQLGetTypeInfo define */ +#define SQL_ALL_TYPES 0 + +/* Default conversion code for SQLBindCol(), SQLBindParam() and SQLGetData() */ +#define SQL_DEFAULT 99 + +/* SQLGetData() code indicating that the application row descriptor + * specifies the data type + */ +#define SQL_ARD_TYPE (-99) + +/* SQL date/time type subcodes */ +#define SQL_CODE_DATE 1 +#define SQL_CODE_TIME 2 +#define SQL_CODE_TIMESTAMP 3 + +/* CLI attribute/option values */ +#define SQL_FALSE 0 +#define SQL_TRUE 1 + +/* + * NULL status defines; these are used in SQLColAttributes, SQLDescribeCol, + * to describe the nullability of a column in a table. + */ + +#define SQL_NO_NULLS 0 +#define SQL_NULLABLE 1 +#define SQL_NULLABLE_UNKNOWN 2 + +/* + * SQLColAttribute defines for SQL_COLUMN_SEARCHABLE condition. + */ +#define SQL_PRED_NONE 0 +#define SQL_PRED_CHAR 1 +#define SQL_PRED_BASIC 2 + + +/* values of UNNAMED field in descriptor used in SQLColAttribute */ +#define SQL_NAMED 0 +#define SQL_UNNAMED 1 + +/* values of ALLOC_TYPE field in descriptor */ +#define SQL_DESC_ALLOC_AUTO 1 +#define SQL_DESC_ALLOC_USER 2 + +/* SQLFreeStmt option values */ +#define SQL_CLOSE 0 +#define SQL_DROP 1 +#define SQL_UNBIND 2 +#define SQL_RESET_PARAMS 3 + +/* SQLDataSources "fDirection" values, also used on SQLExtendedFetch() */ +/* See sqlext.h for additional SQLExtendedFetch fetch direction defines */ +#define SQL_FETCH_NEXT 1 +#define SQL_FETCH_FIRST 2 + +/* OTHER CODES USED FOR FETCHORIENTATION IN SQLFETCHSCROLL() */ +#define SQL_FETCH_LAST 3 +#define SQL_FETCH_PRIOR 4 +#define SQL_FETCH_ABSOLUTE 5 +#define SQL_FETCH_RELATIVE 6 + +/* SQLTransact option values */ +#define SQL_COMMIT 0 +#define SQL_ROLLBACK 1 + +/* NULL handle defines */ +#define SQL_NULL_HENV 0L +#define SQL_NULL_HDBC 0L +#define SQL_NULL_HSTMT 0L +#define SQL_NULL_HDESC 0L +#define SQL_NULL_HANDLE 0L + +/* Column types and scopes in SQLSpecialColumns */ + +#define SQL_SCOPE_CURROW 0 +#define SQL_SCOPE_TRANSACTION 1 +#define SQL_SCOPE_SESSION 2 + +/* Defines for SQLStatistics */ +#define SQL_INDEX_UNIQUE 0 +#define SQL_INDEX_ALL 1 + +/* Defines for SQLStatistics (returned in the result set) */ +#define SQL_INDEX_CLUSTERED 1 +#define SQL_INDEX_HASHED 2 +#define SQL_INDEX_OTHER 3 + +/* Defines for SQLSpecialColumns (returned in the result set) */ +#define SQL_PC_UNKNOWN 0 +#define SQL_PC_NON_PSEUDO 1 +#define SQL_PC_PSEUDO 2 + +/* Reserved value for the IdentifierType argument of SQLSpecialColumns() */ +#define SQL_ROW_IDENTIFIER 1 + +/* SQLGetFunction defines - supported functions */ +#define SQL_API_SQLALLOCCONNECT 1 +#define SQL_API_SQLALLOCENV 2 +#define SQL_API_SQLALLOCSTMT 3 +#define SQL_API_SQLBINDCOL 4 +#define SQL_API_SQLBINDPARAM 1002 +#define SQL_API_SQLCANCEL 5 +#define SQL_API_SQLCONNECT 7 +#define SQL_API_SQLCOPYDESC 1004 +#define SQL_API_SQLDESCRIBECOL 8 +#define SQL_API_SQLDISCONNECT 9 +#define SQL_API_SQLERROR 10 +#define SQL_API_SQLEXECDIRECT 11 +#define SQL_API_SQLEXECUTE 12 +#define SQL_API_SQLFETCH 13 +#define SQL_API_SQLFREECONNECT 14 +#define SQL_API_SQLFREEENV 15 +#define SQL_API_SQLFREESTMT 16 +#define SQL_API_SQLGETCURSORNAME 17 +#define SQL_API_SQLNUMRESULTCOLS 18 +#define SQL_API_SQLPREPARE 19 +#define SQL_API_SQLROWCOUNT 20 +#define SQL_API_SQLSETCURSORNAME 21 +#define SQL_API_SQLSETDESCFIELD 1017 +#define SQL_API_SQLSETDESCREC 1018 +#define SQL_API_SQLSETENVATTR 1019 +#define SQL_API_SQLSETPARAM 22 +#define SQL_API_SQLTRANSACT 23 + +#define SQL_API_SQLCOLUMNS 40 +#define SQL_API_SQLGETCONNECTOPTION 42 +#define SQL_API_SQLGETDATA 43 +#define SQL_API_SQLGETDATAINTERNAL 174 +#define SQL_API_SQLGETDESCFIELD 1008 +#define SQL_API_SQLGETDESCREC 1009 +#define SQL_API_SQLGETDIAGFIELD 1010 +#define SQL_API_SQLGETDIAGREC 1011 +#define SQL_API_SQLGETENVATTR 1012 +#define SQL_API_SQLGETFUNCTIONS 44 +#define SQL_API_SQLGETINFO 45 +#define SQL_API_SQLGETSTMTOPTION 46 +#define SQL_API_SQLGETTYPEINFO 47 +#define SQL_API_SQLPARAMDATA 48 +#define SQL_API_SQLPUTDATA 49 +#define SQL_API_SQLSETCONNECTOPTION 50 +#define SQL_API_SQLSETSTMTOPTION 51 +#define SQL_API_SQLSPECIALCOLUMNS 52 +#define SQL_API_SQLSTATISTICS 53 +#define SQL_API_SQLTABLES 54 +#define SQL_API_SQLDATASOURCES 57 +#define SQL_API_SQLSETCONNECTATTR 1016 +#define SQL_API_SQLSETSTMTATTR 1020 + +#define SQL_API_SQLBINDFILETOCOL 1250 +#define SQL_API_SQLBINDFILETOPARAM 1251 +#define SQL_API_SQLSETCOLATTRIBUTES 1252 +#define SQL_API_SQLGETSQLCA 1253 +#define SQL_API_SQLSETCONNECTION 1254 +#define SQL_API_SQLGETDATALINKATTR 1255 +#define SQL_API_SQLBUILDDATALINK 1256 +#define SQL_API_SQLNEXTRESULT 1257 +#define SQL_API_SQLEXTENDEDPREPARE 1296 +#define SQL_API_SQLEXTENDEDBIND 1297 +#define SQL_API_SQLEXTENDEDDESCRIBE 1298 + +#define SQL_API_SQLFETCHSCROLL 1021 +#define SQL_API_SQLGETLENGTH 1022 +#define SQL_API_SQLGETPOSITION 1023 +#define SQL_API_SQLGETSUBSTRING 1024 + + +#define SQL_API_SQLALLOCHANDLE 1001 +#define SQL_API_SQLFREEHANDLE 1006 +#define SQL_API_SQLCLOSECURSOR 1003 +#define SQL_API_SQLENDTRAN 1005 +#define SQL_API_SQLCOLATTRIBUTE 6 +#define SQL_API_SQLGETSTMTATTR 1014 +#define SQL_API_SQLGETCONNECTATTR 1007 + +/* Information requested by SQLGetInfo() */ +#define SQL_MAX_DRIVER_CONNECTIONS 0 +#define SQL_MAXIMUM_DRIVER_CONNECTIONS SQL_MAX_DRIVER_CONNECTIONS +#define SQL_MAX_CONCURRENT_ACTIVITIES 1 +#define SQL_MAXIMUM_CONCURRENT_ACTIVITIES SQL_MAX_CONCURRENT_ACTIVITIES +#define SQL_ATTR_ANSI_APP 115 + +/* SQLGetInfo defines - Info Type */ +#define SQL_DATA_SOURCE_NAME 2 +#define SQL_FETCH_DIRECTION 8 +#define SQL_SERVER_NAME 13 +#define SQL_SEARCH_PATTERN_ESCAPE 14 +#define SQL_DBMS_NAME 17 +#define SQL_DBMS_VER 18 +#define SQL_ACCESSIBLE_TABLES 19 +#define SQL_ACCESSIBLE_PROCEDURES 20 +#define SQL_CURSOR_COMMIT_BEHAVIOR 23 +#define SQL_DATA_SOURCE_READ_ONLY 25 +#define SQL_DEFAULT_TXN_ISOLATION 26 +#define SQL_IDENTIFIER_CASE 28 +#define SQL_IDENTIFIER_QUOTE_CHAR 29 +#define SQL_MAX_COLUMN_NAME_LEN 30 +#define SQL_MAXIMUM_COLUMN_NAME_LENGTH SQL_MAX_COLUMN_NAME_LEN +#define SQL_MAX_CURSOR_NAME_LEN 31 +#define SQL_MAXIMUM_CURSOR_NAME_LENGTH SQL_MAX_CURSOR_NAME_LEN +#define SQL_MAX_TABLE_NAME_LEN 35 +#define SQL_SCROLL_CONCURRENCY 43 +#define SQL_TXN_CAPABLE 46 +#define SQL_TRANSACTION_CAPABLE SQL_TXN_CAPABLE +#define SQL_USER_NAME 47 +#define SQL_TXN_ISOLATION_OPTION 72 +#define SQL_TRANSACTION_ISOLATION_OPTION SQL_TXN_ISOLATION_OPTION +#define SQL_GETDATA_EXTENSIONS 81 +#define SQL_NULL_COLLATION 85 +#define SQL_ALTER_TABLE 86 +#define SQL_ORDER_BY_COLUMNS_IN_SELECT 90 +#define SQL_SPECIAL_CHARACTERS 94 +#define SQL_MAX_COLUMNS_IN_GROUP_BY 97 +#define SQL_MAXIMUM_COLUMNS_IN_GROUP_BY SQL_MAX_COLUMNS_IN_GROUP_BY +#define SQL_MAX_COLUMNS_IN_INDEX 98 +#define SQL_MAXIMUM_COLUMNS_IN_INDEX SQL_MAX_COLUMNS_IN_INDEX +#define SQL_MAX_COLUMNS_IN_ORDER_BY 99 +#define SQL_MAXIMUM_COLUMNS_IN_ORDER_BY SQL_MAX_COLUMNS_IN_ORDER_BY +#define SQL_MAX_COLUMNS_IN_SELECT 100 +#define SQL_MAXIMUM_COLUMNS_IN_SELECT SQL_MAX_COLUMNS_IN_SELECT +#define SQL_MAX_COLUMNS_IN_TABLE 101 +#define SQL_MAX_INDEX_SIZE 102 +#define SQL_MAXIMUM_INDEX_SIZE SQL_MAX_INDEX_SIZE +#define SQL_MAX_ROW_SIZE 104 +#define SQL_MAXIMUM_ROW_SIZE SQL_MAX_ROW_SIZE +#define SQL_MAX_STATEMENT_LEN 105 +#define SQL_MAXIMUM_STATEMENT_LENGTH SQL_MAX_STATEMENT_LEN +#define SQL_MAX_TABLES_IN_SELECT 106 +#define SQL_MAXIMUM_TABLES_IN_SELECT SQL_MAX_TABLES_IN_SELECT +#define SQL_MAX_USER_NAME_LEN 107 +#define SQL_MAXIMUM_USER_NAME_LENGTH SQL_MAX_USER_NAME_LEN +#define SQL_MAX_SCHEMA_NAME_LEN SQL_MAX_OWNER_NAME_LEN +#define SQL_MAXIMUM_SCHEMA_NAME_LENGTH SQL_MAX_SCHEMA_NAME_LEN +#define SQL_MAX_CATALOG_NAME_LEN SQL_MAX_QUALIFIER_NAME_LEN +#define SQL_MAXIMUM_CATALOG_NAME_LENGTH SQL_MAX_CATALOG_NAME_LEN +#define SQL_OJ_CAPABILITIES 115 +#define SQL_OUTER_JOIN_CAPABILITIES SQL_OJ_CAPABILITIES +#define SQL_XOPEN_CLI_YEAR 10000 +#define SQL_CURSOR_SENSITIVITY 10001 +#define SQL_DESCRIBE_PARAMETER 10002 +#define SQL_CATALOG_NAME 10003 +#define SQL_COLLATION_SEQ 10004 +#define SQL_MAX_IDENTIFIER_LEN 10005 +#define SQL_MAXIMUM_IDENTIFIER_LENGTH SQL_MAX_IDENTIFIER_LEN +#define SQL_INTEGRITY 73 +#define SQL_DATABASE_CODEPAGE 2519 +#define SQL_APPLICATION_CODEPAGE 2520 +#define SQL_CONNECT_CODEPAGE 2521 +#define SQL_ATTR_DB2_APPLICATION_ID 2532 +#define SQL_ATTR_DB2_APPLICATION_HANDLE 2533 +#define SQL_ATTR_HANDLE_XA_ASSOCIATED 2535 +#define SQL_DB2_DRIVER_VER 2550 +#define SQL_ATTR_XML_DECLARATION 2552 +#define SQL_ATTR_CURRENT_IMPLICIT_XMLPARSE_OPTION 2553 +#define SQL_ATTR_XQUERY_STATEMENT 2557 +#define SQL_DB2_DRIVER_TYPE 2567 +#define SQL_INPUT_CHAR_CONVFACTOR 2581 +#define SQL_OUTPUT_CHAR_CONVFACTOR 2582 +#define SQL_ATTR_REPLACE_QUOTED_LITERALS 2586 +#define SQL_ATTR_REPORT_TIMESTAMP_TRUNC_AS_WARN 2587 + + +#define SQL_INFO_LAST 114 +#define SQL_INFO_DRIVER_START 1000 + +/* SQL_ALTER_TABLE bitmasks */ +#define SQL_AT_ADD_COLUMN 0x00000001L +#define SQL_AT_DROP_COLUMN 0x00000002L +#define SQL_AT_ADD_CONSTRAINT 0x00000008L + +/* Bitmasks for SQL_ASYNC_MODE */ + +#define SQL_AM_NONE 0 +#define SQL_AM_CONNECTION 1 +#define SQL_AM_STATEMENT 2 + +/* SQL_CURSOR_COMMIT_BEHAVIOR and SQL_CURSOR_ROLLBACK_BEHAVIOR values */ + +#define SQL_CB_DELETE 0x0000 +#define SQL_CB_CLOSE 0x0001 +#define SQL_CB_PRESERVE 0x0002 + +/* SQL_FETCH_DIRECTION masks */ + +#define SQL_FD_FETCH_NEXT 0x00000001L +#define SQL_FD_FETCH_FIRST 0x00000002L +#define SQL_FD_FETCH_LAST 0x00000004L +#define SQL_FD_FETCH_PRIOR 0x00000008L +#define SQL_FD_FETCH_ABSOLUTE 0x00000010L +#define SQL_FD_FETCH_RELATIVE 0x00000020L +#define SQL_FD_FETCH_RESUME 0x00000040L + +/* SQL_GETDATA_EXTENSIONS values */ + +#define SQL_GD_ANY_COLUMN 0x00000001L +#define SQL_GD_ANY_ORDER 0x00000002L + +/* SQL_IDENTIFIER_CASE values */ + +#define SQL_IC_UPPER 0x0001 +#define SQL_IC_LOWER 0x0002 +#define SQL_IC_SENSITIVE 0x0003 +#define SQL_IC_MIXED 0x0004 + +/* SQL_OJ_CAPABILITIES values */ + +#define SQL_OJ_LEFT 0x00000001L +#define SQL_OJ_RIGHT 0x00000002L +#define SQL_OJ_FULL 0x00000004L +#define SQL_OJ_NESTED 0x00000008L +#define SQL_OJ_NOT_ORDERED 0x00000010L +#define SQL_OJ_INNER 0x00000020L +#define SQL_OJ_ALL_COMPARISON_OPS 0x00000040L + +/* SQL_TXN_CAPABLE values */ + +#define SQL_TC_NONE 0x0000 +#define SQL_TC_DML 0x0001 +#define SQL_TC_ALL 0x0002 +#define SQL_TC_DDL_COMMIT 0x0003 +#define SQL_TC_DDL_IGNORE 0x0004 + +/* SQL_SCROLL_CONCURRENCY masks */ + +#define SQL_SCCO_READ_ONLY 0x00000001L +#define SQL_SCCO_LOCK 0x00000002L +#define SQL_SCCO_OPT_ROWVER 0x00000004L +#define SQL_SCCO_OPT_VALUES 0x00000008L + +/* SQL_TXN_ISOLATION_OPTION masks */ +#define SQL_TXN_READ_UNCOMMITTED 0x00000001L +#define SQL_TRANSACTION_READ_UNCOMMITTED SQL_TXN_READ_UNCOMMITTED +#define SQL_TXN_READ_COMMITTED 0x00000002L +#define SQL_TRANSACTION_READ_COMMITTED SQL_TXN_READ_COMMITTED +#define SQL_TXN_REPEATABLE_READ 0x00000004L +#define SQL_TRANSACTION_REPEATABLE_READ SQL_TXN_REPEATABLE_READ +#define SQL_TXN_SERIALIZABLE 0x00000008L +#define SQL_TRANSACTION_SERIALIZABLE SQL_TXN_SERIALIZABLE +#define SQL_TXN_NOCOMMIT 0x00000020L +#define SQL_TRANSACTION_NOCOMMIT SQL_TXN_NOCOMMIT +#define SQL_TXN_IDS_CURSOR_STABILITY 0x00000040L +#define SQL_TRANSACTION_IDS_CURSOR_STABILITY SQL_TXN_IDS_CURSOR_STABILITY +#define SQL_TXN_IDS_LAST_COMMITTED 0x00000080L +#define SQL_TRANSACTION_IDS_LAST_COMMITTED SQL_TXN_IDS_LAST_COMMITTED + +#define SQL_TXN_LAST_COMMITTED 0x00000010L +#define SQL_TRANSACTION_LAST_COMMITTED SQL_TXN_LAST_COMMITTED + +/* SQL_NULL_COLLATION values */ +#define SQL_NC_HIGH 0 +#define SQL_NC_LOW 1 + +/* API Prototypes */ + +SQLRETURN SQL_API_FN SQLAllocConnect (SQLHENV henv, + SQLHDBC FAR *phdbc); + + +SQLRETURN SQL_API_FN SQLAllocEnv (SQLHENV FAR *phenv); + +SQLRETURN SQL_API_FN SQLAllocStmt (SQLHDBC hdbc, + SQLHSTMT FAR *phstmt); + +SQLRETURN SQL_API_FN SQLAllocHandle (SQLSMALLINT fHandleType, + SQLHANDLE hInput, + SQLHANDLE * phOutput); + +SQLRETURN SQL_API_FN SQLBindCol (SQLHSTMT hstmt, + SQLUSMALLINT icol, + SQLSMALLINT fCType, + SQLPOINTER rgbValue, + SQLLEN cbValueMax, + SQLLEN FAR *pcbValue); + +SQLRETURN SQL_API_FN SQLCancel (SQLHSTMT hstmt); + +SQLRETURN SQL_API_FN SQLBindParam (SQLHSTMT StatementHandle, + SQLUSMALLINT ParameterNumber, + SQLSMALLINT ValueType, + SQLSMALLINT ParameterType, + SQLULEN LengthPrecision, + SQLSMALLINT ParameterScale, + SQLPOINTER ParameterValue, + SQLLEN *StrLen_or_Ind); + +SQLRETURN SQL_API_FN SQLCloseCursor (SQLHSTMT hStmt); + +SQLRETURN SQL_API_FN SQLColAttribute (SQLHSTMT hstmt, + SQLUSMALLINT icol, + SQLUSMALLINT fDescType, + SQLPOINTER rgbDesc, + SQLSMALLINT cbDescMax, + SQLSMALLINT FAR *pcbDesc, + SQLPOINTER pfDesc); + + +SQLRETURN SQL_API_FN SQLColumns (SQLHSTMT hstmt, + SQLCHAR FAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR FAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR FAR *szTableName, + SQLSMALLINT cbTableName, + SQLCHAR FAR *szColumnName, + SQLSMALLINT cbColumnName); + +SQLRETURN SQL_API_FN SQLConnect (SQLHDBC hdbc, + SQLCHAR FAR *szDSN, + SQLSMALLINT cbDSN, + SQLCHAR FAR *szUID, + SQLSMALLINT cbUID, + SQLCHAR FAR *szAuthStr, + SQLSMALLINT cbAuthStr); + +SQLRETURN SQL_API_FN SQLCopyDesc (SQLHDESC hDescSource, + SQLHDESC hDescTarget); + +SQLRETURN SQL_API_FN SQLDataSources (SQLHENV henv, + SQLUSMALLINT fDirection, + SQLCHAR FAR *szDSN, + SQLSMALLINT cbDSNMax, + SQLSMALLINT FAR *pcbDSN, + SQLCHAR FAR *szDescription, + SQLSMALLINT cbDescriptionMax, + SQLSMALLINT FAR *pcbDescription); + +SQLRETURN SQL_API_FN SQLDescribeCol (SQLHSTMT hstmt, + SQLUSMALLINT icol, + SQLCHAR FAR *szColName, + SQLSMALLINT cbColNameMax, + SQLSMALLINT FAR *pcbColName, + SQLSMALLINT FAR *pfSqlType, + SQLULEN FAR *pcbColDef, + SQLSMALLINT FAR *pibScale, + SQLSMALLINT FAR *pfNullable); + +SQLRETURN SQL_API_FN SQLDisconnect (SQLHDBC hdbc); + +SQLRETURN SQL_API_FN SQLEndTran (SQLSMALLINT fHandleType, + SQLHANDLE hHandle, + SQLSMALLINT fType); + +SQLRETURN SQL_API_FN SQLError (SQLHENV henv, + SQLHDBC hdbc, + SQLHSTMT hstmt, + SQLCHAR FAR *szSqlState, + SQLINTEGER FAR *pfNativeError, + SQLCHAR FAR *szErrorMsg, + SQLSMALLINT cbErrorMsgMax, + SQLSMALLINT FAR *pcbErrorMsg); + +SQLRETURN SQL_API_FN SQLExecDirect (SQLHSTMT hstmt, + SQLCHAR FAR *szSqlStr, + SQLINTEGER cbSqlStr); + +SQLRETURN SQL_API_FN SQLExecute (SQLHSTMT hstmt); + +SQLRETURN SQL_API_FN SQLFetch (SQLHSTMT hstmt); + + +SQLRETURN SQL_API SQLFetchScroll (SQLHSTMT StatementHandle, + SQLSMALLINT FetchOrientation, + SQLLEN FetchOffset); + +SQLRETURN SQL_API_FN SQLFreeConnect (SQLHDBC hdbc); + +SQLRETURN SQL_API_FN SQLFreeEnv (SQLHENV henv); + +SQLRETURN SQL_API_FN SQLFreeStmt (SQLHSTMT hstmt, + SQLUSMALLINT fOption); + +SQLRETURN SQL_API_FN SQLFreeHandle (SQLSMALLINT fHandleType, + SQLHANDLE hHandle); + +SQLRETURN SQL_API SQLGetConnectAttr (SQLHDBC ConnectionHandle, + SQLINTEGER Attribute, + SQLPOINTER Value, + SQLINTEGER BufferLength, + SQLINTEGER *StringLength); + +SQLRETURN SQL_API_FN SQLGetConnectOption ( + SQLHDBC hdbc, + SQLUSMALLINT fOption, + SQLPOINTER pvParam); + +SQLRETURN SQL_API_FN SQLGetCursorName (SQLHSTMT hstmt, + SQLCHAR FAR *szCursor, + SQLSMALLINT cbCursorMax, + SQLSMALLINT FAR *pcbCursor); + +SQLRETURN SQL_API_FN SQLGetData (SQLHSTMT hstmt, + SQLUSMALLINT icol, + SQLSMALLINT fCType, + SQLPOINTER rgbValue, + SQLLEN cbValueMax, + SQLLEN FAR *pcbValue); + + +SQLRETURN SQL_API_FN SQLGetDescField( SQLHDESC DescriptorHandle, + SQLSMALLINT RecNumber, + SQLSMALLINT FieldIdentifier, + SQLPOINTER Value, + SQLINTEGER BufferLength, + SQLINTEGER *StringLength); + +SQLRETURN SQL_API_FN SQLGetDescRec( SQLHDESC DescriptorHandle, + SQLSMALLINT RecNumber, + SQLCHAR *Name, + SQLSMALLINT BufferLength, + SQLSMALLINT *StringLength, + SQLSMALLINT *Type, + SQLSMALLINT *SubType, + SQLLEN *Length, + SQLSMALLINT *Precision, + SQLSMALLINT *Scale, + SQLSMALLINT *Nullable); + +SQLRETURN SQL_API_FN SQLGetDiagField( SQLSMALLINT fHandleType, + SQLHANDLE hHandle, + SQLSMALLINT iRecNumber, + SQLSMALLINT fDiagIdentifier, + SQLPOINTER pDiagInfo, + SQLSMALLINT cbDiagInfoMax, + SQLSMALLINT * pcbDiagInfo ); + + +SQLRETURN SQL_API_FN SQLGetDiagRec( SQLSMALLINT fHandleType, + SQLHANDLE hHandle, + SQLSMALLINT iRecNumber, + SQLCHAR * pszSqlState, + SQLINTEGER * pfNativeError, + SQLCHAR * pszErrorMsg, + SQLSMALLINT cbErrorMsgMax, + SQLSMALLINT * pcbErrorMsg ); + +SQLRETURN SQL_API_FN SQLGetEnvAttr (SQLHENV henv, + SQLINTEGER Attribute, + SQLPOINTER Value, + SQLINTEGER BufferLength, + SQLINTEGER FAR *StringLength); + +SQLRETURN SQL_API_FN SQLGetFunctions (SQLHDBC hdbc, + SQLUSMALLINT fFunction, + SQLUSMALLINT FAR *pfExists); + + +SQLRETURN SQL_API_FN SQLGetInfo (SQLHDBC hdbc, + SQLUSMALLINT fInfoType, + SQLPOINTER rgbInfoValue, + SQLSMALLINT cbInfoValueMax, + SQLSMALLINT FAR *pcbInfoValue); + +SQLRETURN SQL_API SQLGetStmtAttr (SQLHSTMT StatementHandle, + SQLINTEGER Attribute, + SQLPOINTER Value, + SQLINTEGER BufferLength, + SQLINTEGER *StringLength); + +SQLRETURN SQL_API_FN SQLGetStmtOption (SQLHSTMT hstmt, + SQLUSMALLINT fOption, + SQLPOINTER pvParam); + +SQLRETURN SQL_API_FN SQLGetTypeInfo (SQLHSTMT hstmt, + SQLSMALLINT fSqlType); + + +SQLRETURN SQL_API_FN SQLNumResultCols (SQLHSTMT hstmt, + SQLSMALLINT FAR *pccol); + + +SQLRETURN SQL_API_FN SQLParamData (SQLHSTMT hstmt, + SQLPOINTER FAR *prgbValue); + + +SQLRETURN SQL_API_FN SQLPrepare (SQLHSTMT hstmt, + SQLCHAR FAR *szSqlStr, + SQLINTEGER cbSqlStr); + +SQLRETURN SQL_API_FN SQLPutData (SQLHSTMT hstmt, + SQLPOINTER rgbValue, + SQLLEN cbValue); + +SQLRETURN SQL_API_FN SQLRowCount (SQLHSTMT hstmt, + SQLLEN FAR *pcrow); + + +SQLRETURN SQL_API_FN SQLSetConnectAttr( + SQLHDBC hdbc, + SQLINTEGER fOption, + SQLPOINTER pvParam, + SQLINTEGER fStrLen); + +SQLRETURN SQL_API_FN SQLSetConnectOption( + SQLHDBC hdbc, + SQLUSMALLINT fOption, + ULONG vParam); + +SQLRETURN SQL_API_FN SQLSetCursorName (SQLHSTMT hstmt, + SQLCHAR FAR *szCursor, + SQLSMALLINT cbCursor); + + +SQLRETURN SQL_API_FN SQLSetDescField (SQLHDESC DescriptorHandle, + SQLSMALLINT RecNumber, + SQLSMALLINT FieldIdentifier, + SQLPOINTER Value, + SQLINTEGER BufferLength); + +SQLRETURN SQL_API_FN SQLSetDescRec (SQLHDESC DescriptorHandle, + SQLSMALLINT RecNumber, + SQLSMALLINT Type, + SQLSMALLINT SubType, + SQLLEN Length, + SQLSMALLINT Precision, + SQLSMALLINT Scale, + SQLPOINTER Data, + SQLLEN *StringLength, + SQLLEN *Indicator); + +SQLRETURN SQL_API_FN SQLSetEnvAttr (SQLHENV henv, + SQLINTEGER Attribute, + SQLPOINTER Value, + SQLINTEGER StringLength); + + +SQLRETURN SQL_API_FN SQLSetParam (SQLHSTMT hstmt, + SQLUSMALLINT ipar, + SQLSMALLINT fCType, + SQLSMALLINT fSqlType, + SQLULEN cbParamDef, + SQLSMALLINT ibScale, + SQLPOINTER rgbValue, + SQLLEN FAR *pcbValue); + +SQLRETURN SQL_API_FN SQLSetStmtAttr (SQLHSTMT hstmt, + SQLINTEGER fOption, + SQLPOINTER pvParam, + SQLINTEGER fStrLen); + + +SQLRETURN SQL_API_FN SQLSetStmtOption (SQLHSTMT hstmt, + SQLUSMALLINT fOption, + SQLULEN vParam); + +SQLRETURN SQL_API_FN SQLSpecialColumns(SQLHSTMT hstmt, + SQLUSMALLINT fColType, + SQLCHAR FAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR FAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR FAR *szTableName, + SQLSMALLINT cbTableName, + SQLUSMALLINT fScope, + SQLUSMALLINT fNullable); + +SQLRETURN SQL_API_FN SQLStatistics (SQLHSTMT hstmt, + SQLCHAR FAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR FAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR FAR *szTableName, + SQLSMALLINT cbTableName, + SQLUSMALLINT fUnique, + + SQLUSMALLINT fAccuracy); + +SQLRETURN SQL_API_FN SQLTables (SQLHSTMT hstmt, + SQLCHAR FAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR FAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR FAR *szTableName, + SQLSMALLINT cbTableName, + SQLCHAR FAR *szTableType, + SQLSMALLINT cbTableType); + +SQLRETURN SQL_API_FN SQLTransact (SQLHENV henv, + SQLHDBC hdbc, + SQLUSMALLINT fType); +#endif + + + +#ifdef __cplusplus +} /* End of extern "C" { */ +#endif /* __cplusplus */ + +#define GUID TAGGUID +typedef struct _TAGGUID { + unsigned long Data1; + unsigned short Data2; + unsigned short Data3; + unsigned char Data4[ 8 ]; +} TAGGUID; + +#define __SQL +#include + +#undef GUID + +/* UNICODE versions */ + +#if defined(_WIN64) || defined(ODBC64) +SQLRETURN SQL_API SQLColAttributeW( + SQLHSTMT hstmt, + SQLUSMALLINT iCol, + SQLUSMALLINT iField, + SQLPOINTER pCharAttr, + SQLSMALLINT cbCharAttrMax, + SQLSMALLINT *pcbCharAttr, + SQLLEN *pNumAttr); +#else + SQLRETURN SQL_API SQLColAttributeW( + SQLHSTMT hstmt, + SQLUSMALLINT iCol, + SQLUSMALLINT iField, + SQLPOINTER pCharAttr, + SQLSMALLINT cbCharAttrMax, + SQLSMALLINT *pcbCharAttr, + SQLPOINTER pNumAttr); +#endif + +SQLRETURN SQL_API SQLColAttributesW( + SQLHSTMT hstmt, + SQLUSMALLINT icol, + SQLUSMALLINT fDescType, + SQLPOINTER rgbDesc, + SQLSMALLINT cbDescMax, + SQLSMALLINT *pcbDesc, + SQLLEN *pfDesc); + +SQLRETURN SQL_API SQLConnectW( + SQLHDBC hdbc, + SQLWCHAR *szDSN, + SQLSMALLINT cbDSN, + SQLWCHAR *szUID, + SQLSMALLINT cbUID, + SQLWCHAR *szAuthStr, + SQLSMALLINT cbAuthStr); + +SQLRETURN SQL_API SQLConnectWInt( + SQLHDBC hdbc, + SQLWCHAR *szDSN, + SQLSMALLINT cbDSN, + SQLWCHAR *szUID, + SQLSMALLINT cbUID, + SQLWCHAR *szAuthStr, + SQLSMALLINT cbAuthStr); + + +SQLRETURN SQL_API SQLDescribeColW( + SQLHSTMT hstmt, + SQLUSMALLINT icol, + SQLWCHAR *szColName, + SQLSMALLINT cbColNameMax, + SQLSMALLINT *pcbColName, + SQLSMALLINT *pfSqlType, + SQLULEN *pcbColDef, + SQLSMALLINT *pibScale, + SQLSMALLINT *pfNullable); + + +SQLRETURN SQL_API SQLErrorW( + SQLHENV henv, + SQLHDBC hdbc, + SQLHSTMT hstmt, + SQLWCHAR *szSqlState, + SQLINTEGER *pfNativeError, + SQLWCHAR *szErrorMsg, + SQLSMALLINT cbErrorMsgMax, + SQLSMALLINT *pcbErrorMsg); + +SQLRETURN SQL_API SQLExecDirectW( + SQLHSTMT hstmt, + SQLWCHAR *szSqlStr, + SQLINTEGER cbSqlStr); + +SQLRETURN SQL_API SQLGetConnectAttrW( + SQLHDBC hdbc, + SQLINTEGER fAttribute, + SQLPOINTER rgbValue, + SQLINTEGER cbValueMax, + SQLINTEGER *pcbValue); + +SQLRETURN SQL_API SQLGetCursorNameW( + SQLHSTMT hstmt, + SQLWCHAR *szCursor, + SQLSMALLINT cbCursorMax, + SQLSMALLINT *pcbCursor); + +SQLRETURN SQL_API SQLSetDescFieldW(SQLHDESC DescriptorHandle, + SQLSMALLINT RecNumber, + SQLSMALLINT FieldIdentifier, + SQLPOINTER Value, + SQLINTEGER BufferLength); + + + +SQLRETURN SQL_API SQLGetDescFieldW( + SQLHDESC hdesc, + SQLSMALLINT iRecord, + SQLSMALLINT iField, + SQLPOINTER rgbValue, + SQLINTEGER cbValueMax, + SQLINTEGER *pcbValue); + +SQLRETURN SQL_API SQLGetDescRecW( + SQLHDESC hdesc, + SQLSMALLINT iRecord, + SQLWCHAR *szName, + SQLSMALLINT cbNameMax, + SQLSMALLINT *pcbName, + SQLSMALLINT *pfType, + SQLSMALLINT *pfSubType, + SQLLEN *pLength, + SQLSMALLINT *pPrecision, + SQLSMALLINT *pScale, + SQLSMALLINT *pNullable); + +SQLRETURN SQL_API SQLGetDiagFieldW( + SQLSMALLINT fHandleType, + SQLHANDLE handle, + SQLSMALLINT iRecord, + SQLSMALLINT fDiagField, + SQLPOINTER rgbDiagInfo, + SQLSMALLINT cbDiagInfoMax, + SQLSMALLINT *pcbDiagInfo); + +SQLRETURN SQL_API SQLGetDiagRecW( + SQLSMALLINT fHandleType, + SQLHANDLE handle, + SQLSMALLINT iRecord, + SQLWCHAR *szSqlState, + SQLINTEGER *pfNativeError, + SQLWCHAR *szErrorMsg, + SQLSMALLINT cbErrorMsgMax, + SQLSMALLINT *pcbErrorMsg); + +SQLRETURN SQL_API_FN SQLGetEnvAttrW( + SQLHENV hEnv, + SQLINTEGER fAttribute, + SQLPOINTER pParam, + SQLINTEGER cbParamMax, + SQLINTEGER * pcbParam ); + +SQLRETURN SQL_API SQLPrepareW( + SQLHSTMT hstmt, + SQLWCHAR *szSqlStr, + SQLINTEGER cbSqlStr); + +SQLRETURN SQL_API_FN SQLExtendedPrepareW( SQLHSTMT hStmt, + SQLWCHAR * pszSqlStrIn, + SQLINTEGER cbSqlStr, + SQLINTEGER cPars, + SQLSMALLINT sStmtType, + SQLINTEGER cStmtAttrs, + SQLINTEGER * piStmtAttr, + SQLINTEGER * pvParams ); + +SQLRETURN SQL_API SQLSetConnectAttrW( + SQLHDBC hdbc, + SQLINTEGER fAttribute, + SQLPOINTER rgbValue, + SQLINTEGER cbValue); + +SQLRETURN SQL_API SQLSetCursorNameW( + SQLHSTMT hstmt, + SQLWCHAR *szCursor, + SQLSMALLINT cbCursor); + +SQLRETURN SQL_API_FN SQLSetEnvAttrW( + SQLHENV hEnv, + SQLINTEGER fAttribute, + SQLPOINTER pParam, + SQLINTEGER cbParam ); + +SQLRETURN SQL_API SQLColumnsW( + SQLHSTMT hstmt, + SQLWCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLWCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLWCHAR *szTableName, + SQLSMALLINT cbTableName, + SQLWCHAR *szColumnName, + SQLSMALLINT cbColumnName); + +SQLRETURN SQL_API SQLGetInfoW( + SQLHDBC hdbc, + SQLUSMALLINT fInfoType, + SQLPOINTER rgbInfoValue, + SQLSMALLINT cbInfoValueMax, + SQLSMALLINT *pcbInfoValue); + +SQLRETURN SQL_API_FN SQLGetConnectOptionW( + SQLHDBC hDbc, + SQLUSMALLINT fOptionIn, + SQLPOINTER pvParam ); + +SQLRETURN SQL_API_FN SQLSetConnectOptionW( + SQLHDBC hDbc, + SQLUSMALLINT fOptionIn, + SQLULEN vParam ); + +SQLRETURN SQL_API_FN SQLGetTypeInfoW( + SQLHSTMT hstmt, + SQLSMALLINT fSqlType); + +SQLRETURN SQL_API SQLSpecialColumnsW( + SQLHSTMT hstmt, + SQLUSMALLINT fColType, + SQLWCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLWCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLWCHAR *szTableName, + SQLSMALLINT cbTableName, + SQLUSMALLINT fScope, + SQLUSMALLINT fNullable); + +SQLRETURN SQL_API SQLStatisticsW( + SQLHSTMT hstmt, + SQLWCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLWCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLWCHAR *szTableName, + SQLSMALLINT cbTableName, + SQLUSMALLINT fUnique, + SQLUSMALLINT fAccuracy); + +SQLRETURN SQL_API SQLTablesW( + SQLHSTMT hstmt, + SQLWCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLWCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLWCHAR *szTableName, + SQLSMALLINT cbTableName, + SQLWCHAR *szTableType, + SQLSMALLINT cbTableType); + + + +SQLRETURN SQL_API SQLDataSourcesW( + SQLHENV henv, + SQLUSMALLINT fDirection, + SQLWCHAR *szDSN, + SQLSMALLINT cbDSNMax, + SQLSMALLINT *pcbDSN, + SQLWCHAR *szDescription, + SQLSMALLINT cbDescriptionMax, + SQLSMALLINT *pcbDescription); + + + + +SQLRETURN SQL_API SQLDriverConnectW( + SQLHDBC hdbc, + SQLHWND hwnd, + SQLWCHAR *szConnStrIn, + SQLSMALLINT cbConnStrIn, + SQLWCHAR *szConnStrOut, + SQLSMALLINT cbConnStrOutMax, + SQLSMALLINT *pcbConnStrOut, + SQLUSMALLINT fDriverCompletion); + + +SQLRETURN SQL_API SQLBrowseConnectW( + SQLHDBC hdbc, + SQLWCHAR *szConnStrIn, + SQLSMALLINT cbConnStrIn, + SQLWCHAR *szConnStrOut, + SQLSMALLINT cbConnStrOutMax, + SQLSMALLINT *pcbConnStrOut); + +SQLRETURN SQL_API SQLColumnPrivilegesW( + SQLHSTMT hstmt, + SQLWCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLWCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLWCHAR *szTableName, + SQLSMALLINT cbTableName, + SQLWCHAR *szColumnName, + SQLSMALLINT cbColumnName); + +SQLRETURN SQL_API SQLGetStmtAttrW( + SQLHSTMT hstmt, + SQLINTEGER fAttribute, + SQLPOINTER rgbValue, + SQLINTEGER cbValueMax, + SQLINTEGER *pcbValue); + +SQLRETURN SQL_API SQLSetStmtAttrW( + SQLHSTMT hstmt, + SQLINTEGER fAttribute, + SQLPOINTER rgbValue, + SQLINTEGER cbValueMax); + +SQLRETURN SQL_API SQLForeignKeysW( + SQLHSTMT hstmt, + SQLWCHAR *szPkCatalogName, + SQLSMALLINT cbPkCatalogName, + SQLWCHAR *szPkSchemaName, + SQLSMALLINT cbPkSchemaName, + SQLWCHAR *szPkTableName, + SQLSMALLINT cbPkTableName, + SQLWCHAR *szFkCatalogName, + SQLSMALLINT cbFkCatalogName, + SQLWCHAR *szFkSchemaName, + SQLSMALLINT cbFkSchemaName, + SQLWCHAR *szFkTableName, + SQLSMALLINT cbFkTableName); + + +SQLRETURN SQL_API SQLNativeSqlW( + SQLHDBC hdbc, + SQLWCHAR *szSqlStrIn, + SQLINTEGER cbSqlStrIn, + SQLWCHAR *szSqlStr, + SQLINTEGER cbSqlStrMax, + SQLINTEGER *pcbSqlStr); + + +SQLRETURN SQL_API SQLPrimaryKeysW( + SQLHSTMT hstmt, + SQLWCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLWCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLWCHAR *szTableName, + SQLSMALLINT cbTableName); + +SQLRETURN SQL_API SQLProcedureColumnsW( + SQLHSTMT hstmt, + SQLWCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLWCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLWCHAR *szProcName, + SQLSMALLINT cbProcName, + SQLWCHAR *szColumnName, + SQLSMALLINT cbColumnName); + +SQLRETURN SQL_API SQLProceduresW( + SQLHSTMT hstmt, + SQLWCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLWCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLWCHAR *szProcName, + SQLSMALLINT cbProcName); + + +SQLRETURN SQL_API SQLTablePrivilegesW( + SQLHSTMT hstmt, + SQLWCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLWCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLWCHAR *szTableName, + SQLSMALLINT cbTableName); + +SQLRETURN SQL_API SQLDriversW( + SQLHENV henv, + SQLUSMALLINT fDirection, + SQLWCHAR *szDriverDesc, + SQLSMALLINT cbDriverDescMax, + SQLSMALLINT *pcbDriverDesc, + SQLWCHAR *szDriverAttributes, + SQLSMALLINT cbDrvrAttrMax, + SQLSMALLINT *pcbDrvrAttr); + +#endif /* __INFXSQL */ diff --git a/libodbc/include/informix/sqlext.h b/libodbc/include/informix/sqlext.h new file mode 100644 index 0000000000..6526be21a0 --- /dev/null +++ b/libodbc/include/informix/sqlext.h @@ -0,0 +1,2069 @@ +//----------------------------------------------------------------------------- +// File: sqlext.h +// +// Copyright: Copyright (c) Microsoft Corporation +// +// Contents: This is the include for applications using the Microsoft SQL Extensions +// +// Comments: +// +//----------------------------------------------------------------------------- + +#ifndef __SQLEXT +#define __SQLEXT + +#ifndef __SQL +#include "sql.h" +#endif + +#ifdef __cplusplus +extern "C" { /* Assume C declarations for C++ */ +#endif /* __cplusplus */ + +/* generally useful constants */ +#define SQL_SPEC_MAJOR 3 /* Major version of specification */ +#define SQL_SPEC_MINOR 52 /* Minor version of specification */ +#define SQL_SPEC_STRING "03.52" /* String constant for version */ + +#define SQL_SQLSTATE_SIZE 5 /* size of SQLSTATE */ +#define SQL_MAX_DSN_LENGTH 32 /* maximum data source name size */ + +#define SQL_MAX_OPTION_STRING_LENGTH 256 + +/* return code SQL_NO_DATA_FOUND is the same as SQL_NO_DATA */ +#if (ODBCVER < 0x0300) +#define SQL_NO_DATA_FOUND 100 +#else +#define SQL_NO_DATA_FOUND SQL_NO_DATA +#endif + +/* an end handle type */ +#if (ODBCVER >= 0x0300) +#define SQL_HANDLE_SENV 5 +#endif /* ODBCVER >= 0x0300 */ + +/* env attribute */ +#if (ODBCVER >= 0x0300) +#define SQL_ATTR_ODBC_VERSION 200 +#define SQL_ATTR_CONNECTION_POOLING 201 +#define SQL_ATTR_CP_MATCH 202 +#endif /* ODBCVER >= 0x0300 */ + +#if (ODBCVER >= 0x0300) +/* values for SQL_ATTR_CONNECTION_POOLING */ +#define SQL_CP_OFF 0UL +#define SQL_CP_ONE_PER_DRIVER 1UL +#define SQL_CP_ONE_PER_HENV 2UL +#define SQL_CP_DEFAULT SQL_CP_OFF + +/* values for SQL_ATTR_CP_MATCH */ +#define SQL_CP_STRICT_MATCH 0UL +#define SQL_CP_RELAXED_MATCH 1UL +#define SQL_CP_MATCH_DEFAULT SQL_CP_STRICT_MATCH + +/* values for SQL_ATTR_ODBC_VERSION */ +#define SQL_OV_ODBC2 2UL +#define SQL_OV_ODBC3 3UL +#endif /* ODBCVER >= 0x0300 */ + +/* connection attributes */ +#define SQL_ACCESS_MODE 101 +#define SQL_AUTOCOMMIT 102 +#define SQL_LOGIN_TIMEOUT 103 +#define SQL_OPT_TRACE 104 +#define SQL_OPT_TRACEFILE 105 +#define SQL_TRANSLATE_DLL 106 +#define SQL_TRANSLATE_OPTION 107 +#define SQL_TXN_ISOLATION 108 +#define SQL_CURRENT_QUALIFIER 109 +#define SQL_ODBC_CURSORS 110 +#define SQL_QUIET_MODE 111 +#define SQL_PACKET_SIZE 112 + +/* connection attributes with new names */ +#if (ODBCVER >= 0x0300) +#define SQL_ATTR_ACCESS_MODE SQL_ACCESS_MODE +#define SQL_ATTR_AUTOCOMMIT SQL_AUTOCOMMIT +#define SQL_ATTR_CONNECTION_TIMEOUT 113 +#define SQL_ATTR_CURRENT_CATALOG SQL_CURRENT_QUALIFIER +#define SQL_ATTR_DISCONNECT_BEHAVIOR 114 +#define SQL_ATTR_ENLIST_IN_DTC 1207 +#define SQL_ATTR_ENLIST_IN_XA 1208 +#define SQL_ATTR_LOGIN_TIMEOUT SQL_LOGIN_TIMEOUT +#define SQL_ATTR_ODBC_CURSORS SQL_ODBC_CURSORS +#define SQL_ATTR_PACKET_SIZE SQL_PACKET_SIZE +#define SQL_ATTR_QUIET_MODE SQL_QUIET_MODE +#define SQL_ATTR_TRACE SQL_OPT_TRACE +#define SQL_ATTR_TRACEFILE SQL_OPT_TRACEFILE +#define SQL_ATTR_TRANSLATE_LIB SQL_TRANSLATE_DLL +#define SQL_ATTR_TRANSLATE_OPTION SQL_TRANSLATE_OPTION +#define SQL_ATTR_TXN_ISOLATION SQL_TXN_ISOLATION +#endif /* ODBCVER >= 0x0300 */ + +#define SQL_ATTR_CONNECTION_DEAD 1209 /* GetConnectAttr only */ + +#if (ODBCVER >= 0x0351) +/* ODBC Driver Manager sets this connection attribute to a unicode driver + (which supports SQLConnectW) when the application is an ANSI application + (which calls SQLConnect, SQLDriverConnect, or SQLBrowseConnect). + This is SetConnectAttr only and application does not set this attribute + This attribute was introduced because some unicode driver's some APIs may + need to behave differently on ANSI or Unicode applications. A unicode + driver, which has same behavior for both ANSI or Unicode applications, + should return SQL_ERROR when the driver manager sets this connection + attribute. When a unicode driver returns SQL_SUCCESS on this attribute, + the driver manager treates ANSI and Unicode connections differently in + connection pooling. +*/ +#define SQL_ATTR_ANSI_APP 115 +#endif + +/* SQL_CONNECT_OPT_DRVR_START is not meaningful for 3.0 driver */ +#if (ODBCVER < 0x0300) +#define SQL_CONNECT_OPT_DRVR_START 1000 +#endif /* ODBCVER < 0x0300 */ + +#if (ODBCVER < 0x0300) +#define SQL_CONN_OPT_MAX SQL_PACKET_SIZE +#define SQL_CONN_OPT_MIN SQL_ACCESS_MODE +#endif /* ODBCVER < 0x0300 */ + +/* SQL_ACCESS_MODE options */ +#define SQL_MODE_READ_WRITE 0UL +#define SQL_MODE_READ_ONLY 1UL +#define SQL_MODE_DEFAULT SQL_MODE_READ_WRITE + +/* SQL_AUTOCOMMIT options */ +#define SQL_AUTOCOMMIT_OFF 0UL +#define SQL_AUTOCOMMIT_ON 1UL +#define SQL_AUTOCOMMIT_DEFAULT SQL_AUTOCOMMIT_ON + +/* SQL_LOGIN_TIMEOUT options */ +#define SQL_LOGIN_TIMEOUT_DEFAULT 15UL + +/* SQL_OPT_TRACE options */ +#define SQL_OPT_TRACE_OFF 0UL +#define SQL_OPT_TRACE_ON 1UL +#define SQL_OPT_TRACE_DEFAULT SQL_OPT_TRACE_OFF +#define SQL_OPT_TRACE_FILE_DEFAULT "\\SQL.LOG" + +/* SQL_ODBC_CURSORS options */ +#define SQL_CUR_USE_IF_NEEDED 0UL +#define SQL_CUR_USE_ODBC 1UL +#define SQL_CUR_USE_DRIVER 2UL +#define SQL_CUR_DEFAULT SQL_CUR_USE_DRIVER + +#if (ODBCVER >= 0x0300) +/* values for SQL_ATTR_DISCONNECT_BEHAVIOR */ +#define SQL_DB_RETURN_TO_POOL 0UL +#define SQL_DB_DISCONNECT 1UL +#define SQL_DB_DEFAULT SQL_DB_RETURN_TO_POOL + +/* values for SQL_ATTR_ENLIST_IN_DTC */ +#define SQL_DTC_DONE 0L +#endif /* ODBCVER >= 0x0300 */ + +/* values for SQL_ATTR_CONNECTION_DEAD */ +#define SQL_CD_TRUE 1L /* Connection is closed/dead */ +#define SQL_CD_FALSE 0L /* Connection is open/available */ + +/* values for SQL_ATTR_ANSI_APP */ +#if (ODBCVER >= 0x0351) +#define SQL_AA_TRUE 1L /* the application is an ANSI app */ +#define SQL_AA_FALSE 0L /* the application is a Unicode app */ +#endif + +/* statement attributes */ +#define SQL_QUERY_TIMEOUT 0 +#define SQL_MAX_ROWS 1 +#define SQL_NOSCAN 2 +#define SQL_MAX_LENGTH 3 +#define SQL_ASYNC_ENABLE 4 /* same as SQL_ATTR_ASYNC_ENABLE */ +#define SQL_BIND_TYPE 5 +#define SQL_CURSOR_TYPE 6 +#define SQL_CONCURRENCY 7 +#define SQL_KEYSET_SIZE 8 +#define SQL_ROWSET_SIZE 9 +#define SQL_SIMULATE_CURSOR 10 +#define SQL_RETRIEVE_DATA 11 +#define SQL_USE_BOOKMARKS 12 +#define SQL_GET_BOOKMARK 13 /* GetStmtOption Only */ +#define SQL_ROW_NUMBER 14 /* GetStmtOption Only */ + +/* statement attributes for ODBC 3.0 */ +#if (ODBCVER >= 0x0300) +#define SQL_ATTR_ASYNC_ENABLE 4 +#define SQL_ATTR_CONCURRENCY SQL_CONCURRENCY +#define SQL_ATTR_CURSOR_TYPE SQL_CURSOR_TYPE +#define SQL_ATTR_ENABLE_AUTO_IPD 15 +#define SQL_ATTR_FETCH_BOOKMARK_PTR 16 +#define SQL_ATTR_KEYSET_SIZE SQL_KEYSET_SIZE +#define SQL_ATTR_MAX_LENGTH SQL_MAX_LENGTH +#define SQL_ATTR_MAX_ROWS SQL_MAX_ROWS +#define SQL_ATTR_NOSCAN SQL_NOSCAN +#define SQL_ATTR_PARAM_BIND_OFFSET_PTR 17 +#define SQL_ATTR_PARAM_BIND_TYPE 18 +#define SQL_ATTR_PARAM_OPERATION_PTR 19 +#define SQL_ATTR_PARAM_STATUS_PTR 20 +#define SQL_ATTR_PARAMS_PROCESSED_PTR 21 +#define SQL_ATTR_PARAMSET_SIZE 22 +#define SQL_ATTR_QUERY_TIMEOUT SQL_QUERY_TIMEOUT +#define SQL_ATTR_RETRIEVE_DATA SQL_RETRIEVE_DATA +#define SQL_ATTR_ROW_BIND_OFFSET_PTR 23 +#define SQL_ATTR_ROW_BIND_TYPE SQL_BIND_TYPE +#define SQL_ATTR_ROW_NUMBER SQL_ROW_NUMBER /*GetStmtAttr*/ +#define SQL_ATTR_ROW_OPERATION_PTR 24 +#define SQL_ATTR_ROW_STATUS_PTR 25 +#define SQL_ATTR_ROWS_FETCHED_PTR 26 +#define SQL_ATTR_ROW_ARRAY_SIZE 27 +#define SQL_ATTR_SIMULATE_CURSOR SQL_SIMULATE_CURSOR +#define SQL_ATTR_USE_BOOKMARKS SQL_USE_BOOKMARKS + +#endif /* ODBCVER >= 0x0300 */ + +#if (ODBCVER < 0x0300) +#define SQL_STMT_OPT_MAX SQL_ROW_NUMBER +#define SQL_STMT_OPT_MIN SQL_QUERY_TIMEOUT +#endif /* ODBCVER < 0x0300 */ + +/* New defines for SEARCHABLE column in SQLGetTypeInfo */ + +#if (ODBCVER >= 0x0300) +#define SQL_COL_PRED_CHAR SQL_LIKE_ONLY +#define SQL_COL_PRED_BASIC SQL_ALL_EXCEPT_LIKE +#endif /* ODBCVER >= 0x0300 */ + + + +/* whether an attribute is a pointer or not */ +#if (ODBCVER >= 0x0300) +#define SQL_IS_POINTER (-4) +#define SQL_IS_UINTEGER (-5) +#define SQL_IS_INTEGER (-6) +#define SQL_IS_USMALLINT (-7) +#define SQL_IS_SMALLINT (-8) +#endif /* ODBCVER >= 0x0300 */ + +/* the value of SQL_ATTR_PARAM_BIND_TYPE */ +#if (ODBCVER >= 0x0300) +#define SQL_PARAM_BIND_BY_COLUMN 0UL +#define SQL_PARAM_BIND_TYPE_DEFAULT SQL_PARAM_BIND_BY_COLUMN +#endif /* ODBCVER >= 0x0300 */ + +/* SQL_QUERY_TIMEOUT options */ +#define SQL_QUERY_TIMEOUT_DEFAULT 0UL + +/* SQL_MAX_ROWS options */ +#define SQL_MAX_ROWS_DEFAULT 0UL + +/* SQL_NOSCAN options */ +#define SQL_NOSCAN_OFF 0UL /* 1.0 FALSE */ +#define SQL_NOSCAN_ON 1UL /* 1.0 TRUE */ +#define SQL_NOSCAN_DEFAULT SQL_NOSCAN_OFF + +/* SQL_MAX_LENGTH options */ +#define SQL_MAX_LENGTH_DEFAULT 0UL + +/* values for SQL_ATTR_ASYNC_ENABLE */ +#define SQL_ASYNC_ENABLE_OFF 0UL +#define SQL_ASYNC_ENABLE_ON 1UL +#define SQL_ASYNC_ENABLE_DEFAULT SQL_ASYNC_ENABLE_OFF + +/* SQL_BIND_TYPE options */ +#define SQL_BIND_BY_COLUMN 0UL +#define SQL_BIND_TYPE_DEFAULT SQL_BIND_BY_COLUMN /* Default value */ + +/* SQL_CONCURRENCY options */ +#define SQL_CONCUR_READ_ONLY 1 +#define SQL_CONCUR_LOCK 2 +#define SQL_CONCUR_ROWVER 3 +#define SQL_CONCUR_VALUES 4 +#define SQL_CONCUR_DEFAULT SQL_CONCUR_READ_ONLY /* Default value */ + +/* SQL_CURSOR_TYPE options */ +#define SQL_CURSOR_FORWARD_ONLY 0UL +#define SQL_CURSOR_KEYSET_DRIVEN 1UL +#define SQL_CURSOR_DYNAMIC 2UL +#define SQL_CURSOR_STATIC 3UL +#define SQL_CURSOR_TYPE_DEFAULT SQL_CURSOR_FORWARD_ONLY /* Default value */ + +/* SQL_ROWSET_SIZE options */ +#define SQL_ROWSET_SIZE_DEFAULT 1UL + +/* SQL_KEYSET_SIZE options */ +#define SQL_KEYSET_SIZE_DEFAULT 0UL + +/* SQL_SIMULATE_CURSOR options */ +#define SQL_SC_NON_UNIQUE 0UL +#define SQL_SC_TRY_UNIQUE 1UL +#define SQL_SC_UNIQUE 2UL + +/* SQL_RETRIEVE_DATA options */ +#define SQL_RD_OFF 0UL +#define SQL_RD_ON 1UL +#define SQL_RD_DEFAULT SQL_RD_ON + +/* SQL_USE_BOOKMARKS options */ +#define SQL_UB_OFF 0UL +#define SQL_UB_ON 01UL +#define SQL_UB_DEFAULT SQL_UB_OFF + +/* New values for SQL_USE_BOOKMARKS attribute */ +#if (ODBCVER >= 0x0300) +#define SQL_UB_FIXED SQL_UB_ON +#define SQL_UB_VARIABLE 2UL +#endif /* ODBCVER >= 0x0300 */ + +/* extended descriptor field */ +#if (ODBCVER >= 0x0300) +#define SQL_DESC_ARRAY_SIZE 20 +#define SQL_DESC_ARRAY_STATUS_PTR 21 +#define SQL_DESC_AUTO_UNIQUE_VALUE SQL_COLUMN_AUTO_INCREMENT +#define SQL_DESC_BASE_COLUMN_NAME 22 +#define SQL_DESC_BASE_TABLE_NAME 23 +#define SQL_DESC_BIND_OFFSET_PTR 24 +#define SQL_DESC_BIND_TYPE 25 +#define SQL_DESC_CASE_SENSITIVE SQL_COLUMN_CASE_SENSITIVE +#define SQL_DESC_CATALOG_NAME SQL_COLUMN_QUALIFIER_NAME +#define SQL_DESC_CONCISE_TYPE SQL_COLUMN_TYPE +#define SQL_DESC_DATETIME_INTERVAL_PRECISION 26 +#define SQL_DESC_DISPLAY_SIZE SQL_COLUMN_DISPLAY_SIZE +#define SQL_DESC_FIXED_PREC_SCALE SQL_COLUMN_MONEY +#define SQL_DESC_LABEL SQL_COLUMN_LABEL +#define SQL_DESC_LITERAL_PREFIX 27 +#define SQL_DESC_LITERAL_SUFFIX 28 +#define SQL_DESC_LOCAL_TYPE_NAME 29 +#define SQL_DESC_MAXIMUM_SCALE 30 +#define SQL_DESC_MINIMUM_SCALE 31 +#define SQL_DESC_NUM_PREC_RADIX 32 +#define SQL_DESC_PARAMETER_TYPE 33 +#define SQL_DESC_ROWS_PROCESSED_PTR 34 +#if (ODBCVER >= 0x0350) +#define SQL_DESC_ROWVER 35 +#endif /* ODBCVER >= 0x0350 */ +#define SQL_DESC_SCHEMA_NAME SQL_COLUMN_OWNER_NAME +#define SQL_DESC_SEARCHABLE SQL_COLUMN_SEARCHABLE +#define SQL_DESC_TYPE_NAME SQL_COLUMN_TYPE_NAME +#define SQL_DESC_TABLE_NAME SQL_COLUMN_TABLE_NAME +#define SQL_DESC_UNSIGNED SQL_COLUMN_UNSIGNED +#define SQL_DESC_UPDATABLE SQL_COLUMN_UPDATABLE +#endif /* ODBCVER >= 0x0300 */ + + +/* defines for diagnostics fields */ +#if (ODBCVER >= 0x0300) +#define SQL_DIAG_CURSOR_ROW_COUNT (-1249) +#define SQL_DIAG_ROW_NUMBER (-1248) +#define SQL_DIAG_COLUMN_NUMBER (-1247) +#endif /* ODBCVER >= 0x0300 */ + +/* SQL extended datatypes */ +#define SQL_DATE 9 +#if (ODBCVER >= 0x0300) +#define SQL_INTERVAL 10 +#endif /* ODBCVER >= 0x0300 */ +#define SQL_TIME 10 +#define SQL_TIMESTAMP 11 +#define SQL_LONGVARCHAR (-1) +#define SQL_BINARY (-2) +#define SQL_VARBINARY (-3) +#define SQL_LONGVARBINARY (-4) +#define SQL_BIGINT (-5) +#define SQL_TINYINT (-6) +#define SQL_BIT (-7) +#if (ODBCVER >= 0x0350) +#define SQL_GUID (-11) +#endif /* ODBCVER >= 0x0350 */ + +#if (ODBCVER >= 0x0300) +/* interval code */ +#define SQL_CODE_YEAR 1 +#define SQL_CODE_MONTH 2 +#define SQL_CODE_DAY 3 +#define SQL_CODE_HOUR 4 +#define SQL_CODE_MINUTE 5 +#define SQL_CODE_SECOND 6 +#define SQL_CODE_YEAR_TO_MONTH 7 +#define SQL_CODE_DAY_TO_HOUR 8 +#define SQL_CODE_DAY_TO_MINUTE 9 +#define SQL_CODE_DAY_TO_SECOND 10 +#define SQL_CODE_HOUR_TO_MINUTE 11 +#define SQL_CODE_HOUR_TO_SECOND 12 +#define SQL_CODE_MINUTE_TO_SECOND 13 + +#define SQL_INTERVAL_YEAR (100 + SQL_CODE_YEAR) +#define SQL_INTERVAL_MONTH (100 + SQL_CODE_MONTH) +#define SQL_INTERVAL_DAY (100 + SQL_CODE_DAY) +#define SQL_INTERVAL_HOUR (100 + SQL_CODE_HOUR) +#define SQL_INTERVAL_MINUTE (100 + SQL_CODE_MINUTE) +#define SQL_INTERVAL_SECOND (100 + SQL_CODE_SECOND) +#define SQL_INTERVAL_YEAR_TO_MONTH (100 + SQL_CODE_YEAR_TO_MONTH) +#define SQL_INTERVAL_DAY_TO_HOUR (100 + SQL_CODE_DAY_TO_HOUR) +#define SQL_INTERVAL_DAY_TO_MINUTE (100 + SQL_CODE_DAY_TO_MINUTE) +#define SQL_INTERVAL_DAY_TO_SECOND (100 + SQL_CODE_DAY_TO_SECOND) +#define SQL_INTERVAL_HOUR_TO_MINUTE (100 + SQL_CODE_HOUR_TO_MINUTE) +#define SQL_INTERVAL_HOUR_TO_SECOND (100 + SQL_CODE_HOUR_TO_SECOND) +#define SQL_INTERVAL_MINUTE_TO_SECOND (100 + SQL_CODE_MINUTE_TO_SECOND) + +#else +#define SQL_INTERVAL_YEAR (-80) +#define SQL_INTERVAL_MONTH (-81) +#define SQL_INTERVAL_YEAR_TO_MONTH (-82) +#define SQL_INTERVAL_DAY (-83) +#define SQL_INTERVAL_HOUR (-84) +#define SQL_INTERVAL_MINUTE (-85) +#define SQL_INTERVAL_SECOND (-86) +#define SQL_INTERVAL_DAY_TO_HOUR (-87) +#define SQL_INTERVAL_DAY_TO_MINUTE (-88) +#define SQL_INTERVAL_DAY_TO_SECOND (-89) +#define SQL_INTERVAL_HOUR_TO_MINUTE (-90) +#define SQL_INTERVAL_HOUR_TO_SECOND (-91) +#define SQL_INTERVAL_MINUTE_TO_SECOND (-92) +#endif /* ODBCVER >= 0x0300 */ + + +#if (ODBCVER <= 0x0300) +#define SQL_UNICODE (-95) +#define SQL_UNICODE_VARCHAR (-96) +#define SQL_UNICODE_LONGVARCHAR (-97) +#define SQL_UNICODE_CHAR SQL_UNICODE +#else +/* The previous definitions for SQL_UNICODE_ are historical and obsolete */ + +#define SQL_UNICODE SQL_WCHAR + +#define SQL_UNICODE_VARCHAR SQL_WVARCHAR +#define SQL_UNICODE_LONGVARCHAR SQL_WLONGVARCHAR +#define SQL_UNICODE_CHAR SQL_WCHAR +#endif + +#if (ODBCVER < 0x0300) +#define SQL_TYPE_DRIVER_START SQL_INTERVAL_YEAR +#define SQL_TYPE_DRIVER_END SQL_UNICODE_LONGVARCHAR +#endif /* ODBCVER < 0x0300 */ + +/* C datatype to SQL datatype mapping SQL types + ------------------- */ +#define SQL_C_CHAR SQL_CHAR /* CHAR, VARCHAR, DECIMAL, NUMERIC */ +#define SQL_C_LONG SQL_INTEGER /* INTEGER */ +#define SQL_C_SHORT SQL_SMALLINT /* SMALLINT */ +#define SQL_C_FLOAT SQL_REAL /* REAL */ +#define SQL_C_DOUBLE SQL_DOUBLE /* FLOAT, DOUBLE */ +#if (ODBCVER >= 0x0300) +#define SQL_C_NUMERIC SQL_NUMERIC +#endif /* ODBCVER >= 0x0300 */ +#define SQL_C_DEFAULT 99 + +#define SQL_SIGNED_OFFSET (-20) +#define SQL_UNSIGNED_OFFSET (-22) + +/* C datatype to SQL datatype mapping */ +#define SQL_C_DATE SQL_DATE +#define SQL_C_TIME SQL_TIME +#define SQL_C_TIMESTAMP SQL_TIMESTAMP +#if (ODBCVER >= 0x0300) +#define SQL_C_TYPE_DATE SQL_TYPE_DATE +#define SQL_C_TYPE_TIME SQL_TYPE_TIME +#define SQL_C_TYPE_TIMESTAMP SQL_TYPE_TIMESTAMP +#define SQL_C_INTERVAL_YEAR SQL_INTERVAL_YEAR +#define SQL_C_INTERVAL_MONTH SQL_INTERVAL_MONTH +#define SQL_C_INTERVAL_DAY SQL_INTERVAL_DAY +#define SQL_C_INTERVAL_HOUR SQL_INTERVAL_HOUR +#define SQL_C_INTERVAL_MINUTE SQL_INTERVAL_MINUTE +#define SQL_C_INTERVAL_SECOND SQL_INTERVAL_SECOND +#define SQL_C_INTERVAL_YEAR_TO_MONTH SQL_INTERVAL_YEAR_TO_MONTH +#define SQL_C_INTERVAL_DAY_TO_HOUR SQL_INTERVAL_DAY_TO_HOUR +#define SQL_C_INTERVAL_DAY_TO_MINUTE SQL_INTERVAL_DAY_TO_MINUTE +#define SQL_C_INTERVAL_DAY_TO_SECOND SQL_INTERVAL_DAY_TO_SECOND +#define SQL_C_INTERVAL_HOUR_TO_MINUTE SQL_INTERVAL_HOUR_TO_MINUTE +#define SQL_C_INTERVAL_HOUR_TO_SECOND SQL_INTERVAL_HOUR_TO_SECOND +#define SQL_C_INTERVAL_MINUTE_TO_SECOND SQL_INTERVAL_MINUTE_TO_SECOND +#endif /* ODBCVER >= 0x0300 */ +#define SQL_C_BINARY SQL_BINARY +#define SQL_C_BIT SQL_BIT +#if (ODBCVER >= 0x0300) +#define SQL_C_SBIGINT (SQL_BIGINT+SQL_SIGNED_OFFSET) /* SIGNED BIGINT */ +#define SQL_C_UBIGINT (SQL_BIGINT+SQL_UNSIGNED_OFFSET) /* UNSIGNED BIGINT */ +#endif /* ODBCVER >= 0x0300 */ +#define SQL_C_TINYINT SQL_TINYINT +#define SQL_C_SLONG (SQL_C_LONG+SQL_SIGNED_OFFSET) /* SIGNED INTEGER */ +#define SQL_C_SSHORT (SQL_C_SHORT+SQL_SIGNED_OFFSET) /* SIGNED SMALLINT */ +#define SQL_C_STINYINT (SQL_TINYINT+SQL_SIGNED_OFFSET) /* SIGNED TINYINT */ +#define SQL_C_ULONG (SQL_C_LONG+SQL_UNSIGNED_OFFSET) /* UNSIGNED INTEGER*/ +#define SQL_C_USHORT (SQL_C_SHORT+SQL_UNSIGNED_OFFSET) /* UNSIGNED SMALLINT*/ +#define SQL_C_UTINYINT (SQL_TINYINT+SQL_UNSIGNED_OFFSET) /* UNSIGNED TINYINT*/ + +#ifdef _WIN64 +#define SQL_C_BOOKMARK SQL_C_UBIGINT /* BOOKMARK */ +#else +#define SQL_C_BOOKMARK SQL_C_ULONG /* BOOKMARK */ +#endif + +#if (ODBCVER >= 0x0350) +#define SQL_C_GUID SQL_GUID +#endif /* ODBCVER >= 0x0350 */ + +#define SQL_TYPE_NULL 0 +#if (ODBCVER < 0x0300) +#define SQL_TYPE_MIN SQL_BIT +#define SQL_TYPE_MAX SQL_VARCHAR +#endif + +#if (ODBCVER >= 0x0300) +#define SQL_C_VARBOOKMARK SQL_C_BINARY +#endif /* ODBCVER >= 0x0300 */ + +/* define for SQL_DIAG_ROW_NUMBER and SQL_DIAG_COLUMN_NUMBER */ +#if (ODBCVER >= 0x0300) +#define SQL_NO_ROW_NUMBER (-1) +#define SQL_NO_COLUMN_NUMBER (-1) +#define SQL_ROW_NUMBER_UNKNOWN (-2) +#define SQL_COLUMN_NUMBER_UNKNOWN (-2) +#endif + +/* SQLBindParameter extensions */ +#define SQL_DEFAULT_PARAM (-5) +#define SQL_IGNORE (-6) +#if (ODBCVER >= 0x0300) +#define SQL_COLUMN_IGNORE SQL_IGNORE +#endif /* ODBCVER >= 0x0300 */ +#define SQL_LEN_DATA_AT_EXEC_OFFSET (-100) +#define SQL_LEN_DATA_AT_EXEC(length) (-(length)+SQL_LEN_DATA_AT_EXEC_OFFSET) + +/* binary length for driver specific attributes */ +#define SQL_LEN_BINARY_ATTR_OFFSET (-100) +#define SQL_LEN_BINARY_ATTR(length) (-(length)+SQL_LEN_BINARY_ATTR_OFFSET) + +/* Defines used by Driver Manager when mapping SQLSetParam to SQLBindParameter +*/ +#define SQL_PARAM_TYPE_DEFAULT SQL_PARAM_INPUT_OUTPUT +#define SQL_SETPARAM_VALUE_MAX (-1L) + +/* SQLColAttributes defines */ +#define SQL_COLUMN_COUNT 0 +#define SQL_COLUMN_NAME 1 +#define SQL_COLUMN_TYPE 2 +#define SQL_COLUMN_LENGTH 3 +#define SQL_COLUMN_PRECISION 4 +#define SQL_COLUMN_SCALE 5 +#define SQL_COLUMN_DISPLAY_SIZE 6 +#define SQL_COLUMN_NULLABLE 7 +#define SQL_COLUMN_UNSIGNED 8 +#define SQL_COLUMN_MONEY 9 +#define SQL_COLUMN_UPDATABLE 10 +#define SQL_COLUMN_AUTO_INCREMENT 11 +#define SQL_COLUMN_CASE_SENSITIVE 12 +#define SQL_COLUMN_SEARCHABLE 13 +#define SQL_COLUMN_TYPE_NAME 14 +#define SQL_COLUMN_TABLE_NAME 15 +#define SQL_COLUMN_OWNER_NAME 16 +#define SQL_COLUMN_QUALIFIER_NAME 17 +#define SQL_COLUMN_LABEL 18 +#define SQL_COLATT_OPT_MAX SQL_COLUMN_LABEL +#if (ODBCVER < 0x0300) +#define SQL_COLUMN_DRIVER_START 1000 +#endif /* ODBCVER < 0x0300 */ + +#define SQL_COLATT_OPT_MIN SQL_COLUMN_COUNT + +/* SQLColAttributes subdefines for SQL_COLUMN_UPDATABLE */ +#define SQL_ATTR_READONLY 0 +#define SQL_ATTR_WRITE 1 +#define SQL_ATTR_READWRITE_UNKNOWN 2 + +/* SQLColAttributes subdefines for SQL_COLUMN_SEARCHABLE */ +/* These are also used by SQLGetInfo */ +#define SQL_UNSEARCHABLE 0 +#define SQL_LIKE_ONLY 1 +#define SQL_ALL_EXCEPT_LIKE 2 +#define SQL_SEARCHABLE 3 +#define SQL_PRED_SEARCHABLE SQL_SEARCHABLE + + +/* Special return values for SQLGetData */ +#define SQL_NO_TOTAL (-4) + +/********************************************/ +/* SQLGetFunctions: additional values for */ +/* fFunction to represent functions that */ +/* are not in the X/Open spec. */ +/********************************************/ + +#if (ODBCVER >= 0x0300) +#define SQL_API_SQLALLOCHANDLESTD 73 +#define SQL_API_SQLBULKOPERATIONS 24 +#endif /* ODBCVER >= 0x0300 */ +#define SQL_API_SQLBINDPARAMETER 72 +#define SQL_API_SQLBROWSECONNECT 55 +#define SQL_API_SQLCOLATTRIBUTES 6 +#define SQL_API_SQLCOLUMNPRIVILEGES 56 +#define SQL_API_SQLDESCRIBEPARAM 58 +#define SQL_API_SQLDRIVERCONNECT 41 +#define SQL_API_SQLDRIVERS 71 +#define SQL_API_SQLEXTENDEDFETCH 59 +#define SQL_API_SQLFOREIGNKEYS 60 +#define SQL_API_SQLMORERESULTS 61 +#define SQL_API_SQLNATIVESQL 62 +#define SQL_API_SQLNUMPARAMS 63 +#define SQL_API_SQLPARAMOPTIONS 64 +#define SQL_API_SQLPRIMARYKEYS 65 +#define SQL_API_SQLPROCEDURECOLUMNS 66 +#define SQL_API_SQLPROCEDURES 67 +#define SQL_API_SQLSETPOS 68 +#define SQL_API_SQLSETSCROLLOPTIONS 69 +#define SQL_API_SQLTABLEPRIVILEGES 70 + +/*-------------------------------------------*/ +/* SQL_EXT_API_LAST is not useful with ODBC */ +/* version 3.0 because some of the values */ +/* from X/Open are in the 10000 range. */ +/*-------------------------------------------*/ + +#if (ODBCVER < 0x0300) +#define SQL_EXT_API_LAST SQL_API_SQLBINDPARAMETER +#define SQL_NUM_FUNCTIONS 23 +#define SQL_EXT_API_START 40 +#define SQL_NUM_EXTENSIONS (SQL_EXT_API_LAST-SQL_EXT_API_START+1) +#endif + +/*--------------------------------------------*/ +/* SQL_API_ALL_FUNCTIONS returns an array */ +/* of 'booleans' representing whether a */ +/* function is implemented by the driver. */ +/* */ +/* CAUTION: Only functions defined in ODBC */ +/* version 2.0 and earlier are returned, the */ +/* new high-range function numbers defined by */ +/* X/Open break this scheme. See the new */ +/* method -- SQL_API_ODBC3_ALL_FUNCTIONS */ +/*--------------------------------------------*/ + +#define SQL_API_ALL_FUNCTIONS 0 /* See CAUTION above */ + +/*----------------------------------------------*/ +/* 2.X drivers export a dummy function with */ +/* ordinal number SQL_API_LOADBYORDINAL to speed*/ +/* loading under the windows operating system. */ +/* */ +/* CAUTION: Loading by ordinal is not supported */ +/* for 3.0 and above drivers. */ +/*----------------------------------------------*/ + +#define SQL_API_LOADBYORDINAL 199 /* See CAUTION above */ + +/*----------------------------------------------*/ +/* SQL_API_ODBC3_ALL_FUNCTIONS */ +/* This returns a bitmap, which allows us to */ +/* handle the higher-valued function numbers. */ +/* Use SQL_FUNC_EXISTS(bitmap,function_number) */ +/* to determine if the function exists. */ +/*----------------------------------------------*/ + + +#if (ODBCVER >= 0x0300) +#define SQL_API_ODBC3_ALL_FUNCTIONS 999 +#define SQL_API_ODBC3_ALL_FUNCTIONS_SIZE 250 /* array of 250 words */ + +#define SQL_FUNC_EXISTS(pfExists, uwAPI) \ + ((*(((UWORD*) (pfExists)) + ((uwAPI) >> 4)) \ + & (1 << ((uwAPI) & 0x000F)) \ + ) ? SQL_TRUE : SQL_FALSE \ + ) +#endif /* ODBCVER >= 0x0300 */ + + +/************************************************/ +/* Extended definitions for SQLGetInfo */ +/************************************************/ + +/*---------------------------------*/ +/* Values in ODBC 2.0 that are not */ +/* in the X/Open spec */ +/*---------------------------------*/ + +#define SQL_INFO_FIRST 0 +#define SQL_ACTIVE_CONNECTIONS 0 /* MAX_DRIVER_CONNECTIONS */ +#define SQL_ACTIVE_STATEMENTS 1 /* MAX_CONCURRENT_ACTIVITIES */ +#define SQL_DRIVER_HDBC 3 +#define SQL_DRIVER_HENV 4 +#define SQL_DRIVER_HSTMT 5 +#define SQL_DRIVER_NAME 6 +#define SQL_DRIVER_VER 7 +#define SQL_ODBC_API_CONFORMANCE 9 +#define SQL_ODBC_VER 10 +#define SQL_ROW_UPDATES 11 +#define SQL_ODBC_SAG_CLI_CONFORMANCE 12 +#define SQL_ODBC_SQL_CONFORMANCE 15 +#define SQL_PROCEDURES 21 +#define SQL_CONCAT_NULL_BEHAVIOR 22 +#define SQL_CURSOR_ROLLBACK_BEHAVIOR 24 +#define SQL_EXPRESSIONS_IN_ORDERBY 27 +#define SQL_MAX_OWNER_NAME_LEN 32 /* MAX_SCHEMA_NAME_LEN */ +#define SQL_MAX_PROCEDURE_NAME_LEN 33 +#define SQL_MAX_QUALIFIER_NAME_LEN 34 /* MAX_CATALOG_NAME_LEN */ +#define SQL_MULT_RESULT_SETS 36 +#define SQL_MULTIPLE_ACTIVE_TXN 37 +#define SQL_OUTER_JOINS 38 +#define SQL_OWNER_TERM 39 +#define SQL_PROCEDURE_TERM 40 +#define SQL_QUALIFIER_NAME_SEPARATOR 41 +#define SQL_QUALIFIER_TERM 42 +#define SQL_SCROLL_OPTIONS 44 +#define SQL_TABLE_TERM 45 +#define SQL_CONVERT_FUNCTIONS 48 +#define SQL_NUMERIC_FUNCTIONS 49 +#define SQL_STRING_FUNCTIONS 50 +#define SQL_SYSTEM_FUNCTIONS 51 +#define SQL_TIMEDATE_FUNCTIONS 52 +#define SQL_CONVERT_BIGINT 53 +#define SQL_CONVERT_BINARY 54 +#define SQL_CONVERT_BIT 55 +#define SQL_CONVERT_CHAR 56 +#define SQL_CONVERT_DATE 57 +#define SQL_CONVERT_DECIMAL 58 +#define SQL_CONVERT_DOUBLE 59 +#define SQL_CONVERT_FLOAT 60 +#define SQL_CONVERT_INTEGER 61 +#define SQL_CONVERT_LONGVARCHAR 62 +#define SQL_CONVERT_NUMERIC 63 +#define SQL_CONVERT_REAL 64 +#define SQL_CONVERT_SMALLINT 65 +#define SQL_CONVERT_TIME 66 +#define SQL_CONVERT_TIMESTAMP 67 +#define SQL_CONVERT_TINYINT 68 +#define SQL_CONVERT_VARBINARY 69 +#define SQL_CONVERT_VARCHAR 70 +#define SQL_CONVERT_LONGVARBINARY 71 +#define SQL_ODBC_SQL_OPT_IEF 73 /* SQL_INTEGRITY */ +#define SQL_CORRELATION_NAME 74 +#define SQL_NON_NULLABLE_COLUMNS 75 +#define SQL_DRIVER_HLIB 76 +#define SQL_DRIVER_ODBC_VER 77 +#define SQL_LOCK_TYPES 78 +#define SQL_POS_OPERATIONS 79 +#define SQL_POSITIONED_STATEMENTS 80 +#define SQL_BOOKMARK_PERSISTENCE 82 +#define SQL_STATIC_SENSITIVITY 83 +#define SQL_FILE_USAGE 84 +#define SQL_COLUMN_ALIAS 87 +#define SQL_GROUP_BY 88 +#define SQL_KEYWORDS 89 +#define SQL_OWNER_USAGE 91 +#define SQL_QUALIFIER_USAGE 92 +#define SQL_QUOTED_IDENTIFIER_CASE 93 +#define SQL_SUBQUERIES 95 +#define SQL_UNION 96 +#define SQL_MAX_ROW_SIZE_INCLUDES_LONG 103 +#define SQL_MAX_CHAR_LITERAL_LEN 108 +#define SQL_TIMEDATE_ADD_INTERVALS 109 +#define SQL_TIMEDATE_DIFF_INTERVALS 110 +#define SQL_NEED_LONG_DATA_LEN 111 +#define SQL_MAX_BINARY_LITERAL_LEN 112 +#define SQL_LIKE_ESCAPE_CLAUSE 113 +#define SQL_QUALIFIER_LOCATION 114 + +#if (ODBCVER >= 0x0201 && ODBCVER < 0x0300) +#define SQL_OJ_CAPABILITIES 65003 /* Temp value until ODBC 3.0 */ +#endif /* ODBCVER >= 0x0201 && ODBCVER < 0x0300 */ + +/*----------------------------------------------*/ +/* SQL_INFO_LAST and SQL_INFO_DRIVER_START are */ +/* not useful anymore, because X/Open has */ +/* values in the 10000 range. You */ +/* must contact X/Open directly to get a range */ +/* of numbers for driver-specific values. */ +/*----------------------------------------------*/ + +#if (ODBCVER < 0x0300) +#define SQL_INFO_LAST SQL_QUALIFIER_LOCATION +#define SQL_INFO_DRIVER_START 1000 +#endif /* ODBCVER < 0x0300 */ + +/*-----------------------------------------------*/ +/* ODBC 3.0 SQLGetInfo values that are not part */ +/* of the X/Open standard at this time. X/Open */ +/* standard values are in sql.h. */ +/*-----------------------------------------------*/ + +#if (ODBCVER >= 0x0300) +#define SQL_ACTIVE_ENVIRONMENTS 116 +#define SQL_ALTER_DOMAIN 117 + +#define SQL_SQL_CONFORMANCE 118 +#define SQL_DATETIME_LITERALS 119 + +#define SQL_ASYNC_MODE 10021 /* new X/Open spec */ +#define SQL_BATCH_ROW_COUNT 120 +#define SQL_BATCH_SUPPORT 121 +#define SQL_CATALOG_LOCATION SQL_QUALIFIER_LOCATION +#define SQL_CATALOG_NAME_SEPARATOR SQL_QUALIFIER_NAME_SEPARATOR +#define SQL_CATALOG_TERM SQL_QUALIFIER_TERM +#define SQL_CATALOG_USAGE SQL_QUALIFIER_USAGE +#define SQL_CONVERT_WCHAR 122 +#define SQL_CONVERT_INTERVAL_DAY_TIME 123 +#define SQL_CONVERT_INTERVAL_YEAR_MONTH 124 +#define SQL_CONVERT_WLONGVARCHAR 125 +#define SQL_CONVERT_WVARCHAR 126 +#define SQL_CREATE_ASSERTION 127 +#define SQL_CREATE_CHARACTER_SET 128 +#define SQL_CREATE_COLLATION 129 +#define SQL_CREATE_DOMAIN 130 +#define SQL_CREATE_SCHEMA 131 +#define SQL_CREATE_TABLE 132 +#define SQL_CREATE_TRANSLATION 133 +#define SQL_CREATE_VIEW 134 +#define SQL_DRIVER_HDESC 135 +#define SQL_DROP_ASSERTION 136 +#define SQL_DROP_CHARACTER_SET 137 +#define SQL_DROP_COLLATION 138 +#define SQL_DROP_DOMAIN 139 +#define SQL_DROP_SCHEMA 140 +#define SQL_DROP_TABLE 141 +#define SQL_DROP_TRANSLATION 142 +#define SQL_DROP_VIEW 143 +#define SQL_DYNAMIC_CURSOR_ATTRIBUTES1 144 +#define SQL_DYNAMIC_CURSOR_ATTRIBUTES2 145 +#define SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1 146 +#define SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2 147 +#define SQL_INDEX_KEYWORDS 148 +#define SQL_INFO_SCHEMA_VIEWS 149 +#define SQL_KEYSET_CURSOR_ATTRIBUTES1 150 +#define SQL_KEYSET_CURSOR_ATTRIBUTES2 151 +#define SQL_MAX_ASYNC_CONCURRENT_STATEMENTS 10022 /* new X/Open spec */ +#define SQL_ODBC_INTERFACE_CONFORMANCE 152 +#define SQL_PARAM_ARRAY_ROW_COUNTS 153 +#define SQL_PARAM_ARRAY_SELECTS 154 +#define SQL_SCHEMA_TERM SQL_OWNER_TERM +#define SQL_SCHEMA_USAGE SQL_OWNER_USAGE +#define SQL_SQL92_DATETIME_FUNCTIONS 155 +#define SQL_SQL92_FOREIGN_KEY_DELETE_RULE 156 +#define SQL_SQL92_FOREIGN_KEY_UPDATE_RULE 157 +#define SQL_SQL92_GRANT 158 +#define SQL_SQL92_NUMERIC_VALUE_FUNCTIONS 159 +#define SQL_SQL92_PREDICATES 160 +#define SQL_SQL92_RELATIONAL_JOIN_OPERATORS 161 +#define SQL_SQL92_REVOKE 162 +#define SQL_SQL92_ROW_VALUE_CONSTRUCTOR 163 +#define SQL_SQL92_STRING_FUNCTIONS 164 +#define SQL_SQL92_VALUE_EXPRESSIONS 165 +#define SQL_STANDARD_CLI_CONFORMANCE 166 +#define SQL_STATIC_CURSOR_ATTRIBUTES1 167 +#define SQL_STATIC_CURSOR_ATTRIBUTES2 168 + +#define SQL_AGGREGATE_FUNCTIONS 169 +#define SQL_DDL_INDEX 170 +#define SQL_DM_VER 171 +#define SQL_INSERT_STATEMENT 172 +#define SQL_CONVERT_GUID 173 +#define SQL_UNION_STATEMENT SQL_UNION +#endif /* ODBCVER >= 0x0300 */ + +#define SQL_DTC_TRANSITION_COST 1750 + +/* SQL_ALTER_TABLE bitmasks */ +#if (ODBCVER >= 0x0300) +/* the following 5 bitmasks are defined in sql.h +*#define SQL_AT_ADD_COLUMN 0x00000001L +*#define SQL_AT_DROP_COLUMN 0x00000002L +*#define SQL_AT_ADD_CONSTRAINT 0x00000008L +*/ +#define SQL_AT_ADD_COLUMN_SINGLE 0x00000020L +#define SQL_AT_ADD_COLUMN_DEFAULT 0x00000040L +#define SQL_AT_ADD_COLUMN_COLLATION 0x00000080L +#define SQL_AT_SET_COLUMN_DEFAULT 0x00000100L +#define SQL_AT_DROP_COLUMN_DEFAULT 0x00000200L +#define SQL_AT_DROP_COLUMN_CASCADE 0x00000400L +#define SQL_AT_DROP_COLUMN_RESTRICT 0x00000800L +#define SQL_AT_ADD_TABLE_CONSTRAINT 0x00001000L +#define SQL_AT_DROP_TABLE_CONSTRAINT_CASCADE 0x00002000L +#define SQL_AT_DROP_TABLE_CONSTRAINT_RESTRICT 0x00004000L +#define SQL_AT_CONSTRAINT_NAME_DEFINITION 0x00008000L +#define SQL_AT_CONSTRAINT_INITIALLY_DEFERRED 0x00010000L +#define SQL_AT_CONSTRAINT_INITIALLY_IMMEDIATE 0x00020000L +#define SQL_AT_CONSTRAINT_DEFERRABLE 0x00040000L +#define SQL_AT_CONSTRAINT_NON_DEFERRABLE 0x00080000L +#endif /* ODBCVER >= 0x0300 */ + +/* SQL_CONVERT_* return value bitmasks */ + +#define SQL_CVT_CHAR 0x00000001L +#define SQL_CVT_NUMERIC 0x00000002L +#define SQL_CVT_DECIMAL 0x00000004L +#define SQL_CVT_INTEGER 0x00000008L +#define SQL_CVT_SMALLINT 0x00000010L +#define SQL_CVT_FLOAT 0x00000020L +#define SQL_CVT_REAL 0x00000040L +#define SQL_CVT_DOUBLE 0x00000080L +#define SQL_CVT_VARCHAR 0x00000100L +#define SQL_CVT_LONGVARCHAR 0x00000200L +#define SQL_CVT_BINARY 0x00000400L +#define SQL_CVT_VARBINARY 0x00000800L +#define SQL_CVT_BIT 0x00001000L +#define SQL_CVT_TINYINT 0x00002000L +#define SQL_CVT_BIGINT 0x00004000L +#define SQL_CVT_DATE 0x00008000L +#define SQL_CVT_TIME 0x00010000L +#define SQL_CVT_TIMESTAMP 0x00020000L +#define SQL_CVT_LONGVARBINARY 0x00040000L +#if (ODBCVER >= 0x0300) +#define SQL_CVT_INTERVAL_YEAR_MONTH 0x00080000L +#define SQL_CVT_INTERVAL_DAY_TIME 0x00100000L +#define SQL_CVT_WCHAR 0x00200000L +#define SQL_CVT_WLONGVARCHAR 0x00400000L +#define SQL_CVT_WVARCHAR 0x00800000L +#define SQL_CVT_GUID 0x01000000L + +#endif /* ODBCVER >= 0x0300 */ + + +/* SQL_CONVERT_FUNCTIONS functions */ +#define SQL_FN_CVT_CONVERT 0x00000001L +#if (ODBCVER >= 0x0300) +#define SQL_FN_CVT_CAST 0x00000002L +#endif /* ODBCVER >= 0x0300 */ + + +/* SQL_STRING_FUNCTIONS functions */ + +#define SQL_FN_STR_CONCAT 0x00000001L +#define SQL_FN_STR_INSERT 0x00000002L +#define SQL_FN_STR_LEFT 0x00000004L +#define SQL_FN_STR_LTRIM 0x00000008L +#define SQL_FN_STR_LENGTH 0x00000010L +#define SQL_FN_STR_LOCATE 0x00000020L +#define SQL_FN_STR_LCASE 0x00000040L +#define SQL_FN_STR_REPEAT 0x00000080L +#define SQL_FN_STR_REPLACE 0x00000100L +#define SQL_FN_STR_RIGHT 0x00000200L +#define SQL_FN_STR_RTRIM 0x00000400L +#define SQL_FN_STR_SUBSTRING 0x00000800L +#define SQL_FN_STR_UCASE 0x00001000L +#define SQL_FN_STR_ASCII 0x00002000L +#define SQL_FN_STR_CHAR 0x00004000L +#define SQL_FN_STR_DIFFERENCE 0x00008000L +#define SQL_FN_STR_LOCATE_2 0x00010000L +#define SQL_FN_STR_SOUNDEX 0x00020000L +#define SQL_FN_STR_SPACE 0x00040000L +#if (ODBCVER >= 0x0300) +#define SQL_FN_STR_BIT_LENGTH 0x00080000L +#define SQL_FN_STR_CHAR_LENGTH 0x00100000L +#define SQL_FN_STR_CHARACTER_LENGTH 0x00200000L +#define SQL_FN_STR_OCTET_LENGTH 0x00400000L +#define SQL_FN_STR_POSITION 0x00800000L +#endif /* ODBCVER >= 0x0300 */ + +/* SQL_SQL92_STRING_FUNCTIONS */ +#if (ODBCVER >= 0x0300) +#define SQL_SSF_CONVERT 0x00000001L +#define SQL_SSF_LOWER 0x00000002L +#define SQL_SSF_UPPER 0x00000004L +#define SQL_SSF_SUBSTRING 0x00000008L +#define SQL_SSF_TRANSLATE 0x00000010L +#define SQL_SSF_TRIM_BOTH 0x00000020L +#define SQL_SSF_TRIM_LEADING 0x00000040L +#define SQL_SSF_TRIM_TRAILING 0x00000080L +#endif /* ODBCVER >= 0x0300 */ + +/* SQL_NUMERIC_FUNCTIONS functions */ + +#define SQL_FN_NUM_ABS 0x00000001L +#define SQL_FN_NUM_ACOS 0x00000002L +#define SQL_FN_NUM_ASIN 0x00000004L +#define SQL_FN_NUM_ATAN 0x00000008L +#define SQL_FN_NUM_ATAN2 0x00000010L +#define SQL_FN_NUM_CEILING 0x00000020L +#define SQL_FN_NUM_COS 0x00000040L +#define SQL_FN_NUM_COT 0x00000080L +#define SQL_FN_NUM_EXP 0x00000100L +#define SQL_FN_NUM_FLOOR 0x00000200L +#define SQL_FN_NUM_LOG 0x00000400L +#define SQL_FN_NUM_MOD 0x00000800L +#define SQL_FN_NUM_SIGN 0x00001000L +#define SQL_FN_NUM_SIN 0x00002000L +#define SQL_FN_NUM_SQRT 0x00004000L +#define SQL_FN_NUM_TAN 0x00008000L +#define SQL_FN_NUM_PI 0x00010000L +#define SQL_FN_NUM_RAND 0x00020000L +#define SQL_FN_NUM_DEGREES 0x00040000L +#define SQL_FN_NUM_LOG10 0x00080000L +#define SQL_FN_NUM_POWER 0x00100000L +#define SQL_FN_NUM_RADIANS 0x00200000L +#define SQL_FN_NUM_ROUND 0x00400000L +#define SQL_FN_NUM_TRUNCATE 0x00800000L + +/* SQL_SQL92_NUMERIC_VALUE_FUNCTIONS */ +#if (ODBCVER >= 0x0300) +#define SQL_SNVF_BIT_LENGTH 0x00000001L +#define SQL_SNVF_CHAR_LENGTH 0x00000002L +#define SQL_SNVF_CHARACTER_LENGTH 0x00000004L +#define SQL_SNVF_EXTRACT 0x00000008L +#define SQL_SNVF_OCTET_LENGTH 0x00000010L +#define SQL_SNVF_POSITION 0x00000020L +#endif /* ODBCVER >= 0x0300 */ + +/* SQL_TIMEDATE_FUNCTIONS functions */ + +#define SQL_FN_TD_NOW 0x00000001L +#define SQL_FN_TD_CURDATE 0x00000002L +#define SQL_FN_TD_DAYOFMONTH 0x00000004L +#define SQL_FN_TD_DAYOFWEEK 0x00000008L +#define SQL_FN_TD_DAYOFYEAR 0x00000010L +#define SQL_FN_TD_MONTH 0x00000020L +#define SQL_FN_TD_QUARTER 0x00000040L +#define SQL_FN_TD_WEEK 0x00000080L +#define SQL_FN_TD_YEAR 0x00000100L +#define SQL_FN_TD_CURTIME 0x00000200L +#define SQL_FN_TD_HOUR 0x00000400L +#define SQL_FN_TD_MINUTE 0x00000800L +#define SQL_FN_TD_SECOND 0x00001000L +#define SQL_FN_TD_TIMESTAMPADD 0x00002000L +#define SQL_FN_TD_TIMESTAMPDIFF 0x00004000L +#define SQL_FN_TD_DAYNAME 0x00008000L +#define SQL_FN_TD_MONTHNAME 0x00010000L +#if (ODBCVER >= 0x0300) +#define SQL_FN_TD_CURRENT_DATE 0x00020000L +#define SQL_FN_TD_CURRENT_TIME 0x00040000L +#define SQL_FN_TD_CURRENT_TIMESTAMP 0x00080000L +#define SQL_FN_TD_EXTRACT 0x00100000L +#endif /* ODBCVER >= 0x0300 */ + +/* SQL_SQL92_DATETIME_FUNCTIONS */ +#if (ODBCVER >= 0x0300) +#define SQL_SDF_CURRENT_DATE 0x00000001L +#define SQL_SDF_CURRENT_TIME 0x00000002L +#define SQL_SDF_CURRENT_TIMESTAMP 0x00000004L +#endif /* ODBCVER >= 0x0300 */ + +/* SQL_SYSTEM_FUNCTIONS functions */ + +#define SQL_FN_SYS_USERNAME 0x00000001L +#define SQL_FN_SYS_DBNAME 0x00000002L +#define SQL_FN_SYS_IFNULL 0x00000004L + +/* SQL_TIMEDATE_ADD_INTERVALS and SQL_TIMEDATE_DIFF_INTERVALS functions */ + +#define SQL_FN_TSI_FRAC_SECOND 0x00000001L +#define SQL_FN_TSI_SECOND 0x00000002L +#define SQL_FN_TSI_MINUTE 0x00000004L +#define SQL_FN_TSI_HOUR 0x00000008L +#define SQL_FN_TSI_DAY 0x00000010L +#define SQL_FN_TSI_WEEK 0x00000020L +#define SQL_FN_TSI_MONTH 0x00000040L +#define SQL_FN_TSI_QUARTER 0x00000080L +#define SQL_FN_TSI_YEAR 0x00000100L + +/* bitmasks for SQL_DYNAMIC_CURSOR_ATTRIBUTES1, + * SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1, + * SQL_KEYSET_CURSOR_ATTRIBUTES1, and SQL_STATIC_CURSOR_ATTRIBUTES1 + */ +#if (ODBCVER >= 0x0300) +/* supported SQLFetchScroll FetchOrientation's */ +#define SQL_CA1_NEXT 0x00000001L +#define SQL_CA1_ABSOLUTE 0x00000002L +#define SQL_CA1_RELATIVE 0x00000004L +#define SQL_CA1_BOOKMARK 0x00000008L + +/* supported SQLSetPos LockType's */ +#define SQL_CA1_LOCK_NO_CHANGE 0x00000040L +#define SQL_CA1_LOCK_EXCLUSIVE 0x00000080L +#define SQL_CA1_LOCK_UNLOCK 0x00000100L + +/* supported SQLSetPos Operations */ +#define SQL_CA1_POS_POSITION 0x00000200L +#define SQL_CA1_POS_UPDATE 0x00000400L +#define SQL_CA1_POS_DELETE 0x00000800L +#define SQL_CA1_POS_REFRESH 0x00001000L + +/* positioned updates and deletes */ +#define SQL_CA1_POSITIONED_UPDATE 0x00002000L +#define SQL_CA1_POSITIONED_DELETE 0x00004000L +#define SQL_CA1_SELECT_FOR_UPDATE 0x00008000L + +/* supported SQLBulkOperations operations */ +#define SQL_CA1_BULK_ADD 0x00010000L +#define SQL_CA1_BULK_UPDATE_BY_BOOKMARK 0x00020000L +#define SQL_CA1_BULK_DELETE_BY_BOOKMARK 0x00040000L +#define SQL_CA1_BULK_FETCH_BY_BOOKMARK 0x00080000L +#endif /* ODBCVER >= 0x0300 */ + +/* bitmasks for SQL_DYNAMIC_CURSOR_ATTRIBUTES2, + * SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2, + * SQL_KEYSET_CURSOR_ATTRIBUTES2, and SQL_STATIC_CURSOR_ATTRIBUTES2 + */ +#if (ODBCVER >= 0x0300) +/* supported values for SQL_ATTR_SCROLL_CONCURRENCY */ +#define SQL_CA2_READ_ONLY_CONCURRENCY 0x00000001L +#define SQL_CA2_LOCK_CONCURRENCY 0x00000002L +#define SQL_CA2_OPT_ROWVER_CONCURRENCY 0x00000004L +#define SQL_CA2_OPT_VALUES_CONCURRENCY 0x00000008L + +/* sensitivity of the cursor to its own inserts, deletes, and updates */ +#define SQL_CA2_SENSITIVITY_ADDITIONS 0x00000010L +#define SQL_CA2_SENSITIVITY_DELETIONS 0x00000020L +#define SQL_CA2_SENSITIVITY_UPDATES 0x00000040L + +/* semantics of SQL_ATTR_MAX_ROWS */ +#define SQL_CA2_MAX_ROWS_SELECT 0x00000080L +#define SQL_CA2_MAX_ROWS_INSERT 0x00000100L +#define SQL_CA2_MAX_ROWS_DELETE 0x00000200L +#define SQL_CA2_MAX_ROWS_UPDATE 0x00000400L +#define SQL_CA2_MAX_ROWS_CATALOG 0x00000800L +#define SQL_CA2_MAX_ROWS_AFFECTS_ALL (SQL_CA2_MAX_ROWS_SELECT | \ + SQL_CA2_MAX_ROWS_INSERT | SQL_CA2_MAX_ROWS_DELETE | \ + SQL_CA2_MAX_ROWS_UPDATE | SQL_CA2_MAX_ROWS_CATALOG) + +/* semantics of SQL_DIAG_CURSOR_ROW_COUNT */ +#define SQL_CA2_CRC_EXACT 0x00001000L +#define SQL_CA2_CRC_APPROXIMATE 0x00002000L + +/* the kinds of positioned statements that can be simulated */ +#define SQL_CA2_SIMULATE_NON_UNIQUE 0x00004000L +#define SQL_CA2_SIMULATE_TRY_UNIQUE 0x00008000L +#define SQL_CA2_SIMULATE_UNIQUE 0x00010000L +#endif /* ODBCVER >= 0x0300 */ + +/* SQL_ODBC_API_CONFORMANCE values */ + +#define SQL_OAC_NONE 0x0000 +#define SQL_OAC_LEVEL1 0x0001 +#define SQL_OAC_LEVEL2 0x0002 + +/* SQL_ODBC_SAG_CLI_CONFORMANCE values */ + +#define SQL_OSCC_NOT_COMPLIANT 0x0000 +#define SQL_OSCC_COMPLIANT 0x0001 + +/* SQL_ODBC_SQL_CONFORMANCE values */ + +#define SQL_OSC_MINIMUM 0x0000 +#define SQL_OSC_CORE 0x0001 +#define SQL_OSC_EXTENDED 0x0002 + + +/* SQL_CONCAT_NULL_BEHAVIOR values */ + +#define SQL_CB_NULL 0x0000 +#define SQL_CB_NON_NULL 0x0001 + +/* SQL_SCROLL_OPTIONS masks */ + +#define SQL_SO_FORWARD_ONLY 0x00000001L +#define SQL_SO_KEYSET_DRIVEN 0x00000002L +#define SQL_SO_DYNAMIC 0x00000004L +#define SQL_SO_MIXED 0x00000008L +#define SQL_SO_STATIC 0x00000010L + +/* SQL_FETCH_DIRECTION masks */ + +/* SQL_FETCH_RESUME is no longer supported +#define SQL_FD_FETCH_RESUME 0x00000040L +*/ +#define SQL_FD_FETCH_BOOKMARK 0x00000080L + +/* SQL_TXN_ISOLATION_OPTION masks */ +/* SQL_TXN_VERSIONING is no longer supported +#define SQL_TXN_VERSIONING 0x00000010L +*/ + +/* SQL_CORRELATION_NAME values */ + +#define SQL_CN_NONE 0x0000 +#define SQL_CN_DIFFERENT 0x0001 +#define SQL_CN_ANY 0x0002 + +/* SQL_NON_NULLABLE_COLUMNS values */ + +#define SQL_NNC_NULL 0x0000 +#define SQL_NNC_NON_NULL 0x0001 + +/* SQL_NULL_COLLATION values */ + +#define SQL_NC_START 0x0002 +#define SQL_NC_END 0x0004 + +/* SQL_FILE_USAGE values */ + +#define SQL_FILE_NOT_SUPPORTED 0x0000 +#define SQL_FILE_TABLE 0x0001 +#define SQL_FILE_QUALIFIER 0x0002 +#define SQL_FILE_CATALOG SQL_FILE_QUALIFIER // ODBC 3.0 + + +/* SQL_GETDATA_EXTENSIONS values */ + +#define SQL_GD_BLOCK 0x00000004L +#define SQL_GD_BOUND 0x00000008L + +/* SQL_POSITIONED_STATEMENTS masks */ + +#define SQL_PS_POSITIONED_DELETE 0x00000001L +#define SQL_PS_POSITIONED_UPDATE 0x00000002L +#define SQL_PS_SELECT_FOR_UPDATE 0x00000004L + +/* SQL_GROUP_BY values */ + +#define SQL_GB_NOT_SUPPORTED 0x0000 +#define SQL_GB_GROUP_BY_EQUALS_SELECT 0x0001 +#define SQL_GB_GROUP_BY_CONTAINS_SELECT 0x0002 +#define SQL_GB_NO_RELATION 0x0003 +#if (ODBCVER >= 0x0300) +#define SQL_GB_COLLATE 0x0004 + +#endif /* ODBCVER >= 0x0300 */ + +/* SQL_OWNER_USAGE masks */ + +#define SQL_OU_DML_STATEMENTS 0x00000001L +#define SQL_OU_PROCEDURE_INVOCATION 0x00000002L +#define SQL_OU_TABLE_DEFINITION 0x00000004L +#define SQL_OU_INDEX_DEFINITION 0x00000008L +#define SQL_OU_PRIVILEGE_DEFINITION 0x00000010L + +/* SQL_SCHEMA_USAGE masks */ +#if (ODBCVER >= 0x0300) +#define SQL_SU_DML_STATEMENTS SQL_OU_DML_STATEMENTS +#define SQL_SU_PROCEDURE_INVOCATION SQL_OU_PROCEDURE_INVOCATION +#define SQL_SU_TABLE_DEFINITION SQL_OU_TABLE_DEFINITION +#define SQL_SU_INDEX_DEFINITION SQL_OU_INDEX_DEFINITION +#define SQL_SU_PRIVILEGE_DEFINITION SQL_OU_PRIVILEGE_DEFINITION +#endif /* ODBCVER >= 0x0300 */ + +/* SQL_QUALIFIER_USAGE masks */ + +#define SQL_QU_DML_STATEMENTS 0x00000001L +#define SQL_QU_PROCEDURE_INVOCATION 0x00000002L +#define SQL_QU_TABLE_DEFINITION 0x00000004L +#define SQL_QU_INDEX_DEFINITION 0x00000008L +#define SQL_QU_PRIVILEGE_DEFINITION 0x00000010L + +#if (ODBCVER >= 0x0300) +/* SQL_CATALOG_USAGE masks */ +#define SQL_CU_DML_STATEMENTS SQL_QU_DML_STATEMENTS +#define SQL_CU_PROCEDURE_INVOCATION SQL_QU_PROCEDURE_INVOCATION +#define SQL_CU_TABLE_DEFINITION SQL_QU_TABLE_DEFINITION +#define SQL_CU_INDEX_DEFINITION SQL_QU_INDEX_DEFINITION +#define SQL_CU_PRIVILEGE_DEFINITION SQL_QU_PRIVILEGE_DEFINITION +#endif /* ODBCVER >= 0x0300 */ + +/* SQL_SUBQUERIES masks */ + +#define SQL_SQ_COMPARISON 0x00000001L +#define SQL_SQ_EXISTS 0x00000002L +#define SQL_SQ_IN 0x00000004L +#define SQL_SQ_QUANTIFIED 0x00000008L +#define SQL_SQ_CORRELATED_SUBQUERIES 0x00000010L + +/* SQL_UNION masks */ + +#define SQL_U_UNION 0x00000001L +#define SQL_U_UNION_ALL 0x00000002L + +/* SQL_BOOKMARK_PERSISTENCE values */ + +#define SQL_BP_CLOSE 0x00000001L +#define SQL_BP_DELETE 0x00000002L +#define SQL_BP_DROP 0x00000004L +#define SQL_BP_TRANSACTION 0x00000008L +#define SQL_BP_UPDATE 0x00000010L +#define SQL_BP_OTHER_HSTMT 0x00000020L +#define SQL_BP_SCROLL 0x00000040L + +/* SQL_STATIC_SENSITIVITY values */ + +#define SQL_SS_ADDITIONS 0x00000001L +#define SQL_SS_DELETIONS 0x00000002L +#define SQL_SS_UPDATES 0x00000004L + +/* SQL_VIEW values */ +#define SQL_CV_CREATE_VIEW 0x00000001L +#define SQL_CV_CHECK_OPTION 0x00000002L +#define SQL_CV_CASCADED 0x00000004L +#define SQL_CV_LOCAL 0x00000008L + +/* SQL_LOCK_TYPES masks */ + +#define SQL_LCK_NO_CHANGE 0x00000001L +#define SQL_LCK_EXCLUSIVE 0x00000002L +#define SQL_LCK_UNLOCK 0x00000004L + +/* SQL_POS_OPERATIONS masks */ + +#define SQL_POS_POSITION 0x00000001L +#define SQL_POS_REFRESH 0x00000002L +#define SQL_POS_UPDATE 0x00000004L +#define SQL_POS_DELETE 0x00000008L +#define SQL_POS_ADD 0x00000010L + +/* SQL_QUALIFIER_LOCATION values */ + +#define SQL_QL_START 0x0001 +#define SQL_QL_END 0x0002 + +/* Here start return values for ODBC 3.0 SQLGetInfo */ + +#if (ODBCVER >= 0x0300) +/* SQL_AGGREGATE_FUNCTIONS bitmasks */ +#define SQL_AF_AVG 0x00000001L +#define SQL_AF_COUNT 0x00000002L +#define SQL_AF_MAX 0x00000004L +#define SQL_AF_MIN 0x00000008L +#define SQL_AF_SUM 0x00000010L +#define SQL_AF_DISTINCT 0x00000020L +#define SQL_AF_ALL 0x00000040L + +/* SQL_SQL_CONFORMANCE bit masks */ +#define SQL_SC_SQL92_ENTRY 0x00000001L +#define SQL_SC_FIPS127_2_TRANSITIONAL 0x00000002L +#define SQL_SC_SQL92_INTERMEDIATE 0x00000004L +#define SQL_SC_SQL92_FULL 0x00000008L + +/* SQL_DATETIME_LITERALS masks */ +#define SQL_DL_SQL92_DATE 0x00000001L +#define SQL_DL_SQL92_TIME 0x00000002L +#define SQL_DL_SQL92_TIMESTAMP 0x00000004L +#define SQL_DL_SQL92_INTERVAL_YEAR 0x00000008L +#define SQL_DL_SQL92_INTERVAL_MONTH 0x00000010L +#define SQL_DL_SQL92_INTERVAL_DAY 0x00000020L +#define SQL_DL_SQL92_INTERVAL_HOUR 0x00000040L +#define SQL_DL_SQL92_INTERVAL_MINUTE 0x00000080L +#define SQL_DL_SQL92_INTERVAL_SECOND 0x00000100L +#define SQL_DL_SQL92_INTERVAL_YEAR_TO_MONTH 0x00000200L +#define SQL_DL_SQL92_INTERVAL_DAY_TO_HOUR 0x00000400L +#define SQL_DL_SQL92_INTERVAL_DAY_TO_MINUTE 0x00000800L +#define SQL_DL_SQL92_INTERVAL_DAY_TO_SECOND 0x00001000L +#define SQL_DL_SQL92_INTERVAL_HOUR_TO_MINUTE 0x00002000L +#define SQL_DL_SQL92_INTERVAL_HOUR_TO_SECOND 0x00004000L +#define SQL_DL_SQL92_INTERVAL_MINUTE_TO_SECOND 0x00008000L + +/* SQL_CATALOG_LOCATION values */ +#define SQL_CL_START SQL_QL_START +#define SQL_CL_END SQL_QL_END + +/* values for SQL_BATCH_ROW_COUNT */ +#define SQL_BRC_PROCEDURES 0x0000001 +#define SQL_BRC_EXPLICIT 0x0000002 +#define SQL_BRC_ROLLED_UP 0x0000004 + +/* bitmasks for SQL_BATCH_SUPPORT */ +#define SQL_BS_SELECT_EXPLICIT 0x00000001L +#define SQL_BS_ROW_COUNT_EXPLICIT 0x00000002L +#define SQL_BS_SELECT_PROC 0x00000004L +#define SQL_BS_ROW_COUNT_PROC 0x00000008L + +/* Values for SQL_PARAM_ARRAY_ROW_COUNTS getinfo */ +#define SQL_PARC_BATCH 1 +#define SQL_PARC_NO_BATCH 2 + +/* values for SQL_PARAM_ARRAY_SELECTS */ +#define SQL_PAS_BATCH 1 +#define SQL_PAS_NO_BATCH 2 +#define SQL_PAS_NO_SELECT 3 + +/* Bitmasks for SQL_INDEX_KEYWORDS */ +#define SQL_IK_NONE 0x00000000L +#define SQL_IK_ASC 0x00000001L +#define SQL_IK_DESC 0x00000002L +#define SQL_IK_ALL (SQL_IK_ASC | SQL_IK_DESC) + +/* Bitmasks for SQL_INFO_SCHEMA_VIEWS */ + +#define SQL_ISV_ASSERTIONS 0x00000001L +#define SQL_ISV_CHARACTER_SETS 0x00000002L +#define SQL_ISV_CHECK_CONSTRAINTS 0x00000004L +#define SQL_ISV_COLLATIONS 0x00000008L +#define SQL_ISV_COLUMN_DOMAIN_USAGE 0x00000010L +#define SQL_ISV_COLUMN_PRIVILEGES 0x00000020L +#define SQL_ISV_COLUMNS 0x00000040L +#define SQL_ISV_CONSTRAINT_COLUMN_USAGE 0x00000080L +#define SQL_ISV_CONSTRAINT_TABLE_USAGE 0x00000100L +#define SQL_ISV_DOMAIN_CONSTRAINTS 0x00000200L +#define SQL_ISV_DOMAINS 0x00000400L +#define SQL_ISV_KEY_COLUMN_USAGE 0x00000800L +#define SQL_ISV_REFERENTIAL_CONSTRAINTS 0x00001000L +#define SQL_ISV_SCHEMATA 0x00002000L +#define SQL_ISV_SQL_LANGUAGES 0x00004000L +#define SQL_ISV_TABLE_CONSTRAINTS 0x00008000L +#define SQL_ISV_TABLE_PRIVILEGES 0x00010000L +#define SQL_ISV_TABLES 0x00020000L +#define SQL_ISV_TRANSLATIONS 0x00040000L +#define SQL_ISV_USAGE_PRIVILEGES 0x00080000L +#define SQL_ISV_VIEW_COLUMN_USAGE 0x00100000L +#define SQL_ISV_VIEW_TABLE_USAGE 0x00200000L +#define SQL_ISV_VIEWS 0x00400000L + +/* Bitmasks for SQL_ASYNC_MODE */ + +#define SQL_AM_NONE 0 +#define SQL_AM_CONNECTION 1 +#define SQL_AM_STATEMENT 2 + +/* Bitmasks for SQL_ALTER_DOMAIN */ +#define SQL_AD_CONSTRAINT_NAME_DEFINITION 0x00000001L +#define SQL_AD_ADD_DOMAIN_CONSTRAINT 0x00000002L +#define SQL_AD_DROP_DOMAIN_CONSTRAINT 0x00000004L +#define SQL_AD_ADD_DOMAIN_DEFAULT 0x00000008L +#define SQL_AD_DROP_DOMAIN_DEFAULT 0x00000010L +#define SQL_AD_ADD_CONSTRAINT_INITIALLY_DEFERRED 0x00000020L +#define SQL_AD_ADD_CONSTRAINT_INITIALLY_IMMEDIATE 0x00000040L +#define SQL_AD_ADD_CONSTRAINT_DEFERRABLE 0x00000080L +#define SQL_AD_ADD_CONSTRAINT_NON_DEFERRABLE 0x00000100L + + +/* SQL_CREATE_SCHEMA bitmasks */ +#define SQL_CS_CREATE_SCHEMA 0x00000001L +#define SQL_CS_AUTHORIZATION 0x00000002L +#define SQL_CS_DEFAULT_CHARACTER_SET 0x00000004L + +/* SQL_CREATE_TRANSLATION bitmasks */ +#define SQL_CTR_CREATE_TRANSLATION 0x00000001L + +/* SQL_CREATE_ASSERTION bitmasks */ +#define SQL_CA_CREATE_ASSERTION 0x00000001L +#define SQL_CA_CONSTRAINT_INITIALLY_DEFERRED 0x00000010L +#define SQL_CA_CONSTRAINT_INITIALLY_IMMEDIATE 0x00000020L +#define SQL_CA_CONSTRAINT_DEFERRABLE 0x00000040L +#define SQL_CA_CONSTRAINT_NON_DEFERRABLE 0x00000080L + +/* SQL_CREATE_CHARACTER_SET bitmasks */ +#define SQL_CCS_CREATE_CHARACTER_SET 0x00000001L +#define SQL_CCS_COLLATE_CLAUSE 0x00000002L +#define SQL_CCS_LIMITED_COLLATION 0x00000004L + +/* SQL_CREATE_COLLATION bitmasks */ +#define SQL_CCOL_CREATE_COLLATION 0x00000001L + +/* SQL_CREATE_DOMAIN bitmasks */ +#define SQL_CDO_CREATE_DOMAIN 0x00000001L +#define SQL_CDO_DEFAULT 0x00000002L +#define SQL_CDO_CONSTRAINT 0x00000004L +#define SQL_CDO_COLLATION 0x00000008L +#define SQL_CDO_CONSTRAINT_NAME_DEFINITION 0x00000010L +#define SQL_CDO_CONSTRAINT_INITIALLY_DEFERRED 0x00000020L +#define SQL_CDO_CONSTRAINT_INITIALLY_IMMEDIATE 0x00000040L +#define SQL_CDO_CONSTRAINT_DEFERRABLE 0x00000080L +#define SQL_CDO_CONSTRAINT_NON_DEFERRABLE 0x00000100L + +/* SQL_CREATE_TABLE bitmasks */ +#define SQL_CT_CREATE_TABLE 0x00000001L +#define SQL_CT_COMMIT_PRESERVE 0x00000002L +#define SQL_CT_COMMIT_DELETE 0x00000004L +#define SQL_CT_GLOBAL_TEMPORARY 0x00000008L +#define SQL_CT_LOCAL_TEMPORARY 0x00000010L +#define SQL_CT_CONSTRAINT_INITIALLY_DEFERRED 0x00000020L +#define SQL_CT_CONSTRAINT_INITIALLY_IMMEDIATE 0x00000040L +#define SQL_CT_CONSTRAINT_DEFERRABLE 0x00000080L +#define SQL_CT_CONSTRAINT_NON_DEFERRABLE 0x00000100L +#define SQL_CT_COLUMN_CONSTRAINT 0x00000200L +#define SQL_CT_COLUMN_DEFAULT 0x00000400L +#define SQL_CT_COLUMN_COLLATION 0x00000800L +#define SQL_CT_TABLE_CONSTRAINT 0x00001000L +#define SQL_CT_CONSTRAINT_NAME_DEFINITION 0x00002000L + +/* SQL_DDL_INDEX bitmasks */ +#define SQL_DI_CREATE_INDEX 0x00000001L +#define SQL_DI_DROP_INDEX 0x00000002L + +/* SQL_DROP_COLLATION bitmasks */ +#define SQL_DC_DROP_COLLATION 0x00000001L + +/* SQL_DROP_DOMAIN bitmasks */ +#define SQL_DD_DROP_DOMAIN 0x00000001L +#define SQL_DD_RESTRICT 0x00000002L +#define SQL_DD_CASCADE 0x00000004L + +/* SQL_DROP_SCHEMA bitmasks */ +#define SQL_DS_DROP_SCHEMA 0x00000001L +#define SQL_DS_RESTRICT 0x00000002L +#define SQL_DS_CASCADE 0x00000004L + +/* SQL_DROP_CHARACTER_SET bitmasks */ +#define SQL_DCS_DROP_CHARACTER_SET 0x00000001L + +/* SQL_DROP_ASSERTION bitmasks */ +#define SQL_DA_DROP_ASSERTION 0x00000001L + +/* SQL_DROP_TABLE bitmasks */ +#define SQL_DT_DROP_TABLE 0x00000001L +#define SQL_DT_RESTRICT 0x00000002L +#define SQL_DT_CASCADE 0x00000004L + +/* SQL_DROP_TRANSLATION bitmasks */ +#define SQL_DTR_DROP_TRANSLATION 0x00000001L + +/* SQL_DROP_VIEW bitmasks */ +#define SQL_DV_DROP_VIEW 0x00000001L +#define SQL_DV_RESTRICT 0x00000002L +#define SQL_DV_CASCADE 0x00000004L + +/* SQL_INSERT_STATEMENT bitmasks */ +#define SQL_IS_INSERT_LITERALS 0x00000001L +#define SQL_IS_INSERT_SEARCHED 0x00000002L +#define SQL_IS_SELECT_INTO 0x00000004L + +/* SQL_ODBC_INTERFACE_CONFORMANCE values */ +#define SQL_OIC_CORE 1UL +#define SQL_OIC_LEVEL1 2UL +#define SQL_OIC_LEVEL2 3UL + +/* SQL_SQL92_FOREIGN_KEY_DELETE_RULE bitmasks */ +#define SQL_SFKD_CASCADE 0x00000001L +#define SQL_SFKD_NO_ACTION 0x00000002L +#define SQL_SFKD_SET_DEFAULT 0x00000004L +#define SQL_SFKD_SET_NULL 0x00000008L + +/* SQL_SQL92_FOREIGN_KEY_UPDATE_RULE bitmasks */ +#define SQL_SFKU_CASCADE 0x00000001L +#define SQL_SFKU_NO_ACTION 0x00000002L +#define SQL_SFKU_SET_DEFAULT 0x00000004L +#define SQL_SFKU_SET_NULL 0x00000008L + +/* SQL_SQL92_GRANT bitmasks */ +#define SQL_SG_USAGE_ON_DOMAIN 0x00000001L +#define SQL_SG_USAGE_ON_CHARACTER_SET 0x00000002L +#define SQL_SG_USAGE_ON_COLLATION 0x00000004L +#define SQL_SG_USAGE_ON_TRANSLATION 0x00000008L +#define SQL_SG_WITH_GRANT_OPTION 0x00000010L +#define SQL_SG_DELETE_TABLE 0x00000020L +#define SQL_SG_INSERT_TABLE 0x00000040L +#define SQL_SG_INSERT_COLUMN 0x00000080L +#define SQL_SG_REFERENCES_TABLE 0x00000100L +#define SQL_SG_REFERENCES_COLUMN 0x00000200L +#define SQL_SG_SELECT_TABLE 0x00000400L +#define SQL_SG_UPDATE_TABLE 0x00000800L +#define SQL_SG_UPDATE_COLUMN 0x00001000L + +/* SQL_SQL92_PREDICATES bitmasks */ +#define SQL_SP_EXISTS 0x00000001L +#define SQL_SP_ISNOTNULL 0x00000002L +#define SQL_SP_ISNULL 0x00000004L +#define SQL_SP_MATCH_FULL 0x00000008L +#define SQL_SP_MATCH_PARTIAL 0x00000010L +#define SQL_SP_MATCH_UNIQUE_FULL 0x00000020L +#define SQL_SP_MATCH_UNIQUE_PARTIAL 0x00000040L +#define SQL_SP_OVERLAPS 0x00000080L +#define SQL_SP_UNIQUE 0x00000100L +#define SQL_SP_LIKE 0x00000200L +#define SQL_SP_IN 0x00000400L +#define SQL_SP_BETWEEN 0x00000800L +#define SQL_SP_COMPARISON 0x00001000L +#define SQL_SP_QUANTIFIED_COMPARISON 0x00002000L + +/* SQL_SQL92_RELATIONAL_JOIN_OPERATORS bitmasks */ +#define SQL_SRJO_CORRESPONDING_CLAUSE 0x00000001L +#define SQL_SRJO_CROSS_JOIN 0x00000002L +#define SQL_SRJO_EXCEPT_JOIN 0x00000004L +#define SQL_SRJO_FULL_OUTER_JOIN 0x00000008L +#define SQL_SRJO_INNER_JOIN 0x00000010L +#define SQL_SRJO_INTERSECT_JOIN 0x00000020L +#define SQL_SRJO_LEFT_OUTER_JOIN 0x00000040L +#define SQL_SRJO_NATURAL_JOIN 0x00000080L +#define SQL_SRJO_RIGHT_OUTER_JOIN 0x00000100L +#define SQL_SRJO_UNION_JOIN 0x00000200L + +/* SQL_SQL92_REVOKE bitmasks */ +#define SQL_SR_USAGE_ON_DOMAIN 0x00000001L +#define SQL_SR_USAGE_ON_CHARACTER_SET 0x00000002L +#define SQL_SR_USAGE_ON_COLLATION 0x00000004L +#define SQL_SR_USAGE_ON_TRANSLATION 0x00000008L +#define SQL_SR_GRANT_OPTION_FOR 0x00000010L +#define SQL_SR_CASCADE 0x00000020L +#define SQL_SR_RESTRICT 0x00000040L +#define SQL_SR_DELETE_TABLE 0x00000080L +#define SQL_SR_INSERT_TABLE 0x00000100L +#define SQL_SR_INSERT_COLUMN 0x00000200L +#define SQL_SR_REFERENCES_TABLE 0x00000400L +#define SQL_SR_REFERENCES_COLUMN 0x00000800L +#define SQL_SR_SELECT_TABLE 0x00001000L +#define SQL_SR_UPDATE_TABLE 0x00002000L +#define SQL_SR_UPDATE_COLUMN 0x00004000L + +/* SQL_SQL92_ROW_VALUE_CONSTRUCTOR bitmasks */ +#define SQL_SRVC_VALUE_EXPRESSION 0x00000001L +#define SQL_SRVC_NULL 0x00000002L +#define SQL_SRVC_DEFAULT 0x00000004L +#define SQL_SRVC_ROW_SUBQUERY 0x00000008L + +/* SQL_SQL92_VALUE_EXPRESSIONS bitmasks */ +#define SQL_SVE_CASE 0x00000001L +#define SQL_SVE_CAST 0x00000002L +#define SQL_SVE_COALESCE 0x00000004L +#define SQL_SVE_NULLIF 0x00000008L + +/* SQL_STANDARD_CLI_CONFORMANCE bitmasks */ +#define SQL_SCC_XOPEN_CLI_VERSION1 0x00000001L +#define SQL_SCC_ISO92_CLI 0x00000002L + +/* SQL_UNION_STATEMENT bitmasks */ +#define SQL_US_UNION SQL_U_UNION +#define SQL_US_UNION_ALL SQL_U_UNION_ALL + +#endif /* ODBCVER >= 0x0300 */ + +/* SQL_DTC_TRANSITION_COST bitmasks */ +#define SQL_DTC_ENLIST_EXPENSIVE 0x00000001L +#define SQL_DTC_UNENLIST_EXPENSIVE 0x00000002L + +/* additional SQLDataSources fetch directions */ +#if (ODBCVER >= 0x0300) +#define SQL_FETCH_FIRST_USER 31 +#define SQL_FETCH_FIRST_SYSTEM 32 +#endif /* ODBCVER >= 0x0300 */ + + +/* Defines for SQLSetPos */ +#define SQL_ENTIRE_ROWSET 0 + +/* Operations in SQLSetPos */ +#define SQL_POSITION 0 /* 1.0 FALSE */ +#define SQL_REFRESH 1 /* 1.0 TRUE */ +#define SQL_UPDATE 2 +#define SQL_DELETE 3 + +/* Operations in SQLBulkOperations */ +#define SQL_ADD 4 +#define SQL_SETPOS_MAX_OPTION_VALUE SQL_ADD +#if (ODBCVER >= 0x0300) +#define SQL_UPDATE_BY_BOOKMARK 5 +#define SQL_DELETE_BY_BOOKMARK 6 +#define SQL_FETCH_BY_BOOKMARK 7 + +#endif /* ODBCVER >= 0x0300 */ + +/* Lock options in SQLSetPos */ +#define SQL_LOCK_NO_CHANGE 0 /* 1.0 FALSE */ +#define SQL_LOCK_EXCLUSIVE 1 /* 1.0 TRUE */ +#define SQL_LOCK_UNLOCK 2 + +#define SQL_SETPOS_MAX_LOCK_VALUE SQL_LOCK_UNLOCK + +/* Macros for SQLSetPos */ +#define SQL_POSITION_TO(hstmt,irow) SQLSetPos(hstmt,irow,SQL_POSITION,SQL_LOCK_NO_CHANGE) +#define SQL_LOCK_RECORD(hstmt,irow,fLock) SQLSetPos(hstmt,irow,SQL_POSITION,fLock) +#define SQL_REFRESH_RECORD(hstmt,irow,fLock) SQLSetPos(hstmt,irow,SQL_REFRESH,fLock) +#define SQL_UPDATE_RECORD(hstmt,irow) SQLSetPos(hstmt,irow,SQL_UPDATE,SQL_LOCK_NO_CHANGE) +#define SQL_DELETE_RECORD(hstmt,irow) SQLSetPos(hstmt,irow,SQL_DELETE,SQL_LOCK_NO_CHANGE) +#define SQL_ADD_RECORD(hstmt,irow) SQLSetPos(hstmt,irow,SQL_ADD,SQL_LOCK_NO_CHANGE) + +/* Column types and scopes in SQLSpecialColumns. */ +#define SQL_BEST_ROWID 1 +#define SQL_ROWVER 2 + +/* Defines for SQLSpecialColumns (returned in the result set) + SQL_PC_UNKNOWN and SQL_PC_PSEUDO are defined in sql.h */ +#define SQL_PC_NOT_PSEUDO 1 + +/* Defines for SQLStatistics */ +#define SQL_QUICK 0 +#define SQL_ENSURE 1 + +/* Defines for SQLStatistics (returned in the result set) + SQL_INDEX_CLUSTERED, SQL_INDEX_HASHED, and SQL_INDEX_OTHER are + defined in sql.h */ +#define SQL_TABLE_STAT 0 + + +/* Defines for SQLTables */ +#if (ODBCVER >= 0x0300) +#define SQL_ALL_CATALOGS "%" +#define SQL_ALL_SCHEMAS "%" +#define SQL_ALL_TABLE_TYPES "%" +#endif /* ODBCVER >= 0x0300 */ + +/* Options for SQLDriverConnect */ +#define SQL_DRIVER_NOPROMPT 0 +#define SQL_DRIVER_COMPLETE 1 +#define SQL_DRIVER_PROMPT 2 +#define SQL_DRIVER_COMPLETE_REQUIRED 3 + +#ifndef RC_INVOKED + +SQLRETURN SQL_API SQLDriverConnect( + SQLHDBC hdbc, + SQLHWND hwnd, + SQLCHAR *szConnStrIn, + SQLSMALLINT cbConnStrIn, + SQLCHAR *szConnStrOut, + SQLSMALLINT cbConnStrOutMax, + SQLSMALLINT *pcbConnStrOut, + SQLUSMALLINT fDriverCompletion); + +#endif /* RC_INVOKED */ + +/* Level 2 Functions */ + +/* SQLExtendedFetch "fFetchType" values */ +#define SQL_FETCH_BOOKMARK 8 + +/* SQLExtendedFetch "rgfRowStatus" element values */ +#define SQL_ROW_SUCCESS 0 +#define SQL_ROW_DELETED 1 +#define SQL_ROW_UPDATED 2 +#define SQL_ROW_NOROW 3 +#define SQL_ROW_ADDED 4 +#define SQL_ROW_ERROR 5 +#if (ODBCVER >= 0x0300) +#define SQL_ROW_SUCCESS_WITH_INFO 6 +#define SQL_ROW_PROCEED 0 +#define SQL_ROW_IGNORE 1 +#endif + +/* value for SQL_DESC_ARRAY_STATUS_PTR */ +#if (ODBCVER >= 0x0300) +#define SQL_PARAM_SUCCESS 0 +#define SQL_PARAM_SUCCESS_WITH_INFO 6 +#define SQL_PARAM_ERROR 5 +#define SQL_PARAM_UNUSED 7 +#define SQL_PARAM_DIAG_UNAVAILABLE 1 + +#define SQL_PARAM_PROCEED 0 +#define SQL_PARAM_IGNORE 1 +#endif /* ODBCVER >= 0x0300 */ + +/* Defines for SQLForeignKeys (UPDATE_RULE and DELETE_RULE) */ +#define SQL_CASCADE 0 +#define SQL_RESTRICT 1 +#define SQL_SET_NULL 2 +#if (ODBCVER >= 0x0250) +#define SQL_NO_ACTION 3 +#define SQL_SET_DEFAULT 4 +#endif /* ODBCVER >= 0x0250 */ + +#if (ODBCVER >= 0x0300) +/* Note that the following are in a different column of SQLForeignKeys than */ +/* the previous #defines. These are for DEFERRABILITY. */ + +#define SQL_INITIALLY_DEFERRED 5 +#define SQL_INITIALLY_IMMEDIATE 6 +#define SQL_NOT_DEFERRABLE 7 + +#endif /* ODBCVER >= 0x0300 */ + +/* Defines for SQLBindParameter and + SQLProcedureColumns (returned in the result set) */ +#define SQL_PARAM_TYPE_UNKNOWN 0 +#define SQL_PARAM_INPUT 1 +#define SQL_PARAM_INPUT_OUTPUT 2 +#define SQL_RESULT_COL 3 +#define SQL_PARAM_OUTPUT 4 +#define SQL_RETURN_VALUE 5 + +/* Defines for SQLProcedures (returned in the result set) */ +#define SQL_PT_UNKNOWN 0 +#define SQL_PT_PROCEDURE 1 +#define SQL_PT_FUNCTION 2 + +#ifndef RC_INVOKED + +/* This define is too large for RC */ +#define SQL_ODBC_KEYWORDS \ +"ABSOLUTE,ACTION,ADA,ADD,ALL,ALLOCATE,ALTER,AND,ANY,ARE,AS,"\ +"ASC,ASSERTION,AT,AUTHORIZATION,AVG,"\ +"BEGIN,BETWEEN,BIT,BIT_LENGTH,BOTH,BY,CASCADE,CASCADED,CASE,CAST,CATALOG,"\ +"CHAR,CHAR_LENGTH,CHARACTER,CHARACTER_LENGTH,CHECK,CLOSE,COALESCE,"\ +"COLLATE,COLLATION,COLUMN,COMMIT,CONNECT,CONNECTION,CONSTRAINT,"\ +"CONSTRAINTS,CONTINUE,CONVERT,CORRESPONDING,COUNT,CREATE,CROSS,CURRENT,"\ +"CURRENT_DATE,CURRENT_TIME,CURRENT_TIMESTAMP,CURRENT_USER,CURSOR,"\ +"DATE,DAY,DEALLOCATE,DEC,DECIMAL,DECLARE,DEFAULT,DEFERRABLE,"\ +"DEFERRED,DELETE,DESC,DESCRIBE,DESCRIPTOR,DIAGNOSTICS,DISCONNECT,"\ +"DISTINCT,DOMAIN,DOUBLE,DROP,"\ +"ELSE,END,END-EXEC,ESCAPE,EXCEPT,EXCEPTION,EXEC,EXECUTE,"\ +"EXISTS,EXTERNAL,EXTRACT,"\ +"FALSE,FETCH,FIRST,FLOAT,FOR,FOREIGN,FORTRAN,FOUND,FROM,FULL,"\ +"GET,GLOBAL,GO,GOTO,GRANT,GROUP,HAVING,HOUR,"\ +"IDENTITY,IMMEDIATE,IN,INCLUDE,INDEX,INDICATOR,INITIALLY,INNER,"\ +"INPUT,INSENSITIVE,INSERT,INT,INTEGER,INTERSECT,INTERVAL,INTO,IS,ISOLATION,"\ +"JOIN,KEY,LANGUAGE,LAST,LEADING,LEFT,LEVEL,LIKE,LOCAL,LOWER,"\ +"MATCH,MAX,MIN,MINUTE,MODULE,MONTH,"\ +"NAMES,NATIONAL,NATURAL,NCHAR,NEXT,NO,NONE,NOT,NULL,NULLIF,NUMERIC,"\ +"OCTET_LENGTH,OF,ON,ONLY,OPEN,OPTION,OR,ORDER,OUTER,OUTPUT,OVERLAPS,"\ +"PAD,PARTIAL,PASCAL,PLI,POSITION,PRECISION,PREPARE,PRESERVE,"\ +"PRIMARY,PRIOR,PRIVILEGES,PROCEDURE,PUBLIC,"\ +"READ,REAL,REFERENCES,RELATIVE,RESTRICT,REVOKE,RIGHT,ROLLBACK,ROWS"\ +"SCHEMA,SCROLL,SECOND,SECTION,SELECT,SESSION,SESSION_USER,SET,SIZE,"\ +"SMALLINT,SOME,SPACE,SQL,SQLCA,SQLCODE,SQLERROR,SQLSTATE,SQLWARNING,"\ +"SUBSTRING,SUM,SYSTEM_USER,"\ +"TABLE,TEMPORARY,THEN,TIME,TIMESTAMP,TIMEZONE_HOUR,TIMEZONE_MINUTE,"\ +"TO,TRAILING,TRANSACTION,TRANSLATE,TRANSLATION,TRIM,TRUE,"\ +"UNION,UNIQUE,UNKNOWN,UPDATE,UPPER,USAGE,USER,USING,"\ +"VALUE,VALUES,VARCHAR,VARYING,VIEW,WHEN,WHENEVER,WHERE,WITH,WORK,WRITE,"\ +"YEAR,ZONE" + +SQLRETURN SQL_API SQLBrowseConnect( + SQLHDBC hdbc, + SQLCHAR *szConnStrIn, + SQLSMALLINT cbConnStrIn, + SQLCHAR *szConnStrOut, + SQLSMALLINT cbConnStrOutMax, + SQLSMALLINT *pcbConnStrOut); + +#if (ODBCVER >= 0x0300) +SQLRETURN SQL_API SQLBulkOperations( + SQLHSTMT StatementHandle, + SQLSMALLINT Operation); +#endif /* ODBCVER >= 0x0300 */ + +SQLRETURN SQL_API SQLColAttributes( + SQLHSTMT hstmt, + SQLUSMALLINT icol, + SQLUSMALLINT fDescType, + SQLPOINTER rgbDesc, + SQLSMALLINT cbDescMax, + SQLSMALLINT *pcbDesc, + SQLLEN * pfDesc); + +SQLRETURN SQL_API SQLColumnPrivileges( + SQLHSTMT hstmt, + SQLCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR *szTableName, + SQLSMALLINT cbTableName, + SQLCHAR *szColumnName, + SQLSMALLINT cbColumnName); + +SQLRETURN SQL_API SQLDescribeParam( + SQLHSTMT hstmt, + SQLUSMALLINT ipar, + SQLSMALLINT *pfSqlType, + SQLULEN *pcbParamDef, + SQLSMALLINT *pibScale, + SQLSMALLINT *pfNullable); + +SQLRETURN SQL_API SQLExtendedFetch( + SQLHSTMT hstmt, + SQLUSMALLINT fFetchType, + SQLLEN irow, + SQLULEN *pcrow, + SQLUSMALLINT *rgfRowStatus); + +SQLRETURN SQL_API SQLForeignKeys( + SQLHSTMT hstmt, + SQLCHAR *szPkCatalogName, + SQLSMALLINT cbPkCatalogName, + SQLCHAR *szPkSchemaName, + SQLSMALLINT cbPkSchemaName, + SQLCHAR *szPkTableName, + SQLSMALLINT cbPkTableName, + SQLCHAR *szFkCatalogName, + SQLSMALLINT cbFkCatalogName, + SQLCHAR *szFkSchemaName, + SQLSMALLINT cbFkSchemaName, + SQLCHAR *szFkTableName, + SQLSMALLINT cbFkTableName); + +SQLRETURN SQL_API SQLMoreResults( + SQLHSTMT hstmt); + +SQLRETURN SQL_API SQLNativeSql( + SQLHDBC hdbc, + SQLCHAR *szSqlStrIn, + SQLINTEGER cbSqlStrIn, + SQLCHAR *szSqlStr, + SQLINTEGER cbSqlStrMax, + SQLINTEGER *pcbSqlStr); + +SQLRETURN SQL_API SQLNumParams( + SQLHSTMT hstmt, + SQLSMALLINT *pcpar); + +SQLRETURN SQL_API SQLParamOptions( + SQLHSTMT hstmt, + SQLULEN crow, + SQLULEN *pirow); + +SQLRETURN SQL_API SQLPrimaryKeys( + SQLHSTMT hstmt, + SQLCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR *szTableName, + SQLSMALLINT cbTableName); + +SQLRETURN SQL_API SQLProcedureColumns( + SQLHSTMT hstmt, + SQLCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR *szProcName, + SQLSMALLINT cbProcName, + SQLCHAR *szColumnName, + SQLSMALLINT cbColumnName); + +SQLRETURN SQL_API SQLProcedures( + SQLHSTMT hstmt, + SQLCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR *szProcName, + SQLSMALLINT cbProcName); + + + +SQLRETURN SQL_API SQLSetPos( + SQLHSTMT hstmt, + SQLSETPOSIROW irow, + SQLUSMALLINT fOption, + SQLUSMALLINT fLock); + +SQLRETURN SQL_API SQLTablePrivileges( + SQLHSTMT hstmt, + SQLCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR *szTableName, + SQLSMALLINT cbTableName); + +SQLRETURN SQL_API SQLDrivers( + SQLHENV henv, + SQLUSMALLINT fDirection, + SQLCHAR *szDriverDesc, + SQLSMALLINT cbDriverDescMax, + SQLSMALLINT *pcbDriverDesc, + SQLCHAR *szDriverAttributes, + SQLSMALLINT cbDrvrAttrMax, + SQLSMALLINT *pcbDrvrAttr); + +SQLRETURN SQL_API SQLBindParameter( + SQLHSTMT hstmt, + SQLUSMALLINT ipar, + SQLSMALLINT fParamType, + SQLSMALLINT fCType, + SQLSMALLINT fSqlType, + SQLULEN cbColDef, + SQLSMALLINT ibScale, + SQLPOINTER rgbValue, + SQLLEN cbValueMax, + SQLLEN *pcbValue); + + +#endif /* RC_INVOKED */ + +/*---------------------------------------------------------*/ +/* SQLAllocHandleStd is implemented to make SQLAllocHandle */ +/* compatible with X/Open standard. an application should */ +/* not call SQLAllocHandleStd directly */ +/*---------------------------------------------------------*/ +#ifdef ODBC_STD +#define SQLAllocHandle SQLAllocHandleStd +#define SQLAllocEnv(phenv) SQLAllocHandleStd(SQL_HANDLE_ENV, SQL_NULL_HANDLE, phenv) + +/* Internal type subcodes */ +#define SQL_YEAR SQL_CODE_YEAR +#define SQL_MONTH SQL_CODE_MONTH +#define SQL_DAY SQL_CODE_DAY +#define SQL_HOUR SQL_CODE_HOUR +#define SQL_MINUTE SQL_CODE_MINUTE +#define SQL_SECOND SQL_CODE_SECOND +#define SQL_YEAR_TO_MONTH SQL_CODE_YEAR_TO_MONTH +#define SQL_DAY_TO_HOUR SQL_CODE_DAY_TO_HOUR +#define SQL_DAY_TO_MINUTE SQL_CODE_DAY_TO_MINUTE +#define SQL_DAY_TO_SECOND SQL_CODE_DAY_TO_SECOND +#define SQL_HOUR_TO_MINUTE SQL_CODE_HOUR_TO_MINUTE +#define SQL_HOUR_TO_SECOND SQL_CODE_HOUR_TO_SECOND +#define SQL_MINUTE_TO_SECOND SQL_CODE_MINUTE_TO_SECOND +#endif /* ODBC_STD */ + +#if (ODBCVER >= 0x0300) +#ifndef RC_INVOKED +SQLRETURN SQL_API SQLAllocHandleStd( + SQLSMALLINT fHandleType, + SQLHANDLE hInput, + SQLHANDLE *phOutput); +#endif /* RC_INVOKED */ +#endif + +/* Deprecated defines from prior versions of ODBC */ +#define SQL_DATABASE_NAME 16 /* Use SQLGetConnectOption/SQL_CURRENT_QUALIFIER */ +#define SQL_FD_FETCH_PREV SQL_FD_FETCH_PRIOR +#define SQL_FETCH_PREV SQL_FETCH_PRIOR +#define SQL_CONCUR_TIMESTAMP SQL_CONCUR_ROWVER +#define SQL_SCCO_OPT_TIMESTAMP SQL_SCCO_OPT_ROWVER +#define SQL_CC_DELETE SQL_CB_DELETE +#define SQL_CR_DELETE SQL_CB_DELETE +#define SQL_CC_CLOSE SQL_CB_CLOSE +#define SQL_CR_CLOSE SQL_CB_CLOSE +#define SQL_CC_PRESERVE SQL_CB_PRESERVE +#define SQL_CR_PRESERVE SQL_CB_PRESERVE +/* SQL_FETCH_RESUME is not supported by 2.0+ drivers +#define SQL_FETCH_RESUME 7 +*/ +#define SQL_SCROLL_FORWARD_ONLY 0L /*-SQL_CURSOR_FORWARD_ONLY */ +#define SQL_SCROLL_KEYSET_DRIVEN (-1L) /*-SQL_CURSOR_KEYSET_DRIVEN */ +#define SQL_SCROLL_DYNAMIC (-2L) /*-SQL_CURSOR_DYNAMIC */ +#define SQL_SCROLL_STATIC (-3L) /*-SQL_CURSOR_STATIC */ + +/* Deprecated functions from prior versions of ODBC */ +#ifndef RC_INVOKED + +SQLRETURN SQL_API SQLSetScrollOptions( /* Use SQLSetStmtOptions */ + SQLHSTMT hstmt, + SQLUSMALLINT fConcurrency, + SQLLEN crowKeyset, + SQLUSMALLINT crowRowset); + +/* Tracing section */ + +#define TRACE_VERSION 1000 /* Version of trace API */ + +RETCODE SQL_API TraceOpenLogFile(LPWSTR,LPWSTR,DWORD);// open a trace log file +RETCODE SQL_API TraceCloseLogFile(); // Request to close a trace log +VOID SQL_API TraceReturn(RETCODE,RETCODE); // Processes trace after FN is called +DWORD SQL_API TraceVersion(); // Returns trace API version + +/* Functions for Visual Studio Analyzer*/ +/* to turn on/off tracing or VS events, call TraceVSControl by setting or clearing the following bits */ +#define TRACE_ON 0x00000001L +#define TRACE_VS_EVENT_ON 0x00000002L + +RETCODE SQL_API TraceVSControl(DWORD); + +/* Functions for setting the connection pooling failure detection code */ +/* The "TryWait" value is the time (in seconds) that the DM will wait */ +/* between detecting that a connection is dead (using */ +/* SQL_ATTR_CONNECTION_DEAD) and retrying the connection. During that */ +/* interval, connection requests will get "The server appears to be */ +/* dead" error returns. */ + + +BOOL SQL_API ODBCSetTryWaitValue(DWORD dwValue); /* In seconds */ +DWORD SQL_API ODBCGetTryWaitValue(); /* In Milliseconds(!) */ + + +/* the flags in ODBC_VS_ARGS */ +#define ODBC_VS_FLAG_UNICODE_ARG 0x00000001L /* the argument is unicode */ +#define ODBC_VS_FLAG_UNICODE_COR 0x00000002L /* the correlation is unicode */ +#define ODBC_VS_FLAG_RETCODE 0x00000004L /* RetCode field is set */ +#define ODBC_VS_FLAG_STOP 0x00000008L /* Stop firing visual studio analyzer events */ + +typedef struct tagODBC_VS_ARGS { + const GUID *pguidEvent; /* the GUID for event */ + DWORD dwFlags; /* flags for the call */ + union { + WCHAR *wszArg; + CHAR *szArg; + }; + union { + WCHAR *wszCorrelation; + CHAR *szCorrelation; + }; + RETCODE RetCode; +} ODBC_VS_ARGS, *PODBC_VS_ARGS; +VOID SQL_API FireVSDebugEvent(PODBC_VS_ARGS); + +#endif /* RC_INVOKED */ + + +#ifdef __cplusplus +} /* End of extern "C" { */ +#endif /* __cplusplus */ + +#if defined(WIN32) || defined(_WIN64) +#include "sqlucode.h" +#endif + +#endif /* __SQLEXT */ diff --git a/libodbc/include/myAPI.h b/libodbc/include/myAPI.h new file mode 100644 index 0000000000..dacb9bd083 --- /dev/null +++ b/libodbc/include/myAPI.h @@ -0,0 +1,303 @@ +// myAPI.h +// +////////////////////////////////////////////////////////////////////// + +#if !defined(__MYAPI_H__) +#define __MYAPI_H__ + +#include "SQLAPI.h" + +// API header(s) +#include +#include + +extern void AddMySQLSupport(const SAConnection * pCon); +extern void ReleaseMySQLSupport(); + +/* Functions to get information from the MYSQL and MYSQL_RES structures */ +/* Should definitely be used if one uses shared libraries */ + +typedef my_ulonglong (STDCALL *mysql_num_rows_t)(MYSQL_RES *res); +typedef unsigned int (STDCALL *mysql_num_fields_t)(MYSQL_RES *res); +typedef my_bool (STDCALL *mysql_eof_t)(MYSQL_RES *res); +typedef MYSQL_FIELD * (STDCALL *mysql_fetch_field_direct_t)(MYSQL_RES *res, + unsigned int fieldnr); +typedef MYSQL_FIELD * (STDCALL *mysql_fetch_fields_t)(MYSQL_RES *res); +typedef MYSQL_ROWS * (STDCALL *mysql_row_tell_t)(MYSQL_RES *res); +typedef unsigned int (STDCALL *mysql_field_tell_t)(MYSQL_RES *res); + +typedef unsigned int (STDCALL *mysql_field_count_t)(MYSQL *mysql); +typedef my_ulonglong (STDCALL *mysql_affected_rows_t)(MYSQL *mysql); +typedef my_ulonglong (STDCALL *mysql_insert_id_t)(MYSQL *mysql); +typedef unsigned int (STDCALL *mysql_errno_t)(MYSQL *mysql); +typedef const char * (STDCALL *mysql_error_t)(MYSQL *mysql); +typedef const char * (STDCALL *mysql_info_t)(MYSQL *mysql); +typedef unsigned long (STDCALL *mysql_thread_id_t)(MYSQL *mysql); +typedef const char * (STDCALL *mysql_character_set_name_t)(MYSQL *mysql); + +typedef MYSQL * (STDCALL *mysql_init_t)(MYSQL *mysql); +//#ifdef HAVE_OPENSSL +typedef int (STDCALL *mysql_ssl_set_t)(MYSQL *mysql, const char *key, + const char *cert, const char *ca, + const char *capath, const char *cipher); +typedef char * (STDCALL *mysql_ssl_cipher_t)(MYSQL *mysql); +typedef int (STDCALL *mysql_ssl_clear_t)(MYSQL *mysql); +//#endif /* HAVE_OPENSSL */ +typedef MYSQL * (STDCALL *mysql_connect_t)(MYSQL *mysql, const char *host, + const char *user, const char *passwd); +typedef my_bool (STDCALL *mysql_change_user_t)(MYSQL *mysql, const char *user, + const char *passwd, const char *db); +//#if MYSQL_VERSION_ID >= 32200 +typedef MYSQL * (STDCALL *mysql_real_connect2_t)(MYSQL *mysql, const char *host, + const char *user, + const char *passwd, + const char *db, + unsigned int port, + const char *unix_socket, + long unsigned int clientflag); +//#else +typedef MYSQL * (STDCALL *mysql_real_connect1_t)(MYSQL *mysql, const char *host, + const char *user, + const char *passwd, + unsigned int port, + const char *unix_socket, + long unsigned int clientflag); +//#endif +typedef void (STDCALL *mysql_close_t)(MYSQL *sock); +typedef int (STDCALL *mysql_next_result_t)(MYSQL *mysql); +typedef int (STDCALL *mysql_select_db_t)(MYSQL *mysql, const char *db); +typedef int (STDCALL *mysql_query_t)(MYSQL *mysql, const char *q); +typedef int (STDCALL *mysql_send_query_t)(MYSQL *mysql, const char *q, + long unsigned int length); +typedef my_bool (STDCALL *mysql_read_query_result_t)(MYSQL *mysql); +typedef int (STDCALL *mysql_real_query_t)(MYSQL *mysql, const char *q, + long unsigned int length); +typedef int (STDCALL *mysql_create_db_t)(MYSQL *mysql, const char *DB); +typedef int (STDCALL *mysql_drop_db_t)(MYSQL *mysql, const char *DB); +typedef int (STDCALL *mysql_shutdown_t)(MYSQL *mysql, mysql_enum_shutdown_level); +typedef int (STDCALL *mysql_dump_debug_info_t)(MYSQL *mysql); +typedef int (STDCALL *mysql_refresh_t)(MYSQL *mysql, + unsigned int refresh_options); +typedef int (STDCALL *mysql_kill_t)(MYSQL *mysql,unsigned long pid); +typedef int (STDCALL *mysql_ping_t)(MYSQL *mysql); +typedef const char * (STDCALL *mysql_stat_t)(MYSQL *mysql); +typedef const char * (STDCALL *mysql_get_server_info_t)(MYSQL *mysql); +typedef const char * (STDCALL *mysql_get_client_info_t)(void); +typedef const char * (STDCALL *mysql_get_host_info_t)(MYSQL *mysql); +typedef unsigned int (STDCALL *mysql_get_proto_info_t)(MYSQL *mysql); +typedef MYSQL_RES * (STDCALL *mysql_list_dbs_t)(MYSQL *mysql,const char *wild); +typedef MYSQL_RES * (STDCALL *mysql_list_tables_t)(MYSQL *mysql,const char *wild); +typedef MYSQL_RES * (STDCALL *mysql_list_fields_t)(MYSQL *mysql, const char *table, + const char *wild); +typedef MYSQL_RES * (STDCALL *mysql_list_processes_t)(MYSQL *mysql); +typedef MYSQL_RES * (STDCALL *mysql_store_result_t)(MYSQL *mysql); +typedef MYSQL_RES * (STDCALL *mysql_use_result_t)(MYSQL *mysql); +typedef int (STDCALL *mysql_options_t)(MYSQL *mysql,enum mysql_option option, + const void *arg); +typedef void (STDCALL *mysql_free_result_t)(MYSQL_RES *result); +typedef void (STDCALL *mysql_data_seek_t)(MYSQL_RES *result, + my_ulonglong offset); +typedef MYSQL_ROW_OFFSET (STDCALL *mysql_row_seek_t)(MYSQL_RES *result, MYSQL_ROW_OFFSET); +typedef MYSQL_FIELD_OFFSET (STDCALL *mysql_field_seek_t)(MYSQL_RES *result, + MYSQL_FIELD_OFFSET offset); +typedef MYSQL_ROW (STDCALL *mysql_fetch_row_t)(MYSQL_RES *result); +typedef unsigned long * (STDCALL *mysql_fetch_lengths_t)(MYSQL_RES *result); +typedef MYSQL_FIELD * (STDCALL *mysql_fetch_field_t)(MYSQL_RES *result); +typedef unsigned long (STDCALL *mysql_escape_string_t)(char *to,const char *from, + unsigned long from_length); +typedef unsigned long (STDCALL *mysql_real_escape_string_t)(MYSQL *mysql, + char *to,const char *from, + unsigned long length); +typedef void (STDCALL *mysql_debug_t)(const char *debug); +typedef char * (STDCALL *mysql_odbc_escape_string_t)(MYSQL *mysql, + char *to, + unsigned long to_length, + const char *from, + unsigned long from_length, + void *param, + char * + (*extend_buffer) + (void *, char *to, + unsigned long *length)); +typedef void (STDCALL *myodbc_remove_escape_t)(MYSQL *mysql,char *name); + +typedef my_bool (STDCALL *mysql_thread_init_t)(void); +typedef void (STDCALL *mysql_thread_end_t)(void); +typedef unsigned int (STDCALL *mysql_thread_safe_t)(void); + +//#define mysql_reload(mysql) mysql_refresh((mysql),REFRESH_GRANT) + +typedef int (STDCALL *mysql_server_init_t)(int argc, char **argv, char **groups); +typedef void (STDCALL *mysql_server_end_t)(void); + +typedef int (STDCALL *mysql_set_character_set_t)(MYSQL *mysql, const char *csname); + + +// MySQL statement API functions +typedef MYSQL_STMT * (STDCALL *mysql_stmt_init_t)(MYSQL *mysql); +typedef int (STDCALL *mysql_stmt_prepare_t)(MYSQL_STMT *stmt, const char *query, + unsigned long length); +typedef int (STDCALL *mysql_stmt_execute_t)(MYSQL_STMT *stmt); +typedef int (STDCALL *mysql_stmt_fetch_t)(MYSQL_STMT *stmt); +typedef int (STDCALL *mysql_stmt_fetch_column_t)(MYSQL_STMT *stmt, MYSQL_BIND *bind, + unsigned int column, + unsigned long offset); +typedef int (STDCALL *mysql_stmt_store_result_t)(MYSQL_STMT *stmt); +typedef unsigned long (STDCALL *mysql_stmt_param_count_t)(MYSQL_STMT * stmt); +typedef my_bool (STDCALL *mysql_stmt_attr_set_t)(MYSQL_STMT *stmt, + enum enum_stmt_attr_type attr_type, + const void *attr); +typedef my_bool (STDCALL *mysql_stmt_attr_get_t)(MYSQL_STMT *stmt, + enum enum_stmt_attr_type attr_type, + void *attr); +typedef my_bool (STDCALL *mysql_stmt_bind_param_t)(MYSQL_STMT * stmt, MYSQL_BIND * bnd); +typedef my_bool (STDCALL *mysql_stmt_bind_result_t)(MYSQL_STMT * stmt, MYSQL_BIND * bnd); +typedef my_bool (STDCALL *mysql_stmt_close_t)(MYSQL_STMT * stmt); +typedef my_bool (STDCALL *mysql_stmt_reset_t)(MYSQL_STMT * stmt); +typedef my_bool (STDCALL *mysql_stmt_free_result_t)(MYSQL_STMT *stmt); +typedef my_bool (STDCALL *mysql_stmt_send_long_data_t)(MYSQL_STMT *stmt, + unsigned int param_number, + const char *data, + unsigned long length); +typedef MYSQL_RES * (STDCALL *mysql_stmt_result_metadata_t)(MYSQL_STMT *stmt); +typedef MYSQL_RES * (STDCALL *mysql_stmt_param_metadata_t)(MYSQL_STMT *stmt); +typedef unsigned int (STDCALL *mysql_stmt_errno_t)(MYSQL_STMT * stmt); +typedef const char * (STDCALL *mysql_stmt_error_t)(MYSQL_STMT * stmt); +typedef const char * (STDCALL *mysql_stmt_sqlstate_t)(MYSQL_STMT * stmt); +typedef MYSQL_ROW_OFFSET (STDCALL *mysql_stmt_row_seek_t)(MYSQL_STMT *stmt, + MYSQL_ROW_OFFSET offset); +typedef MYSQL_ROW_OFFSET (STDCALL *mysql_stmt_row_tell_t)(MYSQL_STMT *stmt); +typedef void (STDCALL *mysql_stmt_data_seek_t)(MYSQL_STMT *stmt, my_ulonglong offset); +typedef my_ulonglong (STDCALL *mysql_stmt_num_rows_t)(MYSQL_STMT *stmt); +typedef my_ulonglong (STDCALL *mysql_stmt_affected_rows_t)(MYSQL_STMT *stmt); +typedef my_ulonglong (STDCALL *mysql_stmt_insert_id_t)(MYSQL_STMT *stmt); +typedef unsigned int (STDCALL *mysql_stmt_field_count_t)(MYSQL_STMT *stmt); + +typedef void (STDCALL *mysql_get_character_set_info_t)(MYSQL *mysql, + MY_CHARSET_INFO *charset); + +// API declarations +class SQLAPI_API myAPI : public saAPI +{ +public: + myAPI(); + + mysql_num_rows_t mysql_num_rows; + mysql_num_fields_t mysql_num_fields; + mysql_eof_t mysql_eof; + mysql_fetch_field_direct_t mysql_fetch_field_direct; + mysql_fetch_fields_t mysql_fetch_fields; + mysql_row_tell_t mysql_row_tell; + mysql_field_tell_t mysql_field_tell; + mysql_field_count_t mysql_field_count; + mysql_affected_rows_t mysql_affected_rows; + mysql_insert_id_t mysql_insert_id; + mysql_errno_t mysql_errno; + mysql_error_t mysql_error; + mysql_info_t mysql_info; + mysql_thread_id_t mysql_thread_id; + mysql_character_set_name_t mysql_character_set_name; + mysql_init_t mysql_init; + mysql_ssl_set_t mysql_ssl_set; + mysql_ssl_cipher_t mysql_ssl_cipher; + mysql_ssl_clear_t mysql_ssl_clear; + mysql_connect_t mysql_connect; + mysql_change_user_t mysql_change_user; + mysql_real_connect1_t mysql_real_connect1; + mysql_real_connect2_t mysql_real_connect2; + mysql_close_t mysql_close; + mysql_next_result_t mysql_next_result; + mysql_select_db_t mysql_select_db; + mysql_query_t mysql_query; + mysql_send_query_t mysql_send_query; + mysql_read_query_result_t mysql_read_query_result; + mysql_real_query_t mysql_real_query; + mysql_create_db_t mysql_create_db; + mysql_drop_db_t mysql_drop_db; + mysql_shutdown_t mysql_shutdown; + mysql_dump_debug_info_t mysql_dump_debug_info; + mysql_refresh_t mysql_refresh; + mysql_kill_t mysql_kill; + mysql_ping_t mysql_ping; + mysql_stat_t mysql_stat; + mysql_get_server_info_t mysql_get_server_info; + mysql_get_client_info_t mysql_get_client_info; + mysql_get_host_info_t mysql_get_host_info; + mysql_get_proto_info_t mysql_get_proto_info; + mysql_list_dbs_t mysql_list_dbs; + mysql_list_tables_t mysql_list_tables; + mysql_list_fields_t mysql_list_fields; + mysql_list_processes_t mysql_list_processes; + mysql_store_result_t mysql_store_result; + mysql_use_result_t mysql_use_result; + mysql_options_t mysql_options; + mysql_free_result_t mysql_free_result; + mysql_data_seek_t mysql_data_seek; + mysql_row_seek_t mysql_row_seek; + mysql_field_seek_t mysql_field_seek; + mysql_fetch_row_t mysql_fetch_row; + mysql_fetch_lengths_t mysql_fetch_lengths; + mysql_fetch_field_t mysql_fetch_field; + mysql_escape_string_t mysql_escape_string; + mysql_real_escape_string_t mysql_real_escape_string; + mysql_debug_t mysql_debug; + mysql_odbc_escape_string_t mysql_odbc_escape_string; + myodbc_remove_escape_t myodbc_remove_escape; + mysql_thread_init_t mysql_thread_init; + mysql_thread_end_t mysql_thread_end; + mysql_thread_safe_t mysql_thread_safe; + mysql_server_init_t mysql_server_init; + mysql_server_end_t mysql_server_end; + mysql_set_character_set_t mysql_set_character_set; + // MySQL statement API functions + mysql_stmt_init_t mysql_stmt_init; + mysql_stmt_prepare_t mysql_stmt_prepare; + mysql_stmt_execute_t mysql_stmt_execute; + mysql_stmt_fetch_t mysql_stmt_fetch; + mysql_stmt_fetch_column_t mysql_stmt_fetch_column; + mysql_stmt_store_result_t mysql_stmt_store_result; + mysql_stmt_param_count_t mysql_stmt_param_count; + mysql_stmt_attr_set_t mysql_stmt_attr_set; + mysql_stmt_attr_get_t mysql_stmt_attr_get; + mysql_stmt_bind_param_t mysql_stmt_bind_param; + mysql_stmt_bind_result_t mysql_stmt_bind_result; + mysql_stmt_close_t mysql_stmt_close; + mysql_stmt_reset_t mysql_stmt_reset; + mysql_stmt_free_result_t mysql_stmt_free_result; + mysql_stmt_send_long_data_t mysql_stmt_send_long_data; + mysql_stmt_result_metadata_t mysql_stmt_result_metadata; + mysql_stmt_param_metadata_t mysql_stmt_param_metadata; + mysql_stmt_errno_t mysql_stmt_errno; + mysql_stmt_error_t mysql_stmt_error; + mysql_stmt_sqlstate_t mysql_stmt_sqlstate; + mysql_stmt_row_seek_t mysql_stmt_row_seek; + mysql_stmt_row_tell_t mysql_stmt_row_tell; + mysql_stmt_data_seek_t mysql_stmt_data_seek; + mysql_stmt_num_rows_t mysql_stmt_num_rows; + mysql_stmt_affected_rows_t mysql_stmt_affected_rows; + mysql_stmt_insert_id_t mysql_stmt_insert_id; + mysql_stmt_field_count_t mysql_stmt_field_count; + + mysql_get_character_set_info_t mysql_get_character_set_info; +}; + +class SQLAPI_API myConnectionHandles : public saConnectionHandles +{ +public: + myConnectionHandles(); + + MYSQL *mysql; // MySQL connection struct +}; + +class SQLAPI_API myCommandHandles : public saCommandHandles +{ +public: + myCommandHandles(); + + MYSQL_RES *result; // MySQL result struct + MYSQL_STMT *stmt; // MySQL statement struct +}; + +extern myAPI g_myAPI; + +#endif // !defined(__MYAPI_H__) diff --git a/libodbc/include/mysql/errmsg.h b/libodbc/include/mysql/errmsg.h new file mode 100644 index 0000000000..31a7dac4da --- /dev/null +++ b/libodbc/include/mysql/errmsg.h @@ -0,0 +1,101 @@ +/* Copyright (C) 2000 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* Error messages for MySQL clients */ +/* (Error messages for the daemon are in sql/share/errmsg.txt) */ + +#ifdef __cplusplus +extern "C" { +#endif +void init_client_errs(void); +void finish_client_errs(void); +extern const char *client_errors[]; /* Error messages */ +#ifdef __cplusplus +} +#endif + +#define CR_MIN_ERROR 2000 /* For easier client code */ +#define CR_MAX_ERROR 2999 +#if !defined(ER) +#define ER(X) client_errors[(X)-CR_MIN_ERROR] +#endif +#define CLIENT_ERRMAP 2 /* Errormap used by my_error() */ + +/* Do not add error numbers before CR_ERROR_FIRST. */ +/* If necessary to add lower numbers, change CR_ERROR_FIRST accordingly. */ +#define CR_ERROR_FIRST 2000 /*Copy first error nr.*/ +#define CR_UNKNOWN_ERROR 2000 +#define CR_SOCKET_CREATE_ERROR 2001 +#define CR_CONNECTION_ERROR 2002 +#define CR_CONN_HOST_ERROR 2003 +#define CR_IPSOCK_ERROR 2004 +#define CR_UNKNOWN_HOST 2005 +#define CR_SERVER_GONE_ERROR 2006 +#define CR_VERSION_ERROR 2007 +#define CR_OUT_OF_MEMORY 2008 +#define CR_WRONG_HOST_INFO 2009 +#define CR_LOCALHOST_CONNECTION 2010 +#define CR_TCP_CONNECTION 2011 +#define CR_SERVER_HANDSHAKE_ERR 2012 +#define CR_SERVER_LOST 2013 +#define CR_COMMANDS_OUT_OF_SYNC 2014 +#define CR_NAMEDPIPE_CONNECTION 2015 +#define CR_NAMEDPIPEWAIT_ERROR 2016 +#define CR_NAMEDPIPEOPEN_ERROR 2017 +#define CR_NAMEDPIPESETSTATE_ERROR 2018 +#define CR_CANT_READ_CHARSET 2019 +#define CR_NET_PACKET_TOO_LARGE 2020 +#define CR_EMBEDDED_CONNECTION 2021 +#define CR_PROBE_SLAVE_STATUS 2022 +#define CR_PROBE_SLAVE_HOSTS 2023 +#define CR_PROBE_SLAVE_CONNECT 2024 +#define CR_PROBE_MASTER_CONNECT 2025 +#define CR_SSL_CONNECTION_ERROR 2026 +#define CR_MALFORMED_PACKET 2027 +#define CR_WRONG_LICENSE 2028 + +/* new 4.1 error codes */ +#define CR_NULL_POINTER 2029 +#define CR_NO_PREPARE_STMT 2030 +#define CR_PARAMS_NOT_BOUND 2031 +#define CR_DATA_TRUNCATED 2032 +#define CR_NO_PARAMETERS_EXISTS 2033 +#define CR_INVALID_PARAMETER_NO 2034 +#define CR_INVALID_BUFFER_USE 2035 +#define CR_UNSUPPORTED_PARAM_TYPE 2036 + +#define CR_SHARED_MEMORY_CONNECTION 2037 +#define CR_SHARED_MEMORY_CONNECT_REQUEST_ERROR 2038 +#define CR_SHARED_MEMORY_CONNECT_ANSWER_ERROR 2039 +#define CR_SHARED_MEMORY_CONNECT_FILE_MAP_ERROR 2040 +#define CR_SHARED_MEMORY_CONNECT_MAP_ERROR 2041 +#define CR_SHARED_MEMORY_FILE_MAP_ERROR 2042 +#define CR_SHARED_MEMORY_MAP_ERROR 2043 +#define CR_SHARED_MEMORY_EVENT_ERROR 2044 +#define CR_SHARED_MEMORY_CONNECT_ABANDONED_ERROR 2045 +#define CR_SHARED_MEMORY_CONNECT_SET_ERROR 2046 +#define CR_CONN_UNKNOW_PROTOCOL 2047 +#define CR_INVALID_CONN_HANDLE 2048 +#define CR_SECURE_AUTH 2049 +#define CR_FETCH_CANCELED 2050 +#define CR_NO_DATA 2051 +#define CR_NO_STMT_METADATA 2052 +#define CR_NO_RESULT_SET 2053 +#define CR_NOT_IMPLEMENTED 2054 +#define CR_SERVER_LOST_EXTENDED 2055 +#define CR_STMT_CLOSED 2056 +#define CR_ERROR_LAST /*Copy last error nr:*/ 2056 +/* Add error numbers before CR_ERROR_LAST and change it accordingly. */ + diff --git a/libodbc/include/mysql/my_alloc.h b/libodbc/include/mysql/my_alloc.h new file mode 100644 index 0000000000..0743587c58 --- /dev/null +++ b/libodbc/include/mysql/my_alloc.h @@ -0,0 +1,51 @@ +/* Copyright (C) 2000 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* + Data structures for mysys/my_alloc.c (root memory allocator) +*/ + +#ifndef _my_alloc_h +#define _my_alloc_h + +#define ALLOC_MAX_BLOCK_TO_DROP 4096 +#define ALLOC_MAX_BLOCK_USAGE_BEFORE_DROP 10 + +typedef struct st_used_mem +{ /* struct for once_alloc (block) */ + struct st_used_mem *next; /* Next block in use */ + unsigned int left; /* memory left in block */ + unsigned int size; /* size of block */ +} USED_MEM; + + +typedef struct st_mem_root +{ + USED_MEM *free; /* blocks with free memory in it */ + USED_MEM *used; /* blocks almost without free memory */ + USED_MEM *pre_alloc; /* preallocated block */ + /* if block have less memory it will be put in 'used' list */ + size_t min_malloc; + size_t block_size; /* initial block size */ + unsigned int block_num; /* allocated blocks counter */ + /* + first free block in queue test counter (if it exceed + MAX_BLOCK_USAGE_BEFORE_DROP block will be dropped in 'used' list) + */ + unsigned int first_block_usage; + + void (*error_handler)(void); +} MEM_ROOT; +#endif diff --git a/libodbc/include/mysql/my_list.h b/libodbc/include/mysql/my_list.h new file mode 100644 index 0000000000..78269a1a3e --- /dev/null +++ b/libodbc/include/mysql/my_list.h @@ -0,0 +1,45 @@ +/* Copyright (C) 2000 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#ifndef _list_h_ +#define _list_h_ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct st_list { + struct st_list *prev,*next; + void *data; +} LIST; + +typedef int (*list_walk_action)(void *,void *); + +extern LIST *list_add(LIST *root,LIST *element); +extern LIST *list_delete(LIST *root,LIST *element); +extern LIST *list_cons(void *data,LIST *root); +extern LIST *list_reverse(LIST *root); +extern void list_free(LIST *root,unsigned int free_data); +extern unsigned int list_length(LIST *); +extern int list_walk(LIST *,list_walk_action action,unsigned char * argument); + +#define list_rest(a) ((a)->next) +#define list_push(a,b) (a)=list_cons((b),(a)) +#define list_pop(A) {LIST *old=(A); (A)=list_delete(old,old) ; my_free((unsigned char *) old,MYF(MY_FAE)); } + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libodbc/include/mysql/mysql.h b/libodbc/include/mysql/mysql.h new file mode 100644 index 0000000000..6baae2eb21 --- /dev/null +++ b/libodbc/include/mysql/mysql.h @@ -0,0 +1,877 @@ +/* Copyright (C) 2000-2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* + This file defines the client API to MySQL and also the ABI of the + dynamically linked libmysqlclient. + + The ABI should never be changed in a released product of MySQL + thus you need to take great care when changing the file. In case + the file is changed so the ABI is broken, you must also + update the SHAREDLIB_MAJOR_VERSION in configure.in . + +*/ + +#ifndef _mysql_h +#define _mysql_h + +#ifdef _AIX /* large-file support will break without this */ +#include +#endif + +#ifdef __CYGWIN__ /* CYGWIN implements a UNIX API */ +#undef WIN +#undef _WIN +#undef _WIN32 +#undef _WIN64 +#undef __WIN__ +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _global_h /* If not standard header */ +#include +#ifdef __LCC__ +#include /* For windows */ +#endif +typedef char my_bool; +#if (defined(_WIN32) || defined(_WIN64)) && !defined(__WIN__) +#define __WIN__ +#endif +#if !defined(__WIN__) +#define STDCALL +#else +#define STDCALL __stdcall +#endif + +#ifndef my_socket_defined +#ifdef __WIN__ +#define my_socket SOCKET +#else +typedef int my_socket; +#endif /* __WIN__ */ +#endif /* my_socket_defined */ +#endif /* _global_h */ + +#include "mysql_version.h" +#include "mysql_com.h" +#include "mysql_time.h" + +#include "my_list.h" /* for LISTs used in 'MYSQL' and 'MYSQL_STMT' */ + +extern unsigned int mysql_port; +extern char *mysql_unix_port; + +#define CLIENT_NET_READ_TIMEOUT 365*24*3600 /* Timeout on read */ +#define CLIENT_NET_WRITE_TIMEOUT 365*24*3600 /* Timeout on write */ + +#ifdef __NETWARE__ +#pragma pack(push, 8) /* 8 byte alignment */ +#endif + +#define IS_PRI_KEY(n) ((n) & PRI_KEY_FLAG) +#define IS_NOT_NULL(n) ((n) & NOT_NULL_FLAG) +#define IS_BLOB(n) ((n) & BLOB_FLAG) +#define IS_NUM(t) ((t) <= MYSQL_TYPE_INT24 || (t) == MYSQL_TYPE_YEAR || (t) == MYSQL_TYPE_NEWDECIMAL) +#define IS_NUM_FIELD(f) ((f)->flags & NUM_FLAG) +#define INTERNAL_NUM_FIELD(f) (((f)->type <= MYSQL_TYPE_INT24 && ((f)->type != MYSQL_TYPE_TIMESTAMP || (f)->length == 14 || (f)->length == 8)) || (f)->type == MYSQL_TYPE_YEAR) +#define IS_LONGDATA(t) ((t) >= MYSQL_TYPE_TINY_BLOB && (t) <= MYSQL_TYPE_STRING) + + +typedef struct st_mysql_field { + char *name; /* Name of column */ + char *org_name; /* Original column name, if an alias */ + char *table; /* Table of column if column was a field */ + char *org_table; /* Org table name, if table was an alias */ + char *db; /* Database for table */ + char *catalog; /* Catalog for table */ + char *def; /* Default value (set by mysql_list_fields) */ + unsigned long length; /* Width of column (create length) */ + unsigned long max_length; /* Max width for selected set */ + unsigned int name_length; + unsigned int org_name_length; + unsigned int table_length; + unsigned int org_table_length; + unsigned int db_length; + unsigned int catalog_length; + unsigned int def_length; + unsigned int flags; /* Div flags */ + unsigned int decimals; /* Number of decimals in field */ + unsigned int charsetnr; /* Character set */ + enum enum_field_types type; /* Type of field. See mysql_com.h for types */ + void *extension; +} MYSQL_FIELD; + +typedef char **MYSQL_ROW; /* return data as array of strings */ +typedef unsigned int MYSQL_FIELD_OFFSET; /* offset to current field */ + +#ifndef _global_h +#if defined(NO_CLIENT_LONG_LONG) +typedef unsigned long my_ulonglong; +#elif defined (__WIN__) +typedef unsigned __int64 my_ulonglong; +#else +typedef unsigned long long my_ulonglong; +#endif +#endif + +#include "typelib.h" + +#define MYSQL_COUNT_ERROR (~(my_ulonglong) 0) + +/* backward compatibility define - to be removed eventually */ +#define ER_WARN_DATA_TRUNCATED WARN_DATA_TRUNCATED + +typedef struct st_mysql_rows { + struct st_mysql_rows *next; /* list of rows */ + MYSQL_ROW data; + unsigned long length; +} MYSQL_ROWS; + +typedef MYSQL_ROWS *MYSQL_ROW_OFFSET; /* offset to current row */ + +#include "my_alloc.h" + +typedef struct embedded_query_result EMBEDDED_QUERY_RESULT; +typedef struct st_mysql_data { + MYSQL_ROWS *data; + struct embedded_query_result *embedded_info; + MEM_ROOT alloc; + my_ulonglong rows; + unsigned int fields; + /* extra info for embedded library */ + void *extension; +} MYSQL_DATA; + +enum mysql_option +{ + MYSQL_OPT_CONNECT_TIMEOUT, MYSQL_OPT_COMPRESS, MYSQL_OPT_NAMED_PIPE, + MYSQL_INIT_COMMAND, MYSQL_READ_DEFAULT_FILE, MYSQL_READ_DEFAULT_GROUP, + MYSQL_SET_CHARSET_DIR, MYSQL_SET_CHARSET_NAME, MYSQL_OPT_LOCAL_INFILE, + MYSQL_OPT_PROTOCOL, MYSQL_SHARED_MEMORY_BASE_NAME, MYSQL_OPT_READ_TIMEOUT, + MYSQL_OPT_WRITE_TIMEOUT, MYSQL_OPT_USE_RESULT, + MYSQL_OPT_USE_REMOTE_CONNECTION, MYSQL_OPT_USE_EMBEDDED_CONNECTION, + MYSQL_OPT_GUESS_CONNECTION, MYSQL_SET_CLIENT_IP, MYSQL_SECURE_AUTH, + MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_RECONNECT, + MYSQL_OPT_SSL_VERIFY_SERVER_CERT +}; + +struct st_mysql_options { + unsigned int connect_timeout, read_timeout, write_timeout; + unsigned int port, protocol; + unsigned long client_flag; + char *host,*user,*password,*unix_socket,*db; + struct st_dynamic_array *init_commands; + char *my_cnf_file,*my_cnf_group, *charset_dir, *charset_name; + char *ssl_key; /* PEM key file */ + char *ssl_cert; /* PEM cert file */ + char *ssl_ca; /* PEM CA file */ + char *ssl_capath; /* PEM directory of CA-s? */ + char *ssl_cipher; /* cipher to use */ + char *shared_memory_base_name; + unsigned long max_allowed_packet; + my_bool use_ssl; /* if to use SSL or not */ + my_bool compress,named_pipe; + /* + On connect, find out the replication role of the server, and + establish connections to all the peers + */ + my_bool rpl_probe; + /* + Each call to mysql_real_query() will parse it to tell if it is a read + or a write, and direct it to the slave or the master + */ + my_bool rpl_parse; + /* + If set, never read from a master, only from slave, when doing + a read that is replication-aware + */ + my_bool no_master_reads; +#if !defined(CHECK_EMBEDDED_DIFFERENCES) || defined(EMBEDDED_LIBRARY) + my_bool separate_thread; +#endif + enum mysql_option methods_to_use; + char *client_ip; + /* Refuse client connecting to server if it uses old (pre-4.1.1) protocol */ + my_bool secure_auth; + /* 0 - never report, 1 - always report (default) */ + my_bool report_data_truncation; + + /* function pointers for local infile support */ + int (*local_infile_init)(void **, const char *, void *); + int (*local_infile_read)(void *, char *, unsigned int); + void (*local_infile_end)(void *); + int (*local_infile_error)(void *, char *, unsigned int); + void *local_infile_userdata; + void *extension; +}; + +enum mysql_status +{ + MYSQL_STATUS_READY,MYSQL_STATUS_GET_RESULT,MYSQL_STATUS_USE_RESULT +}; + +enum mysql_protocol_type +{ + MYSQL_PROTOCOL_DEFAULT, MYSQL_PROTOCOL_TCP, MYSQL_PROTOCOL_SOCKET, + MYSQL_PROTOCOL_PIPE, MYSQL_PROTOCOL_MEMORY +}; +/* + There are three types of queries - the ones that have to go to + the master, the ones that go to a slave, and the adminstrative + type which must happen on the pivot connectioin +*/ +enum mysql_rpl_type +{ + MYSQL_RPL_MASTER, MYSQL_RPL_SLAVE, MYSQL_RPL_ADMIN +}; + +typedef struct character_set +{ + unsigned int number; /* character set number */ + unsigned int state; /* character set state */ + const char *csname; /* collation name */ + const char *name; /* character set name */ + const char *comment; /* comment */ + const char *dir; /* character set directory */ + unsigned int mbminlen; /* min. length for multibyte strings */ + unsigned int mbmaxlen; /* max. length for multibyte strings */ +} MY_CHARSET_INFO; + +struct st_mysql_methods; +struct st_mysql_stmt; + +typedef struct st_mysql +{ + NET net; /* Communication parameters */ + unsigned char *connector_fd; /* ConnectorFd for SSL */ + char *host,*user,*passwd,*unix_socket,*server_version,*host_info; + char *info, *db; + struct charset_info_st *charset; + MYSQL_FIELD *fields; + MEM_ROOT field_alloc; + my_ulonglong affected_rows; + my_ulonglong insert_id; /* id if insert on table with NEXTNR */ + my_ulonglong extra_info; /* Not used */ + unsigned long thread_id; /* Id for connection in server */ + unsigned long packet_length; + unsigned int port; + unsigned long client_flag,server_capabilities; + unsigned int protocol_version; + unsigned int field_count; + unsigned int server_status; + unsigned int server_language; + unsigned int warning_count; + struct st_mysql_options options; + enum mysql_status status; + my_bool free_me; /* If free in mysql_close */ + my_bool reconnect; /* set to 1 if automatic reconnect */ + + /* session-wide random string */ + char scramble[SCRAMBLE_LENGTH+1]; + + /* + Set if this is the original connection, not a master or a slave we have + added though mysql_rpl_probe() or mysql_set_master()/ mysql_add_slave() + */ + my_bool rpl_pivot; + /* + Pointers to the master, and the next slave connections, points to + itself if lone connection. + */ + struct st_mysql* master, *next_slave; + + struct st_mysql* last_used_slave; /* needed for round-robin slave pick */ + /* needed for send/read/store/use result to work correctly with replication */ + struct st_mysql* last_used_con; + + LIST *stmts; /* list of all statements */ + const struct st_mysql_methods *methods; + void *thd; + /* + Points to boolean flag in MYSQL_RES or MYSQL_STMT. We set this flag + from mysql_stmt_close if close had to cancel result set of this object. + */ + my_bool *unbuffered_fetch_owner; + /* needed for embedded server - no net buffer to store the 'info' */ + char *info_buffer; + void *extension; +} MYSQL; + + +typedef struct st_mysql_res { + my_ulonglong row_count; + MYSQL_FIELD *fields; + MYSQL_DATA *data; + MYSQL_ROWS *data_cursor; + unsigned long *lengths; /* column lengths of current row */ + MYSQL *handle; /* for unbuffered reads */ + const struct st_mysql_methods *methods; + MYSQL_ROW row; /* If unbuffered read */ + MYSQL_ROW current_row; /* buffer to current row */ + MEM_ROOT field_alloc; + unsigned int field_count, current_field; + my_bool eof; /* Used by mysql_fetch_row */ + /* mysql_stmt_close() had to cancel this result */ + my_bool unbuffered_fetch_cancelled; + void *extension; +} MYSQL_RES; + +#define MAX_MYSQL_MANAGER_ERR 256 +#define MAX_MYSQL_MANAGER_MSG 256 + +#define MANAGER_OK 200 +#define MANAGER_INFO 250 +#define MANAGER_ACCESS 401 +#define MANAGER_CLIENT_ERR 450 +#define MANAGER_INTERNAL_ERR 500 + +#if !defined(MYSQL_SERVER) && !defined(MYSQL_CLIENT) +#define MYSQL_CLIENT +#endif + + +typedef struct st_mysql_manager +{ + NET net; + char *host, *user, *passwd; + char *net_buf, *net_buf_pos, *net_data_end; + unsigned int port; + int cmd_status; + int last_errno; + int net_buf_size; + my_bool free_me; + my_bool eof; + char last_error[MAX_MYSQL_MANAGER_ERR]; + void *extension; +} MYSQL_MANAGER; + +typedef struct st_mysql_parameters +{ + unsigned long *p_max_allowed_packet; + unsigned long *p_net_buffer_length; + void *extension; +} MYSQL_PARAMETERS; + +#if !defined(MYSQL_SERVER) && !defined(EMBEDDED_LIBRARY) +#define max_allowed_packet (*mysql_get_parameters()->p_max_allowed_packet) +#define net_buffer_length (*mysql_get_parameters()->p_net_buffer_length) +#endif + +/* + Set up and bring down the server; to ensure that applications will + work when linked against either the standard client library or the + embedded server library, these functions should be called. +*/ +int STDCALL mysql_server_init(int argc, char **argv, char **groups); +void STDCALL mysql_server_end(void); + +/* + mysql_server_init/end need to be called when using libmysqld or + libmysqlclient (exactly, mysql_server_init() is called by mysql_init() so + you don't need to call it explicitely; but you need to call + mysql_server_end() to free memory). The names are a bit misleading + (mysql_SERVER* to be used when using libmysqlCLIENT). So we add more general + names which suit well whether you're using libmysqld or libmysqlclient. We + intend to promote these aliases over the mysql_server* ones. +*/ +#define mysql_library_init mysql_server_init +#define mysql_library_end mysql_server_end + +MYSQL_PARAMETERS *STDCALL mysql_get_parameters(void); + +/* + Set up and bring down a thread; these function should be called + for each thread in an application which opens at least one MySQL + connection. All uses of the connection(s) should be between these + function calls. +*/ +my_bool STDCALL mysql_thread_init(void); +void STDCALL mysql_thread_end(void); + +/* + Functions to get information from the MYSQL and MYSQL_RES structures + Should definitely be used if one uses shared libraries. +*/ + +my_ulonglong STDCALL mysql_num_rows(MYSQL_RES *res); +unsigned int STDCALL mysql_num_fields(MYSQL_RES *res); +my_bool STDCALL mysql_eof(MYSQL_RES *res); +MYSQL_FIELD *STDCALL mysql_fetch_field_direct(MYSQL_RES *res, + unsigned int fieldnr); +MYSQL_FIELD * STDCALL mysql_fetch_fields(MYSQL_RES *res); +MYSQL_ROW_OFFSET STDCALL mysql_row_tell(MYSQL_RES *res); +MYSQL_FIELD_OFFSET STDCALL mysql_field_tell(MYSQL_RES *res); + +unsigned int STDCALL mysql_field_count(MYSQL *mysql); +my_ulonglong STDCALL mysql_affected_rows(MYSQL *mysql); +my_ulonglong STDCALL mysql_insert_id(MYSQL *mysql); +unsigned int STDCALL mysql_errno(MYSQL *mysql); +const char * STDCALL mysql_error(MYSQL *mysql); +const char *STDCALL mysql_sqlstate(MYSQL *mysql); +unsigned int STDCALL mysql_warning_count(MYSQL *mysql); +const char * STDCALL mysql_info(MYSQL *mysql); +unsigned long STDCALL mysql_thread_id(MYSQL *mysql); +const char * STDCALL mysql_character_set_name(MYSQL *mysql); +int STDCALL mysql_set_character_set(MYSQL *mysql, const char *csname); + +MYSQL * STDCALL mysql_init(MYSQL *mysql); +my_bool STDCALL mysql_ssl_set(MYSQL *mysql, const char *key, + const char *cert, const char *ca, + const char *capath, const char *cipher); +const char * STDCALL mysql_get_ssl_cipher(MYSQL *mysql); +my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user, + const char *passwd, const char *db); +MYSQL * STDCALL mysql_real_connect(MYSQL *mysql, const char *host, + const char *user, + const char *passwd, + const char *db, + unsigned int port, + const char *unix_socket, + unsigned long clientflag); +int STDCALL mysql_select_db(MYSQL *mysql, const char *db); +int STDCALL mysql_query(MYSQL *mysql, const char *q); +int STDCALL mysql_send_query(MYSQL *mysql, const char *q, + unsigned long length); +int STDCALL mysql_real_query(MYSQL *mysql, const char *q, + unsigned long length); +MYSQL_RES * STDCALL mysql_store_result(MYSQL *mysql); +MYSQL_RES * STDCALL mysql_use_result(MYSQL *mysql); + +/* perform query on master */ +my_bool STDCALL mysql_master_query(MYSQL *mysql, const char *q, + unsigned long length); +my_bool STDCALL mysql_master_send_query(MYSQL *mysql, const char *q, + unsigned long length); +/* perform query on slave */ +my_bool STDCALL mysql_slave_query(MYSQL *mysql, const char *q, + unsigned long length); +my_bool STDCALL mysql_slave_send_query(MYSQL *mysql, const char *q, + unsigned long length); +void STDCALL mysql_get_character_set_info(MYSQL *mysql, + MY_CHARSET_INFO *charset); + +/* local infile support */ + +#define LOCAL_INFILE_ERROR_LEN 512 + +void +mysql_set_local_infile_handler(MYSQL *mysql, + int (*local_infile_init)(void **, const char *, + void *), + int (*local_infile_read)(void *, char *, + unsigned int), + void (*local_infile_end)(void *), + int (*local_infile_error)(void *, char*, + unsigned int), + void *); + +void +mysql_set_local_infile_default(MYSQL *mysql); + + +/* + enable/disable parsing of all queries to decide if they go on master or + slave +*/ +void STDCALL mysql_enable_rpl_parse(MYSQL* mysql); +void STDCALL mysql_disable_rpl_parse(MYSQL* mysql); +/* get the value of the parse flag */ +int STDCALL mysql_rpl_parse_enabled(MYSQL* mysql); + +/* enable/disable reads from master */ +void STDCALL mysql_enable_reads_from_master(MYSQL* mysql); +void STDCALL mysql_disable_reads_from_master(MYSQL* mysql); +/* get the value of the master read flag */ +my_bool STDCALL mysql_reads_from_master_enabled(MYSQL* mysql); + +enum mysql_rpl_type STDCALL mysql_rpl_query_type(const char* q, int len); + +/* discover the master and its slaves */ +my_bool STDCALL mysql_rpl_probe(MYSQL* mysql); + +/* set the master, close/free the old one, if it is not a pivot */ +int STDCALL mysql_set_master(MYSQL* mysql, const char* host, + unsigned int port, + const char* user, + const char* passwd); +int STDCALL mysql_add_slave(MYSQL* mysql, const char* host, + unsigned int port, + const char* user, + const char* passwd); + +int STDCALL mysql_shutdown(MYSQL *mysql, + enum mysql_enum_shutdown_level + shutdown_level); +int STDCALL mysql_dump_debug_info(MYSQL *mysql); +int STDCALL mysql_refresh(MYSQL *mysql, + unsigned int refresh_options); +int STDCALL mysql_kill(MYSQL *mysql,unsigned long pid); +int STDCALL mysql_set_server_option(MYSQL *mysql, + enum enum_mysql_set_option + option); +int STDCALL mysql_ping(MYSQL *mysql); +const char * STDCALL mysql_stat(MYSQL *mysql); +const char * STDCALL mysql_get_server_info(MYSQL *mysql); +const char * STDCALL mysql_get_client_info(void); +unsigned long STDCALL mysql_get_client_version(void); +const char * STDCALL mysql_get_host_info(MYSQL *mysql); +unsigned long STDCALL mysql_get_server_version(MYSQL *mysql); +unsigned int STDCALL mysql_get_proto_info(MYSQL *mysql); +MYSQL_RES * STDCALL mysql_list_dbs(MYSQL *mysql,const char *wild); +MYSQL_RES * STDCALL mysql_list_tables(MYSQL *mysql,const char *wild); +MYSQL_RES * STDCALL mysql_list_processes(MYSQL *mysql); +int STDCALL mysql_options(MYSQL *mysql,enum mysql_option option, + const void *arg); +void STDCALL mysql_free_result(MYSQL_RES *result); +void STDCALL mysql_data_seek(MYSQL_RES *result, + my_ulonglong offset); +MYSQL_ROW_OFFSET STDCALL mysql_row_seek(MYSQL_RES *result, + MYSQL_ROW_OFFSET offset); +MYSQL_FIELD_OFFSET STDCALL mysql_field_seek(MYSQL_RES *result, + MYSQL_FIELD_OFFSET offset); +MYSQL_ROW STDCALL mysql_fetch_row(MYSQL_RES *result); +unsigned long * STDCALL mysql_fetch_lengths(MYSQL_RES *result); +MYSQL_FIELD * STDCALL mysql_fetch_field(MYSQL_RES *result); +MYSQL_RES * STDCALL mysql_list_fields(MYSQL *mysql, const char *table, + const char *wild); +unsigned long STDCALL mysql_escape_string(char *to,const char *from, + unsigned long from_length); +unsigned long STDCALL mysql_hex_string(char *to,const char *from, + unsigned long from_length); +unsigned long STDCALL mysql_real_escape_string(MYSQL *mysql, + char *to,const char *from, + unsigned long length); +void STDCALL mysql_debug(const char *debug); +char * STDCALL mysql_odbc_escape_string(MYSQL *mysql, + char *to, + unsigned long to_length, + const char *from, + unsigned long from_length, + void *param, + char * + (*extend_buffer) + (void *, char *to, + unsigned long *length)); +void STDCALL myodbc_remove_escape(MYSQL *mysql,char *name); +unsigned int STDCALL mysql_thread_safe(void); +my_bool STDCALL mysql_embedded(void); +MYSQL_MANAGER* STDCALL mysql_manager_init(MYSQL_MANAGER* con); +MYSQL_MANAGER* STDCALL mysql_manager_connect(MYSQL_MANAGER* con, + const char* host, + const char* user, + const char* passwd, + unsigned int port); +void STDCALL mysql_manager_close(MYSQL_MANAGER* con); +int STDCALL mysql_manager_command(MYSQL_MANAGER* con, + const char* cmd, int cmd_len); +int STDCALL mysql_manager_fetch_line(MYSQL_MANAGER* con, + char* res_buf, + int res_buf_size); +my_bool STDCALL mysql_read_query_result(MYSQL *mysql); + + +/* + The following definitions are added for the enhanced + client-server protocol +*/ + +/* statement state */ +enum enum_mysql_stmt_state +{ + MYSQL_STMT_INIT_DONE= 1, MYSQL_STMT_PREPARE_DONE, MYSQL_STMT_EXECUTE_DONE, + MYSQL_STMT_FETCH_DONE +}; + + +/* + This structure is used to define bind information, and + internally by the client library. + Public members with their descriptions are listed below + (conventionally `On input' refers to the binds given to + mysql_stmt_bind_param, `On output' refers to the binds given + to mysql_stmt_bind_result): + + buffer_type - One of the MYSQL_* types, used to describe + the host language type of buffer. + On output: if column type is different from + buffer_type, column value is automatically converted + to buffer_type before it is stored in the buffer. + buffer - On input: points to the buffer with input data. + On output: points to the buffer capable to store + output data. + The type of memory pointed by buffer must correspond + to buffer_type. See the correspondence table in + the comment to mysql_stmt_bind_param. + + The two above members are mandatory for any kind of bind. + + buffer_length - the length of the buffer. You don't have to set + it for any fixed length buffer: float, double, + int, etc. It must be set however for variable-length + types, such as BLOBs or STRINGs. + + length - On input: in case when lengths of input values + are different for each execute, you can set this to + point at a variable containining value length. This + way the value length can be different in each execute. + If length is not NULL, buffer_length is not used. + Note, length can even point at buffer_length if + you keep bind structures around while fetching: + this way you can change buffer_length before + each execution, everything will work ok. + On output: if length is set, mysql_stmt_fetch will + write column length into it. + + is_null - On input: points to a boolean variable that should + be set to TRUE for NULL values. + This member is useful only if your data may be + NULL in some but not all cases. + If your data is never NULL, is_null should be set to 0. + If your data is always NULL, set buffer_type + to MYSQL_TYPE_NULL, and is_null will not be used. + + is_unsigned - On input: used to signify that values provided for one + of numeric types are unsigned. + On output describes signedness of the output buffer. + If, taking into account is_unsigned flag, column data + is out of range of the output buffer, data for this column + is regarded truncated. Note that this has no correspondence + to the sign of result set column, if you need to find it out + use mysql_stmt_result_metadata. + error - where to write a truncation error if it is present. + possible error value is: + 0 no truncation + 1 value is out of range or buffer is too small + + Please note that MYSQL_BIND also has internals members. +*/ + +typedef struct st_mysql_bind +{ + unsigned long *length; /* output length pointer */ + my_bool *is_null; /* Pointer to null indicator */ + void *buffer; /* buffer to get/put data */ + /* set this if you want to track data truncations happened during fetch */ + my_bool *error; + unsigned char *row_ptr; /* for the current data position */ + void (*store_param_func)(NET *net, struct st_mysql_bind *param); + void (*fetch_result)(struct st_mysql_bind *, MYSQL_FIELD *, + unsigned char **row); + void (*skip_result)(struct st_mysql_bind *, MYSQL_FIELD *, + unsigned char **row); + /* output buffer length, must be set when fetching str/binary */ + unsigned long buffer_length; + unsigned long offset; /* offset position for char/binary fetch */ + unsigned long length_value; /* Used if length is 0 */ + unsigned int param_number; /* For null count and error messages */ + unsigned int pack_length; /* Internal length for packed data */ + enum enum_field_types buffer_type; /* buffer type */ + my_bool error_value; /* used if error is 0 */ + my_bool is_unsigned; /* set if integer type is unsigned */ + my_bool long_data_used; /* If used with mysql_send_long_data */ + my_bool is_null_value; /* Used if is_null is 0 */ + void *extension; +} MYSQL_BIND; + + +/* statement handler */ +typedef struct st_mysql_stmt +{ + MEM_ROOT mem_root; /* root allocations */ + LIST list; /* list to keep track of all stmts */ + MYSQL *mysql; /* connection handle */ + MYSQL_BIND *params; /* input parameters */ + MYSQL_BIND *bind; /* output parameters */ + MYSQL_FIELD *fields; /* result set metadata */ + MYSQL_DATA result; /* cached result set */ + MYSQL_ROWS *data_cursor; /* current row in cached result */ + /* + mysql_stmt_fetch() calls this function to fetch one row (it's different + for buffered, unbuffered and cursor fetch). + */ + int (*read_row_func)(struct st_mysql_stmt *stmt, + unsigned char **row); + /* copy of mysql->affected_rows after statement execution */ + my_ulonglong affected_rows; + my_ulonglong insert_id; /* copy of mysql->insert_id */ + unsigned long stmt_id; /* Id for prepared statement */ + unsigned long flags; /* i.e. type of cursor to open */ + unsigned long prefetch_rows; /* number of rows per one COM_FETCH */ + /* + Copied from mysql->server_status after execute/fetch to know + server-side cursor status for this statement. + */ + unsigned int server_status; + unsigned int last_errno; /* error code */ + unsigned int param_count; /* input parameter count */ + unsigned int field_count; /* number of columns in result set */ + enum enum_mysql_stmt_state state; /* statement state */ + char last_error[MYSQL_ERRMSG_SIZE]; /* error message */ + char sqlstate[SQLSTATE_LENGTH+1]; + /* Types of input parameters should be sent to server */ + my_bool send_types_to_server; + my_bool bind_param_done; /* input buffers were supplied */ + unsigned char bind_result_done; /* output buffers were supplied */ + /* mysql_stmt_close() had to cancel this result */ + my_bool unbuffered_fetch_cancelled; + /* + Is set to true if we need to calculate field->max_length for + metadata fields when doing mysql_stmt_store_result. + */ + my_bool update_max_length; + void *extension; +} MYSQL_STMT; + +enum enum_stmt_attr_type +{ + /* + When doing mysql_stmt_store_result calculate max_length attribute + of statement metadata. This is to be consistent with the old API, + where this was done automatically. + In the new API we do that only by request because it slows down + mysql_stmt_store_result sufficiently. + */ + STMT_ATTR_UPDATE_MAX_LENGTH, + /* + unsigned long with combination of cursor flags (read only, for update, + etc) + */ + STMT_ATTR_CURSOR_TYPE, + /* + Amount of rows to retrieve from server per one fetch if using cursors. + Accepts unsigned long attribute in the range 1 - ulong_max + */ + STMT_ATTR_PREFETCH_ROWS +}; + + +typedef struct st_mysql_methods +{ + my_bool (*read_query_result)(MYSQL *mysql); + my_bool (*advanced_command)(MYSQL *mysql, + enum enum_server_command command, + const unsigned char *header, + unsigned long header_length, + const unsigned char *arg, + unsigned long arg_length, + my_bool skip_check, + MYSQL_STMT *stmt); + MYSQL_DATA *(*read_rows)(MYSQL *mysql,MYSQL_FIELD *mysql_fields, + unsigned int fields); + MYSQL_RES * (*use_result)(MYSQL *mysql); + void (*fetch_lengths)(unsigned long *to, + MYSQL_ROW column, unsigned int field_count); + void (*flush_use_result)(MYSQL *mysql); +#if !defined(MYSQL_SERVER) || defined(EMBEDDED_LIBRARY) + MYSQL_FIELD * (*list_fields)(MYSQL *mysql); + my_bool (*read_prepare_result)(MYSQL *mysql, MYSQL_STMT *stmt); + int (*stmt_execute)(MYSQL_STMT *stmt); + int (*read_binary_rows)(MYSQL_STMT *stmt); + int (*unbuffered_fetch)(MYSQL *mysql, char **row); + void (*free_embedded_thd)(MYSQL *mysql); + const char *(*read_statistics)(MYSQL *mysql); + my_bool (*next_result)(MYSQL *mysql); + int (*read_change_user_result)(MYSQL *mysql, char *buff, const char *passwd); + int (*read_rows_from_cursor)(MYSQL_STMT *stmt); +#endif +} MYSQL_METHODS; + + +MYSQL_STMT * STDCALL mysql_stmt_init(MYSQL *mysql); +int STDCALL mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query, + unsigned long length); +int STDCALL mysql_stmt_execute(MYSQL_STMT *stmt); +int STDCALL mysql_stmt_fetch(MYSQL_STMT *stmt); +int STDCALL mysql_stmt_fetch_column(MYSQL_STMT *stmt, MYSQL_BIND *bind_arg, + unsigned int column, + unsigned long offset); +int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt); +unsigned long STDCALL mysql_stmt_param_count(MYSQL_STMT * stmt); +my_bool STDCALL mysql_stmt_attr_set(MYSQL_STMT *stmt, + enum enum_stmt_attr_type attr_type, + const void *attr); +my_bool STDCALL mysql_stmt_attr_get(MYSQL_STMT *stmt, + enum enum_stmt_attr_type attr_type, + void *attr); +my_bool STDCALL mysql_stmt_bind_param(MYSQL_STMT * stmt, MYSQL_BIND * bnd); +my_bool STDCALL mysql_stmt_bind_result(MYSQL_STMT * stmt, MYSQL_BIND * bnd); +my_bool STDCALL mysql_stmt_close(MYSQL_STMT * stmt); +my_bool STDCALL mysql_stmt_reset(MYSQL_STMT * stmt); +my_bool STDCALL mysql_stmt_free_result(MYSQL_STMT *stmt); +my_bool STDCALL mysql_stmt_send_long_data(MYSQL_STMT *stmt, + unsigned int param_number, + const char *data, + unsigned long length); +MYSQL_RES *STDCALL mysql_stmt_result_metadata(MYSQL_STMT *stmt); +MYSQL_RES *STDCALL mysql_stmt_param_metadata(MYSQL_STMT *stmt); +unsigned int STDCALL mysql_stmt_errno(MYSQL_STMT * stmt); +const char *STDCALL mysql_stmt_error(MYSQL_STMT * stmt); +const char *STDCALL mysql_stmt_sqlstate(MYSQL_STMT * stmt); +MYSQL_ROW_OFFSET STDCALL mysql_stmt_row_seek(MYSQL_STMT *stmt, + MYSQL_ROW_OFFSET offset); +MYSQL_ROW_OFFSET STDCALL mysql_stmt_row_tell(MYSQL_STMT *stmt); +void STDCALL mysql_stmt_data_seek(MYSQL_STMT *stmt, my_ulonglong offset); +my_ulonglong STDCALL mysql_stmt_num_rows(MYSQL_STMT *stmt); +my_ulonglong STDCALL mysql_stmt_affected_rows(MYSQL_STMT *stmt); +my_ulonglong STDCALL mysql_stmt_insert_id(MYSQL_STMT *stmt); +unsigned int STDCALL mysql_stmt_field_count(MYSQL_STMT *stmt); + +my_bool STDCALL mysql_commit(MYSQL * mysql); +my_bool STDCALL mysql_rollback(MYSQL * mysql); +my_bool STDCALL mysql_autocommit(MYSQL * mysql, my_bool auto_mode); +my_bool STDCALL mysql_more_results(MYSQL *mysql); +int STDCALL mysql_next_result(MYSQL *mysql); +void STDCALL mysql_close(MYSQL *sock); + + +/* status return codes */ +#define MYSQL_NO_DATA 100 +#define MYSQL_DATA_TRUNCATED 101 + +#define mysql_reload(mysql) mysql_refresh((mysql),REFRESH_GRANT) + +#ifdef USE_OLD_FUNCTIONS +MYSQL * STDCALL mysql_connect(MYSQL *mysql, const char *host, + const char *user, const char *passwd); +int STDCALL mysql_create_db(MYSQL *mysql, const char *DB); +int STDCALL mysql_drop_db(MYSQL *mysql, const char *DB); +#define mysql_reload(mysql) mysql_refresh((mysql),REFRESH_GRANT) +#endif +#define HAVE_MYSQL_REAL_CONNECT + +/* + The following functions are mainly exported because of mysqlbinlog; + They are not for general usage +*/ + +#define simple_command(mysql, command, arg, length, skip_check) \ + (*(mysql)->methods->advanced_command)(mysql, command, 0, \ + 0, arg, length, skip_check, NULL) +#define stmt_command(mysql, command, arg, length, stmt) \ + (*(mysql)->methods->advanced_command)(mysql, command, 0, \ + 0, arg, length, 1, stmt) + +#ifdef __NETWARE__ +#pragma pack(pop) /* restore alignment */ +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _mysql_h */ diff --git a/libodbc/include/mysql/mysql_com.h b/libodbc/include/mysql/mysql_com.h new file mode 100644 index 0000000000..acd81c26a4 --- /dev/null +++ b/libodbc/include/mysql/mysql_com.h @@ -0,0 +1,468 @@ +/* Copyright (C) 2000 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* +** Common definition between mysql server & client +*/ + +#ifndef _mysql_com_h +#define _mysql_com_h + +#define HOSTNAME_LENGTH 60 +#define SYSTEM_CHARSET_MBMAXLEN 3 +#define NAME_CHAR_LEN 64 /* Field/table name length */ +#define USERNAME_CHAR_LENGTH 16 +#define NAME_LEN (NAME_CHAR_LEN*SYSTEM_CHARSET_MBMAXLEN) +#define USERNAME_LENGTH (USERNAME_CHAR_LENGTH*SYSTEM_CHARSET_MBMAXLEN) + +#define SERVER_VERSION_LENGTH 60 +#define SQLSTATE_LENGTH 5 + +/* + USER_HOST_BUFF_SIZE -- length of string buffer, that is enough to contain + username and hostname parts of the user identifier with trailing zero in + MySQL standard format: + user_name_part@host_name_part\0 +*/ +#define USER_HOST_BUFF_SIZE HOSTNAME_LENGTH + USERNAME_LENGTH + 2 + +#define LOCAL_HOST "localhost" +#define LOCAL_HOST_NAMEDPIPE "." + + +#if defined(__WIN__) && !defined( _CUSTOMCONFIG_) +#define MYSQL_NAMEDPIPE "MySQL" +#define MYSQL_SERVICENAME "MySQL" +#endif /* __WIN__ */ + +/* + You should add new commands to the end of this list, otherwise old + servers won't be able to handle them as 'unsupported'. +*/ + +enum enum_server_command +{ + COM_SLEEP, COM_QUIT, COM_INIT_DB, COM_QUERY, COM_FIELD_LIST, + COM_CREATE_DB, COM_DROP_DB, COM_REFRESH, COM_SHUTDOWN, COM_STATISTICS, + COM_PROCESS_INFO, COM_CONNECT, COM_PROCESS_KILL, COM_DEBUG, COM_PING, + COM_TIME, COM_DELAYED_INSERT, COM_CHANGE_USER, COM_BINLOG_DUMP, + COM_TABLE_DUMP, COM_CONNECT_OUT, COM_REGISTER_SLAVE, + COM_STMT_PREPARE, COM_STMT_EXECUTE, COM_STMT_SEND_LONG_DATA, COM_STMT_CLOSE, + COM_STMT_RESET, COM_SET_OPTION, COM_STMT_FETCH, COM_DAEMON, + /* don't forget to update const char *command_name[] in sql_parse.cc */ + + /* Must be last */ + COM_END +}; + + +/* + Length of random string sent by server on handshake; this is also length of + obfuscated password, recieved from client +*/ +#define SCRAMBLE_LENGTH 20 +#define SCRAMBLE_LENGTH_323 8 +/* length of password stored in the db: new passwords are preceeded with '*' */ +#define SCRAMBLED_PASSWORD_CHAR_LENGTH (SCRAMBLE_LENGTH*2+1) +#define SCRAMBLED_PASSWORD_CHAR_LENGTH_323 (SCRAMBLE_LENGTH_323*2) + + +#define NOT_NULL_FLAG 1 /* Field can't be NULL */ +#define PRI_KEY_FLAG 2 /* Field is part of a primary key */ +#define UNIQUE_KEY_FLAG 4 /* Field is part of a unique key */ +#define MULTIPLE_KEY_FLAG 8 /* Field is part of a key */ +#define BLOB_FLAG 16 /* Field is a blob */ +#define UNSIGNED_FLAG 32 /* Field is unsigned */ +#define ZEROFILL_FLAG 64 /* Field is zerofill */ +#define BINARY_FLAG 128 /* Field is binary */ + +/* The following are only sent to new clients */ +#define ENUM_FLAG 256 /* field is an enum */ +#define AUTO_INCREMENT_FLAG 512 /* field is a autoincrement field */ +#define TIMESTAMP_FLAG 1024 /* Field is a timestamp */ +#define SET_FLAG 2048 /* field is a set */ +#define NO_DEFAULT_VALUE_FLAG 4096 /* Field doesn't have default value */ +#define NUM_FLAG 32768 /* Field is num (for clients) */ +#define PART_KEY_FLAG 16384 /* Intern; Part of some key */ +#define GROUP_FLAG 32768 /* Intern: Group field */ +#define UNIQUE_FLAG 65536 /* Intern: Used by sql_yacc */ +#define BINCMP_FLAG 131072 /* Intern: Used by sql_yacc */ +#define GET_FIXED_FIELDS_FLAG (1 << 18) /* Used to get fields in item tree */ +#define FIELD_IN_PART_FUNC_FLAG (1 << 19)/* Field part of partition func */ +#define FIELD_IN_ADD_INDEX (1<< 20) /* Intern: Field used in ADD INDEX */ +#define FIELD_IS_RENAMED (1<< 21) /* Intern: Field is being renamed */ + +#define REFRESH_GRANT 1 /* Refresh grant tables */ +#define REFRESH_LOG 2 /* Start on new log file */ +#define REFRESH_TABLES 4 /* close all tables */ +#define REFRESH_HOSTS 8 /* Flush host cache */ +#define REFRESH_STATUS 16 /* Flush status variables */ +#define REFRESH_THREADS 32 /* Flush thread cache */ +#define REFRESH_SLAVE 64 /* Reset master info and restart slave + thread */ +#define REFRESH_MASTER 128 /* Remove all bin logs in the index + and truncate the index */ + +/* The following can't be set with mysql_refresh() */ +#define REFRESH_READ_LOCK 16384 /* Lock tables for read */ +#define REFRESH_FAST 32768 /* Intern flag */ + +/* RESET (remove all queries) from query cache */ +#define REFRESH_QUERY_CACHE 65536 +#define REFRESH_QUERY_CACHE_FREE 0x20000L /* pack query cache */ +#define REFRESH_DES_KEY_FILE 0x40000L +#define REFRESH_USER_RESOURCES 0x80000L + +#define CLIENT_LONG_PASSWORD 1 /* new more secure passwords */ +#define CLIENT_FOUND_ROWS 2 /* Found instead of affected rows */ +#define CLIENT_LONG_FLAG 4 /* Get all column flags */ +#define CLIENT_CONNECT_WITH_DB 8 /* One can specify db on connect */ +#define CLIENT_NO_SCHEMA 16 /* Don't allow database.table.column */ +#define CLIENT_COMPRESS 32 /* Can use compression protocol */ +#define CLIENT_ODBC 64 /* Odbc client */ +#define CLIENT_LOCAL_FILES 128 /* Can use LOAD DATA LOCAL */ +#define CLIENT_IGNORE_SPACE 256 /* Ignore spaces before '(' */ +#define CLIENT_PROTOCOL_41 512 /* New 4.1 protocol */ +#define CLIENT_INTERACTIVE 1024 /* This is an interactive client */ +#define CLIENT_SSL 2048 /* Switch to SSL after handshake */ +#define CLIENT_IGNORE_SIGPIPE 4096 /* IGNORE sigpipes */ +#define CLIENT_TRANSACTIONS 8192 /* Client knows about transactions */ +#define CLIENT_RESERVED 16384 /* Old flag for 4.1 protocol */ +#define CLIENT_SECURE_CONNECTION 32768 /* New 4.1 authentication */ +#define CLIENT_MULTI_STATEMENTS (1UL << 16) /* Enable/disable multi-stmt support */ +#define CLIENT_MULTI_RESULTS (1UL << 17) /* Enable/disable multi-results */ + +#define CLIENT_SSL_VERIFY_SERVER_CERT (1UL << 30) +#define CLIENT_REMEMBER_OPTIONS (1UL << 31) + +#define SERVER_STATUS_IN_TRANS 1 /* Transaction has started */ +#define SERVER_STATUS_AUTOCOMMIT 2 /* Server in auto_commit mode */ +#define SERVER_MORE_RESULTS_EXISTS 8 /* Multi query - next query exists */ +#define SERVER_QUERY_NO_GOOD_INDEX_USED 16 +#define SERVER_QUERY_NO_INDEX_USED 32 +/* + The server was able to fulfill the clients request and opened a + read-only non-scrollable cursor for a query. This flag comes + in reply to COM_STMT_EXECUTE and COM_STMT_FETCH commands. +*/ +#define SERVER_STATUS_CURSOR_EXISTS 64 +/* + This flag is sent when a read-only cursor is exhausted, in reply to + COM_STMT_FETCH command. +*/ +#define SERVER_STATUS_LAST_ROW_SENT 128 +#define SERVER_STATUS_DB_DROPPED 256 /* A database was dropped */ +#define SERVER_STATUS_NO_BACKSLASH_ESCAPES 512 + +#define MYSQL_ERRMSG_SIZE 512 +#define NET_READ_TIMEOUT 30 /* Timeout on read */ +#define NET_WRITE_TIMEOUT 60 /* Timeout on write */ +#define NET_WAIT_TIMEOUT 8*60*60 /* Wait for new query */ + +#define ONLY_KILL_QUERY 1 + +struct st_vio; /* Only C */ +typedef struct st_vio Vio; + +#define MAX_TINYINT_WIDTH 3 /* Max width for a TINY w.o. sign */ +#define MAX_SMALLINT_WIDTH 5 /* Max width for a SHORT w.o. sign */ +#define MAX_MEDIUMINT_WIDTH 8 /* Max width for a INT24 w.o. sign */ +#define MAX_INT_WIDTH 10 /* Max width for a LONG w.o. sign */ +#define MAX_BIGINT_WIDTH 20 /* Max width for a LONGLONG */ +#define MAX_CHAR_WIDTH 255 /* Max length for a CHAR colum */ +#define MAX_BLOB_WIDTH 16777216 /* Default width for blob */ + +typedef struct st_net { +#if !defined(CHECK_EMBEDDED_DIFFERENCES) || !defined(EMBEDDED_LIBRARY) + Vio *vio; + unsigned char *buff,*buff_end,*write_pos,*read_pos; + my_socket fd; /* For Perl DBI/dbd */ + /* + The following variable is set if we are doing several queries in one + command ( as in LOAD TABLE ... FROM MASTER ), + and do not want to confuse the client with OK at the wrong time + */ + unsigned long remain_in_buf,length, buf_length, where_b; + unsigned long max_packet,max_packet_size; + unsigned int pkt_nr,compress_pkt_nr; + unsigned int write_timeout, read_timeout, retry_count; + int fcntl; + unsigned int *return_status; + unsigned char reading_or_writing; + char save_char; + my_bool no_send_ok; /* For SPs and other things that do multiple stmts */ + my_bool no_send_eof; /* For SPs' first version read-only cursors */ + my_bool compress; + /* + Set if OK packet is already sent, and we do not need to send error + messages + */ + my_bool no_send_error; + /* + Pointer to query object in query cache, do not equal NULL (0) for + queries in cache that have not stored its results yet + */ +#endif + /* + 'query_cache_query' should be accessed only via query cache + functions and methods to maintain proper locking. + */ + unsigned char *query_cache_query; + unsigned int last_errno; + unsigned char error; + my_bool report_error; /* We should report error (we have unreported error) */ + my_bool return_errno; + char last_error[MYSQL_ERRMSG_SIZE], sqlstate[SQLSTATE_LENGTH+1]; + void *extension; +} NET; + + +#define packet_error (~(unsigned long) 0) + +enum enum_field_types { MYSQL_TYPE_DECIMAL, MYSQL_TYPE_TINY, + MYSQL_TYPE_SHORT, MYSQL_TYPE_LONG, + MYSQL_TYPE_FLOAT, MYSQL_TYPE_DOUBLE, + MYSQL_TYPE_NULL, MYSQL_TYPE_TIMESTAMP, + MYSQL_TYPE_LONGLONG,MYSQL_TYPE_INT24, + MYSQL_TYPE_DATE, MYSQL_TYPE_TIME, + MYSQL_TYPE_DATETIME, MYSQL_TYPE_YEAR, + MYSQL_TYPE_NEWDATE, MYSQL_TYPE_VARCHAR, + MYSQL_TYPE_BIT, + MYSQL_TYPE_NEWDECIMAL=246, + MYSQL_TYPE_ENUM=247, + MYSQL_TYPE_SET=248, + MYSQL_TYPE_TINY_BLOB=249, + MYSQL_TYPE_MEDIUM_BLOB=250, + MYSQL_TYPE_LONG_BLOB=251, + MYSQL_TYPE_BLOB=252, + MYSQL_TYPE_VAR_STRING=253, + MYSQL_TYPE_STRING=254, + MYSQL_TYPE_GEOMETRY=255 + +}; + +/* For backward compatibility */ +#define CLIENT_MULTI_QUERIES CLIENT_MULTI_STATEMENTS +#define FIELD_TYPE_DECIMAL MYSQL_TYPE_DECIMAL +#define FIELD_TYPE_NEWDECIMAL MYSQL_TYPE_NEWDECIMAL +#define FIELD_TYPE_TINY MYSQL_TYPE_TINY +#define FIELD_TYPE_SHORT MYSQL_TYPE_SHORT +#define FIELD_TYPE_LONG MYSQL_TYPE_LONG +#define FIELD_TYPE_FLOAT MYSQL_TYPE_FLOAT +#define FIELD_TYPE_DOUBLE MYSQL_TYPE_DOUBLE +#define FIELD_TYPE_NULL MYSQL_TYPE_NULL +#define FIELD_TYPE_TIMESTAMP MYSQL_TYPE_TIMESTAMP +#define FIELD_TYPE_LONGLONG MYSQL_TYPE_LONGLONG +#define FIELD_TYPE_INT24 MYSQL_TYPE_INT24 +#define FIELD_TYPE_DATE MYSQL_TYPE_DATE +#define FIELD_TYPE_TIME MYSQL_TYPE_TIME +#define FIELD_TYPE_DATETIME MYSQL_TYPE_DATETIME +#define FIELD_TYPE_YEAR MYSQL_TYPE_YEAR +#define FIELD_TYPE_NEWDATE MYSQL_TYPE_NEWDATE +#define FIELD_TYPE_ENUM MYSQL_TYPE_ENUM +#define FIELD_TYPE_SET MYSQL_TYPE_SET +#define FIELD_TYPE_TINY_BLOB MYSQL_TYPE_TINY_BLOB +#define FIELD_TYPE_MEDIUM_BLOB MYSQL_TYPE_MEDIUM_BLOB +#define FIELD_TYPE_LONG_BLOB MYSQL_TYPE_LONG_BLOB +#define FIELD_TYPE_BLOB MYSQL_TYPE_BLOB +#define FIELD_TYPE_VAR_STRING MYSQL_TYPE_VAR_STRING +#define FIELD_TYPE_STRING MYSQL_TYPE_STRING +#define FIELD_TYPE_CHAR MYSQL_TYPE_TINY +#define FIELD_TYPE_INTERVAL MYSQL_TYPE_ENUM +#define FIELD_TYPE_GEOMETRY MYSQL_TYPE_GEOMETRY +#define FIELD_TYPE_BIT MYSQL_TYPE_BIT + + +/* Shutdown/kill enums and constants */ + +/* Bits for THD::killable. */ +#define MYSQL_SHUTDOWN_KILLABLE_CONNECT (unsigned char)(1 << 0) +#define MYSQL_SHUTDOWN_KILLABLE_TRANS (unsigned char)(1 << 1) +#define MYSQL_SHUTDOWN_KILLABLE_LOCK_TABLE (unsigned char)(1 << 2) +#define MYSQL_SHUTDOWN_KILLABLE_UPDATE (unsigned char)(1 << 3) + +enum mysql_enum_shutdown_level { + /* + We want levels to be in growing order of hardness (because we use number + comparisons). Note that DEFAULT does not respect the growing property, but + it's ok. + */ + SHUTDOWN_DEFAULT = 0, + /* wait for existing connections to finish */ + SHUTDOWN_WAIT_CONNECTIONS= MYSQL_SHUTDOWN_KILLABLE_CONNECT, + /* wait for existing trans to finish */ + SHUTDOWN_WAIT_TRANSACTIONS= MYSQL_SHUTDOWN_KILLABLE_TRANS, + /* wait for existing updates to finish (=> no partial MyISAM update) */ + SHUTDOWN_WAIT_UPDATES= MYSQL_SHUTDOWN_KILLABLE_UPDATE, + /* flush InnoDB buffers and other storage engines' buffers*/ + SHUTDOWN_WAIT_ALL_BUFFERS= (MYSQL_SHUTDOWN_KILLABLE_UPDATE << 1), + /* don't flush InnoDB buffers, flush other storage engines' buffers*/ + SHUTDOWN_WAIT_CRITICAL_BUFFERS= (MYSQL_SHUTDOWN_KILLABLE_UPDATE << 1) + 1, + /* Now the 2 levels of the KILL command */ +#if MYSQL_VERSION_ID >= 50000 + KILL_QUERY= 254, +#endif + KILL_CONNECTION= 255 +}; + + +enum enum_cursor_type +{ + CURSOR_TYPE_NO_CURSOR= 0, + CURSOR_TYPE_READ_ONLY= 1, + CURSOR_TYPE_FOR_UPDATE= 2, + CURSOR_TYPE_SCROLLABLE= 4 +}; + + +/* options for mysql_set_option */ +enum enum_mysql_set_option +{ + MYSQL_OPTION_MULTI_STATEMENTS_ON, + MYSQL_OPTION_MULTI_STATEMENTS_OFF +}; + +#define net_new_transaction(net) ((net)->pkt_nr=0) + +#ifdef __cplusplus +extern "C" { +#endif + +my_bool my_net_init(NET *net, Vio* vio); +void my_net_local_init(NET *net); +void net_end(NET *net); + void net_clear(NET *net, my_bool clear_buffer); +my_bool net_realloc(NET *net, size_t length); +my_bool net_flush(NET *net); +my_bool my_net_write(NET *net,const unsigned char *packet, size_t len); +my_bool net_write_command(NET *net,unsigned char command, + const unsigned char *header, size_t head_len, + const unsigned char *packet, size_t len); +int net_real_write(NET *net,const unsigned char *packet, size_t len); +unsigned long my_net_read(NET *net); + +#ifdef _global_h +void my_net_set_write_timeout(NET *net, uint timeout); +void my_net_set_read_timeout(NET *net, uint timeout); +#endif + +/* + The following function is not meant for normal usage + Currently it's used internally by manager.c +*/ +struct sockaddr; +int my_connect(my_socket s, const struct sockaddr *name, unsigned int namelen, + unsigned int timeout); + +struct rand_struct { + unsigned long seed1,seed2,max_value; + double max_value_dbl; +}; + +#ifdef __cplusplus +} +#endif + + /* The following is for user defined functions */ + +enum Item_result {STRING_RESULT=0, REAL_RESULT, INT_RESULT, ROW_RESULT, + DECIMAL_RESULT}; + +typedef struct st_udf_args +{ + unsigned int arg_count; /* Number of arguments */ + enum Item_result *arg_type; /* Pointer to item_results */ + char **args; /* Pointer to argument */ + unsigned long *lengths; /* Length of string arguments */ + char *maybe_null; /* Set to 1 for all maybe_null args */ + char **attributes; /* Pointer to attribute name */ + unsigned long *attribute_lengths; /* Length of attribute arguments */ + void *extension; +} UDF_ARGS; + + /* This holds information about the result */ + +typedef struct st_udf_init +{ + my_bool maybe_null; /* 1 if function can return NULL */ + unsigned int decimals; /* for real functions */ + unsigned long max_length; /* For string functions */ + char *ptr; /* free pointer for function data */ + /* 0 if result is independent of arguments */ + my_bool const_item; + void *extension; +} UDF_INIT; + + /* Constants when using compression */ +#define NET_HEADER_SIZE 4 /* standard header size */ +#define COMP_HEADER_SIZE 3 /* compression header extra size */ + + /* Prototypes to password functions */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + These functions are used for authentication by client and server and + implemented in sql/password.c +*/ + +void randominit(struct rand_struct *, unsigned long seed1, + unsigned long seed2); +double my_rnd(struct rand_struct *); +void create_random_string(char *to, unsigned int length, struct rand_struct *rand_st); + +void hash_password(unsigned long *to, const char *password, unsigned int password_len); +void make_scrambled_password_323(char *to, const char *password); +void scramble_323(char *to, const char *message, const char *password); +my_bool check_scramble_323(const char *, const char *message, + unsigned long *salt); +void get_salt_from_password_323(unsigned long *res, const char *password); +void make_password_from_salt_323(char *to, const unsigned long *salt); + +void make_scrambled_password(char *to, const char *password); +void scramble(char *to, const char *message, const char *password); +my_bool check_scramble(const char *reply, const char *message, + const unsigned char *hash_stage2); +void get_salt_from_password(unsigned char *res, const char *password); +void make_password_from_salt(char *to, const unsigned char *hash_stage2); +char *octet2hex(char *to, const char *str, unsigned int len); + +/* end of password.c */ + +char *get_tty_password(const char *opt_message); +const char *mysql_errno_to_sqlstate(unsigned int mysql_errno); + +/* Some other useful functions */ + +my_bool my_thread_init(void); +void my_thread_end(void); + +#ifdef _global_h +ulong STDCALL net_field_length(uchar **packet); +my_ulonglong net_field_length_ll(uchar **packet); +uchar *net_store_length(uchar *pkg, ulonglong length); +#endif + +#ifdef __cplusplus +} +#endif + +#define NULL_LENGTH ((unsigned long) ~0) /* For net_store_length */ +#define MYSQL_STMT_HEADER 4 +#define MYSQL_LONG_DATA_HEADER 6 + +#endif diff --git a/libodbc/include/mysql/mysql_time.h b/libodbc/include/mysql/mysql_time.h new file mode 100644 index 0000000000..33c363632c --- /dev/null +++ b/libodbc/include/mysql/mysql_time.h @@ -0,0 +1,55 @@ +/* Copyright (C) 2004 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#ifndef _mysql_time_h_ +#define _mysql_time_h_ + +/* + Time declarations shared between the server and client API: + you should not add anything to this header unless it's used + (and hence should be visible) in mysql.h. + If you're looking for a place to add new time-related declaration, + it's most likely my_time.h. See also "C API Handling of Date + and Time Values" chapter in documentation. +*/ + +enum enum_mysql_timestamp_type +{ + MYSQL_TIMESTAMP_NONE= -2, MYSQL_TIMESTAMP_ERROR= -1, + MYSQL_TIMESTAMP_DATE= 0, MYSQL_TIMESTAMP_DATETIME= 1, MYSQL_TIMESTAMP_TIME= 2 +}; + + +/* + Structure which is used to represent datetime values inside MySQL. + + We assume that values in this structure are normalized, i.e. year <= 9999, + month <= 12, day <= 31, hour <= 23, hour <= 59, hour <= 59. Many functions + in server such as my_system_gmt_sec() or make_time() family of functions + rely on this (actually now usage of make_*() family relies on a bit weaker + restriction). Also functions that produce MYSQL_TIME as result ensure this. + There is one exception to this rule though if this structure holds time + value (time_type == MYSQL_TIMESTAMP_TIME) days and hour member can hold + bigger values. +*/ +typedef struct st_mysql_time +{ + unsigned int year, month, day, hour, minute, second; + unsigned long second_part; + my_bool neg; + enum enum_mysql_timestamp_type time_type; +} MYSQL_TIME; + +#endif /* _mysql_time_h_ */ diff --git a/libodbc/include/mysql/mysql_version.h b/libodbc/include/mysql/mysql_version.h new file mode 100644 index 0000000000..5b29542988 --- /dev/null +++ b/libodbc/include/mysql/mysql_version.h @@ -0,0 +1,29 @@ +/* Copyright Abandoned 1996, 1999, 2001 MySQL AB + This file is public domain and comes with NO WARRANTY of any kind */ + +/* Version numbers for protocol & mysqld */ + +#ifndef _mysql_version_h +#define _mysql_version_h +#ifdef _CUSTOMCONFIG_ +#include +#else +#define PROTOCOL_VERSION 10 +#define MYSQL_SERVER_VERSION "5.1.22-rc" +#define MYSQL_BASE_VERSION "mysqld-5.1" +#define MYSQL_SERVER_SUFFIX_DEF "-community" +#define FRM_VER 6 +#define MYSQL_VERSION_ID 50122 +#define MYSQL_PORT 3306 +#define MYSQL_UNIX_ADDR "/tmp/mysql.sock" +#define MYSQL_CONFIG_NAME "my" +#define MYSQL_COMPILATION_COMMENT "MySQL Community Server (GPL)" + +/* mysqld compile time options */ +#endif /* _CUSTOMCONFIG_ */ + +#ifndef LICENSE +#define LICENSE GPL +#endif /* LICENSE */ + +#endif /* _mysql_version_h */ diff --git a/libodbc/include/mysql/typelib.h b/libodbc/include/mysql/typelib.h new file mode 100644 index 0000000000..e0913f39a1 --- /dev/null +++ b/libodbc/include/mysql/typelib.h @@ -0,0 +1,39 @@ +/* Copyright (C) 2000 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + + +#ifndef _typelib_h +#define _typelib_h + +#include "my_alloc.h" + +typedef struct st_typelib { /* Different types saved here */ + unsigned int count; /* How many types */ + const char *name; /* Name of typelib */ + const char **type_names; + unsigned int *type_lengths; +} TYPELIB; + +extern my_ulonglong find_typeset(char *x, TYPELIB *typelib,int *error_position); +extern int find_type_or_exit(const char *x, TYPELIB *typelib, + const char *option); +extern int find_type(char *x, const TYPELIB *typelib, unsigned int full_name); +extern void make_type(char *to,unsigned int nr,TYPELIB *typelib); +extern const char *get_type(TYPELIB *typelib,unsigned int nr); +extern TYPELIB *copy_typelib(MEM_ROOT *root, TYPELIB *from); + +extern TYPELIB sql_protocol_typelib; + +#endif /* _typelib_h */ diff --git a/libodbc/include/odbcAPI.h b/libodbc/include/odbcAPI.h new file mode 100644 index 0000000000..f42824e2be --- /dev/null +++ b/libodbc/include/odbcAPI.h @@ -0,0 +1,472 @@ +// odbcAPI.h +// +////////////////////////////////////////////////////////////////////// + +#if !defined(__ODBCAPI_H__) +#define __ODBCAPI_H__ + +#include "SQLAPI.h" + +// API header(s) +#include +#include + +extern long g_nODBCDLLVersionLoaded; + +extern void AddODBCSupport(const SAConnection *pCon); +extern void ReleaseODBCSupport(); + +typedef SQLRETURN (SQL_API *SQLAllocConnect_t)(SQLHENV EnvironmentHandle, + SQLHDBC *ConnectionHandle); +typedef SQLRETURN (SQL_API *SQLAllocEnv_t)(SQLHENV *EnvironmentHandle); +typedef SQLRETURN (SQL_API *SQLAllocHandle_t)(SQLSMALLINT HandleType, + SQLHANDLE InputHandle, SQLHANDLE *OutputHandle); +typedef SQLRETURN (SQL_API *SQLAllocStmt_t)(SQLHDBC ConnectionHandle, + SQLHSTMT *StatementHandle); +typedef SQLRETURN (SQL_API *SQLBindCol_t)( + SQLHSTMT StatementHandle, + SQLUSMALLINT ColumnNumber, + SQLSMALLINT TargetType, + SQLPOINTER TargetValue, + SQLLEN BufferLength, + SQLLEN *StrLen_or_Ind); +typedef SQLRETURN (SQL_API *SQLBindParameter_t)( + SQLHSTMT hstmt, + SQLUSMALLINT ipar, + SQLSMALLINT fParamType, + SQLSMALLINT fCType, + SQLSMALLINT fSqlType, + SQLULEN cbColDef, + SQLSMALLINT ibScale, + SQLPOINTER rgbValue, + SQLLEN cbValueMax, + SQLLEN *pcbValue); +typedef SQLRETURN (SQL_API *SQLBrowseConnect_t)( + SQLHDBC hdbc, + SQLTCHAR *szConnStrIn, + SQLSMALLINT cbConnStrIn, + SQLTCHAR *szConnStrOut, + SQLSMALLINT cbConnStrOutMax, + SQLSMALLINT *pcbConnStrOut); +typedef SQLRETURN (SQL_API *SQLBulkOperations_t)( + SQLHSTMT StatementHandle, + SQLSMALLINT Operation); +typedef SQLRETURN (SQL_API *SQLCancel_t)(SQLHSTMT StatementHandle); +typedef SQLRETURN (SQL_API *SQLCloseCursor_t)(SQLHSTMT StatementHandle); +typedef SQLRETURN (SQL_API *SQLColAttribute_t)( + SQLHSTMT StatementHandle, + SQLUSMALLINT ColumnNumber, + SQLUSMALLINT FieldIdentifier, + SQLPOINTER CharacterAttribute, + SQLSMALLINT BufferLength, + SQLSMALLINT *StringLength, + SQLLEN *NumericAttribute); +typedef SQLRETURN (SQL_API *SQLColAttributes_t)( + SQLHSTMT hstmt, + SQLUSMALLINT icol, + SQLUSMALLINT fDescType, + SQLPOINTER rgbDesc, + SQLSMALLINT cbDescMax, + SQLSMALLINT *pcbDesc, + SQLLEN *pfDesc); +typedef SQLRETURN (SQL_API *SQLColumnPrivileges_t)( + SQLHSTMT hstmt, + SQLTCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLTCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLTCHAR *szTableName, + SQLSMALLINT cbTableName, + SQLTCHAR *szColumnName, + SQLSMALLINT cbColumnName); +typedef SQLRETURN (SQL_API *SQLColumns_t)(SQLHSTMT StatementHandle, + SQLTCHAR *CatalogName, SQLSMALLINT NameLength1, + SQLTCHAR *SchemaName, SQLSMALLINT NameLength2, + SQLTCHAR *TableName, SQLSMALLINT NameLength3, + SQLTCHAR *ColumnName, SQLSMALLINT NameLength4); +typedef SQLRETURN (SQL_API *SQLConnect_t)(SQLHDBC ConnectionHandle, + SQLTCHAR *ServerName, SQLSMALLINT NameLength1, + SQLTCHAR *UserName, SQLSMALLINT NameLength2, + SQLTCHAR *Authentication, SQLSMALLINT NameLength3); +typedef SQLRETURN (SQL_API *SQLCopyDesc_t)(SQLHDESC SourceDescHandle, + SQLHDESC TargetDescHandle); +typedef SQLRETURN (SQL_API *SQLDataSources_t)(SQLHENV EnvironmentHandle, + SQLUSMALLINT Direction, SQLTCHAR *ServerName, + SQLSMALLINT BufferLength1, SQLSMALLINT *NameLength1, + SQLTCHAR *Description, SQLSMALLINT BufferLength2, + SQLSMALLINT *NameLength2); +typedef SQLRETURN (SQL_API *SQLDescribeCol_t)( + SQLHSTMT StatementHandle, + SQLUSMALLINT ColumnNumber, + SQLTCHAR *ColumnName, + SQLSMALLINT BufferLength, + SQLSMALLINT *NameLength, + SQLSMALLINT *DataType, + SQLULEN *ColumnSize, + SQLSMALLINT *DecimalDigits, + SQLSMALLINT *Nullable); +typedef SQLRETURN (SQL_API *SQLDescribeParam_t)( + SQLHSTMT hstmt, + SQLUSMALLINT ipar, + SQLSMALLINT *pfSqlType, + SQLULEN *pcbParamDef, + SQLSMALLINT *pibScale, + SQLSMALLINT *pfNullable); +typedef SQLRETURN (SQL_API *SQLDisconnect_t)(SQLHDBC ConnectionHandle); +typedef SQLRETURN (SQL_API *SQLDriverConnect_t)( + SQLHDBC hdbc, + SQLHWND hwnd, + SQLTCHAR *szConnStrIn, + SQLSMALLINT cbConnStrIn, + SQLTCHAR *szConnStrOut, + SQLSMALLINT cbConnStrOutMax, + SQLSMALLINT *pcbConnStrOut, + SQLUSMALLINT fDriverCompletion); +typedef SQLRETURN (SQL_API *SQLDrivers_t)( + SQLHENV henv, + SQLUSMALLINT fDirection, + SQLTCHAR *szDriverDesc, + SQLSMALLINT cbDriverDescMax, + SQLSMALLINT *pcbDriverDesc, + SQLTCHAR *szDriverAttributes, + SQLSMALLINT cbDrvrAttrMax, + SQLSMALLINT *pcbDrvrAttr); +typedef SQLRETURN (SQL_API *SQLEndTran_t)(SQLSMALLINT HandleType, SQLHANDLE Handle, + SQLSMALLINT CompletionType); +typedef SQLRETURN (SQL_API *SQLError_t)(SQLHENV EnvironmentHandle, + SQLHDBC ConnectionHandle, SQLHSTMT StatementHandle, + SQLTCHAR *Sqlstate, SQLINTEGER *NativeError, + SQLTCHAR *MessageText, SQLSMALLINT BufferLength, + SQLSMALLINT *TextLength); +typedef SQLRETURN (SQL_API *SQLExecDirect_t)(SQLHSTMT StatementHandle, + SQLTCHAR *StatementText, SQLINTEGER TextLength); +typedef SQLRETURN (SQL_API *SQLExecute_t)(SQLHSTMT StatementHandle); +typedef SQLRETURN (SQL_API *SQLExtendedFetch_t)( + SQLHSTMT hstmt, + SQLUSMALLINT fFetchType, + SQLLEN irow, + SQLULEN *pcrow, + SQLUSMALLINT *rgfRowStatus); +typedef SQLRETURN (SQL_API *SQLFetch_t)(SQLHSTMT StatementHandle); +typedef SQLRETURN (SQL_API *SQLFetchScroll_t)( + SQLHSTMT StatementHandle, + SQLSMALLINT FetchOrientation, + SQLLEN FetchOffset); +typedef SQLRETURN (SQL_API *SQLForeignKeys_t)( + SQLHSTMT hstmt, + SQLTCHAR *szPkCatalogName, + SQLSMALLINT cbPkCatalogName, + SQLTCHAR *szPkSchemaName, + SQLSMALLINT cbPkSchemaName, + SQLTCHAR *szPkTableName, + SQLSMALLINT cbPkTableName, + SQLTCHAR *szFkCatalogName, + SQLSMALLINT cbFkCatalogName, + SQLTCHAR *szFkSchemaName, + SQLSMALLINT cbFkSchemaName, + SQLTCHAR *szFkTableName, + SQLSMALLINT cbFkTableName); +typedef SQLRETURN (SQL_API *SQLFreeConnect_t)(SQLHDBC ConnectionHandle); +typedef SQLRETURN (SQL_API *SQLFreeEnv_t)(SQLHENV EnvironmentHandle); +typedef SQLRETURN (SQL_API *SQLFreeHandle_t)(SQLSMALLINT HandleType, SQLHANDLE Handle); +typedef SQLRETURN (SQL_API *SQLFreeStmt_t)(SQLHSTMT StatementHandle, + SQLUSMALLINT Option); +typedef SQLRETURN (SQL_API *SQLGetConnectAttr_t)(SQLHDBC ConnectionHandle, + SQLINTEGER Attribute, SQLPOINTER Value, + SQLINTEGER BufferLength, SQLINTEGER *StringLength); +typedef SQLRETURN (SQL_API *SQLGetConnectOption_t)(SQLHDBC ConnectionHandle, + SQLUSMALLINT Option, SQLPOINTER Value); +typedef SQLRETURN (SQL_API *SQLGetCursorName_t)(SQLHSTMT StatementHandle, + SQLTCHAR *CursorName, SQLSMALLINT BufferLength, + SQLSMALLINT *NameLength); +typedef SQLRETURN (SQL_API *SQLGetData_t)( + SQLHSTMT StatementHandle, + SQLUSMALLINT ColumnNumber, + SQLSMALLINT TargetType, + SQLPOINTER TargetValue, + SQLLEN BufferLength, + SQLLEN *StrLen_or_Ind); +typedef SQLRETURN (SQL_API *SQLGetDescField_t)(SQLHDESC DescriptorHandle, + SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier, + SQLPOINTER Value, SQLINTEGER BufferLength, + SQLINTEGER *StringLength); +typedef SQLRETURN (SQL_API *SQLGetDescRec_t)( + SQLHDESC DescriptorHandle, + SQLSMALLINT RecNumber, + SQLTCHAR *Name, + SQLSMALLINT BufferLength, + SQLSMALLINT *StringLength, + SQLSMALLINT *Type, + SQLSMALLINT *SubType, + SQLLEN *Length, + SQLSMALLINT *Precision, + SQLSMALLINT *Scale, + SQLSMALLINT *Nullable); +typedef SQLRETURN (SQL_API *SQLGetDiagRec_t)( + SQLSMALLINT HandleType, + SQLHANDLE Handle, + SQLSMALLINT RecNumber, + SQLTCHAR *Sqlstate, + SQLINTEGER *NativeError, + SQLTCHAR *MessageText, + SQLSMALLINT BufferLength, + SQLSMALLINT *TextLength); +typedef SQLRETURN (SQL_API *SQLGetDiagField_t)(SQLSMALLINT HandleType, SQLHANDLE Handle, + SQLSMALLINT RecNumber, SQLSMALLINT DiagIdentifier, + SQLPOINTER DiagInfo, SQLSMALLINT BufferLength, + SQLSMALLINT *StringLength); +typedef SQLRETURN (SQL_API *SQLGetEnvAttr_t)(SQLHENV EnvironmentHandle, + SQLINTEGER Attribute, SQLPOINTER Value, + SQLINTEGER BufferLength, SQLINTEGER *StringLength); +typedef SQLRETURN (SQL_API *SQLGetFunctions_t)(SQLHDBC ConnectionHandle, + SQLUSMALLINT FunctionId, SQLUSMALLINT *Supported); +typedef SQLRETURN (SQL_API *SQLGetInfo_t)(SQLHDBC ConnectionHandle, + SQLUSMALLINT InfoType, SQLPOINTER InfoValue, + SQLSMALLINT BufferLength, SQLSMALLINT *StringLength); +typedef SQLRETURN (SQL_API *SQLGetStmtAttr_t)(SQLHSTMT StatementHandle, + SQLINTEGER Attribute, SQLPOINTER Value, + SQLINTEGER BufferLength, SQLINTEGER *StringLength); +typedef SQLRETURN (SQL_API *SQLGetStmtOption_t)(SQLHSTMT StatementHandle, + SQLUSMALLINT Option, SQLPOINTER Value); +typedef SQLRETURN (SQL_API *SQLGetTypeInfo_t)(SQLHSTMT StatementHandle, + SQLSMALLINT DataType); +typedef SQLRETURN (SQL_API *SQLMoreResults_t)( + SQLHSTMT hstmt); +typedef SQLRETURN (SQL_API *SQLNativeSql_t)( + SQLHDBC hdbc, + SQLTCHAR *szSqlStrIn, + SQLINTEGER cbSqlStrIn, + SQLTCHAR *szSqlStr, + SQLINTEGER cbSqlStrMax, + SQLINTEGER *pcbSqlStr); +typedef SQLRETURN (SQL_API *SQLNumParams_t)( + SQLHSTMT hstmt, + SQLSMALLINT *pcpar); +typedef SQLRETURN (SQL_API *SQLNumResultCols_t)(SQLHSTMT StatementHandle, + SQLSMALLINT *ColumnCount); +typedef SQLRETURN (SQL_API *SQLParamData_t)(SQLHSTMT StatementHandle, + SQLPOINTER *Value); +typedef SQLRETURN (SQL_API *SQLParamOptions_t)( + SQLHSTMT hstmt, + SQLULEN crow, + SQLULEN *pirow); +typedef SQLRETURN (SQL_API *SQLPrepare_t)(SQLHSTMT StatementHandle, + SQLTCHAR *StatementText, SQLINTEGER TextLength); +typedef SQLRETURN (SQL_API *SQLPrimaryKeys_t)( + SQLHSTMT hstmt, + SQLTCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLTCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLTCHAR *szTableName, + SQLSMALLINT cbTableName); +typedef SQLRETURN (SQL_API *SQLProcedureColumns_t)( + SQLHSTMT hstmt, + SQLTCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLTCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLTCHAR *szProcName, + SQLSMALLINT cbProcName, + SQLTCHAR *szColumnName, + SQLSMALLINT cbColumnName); +typedef SQLRETURN (SQL_API *SQLProcedures_t)( + SQLHSTMT hstmt, + SQLTCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLTCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLTCHAR *szProcName, + SQLSMALLINT cbProcName); +typedef SQLRETURN (SQL_API *SQLPutData_t)( + SQLHSTMT StatementHandle, + SQLPOINTER Data, + SQLLEN StrLen_or_Ind); +typedef SQLRETURN (SQL_API *SQLRowCount_t)( + SQLHSTMT StatementHandle, + SQLLEN *RowCount); +typedef SQLRETURN (SQL_API *SQLSetConnectAttr_t)( + SQLHDBC ConnectionHandle, + SQLINTEGER Attribute, + SQLPOINTER Value, + SQLINTEGER StringLength); +typedef SQLRETURN (SQL_API *SQLSetConnectOption_t)( + SQLHDBC ConnectionHandle, + SQLUSMALLINT Option, + SQLULEN Value); +typedef SQLRETURN (SQL_API *SQLSetCursorName_t)(SQLHSTMT StatementHandle, + SQLTCHAR *CursorName, SQLSMALLINT NameLength); +typedef SQLRETURN (SQL_API *SQLSetDescField_t)(SQLHDESC DescriptorHandle, + SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier, + SQLPOINTER Value, SQLINTEGER BufferLength); +typedef SQLRETURN (SQL_API *SQLSetDescRec_t)( + SQLHDESC DescriptorHandle, + SQLSMALLINT RecNumber, + SQLSMALLINT Type, + SQLSMALLINT SubType, + SQLLEN Length, + SQLSMALLINT Precision, + SQLSMALLINT Scale, + SQLPOINTER Data, + SQLLEN *StringLength, + SQLLEN *Indicator); +typedef SQLRETURN (SQL_API *SQLSetEnvAttr_t)(SQLHENV EnvironmentHandle, + SQLINTEGER Attribute, SQLPOINTER Value, + SQLINTEGER StringLength); +typedef SQLRETURN (SQL_API *SQLSetParam_t)( + SQLHSTMT StatementHandle, + SQLUSMALLINT ParameterNumber, + SQLSMALLINT ValueType, + SQLSMALLINT ParameterType, + SQLULEN LengthPrecision, + SQLSMALLINT ParameterScale, + SQLPOINTER ParameterValue, + SQLLEN *StrLen_or_Ind); +typedef SQLRETURN (SQL_API *SQLSetPos_t)( + SQLHSTMT hstmt, + SQLSETPOSIROW irow, + SQLUSMALLINT fOption, + SQLUSMALLINT fLock); +typedef SQLRETURN (SQL_API *SQLSetScrollOptions_t)( /* Use SQLSetStmtOptions */ + SQLHSTMT hstmt, + SQLUSMALLINT fConcurrency, + SQLLEN crowKeyset, + SQLUSMALLINT crowRowset); +typedef SQLRETURN (SQL_API *SQLSetStmtAttr_t)(SQLHSTMT StatementHandle, + SQLINTEGER Attribute, SQLPOINTER Value, + SQLINTEGER StringLength); +typedef SQLRETURN (SQL_API *SQLSetStmtOption_t)( + SQLHSTMT StatementHandle, + SQLUSMALLINT Option, + SQLULEN Value); +typedef SQLRETURN (SQL_API *SQLSpecialColumns_t)(SQLHSTMT StatementHandle, + SQLUSMALLINT IdentifierType, SQLTCHAR *CatalogName, + SQLSMALLINT NameLength1, SQLTCHAR *SchemaName, + SQLSMALLINT NameLength2, SQLTCHAR *TableName, + SQLSMALLINT NameLength3, SQLUSMALLINT Scope, + SQLUSMALLINT Nullable); +typedef SQLRETURN (SQL_API *SQLStatistics_t)(SQLHSTMT StatementHandle, + SQLTCHAR *CatalogName, SQLSMALLINT NameLength1, + SQLTCHAR *SchemaName, SQLSMALLINT NameLength2, + SQLTCHAR *TableName, SQLSMALLINT NameLength3, + SQLUSMALLINT Unique, SQLUSMALLINT Reserved); +typedef SQLRETURN (SQL_API *SQLTablePrivileges_t)( + SQLHSTMT hstmt, + SQLTCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLTCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLTCHAR *szTableName, + SQLSMALLINT cbTableName); +typedef SQLRETURN (SQL_API *SQLTables_t)(SQLHSTMT StatementHandle, + SQLTCHAR *CatalogName, SQLSMALLINT NameLength1, + SQLTCHAR *SchemaName, SQLSMALLINT NameLength2, + SQLTCHAR *TableName, SQLSMALLINT NameLength3, + SQLTCHAR *TableType, SQLSMALLINT NameLength4); +typedef SQLRETURN (SQL_API *SQLTransact_t)(SQLHENV EnvironmentHandle, + SQLHDBC ConnectionHandle, SQLUSMALLINT CompletionType); + + +class SQLAPI_API odbcAPI : public saAPI +{ +public: + odbcAPI(); + + SQLAllocConnect_t SQLAllocConnect; // 1.0 + SQLAllocEnv_t SQLAllocEnv; // 1.0 + SQLAllocHandle_t SQLAllocHandle; // 3.0 + SQLAllocStmt_t SQLAllocStmt; // 1.0 + SQLBindCol_t SQLBindCol; // 1.0 + SQLBindParameter_t SQLBindParameter; // 2.0 + SQLBrowseConnect_t SQLBrowseConnect; // 1.0 + SQLBulkOperations_t SQLBulkOperations; // 3.0 + SQLCancel_t SQLCancel; // 1.0 + SQLCloseCursor_t SQLCloseCursor; // 3.0 + SQLColAttribute_t SQLColAttribute; // 3.0 + SQLColAttributes_t SQLColAttributes; // 1.0 + SQLColumnPrivileges_t SQLColumnPrivileges;// 1.0 + SQLColumns_t SQLColumns; // 1.0 + SQLConnect_t SQLConnect; // 1.0 + SQLCopyDesc_t SQLCopyDesc; // 3.0 + SQLDataSources_t SQLDataSources; // 1.0 + SQLDescribeCol_t SQLDescribeCol; // 1.0 + SQLDescribeParam_t SQLDescribeParam; // 1.0 + SQLDisconnect_t SQLDisconnect; // 1.0 + SQLDriverConnect_t SQLDriverConnect; // 1.0 + SQLDrivers_t SQLDrivers; // 2.0 + SQLEndTran_t SQLEndTran; // 3.0 + SQLError_t SQLError; // 1.0 + SQLExecDirect_t SQLExecDirect; // 1.0 + SQLExecute_t SQLExecute; // 1.0 + SQLExtendedFetch_t SQLExtendedFetch; // 1.0 + SQLFetch_t SQLFetch; // 1.0 + SQLFetchScroll_t SQLFetchScroll; // 1.0 + SQLForeignKeys_t SQLForeignKeys; // 1.0 + SQLFreeConnect_t SQLFreeConnect; // 1.0 + SQLFreeEnv_t SQLFreeEnv; // 1.0 + SQLFreeHandle_t SQLFreeHandle; // 3.0 + SQLFreeStmt_t SQLFreeStmt; // 1.0 + SQLGetConnectAttr_t SQLGetConnectAttr; // 3.0 + SQLGetConnectOption_t SQLGetConnectOption;// 1.0 + SQLGetCursorName_t SQLGetCursorName; // 1.0 + SQLGetData_t SQLGetData; // 1.0 + SQLGetDescField_t SQLGetDescField; // 3.0 + SQLGetDescRec_t SQLGetDescRec; // 3.0 + SQLGetDiagField_t SQLGetDiagField; // 3.0 + SQLGetDiagRec_t SQLGetDiagRec; // 3.0 + SQLGetEnvAttr_t SQLGetEnvAttr; // 3.0 + SQLGetFunctions_t SQLGetFunctions; // 1.0 + SQLGetInfo_t SQLGetInfo; // 1.0 + SQLGetStmtAttr_t SQLGetStmtAttr; // 3.0 + SQLGetStmtOption_t SQLGetStmtOption; // 1.0 + SQLGetTypeInfo_t SQLGetTypeInfo; // 1.0 + SQLMoreResults_t SQLMoreResults; // 1.0 + SQLNativeSql_t SQLNativeSql; // 1.0 + SQLNumParams_t SQLNumParams; // 1.0 + SQLNumResultCols_t SQLNumResultCols; // 1.0 + SQLParamData_t SQLParamData; // 1.0 + SQLParamOptions_t SQLParamOptions; // 1.0 + SQLPrepare_t SQLPrepare; // 1.0 + SQLPrimaryKeys_t SQLPrimaryKeys; // 1.0 + SQLProcedureColumns_t SQLProcedureColumns;// 1.0 + SQLProcedures_t SQLProcedures; // 1.0 + SQLPutData_t SQLPutData; // 1.0 + SQLRowCount_t SQLRowCount; // 1.0 + SQLSetConnectAttr_t SQLSetConnectAttr; // 3.0 + SQLSetConnectOption_t SQLSetConnectOption;// 1.0 + SQLSetCursorName_t SQLSetCursorName; // 1.0 + SQLSetDescField_t SQLSetDescField; // 3.0 + SQLSetDescRec_t SQLSetDescRec; // 3.0 + SQLSetEnvAttr_t SQLSetEnvAttr; // 3.0 + SQLSetParam_t SQLSetParam; // 1.0 + SQLSetPos_t SQLSetPos; // 1.0 + SQLSetScrollOptions_t SQLSetScrollOptions;// 1.0 + SQLSetStmtAttr_t SQLSetStmtAttr; // 3.0 + SQLSetStmtOption_t SQLSetStmtOption; // 1.0 + SQLSpecialColumns_t SQLSpecialColumns; // 1.0 + SQLStatistics_t SQLStatistics; // 1.0 + SQLTablePrivileges_t SQLTablePrivileges; // 1.0 + SQLTables_t SQLTables; // 1.0 + SQLTransact_t SQLTransact; // 1.0 +}; + +class SQLAPI_API odbcConnectionHandles : public saConnectionHandles +{ +public: + odbcConnectionHandles(); + + SQLHENV m_hevn; + SQLHDBC m_hdbc; +}; + +class SQLAPI_API odbcCommandHandles : public saCommandHandles +{ +public: + odbcCommandHandles(); + + SQLHSTMT m_hstmt; +}; + +extern odbcAPI g_odbcAPI; + +#endif // !defined(__ODBCAPI_H__) diff --git a/libodbc/include/odbc_linux/iodbcext.h b/libodbc/include/odbc_linux/iodbcext.h new file mode 100644 index 0000000000..e3696146c1 --- /dev/null +++ b/libodbc/include/odbc_linux/iodbcext.h @@ -0,0 +1,374 @@ +/* + * iodbcext.h + * + * $Id: iodbcext.h,v 1.3 2013/09/01 17:11:18 yas Exp $ + * + * iODBC extensions and changes to the SAG specifications + * for third party drivers + * + * The iODBC driver manager. + * + * Copyright (C) 1996-2009 by OpenLink Software + * All Rights Reserved. + * + * This software is released under the terms of either of the following + * licenses: + * + * - GNU Library General Public License (see LICENSE.LGPL) + * - The BSD License (see LICENSE.BSD). + * + * Note that the only valid version of the LGPL license as far as this + * project is concerned is the original GNU Library General Public License + * Version 2, dated June 1991. + * + * While not mandated by the BSD license, any patches you make to the + * iODBC source code may be contributed back into the iODBC project + * at your discretion. Contributions will benefit the Open Source and + * Data Access community as a whole. Submissions may be made at: + * + * http://www.iodbc.org + * + * + * GNU Library Generic Public License Version 2 + * ============================================ + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; only + * Version 2 of the License dated June 1991. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * + * The BSD License + * =============== + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name of OpenLink Software Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL OPENLINK OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef _IODBCEXT_H +#define _IODBCEXT_H + + +/* + * OpenLink API Extensions + */ +#define SQL_GETLASTROWID 1048L +#define SQL_GETLASTSERIAL 1049L +#define SQL_CONCUR_VAL_EXTENT 1050L +#define SQL_APPLICATION_NAME 1051L /* connect option */ +#define SQL_PARSE_FWD_ONLY_REQ 1052L +#define SQL_DESC_KEY 1053L +#define SQL_APPEND_KEYS 1054L +#define SQL_DESC_EXPR 1055L +#define SQL_ATTR_WCHAR_SIZE 1056L + +#define SQL_COLUMN_ROWVER SQL_DESC_ROWVER +#define SQL_COLUMN_KEY SQL_DESC_KEY +#define SQL_COLUMN_EXPR SQL_DESC_EXPR +#define SQL_ATTR_PARSE_FWD_ONLY_REQ SQL_PARSE_FWD_ONLY_REQ +#define SQL_ATTR_APPEND_KEYS SQL_APPEND_KEYS + + +/* + * Microsoft extensions for SQLServer + */ + +/* + * SQLSetConnectOption/SQLSetStmtOption driver specific defines. + * Microsoft has 1200 thru 1249 reserved for Microsoft SQL Server + * driver usage. + */ +#define SQL_ATTR_ENLIST_IN_DTC 1207 +#define SQL_ATTR_ENLIST_IN_XA 1208 +#define SQL_ATTR_CONNECTION_DEAD 1209 /* GetConnectAttr only */ +#define SQL_COPT_SS_BASE 1200 +#define SQL_COPT_SS_REMOTE_PWD (SQL_COPT_SS_BASE+1) /* dbrpwset SQLSetConnectOption only */ +#define SQL_COPT_SS_USE_PROC_FOR_PREP (SQL_COPT_SS_BASE+2) /* Use create proc for SQLPrepare */ +#define SQL_COPT_SS_INTEGRATED_SECURITY (SQL_COPT_SS_BASE+3) /* Force integrated security on login */ +#define SQL_COPT_SS_PRESERVE_CURSORS (SQL_COPT_SS_BASE+4) /* Preserve server cursors after SQLTransact */ +#define SQL_COPT_SS_USER_DATA (SQL_COPT_SS_BASE+5) /* dbgetuserdata/dbsetuserdata */ +#define SQL_COPT_SS_ANSI_OEM (SQL_COPT_SS_BASE+6) /* dbsetopt/DBANSItoOEM/DBOEMtoANSI */ +#define SQL_COPT_SS_ENLIST_IN_DTC SQL_ATTR_ENLIST_IN_DTC /* Enlist in a DTC transaction */ +#define SQL_COPT_SS_ENLIST_IN_XA SQL_ATTR_ENLIST_IN_XA /* Enlist in a XA transaction */ +#define SQL_COPT_SS_CONNECTION_DEAD SQL_ATTR_CONNECTION_DEAD /* dbdead SQLGetConnectOption only */ +#define SQL_COPT_SS_FALLBACK_CONNECT (SQL_COPT_SS_BASE+10) /* Enables FallBack connections */ +#define SQL_COPT_SS_PERF_DATA (SQL_COPT_SS_BASE+11) /* Used to access SQL Server ODBC driver performance data */ +#define SQL_COPT_SS_PERF_DATA_LOG (SQL_COPT_SS_BASE+12) /* Used to set the logfile name for the Performance data */ +#define SQL_COPT_SS_PERF_QUERY_INTERVAL (SQL_COPT_SS_BASE+13) /* Used to set the query logging threshold in milliseconds. */ +#define SQL_COPT_SS_PERF_QUERY_LOG (SQL_COPT_SS_BASE+14) /* Used to set the logfile name for saving queries. */ +#define SQL_COPT_SS_PERF_QUERY (SQL_COPT_SS_BASE+15) /* Used to start and stop query logging. */ +#define SQL_COPT_SS_PERF_DATA_LOG_NOW (SQL_COPT_SS_BASE+16) /* Used to make a statistics log entry to disk. */ +#define SQL_COPT_SS_QUOTED_IDENT (SQL_COPT_SS_BASE+17) /* Enable/Disable Quoted Identifiers */ +#define SQL_COPT_SS_ANSI_NPW (SQL_COPT_SS_BASE+18) /* Enable/Disable ANSI NULL, Padding and Warnings */ +#define SQL_COPT_SS_BCP (SQL_COPT_SS_BASE+19) /* Allow BCP usage on connection */ + +#define SQL_COPT_SS_MAX_USED SQL_COPT_SS_BCP + +#define SQL_SOPT_SS_BASE 1225 +#define SQL_SOPT_SS_TEXTPTR_LOGGING (SQL_SOPT_SS_BASE+0) /* Text pointer logging */ +#define SQL_SOPT_SS_CURRENT_COMMAND (SQL_SOPT_SS_BASE+1) /* dbcurcmd SQLGetStmtOption only */ +#define SQL_SOPT_SS_HIDDEN_COLUMNS (SQL_SOPT_SS_BASE+2) /* Expose FOR BROWSE hidden columns */ +#define SQL_SOPT_SS_NOBROWSETABLE (SQL_SOPT_SS_BASE+3) /* Set NOBROWSETABLE option */ +#define SQL_SOPT_SS_REGIONALIZE (SQL_SOPT_SS_BASE+4) /* Regionalize output character conversions */ +#define SQL_SOPT_SS_MAX_USED SQL_SOPT_SS_REGIONALIZE + + +/* Defines for use with SQL_COPT_SS_USE_PROC_FOR_PREP */ +#define SQL_UP_OFF 0L /*Procedures won't be used for prepare*/ +#define SQL_UP_ON 1L /*Procedures will be used for prepare*/ +#define SQL_UP_ON_DROP 2L /*Temp procedures will be explicitly dropped*/ +#define SQL_UP_DEFAULT SQL_UP_ON + +/* Defines for use with SQL_COPT_SS_INTEGRATED_SECURITY - Pre-Connect Option only */ +#define SQL_IS_OFF 0L /* Integrated security isn't used */ +#define SQL_IS_ON 1L /* Integrated security is used */ +#define SQL_IS_DEFAULT SQL_IS_OFF + +/* Defines for use with SQL_COPT_SS_PRESERVE_CURSORS */ +#define SQL_PC_OFF 0L /* Cursors are closed on SQLTransact */ +#define SQL_PC_ON 1L /* Cursors remain open on SQLTransact */ +#define SQL_PC_DEFAULT SQL_PC_OFF + +/* Defines for use with SQL_COPT_SS_USER_DATA */ +#define SQL_UD_NOTSET NULL /* No user data pointer set */ + +/* Defines for use with SQL_COPT_SS_ANSI_OEM */ +#define SQL_AO_OFF 0L /* ANSI/OEM translation is not performed */ +#define SQL_AO_ON 1L /* ANSI/OEM translation is performed */ +#define SQL_AO_DEFAULT SQL_AO_OFF /* Default unless DSN OEM/ANSI checkbox is checked */ + +/* Defines for use with SQL_COPT_SS_FALLBACK_CONNECT */ +#define SQL_FB_OFF 0L /* FallBack connections are disabled */ +#define SQL_FB_ON 1L /* FallBack connections are enabled */ +#define SQL_FB_DEFAULT SQL_FB_OFF + +/* Defines for use with SQL_COPT_SS_BCP */ +#define SQL_BCP_OFF 0L /* BCP is not allowed on connection */ +#define SQL_BCP_ON 1L /* BCP is allowed on connection */ +#define SQL_BCP_DEFAULT SQL_BCP_OFF + +/* Defines for use with SQL_COPT_SS_QUOTED_IDENT - Pre-Connect Option only */ +#define SQL_QI_OFF 0L /* Quoted identifiers are not supported */ +#define SQL_QI_ON 1L /* Quoted identifiers are supported */ +#define SQL_QI_DEFAULT SQL_QI_ON + +/* Defines for use with SQL_COPT_SS_ANSI_NPW - Pre-Connect Option only */ +#define SQL_AD_OFF 0L /* ANSI NULLs, Padding and Warnings are not supported */ +#define SQL_AD_ON 1L /* ANSI NULLs, Padding and Warnings are supported */ +#define SQL_AD_DEFAULT SQL_AD_ON + + +/* Defines for use with SQL_SOPT_SS_TEXTPTR_LOGGING */ +#define SQL_TL_OFF 0L /* No logging on text pointer ops */ +#define SQL_TL_ON 1L /* Logging occurs on text pointer ops */ +#define SQL_TL_DEFAULT SQL_TL_ON + +/* Defines for use with SQL_SOPT_SS_HIDDEN_COLUMNS */ +#define SQL_HC_OFF 0L /* FOR BROWSE columns are hidden */ +#define SQL_HC_ON 1L /* FOR BROWSE columns are exposed */ +#define SQL_HC_DEFAULT SQL_HC_OFF + +/* Defines for use with SQL_SOPT_SS_NOBROWSETABLE */ +#define SQL_NB_OFF 0L /* NO_BROWSETABLE is off */ +#define SQL_NB_ON 1L /* NO_BROWSETABLE is on */ +#define SQL_NB_DEFAULT SQL_NB_OFF + +/* Defines for use with SQL_SOPT_SS_REGIONALIZE */ +#define SQL_RE_OFF 0L /* No regionalization occurs on output character conversions */ +#define SQL_RE_ON 1L /* Regionalization occurs on output character conversions */ +#define SQL_RE_DEFAULT SQL_RE_OFF + + +/* + * IBM extensions for DB2 + */ + +/* Options for SQLGetStmtOption/SQLSetStmtOption extensions */ +#define SQL_CURSOR_HOLD 1250 +#define SQL_ATTR_CURSOR_HOLD 1250 +#define SQL_NODESCRIBE_OUTPUT 1251 +#define SQL_ATTR_NODESCRIBE_OUTPUT 1251 +#define SQL_NODESCRIBE_INPUT 1264 +#define SQL_ATTR_NODESCRIBE_INPUT 1264 +#define SQL_NODESCRIBE SQL_NODESCRIBE_OUTPUT +#define SQL_ATTR_NODESCRIBE SQL_NODESCRIBE_OUTPUT +#define SQL_CLOSE_BEHAVIOR 1257 +#define SQL_ATTR_CLOSE_BEHAVIOR 1257 +#define SQL_ATTR_CLOSEOPEN 1265 +#define SQL_ATTR_CURRENT_PACKAGE_SET 1276 +#define SQL_ATTR_DEFERRED_PREPARE 1277 +#define SQL_ATTR_EARLYCLOSE 1268 +#define SQL_ATTR_PROCESSCTL 1278 + +/* SQL_CLOSE_BEHAVIOR values. */ +#define SQL_CC_NO_RELEASE 0 +#define SQL_CC_RELEASE 1 +#define SQL_CC_DEFAULT SQL_CC_NO_RELEASE + +/* SQL_ATTR_DEFERRED_PREPARE values */ +#define SQL_DEFERRED_PREPARE_ON 1 +#define SQL_DEFERRED_PREPARE_OFF 0 +#define SQL_DEFERRED_PREPARE_DEFAULT SQL_DEFERRED_PREPARE_ON + +/* SQL_ATTR_EARLYCLOSE values */ +#define SQL_EARLYCLOSE_ON 1 +#define SQL_EARLYCLOSE_OFF 0 +#define SQL_EARLYCLOSE_DEFAULT SQL_EARLYCLOSE_ON + +/* SQL_ATTR_PROCESSCTL masks */ +#define SQL_PROCESSCTL_NOTHREAD 0x00000001L +#define SQL_PROCESSCTL_NOFORK 0x00000002L + +/* Options for SQL_CURSOR_HOLD */ +#define SQL_CURSOR_HOLD_ON 1 +#define SQL_CURSOR_HOLD_OFF 0 +#define SQL_CURSOR_HOLD_DEFAULT SQL_CURSOR_HOLD_ON + +/* Options for SQL_NODESCRIBE_INPUT/SQL_NODESCRIBE_OUTPUT */ +#define SQL_NODESCRIBE_ON 1 +#define SQL_NODESCRIBE_OFF 0 +#define SQL_NODESCRIBE_DEFAULT SQL_NODESCRIBE_OFF + +/* Options for SQLGetConnectOption/SQLSetConnectOption extensions */ +#define SQL_WCHARTYPE 1252 +#define SQL_LONGDATA_COMPAT 1253 +#define SQL_CURRENT_SCHEMA 1254 +#define SQL_DB2EXPLAIN 1258 +#define SQL_DB2ESTIMATE 1259 +#define SQL_PARAMOPT_ATOMIC 1260 +#define SQL_STMTTXN_ISOLATION 1261 +#define SQL_MAXCONN 1262 +#define SQL_ATTR_WCHARTYPE SQL_WCHARTYPE +#define SQL_ATTR_LONGDATA_COMPAT SQL_LONGDATA_COMPAT +#define SQL_ATTR_CURRENT_SCHEMA SQL_CURRENT_SCHEMA +#define SQL_ATTR_DB2EXPLAIN SQL_DB2EXPLAIN +#define SQL_ATTR_DB2ESTIMATE SQL_DB2ESTIMATE +#define SQL_ATTR_PARAMOPT_ATOMIC SQL_PARAMOPT_ATOMIC +#define SQL_ATTR_STMTTXN_ISOLATION SQL_STMTTXN_ISOLATION +#define SQL_ATTR_MAXCONN SQL_MAXCONN + +/* Options for SQLSetConnectOption, SQLSetEnvAttr */ +#define SQL_CONNECTTYPE 1255 +#define SQL_SYNC_POINT 1256 +#define SQL_MINMEMORY_USAGE 1263 +#define SQL_CONN_CONTEXT 1269 +#define SQL_ATTR_INHERIT_NULL_CONNECT 1270 +#define SQL_ATTR_FORCE_CONVERSION_ON_CLIENT 1275 +#define SQL_ATTR_CONNECTTYPE SQL_CONNECTTYPE +#define SQL_ATTR_SYNC_POINT SQL_SYNC_POINT +#define SQL_ATTR_MINMEMORY_USAGE SQL_MINMEMORY_USAGE +#define SQL_ATTR_CONN_CONTEXT SQL_CONN_CONTEXT + +/* Options for SQL_LONGDATA_COMPAT */ +#define SQL_LD_COMPAT_YES 1 +#define SQL_LD_COMPAT_NO 0 +#define SQL_LD_COMPAT_DEFAULT SQL_LD_COMPAT_NO + +/* Options for SQL_PARAMOPT_ATOMIC */ +#define SQL_ATOMIC_YES 1 +#define SQL_ATOMIC_NO 0 +#define SQL_ATOMIC_DEFAULT SQL_ATOMIC_YES + +/* Options for SQL_CONNECT_TYPE */ +#define SQL_CONCURRENT_TRANS 1 +#define SQL_COORDINATED_TRANS 2 +#define SQL_CONNECTTYPE_DEFAULT SQL_CONCURRENT_TRANS + +/* Options for SQL_SYNCPOINT */ +#define SQL_ONEPHASE 1 +#define SQL_TWOPHASE 2 +#define SQL_SYNCPOINT_DEFAULT SQL_ONEPHASE + +/* Options for SQL_DB2ESTIMATE */ +#define SQL_DB2ESTIMATE_ON 1 +#define SQL_DB2ESTIMATE_OFF 0 +#define SQL_DB2ESTIMATE_DEFAULT SQL_DB2ESTIMATE_OFF + +/* Options for SQL_DB2EXPLAIN */ +#define SQL_DB2EXPLAIN_OFF 0x00000000L +#define SQL_DB2EXPLAIN_SNAPSHOT_ON 0x00000001L +#define SQL_DB2EXPLAIN_MODE_ON 0x00000002L +#define SQL_DB2EXPLAIN_SNAPSHOT_MODE_ON SQL_DB2EXPLAIN_SNAPSHOT_ON+SQL_DB2EXPLAIN_MODE_ON +#define SQL_DB2EXPLAIN_ON SQL_DB2EXPLAIN_SNAPSHOT_ON +#define SQL_DB2EXPLAIN_DEFAULT SQL_DB2EXPLAIN_OFF + +/* Options for SQL_WCHARTYPE + * Note that you can only specify SQL_WCHARTYPE_CONVERT if you have an + * external compile flag SQL_WCHART_CONVERT defined + */ +#ifdef SQL_WCHART_CONVERT +#define SQL_WCHARTYPE_CONVERT 1 +#endif +#define SQL_WCHARTYPE_NOCONVERT 0 +#define SQL_WCHARTYPE_DEFAULT SQL_WCHARTYPE_NOCONVERT + + +/******************* Virtuoso ODBC Extensions *******************/ + +/* + * ODBC extensions for SQLGetDescField + */ +#define SQL_DESC_COL_DV_TYPE 1057L +#define SQL_DESC_COL_DT_DT_TYPE 1058L +#define SQL_DESC_COL_LITERAL_ATTR 1059L +#define SQL_DESC_COL_BOX_FLAGS 1060L +#define SQL_DESC_COL_LITERAL_LANG 1061L +#define SQL_DESC_COL_LITERAL_TYPE 1062L + + +/* + * Virtuoso - ODBC SQL_DESC_COL_DV_TYPE + */ +#define VIRTUOSO_DV_DATE 129 +#define VIRTUOSO_DV_DATETIME 211 +#define VIRTUOSO_DV_DOUBLE_FLOAT 191 +#define VIRTUOSO_DV_IRI_ID 243 +#define VIRTUOSO_DV_LONG_INT 189 +#define VIRTUOSO_DV_NUMERIC 219 +#define VIRTUOSO_DV_RDF 246 +#define VIRTUOSO_DV_SINGLE_FLOAT 190 +#define VIRTUOSO_DV_STRING 182 +#define VIRTUOSO_DV_TIME 210 +#define VIRTUOSO_DV_TIMESTAMP 128 +#define VIRTUOSO_DV_TIMESTAMP_OBJ 208 + + +/* + * Virtuoso - ODBC SQL_DESC_COL_DT_DT_TYPE + */ +#define VIRTUOSO_DT_TYPE_DATETIME 1 +#define VIRTUOSO_DT_TYPE_DATE 2 +#define VIRTUOSO_DT_TYPE_TIME 3 + +#endif /* _IODBCEXT_H */ diff --git a/libodbc/include/odbc_linux/iodbcinst.h b/libodbc/include/odbc_linux/iodbcinst.h new file mode 100644 index 0000000000..320abf2dc5 --- /dev/null +++ b/libodbc/include/odbc_linux/iodbcinst.h @@ -0,0 +1,83 @@ +/* + * iodbcinst.h + * + * $Id: iodbcinst.h,v 1.4 2013/09/01 17:11:19 yas Exp $ + * + * iODBC Installer defines + * + * The iODBC driver manager. + * + * Copyright (C) 1996-2009 by OpenLink Software + * All Rights Reserved. + * + * This software is released under the terms of either of the following + * licenses: + * + * - GNU Library General Public License (see LICENSE.LGPL) + * - The BSD License (see LICENSE.BSD). + * + * Note that the only valid version of the LGPL license as far as this + * project is concerned is the original GNU Library General Public License + * Version 2, dated June 1991. + * + * While not mandated by the BSD license, any patches you make to the + * iODBC source code may be contributed back into the iODBC project + * at your discretion. Contributions will benefit the Open Source and + * Data Access community as a whole. Submissions may be made at: + * + * http://www.iodbc.org + * + * + * GNU Library Generic Public License Version 2 + * ============================================ + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; only + * Version 2 of the License dated June 1991. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * + * The BSD License + * =============== + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name of OpenLink Software Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL OPENLINK OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This file is deprecated in favor of odbcinst.h and will be removed + * sometime in the future. Please recode your applications to use + * the standard names sql.h, sqlext.h, sqltypes.h and odbcinst.h. + */ + +#include diff --git a/libodbc/include/odbc_linux/iodbcunix.h b/libodbc/include/odbc_linux/iodbcunix.h new file mode 100644 index 0000000000..f9ef5753ce --- /dev/null +++ b/libodbc/include/odbc_linux/iodbcunix.h @@ -0,0 +1,160 @@ +/* + * iodbcunix.h + * + * $Id: iodbcunix.h,v 1.4 2013/09/01 17:11:19 yas Exp $ + * + * ODBC defines for Unix + * + * The iODBC driver manager. + * + * Copyright (C) 1995 by Ke Jin + * Copyright (C) 1996-2009 by OpenLink Software + * All Rights Reserved. + * + * This software is released under the terms of either of the following + * licenses: + * + * - GNU Library General Public License (see LICENSE.LGPL) + * - The BSD License (see LICENSE.BSD). + * + * Note that the only valid version of the LGPL license as far as this + * project is concerned is the original GNU Library General Public License + * Version 2, dated June 1991. + * + * While not mandated by the BSD license, any patches you make to the + * iODBC source code may be contributed back into the iODBC project + * at your discretion. Contributions will benefit the Open Source and + * Data Access community as a whole. Submissions may be made at: + * + * http://www.iodbc.org + * + * + * GNU Library Generic Public License Version 2 + * ============================================ + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; only + * Version 2 of the License dated June 1991. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * + * The BSD License + * =============== + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name of OpenLink Software Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL OPENLINK OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _IODBCUNIX_H +#define _IODBCUNIX_H + +/* + * Standard header files + */ +#include +#include + +#if defined(__WCHAR_TYPE__) && !defined(MACOSX102) +#include +#endif + + +/* + * Windows-style declarations + */ +#define NEAR +#define FAR +#define EXPORT +#define PASCAL +#define VOID void +#define CALLBACK +#define _cdecl +#define __stdcall + + +/* + * Boolean support + */ +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* + * Windows-style typedefs + */ +#if defined (OBSOLETE_WINDOWS_TYPES) +typedef unsigned char BYTE; +#endif +typedef unsigned short WORD; +typedef unsigned int DWORD; +typedef char * LPSTR; +typedef const char * LPCSTR; +typedef wchar_t * LPWSTR; +typedef const wchar_t * LPCWSTR; +typedef DWORD * LPDWORD; + +#if !defined(BOOL) && !defined(_OBJC_OBJC_H_) +typedef int BOOL; +#endif + + +/* + * Determine sizeof(long) in case it is not determined by configure/config.h + */ +#ifndef SIZEOF_LONG +#if defined (_LP64) || \ + defined (__LP64__) || \ + defined (__64BIT__) || \ + defined (__alpha) || \ + defined (__sparcv9) || \ + defined (__arch64__) +#define SIZEOF_LONG 8 /* 64 bit operating systems */ +#else +#define SIZEOF_LONG 4 /* 32 bit operating systems */ +#endif +#endif /* SIZEOF_LONG */ + +#ifdef __cplusplus +} +#endif + +#endif /* _IODBCUNIX_H */ diff --git a/libodbc/include/odbc_linux/isql.h b/libodbc/include/odbc_linux/isql.h new file mode 100644 index 0000000000..eb147aaf95 --- /dev/null +++ b/libodbc/include/odbc_linux/isql.h @@ -0,0 +1,84 @@ +/* + * isql.h + * + * $Id: isql.h,v 1.4 2013/09/01 17:11:19 yas Exp $ + * + * iODBC defines + * + * The iODBC driver manager. + * + * Copyright (C) 1995 by Ke Jin + * Copyright (C) 1996-2009 by OpenLink Software + * All Rights Reserved. + * + * This software is released under the terms of either of the following + * licenses: + * + * - GNU Library General Public License (see LICENSE.LGPL) + * - The BSD License (see LICENSE.BSD). + * + * Note that the only valid version of the LGPL license as far as this + * project is concerned is the original GNU Library General Public License + * Version 2, dated June 1991. + * + * While not mandated by the BSD license, any patches you make to the + * iODBC source code may be contributed back into the iODBC project + * at your discretion. Contributions will benefit the Open Source and + * Data Access community as a whole. Submissions may be made at: + * + * http://www.iodbc.org + * + * + * GNU Library Generic Public License Version 2 + * ============================================ + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; only + * Version 2 of the License dated June 1991. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * + * The BSD License + * =============== + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name of OpenLink Software Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL OPENLINK OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This file is deprecated in favor of sql.h and will be removed + * sometime in the future. Please recode your applications to use + * the standard names sql.h, sqlext.h and sqltypes.h. + */ + +#include diff --git a/libodbc/include/odbc_linux/isqlext.h b/libodbc/include/odbc_linux/isqlext.h new file mode 100644 index 0000000000..0c02500d1a --- /dev/null +++ b/libodbc/include/odbc_linux/isqlext.h @@ -0,0 +1,84 @@ +/* + * isqlext.h + * + * $Id: isqlext.h,v 1.4 2013/09/01 17:11:19 yas Exp $ + * + * iODBC defines (ext) + * + * The iODBC driver manager. + * + * Copyright (C) 1995 by Ke Jin + * Copyright (C) 1996-2009 by OpenLink Software + * All Rights Reserved. + * + * This software is released under the terms of either of the following + * licenses: + * + * - GNU Library General Public License (see LICENSE.LGPL) + * - The BSD License (see LICENSE.BSD). + * + * Note that the only valid version of the LGPL license as far as this + * project is concerned is the original GNU Library General Public License + * Version 2, dated June 1991. + * + * While not mandated by the BSD license, any patches you make to the + * iODBC source code may be contributed back into the iODBC project + * at your discretion. Contributions will benefit the Open Source and + * Data Access community as a whole. Submissions may be made at: + * + * http://www.iodbc.org + * + * + * GNU Library Generic Public License Version 2 + * ============================================ + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; only + * Version 2 of the License dated June 1991. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * + * The BSD License + * =============== + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name of OpenLink Software Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL OPENLINK OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This file is deprecated in favor of sqlext.h and will be removed + * sometime in the future. Please recode your applications to use + * the standard names sql.h, sqlext.h and sqltypes.h. + */ + +#include diff --git a/libodbc/include/odbc_linux/isqltypes.h b/libodbc/include/odbc_linux/isqltypes.h new file mode 100644 index 0000000000..48433b19d0 --- /dev/null +++ b/libodbc/include/odbc_linux/isqltypes.h @@ -0,0 +1,84 @@ +/* + * isqltypes.h + * + * $Id: isqltypes.h,v 1.4 2013/09/01 17:11:19 yas Exp $ + * + * iODBC typedefs + * + * The iODBC driver manager. + * + * Copyright (C) 1995 by Ke Jin + * Copyright (C) 1996-2009 by OpenLink Software + * All Rights Reserved. + * + * This software is released under the terms of either of the following + * licenses: + * + * - GNU Library General Public License (see LICENSE.LGPL) + * - The BSD License (see LICENSE.BSD). + * + * Note that the only valid version of the LGPL license as far as this + * project is concerned is the original GNU Library General Public License + * Version 2, dated June 1991. + * + * While not mandated by the BSD license, any patches you make to the + * iODBC source code may be contributed back into the iODBC project + * at your discretion. Contributions will benefit the Open Source and + * Data Access community as a whole. Submissions may be made at: + * + * http://www.iodbc.org + * + * + * GNU Library Generic Public License Version 2 + * ============================================ + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; only + * Version 2 of the License dated June 1991. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * + * The BSD License + * =============== + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name of OpenLink Software Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL OPENLINK OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This file is deprecated in favor of sqltypes.h and will be removed + * sometime in the future. Please recode your applications to use + * the standard names sql.h, sqlext.h and sqltypes.h. + */ + +#include diff --git a/libodbc/include/odbc_linux/odbcinst.h b/libodbc/include/odbc_linux/odbcinst.h new file mode 100644 index 0000000000..4afa707fcd --- /dev/null +++ b/libodbc/include/odbc_linux/odbcinst.h @@ -0,0 +1,639 @@ +/* + * odbcinst.h + * + * $Id: odbcinst.h,v 1.1 2013/09/01 17:11:19 yas Exp $ + * + * iODBC Installer defines + * + * The iODBC driver manager. + * + * Copyright (C) 1996-2009 by OpenLink Software + * All Rights Reserved. + * + * This software is released under the terms of either of the following + * licenses: + * + * - GNU Library General Public License (see LICENSE.LGPL) + * - The BSD License (see LICENSE.BSD). + * + * Note that the only valid version of the LGPL license as far as this + * project is concerned is the original GNU Library General Public License + * Version 2, dated June 1991. + * + * While not mandated by the BSD license, any patches you make to the + * iODBC source code may be contributed back into the iODBC project + * at your discretion. Contributions will benefit the Open Source and + * Data Access community as a whole. Submissions may be made at: + * + * http://www.iodbc.org + * + * + * GNU Library Generic Public License Version 2 + * ============================================ + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; only + * Version 2 of the License dated June 1991. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * + * The BSD License + * =============== + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name of OpenLink Software Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL OPENLINK OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _ODBCINST_H +#define _ODBCINST_H + +/* + * Set default specification to ODBC 3.51 + */ +#ifndef ODBCVER +#define ODBCVER 0x0351 +#endif + +#ifndef _SQL_H +#include +#endif + +#ifndef _SQLEXT_H +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef EXPORT +#define EXPORT +#endif + +#ifndef SYS_ODBCINST_INI +# if defined(__BEOS__) +# define SYS_ODBCINST_INI "/boot/beos/etc/odbcinst.ini" +# endif +# if defined(macintosh) +# ifdef __POWERPC__ +# define SYS_ODBCINST_INI "Boot:System Folder:Preferences:ODBC Installer Preferences PPC" +# else +# define SYS_ODBCINST_INI "Boot:System Folder:Preferences:ODBC Installer Preferences" +# endif +# else +# define SYS_ODBCINST_INI "/etc/odbcinst.ini" +# endif +#endif + +#ifndef SYS_ODBC_INI +# if defined(__BEOS__) +# define SYS_ODBC_INI "/boot/beos/etc/odbc.ini" +# endif +# if defined(macintosh) +# ifdef __POWERPC__ +# define SYS_ODBC_INI "Boot:System Folder:Preferences:ODBC Preferences PPC" +# else +# define SYS_ODBC_INI "Boot:System Folder:Preferences:ODBC Preferences" +# endif +# else +# define SYS_ODBC_INI "/etc/odbc.ini" +# endif +#endif + +#ifndef DEFAULT_FILEDSNPATH +# if defined(__BEOS__) +# define DEFAULT_FILEDSNPATH "/boot/beos/etc/ODBCDataSources" +# elif defined(macintosh) +# ifdef __POWERPC__ +# define DEFAULT_FILEDSNPATH "Boot:System Folder:Preferences:ODBC Preferences PPC:ODBCDataSources" +# else +# define DEFAULT_FILEDSNPATH "Boot:System Folder:Preferences:ODBC Preferences:ODBCDataSources" +# endif +# elif defined (__APPLE__) +# define DEFAULT_FILEDSNPATH "/Library/ODBC/ODBCDataSources" +# else +# define DEFAULT_FILEDSNPATH "/etc/ODBCDataSources" +# endif +#endif + +#define USERDSN_ONLY 0 +#define SYSTEMDSN_ONLY 1 + +#ifdef WIN32 +#define INSTAPI __stdcall +#else +#define INSTAPI +#endif + +/* + * SQLConfigDataSource + */ +#define ODBC_ADD_DSN 1 +#define ODBC_CONFIG_DSN 2 +#define ODBC_REMOVE_DSN 3 + +#if (ODBCVER >= 0x0250) +#define ODBC_ADD_SYS_DSN 4 +#define ODBC_CONFIG_SYS_DSN 5 +#define ODBC_REMOVE_SYS_DSN 6 +#if (ODBCVER >= 0x0300) +#define ODBC_REMOVE_DEFAULT_DSN 7 +#endif /* ODBCVER >= 0x0300 */ + +/* install request flags */ +#define ODBC_INSTALL_INQUIRY 1 +#define ODBC_INSTALL_COMPLETE 2 + +/* config driver flags */ +#define ODBC_INSTALL_DRIVER 1 +#define ODBC_REMOVE_DRIVER 2 +#define ODBC_CONFIG_DRIVER 3 +#define ODBC_CONFIG_DRIVER_MAX 100 +#endif + +/* SQLGetConfigMode and SQLSetConfigMode flags */ +#if (ODBCVER >= 0x0300) +#define ODBC_BOTH_DSN 0 +#define ODBC_USER_DSN 1 +#define ODBC_SYSTEM_DSN 2 +#endif /* ODBCVER >= 0x0300 */ + +/* SQLInstallerError code */ +#if (ODBCVER >= 0x0300) +#define ODBC_ERROR_GENERAL_ERR 1 +#define ODBC_ERROR_INVALID_BUFF_LEN 2 +#define ODBC_ERROR_INVALID_HWND 3 +#define ODBC_ERROR_INVALID_STR 4 +#define ODBC_ERROR_INVALID_REQUEST_TYPE 5 +#define ODBC_ERROR_COMPONENT_NOT_FOUND 6 +#define ODBC_ERROR_INVALID_NAME 7 +#define ODBC_ERROR_INVALID_KEYWORD_VALUE 8 +#define ODBC_ERROR_INVALID_DSN 9 +#define ODBC_ERROR_INVALID_INF 10 +#define ODBC_ERROR_REQUEST_FAILED 11 +#define ODBC_ERROR_INVALID_PATH 12 +#define ODBC_ERROR_LOAD_LIB_FAILED 13 +#define ODBC_ERROR_INVALID_PARAM_SEQUENCE 14 +#define ODBC_ERROR_INVALID_LOG_FILE 15 +#define ODBC_ERROR_USER_CANCELED 16 +#define ODBC_ERROR_USAGE_UPDATE_FAILED 17 +#define ODBC_ERROR_CREATE_DSN_FAILED 18 +#define ODBC_ERROR_WRITING_SYSINFO_FAILED 19 +#define ODBC_ERROR_REMOVE_DSN_FAILED 20 +#define ODBC_ERROR_OUT_OF_MEM 21 +#define ODBC_ERROR_OUTPUT_STRING_TRUNCATED 22 +#define ODBC_ERROR_DRIVER_SPECIFIC 23 +#endif /* ODBCVER >= 0x0300 */ + +/* + * Function Prototypes + */ + +BOOL INSTAPI +SQLGetConfigMode ( + UWORD* pwConfigMode); + +BOOL INSTAPI +SQLInstallDriverEx ( + LPCSTR lpszDriver, + LPCSTR lpszPathIn, + LPSTR lpszPathOut, + WORD cbPathOutMax, + WORD* pcbPathOut, + WORD fRequest, + LPDWORD lpdwUsageCount); + +BOOL INSTAPI +SQLInstallDriverExW ( + LPCWSTR lpszDriver, + LPCWSTR lpszPathIn, + LPWSTR lpszPathOut, + WORD cbPathOutMax, + WORD* pcbPathOut, + WORD fRequest, + LPDWORD lpdwUsageCount); + +RETCODE INSTAPI +SQLInstallerError ( + WORD iError, + DWORD* pfErrorCode, + LPSTR lpszErrorMsg, + WORD cbErrorMsgMax, + WORD* pcbErrorMsg); + +RETCODE INSTAPI +SQLInstallerErrorW ( + WORD iError, + DWORD* pfErrorCode, + LPWSTR lpszErrorMsg, + WORD cbErrorMsgMax, + WORD* pcbErrorMsg); + +RETCODE INSTAPI +SQLPostInstallerError ( + DWORD fErrorCode, + LPSTR szErrorMsg); + +RETCODE INSTAPI +SQLPostInstallerErrorW ( + DWORD fErrorCode, + LPWSTR szErrorMsg); + +BOOL INSTAPI +SQLInstallTranslatorEx ( + LPCSTR lpszTranslator, + LPCSTR lpszPathIn, + LPSTR lpszPathOut, + WORD cbPathOutMax, + WORD* pcbPathOut, + WORD fRequest, + LPDWORD lpdwUsageCount); + +BOOL INSTAPI +SQLInstallTranslatorExW ( + LPCWSTR lpszTranslator, + LPCWSTR lpszPathIn, + LPWSTR lpszPathOut, + WORD cbPathOutMax, + WORD* pcbPathOut, + WORD fRequest, + LPDWORD lpdwUsageCount); + +BOOL INSTAPI +SQLReadFileDSN ( + LPCSTR lpszFileName, + LPCSTR lpszAppName, + LPCSTR lpszKeyName, + LPSTR lpszString, + WORD cbString, + WORD* pcbString); + +BOOL INSTAPI +SQLReadFileDSNW ( + LPCWSTR lpszFileName, + LPCWSTR lpszAppName, + LPCWSTR lpszKeyName, + LPWSTR lpszString, + WORD cbString, + WORD* pcbString); + +BOOL INSTAPI +SQLWriteFileDSN ( + LPCSTR lpszFileName, + LPCSTR lpszAppName, + LPCSTR lpszKeyName, + LPSTR lpszString); + +BOOL INSTAPI +SQLWriteFileDSNW ( + LPCWSTR lpszFileName, + LPCWSTR lpszAppName, + LPCWSTR lpszKeyName, + LPWSTR lpszString); + +BOOL INSTAPI +SQLSetConfigMode ( + UWORD wConfigMode); + +BOOL INSTAPI SQLInstallODBC ( + HWND hwndParent, + LPCSTR lpszInfFile, + LPCSTR lpszSrcPath, + LPCSTR lpszDrivers); + +BOOL INSTAPI SQLInstallODBCW ( + HWND hwndParent, + LPCWSTR lpszInfFile, + LPCWSTR lpszSrcPath, + LPCWSTR lpszDrivers); + +BOOL INSTAPI SQLManageDataSources (HWND hwndParent); + +BOOL INSTAPI SQLCreateDataSource ( + HWND hwndParent, + LPCSTR lpszDSN); + +BOOL INSTAPI SQLCreateDataSourceW ( + HWND hwndParent, + LPCWSTR lpszDSN); + +BOOL INSTAPI SQLGetTranslator ( + HWND hwnd, + LPSTR lpszName, + WORD cbNameMax, + WORD * pcbNameOut, + LPSTR lpszPath, + WORD cbPathMax, + WORD * pcbPathOut, + DWORD * pvOption); + +BOOL INSTAPI SQLGetTranslatorW ( + HWND hwnd, + LPWSTR lpszName, + WORD cbNameMax, + WORD * pcbNameOut, + LPWSTR lpszPath, + WORD cbPathMax, + WORD * pcbPathOut, + DWORD * pvOption); + +/* Low level APIs + * NOTE: The high-level APIs should always be used. These APIs + * have been left for compatibility. + */ +BOOL INSTAPI SQLInstallDriver ( + LPCSTR lpszInfFile, + LPCSTR lpszDriver, + LPSTR lpszPath, + WORD cbPathMax, + WORD * pcbPathOut); + +BOOL INSTAPI SQLInstallDriverW ( + LPCWSTR lpszInfFile, + LPCWSTR lpszDriver, + LPWSTR lpszPath, + WORD cbPathMax, + WORD * pcbPathOut); + +BOOL INSTAPI SQLInstallDriverManager ( + LPSTR lpszPath, + WORD cbPathMax, + WORD * pcbPathOut); + +BOOL INSTAPI SQLInstallDriverManagerW ( + LPWSTR lpszPath, + WORD cbPathMax, + WORD * pcbPathOut); + +BOOL INSTAPI SQLGetInstalledDrivers ( + LPSTR lpszBuf, + WORD cbBufMax, + WORD * pcbBufOut); + +BOOL INSTAPI SQLGetInstalledDriversW ( + LPWSTR lpszBuf, + WORD cbBufMax, + WORD * pcbBufOut); + +BOOL INSTAPI SQLGetAvailableDrivers ( + LPCSTR lpszInfFile, + LPSTR lpszBuf, + WORD cbBufMax, + WORD * pcbBufOut); + +BOOL INSTAPI SQLGetAvailableDriversW ( + LPCWSTR lpszInfFile, + LPWSTR lpszBuf, + WORD cbBufMax, + WORD * pcbBufOut); + +BOOL INSTAPI SQLConfigDataSource ( + HWND hwndParent, + WORD fRequest, + LPCSTR lpszDriver, + LPCSTR lpszAttributes); + +BOOL INSTAPI SQLConfigDataSourceW ( + HWND hwndParent, + WORD fRequest, + LPCWSTR lpszDriver, + LPCWSTR lpszAttributes); + +BOOL INSTAPI SQLRemoveDefaultDataSource (void); + +BOOL INSTAPI SQLWriteDSNToIni ( + LPCSTR lpszDSN, + LPCSTR lpszDriver); + +BOOL INSTAPI SQLWriteDSNToIniW ( + LPCWSTR lpszDSN, + LPCWSTR lpszDriver); + +BOOL INSTAPI SQLRemoveDSNFromIni (LPCSTR lpszDSN); + +BOOL INSTAPI SQLRemoveDSNFromIniW (LPCWSTR lpszDSN); + +BOOL INSTAPI SQLValidDSN (LPCSTR lpszDSN); + +BOOL INSTAPI SQLValidDSNW (LPCWSTR lpszDSN); + +BOOL INSTAPI SQLWritePrivateProfileString ( + LPCSTR lpszSection, + LPCSTR lpszEntry, + LPCSTR lpszString, + LPCSTR lpszFilename); + +BOOL INSTAPI SQLWritePrivateProfileStringW ( + LPCWSTR lpszSection, + LPCWSTR lpszEntry, + LPCWSTR lpszString, + LPCWSTR lpszFilename); + +int INSTAPI SQLGetPrivateProfileString ( + LPCSTR lpszSection, + LPCSTR lpszEntry, + LPCSTR lpszDefault, + LPSTR lpszRetBuffer, + int cbRetBuffer, + LPCSTR lpszFilename); + +int INSTAPI SQLGetPrivateProfileStringW ( + LPCWSTR lpszSection, + LPCWSTR lpszEntry, + LPCWSTR lpszDefault, + LPWSTR lpszRetBuffer, + int cbRetBuffer, + LPCWSTR lpszFilename); + +BOOL INSTAPI SQLRemoveDriverManager (LPDWORD lpdwUsageCount); + +BOOL INSTAPI SQLInstallTranslator ( + LPCSTR lpszInfFile, + LPCSTR lpszTranslator, + LPCSTR lpszPathIn, + LPSTR lpszPathOut, + WORD cbPathOutMax, + WORD * pcbPathOut, + WORD fRequest, + LPDWORD lpdwUsageCount); + +BOOL INSTAPI SQLInstallTranslatorW ( + LPCWSTR lpszInfFile, + LPCWSTR lpszTranslator, + LPCWSTR lpszPathIn, + LPWSTR lpszPathOut, + WORD cbPathOutMax, + WORD * pcbPathOut, + WORD fRequest, + LPDWORD lpdwUsageCount); + +BOOL INSTAPI SQLRemoveTranslator ( + LPCSTR lpszTranslator, + LPDWORD lpdwUsageCount); + +BOOL INSTAPI SQLRemoveTranslatorW ( + LPCWSTR lpszTranslator, + LPDWORD lpdwUsageCount); + +BOOL INSTAPI SQLRemoveDriver ( + LPCSTR lpszDriver, + BOOL fRemoveDSN, + LPDWORD lpdwUsageCount); + +BOOL INSTAPI SQLRemoveDriverW ( + LPCWSTR lpszDriver, + BOOL fRemoveDSN, + LPDWORD lpdwUsageCount); + +BOOL INSTAPI SQLConfigDriver ( + HWND hwndParent, + WORD fRequest, + LPCSTR lpszDriver, + LPCSTR lpszArgs, + LPSTR lpszMsg, + WORD cbMsgMax, + WORD * pcbMsgOut); + +BOOL INSTAPI SQLConfigDriverW ( + HWND hwndParent, + WORD fRequest, + LPCWSTR lpszDriver, + LPCWSTR lpszArgs, + LPWSTR lpszMsg, + WORD cbMsgMax, + WORD * pcbMsgOut); + +/* Driver specific Setup APIs called by installer */ + +typedef BOOL INSTAPI (*pConfigDSNFunc) ( + HWND hwndParent, + WORD fRequest, + LPCSTR lpszDriver, + LPCSTR lpszAttributes); + +typedef BOOL INSTAPI (*pConfigDSNWFunc) ( + HWND hwndParent, + WORD fRequest, + LPCWSTR lpszDriver, + LPCWSTR lpszAttributes); + +typedef BOOL INSTAPI (*pConfigDriverFunc) ( + HWND hwndParent, + WORD fRequest, + LPCSTR lpszDriver, + LPCSTR lpszArgs, + LPSTR lpszMsg, + WORD cbMsgMax, + WORD * pcbMsgOut); + +typedef BOOL INSTAPI (*pConfigDriverWFunc) ( + HWND hwndParent, + WORD fRequest, + LPCWSTR lpszDriver, + LPCWSTR lpszArgs, + LPWSTR lpszMsg, + WORD cbMsgMax, + WORD * pcbMsgOut); + +typedef BOOL INSTAPI (*pConfigTranslatorFunc) ( + HWND hwndParent, + DWORD *pvOption); + +BOOL INSTAPI ConfigDSN ( + HWND hwndParent, + WORD fRequest, + LPCSTR lpszDriver, + LPCSTR lpszAttributes); + +BOOL INSTAPI ConfigDSNW ( + HWND hwndParent, + WORD fRequest, + LPCWSTR lpszDriver, + LPCWSTR lpszAttributes); + +BOOL INSTAPI ConfigTranslator (HWND hwndParent, + DWORD * pvOption); + +BOOL INSTAPI ConfigDriver ( + HWND hwndParent, + WORD fRequest, + LPCSTR lpszDriver, + LPCSTR lpszArgs, + LPSTR lpszMsg, + WORD cbMsgMax, + WORD * pcbMsgOut); + +BOOL INSTAPI ConfigDriverW ( + HWND hwndParent, + WORD fRequest, + LPCWSTR lpszDriver, + LPCWSTR lpszArgs, + LPWSTR lpszMsg, + WORD cbMsgMax, + WORD * pcbMsgOut); + +#ifndef SQL_NOUNICODEMAP +#ifdef UNICODE + +#define SQLInstallODBC SQLInstallODBCW +#define SQLCreateDataSource SQLCreateDataSourceW +#define SQLGetTranslator SQLGetTranslatorW +#define SQLInstallDriver SQLInstallDriverW +#define SQLInstallDriverManager SQLInstallDriverManagerW +#define SQLGetInstalledDrivers SQLGetInstalledDriversW +#define SQLGetAvailableDrivers SQLGetAvailableDriversW +#define SQLConfigDataSource SQLConfigDataSourceW +#define SQLWriteDSNToIni SQLWriteDSNToIniW +#define SQLRemoveDSNFromIni SQLRemoveDSNFromIniW +#define SQLValidDSN SQLValidDSNW +#define SQLWritePrivateProfileString SQLWritePrivateProfileStringW +#define SQLGetPrivateProfileString SQLGetPrivateProfileStringW +#define SQLInstallTranslator SQLInstallTranslatorW +#define SQLRemoveTranslator SQLRemoveTranslatorW +#define SQLRemoveDriver SQLRemoveDriverW +#define SQLConfigDriver SQLConfigDriverW +#define SQLInstallerError SQLInstallerErrorW +#define SQLPostInstallerError SQLPostInstallerErrorW +#define SQLReadFileDSN SQLReadFileDSNW +#define SQLWriteFileDSN SQLWriteFileDSNW +#define SQLInstallDriverEx SQLInstallDriverExW +#define SQLInstallTranslatorEx SQLInstallTranslatorExW + +#endif /* UNICODE */ +#endif /* SQL_NOUNICODEMAP */ + +#ifdef __cplusplus +} +#endif + +#endif /* _ODBCINST_H */ diff --git a/libodbc/include/odbc_linux/sql.h b/libodbc/include/odbc_linux/sql.h new file mode 100644 index 0000000000..ca96bfa53b --- /dev/null +++ b/libodbc/include/odbc_linux/sql.h @@ -0,0 +1,1187 @@ +/* + * sql.h + * + * $Id: sql.h,v 1.3 2013/09/01 17:11:19 yas Exp $ + * + * ODBC defines + * + * The iODBC driver manager. + * + * Copyright (C) 1995 by Ke Jin + * Copyright (C) 1996-2009 by OpenLink Software + * All Rights Reserved. + * + * This software is released under the terms of either of the following + * licenses: + * + * - GNU Library General Public License (see LICENSE.LGPL) + * - The BSD License (see LICENSE.BSD). + * + * Note that the only valid version of the LGPL license as far as this + * project is concerned is the original GNU Library General Public License + * Version 2, dated June 1991. + * + * While not mandated by the BSD license, any patches you make to the + * iODBC source code may be contributed back into the iODBC project + * at your discretion. Contributions will benefit the Open Source and + * Data Access community as a whole. Submissions may be made at: + * + * http://www.iodbc.org + * + * + * GNU Library Generic Public License Version 2 + * ============================================ + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; only + * Version 2 of the License dated June 1991. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * + * The BSD License + * =============== + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name of OpenLink Software Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL OPENLINK OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _SQL_H +#define _SQL_H + +/* + * Set default specification to ODBC 3.51 + */ +#ifndef ODBCVER +#define ODBCVER 0x0351 +#endif + +#ifndef _SQLTYPES_H +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Useful Constants + */ +#define SQL_MAX_MESSAGE_LENGTH 512 + + +/* + * Handle types + */ +#if (ODBCVER >= 0x0300) +#define SQL_HANDLE_ENV 1 +#define SQL_HANDLE_DBC 2 +#define SQL_HANDLE_STMT 3 +#define SQL_HANDLE_DESC 4 +#endif /* ODBCVER >= 0x0300 */ + + +/* + * Function return codes + */ +#define SQL_SUCCESS 0 +#define SQL_SUCCESS_WITH_INFO 1 +#define SQL_STILL_EXECUTING 2 +#define SQL_ERROR (-1) +#define SQL_INVALID_HANDLE (-2) +#define SQL_NEED_DATA 99 +#if (ODBCVER >= 0x0300) +#define SQL_NO_DATA 100 +#endif /* ODBCVER >= 0x0300 */ + + +/* + * Test for SQL_SUCCESS or SQL_SUCCESS_WITH_INFO + */ +#define SQL_SUCCEEDED(rc) (((rc) & (~1)) == 0) + + +/* + * Special length values + */ +#define SQL_NULL_DATA (-1) +#define SQL_DATA_AT_EXEC (-2) + + +/* + * Flags for null-terminated strings + */ +#define SQL_NTS (-3) +#define SQL_NTSL (-3L) + + +/* + * Standard SQL datatypes, using ANSI type numbering + */ +#define SQL_UNKNOWN_TYPE 0 +#define SQL_CHAR 1 +#define SQL_NUMERIC 2 +#define SQL_DECIMAL 3 +#define SQL_INTEGER 4 +#define SQL_SMALLINT 5 +#define SQL_FLOAT 6 +#define SQL_REAL 7 +#define SQL_DOUBLE 8 +#if (ODBCVER >= 0x0300) +#define SQL_DATETIME 9 +#endif /* ODBCVER >= 0x0300 */ +#define SQL_VARCHAR 12 + + +/* + * SQLGetTypeInfo request for all data types + */ +#define SQL_ALL_TYPES 0 + + +/* + * Statement attribute values for date/time data types + */ +#if (ODBCVER >= 0x0300) +#define SQL_TYPE_DATE 91 +#define SQL_TYPE_TIME 92 +#define SQL_TYPE_TIMESTAMP 93 +#endif /* ODBCVER >= 0x0300 */ + + +/* + * Date/Time length constants + */ +#if (ODBCVER >= 0x0300) +#define SQL_DATE_LEN 10 +#define SQL_TIME_LEN 8 /* add P+1 if prec >0 */ +#define SQL_TIMESTAMP_LEN 19 /* add P+1 if prec >0 */ +#endif /* ODBCVER >= 0x0300 */ + + +/* + * NULL status constants + */ +#define SQL_NO_NULLS 0 +#define SQL_NULLABLE 1 +#define SQL_NULLABLE_UNKNOWN 2 + + +/* + * NULL Handles + */ +#define SQL_NULL_HENV 0 +#define SQL_NULL_HDBC 0 +#define SQL_NULL_HSTMT 0 +#if (ODBCVER >= 0x0300) +#define SQL_NULL_HDESC 0 +#endif /* ODBCVER >= 0x0300 */ + + +/* + * NULL handle for parent argument to SQLAllocHandle when allocating + * a SQLHENV + */ +#if (ODBCVER >= 0x0300) +#define SQL_NULL_HANDLE 0L +#endif /* ODBCVER >= 0x0300 */ + + +/* + * CLI option values + */ +#if (ODBCVER >= 0x0300) +#define SQL_FALSE 0 +#define SQL_TRUE 1 +#endif /* ODBCVER >= 0x0300 */ + + +/* + * Default conversion code for SQLBindCol(), SQLBindParam() and SQLGetData() + */ +#if (ODBCVER >= 0x0300) +#define SQL_DEFAULT 99 +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLDataSources/SQLFetchScroll - FetchOrientation + */ +#define SQL_FETCH_NEXT 1 +#define SQL_FETCH_FIRST 2 + + +/* + * SQLFetchScroll - FetchOrientation + */ +#define SQL_FETCH_LAST 3 +#define SQL_FETCH_PRIOR 4 +#define SQL_FETCH_ABSOLUTE 5 +#define SQL_FETCH_RELATIVE 6 + + +/* + * SQLFreeStmt + */ +#define SQL_CLOSE 0 +#define SQL_DROP 1 +#define SQL_UNBIND 2 +#define SQL_RESET_PARAMS 3 + + +/* + * SQLGetConnectAttr - connection attributes + */ +#if (ODBCVER >= 0x0300) +#define SQL_ATTR_AUTO_IPD 10001 +#define SQL_ATTR_METADATA_ID 10014 +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetData() code indicating that the application row descriptor + * specifies the data type + */ +#if (ODBCVER >= 0x0300) +#define SQL_ARD_TYPE (-99) +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetDescField - identifiers of fields in the SQL descriptor + */ +#if (ODBCVER >= 0x0300) +#define SQL_DESC_COUNT 1001 +#define SQL_DESC_TYPE 1002 +#define SQL_DESC_LENGTH 1003 +#define SQL_DESC_OCTET_LENGTH_PTR 1004 +#define SQL_DESC_PRECISION 1005 +#define SQL_DESC_SCALE 1006 +#define SQL_DESC_DATETIME_INTERVAL_CODE 1007 +#define SQL_DESC_NULLABLE 1008 +#define SQL_DESC_INDICATOR_PTR 1009 +#define SQL_DESC_DATA_PTR 1010 +#define SQL_DESC_NAME 1011 +#define SQL_DESC_UNNAMED 1012 +#define SQL_DESC_OCTET_LENGTH 1013 +#define SQL_DESC_ALLOC_TYPE 1099 +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetDescField - SQL_DESC_ALLOC_TYPE + */ +#if (ODBCVER >= 0x0300) +#define SQL_DESC_ALLOC_AUTO 1 +#define SQL_DESC_ALLOC_USER 2 +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetDescField - SQL_DESC_DATETIME_INTERVAL_CODE + */ +#if (ODBCVER >= 0x0300) +#define SQL_CODE_DATE 1 +#define SQL_CODE_TIME 2 +#define SQL_CODE_TIMESTAMP 3 +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetDescField - SQL_DESC_UNNAMED + */ +#if (ODBCVER >= 0x0300) +#define SQL_NAMED 0 +#define SQL_UNNAMED 1 +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetDiagField - identifiers of fields in the diagnostics area + */ +#if (ODBCVER >= 0x0300) +#define SQL_DIAG_RETURNCODE 1 +#define SQL_DIAG_NUMBER 2 +#define SQL_DIAG_ROW_COUNT 3 +#define SQL_DIAG_SQLSTATE 4 +#define SQL_DIAG_NATIVE 5 +#define SQL_DIAG_MESSAGE_TEXT 6 +#define SQL_DIAG_DYNAMIC_FUNCTION 7 +#define SQL_DIAG_CLASS_ORIGIN 8 +#define SQL_DIAG_SUBCLASS_ORIGIN 9 +#define SQL_DIAG_CONNECTION_NAME 10 +#define SQL_DIAG_SERVER_NAME 11 +#define SQL_DIAG_DYNAMIC_FUNCTION_CODE 12 +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetDiagField - SQL_DIAG_DYNAMIC_FUNCTION_CODE + */ +#if (ODBCVER >= 0x0300) +#define SQL_DIAG_ALTER_DOMAIN 3 +#define SQL_DIAG_ALTER_TABLE 4 +#define SQL_DIAG_CALL 7 +#define SQL_DIAG_CREATE_ASSERTION 6 +#define SQL_DIAG_CREATE_CHARACTER_SET 8 +#define SQL_DIAG_CREATE_COLLATION 10 +#define SQL_DIAG_CREATE_DOMAIN 23 +#define SQL_DIAG_CREATE_INDEX (-1) +#define SQL_DIAG_CREATE_SCHEMA 64 +#define SQL_DIAG_CREATE_TABLE 77 +#define SQL_DIAG_CREATE_TRANSLATION 79 +#define SQL_DIAG_CREATE_VIEW 84 +#define SQL_DIAG_DELETE_WHERE 19 +#define SQL_DIAG_DROP_ASSERTION 24 +#define SQL_DIAG_DROP_CHARACTER_SET 25 +#define SQL_DIAG_DROP_COLLATION 26 +#define SQL_DIAG_DROP_DOMAIN 27 +#define SQL_DIAG_DROP_INDEX (-2) +#define SQL_DIAG_DROP_SCHEMA 31 +#define SQL_DIAG_DROP_TABLE 32 +#define SQL_DIAG_DROP_TRANSLATION 33 +#define SQL_DIAG_DROP_VIEW 36 +#define SQL_DIAG_DYNAMIC_DELETE_CURSOR 38 +#define SQL_DIAG_DYNAMIC_UPDATE_CURSOR 81 +#define SQL_DIAG_GRANT 48 +#define SQL_DIAG_INSERT 50 +#define SQL_DIAG_REVOKE 59 +#define SQL_DIAG_SELECT_CURSOR 85 +#define SQL_DIAG_UNKNOWN_STATEMENT 0 +#define SQL_DIAG_UPDATE_WHERE 82 +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetEnvAttr - environment attribute + */ +#if (ODBCVER >= 0x0300) +#define SQL_ATTR_OUTPUT_NTS 10001 +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetFunctions + */ +#define SQL_API_SQLALLOCCONNECT 1 +#define SQL_API_SQLALLOCENV 2 +#if (ODBCVER >= 0x0300) +#define SQL_API_SQLALLOCHANDLE 1001 +#endif /* ODBCVER >= 0x0300 */ +#define SQL_API_SQLALLOCSTMT 3 +#define SQL_API_SQLBINDCOL 4 +#if (ODBCVER >= 0x0300) +#define SQL_API_SQLBINDPARAM 1002 +#endif /* ODBCVER >= 0x0300 */ +#define SQL_API_SQLCANCEL 5 +#if (ODBCVER >= 0x0300) +#define SQL_API_SQLCLOSECURSOR 1003 +#define SQL_API_SQLCOLATTRIBUTE 6 +#endif /* ODBCVER >= 0x0300 */ +#define SQL_API_SQLCOLUMNS 40 +#define SQL_API_SQLCONNECT 7 +#if (ODBCVER >= 0x0300) +#define SQL_API_SQLCOPYDESC 1004 +#endif /* ODBCVER >= 0x0300 */ +#define SQL_API_SQLDATASOURCES 57 +#define SQL_API_SQLDESCRIBECOL 8 +#define SQL_API_SQLDISCONNECT 9 +#if (ODBCVER >= 0x0300) +#define SQL_API_SQLENDTRAN 1005 +#endif /* ODBCVER >= 0x0300 */ +#define SQL_API_SQLERROR 10 +#define SQL_API_SQLEXECDIRECT 11 +#define SQL_API_SQLEXECUTE 12 +#define SQL_API_SQLFETCH 13 +#if (ODBCVER >= 0x0300) +#define SQL_API_SQLFETCHSCROLL 1021 +#endif /* ODBCVER >= 0x0300 */ +#define SQL_API_SQLFREECONNECT 14 +#define SQL_API_SQLFREEENV 15 +#if (ODBCVER >= 0x0300) +#define SQL_API_SQLFREEHANDLE 1006 +#endif /* ODBCVER >= 0x0300 */ +#define SQL_API_SQLFREESTMT 16 +#if (ODBCVER >= 0x0300) +#define SQL_API_SQLGETCONNECTATTR 1007 +#endif /* ODBCVER >= 0x0300 */ +#define SQL_API_SQLGETCONNECTOPTION 42 +#define SQL_API_SQLGETCURSORNAME 17 +#define SQL_API_SQLGETDATA 43 +#if (ODBCVER >= 0x0300) +#define SQL_API_SQLGETDESCFIELD 1008 +#define SQL_API_SQLGETDESCREC 1009 +#define SQL_API_SQLGETDIAGFIELD 1010 +#define SQL_API_SQLGETDIAGREC 1011 +#define SQL_API_SQLGETENVATTR 1012 +#endif /* ODBCVER >= 0x0300 */ +#define SQL_API_SQLGETFUNCTIONS 44 +#define SQL_API_SQLGETINFO 45 +#if (ODBCVER >= 0x0300) +#define SQL_API_SQLGETSTMTATTR 1014 +#endif /* ODBCVER >= 0x0300 */ +#define SQL_API_SQLGETSTMTOPTION 46 +#define SQL_API_SQLGETTYPEINFO 47 +#define SQL_API_SQLNUMRESULTCOLS 18 +#define SQL_API_SQLPARAMDATA 48 +#define SQL_API_SQLPREPARE 19 +#define SQL_API_SQLPUTDATA 49 +#define SQL_API_SQLROWCOUNT 20 +#if (ODBCVER >= 0x0300) +#define SQL_API_SQLSETCONNECTATTR 1016 +#endif /* ODBCVER >= 0x0300 */ +#define SQL_API_SQLSETCONNECTOPTION 50 +#define SQL_API_SQLSETCURSORNAME 21 +#if (ODBCVER >= 0x0300) +#define SQL_API_SQLSETDESCFIELD 1017 +#define SQL_API_SQLSETDESCREC 1018 +#define SQL_API_SQLSETENVATTR 1019 +#endif /* ODBCVER >= 0x0300 */ +#define SQL_API_SQLSETPARAM 22 +#if (ODBCVER >= 0x0300) +#define SQL_API_SQLSETSTMTATTR 1020 +#endif /* ODBCVER >= 0x0300 */ +#define SQL_API_SQLSETSTMTOPTION 51 +#define SQL_API_SQLSPECIALCOLUMNS 52 +#define SQL_API_SQLSTATISTICS 53 +#define SQL_API_SQLTABLES 54 +#define SQL_API_SQLTRANSACT 23 + + +/* + * SQLGetInfo + */ +#if (ODBCVER >= 0x0300) +#define SQL_MAX_DRIVER_CONNECTIONS 0 +#define SQL_MAXIMUM_DRIVER_CONNECTIONS SQL_MAX_DRIVER_CONNECTIONS +#define SQL_MAX_CONCURRENT_ACTIVITIES 1 +#define SQL_MAXIMUM_CONCURRENT_ACTIVITIES SQL_MAX_CONCURRENT_ACTIVITIES +#endif /* ODBCVER >= 0x0300 */ +#define SQL_DATA_SOURCE_NAME 2 +#define SQL_FETCH_DIRECTION 8 +#define SQL_SERVER_NAME 13 +#define SQL_SEARCH_PATTERN_ESCAPE 14 +#define SQL_DBMS_NAME 17 +#define SQL_DBMS_VER 18 +#define SQL_ACCESSIBLE_TABLES 19 +#define SQL_ACCESSIBLE_PROCEDURES 20 +#define SQL_CURSOR_COMMIT_BEHAVIOR 23 +#define SQL_DATA_SOURCE_READ_ONLY 25 +#define SQL_DEFAULT_TXN_ISOLATION 26 +#define SQL_IDENTIFIER_CASE 28 +#define SQL_IDENTIFIER_QUOTE_CHAR 29 +#define SQL_MAX_COLUMN_NAME_LEN 30 +#define SQL_MAXIMUM_COLUMN_NAME_LENGTH SQL_MAX_COLUMN_NAME_LEN +#define SQL_MAX_CURSOR_NAME_LEN 31 +#define SQL_MAXIMUM_CURSOR_NAME_LENGTH SQL_MAX_CURSOR_NAME_LEN +#define SQL_MAX_SCHEMA_NAME_LEN 32 +#define SQL_MAXIMUM_SCHEMA_NAME_LENGTH SQL_MAX_SCHEMA_NAME_LEN +#define SQL_MAX_CATALOG_NAME_LEN 34 +#define SQL_MAXIMUM_CATALOG_NAME_LENGTH SQL_MAX_CATALOG_NAME_LEN +#define SQL_MAX_TABLE_NAME_LEN 35 +#define SQL_SCROLL_CONCURRENCY 43 +#define SQL_TXN_CAPABLE 46 +#define SQL_TRANSACTION_CAPABLE SQL_TXN_CAPABLE +#define SQL_USER_NAME 47 +#define SQL_TXN_ISOLATION_OPTION 72 +#define SQL_TRANSACTION_ISOLATION_OPTION SQL_TXN_ISOLATION_OPTION +#define SQL_INTEGRITY 73 +#define SQL_GETDATA_EXTENSIONS 81 +#define SQL_NULL_COLLATION 85 +#define SQL_ALTER_TABLE 86 +#define SQL_ORDER_BY_COLUMNS_IN_SELECT 90 +#define SQL_SPECIAL_CHARACTERS 94 +#define SQL_MAX_COLUMNS_IN_GROUP_BY 97 +#define SQL_MAXIMUM_COLUMNS_IN_GROUP_BY SQL_MAX_COLUMNS_IN_GROUP_BY +#define SQL_MAX_COLUMNS_IN_INDEX 98 +#define SQL_MAXIMUM_COLUMNS_IN_INDEX SQL_MAX_COLUMNS_IN_INDEX +#define SQL_MAX_COLUMNS_IN_ORDER_BY 99 +#define SQL_MAXIMUM_COLUMNS_IN_ORDER_BY SQL_MAX_COLUMNS_IN_ORDER_BY +#define SQL_MAX_COLUMNS_IN_SELECT 100 +#define SQL_MAXIMUM_COLUMNS_IN_SELECT SQL_MAX_COLUMNS_IN_SELECT +#define SQL_MAX_COLUMNS_IN_TABLE 101 +#define SQL_MAX_INDEX_SIZE 102 +#define SQL_MAXIMUM_INDEX_SIZE SQL_MAX_INDEX_SIZE +#define SQL_MAX_ROW_SIZE 104 +#define SQL_MAXIMUM_ROW_SIZE SQL_MAX_ROW_SIZE +#define SQL_MAX_STATEMENT_LEN 105 +#define SQL_MAXIMUM_STATEMENT_LENGTH SQL_MAX_STATEMENT_LEN +#define SQL_MAX_TABLES_IN_SELECT 106 +#define SQL_MAXIMUM_TABLES_IN_SELECT SQL_MAX_TABLES_IN_SELECT +#define SQL_MAX_USER_NAME_LEN 107 +#define SQL_MAXIMUM_USER_NAME_LENGTH SQL_MAX_USER_NAME_LEN +#if (ODBCVER >= 0x0300) +#define SQL_OJ_CAPABILITIES 115 +#define SQL_OUTER_JOIN_CAPABILITIES SQL_OJ_CAPABILITIES +#endif /* ODBCVER >= 0x0300 */ + +#if (ODBCVER >= 0x0300) +#define SQL_XOPEN_CLI_YEAR 10000 +#define SQL_CURSOR_SENSITIVITY 10001 +#define SQL_DESCRIBE_PARAMETER 10002 +#define SQL_CATALOG_NAME 10003 +#define SQL_COLLATION_SEQ 10004 +#define SQL_MAX_IDENTIFIER_LEN 10005 +#define SQL_MAXIMUM_IDENTIFIER_LENGTH SQL_MAX_IDENTIFIER_LEN +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_ALTER_TABLE + */ +#if (ODBCVER >= 0x0200) +#define SQL_AT_ADD_COLUMN 0x00000001L +#define SQL_AT_DROP_COLUMN 0x00000002L +#endif /* ODBCVER >= 0x0300 */ + +#if (ODBCVER >= 0x0300) +#define SQL_AT_ADD_CONSTRAINT 0x00000008L +/* + * The following bitmasks are ODBC extensions and defined in sqlext.h: + * + * #define SQL_AT_COLUMN_SINGLE 0x00000020L + * #define SQL_AT_ADD_COLUMN_DEFAULT 0x00000040L + * #define SQL_AT_ADD_COLUMN_COLLATION 0x00000080L + * #define SQL_AT_SET_COLUMN_DEFAULT 0x00000100L + * #define SQL_AT_DROP_COLUMN_DEFAULT 0x00000200L + * #define SQL_AT_DROP_COLUMN_CASCADE 0x00000400L + * #define SQL_AT_DROP_COLUMN_RESTRICT 0x00000800L + * #define SQL_AT_ADD_TABLE_CONSTRAINT 0x00001000L + * #define SQL_AT_DROP_TABLE_CONSTRAINT_CASCADE 0x00002000L + * #define SQL_AT_DROP_TABLE_CONSTRAINT_RESTRICT 0x00004000L + * #define SQL_AT_CONSTRAINT_NAME_DEFINITION 0x00008000L + * #define SQL_AT_CONSTRAINT_INITIALLY_DEFERRED 0x00010000L + * #define SQL_AT_CONSTRAINT_INITIALLY_IMMEDIATE 0x00020000L + * #define SQL_AT_CONSTRAINT_DEFERRABLE 0x00040000L + * #define SQL_AT_CONSTRAINT_NON_DEFERRABLE 0x00080000L + */ +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_ASYNC_MODE + */ +#if (ODBCVER >= 0x0300) +#define SQL_AM_NONE 0 +#define SQL_AM_CONNECTION 1 +#define SQL_AM_STATEMENT 2 +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_CURSOR_COMMIT_BEHAVIOR + */ +#define SQL_CB_DELETE 0 +#define SQL_CB_CLOSE 1 +#define SQL_CB_PRESERVE 2 + + +/* + * SQLGetInfo - SQL_FETCH_DIRECTION + */ +#define SQL_FD_FETCH_NEXT 0x00000001L +#define SQL_FD_FETCH_FIRST 0x00000002L +#define SQL_FD_FETCH_LAST 0x00000004L +#define SQL_FD_FETCH_PRIOR 0x00000008L +#define SQL_FD_FETCH_ABSOLUTE 0x00000010L +#define SQL_FD_FETCH_RELATIVE 0x00000020L + + +/* + * SQLGetInfo - SQL_GETDATA_EXTENSIONS + */ +#define SQL_GD_ANY_COLUMN 0x00000001L +#define SQL_GD_ANY_ORDER 0x00000002L + + +/* + * SQLGetInfo - SQL_IDENTIFIER_CASE + */ +#define SQL_IC_UPPER 1 +#define SQL_IC_LOWER 2 +#define SQL_IC_SENSITIVE 3 +#define SQL_IC_MIXED 4 + + +/* + * SQLGetInfo - SQL_NULL_COLLATION + */ +#define SQL_NC_HIGH 0 +#define SQL_NC_LOW 1 + + +/* + * SQLGetInfo - SQL_OJ_CAPABILITIES + */ +#if (ODBCVER >= 0x0201) +#define SQL_OJ_LEFT 0x00000001L +#define SQL_OJ_RIGHT 0x00000002L +#define SQL_OJ_FULL 0x00000004L +#define SQL_OJ_NESTED 0x00000008L +#define SQL_OJ_NOT_ORDERED 0x00000010L +#define SQL_OJ_INNER 0x00000020L +#define SQL_OJ_ALL_COMPARISON_OPS 0x00000040L +#endif + + +/* + * SQLGetInfo - SQL_SCROLL_CONCURRENCY + */ +#define SQL_SCCO_READ_ONLY 0x00000001L +#define SQL_SCCO_LOCK 0x00000002L +#define SQL_SCCO_OPT_ROWVER 0x00000004L +#define SQL_SCCO_OPT_VALUES 0x00000008L + + +/* + * SQLGetInfo - SQL_TXN_CAPABLE + */ +#define SQL_TC_NONE 0 +#define SQL_TC_DML 1 +#define SQL_TC_ALL 2 +#define SQL_TC_DDL_COMMIT 3 +#define SQL_TC_DDL_IGNORE 4 + + +/* + * SQLGetInfo - SQL_TXN_ISOLATION_OPTION + */ +#define SQL_TXN_READ_UNCOMMITTED 0x00000001L +#define SQL_TRANSACTION_READ_UNCOMMITTED SQL_TXN_READ_UNCOMMITTED +#define SQL_TXN_READ_COMMITTED 0x00000002L +#define SQL_TRANSACTION_READ_COMMITTED SQL_TXN_READ_COMMITTED +#define SQL_TXN_REPEATABLE_READ 0x00000004L +#define SQL_TRANSACTION_REPEATABLE_READ SQL_TXN_REPEATABLE_READ +#define SQL_TXN_SERIALIZABLE 0x00000008L +#define SQL_TRANSACTION_SERIALIZABLE SQL_TXN_SERIALIZABLE + + +/* + * SQLGetStmtAttr - statement attributes + */ +#if (ODBCVER >= 0x0300) +#define SQL_ATTR_APP_ROW_DESC 10010 +#define SQL_ATTR_APP_PARAM_DESC 10011 +#define SQL_ATTR_IMP_ROW_DESC 10012 +#define SQL_ATTR_IMP_PARAM_DESC 10013 +#define SQL_ATTR_CURSOR_SCROLLABLE (-1) +#define SQL_ATTR_CURSOR_SENSITIVITY (-2) +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetStmtAttr - SQL_ATTR_CURSOR_SCROLLABLE + */ +#if (ODBCVER >= 0x0300) +#define SQL_NONSCROLLABLE 0 +#define SQL_SCROLLABLE 1 +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetStmtAttr - SQL_ATTR_CURSOR_SENSITIVITY + */ +#if (ODBCVER >= 0x0300) +#define SQL_UNSPECIFIED 0 +#define SQL_INSENSITIVE 1 +#define SQL_SENSITIVE 2 +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetTypeInfo - SEARCHABLE + */ +#if (ODBCVER >= 0x0300) +#define SQL_PRED_NONE 0 +#define SQL_PRED_CHAR 1 +#define SQL_PRED_BASIC 2 +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLSpecialColumns - Column scopes + */ +#define SQL_SCOPE_CURROW 0 +#define SQL_SCOPE_TRANSACTION 1 +#define SQL_SCOPE_SESSION 2 + + +/* + * SQLSpecialColumns - PSEUDO_COLUMN + */ +#define SQL_PC_UNKNOWN 0 +#if (ODBCVER >= 0x0300) +#define SQL_PC_NON_PSEUDO 1 +#endif /* ODBCVER >= 0x0300 */ +#define SQL_PC_PSEUDO 2 + + +/* + * SQLSpecialColumns - IdentifierType + */ +#if (ODBCVER >= 0x0300) +#define SQL_ROW_IDENTIFIER 1 +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLStatistics - fUnique + */ +#define SQL_INDEX_UNIQUE 0 +#define SQL_INDEX_ALL 1 + + +/* + * SQLStatistics - TYPE + */ +#define SQL_INDEX_CLUSTERED 1 +#define SQL_INDEX_HASHED 2 +#define SQL_INDEX_OTHER 3 + + +/* + * SQLTransact/SQLEndTran + */ +#define SQL_COMMIT 0 +#define SQL_ROLLBACK 1 + + +/* + * Function Prototypes + */ +SQLRETURN SQL_API SQLAllocConnect ( + SQLHENV EnvironmentHandle, + SQLHDBC * ConnectionHandle); + +SQLRETURN SQL_API SQLAllocEnv ( + SQLHENV * EnvironmentHandle); + +#if (ODBCVER >= 0x0300) +SQLRETURN SQL_API SQLAllocHandle ( + SQLSMALLINT HandleType, + SQLHANDLE InputHandle, + SQLHANDLE * OutputHandle); +#endif /* ODBCVER >= 0x0300 */ + +SQLRETURN SQL_API SQLAllocStmt ( + SQLHDBC ConnectionHandle, + SQLHSTMT * StatementHandle); + +SQLRETURN SQL_API SQLBindCol ( + SQLHSTMT StatementHandle, + SQLUSMALLINT ColumnNumber, + SQLSMALLINT TargetType, + SQLPOINTER TargetValue, + SQLLEN BufferLength, + SQLLEN * StrLen_or_Ind); + +#if (ODBCVER >= 0x0300) +SQLRETURN SQL_API SQLBindParam ( + SQLHSTMT StatementHandle, + SQLUSMALLINT ParameterNumber, + SQLSMALLINT ValueType, + SQLSMALLINT ParameterType, + SQLULEN LengthPrecision, + SQLSMALLINT ParameterScale, + SQLPOINTER ParameterValue, + SQLLEN * StrLen_or_Ind); +#endif + +SQLRETURN SQL_API SQLCancel ( + SQLHSTMT StatementHandle); + +#if (ODBCVER >= 0x0300) +SQLRETURN SQL_API SQLCloseCursor ( + SQLHSTMT StatementHandle); + +/* + * Using SQLLEN * instead of SQLPOINTER for NumericAttribute, + * makes the prototype the same as SQLColAttributes (deprecated) + * and clearer for 64bit ports + */ +SQLRETURN SQL_API SQLColAttribute ( + SQLHSTMT StatementHandle, + SQLUSMALLINT ColumnNumber, + SQLUSMALLINT FieldIdentifier, + SQLPOINTER CharacterAttribute, + SQLSMALLINT BufferLength, + SQLSMALLINT * StringLength, + SQLLEN * NumericAttribute); +#endif + +SQLRETURN SQL_API SQLColumns ( + SQLHSTMT StatementHandle, + SQLCHAR * CatalogName, + SQLSMALLINT NameLength1, + SQLCHAR * SchemaName, + SQLSMALLINT NameLength2, + SQLCHAR * TableName, + SQLSMALLINT NameLength3, + SQLCHAR * ColumnName, + SQLSMALLINT NameLength4); + +SQLRETURN SQL_API SQLConnect ( + SQLHDBC ConnectionHandle, + SQLCHAR * ServerName, + SQLSMALLINT NameLength1, + SQLCHAR * UserName, + SQLSMALLINT NameLength2, + SQLCHAR * Authentication, + SQLSMALLINT NameLength3); + +#if (ODBCVER >= 0x0300) +SQLRETURN SQL_API SQLCopyDesc ( + SQLHDESC SourceDescHandle, + SQLHDESC TargetDescHandle); +#endif + +SQLRETURN SQL_API SQLDataSources ( + SQLHENV EnvironmentHandle, + SQLUSMALLINT Direction, + SQLCHAR * ServerName, + SQLSMALLINT BufferLength1, + SQLSMALLINT * NameLength1, + SQLCHAR * Description, + SQLSMALLINT BufferLength2, + SQLSMALLINT * NameLength2); + +SQLRETURN SQL_API SQLDescribeCol ( + SQLHSTMT StatementHandle, + SQLUSMALLINT ColumnNumber, + SQLCHAR * ColumnName, + SQLSMALLINT BufferLength, + SQLSMALLINT * NameLength, + SQLSMALLINT * DataType, + SQLULEN * ColumnSize, + SQLSMALLINT * DecimalDigits, + SQLSMALLINT * Nullable); + +SQLRETURN SQL_API SQLDisconnect ( + SQLHDBC ConnectionHandle); + +#if (ODBCVER >= 0x0300) +SQLRETURN SQL_API SQLEndTran ( + SQLSMALLINT HandleType, + SQLHANDLE Handle, + SQLSMALLINT CompletionType); +#endif + +SQLRETURN SQL_API SQLError ( + SQLHENV EnvironmentHandle, + SQLHDBC ConnectionHandle, + SQLHSTMT StatementHandle, + SQLCHAR * Sqlstate, + SQLINTEGER * NativeError, + SQLCHAR * MessageText, + SQLSMALLINT BufferLength, + SQLSMALLINT * TextLength); + +SQLRETURN SQL_API SQLExecDirect ( + SQLHSTMT StatementHandle, + SQLCHAR * StatementText, + SQLINTEGER TextLength); + +SQLRETURN SQL_API SQLExecute ( + SQLHSTMT StatementHandle); + +SQLRETURN SQL_API SQLFetch ( + SQLHSTMT StatementHandle); + +#if (ODBCVER >= 0x0300) +SQLRETURN SQL_API SQLFetchScroll ( + SQLHSTMT StatementHandle, + SQLSMALLINT FetchOrientation, + SQLLEN FetchOffset); +#endif + +SQLRETURN SQL_API SQLFreeConnect ( + SQLHDBC ConnectionHandle); + +SQLRETURN SQL_API SQLFreeEnv ( + SQLHENV EnvironmentHandle); + +#if (ODBCVER >= 0x0300) +SQLRETURN SQL_API SQLFreeHandle ( + SQLSMALLINT HandleType, + SQLHANDLE Handle); +#endif + +SQLRETURN SQL_API SQLFreeStmt ( + SQLHSTMT StatementHandle, + SQLUSMALLINT Option); + +#if (ODBCVER >= 0x0300) +SQLRETURN SQL_API SQLGetConnectAttr ( + SQLHDBC ConnectionHandle, + SQLINTEGER Attribute, + SQLPOINTER Value, + SQLINTEGER BufferLength, + SQLINTEGER * StringLength); +#endif + +SQLRETURN SQL_API SQLGetConnectOption ( + SQLHDBC ConnectionHandle, + SQLUSMALLINT Option, + SQLPOINTER Value); + +SQLRETURN SQL_API SQLGetCursorName ( + SQLHSTMT StatementHandle, + SQLCHAR * CursorName, + SQLSMALLINT BufferLength, + SQLSMALLINT * NameLength); + +SQLRETURN SQL_API SQLGetData ( + SQLHSTMT StatementHandle, + SQLUSMALLINT ColumnNumber, + SQLSMALLINT TargetType, + SQLPOINTER TargetValue, + SQLLEN BufferLength, + SQLLEN * StrLen_or_Ind); + +#if (ODBCVER >= 0x0300) +SQLRETURN SQL_API SQLGetDescField ( + SQLHDESC DescriptorHandle, + SQLSMALLINT RecNumber, + SQLSMALLINT FieldIdentifier, + SQLPOINTER Value, + SQLINTEGER BufferLength, + SQLINTEGER * StringLength); + +SQLRETURN SQL_API SQLGetDescRec ( + SQLHDESC DescriptorHandle, + SQLSMALLINT RecNumber, + SQLCHAR * Name, + SQLSMALLINT BufferLength, + SQLSMALLINT * StringLength, + SQLSMALLINT * Type, + SQLSMALLINT * SubType, + SQLLEN * Length, + SQLSMALLINT * Precision, + SQLSMALLINT * Scale, + SQLSMALLINT * Nullable); + +SQLRETURN SQL_API SQLGetDiagField ( + SQLSMALLINT HandleType, + SQLHANDLE Handle, + SQLSMALLINT RecNumber, + SQLSMALLINT DiagIdentifier, + SQLPOINTER DiagInfo, + SQLSMALLINT BufferLength, + SQLSMALLINT * StringLength); + +SQLRETURN SQL_API SQLGetDiagRec ( + SQLSMALLINT HandleType, + SQLHANDLE Handle, + SQLSMALLINT RecNumber, + SQLCHAR * Sqlstate, + SQLINTEGER * NativeError, + SQLCHAR * MessageText, + SQLSMALLINT BufferLength, + SQLSMALLINT * TextLength); + +SQLRETURN SQL_API SQLGetEnvAttr ( + SQLHENV EnvironmentHandle, + SQLINTEGER Attribute, + SQLPOINTER Value, + SQLINTEGER BufferLength, + SQLINTEGER * StringLength); +#endif /* ODBCVER >= 0x0300 */ + +SQLRETURN SQL_API SQLGetFunctions ( + SQLHDBC ConnectionHandle, + SQLUSMALLINT FunctionId, + SQLUSMALLINT * Supported); + +SQLRETURN SQL_API SQLGetInfo ( + SQLHDBC ConnectionHandle, + SQLUSMALLINT InfoType, + SQLPOINTER InfoValue, + SQLSMALLINT BufferLength, + SQLSMALLINT * StringLength); + +#if (ODBCVER >= 0x0300) +SQLRETURN SQL_API SQLGetStmtAttr ( + SQLHSTMT StatementHandle, + SQLINTEGER Attribute, + SQLPOINTER Value, + SQLINTEGER BufferLength, + SQLINTEGER * StringLength); +#endif /* ODBCVER >= 0x0300 */ + +SQLRETURN SQL_API SQLGetStmtOption ( + SQLHSTMT StatementHandle, + SQLUSMALLINT Option, + SQLPOINTER Value); + +SQLRETURN SQL_API SQLGetTypeInfo ( + SQLHSTMT StatementHandle, + SQLSMALLINT DataType); + +SQLRETURN SQL_API SQLNumResultCols ( + SQLHSTMT StatementHandle, + SQLSMALLINT * ColumnCount); + +SQLRETURN SQL_API SQLParamData ( + SQLHSTMT StatementHandle, + SQLPOINTER * Value); + +SQLRETURN SQL_API SQLPrepare ( + SQLHSTMT StatementHandle, + SQLCHAR * StatementText, + SQLINTEGER TextLength); + +SQLRETURN SQL_API SQLPutData ( + SQLHSTMT StatementHandle, + SQLPOINTER Data, + SQLLEN StrLen_or_Ind); + +SQLRETURN SQL_API SQLRowCount ( + SQLHSTMT StatementHandle, + SQLLEN * RowCount); + +#if (ODBCVER >= 0x0300) +SQLRETURN SQL_API SQLSetConnectAttr ( + SQLHDBC ConnectionHandle, + SQLINTEGER Attribute, + SQLPOINTER Value, + SQLINTEGER StringLength); +#endif /* ODBCVER >= 0x0300 */ + +SQLRETURN SQL_API SQLSetConnectOption ( + SQLHDBC ConnectionHandle, + SQLUSMALLINT Option, + SQLULEN Value); + +SQLRETURN SQL_API SQLSetCursorName ( + SQLHSTMT StatementHandle, + SQLCHAR * CursorName, + SQLSMALLINT NameLength); + +#if (ODBCVER >= 0x0300) +SQLRETURN SQL_API SQLSetDescField ( + SQLHDESC DescriptorHandle, + SQLSMALLINT RecNumber, + SQLSMALLINT FieldIdentifier, + SQLPOINTER Value, + SQLINTEGER BufferLength); + +SQLRETURN SQL_API SQLSetDescRec ( + SQLHDESC DescriptorHandle, + SQLSMALLINT RecNumber, + SQLSMALLINT Type, + SQLSMALLINT SubType, + SQLLEN Length, + SQLSMALLINT Precision, + SQLSMALLINT Scale, + SQLPOINTER Data, + SQLLEN * StringLength, + SQLLEN * Indicator); + +SQLRETURN SQL_API SQLSetEnvAttr ( + SQLHENV EnvironmentHandle, + SQLINTEGER Attribute, + SQLPOINTER Value, + SQLINTEGER StringLength); +#endif /* ODBCVER >= 0x0300 */ + + +#if (ODBCVER >= 0x0300) +SQLRETURN SQL_API SQLSetStmtAttr ( + SQLHSTMT StatementHandle, + SQLINTEGER Attribute, + SQLPOINTER Value, + SQLINTEGER StringLength); +#endif + +SQLRETURN SQL_API SQLSetStmtOption ( + SQLHSTMT StatementHandle, + SQLUSMALLINT Option, + SQLULEN Value); + +SQLRETURN SQL_API SQLSpecialColumns ( + SQLHSTMT StatementHandle, + SQLUSMALLINT IdentifierType, + SQLCHAR * CatalogName, + SQLSMALLINT NameLength1, + SQLCHAR * SchemaName, + SQLSMALLINT NameLength2, + SQLCHAR * TableName, + SQLSMALLINT NameLength3, + SQLUSMALLINT Scope, + SQLUSMALLINT Nullable); + +SQLRETURN SQL_API SQLStatistics ( + SQLHSTMT StatementHandle, + SQLCHAR * CatalogName, + SQLSMALLINT NameLength1, + SQLCHAR * SchemaName, + SQLSMALLINT NameLength2, + SQLCHAR * TableName, + SQLSMALLINT NameLength3, + SQLUSMALLINT Unique, + SQLUSMALLINT Reserved); + +SQLRETURN SQL_API SQLTables ( + SQLHSTMT StatementHandle, + SQLCHAR * CatalogName, + SQLSMALLINT NameLength1, + SQLCHAR * SchemaName, + SQLSMALLINT NameLength2, + SQLCHAR * TableName, + SQLSMALLINT NameLength3, + SQLCHAR * TableType, + SQLSMALLINT NameLength4); + +SQLRETURN SQL_API SQLTransact ( + SQLHENV EnvironmentHandle, + SQLHDBC ConnectionHandle, + SQLUSMALLINT CompletionType); + + +/* + * Depreciated ODBC 1.0 function - Use SQLBindParameter + */ +SQLRETURN SQL_API SQLSetParam ( + SQLHSTMT StatementHandle, + SQLUSMALLINT ParameterNumber, + SQLSMALLINT ValueType, + SQLSMALLINT ParameterType, + SQLULEN LengthPrecision, + SQLSMALLINT ParameterScale, + SQLPOINTER ParameterValue, + SQLLEN * StrLen_or_Ind); + +#ifdef __cplusplus +} +#endif + +#endif /* _SQL_H */ diff --git a/libodbc/include/odbc_linux/sqlext.h b/libodbc/include/odbc_linux/sqlext.h new file mode 100644 index 0000000000..9b9de1fe62 --- /dev/null +++ b/libodbc/include/odbc_linux/sqlext.h @@ -0,0 +1,2572 @@ +/* + * sqlext.h + * + * $Id: sqlext.h,v 1.3 2013/09/01 17:11:20 yas Exp $ + * + * ODBC defines (ext) + * + * The iODBC driver manager. + * + * Copyright (C) 1995 by Ke Jin + * Copyright (C) 1996-2009 by OpenLink Software + * All Rights Reserved. + * + * This software is released under the terms of either of the following + * licenses: + * + * - GNU Library General Public License (see LICENSE.LGPL) + * - The BSD License (see LICENSE.BSD). + * + * Note that the only valid version of the LGPL license as far as this + * project is concerned is the original GNU Library General Public License + * Version 2, dated June 1991. + * + * While not mandated by the BSD license, any patches you make to the + * iODBC source code may be contributed back into the iODBC project + * at your discretion. Contributions will benefit the Open Source and + * Data Access community as a whole. Submissions may be made at: + * + * http://www.iodbc.org + * + * + * GNU Library Generic Public License Version 2 + * ============================================ + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; only + * Version 2 of the License dated June 1991. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * + * The BSD License + * =============== + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name of OpenLink Software Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL OPENLINK OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _SQLEXT_H +#define _SQLEXT_H + +#ifndef _SQL_H +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +/* + * Useful Constants + */ +#define SQL_SPEC_MAJOR 3 +#define SQL_SPEC_MINOR 52 +#define SQL_SPEC_STRING "03.52" + +#define SQL_SQLSTATE_SIZE 5 +#define SQL_MAX_DSN_LENGTH 32 +#define SQL_MAX_OPTION_STRING_LENGTH 256 + + +/* + * Handle types + */ +#if (ODBCVER >= 0x0300) +#define SQL_HANDLE_SENV 5 +#endif /* ODBCVER >= 0x0300 */ + + +/* + * Function return codes + */ +#if (ODBCVER < 0x0300) +#define SQL_NO_DATA_FOUND 100 +#else +#define SQL_NO_DATA_FOUND SQL_NO_DATA +#endif /* ODBCVER < 0x0300 */ + + +/* + * Special length values for attributes + */ +#if (ODBCVER >= 0x0300) +#define SQL_IS_POINTER (-4) +#define SQL_IS_UINTEGER (-5) +#define SQL_IS_INTEGER (-6) +#define SQL_IS_USMALLINT (-7) +#define SQL_IS_SMALLINT (-8) +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQL extended datatypes + */ +#define SQL_DATE 9 +#if (ODBCVER >= 0x0300) +#define SQL_INTERVAL 10 +#endif /* ODBCVER >= 0x0300 */ +#define SQL_TIME 10 +#define SQL_TIMESTAMP 11 +#define SQL_LONGVARCHAR (-1) +#define SQL_BINARY (-2) +#define SQL_VARBINARY (-3) +#define SQL_LONGVARBINARY (-4) +#define SQL_BIGINT (-5) +#define SQL_TINYINT (-6) +#define SQL_BIT (-7) +#if (ODBCVER >= 0x0350) +#define SQL_GUID (-11) +#endif /* ODBCVER >= 0x0350 */ + + +/* + * SQL Interval datatypes + */ +#if (ODBCVER >= 0x0300) +#define SQL_CODE_YEAR 1 +#define SQL_CODE_MONTH 2 +#define SQL_CODE_DAY 3 +#define SQL_CODE_HOUR 4 +#define SQL_CODE_MINUTE 5 +#define SQL_CODE_SECOND 6 +#define SQL_CODE_YEAR_TO_MONTH 7 +#define SQL_CODE_DAY_TO_HOUR 8 +#define SQL_CODE_DAY_TO_MINUTE 9 +#define SQL_CODE_DAY_TO_SECOND 10 +#define SQL_CODE_HOUR_TO_MINUTE 11 +#define SQL_CODE_HOUR_TO_SECOND 12 +#define SQL_CODE_MINUTE_TO_SECOND 13 + +#define SQL_INTERVAL_YEAR (100 + SQL_CODE_YEAR) +#define SQL_INTERVAL_MONTH (100 + SQL_CODE_MONTH) +#define SQL_INTERVAL_DAY (100 + SQL_CODE_DAY) +#define SQL_INTERVAL_HOUR (100 + SQL_CODE_HOUR) +#define SQL_INTERVAL_MINUTE (100 + SQL_CODE_MINUTE) +#define SQL_INTERVAL_SECOND (100 + SQL_CODE_SECOND) +#define SQL_INTERVAL_YEAR_TO_MONTH (100 + SQL_CODE_YEAR_TO_MONTH) +#define SQL_INTERVAL_DAY_TO_HOUR (100 + SQL_CODE_DAY_TO_HOUR) +#define SQL_INTERVAL_DAY_TO_MINUTE (100 + SQL_CODE_DAY_TO_MINUTE) +#define SQL_INTERVAL_DAY_TO_SECOND (100 + SQL_CODE_DAY_TO_SECOND) +#define SQL_INTERVAL_HOUR_TO_MINUTE (100 + SQL_CODE_HOUR_TO_MINUTE) +#define SQL_INTERVAL_HOUR_TO_SECOND (100 + SQL_CODE_HOUR_TO_SECOND) +#define SQL_INTERVAL_MINUTE_TO_SECOND (100 + SQL_CODE_MINUTE_TO_SECOND) +#else +#define SQL_INTERVAL_YEAR (-80) +#define SQL_INTERVAL_MONTH (-81) +#define SQL_INTERVAL_YEAR_TO_MONTH (-82) +#define SQL_INTERVAL_DAY (-83) +#define SQL_INTERVAL_HOUR (-84) +#define SQL_INTERVAL_MINUTE (-85) +#define SQL_INTERVAL_SECOND (-86) +#define SQL_INTERVAL_DAY_TO_HOUR (-87) +#define SQL_INTERVAL_DAY_TO_MINUTE (-88) +#define SQL_INTERVAL_DAY_TO_SECOND (-89) +#define SQL_INTERVAL_HOUR_TO_MINUTE (-90) +#define SQL_INTERVAL_HOUR_TO_SECOND (-91) +#define SQL_INTERVAL_MINUTE_TO_SECOND (-92) +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQL unicode data types + */ +#if (ODBCVER <= 0x0300) +/* These definitions are historical and obsolete */ +#define SQL_UNICODE (-95) +#define SQL_UNICODE_VARCHAR (-96) +#define SQL_UNICODE_LONGVARCHAR (-97) +#define SQL_UNICODE_CHAR SQL_UNICODE +#else +#define SQL_UNICODE SQL_WCHAR +#define SQL_UNICODE_VARCHAR SQL_WVARCHAR +#define SQL_UNICODE_LONGVARCHAR SQL_WLONGVARCHAR +#define SQL_UNICODE_CHAR SQL_WCHAR +#endif /* ODBCVER >= 0x0300 */ + + +#if (ODBCVER < 0x0300) +#define SQL_TYPE_DRIVER_START SQL_INTERVAL_YEAR +#define SQL_TYPE_DRIVER_END SQL_UNICODE_LONGVARCHAR +#endif /* ODBCVER < 0x0300 */ + + +#define SQL_SIGNED_OFFSET (-20) +#define SQL_UNSIGNED_OFFSET (-22) + + +/* + * C datatype to SQL datatype mapping + */ +#define SQL_C_CHAR SQL_CHAR +#define SQL_C_LONG SQL_INTEGER +#define SQL_C_SHORT SQL_SMALLINT +#define SQL_C_FLOAT SQL_REAL +#define SQL_C_DOUBLE SQL_DOUBLE +#if (ODBCVER >= 0x0300) +#define SQL_C_NUMERIC SQL_NUMERIC +#endif /* ODBCVER >= 0x0300 */ +#define SQL_C_DEFAULT 99 + + +#define SQL_C_DATE SQL_DATE +#define SQL_C_TIME SQL_TIME +#define SQL_C_TIMESTAMP SQL_TIMESTAMP +#define SQL_C_BINARY SQL_BINARY +#define SQL_C_BIT SQL_BIT +#define SQL_C_TINYINT SQL_TINYINT +#define SQL_C_SLONG (SQL_C_LONG+SQL_SIGNED_OFFSET) +#define SQL_C_SSHORT (SQL_C_SHORT+SQL_SIGNED_OFFSET) +#define SQL_C_STINYINT (SQL_TINYINT+SQL_SIGNED_OFFSET) +#define SQL_C_ULONG (SQL_C_LONG+SQL_UNSIGNED_OFFSET) +#define SQL_C_USHORT (SQL_C_SHORT+SQL_UNSIGNED_OFFSET) +#define SQL_C_UTINYINT (SQL_TINYINT+SQL_UNSIGNED_OFFSET) + +#if defined(_WIN64) +#define SQL_C_BOOKMARK SQL_C_UBIGINT +#else +#define SQL_C_BOOKMARK SQL_C_ULONG +#endif + +#if (ODBCVER >= 0x0300) +#define SQL_C_TYPE_DATE SQL_TYPE_DATE +#define SQL_C_TYPE_TIME SQL_TYPE_TIME +#define SQL_C_TYPE_TIMESTAMP SQL_TYPE_TIMESTAMP +#define SQL_C_INTERVAL_YEAR SQL_INTERVAL_YEAR +#define SQL_C_INTERVAL_MONTH SQL_INTERVAL_MONTH +#define SQL_C_INTERVAL_DAY SQL_INTERVAL_DAY +#define SQL_C_INTERVAL_HOUR SQL_INTERVAL_HOUR +#define SQL_C_INTERVAL_MINUTE SQL_INTERVAL_MINUTE +#define SQL_C_INTERVAL_SECOND SQL_INTERVAL_SECOND +#define SQL_C_INTERVAL_YEAR_TO_MONTH SQL_INTERVAL_YEAR_TO_MONTH +#define SQL_C_INTERVAL_DAY_TO_HOUR SQL_INTERVAL_DAY_TO_HOUR +#define SQL_C_INTERVAL_DAY_TO_MINUTE SQL_INTERVAL_DAY_TO_MINUTE +#define SQL_C_INTERVAL_DAY_TO_SECOND SQL_INTERVAL_DAY_TO_SECOND +#define SQL_C_INTERVAL_HOUR_TO_MINUTE SQL_INTERVAL_HOUR_TO_MINUTE +#define SQL_C_INTERVAL_HOUR_TO_SECOND SQL_INTERVAL_HOUR_TO_SECOND +#define SQL_C_INTERVAL_MINUTE_TO_SECOND SQL_INTERVAL_MINUTE_TO_SECOND +#define SQL_C_SBIGINT (SQL_BIGINT+SQL_SIGNED_OFFSET) +#define SQL_C_UBIGINT (SQL_BIGINT+SQL_UNSIGNED_OFFSET) +#define SQL_C_VARBOOKMARK SQL_C_BINARY +#endif /* ODBCVER >= 0x0300 */ + +#if (ODBCVER >= 0x0350) +#define SQL_C_GUID SQL_GUID +#endif + +#define SQL_TYPE_NULL 0 + +#if (ODBCVER < 0x0300) +#define SQL_TYPE_MIN SQL_BIT +#define SQL_TYPE_MAX SQL_VARCHAR +#endif /* ODBCVER < 0x0300 */ + + +/* + * ---------------------------------------------------------------------- + * Level 1 Functions + * ---------------------------------------------------------------------- + */ + +/* + * SQLBindParameter + */ +#define SQL_DEFAULT_PARAM (-5) +#define SQL_IGNORE (-6) +#if (ODBCVER >= 0x0300) +#define SQL_COLUMN_IGNORE SQL_IGNORE +#endif /* ODBCVER >= 0x0300 */ +#define SQL_LEN_DATA_AT_EXEC_OFFSET (-100) +#define SQL_LEN_DATA_AT_EXEC(length) (-(length)+SQL_LEN_DATA_AT_EXEC_OFFSET) + + +/* + * binary length for driver specific attributes + */ +#define SQL_LEN_BINARY_ATTR_OFFSET (-100) +#define SQL_LEN_BINARY_ATTR(length) (-(length)+SQL_LEN_BINARY_ATTR_OFFSET) + + +/* + * SQLColAttributes - ODBC 2.x defines + */ +#define SQL_COLUMN_COUNT 0 +#define SQL_COLUMN_NAME 1 +#define SQL_COLUMN_TYPE 2 +#define SQL_COLUMN_LENGTH 3 +#define SQL_COLUMN_PRECISION 4 +#define SQL_COLUMN_SCALE 5 +#define SQL_COLUMN_DISPLAY_SIZE 6 +#define SQL_COLUMN_NULLABLE 7 +#define SQL_COLUMN_UNSIGNED 8 +#define SQL_COLUMN_MONEY 9 +#define SQL_COLUMN_UPDATABLE 10 +#define SQL_COLUMN_AUTO_INCREMENT 11 +#define SQL_COLUMN_CASE_SENSITIVE 12 +#define SQL_COLUMN_SEARCHABLE 13 +#define SQL_COLUMN_TYPE_NAME 14 +#define SQL_COLUMN_TABLE_NAME 15 +#define SQL_COLUMN_OWNER_NAME 16 +#define SQL_COLUMN_QUALIFIER_NAME 17 +#define SQL_COLUMN_LABEL 18 +#define SQL_COLATT_OPT_MAX SQL_COLUMN_LABEL +#if (ODBCVER < 0x0300) +#define SQL_COLUMN_DRIVER_START 1000 +#endif /* ODBCVER < 0x0300 */ + +#define SQL_COLATT_OPT_MIN SQL_COLUMN_COUNT + + +/* + * SQLColAttributes - SQL_COLUMN_UPDATABLE + */ +#define SQL_ATTR_READONLY 0 +#define SQL_ATTR_WRITE 1 +#define SQL_ATTR_READWRITE_UNKNOWN 2 + + +/* + * SQLColAttributes - SQL_COLUMN_SEARCHABLE + */ +#define SQL_UNSEARCHABLE 0 +#define SQL_LIKE_ONLY 1 +#define SQL_ALL_EXCEPT_LIKE 2 +#define SQL_SEARCHABLE 3 +#define SQL_PRED_SEARCHABLE SQL_SEARCHABLE + + +/* + * SQLDataSources - additional fetch directions + */ +#if (ODBCVER >= 0x0300) +#define SQL_FETCH_FIRST_USER 31 +#define SQL_FETCH_FIRST_SYSTEM 32 +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLDriverConnect + */ +#define SQL_DRIVER_NOPROMPT 0 +#define SQL_DRIVER_COMPLETE 1 +#define SQL_DRIVER_PROMPT 2 +#define SQL_DRIVER_COMPLETE_REQUIRED 3 + + +/* + * SQLGetConnectAttr - ODBC 2.x attributes + */ +#define SQL_ACCESS_MODE 101 +#define SQL_AUTOCOMMIT 102 +#define SQL_LOGIN_TIMEOUT 103 +#define SQL_OPT_TRACE 104 +#define SQL_OPT_TRACEFILE 105 +#define SQL_TRANSLATE_DLL 106 +#define SQL_TRANSLATE_OPTION 107 +#define SQL_TXN_ISOLATION 108 +#define SQL_CURRENT_QUALIFIER 109 +#define SQL_ODBC_CURSORS 110 +#define SQL_QUIET_MODE 111 +#define SQL_PACKET_SIZE 112 + + +/* + * SQLGetConnectAttr - ODBC 3.0 attributes + */ +#if (ODBCVER >= 0x0300) +#define SQL_ATTR_ACCESS_MODE SQL_ACCESS_MODE +#define SQL_ATTR_AUTOCOMMIT SQL_AUTOCOMMIT +#define SQL_ATTR_CONNECTION_TIMEOUT 113 +#define SQL_ATTR_CURRENT_CATALOG SQL_CURRENT_QUALIFIER +#define SQL_ATTR_DISCONNECT_BEHAVIOR 114 +#define SQL_ATTR_ENLIST_IN_DTC 1207 +#define SQL_ATTR_ENLIST_IN_XA 1208 +#define SQL_ATTR_LOGIN_TIMEOUT SQL_LOGIN_TIMEOUT +#define SQL_ATTR_ODBC_CURSORS SQL_ODBC_CURSORS +#define SQL_ATTR_PACKET_SIZE SQL_PACKET_SIZE +#define SQL_ATTR_QUIET_MODE SQL_QUIET_MODE +#define SQL_ATTR_TRACE SQL_OPT_TRACE +#define SQL_ATTR_TRACEFILE SQL_OPT_TRACEFILE +#define SQL_ATTR_TRANSLATE_LIB SQL_TRANSLATE_DLL +#define SQL_ATTR_TRANSLATE_OPTION SQL_TRANSLATE_OPTION +#define SQL_ATTR_TXN_ISOLATION SQL_TXN_ISOLATION +#endif /* ODBCVER >= 0x0300 */ + +#define SQL_ATTR_CONNECTION_DEAD 1209 /* GetConnectAttr only */ + + +/* + * These options have no meaning for a 3.0 driver + */ +#if (ODBCVER < 0x0300) +#define SQL_CONN_OPT_MIN SQL_ACCESS_MODE +#define SQL_CONN_OPT_MAX SQL_PACKET_SIZE +#define SQL_CONNECT_OPT_DRVR_START 1000 +#endif /* ODBCVER < 0x0300 */ + + +/* + * SQLGetConnectAttr - SQL_ACCESS_MODE + */ +#define SQL_MODE_READ_WRITE 0UL +#define SQL_MODE_READ_ONLY 1UL +#define SQL_MODE_DEFAULT SQL_MODE_READ_WRITE + + +/* + * SQLGetConnectAttr - SQL_AUTOCOMMIT + */ +#define SQL_AUTOCOMMIT_OFF 0UL +#define SQL_AUTOCOMMIT_ON 1UL +#define SQL_AUTOCOMMIT_DEFAULT SQL_AUTOCOMMIT_ON + + +/* + * SQLGetConnectAttr - SQL_LOGIN_TIMEOUT + */ +#define SQL_LOGIN_TIMEOUT_DEFAULT 15UL + + +/* + * SQLGetConnectAttr - SQL_ODBC_CURSORS + */ +#define SQL_CUR_USE_IF_NEEDED 0UL +#define SQL_CUR_USE_ODBC 1UL +#define SQL_CUR_USE_DRIVER 2UL +#define SQL_CUR_DEFAULT SQL_CUR_USE_DRIVER + + +/* + * SQLGetConnectAttr - SQL_OPT_TRACE + */ +#define SQL_OPT_TRACE_OFF 0UL +#define SQL_OPT_TRACE_ON 1UL +#define SQL_OPT_TRACE_DEFAULT SQL_OPT_TRACE_OFF +#if defined (WIN32) +#define SQL_OPT_TRACE_FILE_DEFAULT "\\SQL.LOG" +#define SQL_OPT_TRACE_FILE_DEFAULTW L"\\SQL.LOG" +#else +#define SQL_OPT_TRACE_FILE_DEFAULT "/tmp/odbc.log" +#define SQL_OPT_TRACE_FILE_DEFAULTW L"/tmp/odbc.log" +#endif + + +/* + * SQLGetConnectAttr - SQL_ATTR_ANSI_APP + */ +#if (ODBCVER >= 0x0351) +#define SQL_AA_TRUE 1L /* ANSI app */ +#define SQL_AA_FALSE 0L /* Unicode app */ +#endif + + +/* + * SQLGetConnectAttr - SQL_ATTR_CONNECTION_DEAD + */ +#define SQL_CD_TRUE 1L /* closed/dead */ +#define SQL_CD_FALSE 0L /* open/available */ + + +/* + * SQLGetConnectAttr - SQL_ATTR_DISCONNECT_BEHAVIOR + */ +#if (ODBCVER >= 0x0300) +#define SQL_DB_RETURN_TO_POOL 0UL +#define SQL_DB_DISCONNECT 1UL +#define SQL_DB_DEFAULT SQL_DB_RETURN_TO_POOL +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetConnectAttr - SQL_ATTR_ENLIST_IN_DTC + */ +#if (ODBCVER >= 0x0300) +#define SQL_DTC_DONE 0L +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetConnectAttr - Unicode drivers + */ +#if (ODBCVER >= 0x0351) +#define SQL_ATTR_ANSI_APP 115 +#endif + + +/* + * SQLGetData + */ +#define SQL_NO_TOTAL (-4) + + +/* + * SQLGetDescField - extended descriptor field + */ +#if (ODBCVER >= 0x0300) +#define SQL_DESC_ARRAY_SIZE 20 +#define SQL_DESC_ARRAY_STATUS_PTR 21 +#define SQL_DESC_AUTO_UNIQUE_VALUE SQL_COLUMN_AUTO_INCREMENT +#define SQL_DESC_BASE_COLUMN_NAME 22 +#define SQL_DESC_BASE_TABLE_NAME 23 +#define SQL_DESC_BIND_OFFSET_PTR 24 +#define SQL_DESC_BIND_TYPE 25 +#define SQL_DESC_CASE_SENSITIVE SQL_COLUMN_CASE_SENSITIVE +#define SQL_DESC_CATALOG_NAME SQL_COLUMN_QUALIFIER_NAME +#define SQL_DESC_CONCISE_TYPE SQL_COLUMN_TYPE +#define SQL_DESC_DATETIME_INTERVAL_PRECISION 26 +#define SQL_DESC_DISPLAY_SIZE SQL_COLUMN_DISPLAY_SIZE +#define SQL_DESC_FIXED_PREC_SCALE SQL_COLUMN_MONEY +#define SQL_DESC_LABEL SQL_COLUMN_LABEL +#define SQL_DESC_LITERAL_PREFIX 27 +#define SQL_DESC_LITERAL_SUFFIX 28 +#define SQL_DESC_LOCAL_TYPE_NAME 29 +#define SQL_DESC_MAXIMUM_SCALE 30 +#define SQL_DESC_MINIMUM_SCALE 31 +#define SQL_DESC_NUM_PREC_RADIX 32 +#define SQL_DESC_PARAMETER_TYPE 33 +#define SQL_DESC_ROWS_PROCESSED_PTR 34 +#if (ODBCVER >= 0x0350) +#define SQL_DESC_ROWVER 35 +#endif /* ODBCVER >= 0x0350 */ +#define SQL_DESC_SCHEMA_NAME SQL_COLUMN_OWNER_NAME +#define SQL_DESC_SEARCHABLE SQL_COLUMN_SEARCHABLE +#define SQL_DESC_TYPE_NAME SQL_COLUMN_TYPE_NAME +#define SQL_DESC_TABLE_NAME SQL_COLUMN_TABLE_NAME +#define SQL_DESC_UNSIGNED SQL_COLUMN_UNSIGNED +#define SQL_DESC_UPDATABLE SQL_COLUMN_UPDATABLE +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetDiagField - defines for diagnostics fields + */ +#if (ODBCVER >= 0x0300) +#define SQL_DIAG_CURSOR_ROW_COUNT (-1249) +#define SQL_DIAG_ROW_NUMBER (-1248) +#define SQL_DIAG_COLUMN_NUMBER (-1247) +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetDiagField - SQL_DIAG_ROW_NUMBER and SQL_DIAG_COLUMN_NUMBER + */ +#if (ODBCVER >= 0x0300) +#define SQL_NO_ROW_NUMBER (-1) +#define SQL_NO_COLUMN_NUMBER (-1) +#define SQL_ROW_NUMBER_UNKNOWN (-2) +#define SQL_COLUMN_NUMBER_UNKNOWN (-2) +#endif + + +#if (ODBCVER >= 0x0300) +/* + * SQLGetEnvAttr - Attributes + */ +#define SQL_ATTR_ODBC_VERSION 200 +#define SQL_ATTR_CONNECTION_POOLING 201 +#define SQL_ATTR_CP_MATCH 202 + + +/* + * SQLGetEnvAttr - SQL_ATTR_ODBC_VERSION + */ +#define SQL_OV_ODBC2 2UL +#define SQL_OV_ODBC3 3UL + + +/* + * SQLGetEnvAttr - SQL_ATTR_CONNECTION_POOLING + */ +#define SQL_CP_OFF 0UL +#define SQL_CP_ONE_PER_DRIVER 1UL +#define SQL_CP_ONE_PER_HENV 2UL +#define SQL_CP_DEFAULT SQL_CP_OFF + + +/* + * SQLGetEnvAttr - SQL_ATTR_CP_MATCH + */ +#define SQL_CP_STRICT_MATCH 0UL +#define SQL_CP_RELAXED_MATCH 1UL +#define SQL_CP_MATCH_DEFAULT SQL_CP_STRICT_MATCH +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetFunctions - extensions to the X/Open specification + */ +#if (ODBCVER >= 0x0300) +#define SQL_API_SQLALLOCHANDLESTD 73 +#define SQL_API_SQLBULKOPERATIONS 24 +#endif /* ODBCVER >= 0x0300 */ +#define SQL_API_SQLBINDPARAMETER 72 +#define SQL_API_SQLBROWSECONNECT 55 +#define SQL_API_SQLCOLATTRIBUTES 6 +#define SQL_API_SQLCOLUMNPRIVILEGES 56 +#define SQL_API_SQLDESCRIBEPARAM 58 +#define SQL_API_SQLDRIVERCONNECT 41 +#define SQL_API_SQLDRIVERS 71 +#define SQL_API_SQLEXTENDEDFETCH 59 +#define SQL_API_SQLFOREIGNKEYS 60 +#define SQL_API_SQLMORERESULTS 61 +#define SQL_API_SQLNATIVESQL 62 +#define SQL_API_SQLNUMPARAMS 63 +#define SQL_API_SQLPARAMOPTIONS 64 +#define SQL_API_SQLPRIMARYKEYS 65 +#define SQL_API_SQLPROCEDURECOLUMNS 66 +#define SQL_API_SQLPROCEDURES 67 +#define SQL_API_SQLSETPOS 68 +#define SQL_API_SQLSETSCROLLOPTIONS 69 +#define SQL_API_SQLTABLEPRIVILEGES 70 + + +/* + * These are not useful anymore as the X/Open specification defines + * functions in the 10000 range + */ +#if (ODBCVER < 0x0300) +#define SQL_EXT_API_LAST SQL_API_SQLBINDPARAMETER +#define SQL_NUM_FUNCTIONS 23 +#define SQL_EXT_API_START 40 +#define SQL_NUM_EXTENSIONS (SQL_EXT_API_LAST-SQL_EXT_API_START+1) +#endif /* ODBCVER < 0x0300 */ + + +/* + * SQLGetFunctions - ODBC version 2.x and earlier + */ +#define SQL_API_ALL_FUNCTIONS 0 + + +/* + * Loading by ordinal is not supported for 3.0 and above drivers + */ +#define SQL_API_LOADBYORDINAL 199 + + +/* + * SQLGetFunctions - SQL_API_ODBC3_ALL_FUNCTIONS + */ +#if (ODBCVER >= 0x0300) +#define SQL_API_ODBC3_ALL_FUNCTIONS 999 +#define SQL_API_ODBC3_ALL_FUNCTIONS_SIZE 250 + +#define SQL_FUNC_EXISTS(pfExists, uwAPI) \ + ((*(((UWORD*) (pfExists)) + ((uwAPI) >> 4)) & (1 << ((uwAPI) & 0x000F))) \ + ? SQL_TRUE : SQL_FALSE) +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - ODBC 2.x extensions to the X/Open standard + */ +#define SQL_INFO_FIRST 0 +#define SQL_ACTIVE_CONNECTIONS 0 /* MAX_DRIVER_CONNECTIONS */ +#define SQL_ACTIVE_STATEMENTS 1 /* MAX_CONCURRENT_ACTIVITIES */ +#define SQL_DRIVER_HDBC 3 +#define SQL_DRIVER_HENV 4 +#define SQL_DRIVER_HSTMT 5 +#define SQL_DRIVER_NAME 6 +#define SQL_DRIVER_VER 7 +#define SQL_ODBC_API_CONFORMANCE 9 +#define SQL_ODBC_VER 10 +#define SQL_ROW_UPDATES 11 +#define SQL_ODBC_SAG_CLI_CONFORMANCE 12 +#define SQL_ODBC_SQL_CONFORMANCE 15 +#define SQL_PROCEDURES 21 +#define SQL_CONCAT_NULL_BEHAVIOR 22 +#define SQL_CURSOR_ROLLBACK_BEHAVIOR 24 +#define SQL_EXPRESSIONS_IN_ORDERBY 27 +#define SQL_MAX_OWNER_NAME_LEN 32 /* MAX_SCHEMA_NAME_LEN */ +#define SQL_MAX_PROCEDURE_NAME_LEN 33 +#define SQL_MAX_QUALIFIER_NAME_LEN 34 /* MAX_CATALOG_NAME_LEN */ +#define SQL_MULT_RESULT_SETS 36 +#define SQL_MULTIPLE_ACTIVE_TXN 37 +#define SQL_OUTER_JOINS 38 +#define SQL_OWNER_TERM 39 +#define SQL_PROCEDURE_TERM 40 +#define SQL_QUALIFIER_NAME_SEPARATOR 41 +#define SQL_QUALIFIER_TERM 42 +#define SQL_SCROLL_OPTIONS 44 +#define SQL_TABLE_TERM 45 +#define SQL_CONVERT_FUNCTIONS 48 +#define SQL_NUMERIC_FUNCTIONS 49 +#define SQL_STRING_FUNCTIONS 50 +#define SQL_SYSTEM_FUNCTIONS 51 +#define SQL_TIMEDATE_FUNCTIONS 52 +#define SQL_CONVERT_BIGINT 53 +#define SQL_CONVERT_BINARY 54 +#define SQL_CONVERT_BIT 55 +#define SQL_CONVERT_CHAR 56 +#define SQL_CONVERT_DATE 57 +#define SQL_CONVERT_DECIMAL 58 +#define SQL_CONVERT_DOUBLE 59 +#define SQL_CONVERT_FLOAT 60 +#define SQL_CONVERT_INTEGER 61 +#define SQL_CONVERT_LONGVARCHAR 62 +#define SQL_CONVERT_NUMERIC 63 +#define SQL_CONVERT_REAL 64 +#define SQL_CONVERT_SMALLINT 65 +#define SQL_CONVERT_TIME 66 +#define SQL_CONVERT_TIMESTAMP 67 +#define SQL_CONVERT_TINYINT 68 +#define SQL_CONVERT_VARBINARY 69 +#define SQL_CONVERT_VARCHAR 70 +#define SQL_CONVERT_LONGVARBINARY 71 +#define SQL_ODBC_SQL_OPT_IEF 73 /* SQL_INTEGRITY */ +#define SQL_CORRELATION_NAME 74 +#define SQL_NON_NULLABLE_COLUMNS 75 +#define SQL_DRIVER_HLIB 76 +#define SQL_DRIVER_ODBC_VER 77 +#define SQL_LOCK_TYPES 78 +#define SQL_POS_OPERATIONS 79 +#define SQL_POSITIONED_STATEMENTS 80 +#define SQL_BOOKMARK_PERSISTENCE 82 +#define SQL_STATIC_SENSITIVITY 83 +#define SQL_FILE_USAGE 84 +#define SQL_COLUMN_ALIAS 87 +#define SQL_GROUP_BY 88 +#define SQL_KEYWORDS 89 +#define SQL_OWNER_USAGE 91 +#define SQL_QUALIFIER_USAGE 92 +#define SQL_QUOTED_IDENTIFIER_CASE 93 +#define SQL_SUBQUERIES 95 +#define SQL_UNION 96 +#define SQL_MAX_ROW_SIZE_INCLUDES_LONG 103 +#define SQL_MAX_CHAR_LITERAL_LEN 108 +#define SQL_TIMEDATE_ADD_INTERVALS 109 +#define SQL_TIMEDATE_DIFF_INTERVALS 110 +#define SQL_NEED_LONG_DATA_LEN 111 +#define SQL_MAX_BINARY_LITERAL_LEN 112 +#define SQL_LIKE_ESCAPE_CLAUSE 113 +#define SQL_QUALIFIER_LOCATION 114 + +#if (ODBCVER >= 0x0201 && ODBCVER < 0x0300) +#define SQL_OJ_CAPABILITIES 65003 /* Temp value until ODBC 3.0 */ +#endif /* ODBCVER >= 0x0201 && ODBCVER < 0x0300 */ + + +/* + * These values are not useful anymore as X/Open defines values in the + * 10000 range + */ +#if (ODBCVER < 0x0300) +#define SQL_INFO_LAST SQL_QUALIFIER_LOCATION +#define SQL_INFO_DRIVER_START 1000 +#endif /* ODBCVER < 0x0300 */ + + +/* + * SQLGetInfo - ODBC 3.x extensions to the X/Open standard + */ +#if (ODBCVER >= 0x0300) +#define SQL_ACTIVE_ENVIRONMENTS 116 +#define SQL_ALTER_DOMAIN 117 + +#define SQL_SQL_CONFORMANCE 118 +#define SQL_DATETIME_LITERALS 119 + +#define SQL_ASYNC_MODE 10021 /* new X/Open spec */ +#define SQL_BATCH_ROW_COUNT 120 +#define SQL_BATCH_SUPPORT 121 +#define SQL_CATALOG_LOCATION SQL_QUALIFIER_LOCATION +#define SQL_CATALOG_NAME_SEPARATOR SQL_QUALIFIER_NAME_SEPARATOR +#define SQL_CATALOG_TERM SQL_QUALIFIER_TERM +#define SQL_CATALOG_USAGE SQL_QUALIFIER_USAGE +#define SQL_CONVERT_WCHAR 122 +#define SQL_CONVERT_INTERVAL_DAY_TIME 123 +#define SQL_CONVERT_INTERVAL_YEAR_MONTH 124 +#define SQL_CONVERT_WLONGVARCHAR 125 +#define SQL_CONVERT_WVARCHAR 126 +#define SQL_CREATE_ASSERTION 127 +#define SQL_CREATE_CHARACTER_SET 128 +#define SQL_CREATE_COLLATION 129 +#define SQL_CREATE_DOMAIN 130 +#define SQL_CREATE_SCHEMA 131 +#define SQL_CREATE_TABLE 132 +#define SQL_CREATE_TRANSLATION 133 +#define SQL_CREATE_VIEW 134 +#define SQL_DRIVER_HDESC 135 +#define SQL_DROP_ASSERTION 136 +#define SQL_DROP_CHARACTER_SET 137 +#define SQL_DROP_COLLATION 138 +#define SQL_DROP_DOMAIN 139 +#define SQL_DROP_SCHEMA 140 +#define SQL_DROP_TABLE 141 +#define SQL_DROP_TRANSLATION 142 +#define SQL_DROP_VIEW 143 +#define SQL_DYNAMIC_CURSOR_ATTRIBUTES1 144 +#define SQL_DYNAMIC_CURSOR_ATTRIBUTES2 145 +#define SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1 146 +#define SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2 147 +#define SQL_INDEX_KEYWORDS 148 +#define SQL_INFO_SCHEMA_VIEWS 149 +#define SQL_KEYSET_CURSOR_ATTRIBUTES1 150 +#define SQL_KEYSET_CURSOR_ATTRIBUTES2 151 +#define SQL_MAX_ASYNC_CONCURRENT_STATEMENTS 10022 /* new X/Open spec */ +#define SQL_ODBC_INTERFACE_CONFORMANCE 152 +#define SQL_PARAM_ARRAY_ROW_COUNTS 153 +#define SQL_PARAM_ARRAY_SELECTS 154 +#define SQL_SCHEMA_TERM SQL_OWNER_TERM +#define SQL_SCHEMA_USAGE SQL_OWNER_USAGE +#define SQL_SQL92_DATETIME_FUNCTIONS 155 +#define SQL_SQL92_FOREIGN_KEY_DELETE_RULE 156 +#define SQL_SQL92_FOREIGN_KEY_UPDATE_RULE 157 +#define SQL_SQL92_GRANT 158 +#define SQL_SQL92_NUMERIC_VALUE_FUNCTIONS 159 +#define SQL_SQL92_PREDICATES 160 +#define SQL_SQL92_RELATIONAL_JOIN_OPERATORS 161 +#define SQL_SQL92_REVOKE 162 +#define SQL_SQL92_ROW_VALUE_CONSTRUCTOR 163 +#define SQL_SQL92_STRING_FUNCTIONS 164 +#define SQL_SQL92_VALUE_EXPRESSIONS 165 +#define SQL_STANDARD_CLI_CONFORMANCE 166 +#define SQL_STATIC_CURSOR_ATTRIBUTES1 167 +#define SQL_STATIC_CURSOR_ATTRIBUTES2 168 + +#define SQL_AGGREGATE_FUNCTIONS 169 +#define SQL_DDL_INDEX 170 +#define SQL_DM_VER 171 +#define SQL_INSERT_STATEMENT 172 +#define SQL_UNION_STATEMENT SQL_UNION + +#endif /* ODBCVER >= 0x0300 */ + +#define SQL_DTC_TRANSITION_COST 1750 + + +/* + * SQLGetInfo - SQL_AGGREGATE_FUNCTIONS + */ +#if (ODBCVER >= 0x0300) +#define SQL_AF_AVG 0x00000001L +#define SQL_AF_COUNT 0x00000002L +#define SQL_AF_MAX 0x00000004L +#define SQL_AF_MIN 0x00000008L +#define SQL_AF_SUM 0x00000010L +#define SQL_AF_DISTINCT 0x00000020L +#define SQL_AF_ALL 0x00000040L +#endif /* ODBCVER >= 0x0300 */ + +/* + * SQLGetInfo - SQL_ALTER_DOMAIN + */ +#if (ODBCVER >= 0x0300) +#define SQL_AD_CONSTRAINT_NAME_DEFINITION 0x00000001L +#define SQL_AD_ADD_DOMAIN_CONSTRAINT 0x00000002L +#define SQL_AD_DROP_DOMAIN_CONSTRAINT 0x00000004L +#define SQL_AD_ADD_DOMAIN_DEFAULT 0x00000008L +#define SQL_AD_DROP_DOMAIN_DEFAULT 0x00000010L +#define SQL_AD_ADD_CONSTRAINT_INITIALLY_DEFERRED 0x00000020L +#define SQL_AD_ADD_CONSTRAINT_INITIALLY_IMMEDIATE 0x00000040L +#define SQL_AD_ADD_CONSTRAINT_DEFERRABLE 0x00000080L +#define SQL_AD_ADD_CONSTRAINT_NON_DEFERRABLE 0x00000100L +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_ALTER_TABLE + */ +#if (ODBCVER >= 0x0300) +/* + * The following 5 bitmasks are defined in sql.h + * + * #define SQL_AT_ADD_COLUMN 0x00000001L + * #define SQL_AT_DROP_COLUMN 0x00000002L + * #define SQL_AT_ADD_CONSTRAINT 0x00000008L + */ +#define SQL_AT_ADD_COLUMN_SINGLE 0x00000020L +#define SQL_AT_ADD_COLUMN_DEFAULT 0x00000040L +#define SQL_AT_ADD_COLUMN_COLLATION 0x00000080L +#define SQL_AT_SET_COLUMN_DEFAULT 0x00000100L +#define SQL_AT_DROP_COLUMN_DEFAULT 0x00000200L +#define SQL_AT_DROP_COLUMN_CASCADE 0x00000400L +#define SQL_AT_DROP_COLUMN_RESTRICT 0x00000800L +#define SQL_AT_ADD_TABLE_CONSTRAINT 0x00001000L +#define SQL_AT_DROP_TABLE_CONSTRAINT_CASCADE 0x00002000L +#define SQL_AT_DROP_TABLE_CONSTRAINT_RESTRICT 0x00004000L +#define SQL_AT_CONSTRAINT_NAME_DEFINITION 0x00008000L +#define SQL_AT_CONSTRAINT_INITIALLY_DEFERRED 0x00010000L +#define SQL_AT_CONSTRAINT_INITIALLY_IMMEDIATE 0x00020000L +#define SQL_AT_CONSTRAINT_DEFERRABLE 0x00040000L +#define SQL_AT_CONSTRAINT_NON_DEFERRABLE 0x00080000L +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_ASYNC_MODE + */ +#if (ODBCVER >= 0x0300) +#define SQL_AM_NONE 0 +#define SQL_AM_CONNECTION 1 +#define SQL_AM_STATEMENT 2 +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_BATCH_ROW_COUNT + */ +#if (ODBCVER >= 0x0300) +#define SQL_BRC_PROCEDURES 0x0000001 +#define SQL_BRC_EXPLICIT 0x0000002 +#define SQL_BRC_ROLLED_UP 0x0000004 +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_BATCH_SUPPORT + */ +#if (ODBCVER >= 0x0300) +#define SQL_BS_SELECT_EXPLICIT 0x00000001L +#define SQL_BS_ROW_COUNT_EXPLICIT 0x00000002L +#define SQL_BS_SELECT_PROC 0x00000004L +#define SQL_BS_ROW_COUNT_PROC 0x00000008L +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_BOOKMARK_PERSISTENCE + */ +#define SQL_BP_CLOSE 0x00000001L +#define SQL_BP_DELETE 0x00000002L +#define SQL_BP_DROP 0x00000004L +#define SQL_BP_TRANSACTION 0x00000008L +#define SQL_BP_UPDATE 0x00000010L +#define SQL_BP_OTHER_HSTMT 0x00000020L +#define SQL_BP_SCROLL 0x00000040L + + +/* + * SQLGetInfo - SQL_CATALOG_LOCATION + */ +#if (ODBCVER >= 0x0300) +#define SQL_CL_START SQL_QL_START +#define SQL_CL_END SQL_QL_END +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_CATALOG_USAGE + */ +#if (ODBCVER >= 0x0300) +#define SQL_CU_DML_STATEMENTS SQL_QU_DML_STATEMENTS +#define SQL_CU_PROCEDURE_INVOCATION SQL_QU_PROCEDURE_INVOCATION +#define SQL_CU_TABLE_DEFINITION SQL_QU_TABLE_DEFINITION +#define SQL_CU_INDEX_DEFINITION SQL_QU_INDEX_DEFINITION +#define SQL_CU_PRIVILEGE_DEFINITION SQL_QU_PRIVILEGE_DEFINITION +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_CONCAT_NULL_BEHAVIOR + */ +#define SQL_CB_NULL 0x0000 +#define SQL_CB_NON_NULL 0x0001 + + +/* + * SQLGetInfo - SQL_CONVERT_* bitmask values + */ +#define SQL_CVT_CHAR 0x00000001L +#define SQL_CVT_NUMERIC 0x00000002L +#define SQL_CVT_DECIMAL 0x00000004L +#define SQL_CVT_INTEGER 0x00000008L +#define SQL_CVT_SMALLINT 0x00000010L +#define SQL_CVT_FLOAT 0x00000020L +#define SQL_CVT_REAL 0x00000040L +#define SQL_CVT_DOUBLE 0x00000080L +#define SQL_CVT_VARCHAR 0x00000100L +#define SQL_CVT_LONGVARCHAR 0x00000200L +#define SQL_CVT_BINARY 0x00000400L +#define SQL_CVT_VARBINARY 0x00000800L +#define SQL_CVT_BIT 0x00001000L +#define SQL_CVT_TINYINT 0x00002000L +#define SQL_CVT_BIGINT 0x00004000L +#define SQL_CVT_DATE 0x00008000L +#define SQL_CVT_TIME 0x00010000L +#define SQL_CVT_TIMESTAMP 0x00020000L +#define SQL_CVT_LONGVARBINARY 0x00040000L +#if (ODBCVER >= 0x0300) +#define SQL_CVT_INTERVAL_YEAR_MONTH 0x00080000L +#define SQL_CVT_INTERVAL_DAY_TIME 0x00100000L +#define SQL_CVT_WCHAR 0x00200000L +#define SQL_CVT_WLONGVARCHAR 0x00400000L +#define SQL_CVT_WVARCHAR 0x00800000L +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_CONVERT_FUNCTIONS + */ +#define SQL_FN_CVT_CONVERT 0x00000001L +#if (ODBCVER >= 0x0300) +#define SQL_FN_CVT_CAST 0x00000002L +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_CORRELATION_NAME + */ +#define SQL_CN_NONE 0x0000 +#define SQL_CN_DIFFERENT 0x0001 +#define SQL_CN_ANY 0x0002 + + +/* + * SQLGetInfo - SQL_CREATE_ASSERTION + */ +#if (ODBCVER >= 0x0300) +#define SQL_CA_CREATE_ASSERTION 0x00000001L +#define SQL_CA_CONSTRAINT_INITIALLY_DEFERRED 0x00000010L +#define SQL_CA_CONSTRAINT_INITIALLY_IMMEDIATE 0x00000020L +#define SQL_CA_CONSTRAINT_DEFERRABLE 0x00000040L +#define SQL_CA_CONSTRAINT_NON_DEFERRABLE 0x00000080L +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_CREATE_CHARACTER_SET + */ +#if (ODBCVER >= 0x0300) +#define SQL_CCS_CREATE_CHARACTER_SET 0x00000001L +#define SQL_CCS_COLLATE_CLAUSE 0x00000002L +#define SQL_CCS_LIMITED_COLLATION 0x00000004L +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_CREATE_COLLATION + */ +#if (ODBCVER >= 0x0300) +#define SQL_CCOL_CREATE_COLLATION 0x00000001L +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_CREATE_DOMAIN + */ +#if (ODBCVER >= 0x0300) +#define SQL_CDO_CREATE_DOMAIN 0x00000001L +#define SQL_CDO_DEFAULT 0x00000002L +#define SQL_CDO_CONSTRAINT 0x00000004L +#define SQL_CDO_COLLATION 0x00000008L +#define SQL_CDO_CONSTRAINT_NAME_DEFINITION 0x00000010L +#define SQL_CDO_CONSTRAINT_INITIALLY_DEFERRED 0x00000020L +#define SQL_CDO_CONSTRAINT_INITIALLY_IMMEDIATE 0x00000040L +#define SQL_CDO_CONSTRAINT_DEFERRABLE 0x00000080L +#define SQL_CDO_CONSTRAINT_NON_DEFERRABLE 0x00000100L +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_CREATE_SCHEMA + */ +#if (ODBCVER >= 0x0300) +#define SQL_CS_CREATE_SCHEMA 0x00000001L +#define SQL_CS_AUTHORIZATION 0x00000002L +#define SQL_CS_DEFAULT_CHARACTER_SET 0x00000004L +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_CREATE_TABLE + */ +#if (ODBCVER >= 0x0300) +#define SQL_CT_CREATE_TABLE 0x00000001L +#define SQL_CT_COMMIT_PRESERVE 0x00000002L +#define SQL_CT_COMMIT_DELETE 0x00000004L +#define SQL_CT_GLOBAL_TEMPORARY 0x00000008L +#define SQL_CT_LOCAL_TEMPORARY 0x00000010L +#define SQL_CT_CONSTRAINT_INITIALLY_DEFERRED 0x00000020L +#define SQL_CT_CONSTRAINT_INITIALLY_IMMEDIATE 0x00000040L +#define SQL_CT_CONSTRAINT_DEFERRABLE 0x00000080L +#define SQL_CT_CONSTRAINT_NON_DEFERRABLE 0x00000100L +#define SQL_CT_COLUMN_CONSTRAINT 0x00000200L +#define SQL_CT_COLUMN_DEFAULT 0x00000400L +#define SQL_CT_COLUMN_COLLATION 0x00000800L +#define SQL_CT_TABLE_CONSTRAINT 0x00001000L +#define SQL_CT_CONSTRAINT_NAME_DEFINITION 0x00002000L +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_CREATE_TRANSLATION + */ +#if (ODBCVER >= 0x0300) +#define SQL_CTR_CREATE_TRANSLATION 0x00000001L +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_CREATE_VIEW + */ +#define SQL_CV_CREATE_VIEW 0x00000001L +#define SQL_CV_CHECK_OPTION 0x00000002L +#define SQL_CV_CASCADED 0x00000004L +#define SQL_CV_LOCAL 0x00000008L + + +/* + * SQLGetInfo - SQL_DATETIME_LITERALS + */ +#if (ODBCVER >= 0x0300) +#define SQL_DL_SQL92_DATE 0x00000001L +#define SQL_DL_SQL92_TIME 0x00000002L +#define SQL_DL_SQL92_TIMESTAMP 0x00000004L +#define SQL_DL_SQL92_INTERVAL_YEAR 0x00000008L +#define SQL_DL_SQL92_INTERVAL_MONTH 0x00000010L +#define SQL_DL_SQL92_INTERVAL_DAY 0x00000020L +#define SQL_DL_SQL92_INTERVAL_HOUR 0x00000040L +#define SQL_DL_SQL92_INTERVAL_MINUTE 0x00000080L +#define SQL_DL_SQL92_INTERVAL_SECOND 0x00000100L +#define SQL_DL_SQL92_INTERVAL_YEAR_TO_MONTH 0x00000200L +#define SQL_DL_SQL92_INTERVAL_DAY_TO_HOUR 0x00000400L +#define SQL_DL_SQL92_INTERVAL_DAY_TO_MINUTE 0x00000800L +#define SQL_DL_SQL92_INTERVAL_DAY_TO_SECOND 0x00001000L +#define SQL_DL_SQL92_INTERVAL_HOUR_TO_MINUTE 0x00002000L +#define SQL_DL_SQL92_INTERVAL_HOUR_TO_SECOND 0x00004000L +#define SQL_DL_SQL92_INTERVAL_MINUTE_TO_SECOND 0x00008000L +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_DDL_INDEX + */ +#if (ODBCVER >= 0x0300) +#define SQL_DI_CREATE_INDEX 0x00000001L +#define SQL_DI_DROP_INDEX 0x00000002L +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_DROP_ASSERTION + */ +#if (ODBCVER >= 0x0300) +#define SQL_DA_DROP_ASSERTION 0x00000001L +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_DROP_CHARACTER_SET + */ +#if (ODBCVER >= 0x0300) +#define SQL_DCS_DROP_CHARACTER_SET 0x00000001L +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_DROP_COLLATION + */ +#if (ODBCVER >= 0x0300) +#define SQL_DC_DROP_COLLATION 0x00000001L +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_DROP_DOMAIN + */ +#if (ODBCVER >= 0x0300) +#define SQL_DD_DROP_DOMAIN 0x00000001L +#define SQL_DD_RESTRICT 0x00000002L +#define SQL_DD_CASCADE 0x00000004L +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_DROP_SCHEMA + */ +#if (ODBCVER >= 0x0300) +#define SQL_DS_DROP_SCHEMA 0x00000001L +#define SQL_DS_RESTRICT 0x00000002L +#define SQL_DS_CASCADE 0x00000004L +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_DROP_TABLE + */ +#if (ODBCVER >= 0x0300) +#define SQL_DT_DROP_TABLE 0x00000001L +#define SQL_DT_RESTRICT 0x00000002L +#define SQL_DT_CASCADE 0x00000004L +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_DROP_TRANSLATION + */ +#if (ODBCVER >= 0x0300) +#define SQL_DTR_DROP_TRANSLATION 0x00000001L +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_DROP_VIEW + */ +#if (ODBCVER >= 0x0300) +#define SQL_DV_DROP_VIEW 0x00000001L +#define SQL_DV_RESTRICT 0x00000002L +#define SQL_DV_CASCADE 0x00000004L +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_DTC_TRANSITION_COST + */ +#define SQL_DTC_ENLIST_EXPENSIVE 0x00000001L +#define SQL_DTC_UNENLIST_EXPENSIVE 0x00000002L + + +/* + * SQLGetInfo - SQL_DYNAMIC_CURSOR_ATTRIBUTES1 + * SQLGetInfo - SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1 + * SQLGetInfo - SQL_KEYSET_CURSOR_ATTRIBUTES1 + * SQLGetInfo - SQL_STATIC_CURSOR_ATTRIBUTES1 + */ +/* + * SQLFetchScroll - FetchOrientation + */ +#if (ODBCVER >= 0x0300) +#define SQL_CA1_NEXT 0x00000001L +#define SQL_CA1_ABSOLUTE 0x00000002L +#define SQL_CA1_RELATIVE 0x00000004L +#define SQL_CA1_BOOKMARK 0x00000008L +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLSetPos - LockType + */ +#if (ODBCVER >= 0x0300) +#define SQL_CA1_LOCK_NO_CHANGE 0x00000040L +#define SQL_CA1_LOCK_EXCLUSIVE 0x00000080L +#define SQL_CA1_LOCK_UNLOCK 0x00000100L +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLSetPos Operations + */ +#if (ODBCVER >= 0x0300) +#define SQL_CA1_POS_POSITION 0x00000200L +#define SQL_CA1_POS_UPDATE 0x00000400L +#define SQL_CA1_POS_DELETE 0x00000800L +#define SQL_CA1_POS_REFRESH 0x00001000L +#endif /* ODBCVER >= 0x0300 */ + + +/* + * positioned updates and deletes + */ +#if (ODBCVER >= 0x0300) +#define SQL_CA1_POSITIONED_UPDATE 0x00002000L +#define SQL_CA1_POSITIONED_DELETE 0x00004000L +#define SQL_CA1_SELECT_FOR_UPDATE 0x00008000L +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLBulkOperations operations + */ +#if (ODBCVER >= 0x0300) +#define SQL_CA1_BULK_ADD 0x00010000L +#define SQL_CA1_BULK_UPDATE_BY_BOOKMARK 0x00020000L +#define SQL_CA1_BULK_DELETE_BY_BOOKMARK 0x00040000L +#define SQL_CA1_BULK_FETCH_BY_BOOKMARK 0x00080000L +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_DYNAMIC_CURSOR_ATTRIBUTES2 + * SQLGetInfo - SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2 + * SQLGetInfo - SQL_KEYSET_CURSOR_ATTRIBUTES2 + * SQLGetInfo - SQL_STATIC_CURSOR_ATTRIBUTES2 + */ +/* + * SQL_ATTR_SCROLL_CONCURRENCY + */ +#if (ODBCVER >= 0x0300) +#define SQL_CA2_READ_ONLY_CONCURRENCY 0x00000001L +#define SQL_CA2_LOCK_CONCURRENCY 0x00000002L +#define SQL_CA2_OPT_ROWVER_CONCURRENCY 0x00000004L +#define SQL_CA2_OPT_VALUES_CONCURRENCY 0x00000008L +#endif /* ODBCVER >= 0x0300 */ + + +/* + * sensitivity of the cursor to its own inserts, deletes, and updates + */ +#if (ODBCVER >= 0x0300) +#define SQL_CA2_SENSITIVITY_ADDITIONS 0x00000010L +#define SQL_CA2_SENSITIVITY_DELETIONS 0x00000020L +#define SQL_CA2_SENSITIVITY_UPDATES 0x00000040L +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQL_ATTR_MAX_ROWS + */ +#if (ODBCVER >= 0x0300) +#define SQL_CA2_MAX_ROWS_SELECT 0x00000080L +#define SQL_CA2_MAX_ROWS_INSERT 0x00000100L +#define SQL_CA2_MAX_ROWS_DELETE 0x00000200L +#define SQL_CA2_MAX_ROWS_UPDATE 0x00000400L +#define SQL_CA2_MAX_ROWS_CATALOG 0x00000800L +#define SQL_CA2_MAX_ROWS_AFFECTS_ALL (SQL_CA2_MAX_ROWS_SELECT | \ + SQL_CA2_MAX_ROWS_INSERT | \ + SQL_CA2_MAX_ROWS_DELETE | \ + SQL_CA2_MAX_ROWS_UPDATE | \ + SQL_CA2_MAX_ROWS_CATALOG) +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQL_DIAG_CURSOR_ROW_COUNT + */ +#if (ODBCVER >= 0x0300) +#define SQL_CA2_CRC_EXACT 0x00001000L +#define SQL_CA2_CRC_APPROXIMATE 0x00002000L +#endif /* ODBCVER >= 0x0300 */ + + +/* + * the kinds of positioned statements that can be simulated + */ +#if (ODBCVER >= 0x0300) +#define SQL_CA2_SIMULATE_NON_UNIQUE 0x00004000L +#define SQL_CA2_SIMULATE_TRY_UNIQUE 0x00008000L +#define SQL_CA2_SIMULATE_UNIQUE 0x00010000L +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_FETCH_DIRECTION + */ +#if (ODBCVER < 0x0300) +#define SQL_FD_FETCH_RESUME 0x00000040L +#endif /* ODBCVER < 0x0300 */ +#define SQL_FD_FETCH_BOOKMARK 0x00000080L + + +/* + * SQLGetInfo - SQL_FILE_USAGE + */ +#define SQL_FILE_NOT_SUPPORTED 0x0000 +#define SQL_FILE_TABLE 0x0001 +#define SQL_FILE_QUALIFIER 0x0002 +#define SQL_FILE_CATALOG SQL_FILE_QUALIFIER + + +/* + * SQLGetInfo - SQL_GETDATA_EXTENSIONS + */ +#define SQL_GD_BLOCK 0x00000004L +#define SQL_GD_BOUND 0x00000008L + + +/* + * SQLGetInfo - SQL_GROUP_BY + */ +#define SQL_GB_NOT_SUPPORTED 0x0000 +#define SQL_GB_GROUP_BY_EQUALS_SELECT 0x0001 +#define SQL_GB_GROUP_BY_CONTAINS_SELECT 0x0002 +#define SQL_GB_NO_RELATION 0x0003 +#if (ODBCVER >= 0x0300) +#define SQL_GB_COLLATE 0x0004 +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_INDEX_KEYWORDS + */ +#if (ODBCVER >= 0x0300) +#define SQL_IK_NONE 0x00000000L +#define SQL_IK_ASC 0x00000001L +#define SQL_IK_DESC 0x00000002L +#define SQL_IK_ALL (SQL_IK_ASC | SQL_IK_DESC) +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_INFO_SCHEMA_VIEWS + */ +#if (ODBCVER >= 0x0300) +#define SQL_ISV_ASSERTIONS 0x00000001L +#define SQL_ISV_CHARACTER_SETS 0x00000002L +#define SQL_ISV_CHECK_CONSTRAINTS 0x00000004L +#define SQL_ISV_COLLATIONS 0x00000008L +#define SQL_ISV_COLUMN_DOMAIN_USAGE 0x00000010L +#define SQL_ISV_COLUMN_PRIVILEGES 0x00000020L +#define SQL_ISV_COLUMNS 0x00000040L +#define SQL_ISV_CONSTRAINT_COLUMN_USAGE 0x00000080L +#define SQL_ISV_CONSTRAINT_TABLE_USAGE 0x00000100L +#define SQL_ISV_DOMAIN_CONSTRAINTS 0x00000200L +#define SQL_ISV_DOMAINS 0x00000400L +#define SQL_ISV_KEY_COLUMN_USAGE 0x00000800L +#define SQL_ISV_REFERENTIAL_CONSTRAINTS 0x00001000L +#define SQL_ISV_SCHEMATA 0x00002000L +#define SQL_ISV_SQL_LANGUAGES 0x00004000L +#define SQL_ISV_TABLE_CONSTRAINTS 0x00008000L +#define SQL_ISV_TABLE_PRIVILEGES 0x00010000L +#define SQL_ISV_TABLES 0x00020000L +#define SQL_ISV_TRANSLATIONS 0x00040000L +#define SQL_ISV_USAGE_PRIVILEGES 0x00080000L +#define SQL_ISV_VIEW_COLUMN_USAGE 0x00100000L +#define SQL_ISV_VIEW_TABLE_USAGE 0x00200000L +#define SQL_ISV_VIEWS 0x00400000L +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_INSERT_STATEMENT + */ +#if (ODBCVER >= 0x0300) +#define SQL_IS_INSERT_LITERALS 0x00000001L +#define SQL_IS_INSERT_SEARCHED 0x00000002L +#define SQL_IS_SELECT_INTO 0x00000004L +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_LOCK_TYPES + */ +#define SQL_LCK_NO_CHANGE 0x00000001L +#define SQL_LCK_EXCLUSIVE 0x00000002L +#define SQL_LCK_UNLOCK 0x00000004L + + +/* + * SQLGetInfo - SQL_POS_OPERATIONS + */ +#define SQL_POS_POSITION 0x00000001L +#define SQL_POS_REFRESH 0x00000002L +#define SQL_POS_UPDATE 0x00000004L +#define SQL_POS_DELETE 0x00000008L +#define SQL_POS_ADD 0x00000010L + + +/* + * SQLGetInfo - SQL_NON_NULLABLE_COLUMNS + */ +#define SQL_NNC_NULL 0x0000 +#define SQL_NNC_NON_NULL 0x0001 + + +/* + * SQLGetInfo - SQL_NULL_COLLATION + */ +#define SQL_NC_START 0x0002 +#define SQL_NC_END 0x0004 + + +/* + * SQLGetInfo - SQL_NUMERIC_FUNCTIONS + */ +#define SQL_FN_NUM_ABS 0x00000001L +#define SQL_FN_NUM_ACOS 0x00000002L +#define SQL_FN_NUM_ASIN 0x00000004L +#define SQL_FN_NUM_ATAN 0x00000008L +#define SQL_FN_NUM_ATAN2 0x00000010L +#define SQL_FN_NUM_CEILING 0x00000020L +#define SQL_FN_NUM_COS 0x00000040L +#define SQL_FN_NUM_COT 0x00000080L +#define SQL_FN_NUM_EXP 0x00000100L +#define SQL_FN_NUM_FLOOR 0x00000200L +#define SQL_FN_NUM_LOG 0x00000400L +#define SQL_FN_NUM_MOD 0x00000800L +#define SQL_FN_NUM_SIGN 0x00001000L +#define SQL_FN_NUM_SIN 0x00002000L +#define SQL_FN_NUM_SQRT 0x00004000L +#define SQL_FN_NUM_TAN 0x00008000L +#define SQL_FN_NUM_PI 0x00010000L +#define SQL_FN_NUM_RAND 0x00020000L +#define SQL_FN_NUM_DEGREES 0x00040000L +#define SQL_FN_NUM_LOG10 0x00080000L +#define SQL_FN_NUM_POWER 0x00100000L +#define SQL_FN_NUM_RADIANS 0x00200000L +#define SQL_FN_NUM_ROUND 0x00400000L +#define SQL_FN_NUM_TRUNCATE 0x00800000L + + +/* + * SQLGetInfo - SQL_ODBC_API_CONFORMANCE + */ +#define SQL_OAC_NONE 0x0000 +#define SQL_OAC_LEVEL1 0x0001 +#define SQL_OAC_LEVEL2 0x0002 + + +/* + * SQLGetInfo - SQL_ODBC_INTERFACE_CONFORMANCE + */ +#if (ODBCVER >= 0x0300) +#define SQL_OIC_CORE 1UL +#define SQL_OIC_LEVEL1 2UL +#define SQL_OIC_LEVEL2 3UL +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_ODBC_SAG_CLI_CONFORMANCE + */ +#define SQL_OSCC_NOT_COMPLIANT 0x0000 +#define SQL_OSCC_COMPLIANT 0x0001 + + +/* + * SQLGetInfo - SQL_ODBC_SQL_CONFORMANCE + */ +#define SQL_OSC_MINIMUM 0x0000 +#define SQL_OSC_CORE 0x0001 +#define SQL_OSC_EXTENDED 0x0002 + + +/* + * SQLGetInfo - SQL_OWNER_USAGE + */ +#define SQL_OU_DML_STATEMENTS 0x00000001L +#define SQL_OU_PROCEDURE_INVOCATION 0x00000002L +#define SQL_OU_TABLE_DEFINITION 0x00000004L +#define SQL_OU_INDEX_DEFINITION 0x00000008L +#define SQL_OU_PRIVILEGE_DEFINITION 0x00000010L + + +/* + * SQLGetInfo - SQL_PARAM_ARRAY_ROW_COUNTS + */ +#if (ODBCVER >= 0x0300) +#define SQL_PARC_BATCH 1 +#define SQL_PARC_NO_BATCH 2 +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_PARAM_ARRAY_SELECTS + */ +#if (ODBCVER >= 0x0300) +#define SQL_PAS_BATCH 1 +#define SQL_PAS_NO_BATCH 2 +#define SQL_PAS_NO_SELECT 3 +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_POSITIONED_STATEMENTS + */ +#define SQL_PS_POSITIONED_DELETE 0x00000001L +#define SQL_PS_POSITIONED_UPDATE 0x00000002L +#define SQL_PS_SELECT_FOR_UPDATE 0x00000004L + + +/* + * SQLGetInfo - SQL_QUALIFIER_LOCATION + */ +#define SQL_QL_START 0x0001 +#define SQL_QL_END 0x0002 + + +/* + * SQLGetInfo - SQL_QUALIFIER_USAGE + */ +#define SQL_QU_DML_STATEMENTS 0x00000001L +#define SQL_QU_PROCEDURE_INVOCATION 0x00000002L +#define SQL_QU_TABLE_DEFINITION 0x00000004L +#define SQL_QU_INDEX_DEFINITION 0x00000008L +#define SQL_QU_PRIVILEGE_DEFINITION 0x00000010L + + +/* + * SQLGetInfo - SQL_SCHEMA_USAGE + */ +#if (ODBCVER >= 0x0300) +#define SQL_SU_DML_STATEMENTS SQL_OU_DML_STATEMENTS +#define SQL_SU_PROCEDURE_INVOCATION SQL_OU_PROCEDURE_INVOCATION +#define SQL_SU_TABLE_DEFINITION SQL_OU_TABLE_DEFINITION +#define SQL_SU_INDEX_DEFINITION SQL_OU_INDEX_DEFINITION +#define SQL_SU_PRIVILEGE_DEFINITION SQL_OU_PRIVILEGE_DEFINITION +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_SCROLL_OPTIONS + */ +#define SQL_SO_FORWARD_ONLY 0x00000001L +#define SQL_SO_KEYSET_DRIVEN 0x00000002L +#define SQL_SO_DYNAMIC 0x00000004L +#define SQL_SO_MIXED 0x00000008L +#define SQL_SO_STATIC 0x00000010L + + +/* + * SQLGetInfo - SQL_SQL_CONFORMANCE + */ +#if (ODBCVER >= 0x0300) +#define SQL_SC_SQL92_ENTRY 0x00000001L +#define SQL_SC_FIPS127_2_TRANSITIONAL 0x00000002L +#define SQL_SC_SQL92_INTERMEDIATE 0x00000004L +#define SQL_SC_SQL92_FULL 0x00000008L +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_SQL92_DATETIME_FUNCTIONS + */ +#if (ODBCVER >= 0x0300) +#define SQL_SDF_CURRENT_DATE 0x00000001L +#define SQL_SDF_CURRENT_TIME 0x00000002L +#define SQL_SDF_CURRENT_TIMESTAMP 0x00000004L +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_SQL92_FOREIGN_KEY_DELETE_RULE + */ +#if (ODBCVER >= 0x0300) +#define SQL_SFKD_CASCADE 0x00000001L +#define SQL_SFKD_NO_ACTION 0x00000002L +#define SQL_SFKD_SET_DEFAULT 0x00000004L +#define SQL_SFKD_SET_NULL 0x00000008L +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_SQL92_FOREIGN_KEY_UPDATE_RULE + */ +#if (ODBCVER >= 0x0300) +#define SQL_SFKU_CASCADE 0x00000001L +#define SQL_SFKU_NO_ACTION 0x00000002L +#define SQL_SFKU_SET_DEFAULT 0x00000004L +#define SQL_SFKU_SET_NULL 0x00000008L +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_SQL92_GRANT + */ +#if (ODBCVER >= 0x0300) +#define SQL_SG_USAGE_ON_DOMAIN 0x00000001L +#define SQL_SG_USAGE_ON_CHARACTER_SET 0x00000002L +#define SQL_SG_USAGE_ON_COLLATION 0x00000004L +#define SQL_SG_USAGE_ON_TRANSLATION 0x00000008L +#define SQL_SG_WITH_GRANT_OPTION 0x00000010L +#define SQL_SG_DELETE_TABLE 0x00000020L +#define SQL_SG_INSERT_TABLE 0x00000040L +#define SQL_SG_INSERT_COLUMN 0x00000080L +#define SQL_SG_REFERENCES_TABLE 0x00000100L +#define SQL_SG_REFERENCES_COLUMN 0x00000200L +#define SQL_SG_SELECT_TABLE 0x00000400L +#define SQL_SG_UPDATE_TABLE 0x00000800L +#define SQL_SG_UPDATE_COLUMN 0x00001000L +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_SQL92_NUMERIC_VALUE_FUNCTIONS + */ +#if (ODBCVER >= 0x0300) +#define SQL_SNVF_BIT_LENGTH 0x00000001L +#define SQL_SNVF_CHAR_LENGTH 0x00000002L +#define SQL_SNVF_CHARACTER_LENGTH 0x00000004L +#define SQL_SNVF_EXTRACT 0x00000008L +#define SQL_SNVF_OCTET_LENGTH 0x00000010L +#define SQL_SNVF_POSITION 0x00000020L +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_SQL92_PREDICATES + */ +#if (ODBCVER >= 0x0300) +#define SQL_SP_EXISTS 0x00000001L +#define SQL_SP_ISNOTNULL 0x00000002L +#define SQL_SP_ISNULL 0x00000004L +#define SQL_SP_MATCH_FULL 0x00000008L +#define SQL_SP_MATCH_PARTIAL 0x00000010L +#define SQL_SP_MATCH_UNIQUE_FULL 0x00000020L +#define SQL_SP_MATCH_UNIQUE_PARTIAL 0x00000040L +#define SQL_SP_OVERLAPS 0x00000080L +#define SQL_SP_UNIQUE 0x00000100L +#define SQL_SP_LIKE 0x00000200L +#define SQL_SP_IN 0x00000400L +#define SQL_SP_BETWEEN 0x00000800L +#define SQL_SP_COMPARISON 0x00001000L +#define SQL_SP_QUANTIFIED_COMPARISON 0x00002000L +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_SQL92_RELATIONAL_JOIN_OPERATORS + */ +#if (ODBCVER >= 0x0300) +#define SQL_SRJO_CORRESPONDING_CLAUSE 0x00000001L +#define SQL_SRJO_CROSS_JOIN 0x00000002L +#define SQL_SRJO_EXCEPT_JOIN 0x00000004L +#define SQL_SRJO_FULL_OUTER_JOIN 0x00000008L +#define SQL_SRJO_INNER_JOIN 0x00000010L +#define SQL_SRJO_INTERSECT_JOIN 0x00000020L +#define SQL_SRJO_LEFT_OUTER_JOIN 0x00000040L +#define SQL_SRJO_NATURAL_JOIN 0x00000080L +#define SQL_SRJO_RIGHT_OUTER_JOIN 0x00000100L +#define SQL_SRJO_UNION_JOIN 0x00000200L +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_SQL92_REVOKE + */ +#if (ODBCVER >= 0x0300) +#define SQL_SR_USAGE_ON_DOMAIN 0x00000001L +#define SQL_SR_USAGE_ON_CHARACTER_SET 0x00000002L +#define SQL_SR_USAGE_ON_COLLATION 0x00000004L +#define SQL_SR_USAGE_ON_TRANSLATION 0x00000008L +#define SQL_SR_GRANT_OPTION_FOR 0x00000010L +#define SQL_SR_CASCADE 0x00000020L +#define SQL_SR_RESTRICT 0x00000040L +#define SQL_SR_DELETE_TABLE 0x00000080L +#define SQL_SR_INSERT_TABLE 0x00000100L +#define SQL_SR_INSERT_COLUMN 0x00000200L +#define SQL_SR_REFERENCES_TABLE 0x00000400L +#define SQL_SR_REFERENCES_COLUMN 0x00000800L +#define SQL_SR_SELECT_TABLE 0x00001000L +#define SQL_SR_UPDATE_TABLE 0x00002000L +#define SQL_SR_UPDATE_COLUMN 0x00004000L +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_SQL92_ROW_VALUE_CONSTRUCTOR + */ +#if (ODBCVER >= 0x0300) +#define SQL_SRVC_VALUE_EXPRESSION 0x00000001L +#define SQL_SRVC_NULL 0x00000002L +#define SQL_SRVC_DEFAULT 0x00000004L +#define SQL_SRVC_ROW_SUBQUERY 0x00000008L +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_SQL92_STRING_FUNCTIONS + */ +#if (ODBCVER >= 0x0300) +#define SQL_SSF_CONVERT 0x00000001L +#define SQL_SSF_LOWER 0x00000002L +#define SQL_SSF_UPPER 0x00000004L +#define SQL_SSF_SUBSTRING 0x00000008L +#define SQL_SSF_TRANSLATE 0x00000010L +#define SQL_SSF_TRIM_BOTH 0x00000020L +#define SQL_SSF_TRIM_LEADING 0x00000040L +#define SQL_SSF_TRIM_TRAILING 0x00000080L +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_SQL92_VALUE_EXPRESSIONS + */ +#if (ODBCVER >= 0x0300) +#define SQL_SVE_CASE 0x00000001L +#define SQL_SVE_CAST 0x00000002L +#define SQL_SVE_COALESCE 0x00000004L +#define SQL_SVE_NULLIF 0x00000008L +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_STANDARD_CLI_CONFORMANCE + */ +#if (ODBCVER >= 0x0300) +#define SQL_SCC_XOPEN_CLI_VERSION1 0x00000001L +#define SQL_SCC_ISO92_CLI 0x00000002L +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_STATIC_SENSITIVITY + */ +#define SQL_SS_ADDITIONS 0x00000001L +#define SQL_SS_DELETIONS 0x00000002L +#define SQL_SS_UPDATES 0x00000004L + + +/* + * SQLGetInfo - SQL_SUBQUERIES + */ +#define SQL_SQ_COMPARISON 0x00000001L +#define SQL_SQ_EXISTS 0x00000002L +#define SQL_SQ_IN 0x00000004L +#define SQL_SQ_QUANTIFIED 0x00000008L +#define SQL_SQ_CORRELATED_SUBQUERIES 0x00000010L + + +/* + * SQLGetInfo - SQL_SYSTEM_FUNCTIONS + */ +#define SQL_FN_SYS_USERNAME 0x00000001L +#define SQL_FN_SYS_DBNAME 0x00000002L +#define SQL_FN_SYS_IFNULL 0x00000004L + + +/* + * SQLGetInfo - SQL_STRING_FUNCTIONS + */ +#define SQL_FN_STR_CONCAT 0x00000001L +#define SQL_FN_STR_INSERT 0x00000002L +#define SQL_FN_STR_LEFT 0x00000004L +#define SQL_FN_STR_LTRIM 0x00000008L +#define SQL_FN_STR_LENGTH 0x00000010L +#define SQL_FN_STR_LOCATE 0x00000020L +#define SQL_FN_STR_LCASE 0x00000040L +#define SQL_FN_STR_REPEAT 0x00000080L +#define SQL_FN_STR_REPLACE 0x00000100L +#define SQL_FN_STR_RIGHT 0x00000200L +#define SQL_FN_STR_RTRIM 0x00000400L +#define SQL_FN_STR_SUBSTRING 0x00000800L +#define SQL_FN_STR_UCASE 0x00001000L +#define SQL_FN_STR_ASCII 0x00002000L +#define SQL_FN_STR_CHAR 0x00004000L +#define SQL_FN_STR_DIFFERENCE 0x00008000L +#define SQL_FN_STR_LOCATE_2 0x00010000L +#define SQL_FN_STR_SOUNDEX 0x00020000L +#define SQL_FN_STR_SPACE 0x00040000L +#if (ODBCVER >= 0x0300) +#define SQL_FN_STR_BIT_LENGTH 0x00080000L +#define SQL_FN_STR_CHAR_LENGTH 0x00100000L +#define SQL_FN_STR_CHARACTER_LENGTH 0x00200000L +#define SQL_FN_STR_OCTET_LENGTH 0x00400000L +#define SQL_FN_STR_POSITION 0x00800000L +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_TIMEDATE_ADD_INTERVALS + * SQLGetInfo - SQL_TIMEDATE_DIFF_INTERVALS + */ +#define SQL_FN_TSI_FRAC_SECOND 0x00000001L +#define SQL_FN_TSI_SECOND 0x00000002L +#define SQL_FN_TSI_MINUTE 0x00000004L +#define SQL_FN_TSI_HOUR 0x00000008L +#define SQL_FN_TSI_DAY 0x00000010L +#define SQL_FN_TSI_WEEK 0x00000020L +#define SQL_FN_TSI_MONTH 0x00000040L +#define SQL_FN_TSI_QUARTER 0x00000080L +#define SQL_FN_TSI_YEAR 0x00000100L + + +/* + * SQLGetInfo - SQL_TIMEDATE_FUNCTIONS + */ +#define SQL_FN_TD_NOW 0x00000001L +#define SQL_FN_TD_CURDATE 0x00000002L +#define SQL_FN_TD_DAYOFMONTH 0x00000004L +#define SQL_FN_TD_DAYOFWEEK 0x00000008L +#define SQL_FN_TD_DAYOFYEAR 0x00000010L +#define SQL_FN_TD_MONTH 0x00000020L +#define SQL_FN_TD_QUARTER 0x00000040L +#define SQL_FN_TD_WEEK 0x00000080L +#define SQL_FN_TD_YEAR 0x00000100L +#define SQL_FN_TD_CURTIME 0x00000200L +#define SQL_FN_TD_HOUR 0x00000400L +#define SQL_FN_TD_MINUTE 0x00000800L +#define SQL_FN_TD_SECOND 0x00001000L +#define SQL_FN_TD_TIMESTAMPADD 0x00002000L +#define SQL_FN_TD_TIMESTAMPDIFF 0x00004000L +#define SQL_FN_TD_DAYNAME 0x00008000L +#define SQL_FN_TD_MONTHNAME 0x00010000L +#if (ODBCVER >= 0x0300) +#define SQL_FN_TD_CURRENT_DATE 0x00020000L +#define SQL_FN_TD_CURRENT_TIME 0x00040000L +#define SQL_FN_TD_CURRENT_TIMESTAMP 0x00080000L +#define SQL_FN_TD_EXTRACT 0x00100000L +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetInfo - SQL_TXN_ISOLATION_OPTION + */ +#if (ODBCVER < 0x0300) +#define SQL_TXN_VERSIONING 0x00000010L +#endif /* ODBCVER < 0x0300 */ + + +/* + * SQLGetInfo - SQL_UNION + */ +#define SQL_U_UNION 0x00000001L +#define SQL_U_UNION_ALL 0x00000002L + + +/* + * SQLGetInfo - SQL_UNION_STATEMENT + */ +#if (ODBCVER >= 0x0300) +#define SQL_US_UNION SQL_U_UNION +#define SQL_US_UNION_ALL SQL_U_UNION_ALL +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetStmtAttr - ODBC 2.x attributes + */ +#define SQL_QUERY_TIMEOUT 0 +#define SQL_MAX_ROWS 1 +#define SQL_NOSCAN 2 +#define SQL_MAX_LENGTH 3 +#define SQL_ASYNC_ENABLE 4 +#define SQL_BIND_TYPE 5 +#define SQL_CURSOR_TYPE 6 +#define SQL_CONCURRENCY 7 +#define SQL_KEYSET_SIZE 8 +#define SQL_ROWSET_SIZE 9 +#define SQL_SIMULATE_CURSOR 10 +#define SQL_RETRIEVE_DATA 11 +#define SQL_USE_BOOKMARKS 12 +#define SQL_GET_BOOKMARK 13 +#define SQL_ROW_NUMBER 14 + + +/* + * SQLGetStmtAttr - ODBC 3.x attributes + */ +#if (ODBCVER >= 0x0300) +#define SQL_ATTR_ASYNC_ENABLE 4 +#define SQL_ATTR_CONCURRENCY SQL_CONCURRENCY +#define SQL_ATTR_CURSOR_TYPE SQL_CURSOR_TYPE +#define SQL_ATTR_ENABLE_AUTO_IPD 15 +#define SQL_ATTR_FETCH_BOOKMARK_PTR 16 +#define SQL_ATTR_KEYSET_SIZE SQL_KEYSET_SIZE +#define SQL_ATTR_MAX_LENGTH SQL_MAX_LENGTH +#define SQL_ATTR_MAX_ROWS SQL_MAX_ROWS +#define SQL_ATTR_NOSCAN SQL_NOSCAN +#define SQL_ATTR_PARAM_BIND_OFFSET_PTR 17 +#define SQL_ATTR_PARAM_BIND_TYPE 18 +#define SQL_ATTR_PARAM_OPERATION_PTR 19 +#define SQL_ATTR_PARAM_STATUS_PTR 20 +#define SQL_ATTR_PARAMS_PROCESSED_PTR 21 +#define SQL_ATTR_PARAMSET_SIZE 22 +#define SQL_ATTR_QUERY_TIMEOUT SQL_QUERY_TIMEOUT +#define SQL_ATTR_RETRIEVE_DATA SQL_RETRIEVE_DATA +#define SQL_ATTR_ROW_BIND_OFFSET_PTR 23 +#define SQL_ATTR_ROW_BIND_TYPE SQL_BIND_TYPE +#define SQL_ATTR_ROW_NUMBER SQL_ROW_NUMBER /*GetStmtAttr*/ +#define SQL_ATTR_ROW_OPERATION_PTR 24 +#define SQL_ATTR_ROW_STATUS_PTR 25 +#define SQL_ATTR_ROWS_FETCHED_PTR 26 +#define SQL_ATTR_ROW_ARRAY_SIZE 27 +#define SQL_ATTR_SIMULATE_CURSOR SQL_SIMULATE_CURSOR +#define SQL_ATTR_USE_BOOKMARKS SQL_USE_BOOKMARKS +#endif /* ODBCVER >= 0x0300 */ + +#if (ODBCVER < 0x0300) +#define SQL_STMT_OPT_MAX SQL_ROW_NUMBER +#define SQL_STMT_OPT_MIN SQL_QUERY_TIMEOUT +#endif /* ODBCVER < 0x0300 */ + + +/* + * SQLGetStmtAttr - SQL_ATTR_ASYNC_ENABLE + */ +#define SQL_ASYNC_ENABLE_OFF 0UL +#define SQL_ASYNC_ENABLE_ON 1UL +#define SQL_ASYNC_ENABLE_DEFAULT SQL_ASYNC_ENABLE_OFF + + +/* + * SQLGetStmtAttr - SQL_ATTR_PARAM_BIND_TYPE + */ +#if (ODBCVER >= 0x0300) +#define SQL_PARAM_BIND_BY_COLUMN 0UL +#define SQL_PARAM_BIND_TYPE_DEFAULT SQL_PARAM_BIND_BY_COLUMN +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetStmtAttr - SQL_BIND_TYPE + */ +#define SQL_BIND_BY_COLUMN 0UL +#define SQL_BIND_TYPE_DEFAULT SQL_BIND_BY_COLUMN + + +/* + * SQLGetStmtAttr - SQL_CONCURRENCY + */ +#define SQL_CONCUR_READ_ONLY 1 +#define SQL_CONCUR_LOCK 2 +#define SQL_CONCUR_ROWVER 3 +#define SQL_CONCUR_VALUES 4 +#define SQL_CONCUR_DEFAULT SQL_CONCUR_READ_ONLY + + +/* + * SQLGetStmtAttr - SQL_CURSOR_TYPE + */ +#define SQL_CURSOR_FORWARD_ONLY 0UL +#define SQL_CURSOR_KEYSET_DRIVEN 1UL +#define SQL_CURSOR_DYNAMIC 2UL +#define SQL_CURSOR_STATIC 3UL +#define SQL_CURSOR_TYPE_DEFAULT SQL_CURSOR_FORWARD_ONLY + + +/* + * SQLGetStmtAttr - SQL_KEYSET_SIZE + */ +#define SQL_KEYSET_SIZE_DEFAULT 0UL + + +/* + * SQLGetStmtAttr - SQL_MAX_LENGTH + */ +#define SQL_MAX_LENGTH_DEFAULT 0UL + + +/* + * SQLGetStmtAttr - SQL_MAX_ROWS + */ +#define SQL_MAX_ROWS_DEFAULT 0UL + + +/* + * SQLGetStmtAttr - SQL_NOSCAN + */ +#define SQL_NOSCAN_OFF 0UL /* 1.0 FALSE */ +#define SQL_NOSCAN_ON 1UL /* 1.0 TRUE */ +#define SQL_NOSCAN_DEFAULT SQL_NOSCAN_OFF + + +/* + * SQLGetStmtAttr - SQL_QUERY_TIMEOUT + */ +#define SQL_QUERY_TIMEOUT_DEFAULT 0UL + + +/* + * SQLGetStmtAttr - SQL_RETRIEVE_DATA + */ +#define SQL_RD_OFF 0UL +#define SQL_RD_ON 1UL +#define SQL_RD_DEFAULT SQL_RD_ON + + +/* + * SQLGetStmtAttr - SQL_ROWSET_SIZE + */ +#define SQL_ROWSET_SIZE_DEFAULT 1UL + + +/* + * SQLGetStmtAttr - SQL_SIMULATE_CURSOR + */ +#define SQL_SC_NON_UNIQUE 0UL +#define SQL_SC_TRY_UNIQUE 1UL +#define SQL_SC_UNIQUE 2UL + + +/* + * SQLGetStmtAttr - SQL_USE_BOOKMARKS + */ +#define SQL_UB_OFF 0UL +#define SQL_UB_ON 1UL +#define SQL_UB_DEFAULT SQL_UB_OFF +#if (ODBCVER >= 0x0300) +#define SQL_UB_FIXED SQL_UB_ON +#define SQL_UB_VARIABLE 2UL +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLGetTypeInfo - SEARCHABLE + */ +#if (ODBCVER >= 0x0300) +#define SQL_COL_PRED_CHAR SQL_LIKE_ONLY +#define SQL_COL_PRED_BASIC SQL_ALL_EXCEPT_LIKE +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLSetPos + */ +#define SQL_ENTIRE_ROWSET 0 + + +/* + * SQLSetPos - Operation + */ +#define SQL_POSITION 0 +#define SQL_REFRESH 1 +#define SQL_UPDATE 2 +#define SQL_DELETE 3 + + +/* + * SQLBulkOperations - Operation + */ +#define SQL_ADD 4 +#define SQL_SETPOS_MAX_OPTION_VALUE SQL_ADD +#if (ODBCVER >= 0x0300) +#define SQL_UPDATE_BY_BOOKMARK 5 +#define SQL_DELETE_BY_BOOKMARK 6 +#define SQL_FETCH_BY_BOOKMARK 7 +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLSetPos - LockType + */ +#define SQL_LOCK_NO_CHANGE 0 +#define SQL_LOCK_EXCLUSIVE 1 +#define SQL_LOCK_UNLOCK 2 +#define SQL_SETPOS_MAX_LOCK_VALUE SQL_LOCK_UNLOCK + + +/* + * SQLSetPos macros + */ +#define SQL_POSITION_TO(hstmt,irow) \ + SQLSetPos(hstmt,irow,SQL_POSITION,SQL_LOCK_NO_CHANGE) +#define SQL_LOCK_RECORD(hstmt,irow,fLock) \ + SQLSetPos(hstmt,irow,SQL_POSITION,fLock) +#define SQL_REFRESH_RECORD(hstmt,irow,fLock) \ + SQLSetPos(hstmt,irow,SQL_REFRESH,fLock) +#define SQL_UPDATE_RECORD(hstmt,irow) \ + SQLSetPos(hstmt,irow,SQL_UPDATE,SQL_LOCK_NO_CHANGE) +#define SQL_DELETE_RECORD(hstmt,irow) \ + SQLSetPos(hstmt,irow,SQL_DELETE,SQL_LOCK_NO_CHANGE) +#define SQL_ADD_RECORD(hstmt,irow) \ + SQLSetPos(hstmt,irow,SQL_ADD,SQL_LOCK_NO_CHANGE) + + +/* + * SQLSpecialColumns - Column types and scopes + */ +#define SQL_BEST_ROWID 1 +#define SQL_ROWVER 2 + + +/* + * All the ODBC keywords + */ +#define SQL_ODBC_KEYWORDS \ +"ABSOLUTE,ACTION,ADA,ADD,ALL,ALLOCATE,ALTER,AND,ANY,ARE,AS,"\ +"ASC,ASSERTION,AT,AUTHORIZATION,AVG,"\ +"BEGIN,BETWEEN,BIT,BIT_LENGTH,BOTH,BY,CASCADE,CASCADED,CASE,CAST,CATALOG,"\ +"CHAR,CHAR_LENGTH,CHARACTER,CHARACTER_LENGTH,CHECK,CLOSE,COALESCE,"\ +"COLLATE,COLLATION,COLUMN,COMMIT,CONNECT,CONNECTION,CONSTRAINT,"\ +"CONSTRAINTS,CONTINUE,CONVERT,CORRESPONDING,COUNT,CREATE,CROSS,CURRENT,"\ +"CURRENT_DATE,CURRENT_TIME,CURRENT_TIMESTAMP,CURRENT_USER,CURSOR,"\ +"DATE,DAY,DEALLOCATE,DEC,DECIMAL,DECLARE,DEFAULT,DEFERRABLE,"\ +"DEFERRED,DELETE,DESC,DESCRIBE,DESCRIPTOR,DIAGNOSTICS,DISCONNECT,"\ +"DISTINCT,DOMAIN,DOUBLE,DROP,"\ +"ELSE,END,END-EXEC,ESCAPE,EXCEPT,EXCEPTION,EXEC,EXECUTE,"\ +"EXISTS,EXTERNAL,EXTRACT,"\ +"FALSE,FETCH,FIRST,FLOAT,FOR,FOREIGN,FORTRAN,FOUND,FROM,FULL,"\ +"GET,GLOBAL,GO,GOTO,GRANT,GROUP,HAVING,HOUR,"\ +"IDENTITY,IMMEDIATE,IN,INCLUDE,INDEX,INDICATOR,INITIALLY,INNER,"\ +"INPUT,INSENSITIVE,INSERT,INT,INTEGER,INTERSECT,INTERVAL,INTO,IS,ISOLATION,"\ +"JOIN,KEY,LANGUAGE,LAST,LEADING,LEFT,LEVEL,LIKE,LOCAL,LOWER,"\ +"MATCH,MAX,MIN,MINUTE,MODULE,MONTH,"\ +"NAMES,NATIONAL,NATURAL,NCHAR,NEXT,NO,NONE,NOT,NULL,NULLIF,NUMERIC,"\ +"OCTET_LENGTH,OF,ON,ONLY,OPEN,OPTION,OR,ORDER,OUTER,OUTPUT,OVERLAPS,"\ +"PAD,PARTIAL,PASCAL,PLI,POSITION,PRECISION,PREPARE,PRESERVE,"\ +"PRIMARY,PRIOR,PRIVILEGES,PROCEDURE,PUBLIC,"\ +"READ,REAL,REFERENCES,RELATIVE,RESTRICT,REVOKE,RIGHT,ROLLBACK,ROWS"\ +"SCHEMA,SCROLL,SECOND,SECTION,SELECT,SESSION,SESSION_USER,SET,SIZE,"\ +"SMALLINT,SOME,SPACE,SQL,SQLCA,SQLCODE,SQLERROR,SQLSTATE,SQLWARNING,"\ +"SUBSTRING,SUM,SYSTEM_USER,"\ +"TABLE,TEMPORARY,THEN,TIME,TIMESTAMP,TIMEZONE_HOUR,TIMEZONE_MINUTE,"\ +"TO,TRAILING,TRANSACTION,TRANSLATE,TRANSLATION,TRIM,TRUE,"\ +"UNION,UNIQUE,UNKNOWN,UPDATE,UPPER,USAGE,USER,USING,"\ +"VALUE,VALUES,VARCHAR,VARYING,VIEW,WHEN,WHENEVER,WHERE,WITH,WORK,WRITE,"\ +"YEAR,ZONE" + + +/* + * ---------------------------------------------------------------------- + * Level 2 Functions + * ---------------------------------------------------------------------- + */ + +/* + * SQLExtendedFetch - fFetchType + */ +#define SQL_FETCH_BOOKMARK 8 + + +/* + * SQLExtendedFetch - rgfRowStatus + */ +#define SQL_ROW_SUCCESS 0 +#define SQL_ROW_DELETED 1 +#define SQL_ROW_UPDATED 2 +#define SQL_ROW_NOROW 3 +#define SQL_ROW_ADDED 4 +#define SQL_ROW_ERROR 5 +#if (ODBCVER >= 0x0300) +#define SQL_ROW_SUCCESS_WITH_INFO 6 +#define SQL_ROW_PROCEED 0 +#define SQL_ROW_IGNORE 1 +#endif + + +/* + * SQL_DESC_ARRAY_STATUS_PTR + */ +#if (ODBCVER >= 0x0300) +#define SQL_PARAM_SUCCESS 0 +#define SQL_PARAM_SUCCESS_WITH_INFO 6 +#define SQL_PARAM_ERROR 5 +#define SQL_PARAM_UNUSED 7 +#define SQL_PARAM_DIAG_UNAVAILABLE 1 + +#define SQL_PARAM_PROCEED 0 +#define SQL_PARAM_IGNORE 1 +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLForeignKeys - UPDATE_RULE/DELETE_RULE + */ +#define SQL_CASCADE 0 +#define SQL_RESTRICT 1 +#define SQL_SET_NULL 2 + +#if (ODBCVER >= 0x0250) +#define SQL_NO_ACTION 3 +#define SQL_SET_DEFAULT 4 +#endif /* ODBCVER >= 0x0250 */ + + +/* + * SQLForeignKeys - DEFERABILITY + */ +#if (ODBCVER >= 0x0300) +#define SQL_INITIALLY_DEFERRED 5 +#define SQL_INITIALLY_IMMEDIATE 6 +#define SQL_NOT_DEFERRABLE 7 +#endif /* ODBCVER >= 0x0300 */ + + +/* + * SQLBindParameter - fParamType + * SQLProcedureColumns - COLUMN_TYPE + */ +#define SQL_PARAM_TYPE_UNKNOWN 0 +#define SQL_PARAM_INPUT 1 +#define SQL_PARAM_INPUT_OUTPUT 2 +#define SQL_RESULT_COL 3 +#define SQL_PARAM_OUTPUT 4 +#define SQL_RETURN_VALUE 5 + + +/* + * SQLProcedures - PROCEDURE_TYPE + */ +#define SQL_PT_UNKNOWN 0 +#define SQL_PT_PROCEDURE 1 +#define SQL_PT_FUNCTION 2 + + +/* + * SQLSetParam to SQLBindParameter conversion + */ +#define SQL_PARAM_TYPE_DEFAULT SQL_PARAM_INPUT_OUTPUT +#define SQL_SETPARAM_VALUE_MAX (-1L) + + +/* + * SQLStatistics - fAccuracy + */ +#define SQL_QUICK 0 +#define SQL_ENSURE 1 + + +/* + * SQLStatistics - TYPE + */ +#define SQL_TABLE_STAT 0 + + +/* + * SQLTables + */ +#if (ODBCVER >= 0x0300) +#define SQL_ALL_CATALOGS "%" +#define SQL_ALL_SCHEMAS "%" +#define SQL_ALL_TABLE_TYPES "%" +#endif /* ODBCVER >= 0x0300 */ + +/* + * SQLSpecialColumns - PSEUDO_COLUMN + */ +#define SQL_PC_NOT_PSEUDO 1 + + +/* + * Deprecated defines from prior versions of ODBC + */ +#define SQL_DATABASE_NAME 16 +#define SQL_FD_FETCH_PREV SQL_FD_FETCH_PRIOR +#define SQL_FETCH_PREV SQL_FETCH_PRIOR +#define SQL_CONCUR_TIMESTAMP SQL_CONCUR_ROWVER +#define SQL_SCCO_OPT_TIMESTAMP SQL_SCCO_OPT_ROWVER +#define SQL_CC_DELETE SQL_CB_DELETE +#define SQL_CR_DELETE SQL_CB_DELETE +#define SQL_CC_CLOSE SQL_CB_CLOSE +#define SQL_CR_CLOSE SQL_CB_CLOSE +#define SQL_CC_PRESERVE SQL_CB_PRESERVE +#define SQL_CR_PRESERVE SQL_CB_PRESERVE +#if (ODBCVER < 0x0200) +#define SQL_FETCH_RESUME 7 +#endif +#define SQL_SCROLL_FORWARD_ONLY 0L +#define SQL_SCROLL_KEYSET_DRIVEN (-1L) +#define SQL_SCROLL_DYNAMIC (-2L) +#define SQL_SCROLL_STATIC (-3L) + + +/* + * Level 1 function prototypes + */ +SQLRETURN SQL_API SQLDriverConnect ( + SQLHDBC hdbc, + SQLHWND hwnd, + SQLCHAR * szConnStrIn, + SQLSMALLINT cbConnStrIn, + SQLCHAR * szConnStrOut, + SQLSMALLINT cbConnStrOutMax, + SQLSMALLINT * pcbConnStrOut, + SQLUSMALLINT fDriverCompletion); + +/* + * Level 2 function prototypes + */ + +SQLRETURN SQL_API SQLBrowseConnect ( + SQLHDBC hdbc, + SQLCHAR * szConnStrIn, + SQLSMALLINT cbConnStrIn, + SQLCHAR * szConnStrOut, + SQLSMALLINT cbConnStrOutMax, + SQLSMALLINT * pcbConnStrOut); + +#if (ODBCVER >= 0x0300) +SQLRETURN SQL_API SQLBulkOperations ( + SQLHSTMT StatementHandle, + SQLSMALLINT Operation); +#endif /* ODBCVER >= 0x0300 */ + +SQLRETURN SQL_API SQLColAttributes ( + SQLHSTMT hstmt, + SQLUSMALLINT icol, + SQLUSMALLINT fDescType, + SQLPOINTER rgbDesc, + SQLSMALLINT cbDescMax, + SQLSMALLINT * pcbDesc, + SQLLEN * pfDesc); + +SQLRETURN SQL_API SQLColumnPrivileges ( + SQLHSTMT hstmt, + SQLCHAR * szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR * szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR * szTableName, + SQLSMALLINT cbTableName, + SQLCHAR * szColumnName, + SQLSMALLINT cbColumnName); + +SQLRETURN SQL_API SQLDescribeParam ( + SQLHSTMT hstmt, + SQLUSMALLINT ipar, + SQLSMALLINT * pfSqlType, + SQLULEN * pcbParamDef, + SQLSMALLINT * pibScale, + SQLSMALLINT * pfNullable); + +SQLRETURN SQL_API SQLExtendedFetch ( + SQLHSTMT hstmt, + SQLUSMALLINT fFetchType, + SQLLEN irow, + SQLULEN * pcrow, + SQLUSMALLINT * rgfRowStatus); + +SQLRETURN SQL_API SQLForeignKeys ( + SQLHSTMT hstmt, + SQLCHAR * szPkCatalogName, + SQLSMALLINT cbPkCatalogName, + SQLCHAR * szPkSchemaName, + SQLSMALLINT cbPkSchemaName, + SQLCHAR * szPkTableName, + SQLSMALLINT cbPkTableName, + SQLCHAR * szFkCatalogName, + SQLSMALLINT cbFkCatalogName, + SQLCHAR * szFkSchemaName, + SQLSMALLINT cbFkSchemaName, + SQLCHAR * szFkTableName, + SQLSMALLINT cbFkTableName); + +SQLRETURN SQL_API SQLMoreResults ( + SQLHSTMT hstmt); + +SQLRETURN SQL_API SQLNativeSql ( + SQLHDBC hdbc, + SQLCHAR * szSqlStrIn, + SQLINTEGER cbSqlStrIn, + SQLCHAR * szSqlStr, + SQLINTEGER cbSqlStrMax, + SQLINTEGER * pcbSqlStr); + +SQLRETURN SQL_API SQLNumParams ( + SQLHSTMT hstmt, + SQLSMALLINT * pcpar); + +SQLRETURN SQL_API SQLParamOptions ( + SQLHSTMT hstmt, + SQLULEN crow, + SQLULEN * pirow); + +SQLRETURN SQL_API SQLPrimaryKeys ( + SQLHSTMT hstmt, + SQLCHAR * szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR * szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR * szTableName, + SQLSMALLINT cbTableName); + +SQLRETURN SQL_API SQLProcedureColumns ( + SQLHSTMT hstmt, + SQLCHAR * szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR * szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR * szProcName, + SQLSMALLINT cbProcName, + SQLCHAR * szColumnName, + SQLSMALLINT cbColumnName); + +SQLRETURN SQL_API SQLProcedures ( + SQLHSTMT hstmt, + SQLCHAR * szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR * szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR * szProcName, + SQLSMALLINT cbProcName); + +SQLRETURN SQL_API SQLSetPos ( + SQLHSTMT hstmt, + SQLSETPOSIROW irow, + SQLUSMALLINT fOption, + SQLUSMALLINT fLock); + +SQLRETURN SQL_API SQLTablePrivileges ( + SQLHSTMT hstmt, + SQLCHAR * szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR * szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR * szTableName, + SQLSMALLINT cbTableName); + +SQLRETURN SQL_API SQLDrivers ( + SQLHENV henv, + SQLUSMALLINT fDirection, + SQLCHAR * szDriverDesc, + SQLSMALLINT cbDriverDescMax, + SQLSMALLINT * pcbDriverDesc, + SQLCHAR * szDriverAttributes, + SQLSMALLINT cbDrvrAttrMax, + SQLSMALLINT * pcbDrvrAttr); + +SQLRETURN SQL_API SQLBindParameter ( + SQLHSTMT hstmt, + SQLUSMALLINT ipar, + SQLSMALLINT fParamType, + SQLSMALLINT fCType, + SQLSMALLINT fSqlType, + SQLULEN cbColDef, + SQLSMALLINT ibScale, + SQLPOINTER rgbValue, + SQLLEN cbValueMax, + SQLLEN * pcbValue); + +/* + * Depreciated - use SQLSetStmtOptions + */ +SQLRETURN SQL_API SQLSetScrollOptions ( /* Use SQLSetStmtOptions */ + SQLHSTMT hstmt, + SQLUSMALLINT fConcurrency, + SQLLEN crowKeyset, + SQLUSMALLINT crowRowset); + + +/* + * SQLAllocHandleStd - make SQLAllocHandle compatible with X/Open standard + * + * NOTE: An application should not call SQLAllocHandleStd directly + */ +#ifdef ODBC_STD +#define SQLAllocHandle SQLAllocHandleStd +#define SQLAllocEnv(phenv) \ + SQLAllocHandleStd(SQL_HANDLE_ENV, SQL_NULL_HANDLE, phenv) + +#if (ODBCVER >= 0x0300) +SQLRETURN SQL_API SQLAllocHandleStd ( + SQLSMALLINT fHandleType, + SQLHANDLE hInput, + SQLHANDLE * phOutput); +#endif + + +/* Internal type subcodes */ +#define SQL_YEAR SQL_CODE_YEAR +#define SQL_MONTH SQL_CODE_MONTH +#define SQL_DAY SQL_CODE_DAY +#define SQL_HOUR SQL_CODE_HOUR +#define SQL_MINUTE SQL_CODE_MINUTE +#define SQL_SECOND SQL_CODE_SECOND +#define SQL_YEAR_TO_MONTH SQL_CODE_YEAR_TO_MONTH +#define SQL_DAY_TO_HOUR SQL_CODE_DAY_TO_HOUR +#define SQL_DAY_TO_MINUTE SQL_CODE_DAY_TO_MINUTE +#define SQL_DAY_TO_SECOND SQL_CODE_DAY_TO_SECOND +#define SQL_HOUR_TO_MINUTE SQL_CODE_HOUR_TO_MINUTE +#define SQL_HOUR_TO_SECOND SQL_CODE_HOUR_TO_SECOND +#define SQL_MINUTE_TO_SECOND SQL_CODE_MINUTE_TO_SECOND +#endif /* ODBC_STD */ + + +#ifdef __cplusplus +} +#endif + +#include + +#endif /* _SQLEXT_H */ diff --git a/libodbc/include/odbc_linux/sqltypes.h b/libodbc/include/odbc_linux/sqltypes.h new file mode 100644 index 0000000000..1b852cff4c --- /dev/null +++ b/libodbc/include/odbc_linux/sqltypes.h @@ -0,0 +1,431 @@ +/* + * sqltypes.h + * + * $Id: sqltypes.h,v 1.4 2013/09/01 17:11:20 yas Exp $ + * + * ODBC typedefs + * + * The iODBC driver manager. + * + * Copyright (C) 1995 by Ke Jin + * Copyright (C) 1996-2009 by OpenLink Software + * All Rights Reserved. + * + * This software is released under the terms of either of the following + * licenses: + * + * - GNU Library General Public License (see LICENSE.LGPL) + * - The BSD License (see LICENSE.BSD). + * + * Note that the only valid version of the LGPL license as far as this + * project is concerned is the original GNU Library General Public License + * Version 2, dated June 1991. + * + * While not mandated by the BSD license, any patches you make to the + * iODBC source code may be contributed back into the iODBC project + * at your discretion. Contributions will benefit the Open Source and + * Data Access community as a whole. Submissions may be made at: + * + * http://www.iodbc.org + * + * + * GNU Library Generic Public License Version 2 + * ============================================ + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; only + * Version 2 of the License dated June 1991. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * + * The BSD License + * =============== + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name of OpenLink Software Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL OPENLINK OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _SQLTYPES_H +#define _SQLTYPES_H + +/* + * Set default specification to ODBC 3.51 + */ +#ifndef ODBCVER +#define ODBCVER 0x0351 +#endif + +/* + * Include Windows style defines and typedefs on Unix + */ +#ifndef _IODBCUNIX_H +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _IODBCUNIX_H +#include +#endif + +/* + * Environment specific definitions + */ +#ifndef EXPORT +#define EXPORT +#endif + +#ifdef WIN32 +#define SQL_API __stdcall +#else +#define SQL_API +#endif + + +/* + * API declaration data types + */ +typedef unsigned char SQLCHAR; +typedef signed short SQLSMALLINT; +typedef unsigned short SQLUSMALLINT; +#if (SIZEOF_LONG == 8) +typedef signed int SQLINTEGER; +typedef unsigned int SQLUINTEGER; +#else +typedef signed long SQLINTEGER; +typedef unsigned long SQLUINTEGER; +#endif +typedef void * SQLPOINTER; + +#if (ODBCVER >= 0x0300) +typedef signed char SQLSCHAR; +typedef unsigned char SQLDATE; +typedef unsigned char SQLDECIMAL; +typedef unsigned char SQLNUMERIC; +typedef double SQLDOUBLE; +typedef double SQLFLOAT; +typedef float SQLREAL; +typedef unsigned char SQLTIME; +typedef unsigned char SQLTIMESTAMP; +typedef unsigned char SQLVARCHAR; +#endif /* ODBCVER >= 0x0300 */ + + +/* + * New Win64 datatypes + */ +#ifdef _WIN64 +typedef INT64 SQLLEN; +typedef UINT64 SQLULEN; +typedef UINT64 SQLSETPOSIROW; +#elif defined(STRICT_ODBC_TYPES) +typedef long SQLLEN; +typedef unsigned long SQLULEN; +typedef unsigned short SQLSETPOSIROW; +#else +#define SQLLEN long +#define SQLULEN unsigned long +#define SQLSETPOSIROW unsigned short +#endif + + +/* + * Backward compatibility with older platform sdks + */ +typedef SQLULEN SQLROWCOUNT; +typedef SQLULEN SQLROWSETSIZE; +typedef SQLULEN SQLTRANSID; +typedef SQLLEN SQLROWOFFSET; + + +/* + * Generic pointer types + */ +typedef void * PTR; +typedef void * SQLHANDLE; + + +/* + * Handles + */ +typedef void * HENV; +typedef void * HDBC; +typedef void * HSTMT; + +typedef SQLHANDLE SQLHENV; +typedef SQLHANDLE SQLHDBC; +typedef SQLHANDLE SQLHSTMT; +#if (ODBCVER >= 0x0300) +typedef SQLHANDLE SQLHDESC; +#endif /* ODBCVER >= 0x0300 */ + + +/* + * Window Handle + */ +#if defined(WIN32) || defined (_WIN64) || defined(OS2) +typedef HWND SQLHWND; +#elif defined(macintosh) +#include +typedef WindowPtr HWND; +typedef HWND SQLHWND; +#else +typedef SQLPOINTER HWND; +typedef SQLPOINTER SQLHWND; +#endif + + +/* + * SQL portable types for C + */ +typedef unsigned char UCHAR; +typedef signed char SCHAR; +typedef short int SWORD; +typedef unsigned short int UWORD; +typedef long int SDWORD; +typedef unsigned long int UDWORD; + +typedef signed short SSHORT; +typedef unsigned short USHORT; +typedef signed long SLONG; +typedef unsigned long ULONG; +typedef float SFLOAT; +typedef double SDOUBLE; +typedef double LDOUBLE; + + +/* + * Return type for functions + */ +typedef signed short RETCODE; +typedef SQLSMALLINT SQLRETURN; + + +/* + * SQL portable types for C - DATA, TIME, TIMESTAMP, and BOOKMARK + */ +typedef SQLULEN BOOKMARK; + + +typedef struct tagDATE_STRUCT + { + SQLSMALLINT year; + SQLUSMALLINT month; + SQLUSMALLINT day; + } +DATE_STRUCT; + +#if (ODBCVER >= 0x0300) +typedef DATE_STRUCT SQL_DATE_STRUCT; +#endif /* ODBCVER >= 0x0300 */ + + +typedef struct tagTIME_STRUCT + { + SQLUSMALLINT hour; + SQLUSMALLINT minute; + SQLUSMALLINT second; + } +TIME_STRUCT; + +#if (ODBCVER >= 0x0300) +typedef TIME_STRUCT SQL_TIME_STRUCT; +#endif /* ODBCVER >= 0x0300 */ + + +typedef struct tagTIMESTAMP_STRUCT + { + SQLSMALLINT year; + SQLUSMALLINT month; + SQLUSMALLINT day; + SQLUSMALLINT hour; + SQLUSMALLINT minute; + SQLUSMALLINT second; + SQLUINTEGER fraction; + } +TIMESTAMP_STRUCT; + +#if (ODBCVER >= 0x0300) +typedef TIMESTAMP_STRUCT SQL_TIMESTAMP_STRUCT; +#endif /* ODBCVER >= 0x0300 */ + + +/* + * Enumeration for DATETIME_INTERVAL_SUBCODE values for interval data types + * + * These values are from SQL-92 + */ +#if (ODBCVER >= 0x0300) +typedef enum + { + SQL_IS_YEAR = 1, + SQL_IS_MONTH = 2, + SQL_IS_DAY = 3, + SQL_IS_HOUR = 4, + SQL_IS_MINUTE = 5, + SQL_IS_SECOND = 6, + SQL_IS_YEAR_TO_MONTH = 7, + SQL_IS_DAY_TO_HOUR = 8, + SQL_IS_DAY_TO_MINUTE = 9, + SQL_IS_DAY_TO_SECOND = 10, + SQL_IS_HOUR_TO_MINUTE = 11, + SQL_IS_HOUR_TO_SECOND = 12, + SQL_IS_MINUTE_TO_SECOND = 13 + } +SQLINTERVAL; + + +typedef struct tagSQL_YEAR_MONTH + { + SQLUINTEGER year; + SQLUINTEGER month; + } +SQL_YEAR_MONTH_STRUCT; + + +typedef struct tagSQL_DAY_SECOND + { + SQLUINTEGER day; + SQLUINTEGER hour; + SQLUINTEGER minute; + SQLUINTEGER second; + SQLUINTEGER fraction; + } +SQL_DAY_SECOND_STRUCT; + + +typedef struct tagSQL_INTERVAL_STRUCT + { + SQLINTERVAL interval_type; + SQLSMALLINT interval_sign; + union + { + SQL_YEAR_MONTH_STRUCT year_month; + SQL_DAY_SECOND_STRUCT day_second; + } + intval; + } +SQL_INTERVAL_STRUCT; +#endif /* ODBCVER >= 0x0300 */ + + +/* + * The ODBC C types for SQL_C_SBIGINT and SQL_C_UBIGINT + */ +#if (ODBCVER >= 0x0300) + +#if (_MSC_VER >= 900) +# define ODBCINT64 __int64 +#endif + +#ifndef ODBCINT64 +# if (SIZEOF_LONG == 8) +# define ODBCINT64 long +# else +# define ODBCINT64 long long +# endif +#endif /* ODBCINT64 */ + +#if defined (ODBCINT64) +typedef signed ODBCINT64 SQLBIGINT; +typedef unsigned ODBCINT64 SQLUBIGINT; +#endif /* ODBCINT64 */ + +#endif /* ODBCVER >= 0x0300 */ + + +/* + * The internal representation of the numeric data type + */ +#if (ODBCVER >= 0x0300) +#define SQL_MAX_NUMERIC_LEN 16 +typedef struct tagSQL_NUMERIC_STRUCT + { + SQLCHAR precision; + SQLSCHAR scale; + SQLCHAR sign; /* 0 for negative, 1 for positive */ + SQLCHAR val[SQL_MAX_NUMERIC_LEN]; + } +SQL_NUMERIC_STRUCT; +#endif /* ODBCVER >= 0x0300 */ + + +#if (ODBCVER >= 0x0350) +#ifdef GUID_DEFINED +typedef GUID SQLGUID; +#else +typedef struct tagSQLGUID + { + unsigned int Data1; + unsigned short Data2; + unsigned short Data3; + unsigned char Data4[8]; /* BYTE */ + } +SQLGUID; +#endif /* GUID_DEFINED */ +#endif /* ODBCVER >= 0x0350 */ + + +#if defined(WIN32) +typedef unsigned short SQLWCHAR; +#else +# include + +# if defined(__cplusplus) || \ + defined(_WCHAR_T) || \ + defined(_WCHAR_T_DEFINED) || \ + defined(_WCHAR_T_DEFINED_) || \ + defined(_WCHAR_T_DECLARED) || \ + defined(_BSD_WCHAR_T_DEFINED_) || \ + defined(_BSD_WCHAR_T_) || \ + defined(_BSD_CT_RUNE_T_) +typedef wchar_t SQLWCHAR; +# else +# error Please make sure your system supports the wchar_t type +# endif +#endif /* WIN32 */ + + +#ifdef UNICODE +typedef SQLWCHAR SQLTCHAR; +#else +typedef SQLCHAR SQLTCHAR; +#endif /* UNICODE */ + +#ifdef __cplusplus +} +#endif + +#endif /* _SQLTYPES_H */ diff --git a/libodbc/include/odbc_linux/sqlucode.h b/libodbc/include/odbc_linux/sqlucode.h new file mode 100644 index 0000000000..6cadabda7f --- /dev/null +++ b/libodbc/include/odbc_linux/sqlucode.h @@ -0,0 +1,818 @@ +/* + * sqlucode.h + * + * $Id: sqlucode.h,v 1.2 2013/09/01 17:11:20 yas Exp $ + * + * ODBC Unicode defines + * + * The iODBC driver manager. + * + * Copyright (C) 1996-2009 by OpenLink Software + * All Rights Reserved. + * + * This software is released under the terms of either of the following + * licenses: + * + * - GNU Library General Public License (see LICENSE.LGPL) + * - The BSD License (see LICENSE.BSD). + * + * Note that the only valid version of the LGPL license as far as this + * project is concerned is the original GNU Library General Public License + * Version 2, dated June 1991. + * + * While not mandated by the BSD license, any patches you make to the + * iODBC source code may be contributed back into the iODBC project + * at your discretion. Contributions will benefit the Open Source and + * Data Access community as a whole. Submissions may be made at: + * + * http://www.iodbc.org + * + * + * GNU Library Generic Public License Version 2 + * ============================================ + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; only + * Version 2 of the License dated June 1991. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * + * The BSD License + * =============== + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name of OpenLink Software Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL OPENLINK OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _SQLUCODE_H +#define _SQLUCODE_H + +#ifndef _SQLEXT_H +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +/* + * SQL datatypes - Unicode + */ +#define SQL_WCHAR (-8) +#define SQL_WVARCHAR (-9) +#define SQL_WLONGVARCHAR (-10) +#define SQL_C_WCHAR SQL_WCHAR + +#ifdef UNICODE +#define SQL_C_TCHAR SQL_C_WCHAR +#else +#define SQL_C_TCHAR SQL_C_CHAR +#endif + + +/* SQLTablesW */ +#if (ODBCVER >= 0x0300) +#define SQL_ALL_CATALOGSW L"%" +#define SQL_ALL_SCHEMASW L"%" +#define SQL_ALL_TABLE_TYPESW L"%" +#endif /* ODBCVER >= 0x0300 */ + + +/* + * Size of SQLSTATE - Unicode + */ +#define SQL_SQLSTATE_SIZEW 10 + + +/* + * Function Prototypes - Unicode + */ +SQLRETURN SQL_API SQLColAttributeW ( + SQLHSTMT hstmt, + SQLUSMALLINT iCol, + SQLUSMALLINT iField, + SQLPOINTER pCharAttr, + SQLSMALLINT cbCharAttrMax, + SQLSMALLINT * pcbCharAttr, + SQLLEN * pNumAttr); + +SQLRETURN SQL_API SQLColAttributesW ( + SQLHSTMT hstmt, + SQLUSMALLINT icol, + SQLUSMALLINT fDescType, + SQLPOINTER rgbDesc, + SQLSMALLINT cbDescMax, + SQLSMALLINT * pcbDesc, + SQLLEN * pfDesc); + +SQLRETURN SQL_API SQLConnectW ( + SQLHDBC hdbc, + SQLWCHAR * szDSN, + SQLSMALLINT cbDSN, + SQLWCHAR * szUID, + SQLSMALLINT cbUID, + SQLWCHAR * szAuthStr, + SQLSMALLINT cbAuthStr); + +SQLRETURN SQL_API SQLDescribeColW ( + SQLHSTMT hstmt, + SQLUSMALLINT icol, + SQLWCHAR * szColName, + SQLSMALLINT cbColNameMax, + SQLSMALLINT * pcbColName, + SQLSMALLINT * pfSqlType, + SQLULEN * pcbColDef, + SQLSMALLINT * pibScale, + SQLSMALLINT * pfNullable); + +SQLRETURN SQL_API SQLErrorW ( + SQLHENV henv, + SQLHDBC hdbc, + SQLHSTMT hstmt, + SQLWCHAR * szSqlState, + SQLINTEGER * pfNativeError, + SQLWCHAR * szErrorMsg, + SQLSMALLINT cbErrorMsgMax, + SQLSMALLINT * pcbErrorMsg); + +SQLRETURN SQL_API SQLExecDirectW ( + SQLHSTMT hstmt, + SQLWCHAR * szSqlStr, + SQLINTEGER cbSqlStr); + +SQLRETURN SQL_API SQLGetConnectAttrW ( + SQLHDBC hdbc, + SQLINTEGER fAttribute, + SQLPOINTER rgbValue, + SQLINTEGER cbValueMax, + SQLINTEGER * pcbValue); + +SQLRETURN SQL_API SQLGetCursorNameW ( + SQLHSTMT hstmt, + SQLWCHAR * szCursor, + SQLSMALLINT cbCursorMax, + SQLSMALLINT * pcbCursor); + +#if (ODBCVER >= 0x0300) +SQLRETURN SQL_API SQLSetDescFieldW ( + SQLHDESC DescriptorHandle, + SQLSMALLINT RecNumber, + SQLSMALLINT FieldIdentifier, + SQLPOINTER Value, + SQLINTEGER BufferLength); + +SQLRETURN SQL_API SQLGetDescFieldW ( + SQLHDESC hdesc, + SQLSMALLINT iRecord, + SQLSMALLINT iField, + SQLPOINTER rgbValue, + SQLINTEGER cbValueMax, + SQLINTEGER * pcbValue); + +SQLRETURN SQL_API SQLGetDescRecW ( + SQLHDESC hdesc, + SQLSMALLINT iRecord, + SQLWCHAR * szName, + SQLSMALLINT cbNameMax, + SQLSMALLINT * pcbName, + SQLSMALLINT * pfType, + SQLSMALLINT * pfSubType, + SQLLEN * pLength, + SQLSMALLINT * pPrecision, + SQLSMALLINT * pScale, + SQLSMALLINT * pNullable); + +SQLRETURN SQL_API SQLGetDiagFieldW ( + SQLSMALLINT fHandleType, + SQLHANDLE handle, + SQLSMALLINT iRecord, + SQLSMALLINT fDiagField, + SQLPOINTER rgbDiagInfo, + SQLSMALLINT cbDiagInfoMax, + SQLSMALLINT * pcbDiagInfo); + +SQLRETURN SQL_API SQLGetDiagRecW ( + SQLSMALLINT fHandleType, + SQLHANDLE handle, + SQLSMALLINT iRecord, + SQLWCHAR * szSqlState, + SQLINTEGER * pfNativeError, + SQLWCHAR * szErrorMsg, + SQLSMALLINT cbErrorMsgMax, + SQLSMALLINT * pcbErrorMsg); +#endif + +SQLRETURN SQL_API SQLPrepareW ( + SQLHSTMT hstmt, + SQLWCHAR * szSqlStr, + SQLINTEGER cbSqlStr); + +SQLRETURN SQL_API SQLSetConnectAttrW ( + SQLHDBC hdbc, + SQLINTEGER fAttribute, + SQLPOINTER rgbValue, + SQLINTEGER cbValue); + +SQLRETURN SQL_API SQLSetCursorNameW ( + SQLHSTMT hstmt, + SQLWCHAR * szCursor, + SQLSMALLINT cbCursor); + +SQLRETURN SQL_API SQLColumnsW ( + SQLHSTMT hstmt, + SQLWCHAR * szCatalogName, + SQLSMALLINT cbCatalogName, + SQLWCHAR * szSchemaName, + SQLSMALLINT cbSchemaName, + SQLWCHAR * szTableName, + SQLSMALLINT cbTableName, + SQLWCHAR * szColumnName, + SQLSMALLINT cbColumnName); + +SQLRETURN SQL_API SQLGetConnectOptionW ( + SQLHDBC hdbc, + SQLUSMALLINT fOption, + SQLPOINTER pvParam); + +SQLRETURN SQL_API SQLGetInfoW ( + SQLHDBC hdbc, + SQLUSMALLINT fInfoType, + SQLPOINTER rgbInfoValue, + SQLSMALLINT cbInfoValueMax, + SQLSMALLINT * pcbInfoValue); + +SQLRETURN SQL_API SQLGetTypeInfoW ( + SQLHSTMT StatementHandle, + SQLSMALLINT DataType); + +SQLRETURN SQL_API SQLSetConnectOptionW ( + SQLHDBC hdbc, + SQLUSMALLINT fOption, + SQLULEN vParam); + +SQLRETURN SQL_API SQLSpecialColumnsW ( + SQLHSTMT hstmt, + SQLUSMALLINT fColType, + SQLWCHAR * szCatalogName, + SQLSMALLINT cbCatalogName, + SQLWCHAR * szSchemaName, + SQLSMALLINT cbSchemaName, + SQLWCHAR * szTableName, + SQLSMALLINT cbTableName, + SQLUSMALLINT fScope, + SQLUSMALLINT fNullable); + +SQLRETURN SQL_API SQLStatisticsW ( + SQLHSTMT hstmt, + SQLWCHAR * szCatalogName, + SQLSMALLINT cbCatalogName, + SQLWCHAR * szSchemaName, + SQLSMALLINT cbSchemaName, + SQLWCHAR * szTableName, + SQLSMALLINT cbTableName, + SQLUSMALLINT fUnique, + SQLUSMALLINT fAccuracy); + +SQLRETURN SQL_API SQLTablesW ( + SQLHSTMT hstmt, + SQLWCHAR * szCatalogName, + SQLSMALLINT cbCatalogName, + SQLWCHAR * szSchemaName, + SQLSMALLINT cbSchemaName, + SQLWCHAR * szTableName, + SQLSMALLINT cbTableName, + SQLWCHAR * szTableType, + SQLSMALLINT cbTableType); + +SQLRETURN SQL_API SQLDataSourcesW ( + SQLHENV henv, + SQLUSMALLINT fDirection, + SQLWCHAR * szDSN, + SQLSMALLINT cbDSNMax, + SQLSMALLINT * pcbDSN, + SQLWCHAR * szDescription, + SQLSMALLINT cbDescriptionMax, + SQLSMALLINT * pcbDescription); + +SQLRETURN SQL_API SQLDriverConnectW ( + SQLHDBC hdbc, + SQLHWND hwnd, + SQLWCHAR * szConnStrIn, + SQLSMALLINT cbConnStrIn, + SQLWCHAR * szConnStrOut, + SQLSMALLINT cbConnStrOutMax, + SQLSMALLINT * pcbConnStrOut, + SQLUSMALLINT fDriverCompletion); + +SQLRETURN SQL_API SQLBrowseConnectW ( + SQLHDBC hdbc, + SQLWCHAR * szConnStrIn, + SQLSMALLINT cbConnStrIn, + SQLWCHAR * szConnStrOut, + SQLSMALLINT cbConnStrOutMax, + SQLSMALLINT * pcbConnStrOut); + +SQLRETURN SQL_API SQLColumnPrivilegesW ( + SQLHSTMT hstmt, + SQLWCHAR * szCatalogName, + SQLSMALLINT cbCatalogName, + SQLWCHAR * szSchemaName, + SQLSMALLINT cbSchemaName, + SQLWCHAR * szTableName, + SQLSMALLINT cbTableName, + SQLWCHAR * szColumnName, + SQLSMALLINT cbColumnName); + +SQLRETURN SQL_API SQLGetStmtAttrW ( + SQLHSTMT hstmt, + SQLINTEGER fAttribute, + SQLPOINTER rgbValue, + SQLINTEGER cbValueMax, + SQLINTEGER * pcbValue); + +SQLRETURN SQL_API SQLSetStmtAttrW ( + SQLHSTMT hstmt, + SQLINTEGER fAttribute, + SQLPOINTER rgbValue, + SQLINTEGER cbValueMax); + +SQLRETURN SQL_API SQLForeignKeysW ( + SQLHSTMT hstmt, + SQLWCHAR * szPkCatalogName, + SQLSMALLINT cbPkCatalogName, + SQLWCHAR * szPkSchemaName, + SQLSMALLINT cbPkSchemaName, + SQLWCHAR * szPkTableName, + SQLSMALLINT cbPkTableName, + SQLWCHAR * szFkCatalogName, + SQLSMALLINT cbFkCatalogName, + SQLWCHAR * szFkSchemaName, + SQLSMALLINT cbFkSchemaName, + SQLWCHAR * szFkTableName, + SQLSMALLINT cbFkTableName); + +SQLRETURN SQL_API SQLNativeSqlW ( + SQLHDBC hdbc, + SQLWCHAR * szSqlStrIn, + SQLINTEGER cbSqlStrIn, + SQLWCHAR * szSqlStr, + SQLINTEGER cbSqlStrMax, + SQLINTEGER * pcbSqlStr); + +SQLRETURN SQL_API SQLPrimaryKeysW ( + SQLHSTMT hstmt, + SQLWCHAR * szCatalogName, + SQLSMALLINT cbCatalogName, + SQLWCHAR * szSchemaName, + SQLSMALLINT cbSchemaName, + SQLWCHAR * szTableName, + SQLSMALLINT cbTableName); + +SQLRETURN SQL_API SQLProcedureColumnsW ( + SQLHSTMT hstmt, + SQLWCHAR * szCatalogName, + SQLSMALLINT cbCatalogName, + SQLWCHAR * szSchemaName, + SQLSMALLINT cbSchemaName, + SQLWCHAR * szProcName, + SQLSMALLINT cbProcName, + SQLWCHAR * szColumnName, + SQLSMALLINT cbColumnName); + +SQLRETURN SQL_API SQLProceduresW ( + SQLHSTMT hstmt, + SQLWCHAR * szCatalogName, + SQLSMALLINT cbCatalogName, + SQLWCHAR * szSchemaName, + SQLSMALLINT cbSchemaName, + SQLWCHAR * szProcName, + SQLSMALLINT cbProcName); + +SQLRETURN SQL_API SQLTablePrivilegesW ( + SQLHSTMT hstmt, + SQLWCHAR * szCatalogName, + SQLSMALLINT cbCatalogName, + SQLWCHAR * szSchemaName, + SQLSMALLINT cbSchemaName, + SQLWCHAR * szTableName, + SQLSMALLINT cbTableName); + +SQLRETURN SQL_API SQLDriversW ( + SQLHENV henv, + SQLUSMALLINT fDirection, + SQLWCHAR * szDriverDesc, + SQLSMALLINT cbDriverDescMax, + SQLSMALLINT * pcbDriverDesc, + SQLWCHAR * szDriverAttributes, + SQLSMALLINT cbDrvrAttrMax, + SQLSMALLINT * pcbDrvrAttr); + + +/* + * Function prototypes - ANSI + */ + +SQLRETURN SQL_API SQLColAttributeA ( + SQLHSTMT hstmt, + SQLUSMALLINT iCol, + SQLUSMALLINT iField, + SQLPOINTER pCharAttr, + SQLSMALLINT cbCharAttrMax, + SQLSMALLINT * pcbCharAttr, + SQLLEN * pNumAttr); + +SQLRETURN SQL_API SQLColAttributesA ( + SQLHSTMT hstmt, + SQLUSMALLINT icol, + SQLUSMALLINT fDescType, + SQLPOINTER rgbDesc, + SQLSMALLINT cbDescMax, + SQLSMALLINT * pcbDesc, + SQLLEN * pfDesc); + +SQLRETURN SQL_API SQLConnectA ( + SQLHDBC hdbc, + SQLCHAR * szDSN, + SQLSMALLINT cbDSN, + SQLCHAR * szUID, + SQLSMALLINT cbUID, + SQLCHAR * szAuthStr, + SQLSMALLINT cbAuthStr); + +SQLRETURN SQL_API SQLDescribeColA ( + SQLHSTMT hstmt, + SQLUSMALLINT icol, + SQLCHAR * szColName, + SQLSMALLINT cbColNameMax, + SQLSMALLINT * pcbColName, + SQLSMALLINT * pfSqlType, + SQLULEN * pcbColDef, + SQLSMALLINT * pibScale, + SQLSMALLINT * pfNullable); + +SQLRETURN SQL_API SQLErrorA ( + SQLHENV henv, + SQLHDBC hdbc, + SQLHSTMT hstmt, + SQLCHAR * szSqlState, + SQLINTEGER * pfNativeError, + SQLCHAR * szErrorMsg, + SQLSMALLINT cbErrorMsgMax, + SQLSMALLINT * pcbErrorMsg); + +SQLRETURN SQL_API SQLExecDirectA ( + SQLHSTMT hstmt, + SQLCHAR * szSqlStr, + SQLINTEGER cbSqlStr); + +SQLRETURN SQL_API SQLGetConnectAttrA ( + SQLHDBC hdbc, + SQLINTEGER fAttribute, + SQLPOINTER rgbValue, + SQLINTEGER cbValueMax, + SQLINTEGER * pcbValue); + +SQLRETURN SQL_API SQLGetCursorNameA ( + SQLHSTMT hstmt, + SQLCHAR * szCursor, + SQLSMALLINT cbCursorMax, + SQLSMALLINT * pcbCursor); + +#if (ODBCVER >= 0x0300) +SQLRETURN SQL_API SQLSetDescFieldA ( + SQLHDESC DescriptorHandle, + SQLSMALLINT RecNumber, + SQLSMALLINT FieldIdentifier, + SQLPOINTER Value, + SQLINTEGER BufferLength); + +SQLRETURN SQL_API SQLGetDescFieldA ( + SQLHDESC hdesc, + SQLSMALLINT iRecord, + SQLSMALLINT iField, + SQLPOINTER rgbValue, + SQLINTEGER cbValueMax, + SQLINTEGER * pcbValue); + +SQLRETURN SQL_API SQLGetDescRecA ( + SQLHDESC hdesc, + SQLSMALLINT iRecord, + SQLCHAR * szName, + SQLSMALLINT cbNameMax, + SQLSMALLINT * pcbName, + SQLSMALLINT * pfType, + SQLSMALLINT * pfSubType, + SQLLEN * pLength, + SQLSMALLINT * pPrecision, + SQLSMALLINT * pScale, + SQLSMALLINT * pNullable); + +SQLRETURN SQL_API SQLGetDiagFieldA ( + SQLSMALLINT fHandleType, + SQLHANDLE handle, + SQLSMALLINT iRecord, + SQLSMALLINT fDiagField, + SQLPOINTER rgbDiagInfo, + SQLSMALLINT cbDiagInfoMax, + SQLSMALLINT * pcbDiagInfo); + +SQLRETURN SQL_API SQLGetDiagRecA ( + SQLSMALLINT fHandleType, + SQLHANDLE handle, + SQLSMALLINT iRecord, + SQLCHAR * szSqlState, + SQLINTEGER * pfNativeError, + SQLCHAR * szErrorMsg, + SQLSMALLINT cbErrorMsgMax, + SQLSMALLINT * pcbErrorMsg); +#endif + +SQLRETURN SQL_API SQLPrepareA ( + SQLHSTMT hstmt, + SQLCHAR * szSqlStr, + SQLINTEGER cbSqlStr); + +SQLRETURN SQL_API SQLSetConnectAttrA ( + SQLHDBC hdbc, + SQLINTEGER fAttribute, + SQLPOINTER rgbValue, + SQLINTEGER cbValue); + +SQLRETURN SQL_API SQLSetCursorNameA ( + SQLHSTMT hstmt, + SQLCHAR * szCursor, + SQLSMALLINT cbCursor); + +SQLRETURN SQL_API SQLColumnsA ( + SQLHSTMT hstmt, + SQLCHAR * szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR * szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR * szTableName, + SQLSMALLINT cbTableName, + SQLCHAR * szColumnName, + SQLSMALLINT cbColumnName); + +SQLRETURN SQL_API SQLGetConnectOptionA ( + SQLHDBC hdbc, + SQLUSMALLINT fOption, + SQLPOINTER pvParam); + +SQLRETURN SQL_API SQLGetInfoA ( + SQLHDBC hdbc, + SQLUSMALLINT fInfoType, + SQLPOINTER rgbInfoValue, + SQLSMALLINT cbInfoValueMax, + SQLSMALLINT * pcbInfoValue); + +SQLRETURN SQL_API SQLGetTypeInfoA ( + SQLHSTMT StatementHandle, + SQLSMALLINT DataType); + +SQLRETURN SQL_API SQLSetConnectOptionA ( + SQLHDBC hdbc, + SQLUSMALLINT fOption, + SQLULEN vParam); + +SQLRETURN SQL_API SQLSpecialColumnsA ( + SQLHSTMT hstmt, + SQLUSMALLINT fColType, + SQLCHAR * szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR * szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR * szTableName, + SQLSMALLINT cbTableName, + SQLUSMALLINT fScope, + SQLUSMALLINT fNullable); + +SQLRETURN SQL_API SQLStatisticsA ( + SQLHSTMT hstmt, + SQLCHAR * szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR * szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR * szTableName, + SQLSMALLINT cbTableName, + SQLUSMALLINT fUnique, + SQLUSMALLINT fAccuracy); + +SQLRETURN SQL_API SQLTablesA ( + SQLHSTMT hstmt, + SQLCHAR * szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR * szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR * szTableName, + SQLSMALLINT cbTableName, + SQLCHAR * szTableType, + SQLSMALLINT cbTableType); + +SQLRETURN SQL_API SQLDataSourcesA ( + SQLHENV henv, + SQLUSMALLINT fDirection, + SQLCHAR * szDSN, + SQLSMALLINT cbDSNMax, + SQLSMALLINT * pcbDSN, + SQLCHAR * szDescription, + SQLSMALLINT cbDescriptionMax, + SQLSMALLINT * pcbDescription); + +SQLRETURN SQL_API SQLDriverConnectA ( + SQLHDBC hdbc, + SQLHWND hwnd, + SQLCHAR * szConnStrIn, + SQLSMALLINT cbConnStrIn, + SQLCHAR * szConnStrOut, + SQLSMALLINT cbConnStrOutMax, + SQLSMALLINT * pcbConnStrOut, + SQLUSMALLINT fDriverCompletion); + +SQLRETURN SQL_API SQLBrowseConnectA ( + SQLHDBC hdbc, + SQLCHAR * szConnStrIn, + SQLSMALLINT cbConnStrIn, + SQLCHAR * szConnStrOut, + SQLSMALLINT cbConnStrOutMax, + SQLSMALLINT * pcbConnStrOut); + +SQLRETURN SQL_API SQLColumnPrivilegesA ( + SQLHSTMT hstmt, + SQLCHAR * szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR * szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR * szTableName, + SQLSMALLINT cbTableName, + SQLCHAR * szColumnName, + SQLSMALLINT cbColumnName); + +SQLRETURN SQL_API SQLGetStmtAttrA ( + SQLHSTMT hstmt, + SQLINTEGER fAttribute, + SQLPOINTER rgbValue, + SQLINTEGER cbValueMax, + SQLINTEGER * pcbValue); + +SQLRETURN SQL_API SQLSetStmtAttrA ( + SQLHSTMT hstmt, + SQLINTEGER fAttribute, + SQLPOINTER rgbValue, + SQLINTEGER cbValueMax); + +SQLRETURN SQL_API SQLForeignKeysA ( + SQLHSTMT hstmt, + SQLCHAR * szPkCatalogName, + SQLSMALLINT cbPkCatalogName, + SQLCHAR * szPkSchemaName, + SQLSMALLINT cbPkSchemaName, + SQLCHAR * szPkTableName, + SQLSMALLINT cbPkTableName, + SQLCHAR * szFkCatalogName, + SQLSMALLINT cbFkCatalogName, + SQLCHAR * szFkSchemaName, + SQLSMALLINT cbFkSchemaName, + SQLCHAR * szFkTableName, + SQLSMALLINT cbFkTableName); + +SQLRETURN SQL_API SQLNativeSqlA ( + SQLHDBC hdbc, + SQLCHAR * szSqlStrIn, + SQLINTEGER cbSqlStrIn, + SQLCHAR * szSqlStr, + SQLINTEGER cbSqlStrMax, + SQLINTEGER * pcbSqlStr); + +SQLRETURN SQL_API SQLPrimaryKeysA ( + SQLHSTMT hstmt, + SQLCHAR * szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR * szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR * szTableName, + SQLSMALLINT cbTableName); + +SQLRETURN SQL_API SQLProcedureColumnsA ( + SQLHSTMT hstmt, + SQLCHAR * szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR * szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR * szProcName, + SQLSMALLINT cbProcName, + SQLCHAR * szColumnName, + SQLSMALLINT cbColumnName); + +SQLRETURN SQL_API SQLProceduresA ( + SQLHSTMT hstmt, + SQLCHAR * szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR * szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR * szProcName, + SQLSMALLINT cbProcName); + +SQLRETURN SQL_API SQLTablePrivilegesA ( + SQLHSTMT hstmt, + SQLCHAR * szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR * szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR * szTableName, + SQLSMALLINT cbTableName); + +SQLRETURN SQL_API SQLDriversA ( + SQLHENV henv, + SQLUSMALLINT fDirection, + SQLCHAR * szDriverDesc, + SQLSMALLINT cbDriverDescMax, + SQLSMALLINT * pcbDriverDesc, + SQLCHAR * szDriverAttributes, + SQLSMALLINT cbDrvrAttrMax, + SQLSMALLINT * pcbDrvrAttr); + + +/* + * Mapping macros for Unicode + */ +#ifndef SQL_NOUNICODEMAP /* define this to disable the mapping */ +#ifdef UNICODE + +#define SQLColAttribute SQLColAttributeW +#define SQLColAttributes SQLColAttributesW +#define SQLConnect SQLConnectW +#define SQLDescribeCol SQLDescribeColW +#define SQLError SQLErrorW +#define SQLExecDirect SQLExecDirectW +#define SQLGetConnectAttr SQLGetConnectAttrW +#define SQLGetCursorName SQLGetCursorNameW +#define SQLGetDescField SQLGetDescFieldW +#define SQLGetDescRec SQLGetDescRecW +#define SQLGetDiagField SQLGetDiagFieldW +#define SQLGetDiagRec SQLGetDiagRecW +#define SQLPrepare SQLPrepareW +#define SQLSetConnectAttr SQLSetConnectAttrW +#define SQLSetCursorName SQLSetCursorNameW +#define SQLSetDescField SQLSetDescFieldW +#define SQLSetStmtAttr SQLSetStmtAttrW +#define SQLGetStmtAttr SQLGetStmtAttrW +#define SQLColumns SQLColumnsW +#define SQLGetConnectOption SQLGetConnectOptionW +#define SQLGetInfo SQLGetInfoW +#define SQLGetTypeInfo SQLGetTypeInfoW +#define SQLSetConnectOption SQLSetConnectOptionW +#define SQLSpecialColumns SQLSpecialColumnsW +#define SQLStatistics SQLStatisticsW +#define SQLTables SQLTablesW +#define SQLDataSources SQLDataSourcesW +#define SQLDriverConnect SQLDriverConnectW +#define SQLBrowseConnect SQLBrowseConnectW +#define SQLColumnPrivileges SQLColumnPrivilegesW +#define SQLForeignKeys SQLForeignKeysW +#define SQLNativeSql SQLNativeSqlW +#define SQLPrimaryKeys SQLPrimaryKeysW +#define SQLProcedureColumns SQLProcedureColumnsW +#define SQLProcedures SQLProceduresW +#define SQLTablePrivileges SQLTablePrivilegesW +#define SQLDrivers SQLDriversW + +#endif /* UNICODE */ +#endif /* SQL_NOUNICODEMAP */ + +#ifdef __cplusplus +} +#endif + +#endif /* _SQLUCODE_H */ diff --git a/libodbc/include/ora7API.h b/libodbc/include/ora7API.h new file mode 100644 index 0000000000..031e7c9bfe --- /dev/null +++ b/libodbc/include/ora7API.h @@ -0,0 +1,201 @@ +// ora7API.h +// +////////////////////////////////////////////////////////////////////// + +#if !defined(__ORA7API_H__) +#define __ORA7API_H__ + +#include "SQLAPI.h" + +// API header(s) +#include +#include + +extern long g_nORA7DLLVersionLoaded; + +extern void AddORA7Support(); +extern void ReleaseORA7Support(); + +/* + * Oci BIND (Piecewise or with Skips) + */ +typedef sword (*obindps_t)(struct cda_def *cursor, ub1 opcode, text *sqlvar, + sb4 sqlvl, ub1 *pvctx, sb4 progvl, + sword ftype, sword scale, + sb2 *indp, ub2 *alen, ub2 *arcode, + sb4 pv_skip, sb4 ind_skip, sb4 alen_skip, sb4 rc_skip, + ub4 maxsiz, ub4 *cursiz, + text *fmt, sb4 fmtl, sword fmtt); +typedef sword (*obreak_t)(struct cda_def *lda); +typedef sword (*ocan_t)(struct cda_def *cursor); +typedef sword (*oclose_t)(struct cda_def *cursor); +typedef sword (*ocof_t)(struct cda_def *lda); +typedef sword (*ocom_t)(struct cda_def *lda); +typedef sword (*ocon_t)(struct cda_def *lda); + + +/* + * Oci DEFINe (Piecewise or with Skips) + */ +typedef sword (*odefinps_t)(struct cda_def *cursor, ub1 opcode, sword pos,ub1 *bufctx, + sb4 bufl, sword ftype, sword scale, + sb2 *indp, text *fmt, sb4 fmtl, sword fmtt, + ub2 *rlen, ub2 *rcode, + sb4 pv_skip, sb4 ind_skip, sb4 alen_skip, sb4 rc_skip); +typedef sword (*odessp_t)(struct cda_def *cursor, text *objnam, size_t onlen, + ub1 *rsv1, size_t rsv1ln, ub1 *rsv2, size_t rsv2ln, + ub2 *ovrld, ub2 *pos, ub2 *level, text **argnam, + ub2 *arnlen, ub2 *dtype, ub1 *defsup, ub1* mode, + ub4 *dtsiz, sb2 *prec, sb2 *scale, ub1 *radix, + ub4 *spare, ub4 *arrsiz); +typedef sword (*odescr_t)(struct cda_def *cursor, sword pos, sb4 *dbsize, + sb2 *dbtype, sb1 *cbuf, sb4 *cbufl, sb4 *dsize, + sb2 *prec, sb2 *scale, sb2 *nullok); +typedef sword (*oerhms_t)(struct cda_def *lda, sb2 rcode, text *buf, + sword bufsiz); +typedef sword (*oermsg_t)(sb2 rcode, text *buf); +typedef sword (*oexec_t)(struct cda_def *cursor); +typedef sword (*oexfet_t)(struct cda_def *cursor, ub4 nrows, + sword cancel, sword exact); +typedef sword (*oexn_t)(struct cda_def *cursor, sword iters, sword rowoff); +typedef sword (*ofen_t)(struct cda_def *cursor, sword nrows); +typedef sword (*ofetch_t)(struct cda_def *cursor); +typedef sword (*oflng_t)(struct cda_def *cursor, sword pos, ub1 *buf, + sb4 bufl, sword dtype, ub4 *retl, sb4 offset); +typedef sword (*ogetpi_t) (struct cda_def *cursor, ub1 *piecep, dvoid **ctxpp, + ub4 *iterp, ub4 *indexp); +typedef sword (*oopt_t) (struct cda_def *cursor, sword rbopt, sword waitopt); +typedef sword (*opinit_t) (ub4 mode); +typedef sword (*olog_t) (struct cda_def *lda, ub1* hda, + text *uid, sword uidl, + text *pswd, sword pswdl, + text *conn, sword connl, + ub4 mode); +typedef sword (*ologof_t) (struct cda_def *lda); +typedef sword (*oopen_t) (struct cda_def *cursor, struct cda_def *lda, + text *dbn, sword dbnl, sword arsize, + text *uid, sword uidl); +typedef sword (*oparse_t) (struct cda_def *cursor, text *sqlstm, sb4 sqllen, + sword defflg, ub4 lngflg); +typedef sword (*orol_t) (struct cda_def *lda); +typedef sword (*osetpi_t) (struct cda_def *cursor, ub1 piece, dvoid *bufp, ub4 *lenp); + +typedef void (*sqlld2_t) (struct cda_def *lda, text *cname, sb4 *cnlen); +typedef void (*sqllda_t) (struct cda_def *lda); + +/* non-blocking functions */ +typedef sword (*onbset_t) (struct cda_def *lda ); +typedef sword (*onbtst_t) (struct cda_def *lda ); +typedef sword (*onbclr_t) (struct cda_def *lda ); +typedef sword (*ognfd_t) (struct cda_def *lda, dvoid *fdp); + +/* + * OBSOLETE CALLS + */ + +/* + * OBSOLETE BIND CALLS + */ +typedef sword (*obndra_t)(struct cda_def *cursor, text *sqlvar, sword sqlvl, + ub1 *progv, sword progvl, sword ftype, sword scale, + sb2 *indp, ub2 *alen, ub2 *arcode, ub4 maxsiz, + ub4 *cursiz, text *fmt, sword fmtl, sword fmtt); +typedef sword (*obndrn_t)(struct cda_def *cursor, sword sqlvn, ub1 *progv, + sword progvl, sword ftype, sword scale, sb2 *indp, + text *fmt, sword fmtl, sword fmtt); +typedef sword (*obndrv_t)(struct cda_def *cursor, text *sqlvar, sword sqlvl, + ub1 *progv, sword progvl, sword ftype, sword scale, + sb2 *indp, text *fmt, sword fmtl, sword fmtt); + +/* + * OBSOLETE DEFINE CALLS + */ +typedef sword (*odefin_t)(struct cda_def *cursor, sword pos, ub1 *buf, + sword bufl, sword ftype, sword scale, sb2 *indp, + text *fmt, sword fmtl, sword fmtt, ub2 *rlen, ub2 *rcode); + +/* older calls ; preferred equivalent calls above */ + +typedef sword (*oname_t) (struct cda_def *cursor, sword pos, sb1 *tbuf, + sb2 *tbufl, sb1 *buf, sb2 *bufl); +typedef sword (*orlon_t) (struct cda_def *lda, ub1 *hda, + text *uid, sword uidl, + text *pswd, sword pswdl, + sword audit); +typedef sword (*olon_t) (struct cda_def *lda, text *uid, sword uidl, + text *pswd, sword pswdl, sword audit); +typedef sword (*osql3_t) (struct cda_def *cda, text *sqlstm, sword sqllen); +typedef sword (*odsc_t) (struct cda_def *cursor, sword pos, sb2 *dbsize, + sb2 *fsize, sb2 *rcode, sb2 *dtype, sb1 *buf, + sb2 *bufl, sb2 *dsize); + +// API declarations +class SQLAPI_API ora7API : public saAPI +{ +public: + ora7API(); + + obindps_t obindps; + obreak_t obreak; + ocan_t ocan; + oclose_t oclose; + ocof_t ocof; + ocom_t ocom; + ocon_t ocon; + odefinps_t odefinps; + odessp_t odessp; + odescr_t odescr; + oerhms_t oerhms; + oermsg_t oermsg; + oexec_t oexec; + oexfet_t oexfet; + oexn_t oexn; + ofen_t ofen; + ofetch_t ofetch; + oflng_t oflng; + ogetpi_t ogetpi; + oopt_t oopt; + opinit_t opinit; + olog_t olog; + ologof_t ologof; + oopen_t oopen; + oparse_t oparse; + orol_t orol; + osetpi_t osetpi; + sqlld2_t sqlld2; + sqllda_t sqllda; + onbset_t onbset; + onbtst_t onbtst; + onbclr_t onbclr; + ognfd_t ognfd; + obndra_t obndra; + obndrn_t obndrn; + obndrv_t obndrv; + odefin_t odefin; + oname_t oname; + orlon_t orlon; + olon_t olon; + osql3_t osql3; + odsc_t odsc; +}; + +class SQLAPI_API ora7ConnectionHandles : public saConnectionHandles +{ +public: + ora7ConnectionHandles(); + + Lda_Def m_lda; + ub1 m_hda[512]; +}; + +class SQLAPI_API ora7CommandHandles : public saCommandHandles +{ +public: + ora7CommandHandles(); + + Cda_Def m_cda; +}; + +extern ora7API g_ora7API; + +#endif // !defined(__ORA7API_H__) diff --git a/libodbc/include/oraAPI.h b/libodbc/include/oraAPI.h new file mode 100644 index 0000000000..620d3cbb62 --- /dev/null +++ b/libodbc/include/oraAPI.h @@ -0,0 +1,508 @@ +// ora8API.h +// +////////////////////////////////////////////////////////////////////// + +#if !defined(__ORA8API_H__) +#define __ORA8API_H__ + +#include "SQLAPI.h" + +// API header(s) +#include + +extern long g_nORA8DLLVersionLoaded; + +extern void AddORA8Support(const SAConnection * pCon); +extern void ReleaseORA8Support(); + +// 8.0.x calls +typedef sword (*OCIInitialize_t)(ub4 mode, dvoid *ctxp, + dvoid *(*malocfp)(dvoid *ctxp, size_t size), + dvoid *(*ralocfp)(dvoid *ctxp, dvoid *memptr, size_t newsize), + void (*mfreefp)(dvoid *ctxp, dvoid *memptr) ); + +typedef sword (*OCIHandleAlloc_t)(CONST dvoid *parenth, dvoid **hndlpp, CONST ub4 type, + CONST size_t xtramem_sz, dvoid **usrmempp); + +typedef sword (*OCIHandleFree_t)(dvoid *hndlp, CONST ub4 type); + + +typedef sword (*OCIDescriptorAlloc_t)(CONST dvoid *parenth, dvoid **descpp, CONST ub4 type, + CONST size_t xtramem_sz, dvoid **usrmempp); + +typedef sword (*OCIDescriptorFree_t)(dvoid *descp, CONST ub4 type); + +typedef sword (*OCIEnvInit_t)(OCIEnv **envp, ub4 mode, + size_t xtramem_sz, dvoid **usrmempp); + +typedef sword (*OCIServerAttach_t)(OCIServer *srvhp, OCIError *errhp, + CONST text *dblink, sb4 dblink_len, ub4 mode); + +typedef sword (*OCIServerDetach_t)(OCIServer *srvhp, OCIError *errhp, ub4 mode); + +typedef sword (*OCISessionBegin_t)(OCISvcCtx *svchp, OCIError *errhp, OCISession *usrhp, + ub4 credt, ub4 mode); + +typedef sword (*OCISessionEnd_t)(OCISvcCtx *svchp, OCIError *errhp, OCISession *usrhp, + ub4 mode); + +typedef sword (*OCILogon_t)(OCIEnv *envhp, OCIError *errhp, OCISvcCtx **svchp, + CONST text *username, ub4 uname_len, + CONST text *password, ub4 passwd_len, + CONST text *dbname, ub4 dbname_len); + +typedef sword (*OCILogoff_t)(OCISvcCtx *svchp, OCIError *errhp); + + +typedef sword (*OCIPasswordChange_t)(OCISvcCtx *svchp, OCIError *errhp, + CONST text *user_name, ub4 usernm_len, + CONST text *opasswd, ub4 opasswd_len, + CONST text *npasswd, ub4 npasswd_len, ub4 mode); + +typedef sword (*OCIStmtPrepare_t)(OCIStmt *stmtp, OCIError *errhp, CONST text *stmt, + ub4 stmt_len, ub4 language, ub4 mode); + +typedef sword (*OCIBindByPos_t)(OCIStmt *stmtp, OCIBind **bindp, OCIError *errhp, + ub4 position, dvoid *valuep, sb4 value_sz, + ub2 dty, dvoid *indp, ub2 *alenp, ub2 *rcodep, + ub4 maxarr_len, ub4 *curelep, ub4 mode); + +typedef sword (*OCIBindByName_t)(OCIStmt *stmtp, OCIBind **bindp, OCIError *errhp, + CONST text *placeholder, sb4 placeh_len, + dvoid *valuep, sb4 value_sz, ub2 dty, + dvoid *indp, ub2 *alenp, ub2 *rcodep, + ub4 maxarr_len, ub4 *curelep, ub4 mode); + +typedef sword (*OCIBindObject_t)(OCIBind *bindp, OCIError *errhp, CONST OCIType *type, + dvoid **pgvpp, ub4 *pvszsp, dvoid **indpp, + ub4 *indszp); + +typedef sword (*OCIBindDynamic_t)(OCIBind *bindp, OCIError *errhp, dvoid *ictxp, + OCICallbackInBind icbfp, dvoid *octxp, + OCICallbackOutBind ocbfp); + +typedef sword (*OCIBindArrayOfStruct_t)(OCIBind *bindp, OCIError *errhp, + ub4 pvskip, ub4 indskip, + ub4 alskip, ub4 rcskip); + +typedef sword (*OCIStmtGetPieceInfo_t)(OCIStmt *stmtp, OCIError *errhp, + dvoid **hndlpp, ub4 *typep, + ub1 *in_outp, ub4 *iterp, ub4 *idxp, + ub1 *piecep); + +typedef sword (*OCIStmtSetPieceInfo_t)(dvoid *hndlp, ub4 type, OCIError *errhp, + CONST dvoid *bufp, ub4 *alenp, ub1 piece, + CONST dvoid *indp, ub2 *rcodep); + +typedef sword (*OCIStmtExecute_t)(OCISvcCtx *svchp, OCIStmt *stmtp, OCIError *errhp, + ub4 iters, ub4 rowoff, CONST OCISnapshot *snap_in, + OCISnapshot *snap_out, ub4 mode); + +typedef sword (*OCIDefineByPos_t)(OCIStmt *stmtp, OCIDefine **defnp, OCIError *errhp, + ub4 position, dvoid *valuep, sb4 value_sz, ub2 dty, + dvoid *indp, ub2 *rlenp, ub2 *rcodep, ub4 mode); + +typedef sword (*OCIDefineObject_t)(OCIDefine *defnp, OCIError *errhp, + CONST OCIType *type, dvoid **pgvpp, + ub4 *pvszsp, dvoid **indpp, ub4 *indszp); + +typedef sword (*OCIDefineDynamic_t)(OCIDefine *defnp, OCIError *errhp, dvoid *octxp, + OCICallbackDefine ocbfp); + +typedef sword (*OCIDefineArrayOfStruct_t)(OCIDefine *defnp, OCIError *errhp, ub4 pvskip, + ub4 indskip, ub4 rlskip, ub4 rcskip); + +typedef sword (*OCIStmtFetch_t)(OCIStmt *stmtp, OCIError *errhp, ub4 nrows, + ub2 orientation, ub4 mode); + +typedef sword (*OCIStmtGetBindInfo_t)(OCIStmt *stmtp, OCIError *errhp, ub4 size, + ub4 startloc, + sb4 *found, text *bvnp[], ub1 bvnl[], + text *invp[], ub1 inpl[], ub1 dupl[], + OCIBind *hndl[]); + +typedef sword (*OCIDescribeAny_t)(OCISvcCtx *svchp, OCIError *errhp, + dvoid *objptr, + ub4 objnm_len, ub1 objptr_typ, ub1 info_level, + ub1 objtyp, OCIDescribe *dschp); + +typedef sword (*OCIParamGet_t)(CONST dvoid *hndlp, ub4 htype, OCIError *errhp, + dvoid **parmdpp, ub4 pos); + +typedef sword (*OCIParamSet_t)(dvoid *hdlp, ub4 htyp, OCIError *errhp, CONST dvoid *dscp, + ub4 dtyp, ub4 pos); + +typedef sword (*OCITransStart_t)(OCISvcCtx *svchp, OCIError *errhp, + uword timeout, ub4 flags ); + +typedef sword (*OCITransDetach_t)(OCISvcCtx *svchp, OCIError *errhp, ub4 flags ); + +typedef sword (*OCITransCommit_t)(OCISvcCtx *svchp, OCIError *errhp, ub4 flags); + +typedef sword (*OCITransRollback_t)(OCISvcCtx *svchp, OCIError *errhp, ub4 flags); + +typedef sword (*OCITransPrepare_t)(OCISvcCtx *svchp, OCIError *errhp, ub4 flags); + +typedef sword (*OCITransForget_t)(OCISvcCtx *svchp, OCIError *errhp, ub4 flags); + +typedef sword (*OCIErrorGet_t)(dvoid *hndlp, ub4 recordno, text *sqlstate, + sb4 *errcodep, text *bufp, ub4 bufsiz, ub4 type); + +typedef sword (*OCILobAppend_t)(OCISvcCtx *svchp, OCIError *errhp, + OCILobLocator *dst_locp, + OCILobLocator *src_locp); + +typedef sword (*OCILobAssign_t)(OCIEnv *envhp, OCIError *errhp, + CONST OCILobLocator *src_locp, + OCILobLocator **dst_locpp); + +typedef sword (*OCILobCharSetForm_t)(OCIEnv *envhp, OCIError *errhp, + CONST OCILobLocator *locp, ub1 *csfrm); + +typedef sword (*OCILobCharSetId_t)(OCIEnv *envhp, OCIError *errhp, + CONST OCILobLocator *locp, ub2 *csid); + +typedef sword (*OCILobCopy_t)(OCISvcCtx *svchp, OCIError *errhp, OCILobLocator *dst_locp, + OCILobLocator *src_locp, ub4 amount, ub4 dst_offset, + ub4 src_offset); + +typedef sword (*OCILobDisableBuffering_t)(OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp); + +typedef sword (*OCILobEnableBuffering_t)(OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp); + +typedef sword (*OCILobErase_t)(OCISvcCtx *svchp, OCIError *errhp, OCILobLocator *locp, + ub4 *amount, ub4 offset); + +typedef sword (*OCILobFileClose_t)(OCISvcCtx *svchp, OCIError *errhp, + OCILobLocator *filep); + +typedef sword (*OCILobFileCloseAll_t)(OCISvcCtx *svchp, OCIError *errhp); + +typedef sword (*OCILobFileExists_t)(OCISvcCtx *svchp, OCIError *errhp, + OCILobLocator *filep, + boolean *flag); + +typedef sword (*OCILobFileGetName_t)(OCIEnv *envhp, OCIError *errhp, + CONST OCILobLocator *filep, + text *dir_alias, ub2 *d_length, + text *filename, ub2 *f_length); + +typedef sword (*OCILobFileIsOpen_t)(OCISvcCtx *svchp, OCIError *errhp, + OCILobLocator *filep, + boolean *flag); + +typedef sword (*OCILobFileOpen_t)(OCISvcCtx *svchp, OCIError *errhp, + OCILobLocator *filep, + ub1 mode); + +typedef sword (*OCILobFileSetName_t)(OCIEnv *envhp, OCIError *errhp, + OCILobLocator **filepp, + CONST text *dir_alias, ub2 d_length, + CONST text *filename, ub2 f_length); + +typedef sword (*OCILobFlushBuffer_t)(OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp, + ub4 flag); + +typedef sword (*OCILobGetLength_t)(OCISvcCtx *svchp, OCIError *errhp, + OCILobLocator *locp, + ub4 *lenp); + +typedef sword (*OCILobIsEqual_t)(OCIEnv *envhp, CONST OCILobLocator *x, + CONST OCILobLocator *y, + boolean *is_equal); + +typedef sword (*OCILobLoadFromFile_t)(OCISvcCtx *svchp, OCIError *errhp, + OCILobLocator *dst_locp, + OCILobLocator *src_filep, + ub4 amount, ub4 dst_offset, + ub4 src_offset); + +typedef sword (*OCILobLocatorIsInit_t)(OCIEnv *envhp, OCIError *errhp, + CONST OCILobLocator *locp, + boolean *is_initialized); + +typedef sword (*OCILobRead_t)(OCISvcCtx *svchp, OCIError *errhp, OCILobLocator *locp, + ub4 *amtp, ub4 offset, dvoid *bufp, ub4 bufl, + dvoid *ctxp, sb4 (*cbfp)(dvoid *ctxp, + CONST dvoid *bufp, + ub4 len, + ub1 piece), + ub2 csid, ub1 csfrm); + +typedef sword (*OCILobRead2_t)(OCISvcCtx *svchp, OCIError *errhp, OCILobLocator *locp, + oraub8 *byte_amtp, oraub8 *char_amtp, oraub8 offset, dvoid *bufp, oraub8 bufl, + ub1 piece, dvoid *ctxp, sb4 (*cbfp)(dvoid *ctxp, + CONST dvoid *bufp, + oraub8 len, ub1 piecep, + dvoid **changed_bufpp,oraub8 *changed_lenp), + ub2 csid, ub1 csfrm); + +typedef sword (*OCILobTrim_t)(OCISvcCtx *svchp, OCIError *errhp, OCILobLocator *locp, + ub4 newlen); + +typedef sword (*OCILobWrite_t)(OCISvcCtx *svchp, OCIError *errhp, OCILobLocator *locp, + ub4 *amtp, ub4 offset, dvoid *bufp, ub4 buflen, + ub1 piece, dvoid *ctxp, + sb4 (*cbfp)(dvoid *ctxp, + dvoid *bufp, + ub4 *len, + ub1 *piece), + ub2 csid, ub1 csfrm); + +typedef sword (*OCILobWrite2_t)(OCISvcCtx *svchp, OCIError *errhp, OCILobLocator *locp, + oraub8 *byte_amtp, oraub8 *char_amtp, oraub8 offset, + void *bufp, oraub8 buflen, ub1 piece, void *ctxp, + OCICallbackLobWrite2 cbfp, ub2 csid, ub1 csfrm); + +typedef sword (*OCIBreak_t)(dvoid *hndlp, OCIError *errhp); + +typedef sword (*OCIReset_t)(dvoid *hndlp, OCIError *errhp); + +typedef sword (*OCIServerVersion_t)(dvoid *hndlp, OCIError *errhp, text *bufp, + ub4 bufsz, + ub1 hndltype); + + +typedef sword (*OCIAttrGet_t)(CONST dvoid *trgthndlp, ub4 trghndltyp, + dvoid *attributep, ub4 *sizep, ub4 attrtype, + OCIError *errhp); + +typedef sword (*OCIAttrSet_t)(dvoid *trgthndlp, ub4 trghndltyp, dvoid *attributep, + ub4 size, ub4 attrtype, OCIError *errhp); + +typedef sword (*OCISvcCtxToLda_t)(OCISvcCtx *svchp, OCIError *errhp, Lda_Def *ldap); + +typedef sword (*OCILdaToSvcCtx_t)(OCISvcCtx **svchpp, OCIError *errhp, Lda_Def *ldap); + +typedef sword (*OCIResultSetToStmt_t)(OCIResult *rsetdp, OCIError *errhp); + + +// 8.1.x (8i) calls +typedef sword (*OCIEnvCreate_t)(OCIEnv **envp, ub4 mode, dvoid *ctxp, + dvoid *(*malocfp)(dvoid *ctxp, size_t size), + dvoid *(*ralocfp)(dvoid *ctxp, dvoid *memptr, size_t newsize), + void (*mfreefp)(dvoid *ctxp, dvoid *memptr), + size_t xtramem_sz, dvoid **usrmempp); + +typedef sword (*OCIEnvNlsCreate_t)(OCIEnv **envhpp, ub4 mode, dvoid *ctxp, + dvoid *(*malocfp)(dvoid *ctxp, size_t size), + dvoid *(*ralocfp)(dvoid *ctxp, dvoid *memptr, size_t newsize), + void (*mfreefp)(dvoid *ctxp, dvoid *memptr), + size_t xtramemsz, dvoid **usrmempp, + ub2 charset, ub2 ncharset); + +typedef sword (*OCIDurationBegin_t)( OCIEnv *env, OCIError *err, CONST OCISvcCtx *svc, + OCIDuration parent, OCIDuration *dur ); + +typedef sword (*OCIDurationEnd_t)( OCIEnv *env, OCIError *err, CONST OCISvcCtx *svc, + OCIDuration duration ); + +typedef sword (*OCILobCreateTemporary_t)(OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp, + ub2 csid, + ub1 csfrm, + ub1 lobtype, + boolean cache, + OCIDuration duration); + +typedef sword (*OCILobFreeTemporary_t)(OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp); + +typedef sword (*OCILobIsTemporary_t)(OCIEnv *envp, + OCIError *errhp, + OCILobLocator *locp, + boolean *is_temporary); + +typedef sword (*OCIAQEnq_t)(OCISvcCtx *svchp, OCIError *errhp, OraText *queue_name, + OCIAQEnqOptions *enqopt, OCIAQMsgProperties *msgprop, + OCIType *payload_tdo, dvoid **payload, dvoid **payload_ind, + OCIRaw **msgid, ub4 flags); + +typedef sword (*OCIAQDeq_t)(OCISvcCtx *svchp, OCIError *errhp, OraText *queue_name, + OCIAQDeqOptions *deqopt, OCIAQMsgProperties *msgprop, + OCIType *payload_tdo, dvoid **payload, dvoid **payload_ind, + OCIRaw **msgid, ub4 flags); + +typedef sword (*OCIAQListen_t)(OCISvcCtx *svchp, OCIError *errhp, + OCIAQAgent **agent_list, ub4 num_agents, + sb4 wait, OCIAQAgent **agent, + ub4 flags); + +typedef sword (*OCIStmtFetch2_t)(OCIStmt *stmtp, OCIError *errhp, ub4 nrows, + ub2 orientation, sb4 scrollOffset, ub4 mode ); + +//--------------- Begin OCI Client Notification Interfaces ------------------ + +typedef sword (*OCISubscriptionRegister_t)(OCISvcCtx *svchp, OCISubscription **subscrhpp, + ub2 count, OCIError *errhp, ub4 mode); + +typedef sword (*OCISubscriptionPost_t)(OCISvcCtx *svchp, OCISubscription **subscrhpp, + ub2 count, OCIError *errhp, ub4 mode); + +typedef sword (*OCISubscriptionUnRegister_t)(OCISvcCtx *svchp, OCISubscription *subscrhp, + OCIError *errhp, ub4 mode); + +typedef sword (*OCISubscriptionDisable_t)(OCISubscription *subscrhp, + OCIError *errhp, ub4 mode); + +typedef sword (*OCISubscriptionEnable_t)(OCISubscription *subscrhp, + OCIError *errhp, ub4 mode); + +//------------------- End OCI Publish/Subscribe Interfaces ------------------ + + +typedef sword (*OCIDateTimeConstruct_t)( dvoid *hndl, + OCIError *err, OCIDateTime *datetime, + sb2 year, ub1 month, ub1 day, + ub1 hour, ub1 min, ub1 sec, ub4 fsec, + OraText *timezone, size_t timezone_length); + +typedef sword (*OCIDateTimeGetDate_t)(dvoid *hndl, + OCIError *err, CONST OCIDateTime *datetime, + sb2 *year, ub1 *month, ub1 *day); + +typedef sword (*OCIDateTimeGetTime_t)(dvoid *hndl, + OCIError *err, OCIDateTime *datetime, + ub1 *hour, ub1 *min, ub1 *sec, ub4 *fsec); + + +typedef sword (*OCINlsNumericInfoGet_t)(dvoid *envhp, OCIError *errhp, sb4 *val, ub2 item); + +// API declarations +class SQLAPI_API ora8API : public saAPI +{ +public: + ora8API(); + + // 8.0.x calls + OCIInitialize_t OCIInitialize; + OCIHandleAlloc_t OCIHandleAlloc; + OCIHandleFree_t OCIHandleFree; + OCIDescriptorAlloc_t OCIDescriptorAlloc; + OCIDescriptorFree_t OCIDescriptorFree; + OCIEnvInit_t OCIEnvInit; + OCIServerAttach_t OCIServerAttach; + OCIServerDetach_t OCIServerDetach; + OCISessionBegin_t OCISessionBegin; + OCISessionEnd_t OCISessionEnd; + OCILogon_t OCILogon; + OCILogoff_t OCILogoff; + OCIPasswordChange_t OCIPasswordChange; + OCIStmtPrepare_t OCIStmtPrepare; + OCIBindByPos_t OCIBindByPos; + OCIBindByName_t OCIBindByName; + OCIBindObject_t OCIBindObject; + OCIBindDynamic_t OCIBindDynamic; + OCIBindArrayOfStruct_t OCIBindArrayOfStruct; + OCIStmtGetPieceInfo_t OCIStmtGetPieceInfo; + OCIStmtSetPieceInfo_t OCIStmtSetPieceInfo; + OCIStmtExecute_t OCIStmtExecute; + OCIDefineByPos_t OCIDefineByPos; + OCIDefineObject_t OCIDefineObject; + OCIDefineDynamic_t OCIDefineDynamic; + OCIDefineArrayOfStruct_t OCIDefineArrayOfStruct; + OCIStmtFetch_t OCIStmtFetch; + OCIStmtGetBindInfo_t OCIStmtGetBindInfo; + OCIDescribeAny_t OCIDescribeAny; + OCIParamGet_t OCIParamGet; + OCIParamSet_t OCIParamSet; + OCITransStart_t OCITransStart; + OCITransDetach_t OCITransDetach; + OCITransCommit_t OCITransCommit; + OCITransRollback_t OCITransRollback; + OCITransPrepare_t OCITransPrepare; + OCITransForget_t OCITransForget; + OCIErrorGet_t OCIErrorGet; + OCILobAppend_t OCILobAppend; + OCILobAssign_t OCILobAssign; + OCILobCharSetForm_t OCILobCharSetForm; + OCILobCharSetId_t OCILobCharSetId; + OCILobCopy_t OCILobCopy; + OCILobDisableBuffering_t OCILobDisableBuffering; + OCILobEnableBuffering_t OCILobEnableBuffering; + OCILobErase_t OCILobErase; + OCILobFileClose_t OCILobFileClose; + OCILobFileCloseAll_t OCILobFileCloseAll; + OCILobFileExists_t OCILobFileExists; + OCILobFileGetName_t OCILobFileGetName; + OCILobFileIsOpen_t OCILobFileIsOpen; + OCILobFileOpen_t OCILobFileOpen; + OCILobFileSetName_t OCILobFileSetName; + OCILobFlushBuffer_t OCILobFlushBuffer; + OCILobGetLength_t OCILobGetLength; + OCILobIsEqual_t OCILobIsEqual; + OCILobLoadFromFile_t OCILobLoadFromFile; + OCILobLocatorIsInit_t OCILobLocatorIsInit; + OCILobRead_t OCILobRead; + OCILobRead2_t OCILobRead2; + OCILobTrim_t OCILobTrim; + OCILobWrite_t OCILobWrite; + OCILobWrite2_t OCILobWrite2; + OCIBreak_t OCIBreak; + OCIReset_t OCIReset; + OCIServerVersion_t OCIServerVersion; + OCIAttrGet_t OCIAttrGet; + OCIAttrSet_t OCIAttrSet; + OCISvcCtxToLda_t OCISvcCtxToLda; + OCILdaToSvcCtx_t OCILdaToSvcCtx; + OCIResultSetToStmt_t OCIResultSetToStmt; + + // 8.1.x (8i) calls + OCIEnvCreate_t OCIEnvCreate; + OCIEnvNlsCreate_t OCIEnvNlsCreate; + OCIDurationBegin_t OCIDurationBegin; + OCIDurationEnd_t OCIDurationEnd; + OCILobCreateTemporary_t OCILobCreateTemporary; + OCILobFreeTemporary_t OCILobFreeTemporary; + OCILobIsTemporary_t OCILobIsTemporary; + + OCIAQEnq_t OCIAQEnq; + OCIAQDeq_t OCIAQDeq; + OCIAQListen_t OCIAQListen; + OCISubscriptionRegister_t OCISubscriptionRegister; + OCISubscriptionPost_t OCISubscriptionPost; + OCISubscriptionUnRegister_t OCISubscriptionUnRegister; + OCISubscriptionDisable_t OCISubscriptionDisable; + OCISubscriptionEnable_t OCISubscriptionEnable; + + OCIDateTimeConstruct_t OCIDateTimeConstruct; + OCIDateTimeGetDate_t OCIDateTimeGetDate; + OCIDateTimeGetTime_t OCIDateTimeGetTime; + + OCINlsNumericInfoGet_t OCINlsNumericInfoGet; + + OCIStmtFetch2_t OCIStmtFetch2; +}; + +class SQLAPI_API ora8ConnectionHandles : public saConnectionHandles +{ +public: + ora8ConnectionHandles(); + + OCIEnv *m_pOCIEnv; + OCIError *m_pOCIError; + OCISvcCtx *m_pOCISvcCtx; + OCIServer *m_pOCIServer; + OCISession *m_pOCISession; +}; + +class SQLAPI_API ora8CommandHandles : public saCommandHandles +{ +public: + ora8CommandHandles(); + + OCIStmt *m_pOCIStmt; + OCIError *m_pOCIError; // cursor owned error handle +}; + +extern ora8API g_ora8API; + +#endif // !defined(__ORA8API_H__) diff --git a/libodbc/include/ora_linux/nzerror.h b/libodbc/include/ora_linux/nzerror.h new file mode 100644 index 0000000000..f280ff55d7 --- /dev/null +++ b/libodbc/include/ora_linux/nzerror.h @@ -0,0 +1,663 @@ +/* DISABLE check_long_lines */ + +/* + * $Header: /home/yas/cvs/SQLAPI/include/ora_linux/nzerror.h,v 1.2 2009/02/26 19:52:52 yas Exp $ + * + * Copyright (c) 1995, 2006, Oracle. All rights reserved. + */ + +/* ENABLE check_long_lines */ +/* + NAME + nzerror.h - error numbers for the Oracle Security Server + DESCRIPTION + None. + PUBLIC FUNCTION(S) + None. + PRIVATE FUNCTION(S) + None. + NOTES + A pragma is used to silence olint about the enum value names not being + unique within 7 characters. This limit is being changed to 30. + MODIFIED + rchahal 06/12/06 - + skalyana 01/30/05 - + rchahal 07/16/04 - add cert label + rchahal 07/06/04 - + rchahal 10/15/03 - bug 2513821 + rchahal 08/14/03 - new error range (43000 - 43499) + skalyana 08/25/03 - Error changes + rchahal 06/27/03 - RSA errors + rchahal 05/27/03 - convert wallet + skalyana 03/07/03 - Move FIPS errors + rchahal 02/28/03 - bug 2648177 + rchahal 01/20/03 - use sltsky + rchahal 11/11/02 - pkcs11 support + skalyana 11/29/02 - Add mutex errors + akoyfman 11/01/02 - adding crl cache + rchahal 10/23/02 - crldp error + rchahal 10/15/02 - fetch crl from ldap + rchahal 10/07/02 - crl support + akoyfman 10/16/02 - Update with SSL PLus 4.2 errors + skalyana 10/04/02 - Certicom SSL Plus 4.2 Upgrade changes + akoyfman 08/06/02 - adding sso wallet errors + akoyfman 07/12/02 - adding secret store errors + skalyana 07/07/02 - Add more errors for FIPS self tests + skalyana 07/01/02 - Add more errors + skalyana 06/03/02 - Add NZ error for self test failure. + ajacobs 02/22/01 - Add some entrust errors + vle 02/09/01 - add error mesg + lkethana 08/11/00 - Extension Errors + lkethana 07/30/00 - add pkcs12 errors + lkethana 06/17/00 - mult cert errors + lkethana 06/11/00 - multiple cert support + rturlapa 03/29/00 - Add error meesage for Entrust Login failure. + rwessman 07/07/99 - Deleted include of sslerrs.h. It caused the RDBMS bu + rwessman 07/02/99 - fixed merge errors + rwessman 07/01/99 - moved NZOS errors to nzerror to make them visible + supriya 12/16/98 - add new error for cert chain. + arswamin 12/04/98 - add NZERROR_NO_MATCHING_PRIVATE_KEY + qdinh 11/12/98 - add NZERROR_VALIDITY_EXPIRED. + arswamin 06/17/98 - add INIT_FAILED + sdange 06/10/98 - change wrong password to bad password + amthakur 06/09/98 - adding error messages + wliau 03/10/97 - Add new error message for snzdfo.c. + rwessman 03/14/97 - Consolidated PL/SQL toolkit errors into generic erro + rwessman 02/26/97 - Added NZERROR_UNSUPPORTED. Corrected values of + errors outside the valid range. + asriniva 03/02/97 - Fix olint warning + rwessman 02/26/97 - Added NZERROR_UNSUPPORTED + rwessman 01/02/97 - Changed PLSQL package errors to be TK_PLSQL to + separate them from the errors generated by the + Oracle interface. + rwessman 12/30/96 - Merged in PL/SQL toolkit errors + sdange 11/14/96 - (Added NZERROR_DECRYPT_FAILED to the enum list) + rwessman 12/02/96 - + rwessman 11/25/96 - Added error messages for PL/SQL functions. + asriniva 10/31/96 - Include oratypes.h + asriniva 10/29/96 - Fix numbering. + asriniva 10/29/96 - Fix error numbers + asriniva 10/29/96 - Correct type-o + asriniva 10/28/96 - Add more TK errors + asriniva 10/28/96 - Convert OKAPI errors to TK errors. + rwessman 10/17/96 - still more OSS TK errors + asriniva 10/16/96 - OKAPI errors + asriniva 10/15/96 - OSSTK errors + rwessman 10/15/96 - Added more OSS TK errors + asriniva 10/09/96 - Add OSSTK errors. + rwessman 09/05/96 - Added errors for PL/SQL functions. + wliau 09/05/96 - correct error numbers. + $Log: nzerror.h,v $ + Revision 1.2 2009/02/26 19:52:52 yas + no message + + * Revision 1.26 1996/07/15 23:07:23 wliau + * Added NZERROR_AUTH_SHARED_MEMORY + * + * Revision 1.25 1996/07/01 20:40:15 asriniva + * Finished RSA verify/sign. + * + * Revision 1.24 1996/06/27 20:39:41 rwessman + * Added more errors. + * + * Revision 1.23 1996/05/31 17:33:40 rwessman + * Updated nzerror.h to contain bug # for olint enum bug. + * + * Revision 1.22 1996/05/31 17:12:30 rwessman + * Assigned values to the various errors. + * + * Revision 1.21 1996/05/13 20:46:58 ggilchri + * Added more attribute related error conditions + * +*/ + +#ifndef NZERROR_ORACLE +# define NZERROR_ORACLE + +#ifndef ORATYPES +# include +#endif /* ORATYPES */ + +/* +** Errors - when an error is added here, a message corresponding to the +** error number must be added to the message file. +** New errors must be assigned numbers, otherwise the compiler can assign any +** value that it wants, which may lead to invalid error numbers being +** generated. +** The number range currently assigned to the OSS is 28750 - 29249 +** New number range 43000 - 43499 +*/ + +typedef enum nzerror +{ + NZERROR_OK = 0, + NZERROR_GENERIC = 28750, /* A catchall for errors */ + NZERROR_NO_MEMORY = 28751, /* No more memory */ + NZERROR_DATA_SOURCE_INIT_FAILED = 28752, /* Failed to init data source */ + NZERROR_DATA_SOURCE_TERM_FAILED = 28753,/* Failed to terminate data source */ + NZERROR_OBJECT_STORE_FAILED = 28754, /* Store object in data source failed */ + NZERROR_OBJECT_GET_FAILED = 28755, + /* Failed to obtain object from data source */ + NZERROR_MEMORY_ALLOC_FAILED = 28756, + /* Callback failed to allocate memory */ + NZERROR_MEMORY_ALLOC_0_BYTES = 28757, + /* Attempted to ask for 0 bytes of memory */ + NZERROR_MEMORY_FREE_FAILED = 28758, + /* Callback failed to free memory */ + NZERROR_FILE_OPEN_FAILED = 28759, + /* Open of file failed */ + NZERROR_LIST_CREATION_FAILED = 28760, + /* Creation of list failed */ + NZERROR_NO_ELEMENT = 28761, + /* No list element found */ + NZERROR_ELEMENT_ADD_FAILED = 28762, + /* Addition of list element failed */ + NZERROR_PARAMETER_BAD_TYPE = 28763, + /* Retrieval of an unknown parameter type */ + NZERROR_PARAMETER_RETRIEVAL = 28764, /* Retrieval of parameter failed */ + + NZERROR_NO_LIST = 28765, /* Data method list does not exist */ + NZERROR_TERMINATE_FAIL = 28766, /* Failed to terminate */ + NZERROR_BAD_VERSION_NUMBER = 28767, /* Bad version number */ + NZERROR_BAD_MAGIC_NUMBER = 28768, /* Bad magic number */ + NZERROR_METHOD_NOT_FOUND = 28769, + /* Data retrieval method specified does not exist */ + NZERROR_ALREADY_INITIALIZED = 28770, + /*The data source is already initialized */ + NZERROR_NOT_INITIALIZED = 28771, /* The data source is not initialized */ + NZERROR_BAD_FILE_ID = 28772, /* File ID is bad */ + NZERROR_WRITE_MAGIC_VERSION = 28773, /* Failed to write magic and version */ + NZERROR_FILE_WRITE_FAILED = 28774, /* Failed to write to file */ + NZERROR_FILE_CLOSE_FAILED = 28775, /* Failed to close file */ + NZERROR_OUTPUT_BUFFER_TOO_SMALL = 28776, + /* The buffer supplied by the caller is too small */ + NZERROR_BINDING_CREATION_FAILED = 28777,/* NL failed in creating a binding */ + NZERROR_PARAMETER_MALFORMED = 28778, /* A parameter was in a bad format */ + NZERROR_PARAMETER_NO_METHOD = 28779, + /* No method was specified for a data type */ + NZERROR_BAD_PARAMETER_METHOD = 28780, /* Illegal method for data type */ + NZERROR_PARAMETER_NO_DATA = 28781, /* No method specified when required */ + NZERROR_NOT_ALLOCATED = 28782, /* Data source is not allocated */ + NZERROR_INVALID_PARAMETER = 28783, /* Invalid parameter name */ + NZERROR_FILE_NAME_TRANSLATION = 28784,/* Could not translate OSD file name */ + NZERROR_NO_SUCH_PARAMETER = 28785, /* Selected parameter is non-existent */ + + NZERROR_DECRYPT_FAILED = 28786, + /* Encrypted private key decryption failure */ + NZERROR_ENCRYPT_FAILED = 28787, /* Private key encryption failed */ + + NZERROR_INVALID_INPUT = 28788, /* Incorrect input or unknown error */ + + NZERROR_NAME_TYPE_NOT_FOUND = 28789, + /* Type of name requested is not available */ + NZERROR_NLS_STRING_OPEN_FAILED = 28790, + /* Failure to generate an NLS string */ + NZERROR_CERTIFICATE_VERIFY = 28791, /* Failed to verify a certificate */ + NZERROR_OCI_PLSQL_FAILED = 28792, + /* an OCI call to process some plsql failed */ + NZERROR_OCI_BIND_FAILED = 28793, + /* an OCI call to bind an internal var. failed */ + NZERROR_ATTRIBUTE_INIT = 28794, /* failed to init role retrieval */ + NZERROR_ATTRIBUTE_FINISH_FAILED = 28795,/* Did not complete role retrieval */ + NZERROR_UNSUPPORTED_METHOD = 28796, /* Data method specified not supported */ + NZERROR_INVALID_KEY_DATA_TYPE = 28797, + /* Invalid data type specified for key */ + NZEROR_BIND_SUBKEY_COUNT = 28798, + /* Number of sub-keys to bind does not match count in initialized key */ + NZERROR_AUTH_SHARED_MEMORY = 28799, + /* Failed to retreieve authentication information from the shared memory */ + NZERROR_RIO_OPEN = 28800, /* RIO Open Failed */ + NZERROR_RIO_OBJECT_TYPE = 28801, /* RIO object type invalid */ + NZERROR_RIO_MODE = 28802, /* RIO mode invalid */ + NZERROR_RIO_IO = 28803, /* RIO io set or numberinvalid */ + NZERROR_RIO_CLOSE = 28804, /* RIO close failed */ + NZERROR_RIO_RETRIEVE = 28805, /* RIO retrieve failed */ + NZERROR_RIO_STORE = 28806, /* RIO store failed */ + NZERROR_RIO_UPDATE = 28807, /* RIO update failed */ + NZERROR_RIO_INFO = 28808, /* RIO info failed */ + NZERROR_RIO_DELETE = 28809, /* RIO delete failed */ + NZERROR_KD_CREATE = 28810, /* Key descriptor create failed */ + NZERROR_RIO_ACCESS_DESCRIPTOR = 28811, /* access descriptor invalid */ + NZERROR_RIO_RECORD = 28812, /* record invalid */ + NZERROR_RIO_RECORD_TYPE = 28813, /* record type and AD type not matched */ + NZERROR_PLSQL_ORACLE_TO_REAL = 28814, + /* A number passed to PL/SQL could not be converted to real format */ + NZERROR_PLSQL_REAL_TO_ORACLE = 28815, + /* A number in machine format could not be converted to Oracle format */ + NZERROR_TK_PLSQL_NO_PASSWORD = 28816, + /* A password was not provided to a PL/SQL function */ + NZERROR_TK_PLSQL_GENERIC = 28817, + /* A PL/SQL function returned an error */ + NZERROR_TK_PLSQL_NO_CONTEXT = 28818, + /* The package context was not specified to a PL/SQL function */ + NZERROR_TK_PLSQL_NO_DIST_NAME = 28819, + /* The user's distinguished name was not provided to a PL/SQL function */ + NZERROR_TK_PLSQL_NO_STATE = 28820, +/* The state of either a signature or decryption/encryption was not provided */ + NZERROR_TK_PLSQL_NO_INPUT = 28821, + /* An input buffer was specified to a PL/SQL function */ + NZERROR_TK_PLSQL_NO_SEED = 28822, + /* No seed was specified to the PL/SQL seed initialization function */ + NZERROR_TK_PLSQL_NO_BYTES = 28823, + /* Number of bytes was not specified to the PL/SQL random number generator */ + NZERROR_TK_INVALID_STATE = 28824, + /* Invalid encryption/decryption/signature state passed */ + NZERROR_TK_PLSQL_NO_ENG_FUNC = 28825, + /* No crypto engine function was passed in */ + NZERROR_TK_INV_ENG_FUNC = 28826, + /* An invalid crypto engine function was passed in */ + NZERROR_TK_INV_CIPHR_TYPE = 28827, + /* An invalid cipher type was passed in */ + NZERROR_TK_INV_IDENT_TYPE = 28828, + /* An invalid identity type was specified */ + NZERROR_TK_PLSQL_NO_CIPHER_TYPE = 28829, + /* No cipher type was specified */ + NZERROR_TK_PLSQL_NO_IDENT_TYPE = 28830, + /* No identity type was specified */ + NZERROR_TK_PLSQL_NO_DATA_FMT = 28831, + /* No data unit format was specified */ + NZERROR_TK_INV_DATA_FMT = 28832, + /* Invalid data unit format was provided to function */ + NZERROR_TK_PLSQL_INSUFF_INFO = 28833, + /* Not enough info (usually parameters) provided to a PL/SQL function */ + NZERROR_TK_PLSQL_BUF_TOO_SMALL = 28834, + /* Buffer provided by PL/SQL is too small for data to be returned */ + NZERROR_TK_PLSQL_INV_IDENT_DESC = 28835, + /* Identity descriptor not present or too small */ + NZERROR_TK_PLSQL_WALLET_NOTOPEN = 28836, + /* Wallet has not been opened yet */ + NZERROR_TK_PLSQL_NO_WALLET = 28837, + /* No wallet descriptor specified to PL/SQL function */ + NZERROR_TK_PLSQL_NO_IDENTITY = 28838, + /* No identity descriptor specified to PL/SQL function */ + NZERROR_TK_PLSQL_NO_PERSONA = 28839, + /* No persona descriptor was specified to PL/SQL function */ + NZERROR_TK_PLSQL_WALLET_OPEN = 28840, + /* Wallet was already opened */ + NZERROR_UNSUPPORTED = 28841, /* Operation is not supported */ + NZERROR_FILE_BAD_PERMISSION = 28842, /* Bad file permission specified */ + NZERROR_FILE_OSD_ERROR = 28843, /* OSD error when opening file */ + NZERROR_NO_WALLET = 28844, /* cert + privkey + tp files do not exist */ + NZERROR_NO_CERTIFICATE_ALERT = 28845, /* no certificate */ + NZERROR_NO_PRIVATE_KEY = 28846, /* no private-key */ + NZERROR_NO_CLEAR_PRIVATE_KEY_FILE = 28847, /* no clear key-file */ + NZERROR_NO_ENCRYPTED_PRIVATE_KEY_FILE = 28848, /* no encrypted priv key */ + NZERROR_NO_TRUSTPOINTS = 28849, /* no trustpoints */ + NZERROR_NO_CLEAR_TRUSTPOINT_FILE = 28850, /* no clear trustpoints */ + NZERROR_NO_ENCRYPTED_TRUSTPOINT_FILE = 28851, /* no encrypted trustpoints */ + NZERROR_BAD_PASSWORD = 28852, /* bad password */ + NZERROR_INITIALIZATION_FAILED = 28853, /* init failed or + module loading failed */ + /******************************* SSL ERRORS ********************************/ + /* + * In order to allow SSL errors to be mapped to Oracle errors, space is + * provided here. One Oracle error is provided for each SSL error to make + * error handling easier. A macro is provided to do the conversion. + * NOTE: ANY CHANGE IN SSL ERRORS MUST BE REFLECTED HERE. + * To add an SSL error, use the following formula to calculate the Oracle + * error: + * new_oracle_error = (new_ssl_error - SSLMemoryError) + NZERROR_SSLMemoryErr + * or numerically: + * new_oracle_error = (new_ssl_error - -7000) + 28854 + */ + NZERROR_SSLMemoryErr = 28854, + NZERROR_SSLUnsupportedErr = 28855, + NZERROR_SSLOverflowErr = 28856, + NZERROR_SSLUnknownErr = 28857, + NZERROR_SSLProtocolErr = 28858, + NZERROR_SSLNegotiationErr = 28859, + NZERROR_SSLFatalAlert = 28860, + NZERROR_SSLWouldBlockErr = 28861, + NZERROR_SSLIOErr = 28862, + NZERROR_SSLSessionNotFoundErr = 28863, + NZERROR_SSLConnectionClosedGraceful = 28864, + NZERROR_SSLConnectionClosedError = 28865, + NZERROR_ASNBadEncodingErr = 28866, + NZERROR_ASNIntegerTooBigErr = 28867, + NZERROR_X509CertChainInvalidErr = 28868, + NZERROR_X509CertExpiredErr = 28869, + NZERROR_X509NamesNotEqualErr = 28870, + NZERROR_X509CertChainIncompleteErr = 28871, + NZERROR_X509DataNotFoundErr = 28872, + NZERROR_SSLBadParameterErr = 28873, + NZERROR_SSLIOClosedOverrideGoodbyeKiss = 28874, + NZERROR_X509MozillaSGCErr = 28875, + NZERROR_X509IESGCErr = 28876, + NZERROR_ImproperServerCredentials = 28877, + NZERROR_ImproperClientCredentials = 28878, + NZERROR_NoProtocolSideSet = 28879, + NZERROR_setPersonaFailed = 28880, + NZERROR_setCertFailed = 28881, + NZERROR_setVKeyFailed = 28882, + NZERROR_setTPFailed = 28883, + NZERROR_BadCipherSuite = 28884, + NZERROR_NoKeyPairForKeyUsage = 28885, + +/* ============>>> ENTRUST ERRORS */ + NZERROR_EntrustLoginFailed = 28890, + NZERROR_EntrustGetInfoFailed = 28891, + NZERROR_EntrustLoadCertificateFailed = 28892, + NZERROR_EntrustGetNameFailed = 28893, + +/* ============>>> NZERRORS CONTINUED */ + NZERROR_CertNotInstalled = 29000, + NZERROR_ServerDNMisMatched = 29002, + NZERROR_ServerDNMisConfigured = 29003, + +/* ============>>> PKI VENDORS ERRORS 29050 - 29099 */ + +/* ============>>> SSL Errors CONTINUED */ + NZERROR_CIC_ERR_SSL_ALERT_CB_FAILURE = 29004, + NZERROR_CIC_ERR_SSL_BAD_CERTIFICATE = 29005, + NZERROR_CIC_ERR_SSL_BAD_CERTIFICATE_REQUEST = 29006, + NZERROR_CIC_ERR_SSL_BAD_CLEAR_KEY_LEN = 29007, + NZERROR_CIC_ERR_SSL_BAD_DHPARAM_KEY_LENGTH = 29008, + NZERROR_CIC_ERR_SSL_BAD_ENCRYPTED_KEY_LEN = 29009, + NZERROR_CIC_ERR_SSL_BAD_EXPORT_KEY_LENGTH = 29010, + NZERROR_CIC_ERR_SSL_BAD_FINISHED_MESSAGE = 29011, + NZERROR_CIC_ERR_SSL_BAD_KEY_ARG_LEN = 29012, + NZERROR_CIC_ERR_SSL_BAD_MAC = 29013, + NZERROR_CIC_ERR_SSL_BAD_MAX_FRAGMENT_LENGTH_EXTENSION = 29014, + NZERROR_CIC_ERR_SSL_BAD_MESSAGE_LENGTH = 29015, + NZERROR_CIC_ERR_SSL_BAD_PKCS1_PADDING = 29016, + NZERROR_CIC_ERR_SSL_BAD_PREMASTER_SECRET_LENGTH = 29017, + NZERROR_CIC_ERR_SSL_BAD_PREMASTER_SECRET_VERSION = 29018, + NZERROR_CIC_ERR_SSL_BAD_PROTOCOL_VERSION = 29019, + NZERROR_CIC_ERR_SSL_BAD_RECORD_LENGTH = 29020, + NZERROR_CIC_ERR_SSL_BAD_SECRET_KEY_LEN = 29021, + NZERROR_CIC_ERR_SSL_BAD_SIDE = 29022, + NZERROR_CIC_ERR_SSL_BUFFERS_NOT_EMPTY = 29023, + NZERROR_CIC_ERR_SSL_CERTIFICATE_VALIDATE_FAILED = 29024, + NZERROR_CIC_ERR_SSL_CERT_CHECK_CALLBACK = 29025, + NZERROR_CIC_ERR_SSL_DECRYPT_FAILED = 29026, + NZERROR_CIC_ERR_SSL_ENTROPY_COLLECTION = 29027, + NZERROR_CIC_ERR_SSL_FAIL_SERVER_VERIFY = 29028, + NZERROR_CIC_ERR_SSL_HANDSHAKE_ALREADY_COMPLETED = 29029, + NZERROR_CIC_ERR_SSL_HANDSHAKE_REQUESTED = 29030, + NZERROR_CIC_ERR_SSL_HANDSHAKE_REQUIRED = 29031, + NZERROR_CIC_ERR_SSL_INCOMPLETE_IDENTITY = 29032, + NZERROR_CIC_ERR_SSL_INVALID_PFX = 29033, + NZERROR_CIC_ERR_SSL_NEEDS_CIPHER_OR_CLIENTAUTH = 29034, + NZERROR_CIC_ERR_SSL_NEEDS_PRNG = 29035, + NZERROR_CIC_ERR_SSL_NOT_SUPPORTED = 29036, + NZERROR_CIC_ERR_SSL_NO_CERTIFICATE = 29037, + NZERROR_CIC_ERR_SSL_NO_MATCHING_CERTIFICATES = 29038, + NZERROR_CIC_ERR_SSL_NO_MATCHING_CIPHER_SUITES = 29039, + NZERROR_CIC_ERR_SSL_NO_SUPPORTED_CIPHER_SUITES = 29040, + NZERROR_CIC_ERR_SSL_NULL_CB = 29041, + NZERROR_CIC_ERR_SSL_READ_BUFFER_NOT_EMPTY = 29042, + NZERROR_CIC_ERR_SSL_READ_REQUIRED = 29043, + NZERROR_CIC_ERR_SSL_RENEGOTIATION_ALREADY_REQUESTED = 29044, + NZERROR_CIC_ERR_SSL_RENEGOTIATION_REFUSED = 29045, + NZERROR_CIC_ERR_SSL_RESUMABLE_SESSION = 29046, + NZERROR_CIC_ERR_SSL_TLS_EXTENSION_MISMATCH = 29047, + NZERROR_CIC_ERR_SSL_UNEXPECTED_MSG = 29048, + NZERROR_CIC_ERR_SSL_UNKNOWN_RECORD = 29049, + NZERROR_CIC_ERR_SSL_UNSUPPORTED_CLIENT_AUTH_MODE = 29050, + NZERROR_CIC_ERR_SSL_UNSUPPORTED_PUBKEY_TYPE = 29051, + NZERROR_CIC_ERR_SSL_WRITE_BUFFER_NOT_EMPTY = 29052, + NZERROR_CIC_ERR_PKCS12_MISSING_ALG = 29053, + NZERROR_CIC_ERR_PKCS_AUTH_FAILED = 29054, + NZERROR_CIC_ERR_PKCS_BAD_CONTENT_TYPE = 29055, + NZERROR_CIC_ERR_PKCS_BAD_INPUT = 29056, + NZERROR_CIC_ERR_PKCS_BAD_PADDING = 29057, + NZERROR_CIC_ERR_PKCS_BAD_SN = 29058, + NZERROR_CIC_ERR_PKCS_BAD_SN_LENGTH = 29059, + NZERROR_CIC_ERR_PKCS_BAD_VERSION = 29060, + NZERROR_CIC_ERR_PKCS_BASE = 29061, + NZERROR_CIC_ERR_PKCS_FIELD_NOT_PRESENT = 29062, + NZERROR_CIC_ERR_PKCS_NEED_CERTVAL = 29063, + NZERROR_CIC_ERR_PKCS_NEED_PASSWORD = 29064, + NZERROR_CIC_ERR_PKCS_NEED_PKC = 29065, + NZERROR_CIC_ERR_PKCS_NEED_PRV_KEY = 29066, + NZERROR_CIC_ERR_PKCS_NEED_TRUSTED = 29067, + NZERROR_CIC_ERR_PKCS_UNSUPPORTED_CERT_FORMAT = 29068, + NZERROR_CIC_ERR_PKCS_UNSUP_PRVKEY_TYPE = 29069, + NZERROR_CIC_ERR_CODING_BAD_PEM = 29070, + NZERROR_CIC_ERR_CODING_BASE = 29071, + NZERROR_CIC_ERR_DER_BAD_ENCODING = 29072, + NZERROR_CIC_ERR_DER_BAD_ENCODING_LENGTH = 29073, + NZERROR_CIC_ERR_DER_BASE = 29074, + NZERROR_CIC_ERR_DER_ELEMENT_TOO_LONG = 29075, + NZERROR_CIC_ERR_DER_INDEFINITE_LENGTH = 29076, + NZERROR_CIC_ERR_DER_NO_MORE_ELEMENTS = 29077, + NZERROR_CIC_ERR_DER_OBJECT_TOO_LONG = 29078, + NZERROR_CIC_ERR_DER_TAG_SIZE = 29079, + NZERROR_CIC_ERR_DER_TIME_OUT_OF_RANGE = 29080, + NZERROR_CIC_ERR_DER_UNUSED_BITS_IN_BIT_STR = 29081, + NZERROR_CIC_ERR_GENERAL_BASE = 29082, + NZERROR_CIC_ERR_HASH_BASE = 29083, + NZERROR_CIC_ERR_ILLEGAL_PARAM = 29084, + NZERROR_CIC_ERR_MEM_NOT_OURS = 29085, + NZERROR_CIC_ERR_MEM_OVERRUN = 29086, + NZERROR_CIC_ERR_MEM_UNDERRUN = 29087, + NZERROR_CIC_ERR_MEM_WAS_FREED = 29088, + NZERROR_CIC_ERR_NOT_FOUND = 29090, + NZERROR_CIC_ERR_NO_PTR = 29091, + NZERROR_CIC_ERR_TIMEOUT = 29092, + NZERROR_CIC_ERR_UNIT_MASK = 29093, + NZERROR_CIC_ERR_BAD_CTX = 29094, + NZERROR_CIC_ERR_BAD_INDEX = 29095, + NZERROR_CIC_ERR_BAD_LENGTH = 29096, + NZERROR_CIC_ERR_CODING_BAD_ENCODING = 29097, + NZERROR_CIC_ERR_SSL_NO_CLIENT_AUTH_MODES = 29098, + + /* ============>>> PKCS12 error 29100 - 29149 */ + + NZERROR_LOCKEYID_CREATE_FAILED = 29100, + NZERROR_P12_ADD_PVTKEY_FAILED = 29101, + NZERROR_P12_ADD_CERT_FAILED = 29102, + NZERROR_P12_WLT_CREATE_FAILED = 29103, + NZERROR_P12_ADD_CERTREQ_FAILED = 29104, + NZERROR_P12_WLT_EXP_FAILED = 29105, + NZERROR_P12_WLT_IMP_FAILED = 29106, + NZERROR_P12_CREATE_FAILED = 29107, + NZERROR_P12_DEST_FAILED = 29107, + NZERROR_P12_RAND_ERROR = 29108, + NZERROR_P12_PVTKEY_CRT_FAILED = 29109, + NZERROR_P12_INVALID_BAG = 29110, + NZERROR_P12_INVALID_INDEX = 29111, + NZERROR_P12_GET_CERT_FAILED = 29112, + NZERROR_P12_GET_PVTKEY_FAILED = 29113, + NZERROR_P12_IMP_PVTKEY_FAILED = 29114, + NZERROR_P12_EXP_PVTKEY_FAILED = 29115, + NZERROR_P12_GET_ATTRIB_FAILED = 29116, + NZERROR_P12_ADD_ATTRIB_FAILED = 29117, + NZERROR_P12_CRT_ATTRIB_FAILED = 29118, + NZERROR_P12_IMP_CERT_FAILED = 29119, + NZERROR_P12_EXP_CERT_FAILED = 29120, + NZERROR_P12_ADD_SECRET_FAILED = 29121, + NZERROR_P12_ADD_PKCS11INFO_FAILED = 29122, + NZERROR_P12_GET_PKCS11INFO_FAILED = 29123, + NZERROR_P12_MULTIPLE_PKCS11_LIBNAME = 29124, + NZERROR_P12_MULTIPLE_PKCS11_TOKENLABEL = 29125, + NZERROR_P12_MULTIPLE_PKCS11_TOKENPASSPHRASE = 29126, + NZERROR_P12_UNKNOWN_PKCS11INFO = 29127, + NZERROR_P12_PKCS11_LIBNAME_NOT_SET = 29128, + NZERROR_P12_PKCS11_TOKENLABEL_NOT_SET = 29129, + NZERROR_P12_PKCS11_TOKENPASSPHRASE_NOT_SET = 29130, + NZERROR_P12_MULTIPLE_PKCS11_CERTLABEL = 29131, + +/* ===========>>> SSL Errors CONTINUED 29135 - 29139 */ + NZERROR_CIC_ERR_RANDOM = 29135, + NZERROR_CIC_ERR_SMALL_BUFFER = 29136, + NZERROR_CIC_ERR_SSL_BAD_CONTEXT = 29137, + +/* ==========>>> Mutex Errors 29138 - 29139 */ + NZERROR_MUTEX_INITIALIZE_FAILED = 29138, + NZERROR_MUTEX_DESTROY_FAILED = 29139, + + +/* ============>>> EXTENSIONS Errors 29140 - 29149 */ + NZERROR_BS_CERTOBJ_CREAT_FAILED = 29140, + NZERROR_BS_DER_IMP_FAILED = 29141, + + +/* ============>>> FIPS ERRORS 29150 - 29175 */ + NZERROR_DES_SELF_TEST_FAILED = 29150, + NZERROR_3DES_SELF_TEST_FAILED = 29151, + NZERROR_SHA_SELF_TEST_FAILED = 29152, + NZERROR_RSA_SELF_TEST_FAILED = 29153, + NZERROR_DRNG_SELF_TEST_FAILED = 29154, + NZERROR_CKEYPAIR_SELF_TEST_FAILED = 29155, + NZERROR_CRNG_SELF_TEST_FAILED = 29156, + NZERROR_FIPS_PATHNAME_ERROR = 29157, + NZERROR_FIPS_LIB_OPEN_FAILED = 29158, + NZERROR_FIPS_LIB_READ_ERROR = 29159, + NZERROR_FIPS_LIB_DIFFERS = 29160, + NZERROR_DAC_SELF_TEST_FAILED = 29161, + NZERROR_NONFIPS_CIPHERSUITE = 29162, + NZERROR_VENDOR_NOT_SUPPORTED_FIPS_MODE = 29163, + NZERROR_EXTERNAL_PKCS12_NOT_SUPPORTED_FIPS_MODE = 29164, + NZERROR_AES_SELF_TEST_FAILED = 29165, + +/* ============>>> CRL ERRORS 29176 - 29200 */ + NZERROR_CRL_SIG_VERIFY_FAILED = 29176, /*CRL signature verification failed*/ + NZERROR_CERT_NOT_IN_CRL = 29177, + /*Cert is not in CRL - cert is not revoked*/ + NZERROR_CERT_IN_CRL = 29178, /*Cert is in CRL - cert is revoked*/ + NZERROR_CERT_IN_CRL_CHECK_FAILED = 29179, /*Cert revocation check failed */ + NZERROR_INVALID_CERT_STATUS_PROTOCOL = 29180, + NZERROR_LDAP_OPEN_FAILED = 29181, /* ldap_open failed */ + NZERROR_LDAP_BIND_FAILED = 29182, /* ldap_bind failed */ + NZERROR_LDAP_SEARCH_FAILED = 29183, /* ldap_search failed */ + NZERROR_LDAP_RESULT_FAILED = 29184, /* ldap_result failed */ + NZERROR_LDAP_FIRSTATTR_FAILED = 29185, /* ldap_first_attribute failed */ + NZERROR_LDAP_GETVALUESLEN_FAILED = 29186, /* ldap_get_values_len failed */ + NZERROR_LDAP_UNSUPPORTED_VALMEC = 29187, + /* unsupported validation mechanism */ + NZERROR_LDAP_COUNT_ENTRIES_FAILED = 29188,/* ldap_count_entries failed */ + NZERROR_LDAP_NO_ENTRY_FOUND = 29189, /* No entry found in OID */ + NZERROR_LDAP_MULTIPLE_ENTRIES_FOUND = 29190, /* Multiple entries in OID*/ + NZERROR_OID_INFO_NOT_SET = 29191, + NZERROR_LDAP_VALMEC_NOT_SET = 29192, + /* Validation mechanism not set in OID*/ + NZERROR_CRLDP_NO_CRL_FOUND = 29193, + /* No CRL found using CRLDP mechanism */ + NZERROR_CRL_NOT_IN_CACHE = 29194, /* No CRL found in the cache*/ + NZERROR_CRL_EXPIRED = 29195, /* CRL nextUpdate time is in the past */ + +/* ============>>> ADD ERRORS HERE -- NOTE DECREASING numbers */ + NZERROR_DN_MATCH = 29222, /* for nztCompareDN */ + NZERROR_CERT_CHAIN_CREATION = 29223, /* unable to create a cert chain + * with the existing TPs for the + * cert to be installed. + */ + NZERROR_NO_MATCHING_CERT_REQ = 29224, /* No matching cert_req was + * found the corresponding to + * the privatekey which + * matches the cert to be + * installed */ + NZERROR_CERT_ALREADY_INSTALLED = 29225, /* we are attempting to + * install a cert again into + * a persona which already + * has it installed. + */ + NZERROR_NO_MATCHING_PRIVATE_KEY = 29226, /* could not find a matching + * persona-private(privatekey) in + * the Persona, for the given + * cert(public key). + */ + NZERROR_VALIDITY_EXPIRED = 29227, /* certificate validity date expired */ + NZERROR_TK_BYTES_NEEDED = 29228, /* Couldn't determine # of bytes needed */ + NZERROR_TK_BAD_MAGIC_NUMBER = 29229, + /* Magic number found in header does not match expected */ + NZERROR_TK_BAD_HEADER_LENGTH = 29230, + /* Header length passed in not sufficient for message header */ + NZERROR_TK_CE_INIT = 29231, /* Crypto engine failed to initialize */ + NZERROR_TK_CE_KEYINIT = 29232, /* Crypto engine key initialization failed */ + NZERROR_TK_CE_ENCODE_KEY = 29233, /* Count not encode key object */ + NZERROR_TK_CE_DECODE_KEY = 29234, /* Could not decode key into object */ + NZERROR_TK_CE_GEYKEYINFO = 29235, /* Crypto engine failed to get key info */ + NZERROR_TK_SEED_RANDOM = 29236, /* Couldn't seed random number generator */ + NZERROR_TK_CE_ALGFINISH = 29237, /* Couldn't finish algorithm */ + NZERROR_TK_CE_ALGAPPLY = 29238, /* Couldn't apply algorithm to data */ + NZERROR_TK_CE_ALGINIT = 29239, /* Couldn't init CE for algorithm */ + NZERROR_TK_ALGORITHM = 29240, /* Have no idea what algorithm you want */ + NZERROR_TK_CANNOT_GROW = 29241, /* Cannot grow output buffer block */ + NZERROR_TK_KEYSIZE = 29242, /* Key not large enough for data */ + NZERROR_TK_KEYTYPE = 29243, /* Unknown key type. */ + + NZERROR_TK_PLSQL_NO_WRL = 29244, + /* Wallet resource locator not specified to PL/SQL function */ + + NZERROR_TK_CE_FUNC = 29245, /* Unknown crypto engine function */ + NZERROR_TK_TDU_FORMAT = 29246, /* Unknown TDU format */ + NZERROR_TK_NOTOPEN = 29247, /* Object must be open */ + NZERROR_TK_WRLTYPE = 29248, /* Bad WRL type */ + NZERROR_TK_CE_STATE = 29249, /* Bad state specified for the crypto engine */ + + /* After 29249, use error numbers in block 43000 - 43499 */ + NZERROR_PKCS11_LIBRARY_NOT_FOUND = 43000, /* PKCS #11 library not found */ + NZERROR_PKCS11_TOKEN_NOT_FOUND = 43001, + /* can't find token with given label*/ + NZERROR_PKCS11_BAD_PASSPHRASE = 43002, /* passphrase is incorrect/expired */ + NZERROR_PKCS11_GET_FUNC_LIST = 43003, /* C_GetFunctionList returned error */ + NZERROR_PKCS11_INITIALIZE = 43004, /* C_Initialize returned error */ + NZERROR_PKCS11_NO_TOKENS_PRESENT = 43005, /* No tokens present */ + NZERROR_PKCS11_GET_SLOT_LIST = 43006, /* C_GetSlotList returned error */ + + NZERROR_PKCS11_GET_TOKEN_INFO = 43008, /* C_GetTokenInfo returned error */ + NZERROR_PKCS11_SYMBOL_NOT_FOUND = 43009, /* Symbol not found in PKCS11 lib */ + + NZERROR_PKCS11_TOKEN_LOGIN_FAILED = 43011, /* Token login failed */ + + NZERROR_PKCS11_CHANGE_PROVIDERS_ERROR = 43013, /* Change providers error */ + NZERROR_PKCS11_GET_PRIVATE_KEY_ERROR = 43014, + /* Error trying to find private key on token */ + NZERROR_PKCS11_CREATE_KEYPAIR_ERROR = 43015, /* Key pair gen error */ + NZERROR_PKCS11_WALLET_CONTAINS_P11_INFO = 43016, /* Wallet already contains + pkcs11 info */ + NZERROR_PKCS11_NO_CERT_ON_TOKEN = 43017, /* No cert found on token */ + NZERROR_PKCS11_NO_USER_CERT_ON_TOKEN = 43018, /*No user cert found on token*/ + NZERROR_PKCS11_NO_CERT_ON_TOKEN_WITH_GIVEN_LABEL = 43019, /*No cert found on token with given certificate label.*/ + NZERROR_PKCS11_MULTIPLE_CERTS_ON_TOKEN_WITH_GIVEN_LABEL = 43020, /*Multiple certs found on token with given certificate label.*/ + NZERROR_PKCS11_CERT_WITH_LABEL_NOT_USER_CERT = 43021, /*Cert with given cert is not a user cert because no corresponding pvt key found on token */ + + /* RSA ERRORS 43050 - 43059 */ + NZERROR_BIND_SERVICE_ERROR = 43050, /* C_BindService returned error */ + NZERROR_CREATE_KEY_OBJ_ERROR = 43051, /* B_CreateKeyObject returned error */ + NZERROR_GET_CERT_FIELDS = 43052, /* C_GetCertFields returned error */ + NZERROR_CREATE_PKCS10_OBJECT = 43053, + /* C_CreatePKCS10Object returned error */ + NZERROR_SET_PKCS10_FIELDS = 43054, /* C_SetPKCS10Fields returned error */ + NZERROR_SIGN_CERT_REQUEST = 43055, /* C_SignCertRequest returned error */ + NZERROR_GET_PKCS10_DER = 43056, /* C_GetPKCS10DER returned error */ + NZERROR_INITIALIZE_CERTC = 43057, /* C_InitializeCertC returned error */ + NZERROR_INSERT_PRIVATE_KEY = 43058, /* C_InsertPrivateKey returned error */ + NZERROR_RSA_ERROR = 43059, /* RSA error. See trace output */ + + /* slts ERRORS 43060 - 43069 */ + NZERROR_SLTSCTX_INIT_FAILED = 43060, /* sltsini() returned error */ + NZERROR_SLTSKYC_FAILED = 43061, /* sltskyc() returned error */ + NZERROR_SLTSCTX_TERM_FAILED = 43062, /* sltster() returned error */ + NZERROR_SLTSKYS_FAILED = 43063, /* sltskys() returned error */ + + NZERROR_INVALID_HEADER_LENGTH = 43070, /* bad sso header length */ + NZERROR_WALLET_CONTAINS_USER_CREDENTIALS = 43071, /* wallet not empty */ + NZERROR_CANNOT_MODIFY_AL = 43072, /* Cannot modify AL wallet */ + + NZERROR_LAST_ERROR = 43499, /* Last available error */ + /* MAXIMUM ERROR NUMBER IS 43499 */ + + /* + * DO NOT JUST INSERT NEW ERRORS IN ANY OLD PLACE. New errors should be + * added such the current error retains their integer values. Duplicate + * values will cause compiler errors. + */ + NZERROR_THIS_MUST_BE_LAST + +} nzerror; + +/* + * Macro to convert SSL errors to Oracle errors. As SSL errors are negative + * and Oracle numbers are positive, the following needs to be done. + * 1. The base error number, which is the highest, is added to the + * SSL error to get the index into the number range. + * 2. The result is added to the base Oracle number to get the Oracle error. + */ +#define NZERROR_SSL_TO_ORACLE(ssl_error_) \ + ((ssl_error_ == SSLNoErr) \ + ? NZERROR_OK \ + : (nzerror) ((ssl_error_ - SSLMemoryErr) + (uword) NZERROR_SSLMemoryErr)) +#endif /* NZERROR_ORACLE */ diff --git a/libodbc/include/ora_linux/nzt.h b/libodbc/include/ora_linux/nzt.h new file mode 100644 index 0000000000..ac9bf9f48d --- /dev/null +++ b/libodbc/include/ora_linux/nzt.h @@ -0,0 +1,2386 @@ +/* DISABLE check_long_lines */ + +/* Copyright (c) 1996, 2006, Oracle. All rights reserved. */ +/* Copyright (c) 1996, 2006, Oracle. All rights reserved. */ + +/* + * + */ + +/* + * NAME + * nzt.h + * + * DESCRIPTION + * Toolkit public declarations. + * + * PUBLIC FUNCTIONS + * nztwOpenWallet - Open a wallet based on a WRL and pwd. + * nztwCloseWallet - Close a wallet. + * + nztwCreateWallet - Create a new wallet. + * + nztwDestroyWallet - Destroy an existing wallet. + * nztwRetrievePersonaCopy - Retieve a copy of a particular persona. + * + nzteStorePersona - Store a persona in the wallet. + * nzteOpenPersona - Open a persona. + * nzteClosePersona - Close a persona. + * + nzteRemovePersona - Remove a persona from a wallet. + * + nzteCreatePersona - Create a persona. + * nzteDestroyPersona - Destroy a persona. + * nztiStoreTrustedIdentity - Store an identity with associated trust. + * nzteRetrieveTrustedIdentCopy - Retrieves a trusted identity from persona + * + nzteSetProtection - Modify the protection set in a persona. + * + nzteGetProtection - Get the protection set in a persona + * nztePriKey - Get the Private Key (X509 Only) + * nzteMyCert - Get the Certificate (X509 only) + * nzteX509CreatePersona - Create a persona given an X509 Certificate. + * + nztiRemoveIdentity - Remove an identity from a persona. + * nztiCreateIdentity - Create an identity. + * nztiDuplicateIdentity - Create a complete copy of an identity. + * nztiAbortIdentity - Discard an unstored identity. + * nztidGetIdentityDesc - Gets Identity Description from Identity. + * nztidFreeIdentityDesc - Frees memory for Identity Desc object. + * nztSign - Generate an attached signature. + * + nztxSignExpansion - Determine size of signature. + * nztVerify - Verify an attached signature. + * nztValidate - Validate an identity. + * nztsd_SignDetached - Generate a detached signature. + * + nztxsd_SignDetachedExpansion - Determine size of detached signature. + * nztved_VerifyDetached - Verify a detached signature. + * + nztEncrypt - Symmetric key encryption. + * + nztxEncryptExpansion - Determine the tdu length for encryption. + * + nztDecrypt - Symmetric key decryption. + * + nztEnvelope - Sign then encrypt data for recipient(s). + * + nztDeEnvelope - Reverse nztEnvelope. + * + nztKeyedHash - Generate keyed hash. + * + nztxKeyedHashExpansion - Determine size of TDU for keyed hash. + * nztHash - Generate hash. + * + nztxHashExpansion - Determine the size of the TDU for a hash. + * nztSeedRandom - See the random number generator. + * nztrb_RandomBytes - Generate a series of random bytes. + * nztrn_RandomNumber - Generate a random number. + * nztbbInitBlock - Initialize a buffer block. + * nztbbReuseBlock - Reuse a buffer block. + * nztbbSizeBlock - Find the size of the buffer block. + * nztbbGrowBlock - Grow initialized buffer block by 'inc' bytes. + * nztbbPurgeBlock - Purge the memory used within a buffer block. + * nztbbSetBlock - Set block to known state. + * nztkec_PKEncrypt - Encrypt data then encrypt key for recipient. + * nztkdc_PKDecrypt - Decrypt PKEncrypt'ed data. + * nztific_FreeIdentityContent - Free the contents of an identity. + * nztifdn - Create an identity from a distinguished name + * nztcts_CipherSpecToStr - Converts the Cipher Spec Code To String + * nztiae_IsAuthEnabled - Checks to see if Authentication is Enabled + * in the current Cipher Spec. + * nztiae_IsEncrEnabled - Checks to see if Encryption is Enabled + * in the current Cipher Spec. + * nztiae_IsHashEnabled - Checks to see if Hashing is Enabled + * in the current Cipher Spec. + * nztwGetCertInfo - Get peer certificate info + * + * NOTE: the '+' indicates that these functions are UNSUPPORTED at this time. + * + * NOTES + * + * MODIFIED + * skalyana 08/15/07 - + * pkale 09/28/06 - Bug 5565668: Removed __STDC__ + * tnallath 09/22/05 - + * rchahal 07/27/04 - add keyusage + * srtata 11/10/03 - fix nztSetAppDefaultLocation header + * rchahal 10/15/03 - bug 2513821 + * rchahal 11/11/02 - pkcs11 support + * akoyfman 07/05/02 - adding secret store to persona + * supriya 10/11/01 - Fix for bug # 2015732 + * ajacobs 04/04/01 - make NZT_REGISTRY_WRL always available + * ajacobs 03/06/01 - olint fix + * ajacobs 03/02/01 - Add GetCertInfo + * supriya 02/23/01 - Move nzttKPUsage from nzt0.h + * rchahal 01/26/01 - olint fixes + * supriya 12/07/00 - Change fn name + * supriya 12/01/00 - Certificate API's needed for iAS + * supriya 06/19/00 - Adding definitions for MCS and ENTR + * lkethana 05/31/00 - multiple cert support + * skanjila 06/25/99 - Remove nztcts_CipherSpecToStr() to NZOS. + * skanjila 06/23/99 - Change API of nztcts_CipherSpecToStr. + * lkethana 06/18/99 - rem nztIPrivateAlloc, etc + * lkethana 06/10/99 - changing size_t to ub4 + * lkethana 06/02/99 - add api for getting auth/encry/hash capability of c + * arswamin 12/28/98 - add NZT_MAX_MD5. + * arswamin 12/21/98 - change signature of compareDN + * qdinh 12/21/98 - change size_t to ub4. + * inetwork 11/22/98 - Removing NZDEPRECATED definition + * amthakur 09/14/98 - deprecating and updating the c-structures. + * arswamin 09/24/98 - adding NZTTWRL_NULL for SSO support. + * amthakur 07/30/98 - changing the prototype of nztGetCertChain. + * qdinh 05/01/98 - add NZTTIDENTTYPE_INVALID_TYPE + * qdinh 04/17/98 - add NZTTWRL_ORACLE. + * ascott 10/08/97 - implement nztiStoreTrustedIdentity + * ascott 10/07/97 - add nztiGetIdentityDesc + * ascott 09/28/97 - clarify prototype comments and error codes + * ascott 09/05/97 - update identity: create, destroy, duplicate + * ascott 08/21/97 - add GetCert and GetPriKey + * ascott 08/07/97 - add other WRL settings + * asriniva 03/25/97 - Add ANSI prototypes + * rwessman 03/19/97 - Added prototypes for nztific_FreeIdentityContent() + * asriniva 03/11/97 - Fix olint errors + * sdange 02/28/97 - Removed inclusion of nz0decl.h + * sdange 02/18/97 - Moved nzt specific declarations from nz0decl.h + * asriniva 01/21/97 - Remove prototypes. + * asriniva 10/31/96 - Include oratypes.h + * asriniva 10/15/96 - Declare buffer block helper functions + * asriniva 10/08/96 - First pass at wallet open/close + * asriniva 10/04/96 - Add random number seed function + * asriniva 10/03/96 - Reorder parameters in nztbbSetBlock + * asriniva 10/03/96 - Keep editing. + * asriniva 10/03/96 - Continued edits. + * asriniva 10/02/96 - Continue editing. + * asriniva 09/26/96 - + */ + +/* ENABLE check_long_lines */ + +#ifndef NZT_ORACLE +#define NZT_ORACLE + +#ifndef ORATYPES +# include +#endif /* ORATYPES */ + +#ifndef NZERROR_ORACLE +# include /* NZ error type */ +#endif /* NZERROR_ORACLE */ + + +#define NZT_MAX_SHA1 20 +#define NZT_MAX_MD5 16 + +/***************************************/ +/* PUBLIC CONSTANTS, MACROS, AND TYPES */ +/***************************************/ + +/* + * Wallet Resource Locator Type Strings + * + * WRL TYPE PARAMETERS BEHAVIOR + * ======== ========== ===================================== + * default: Uses directory defined by the parameter + * SNZD_DEFAULT_FILE_DIRECTORY which in + * unix is "$HOME/oracle/oss" + * + * file: file path Find the Oracle wallet in this directory. + * example: file: + * + * sqlnet: In this case, the directory path will be + * retrieved from the sqlnet.ora file under + * the oss.source.my_wallet parameter. + * + * mcs: Microsoft WRL. + * + * entr: dir path Entrust WRL. eg: ENTR: + * + */ +/* Note that there is no NZT_NULL_WRL. Instead look in snzd.h for DEFAULT_WRP + * which is used in our new defaulting mechanism. The NZT_DEFAULT_WRL + * should be deprecated. + */ +#define NZT_DEFAULT_WRL ((text *)"default:") +#define NZT_SQLNET_WRL ((text *)"sqlnet:") +#define NZT_FILE_WRL ((text *)"file:") +#define NZT_ENTR_WRL ((text *)"entr:") +#define NZT_MCS_WRL ((text *)"mcs:") +#define NZT_ORACLE_WRL ((text *)"oracle:") +#define NZT_REGISTRY_WRL ((text *)"reg:") + +enum nzttwrl +{ + NZTTWRL_DEFAULT = 1, /* Default, use SNZD_DEFAULT_FILE_DIRECTORY */ + NZTTWRL_SQLNET, /* Use oss.source.my_wallet in sqlnet.ora file */ + NZTTWRL_FILE, /* Find the oracle wallet in this directory */ + NZTTWRL_ENTR, /* Find the entrust profile in this directory */ + NZTTWRL_MCS, /* WRL for Microsoft */ + NZTTWRL_ORACLE, /* Get the wallet from OSS db */ + NZTTWRL_NULL, /* New SSO defaulting mechanism */ + NZTTWRL_REGISTRY /* Find the wallet in Windows Registry */ +}; +typedef enum nzttwrl nzttwrl; + +#ifndef NZ0DECL_ORACLE + /* + * With the elimination of nz0decl.h from public, we need this + * redundant typedef. + */ + typedef struct nzctx nzctx; + typedef struct nzstrc nzstrc; + typedef struct nzosContext nzosContext; +#endif /* NZ0DECL_ORACLE */ + +/* Moved from nz0decl.h */ + +typedef struct nzttIdentity nzttIdentity; +typedef struct nzttIdentityPrivate nzttIdentityPrivate; +typedef struct nzttPersona nzttPersona; +typedef struct nzttPersonaPrivate nzttPersonaPrivate; +typedef struct nzttWallet nzttWallet; +typedef struct nzttWalletPrivate nzttWalletPrivate; +typedef struct nzttWalletObj nzttWalletObj; /* For wallet object */ +typedef struct nzssEntry nzssEntry; /* For secretstore */ +typedef struct nzpkcs11_Info nzpkcs11_Info; + +/* + * Crypto Engine State + * + * Once the crypto engine (CE) has been initialized for a particular + * cipher, it is either at the initial state, or it is continuing to + * use the cipher. NZTCES_END is used to change the state back to + * initialized and flush any remaining output. NZTTCES_RESET can be + * used to change the state back to initialized and throw away any + * remaining output. + */ +enum nzttces +{ + NZTTCES_CONTINUE = 1, /* Continue processing input */ + NZTTCES_END, /* End processing input */ + NZTTCES_RESET /* Reset processing and skip generating output */ +}; +typedef enum nzttces nzttces; + +/* + * Crypto Engine Functions + * + * List of crypto engine categories; used to index into protection + * vector. + */ +enum nzttcef +{ + NZTTCEF_DETACHEDSIGNATURE = 1, /* Signature, detached from content */ + NZTTCEF_SIGNATURE, /* Signature combined with content */ + NZTTCEF_ENVELOPING, /* Signature and encryption with content */ + NZTTCEF_PKENCRYPTION, /* Encryption for one or more recipients */ + NZTTCEF_ENCRYPTION, /* Symmetric encryption */ + NZTTCEF_KEYEDHASH, /* Keyed hash/checkusm */ + NZTTCEF_HASH, /* Hash/checsum */ + NZTTCEF_RANDOM, /* Random byte generation */ + + NZTTCEF_LAST /* Used for array size */ +}; +typedef enum nzttcef nzttcef; + +/* + * State of the persona. + */ +enum nzttState +{ + NZTTSTATE_EMPTY = 0, /* is not in any state(senseless???) */ + NZTTSTATE_REQUESTED, /* cert-request */ + NZTTSTATE_READY, /* certificate */ + NZTTSTATE_INVALID, /* certificate */ + NZTTSTATE_RENEWAL /* renewal-requested */ +}; +typedef enum nzttState nzttState; + +/* + * Cert-version types + * + * This is used to quickly look-up the cert-type + */ +enum nzttVersion +{ + NZTTVERSION_X509v1 = 1, /* X.509v1 */ + NZTTVERSION_X509v3, /* X.509v3 */ +#ifdef NZDEPRECATED + NZTTVERSION_SYMMETRIC, /* Symmetric */ +#endif + NZTTVERSION_INVALID_TYPE /* For Initialization */ +}; +typedef enum nzttVersion nzttVersion; + +/* + * Cipher Types + * + * List of all cryptographic algorithms, some of which may not be + * available. + */ +enum nzttCipherType +{ + NZTTCIPHERTYPE_RSA = 1, /* RSA public key */ + NZTTCIPHERTYPE_DES, /* DES */ + NZTTCIPHERTYPE_RC4, /* RC4 */ + NZTTCIPHERTYPE_MD5DES, /* DES encrypted MD5 with salt (PBE) */ + NZTTCIPHERTYPE_MD5RC2, /* RC2 encrypted MD5 with salt (PBE) */ + NZTTCIPHERTYPE_MD5, /* MD5 */ + NZTTCIPHERTYPE_SHA /* SHA */ +}; +typedef enum nzttCipherType nzttCipherType; + +/* + * TDU Formats + * + * List of possible toolkit data unit (TDU) formats. Depending on the + * function and cipher used some may be not be available. + */ +enum nztttdufmt +{ + NZTTTDUFMT_PKCS7 = 1, /* PKCS7 format */ + NZTTTDUFMT_RSAPAD, /* RSA padded format */ + NZTTTDUFMT_ORACLEv1, /* Oracle v1 format */ + NZTTTDUFMT_LAST /* Used for array size */ +}; +typedef enum nztttdufmt nztttdufmt; + +/* + * Validate State + * + * Possible validation states an identity can be in. + */ +enum nzttValState +{ + NZTTVALSTATE_NONE = 1, /* Needs to be validated */ + NZTTVALSTATE_GOOD, /* Validated */ + NZTTVALSTATE_REVOKED /* Failed to validate */ +}; +typedef enum nzttValState nzttValState; + +/* + * Policy Fields <----NEW (09/14/98) + * + * Policies enforced + */ +enum nzttPolicy +{ + NZTTPOLICY_NONE = 0, + NZTTPOLICY_RETRY_1, /* number of retries for decryption = 1 */ + NZTTPOLICY_RETRY_2, /* number of retries for decryption = 2 */ + NZTTPOLICY_RETRY_3 /* number of retries for decryption = 3 */ +}; +typedef enum nzttPolicy nzttPolicy; + +/* + * Persona Usage <----NEW (09/14/98) + * + * what a persona will be used for? + */ + +#ifdef NZDEPRECATED_MULTIPLECERTS +enum nzttUsage +{ + NZTTUSAGE_NONE = 0, + NZTTUSAGE_SSL /* persona for SSL usage */ +}; +typedef enum nzttUsage nzttUsage; +#endif + +/* + * Personas and identities have unique id's that are represented with + * 128 bits. + */ +typedef ub1 nzttID[16]; + +/* + * Identity Types + * + * List of all Identity types.. + */ +enum nzttIdentType +{ + NZTTIDENTITYTYPE_INVALID_TYPE = 0, + NZTTIDENTITYTYPE_CERTIFICTAE, + NZTTIDENTITYTYPE_CERT_REQ, + NZTTIDENTITYTYPE_RENEW_CERT_REQ, + NZTTIDENTITYTYPE_CLEAR_ETP, + NZTTIDENTITYTYPE_CLEAR_UTP, + NZTTIDENTITYTYPE_CLEAR_PTP +}; +typedef enum nzttIdentType nzttIdentType; + +typedef ub4 nzttKPUsage; +/* IF new types are added nztiMUS should be changed */ +#define NZTTKPUSAGE_NONE 0 +#define NZTTKPUSAGE_SSL 1 /* SSL Server */ +#define NZTTKPUSAGE_SMIME_ENCR 2 +#define NZTTKPUSAGE_SMIME_SIGN 4 +#define NZTTKPUSAGE_CODE_SIGN 8 +#define NZTTKPUSAGE_CERT_SIGN 16 +#define NZTTKPUSAGE_SSL_CLIENT 32 /* SSL Client */ +#define NZTTKPUSAGE_INVALID_USE 0xffff + + +/* + * Timestamp as 32 bit quantity in UTC. + */ +typedef ub1 nzttTStamp[4]; + +/* + * Buffer Block + * + * A function that needs to fill (and possibly grow) an output buffer + * uses an output parameter block to describe each buffer. + * + * The flags_nzttBufferBlock member tells the function whether the + * buffer can be grown or not. If flags_nzttBufferBlock is 0, then + * the buffer will be realloc'ed automatically. + * + * The buflen_nzttBufferBLock member is set to the length of the + * buffer before the function is called and will be the length of the + * buffer when the function is finished. If buflen_nzttBufferBlock is + * 0, then the initial pointer stored in pobj_nzttBufferBlock is + * ignored. + * + * The objlen_nzttBufferBlock member is set to the length of the + * object stored in the buffer when the function is finished. If the + * initial buffer had a non-0 length, then it is possible that the + * object length is shorter than the buffer length. + * + * The pobj_nzttBufferBlock member is a pointer to the output object. + */ +struct nzttBufferBlock +{ +# define NZT_NO_AUTO_REALLOC 0x1 + + uword flags_nzttBufferBlock; /* Flags */ + ub4 buflen_nzttBufferBlock; /* Total length of buffer */ + ub4 usedlen_nzttBufferBlock; /* Length of used buffer part */ + ub1 *buffer_nzttBufferBlock; /* Pointer to buffer */ +}; +typedef struct nzttBufferBlock nzttBufferBlock; + +/* + * Wallet. + */ +struct nzttWallet +{ + ub1 *ldapName_nzttWallet; /* user's LDAP Name */ + ub4 ldapNamelen_nzttWallet; /* len of user's LDAP Name */ + nzttPolicy securePolicy_nzttWallet; /* secured-policy of the wallet */ + nzttPolicy openPolicy_nzttWallet; /* open-policy of the wallet */ + nzttPersona *persona_nzttWallet; /* List of personas in wallet */ + nzttWalletPrivate *private_nzttWallet; /* Private wallet information */ +#ifdef NZDEPRECATED + ub4 npersona_nzttWallet; /* Number of personas */ +#endif +}; + +/* + * The wallet contains, one or more personas. A persona always + * contains its private key and its identity. It may also contain + * other 3rd party identites. All identities qualified with trust + * where the qualifier can indicate anything from untrusted to trusted + * for specific operations. + */ + +/* + * Persona + * + * Structure containing information about a persona. + */ +struct nzttPersona +{ + ub1 *genericName_nzttPersona; /* user-friendly persona name */ + ub4 genericNamelen_nzttPersona; /* persona-name length */ + nzttPersonaPrivate *private_nzttPersona; /* Opaque part of persona */ + nzttIdentity *mycertreqs_nzttPersona; /* My cert-requests */ + nzttIdentity *mycerts_nzttPersona; /* My certificates */ + nzttIdentity *mytps_nzttPersona; /* List of trusted identities */ + nzssEntry *mystore_nzttPersona; /* List of secrets */ + nzpkcs11_Info *mypkcs11Info_nzttPersona; /* PKCS11 token info */ + struct nzttPersona *next_nzttPersona; /* Next persona */ +#ifdef NZDEPRECATED_MULTIPLECERTS + /* As Persona has multiple certs for different + usages, Persona Usage does not mean anything. Similarly + each key pair has its own state and Persona state itself + does not mean anything. - lk 5/31/00 + */ + nzttUsage usage_nzttPersona; /* persona usage; SSL/SET/.. */ + nzttState state_nzttPersona; /* persona state-requested/ready */ + ub4 ntps_nzttPersona; /* Num of trusted identities */ +#endif +}; + +/* + * Identity + * + * Structure containing information about an identity. + * + * NOTE + * -- the next_trustpoint field only applies to trusted identities and + * has no meaning (i.e. is NULL) for self identities. + */ +struct nzttIdentity +{ + text *dn_nzttIdentity; /* Alias */ + ub4 dnlen_nzttIdentity; /* Length of alias */ + text *comment_nzttIdentity; /* Comment */ + ub4 commentlen_nzttIdentity; /* Length of comment */ + nzttIdentityPrivate *private_nzttIdentity; /* Opaque part of identity */ + nzttIdentity *next_nzttIdentity; /* next identity in list */ +}; + +struct nzttB64Cert +{ + ub1 *b64Cert_nzttB64Cert; + ub4 b64Certlen_nzttB64Cert; + struct nzttB64Cert *next_nzttB64Cert; +}; +typedef struct nzttB64Cert nzttB64Cert; + + +struct nzttPKCS7ProtInfo +{ + nzttCipherType mictype_nzttPKCS7ProtInfo; /* Hash cipher */ + nzttCipherType symmtype_nzttPKCS7ProtInfo; /* Symmetric cipher */ + ub4 keylen_nzttPKCS7ProtInfo; /* Length of key to use */ +}; +typedef struct nzttPKCS7ProtInfo nzttPKCS7ProtInfo; + +/* + * Protection Information. + * + * Information specific to a type of protection. + */ +union nzttProtInfo +{ + nzttPKCS7ProtInfo pkcs7_nzttProtInfo; +}; +typedef union nzttProtInfo nzttProtInfo; + +/* + * A description of a persona so that the toolkit can create one. A + * persona can be symmetric or asymmetric and both contain an + * identity. The identity for an asymmetric persona will be the + * certificate and the identity for the symmetric persona will be + * descriptive information about the persona. In either case, an + * identity will have been created before the persona is created. + * + * A persona can be stored separately from the wallet that references + * it. By default, a persona is stored with the wallet (it inherits + * with WRL used to open the wallet). If a WRL is specified, then it + * is used to store the actuall persona and the wallet will have a + * reference to it. + */ +struct nzttPersonaDesc +{ + ub4 privlen_nzttPersonaDesc; /* Length of private info (key)*/ + ub1 *priv_nzttPersonaDesc; /* Private information */ + ub4 prllen_nzttPersonaDesc; /* Length of PRL */ + text *prl_nzttPersonaDesc; /* PRL for storage */ + ub4 aliaslen_nzttPersonaDesc; /* Length of alias */ + text *alias_nzttPersonaDesc; /* Alias */ + ub4 longlen_nzttPersonaDesc; /* Length of longer description*/ + text *long_nzttPersonaDesc; /* Longer persona description */ +}; +typedef struct nzttPersonaDesc nzttPersonaDesc; + +/* + * A description of an identity so that the toolkit can create one. + * Since an identity can be symmetric or asymmetric, the asymmetric + * identity information will not be used when a symmetric identity is + * created. This means the publen_nzttIdentityDesc and + * pub_nzttIdentityDesc members will not be used when creating a + * symmetric identity. + */ +struct nzttIdentityDesc +{ + ub4 publen_nzttIdentityDesc; /* Length of identity */ + ub1 *pub_nzttIdentityDesc; /* Type specific identity */ + ub4 dnlen_nzttIdentityDesc; /* Length of alias */ + text *dn_nzttIdentityDesc; /* Alias */ + ub4 longlen_nzttIdentityDesc; /* Length of longer description */ + text *long_nzttIdentityDesc; /* Longer description */ + ub4 quallen_nzttIdentityDesc; /* Length of trust qualifier */ + text *trustqual_nzttIdentityDesc; /* Trust qualifier */ +}; +typedef struct nzttIdentityDesc nzttIdentityDesc; + +/********************************/ +/* PUBLIC FUNCTION DECLARATIONS */ +/********************************/ + +/*---------------------- nztwOpenWallet ----------------------*/ + +/* + * NAME + * nztwOpenWallet - Open a wallet based on a wallet Resource Locator (WRL). + * + * PARAMETERS + * osscntxt {IN} OSS context. + * wrllen {IN} Length of WRL. + * wrl {IN} WRL. + * pwdlen {IN} Length of password. + * pwd {IN} Password. + * wallet {IN/OUT} Initialized wallet structure. + * + * NOTES + * The syntax for a WRL is :. + * + * Wallet Type Wallet Type Parameters. + * ----------- ---------------------- + * File Pathname (e.g. "file:/home/asriniva") + * Oracle Connect string (e.g. "oracle:scott/tiger@oss") + * + * There are also defaults. If the WRL is NZT_DEFAULT_WRL, then + * the platform specific WRL default is used. If only the wallet + * type is specified, then the WRL type specific default is used + * (e.g. "oracle:") + * + * There is an implication with Oracle that should be stated: An + * Oracle based wallet can be implemented in a user's private space + * or in world readable space. + * + * When the wallet is opened, the password is verified by hashing + * it and comparing against the password hash stored with the + * wallet. The list of personas (and their associated identities) + * is built and stored into the wallet structure. + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_RIO_OPEN RIO could not open wallet (see network trace file). + * NZERROR_TK_PASSWORD Password verification failed. + * NZERROR_TK_WRLTYPE WRL type is not known. + * NZERROR_TK_WRLPARM WRL parm does not match type. + */ +nzerror nztwOpenWallet( nzctx *, ub4, text *, ub4, text *, + nzttWallet * ); + + +/*---------------------- nztwCloseWallet ----------------------*/ + +/* + * NAME + * nztwCloseWallet - Close a wallet + * + * PARAMETERS + * osscntxt {IN} OSS context. + * wallet {IN/OUT} Wallet. + * + * NOTES + * Closing a wallet also closes all personas associated with that + * wallet. It does not cause a persona to automatically be saved + * if it has changed. The implication is that a persona can be + * modified by an application but if it is not explicitly saved it + * reverts back to what was in the wallet. + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_RIO_CLOSE RIO could not close wallet (see network trace file). + */ +nzerror nztwCloseWallet( nzctx *, nzttWallet * ); + +/*--------------------nztwGetCertInfo----------------------------*/ +/****NOTE: This function is a temporary hack.****/ +/****DO NOT CALL. It will soon disappear.****/ +nzerror nztwGetCertInfo( nzctx *nz_context, + nzosContext *nzosCtx, + nzttWallet *walletRef, + void *peerCert ); + + +/*------------------------ nztwConstructWallet -----------------------*/ +/* + * + * nzerror nztwConstructWallet( nzctx *oss_context, + * nzttPolicy openPolicy, + * nzttPolicy securePolicy, + * ub1 *ldapName, + * ub4 ldapNamelen, + * nzstrc *wrl, + * nzttPersona *personas, + * nzttWallet **wallet ); + */ + +/*---------------------- nztwRetrievePersonaCopy ----------------------*/ + +/* + * NAME + * nztwRetrievePersonaCopy - Retrieves a persona based from wallet + * + * PARAMETERS + * osscntxt {IN} OSS context. + * wallet {IN} Wallet. + * index {IN} Which wallet index to remove (first persona is zero). + * persona {OUT} Persona found. + * + * NOTES + * Retrieves a persona from the wallet based on the index number passed + * in. This persona is a COPY of the one stored in the wallet, therefore + * it is perfectly fine for the wallet to be closed after this call is + * made. + * + * The caller is responsible for disposing of the persona when completed. + * + * RETURNS + * NZERROR_OK Success. + */ +nzerror nztwRetrievePersonaCopy( nzctx *, nzttWallet *, ub4, + nzttPersona ** ); + + +/*---------------------- nztwRetrievePersonaCopyByName ----------------------*/ + +/* + * NAME + * nztwRetrievePersonaCopyByName - Retrieves a persona based on its name. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * wallet {IN} Wallet. + * name {IN} Name of the persona + * persona {OUT} Persona found. + * + * NOTES + * Retrieves a persona from the wallet based on the name of the persona. + * This persona is a COPY of the one stored in the wallet, therefore + * it is perfectly fine for the wallet to be closed after this call is + * made. + * + * The caller is responsible for disposing of the persona when completed. + * + * RETURNS + * NZERROR_OK Success. + */ +nzerror nztwRetrievePersonaCopyByName( nzctx *, nzttWallet *, char *, + nzttPersona ** ); + +/*---------------------- nzteOpenPersona ----------------------*/ + +/* + * NAME + * nzteOpenPersona - Open a persona. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN/OUT} Persona. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_PASSWORD Password failed to decrypt persona. + * NZERROR_TK_BADPRL Persona resource locator did not work. + * NZERROR_RIO_OPEN Could not open persona (see network trace file). + */ +nzerror nzteOpenPersona( nzctx *, nzttPersona * ); + +/*--------------------- nzteClosePersona ---------------------*/ + +/* + * NAME + * nzteClosePersona - Close a persona. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN/OUT} Persona. + * + * NOTES + * Closing a persona does not store the persona, it simply releases + * the memory associated with the crypto engine. + * + * RETURNS + * NZERROR_OK Success. + */ +nzerror nzteClosePersona( nzctx *, nzttPersona * ); + +/*--------------------- nzteDestroyPersona ---------------------*/ + +/* + * NAME + * nzteDestroyPersona - Destroy a persona. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN/OUT} Persona. + * + * NOTES + * The persona is destroyd in the open state, but it will + * not be associated with a wallet. + * + * The persona parameter is doubly indirect so that at the + * conclusion of the function, the pointer can be set to NULL. + * + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_TYPE Unsupported itype/ctype combination. + * NZERROR_TK_PARMS Error in persona description. + */ +nzerror nzteDestroyPersona( nzctx *, nzttPersona ** ); + +/*---------------------- nzteRetrieveTrustedIdentCopy ----------------------*/ + +/* + * NAME + * nzteRetrieveTrustedIdentCopy - Retrieves a trusted identity from persona + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Persona. + * index {IN} Which wallet index to remove (first element is zero). + * identity {OUT} Trusted Identity from this persona. + * + * NOTES + * Retrieves a trusted identity from the persona based on the index + * number passed in. This identity is a COPY of the one stored in + * the persona, therefore it is perfectly fine to close the persona + * after this call is made. + * + * The caller is responsible for freeing the memory of this object + * by calling nztiAbortIdentity it is no longer needed + * + * RETURNS + * NZERROR_OK Success. + */ +nzerror nzteRetrieveTrustedIdentCopy( nzctx *, nzttPersona *, ub4, + nzttIdentity ** ); + +/*--------------------- nztePriKey ---------------------*/ + +/* + * NAME + * nztePriKey - Get the decrypted Private Key for the Persona + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Persona. + * vkey {OUT} Private Key [B_KEY_OBJ] + * vkey_len {OUT} Private Key Length + * + * NOTES + * This funiction will only work for X.509 based persona which contain + * a private key. + * A copy of the private key is returned to the caller so that they do not + * have to worry about the key changeing "underneath them". + * Memory will be allocated for the vkey and therefore, the CALLER + * will be responsible for freeing this memory. + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_NO_MEMORY ossctx is null. + * NZERROR_TK_BADPRL Persona resource locator did not work. + */ +nzerror nztePriKey( nzctx *, nzttPersona *, ub1 **, ub4 * ); + +/*--------------------- nzteMyCert ---------------------*/ + +/* + * NAME + * nzteMyCert - Get the X.509 Certificate for a persona + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Persona. + * cert {OUT} X.509 Certificate [BER encoded] + * cert_len {OUT} Certificate length + * + * NOTES + * This funiction will only work for X.509 based persona which contain + * a certificate for the self identity. + * A copy of the certificate is returned to the caller so that they do not + * have to worry about the certificate changeing "underneath them". + * Memory will be allocated for the cert and therefore, the CALLER + * will be responsible for freeing this memory. + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_NO_MEMORY ossctx is null. + */ +nzerror nzteMyCert( nzctx *, nzttPersona *, ub1 **, ub4 * ); + +/*--------------------- nzteX509CreatePersona ---------------------*/ + +/* + * NAME + * nzteX509CreatePersona - Given a BER X.509 cert, create a persona + * + * PARAMETERS + * osscntxt {IN} OSS context. + * cert {IN} X.509 Certificate [BER encoded] + * cert_len {IN} Certificate length + * persona {OUT} Persona. + * + * NOTES + * Memory will be allocated for the persona and therefore, the CALLER + * will be responsible for freeing this memory. + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_NO_MEMORY ossctx is null. + */ +nzerror nzteX509CreatePersona( nzctx *, ub1 *, ub4, nzttPersona ** ); + +/*-------------------- nztiCreateIdentity --------------------*/ + +/* + * NAME + * nztiCreateIdentity - Create an identity. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * itype {IN} Identity type. + * desc {IN} Description of identity. + * identity {IN/OUT} Identity. + * + * NOTES + * Memory is only allocated for the identity structure. The elements in + * the description struct are not copied. Rather their pointers are copied + * into the identity structure. Therefore, the caller should not free + * the elements referenced by the desc. These elements will be freed + * when the nztiDestroyIdentity is called. + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_PARMS Error in description. + */ +nzerror nztiCreateIdentity( nzctx *, nzttVersion, nzttIdentityDesc *, + nzttIdentity ** ); + +#ifdef NZ_OLD_TOOLS +/*-------------------- nztiDuplicateIdentity --------------------*/ + +/* + * NAME + * nztiDuplicateIdentity - Duplicate an identity. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * identity {IN} Target Identity. + * new_identity {IN} New Identity. + * + * NOTES + * Memory for the identity is allocated inside the function, and all + * internal identity elements as well. + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_NOTFOUND Identity not found. + * NZERROR_PARMS Error in description. + */ +nzerror nztiDuplicateIdentity( nzctx *, nzttIdentity *, + nzttIdentity ** ); +#endif /* NZ_OLD_TOOLS */ + +/*--------------------- nztiAbortIdentity ---------------------*/ + +/* + * NAME + * nztiAbortIdentity - Abort an unassociated identity. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * identity {IN/OUT} Identity. + * + * NOTES + * It is an error to try to abort an identity that can be + * referenced through a persona. + * + * The identity pointer is set to NULL at the conclusion. + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_CANTABORT Identity is associated with persona. + */ +nzerror nztiAbortIdentity( nzctx *, nzttIdentity ** ); + +#ifdef NZ_OLD_TOOLS +/*----------------- nztidGetIdentityDesc -----------------*/ + +/* + * NAME + * nztidGetIdentityDesc - Gets an Identity Description from the identity + * + * PARAMETERS + * osscntxt {IN} Success. + * identity {IN} Identity. + * description {IN/OUT} Identity Description. + * + * NOTES + * Memory is allocated for the Identity Description. It + * is the callers responsibility to free this memory by calling + * nztiFreeIdentityDesc. + * + * RETURNS + * NZERROR_OK Success. + */ +nzerror nztidGetIdentityDesc( nzctx *, nzttIdentity *, + nzttIdentityDesc ** ); + +/*----------------- nztidFreeIdentityDesc -----------------*/ + +/* + * NAME + * nztidFreeIdentityDesc - Frees memory for Identity Desc object. + * + * PARAMETERS + * osscntxt {IN} oss context. + * description {IN/OUT} Identity Description. + * + * NOTES + * Memory is freed for all Identity description elements. Pointer is + * then set to null. + * + * RETURNS + * NZERROR_OK Success. + */ +nzerror nztidFreeIdentityDesc( nzctx *, nzttIdentityDesc ** ); +#endif /* NZ_OLD_TOOLS */ + +/*---------------- nztific_FreeIdentityContent ----------------*/ + +/* + * NAME + * nztific_FreeIdentityContent - free the contents of an identity. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * identity {IN/OUT} freed identity + * + * NOTES + * Free a created identity. + * + * RETURNS + * NZERROR_OK Success. + */ +/* + * Free the identity content. + */ +nzerror nztific_FreeIdentityContent( nzctx *ossctx, + nzttIdentity *identity ); + + +/*-------------------------- nztSign --------------------------*/ + +/* + * NAME + * nztSign - Create an attached signature. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Open persona acting as signer. + * state {IN} State of signature. + * inlen {IN} Length of this input part. + * in {IN} This input part. + * tdubuf {IN/OUT} TDU buffer. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_CANTGROW Needed to grow output buffer but could not. + * NZERROR_TK_NOTOPEN Persona is not open. + * NZERROR_TK_NOTSUPP Function not supported with persona. + */ +nzerror nztSign( nzctx *, nzttPersona *, nzttces, ub4, ub1 *, + nzttBufferBlock * ); + +/*------------------------- nztVerify -------------------------*/ + +/* + * NAME + * nztVerify - Verify an attached signature. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Persona. + * state {IN} State of verification. + * intdulen {IN} TDU length. + * intdu {IN} TDU. + * out {IN/OUT} Extracted message. + * verified {OUT} TRUE if signature verified. + * validated{OUT} TRUE if signing identity validated. + * identity {OUT} Identity of signing party. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_CANTGROW Needed to grow outptu buffer but could not. + * NZERROR_TK_NOTOPEN Persona is not open. + * NZERROR_TK_NOTSUPP Function not supported with persona. + */ +nzerror nztVerify( nzctx *, nzttPersona *, nzttces, ub4, ub1 *, + nzttBufferBlock *, boolean *, boolean *, + nzttIdentity ** ); + +/*------------------------ nztValidate ------------------------*/ + +/* + * NAME + * nztValidate - Validate an identity. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Persona. + * identity {IN} Identity. + * validated{OUT} TRUE if identity was validated. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_NOTOPEN Persona is not open. + * NZERROR_TK_NOTSUPP Function not supported with persona. + */ +nzerror nztValidate( nzctx *, nzttPersona *, nzttIdentity *, boolean * ); + +/*-------------------- nztsd_SignDetached --------------------*/ + +/* + * NAME + * nztsd_SignDetached - Generate a detached signature. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Persona. + * state {IN} State of signature. + * inlen {IN} Length of this input part. + * in {IN} This input part. + * tdubuf {IN/OUT} TDU buffer. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_CANTGROW Needed to grow output buffer but could not. + * NZERROR_TK_NOTOPEN Persona is not open. + * NZERROR_TK_NOTSUPP Function not supported with persona. + */ +nzerror nztsd_SignDetached( nzctx *, nzttPersona *, nzttces, ub4, ub1 *, + nzttBufferBlock * ); + +/*------------------- nztved_VerifyDetached -------------------*/ + +/* + * NAME + * nztved_VerifyDetached - Verify a detached signature. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Persona. + * state {IN} State of verification. + * inlen {IN} Length of data. + * in {IN} Data. + * intdulen {IN} Input TDU length. + * tdu {IN} Input TDU. + * verified {OUT} TRUE if signature verified. + * validated{OUT} TRUE if signing identity validated. + * identity {OUT} Identity of signing party. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_NOTOPEN Persona is not open. + * NZERROR_TK_NOTSUPP Function not supported with persona. + */ +nzerror nztved_VerifyDetached( nzctx *, nzttPersona *, nzttces, ub4, + ub1 *, ub4, ub1 *, boolean *, boolean *, + nzttIdentity ** ); + +/*--------------------- nztkec_PKEncrypt ---------------------*/ + +/* + * NAME + * nztkec_PKEncrypt - Encrypt data symmetrically, encrypt key asymmetrically + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Persona. + * nrecipients {IN} Number of recipients for this encryption. + * recipients {IN} List of recipients. + * state {IN} State of encryption. + * inlen {IN} Length of this input part. + * in {IN} This input part. + * tdubuf {IN/OUT} TDU buffer. + * + * NOTES + * There is a limitation of 1 recipient (nrecipients = 1) at this + * time. + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_CANTGROW Needed to grow output buffer but could not. + * NZERROR_TK_NOTOPEN Persona is not open. + * NZERROR_TK_NOTSUPP Function not supported with persona. + */ +nzerror nztkec_PKEncrypt( nzctx *, nzttPersona *, ub4, nzttIdentity *, + nzttces, ub4, ub1 *, nzttBufferBlock * ); + +/*---------------- nztxkec_PKEncryptExpansion ----------------*/ + +/* + * NAME + * nztxkec_PKEncryptExpansion - Determine the buffer needed for PKEncrypt + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Persona. + * nrecipients {IN} Number of recipients. + * inlen {IN} Length of input. + * tdulen {out} Length of buffer need. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_NOTOPEN Persona is not open. + * NZERROR_TK_NOTSUPP Function not supported with persona. + */ +nzerror nztxkec_PKEncryptExpansion( nzctx *, nzttPersona *, ub4, ub4, + ub4 * ); + +/*--------------------- nztkdc_PKDecrypt ---------------------*/ + +/* + * NAME + * nztkdc_PKDecrypt - Decrypt a PKEncrypted message. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Persona. + * state {IN} State of encryption. + * inlen {IN} Length of this input part. + * in {IN} This input part. + * tdubuf {IN/OUT} TDU buffer. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_CANTGROW Needed to grow output buffer but could not. + * NZERROR_TK_NOTOPEN Persona is not open. + * NZERROR_TK_NOTSUPP Function not supported with persona. + */ +nzerror nztkdc_PKDecrypt( nzctx *, nzttPersona *, nzttces, ub4, ub1 *, + nzttBufferBlock * ); + +/*-------------------------- nztHash --------------------------*/ + +/* + * NAME + * nztHash - Generate a hash. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Persona. + * state {IN} State of hash. + * inlen {IN} Length of this input. + * in {IN} This input. + * tdu {IN/OUT} Output tdu. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_CANTGROW Needed to grow TDU buffer but could not. + * NZERROR_TK_NOTOPEN Persona is not open. + * NZERROR_TK_NOTSUPP Function not supported with persona. + */ +nzerror nztHash( nzctx *, nzttPersona *, nzttces, ub4, ub1 *, + nzttBufferBlock * ); + +/*----------------------- nztSeedRandom -----------------------*/ + +/* + * NAME + * nztSeedRandom - Seed the random function + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Persona. + * seedlen {IN} Length of seed. + * seed {IN} Seed. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_NOTOPEN Persona is not open. + * NZERROR_TK_NOTSUPP Function not supported with persona. + */ +nzerror nztSeedRandom( nzctx *, nzttPersona *, ub4, ub1 * ); + +/*--------------------- nztrb_RandomBytes ---------------------*/ + +/* + * NAME + * nztrb_RandomBytes - Generate a buffer random bytes. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Persona. + * nbytes {IN} Number of bytes desired. + * out {IN/OUT} Buffer block for bytes. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_CANTGROW Needed to grow TDU buffer but could not. + * NZERROR_TK_NOTOPEN Persona is not open. + * NZERROR_TK_NOTSUPP Function not supported with persona. + */ +nzerror nztrb_RandomBytes( nzctx *, nzttPersona *, ub4, + nzttBufferBlock * ); + +/*-------------------- nztrn_RandomNumber --------------------*/ + +/* + * NAME + * nztrn_RandomNumber - Generate a random number + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Persona. + * num {OUT} Number. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_NOTOPEN Persona is not open. + * NZERROR_TK_NOTSUPP Function not supported with persona. + */ +nzerror nztrn_RandomNumber( nzctx *, nzttPersona *, uword * ); + +/*---------------------- nztbbInitBlock ----------------------*/ + +/* + * NAME + * nztbbInitBlock - Initialize a buffer block. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * block {IN/OUT} Buffer block. + * + * NOTES + * The buffer block is initialized to be empty (all members are set + * to 0/NULL). Such a block will be allocated memory as needed. + * + * RETURNS + * NZERROR_OK Success. + */ +nzerror nztbbInitBlock( nzctx *, nzttBufferBlock * ); + +/*---------------------- nztbbReuseBlock ----------------------*/ + +/* + * NAME + * nztbbReuseBlock - Reuse an already initialized and possibly used block. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * block {IN/OUT} Buffer block. + * + * NOTES + * This function simply sets the used length member of the buffer + * block to 0. If the block already has memory allocated to it, + * this will cause it to be reused. + * + * RETURNS + * NZERROR_OK Success. + */ +nzerror nztbbReuseBlock( nzctx *, nzttBufferBlock * ); + +/*---------------------- nztbbSizeBlock ----------------------*/ + +/* + * NAME + * nztbbSizeBlock - Size an initialized block to a particular size. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * len {IN} Minimum number of unused bytes desired. + * block {IN/OUT} Buffer block. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + */ +nzerror nztbbSizeBlock( nzctx *, ub4, nzttBufferBlock * ); + +/*----------------------- nztbbGrowBlock -----------------------*/ + +/* + * NAME + * nzbbGrowBlock - Increase the size of the buffer block. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * inc {IN} Number of bytes to increase. + * block {IN/OUT} Buffer block. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + */ +nzerror nztbbGrowBlock( nzctx *, ub4, nzttBufferBlock * ); + +/*---------------------- nztbbPurgeBlock ----------------------*/ + +/* + * NAME + * nztbbPurgeBlock - Purge a buffer block of its memory. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * block {IN/OUT} Buffer block. + * + * NOTES + * The memory used by the buffer block as the buffer is released. + * The buffer block itself is not affected. + * + * RETURNS + * NZERROR_OK Success. + */ +nzerror nztbbPurgeBlock( nzctx *, nzttBufferBlock * ); + +/*----------------------- nztbbSetBlock -----------------------*/ + +/* + * NAME + * nztbbSetBlock - Set a buffer block to a known state. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * flags {IN} Flags to set. + * buflen {IN} Length of buffer. + * usedlen {IN} Used length. + * buffer {IN} Buffer. + * block {IN/OUT} Buffer block + * + * NOTES + * If buflen > 0, objlen == 0, and obj == NULL, then buflen bytes + * of memory is allocated and a pointer is stored in the buffer + * block. + * + * The buffer parameter remains unchanged. + * + * RETURNS + * NZERROR_OK Success. + */ +nzerror nztbbSetBlock( nzctx *, uword, ub4, ub4, ub1 *, + nzttBufferBlock * ); + + +/*--------------------- nztiGetSecInfo ---------------------*/ + +/* + * NAME + * nztiGetSecInfo - Get some security information for SSL + * + * PARAMETERS + * Name {IN/OUT} Description + * osscntxt {IN} OSS context. + * persona {IN} persona + * dname {OUT} distinguished name of the certificate + * dnamelen {OUT} length of the distinguished name + * issuername {OUT} issuer name of the certificate + * certhash {OUT} SHA1 hash of the certificate + * certhashlen{OUT} length of the hash + * NOTES + * This function allocate memories for issuername, certhash, and dname. + * To deallocate memory for those params, you should call nztdbuf_DestroyBuf. + * RETURNS + * + */ +nzerror nztiGetSecInfo( nzctx *, nzttPersona *, text **, ub4 *, + text **, ub4 *, ub1 **, ub4 * ); + + +/*---------------------- nztiGetDName ----------------------*/ + +/* + * NAME + * nztiGetDName - Get the distinguished name for the given identity + * + * PARAMETERS + * Name {IN/OUT} Description + * osscntxt {IN} OSS context. + * identity {IN} identity need to get dname from + * dn {OUT} distinguished name + * dnlen {OUT} length of the dname + * + * NOTES + * + * RETURNS + * + */ + +nzerror nztiGetDName( nzctx *, nzttIdentity *, + text **, ub4 * ); + +/*------------------- nztiGetIssuerName -------------------*/ + +/* + * NAME + * nztiGetIssuerName - Get IssuerName for the given identity + * + * PARAMETERS + * Name {IN/OUT} Description + * osscntxt {IN} OSS context. + * identity {IN} identity need to get issuername from + * issuername {OUT} issuer's name + * issuernamelen {OUT} length of the issuer's name + * + * NOTES + * + * RETURNS + * + */ +nzerror nztiGetIssuerName( nzctx *, nzttIdentity *, + text **, ub4 * ); + + +/*-------------------- nztgch_GetCertHash --------------------*/ + +/* + * NAME + * nztgch_GetCertHash - Get SHA1 hash for the certificate of the identity + * + * PARAMETERS + * Name {IN/OUT} Description + * osscntxt {IN} OSS context. + * identity {IN} identity need to get issuername from + * certHash {OUT} certHash buffer + * hashLen {OUT} length of the certHash + * + * NOTES + * Need to call nztdbuf_DestroyBuf to deallocate memory for certHash. + * RETURNS + * + */ +nzerror nztgch_GetCertHash( nzctx *, nzttIdentity *, + ub1 **, ub4 * ); + +/*-------------------- nztdbuf_DestroyBuf --------------------*/ + +/* + * NAME + * nztdbuf_DestroyBuf - Deallocation funtions for ub1 and text buffer + * + * PARAMETERS + * Name {IN/OUT} Description + * osscntxt {IN} OSS context. + * buf {IN} Allocated buffer to be destroyed. + * + * NOTES + * + * RETURNS + * + */ +nzerror nztdbuf_DestroyBuf( nzctx *, void ** ); + + +/*----------------------- nztGetCertChain -----------------------*/ + +/* + * NAME + * nztGetCertChain - + * + * PARAMETERS + * Name {IN/OUT} Description + * osscntxt {IN} OSS context. + * + * NOTES + * + * RETURNS + * + */ +nzerror nztGetCertChain( nzctx *, nzttWallet * ); + +/*----------------------- nztCompareDN -----------------------*/ + +/* + * NAME + * nztCompareDN - + * + * PARAMETERS + * Name {IN/OUT} Description + * osscntxt {IN} OSS context. + * dn1 {IN} distinguished name 1 + * dn2 {IN} distinguished name 2 + * + * NOTES + * + * RETURNS + * NZERROR_OK succeeded + * others failed + * + */ +nzerror nztCompareDN( nzctx *, ub1 *,ub4 , ub1 *, ub4, boolean * ); + + +#ifdef NZ_OLD_TOOLS +/*--------------------- nztIdentityAlloc ---------------------*/ + +/* + * NAME + * nztIdentityAlloc - Allocate memory for nzttIdentity context + * + * PARAMETERS + * Name {IN/OUT} Description + * osscntxt {IN} OSS context. + * identity {OUT} nzttIdentity context + * + * NOTES + * + * RETURNS + * NZERROR_OK succeeded + * others failed + * + */ +nzerror nztIdentityAlloc( nzctx *, nzttIdentity ** ); + +/*--------------------- nztIPrivateAlloc ---------------------*/ + +/* + * NAME + * nztIPrivateAlloc - Allocate memory for nzttIdentityPrivate + * + * PARAMETERS + * Name {IN/OUT} Description + * + * osscntxt {IN} OSS context. + * ipriv {OUT} identityPrivate structure + * NOTES + * + * RETURNS + * NZERROR_OK succeeded + * others failed + * + */ + +nzerror nztIPrivateAlloc( nzctx *, nzttIdentityPrivate **); + + +/*---------------------- nztIDupContent ----------------------*/ + +/* + * NAME + * nztIDupContent - + * + * PARAMETERS + * Name {IN/OUT} Description + * osscntxt {IN} OSS context. + * targetIdentity{OUT} target identity + * sourceIdentity {IN} source identity + * NOTES + * + * RETURNS + * NZERROR_OK succeeded + * others failed + * + */ + +nzerror nztIDupContent( nzctx *, nzttIdentity *, nzttIdentity * ); +/*---------------------- nztIPDuplicate ----------------------*/ + +/* + * NAME + * nztIPDuplicate - + * + * PARAMETERS + * Name {IN/OUT} Description + * osscntxt {IN} OSS context. + * target_ipriv {OUT} target identityPrivate + * source_ipriv {IN} source identityPrivate + * + * NOTES + * + * RETURNS + * NZERROR_OK succeeded + * others failed + * + */ +nzerror nztIPDuplicate( nzctx *, nzttIdentityPrivate **, + nzttIdentityPrivate * ); + +/*--------------------- nztiDupIdentList ---------------------*/ + +/* + * NAME + * nztiDupIdentList - + * + * PARAMETERS + * Name {IN/OUT} Description + * osscntxt {IN} OSS context. + * source_identities {IN} source identity list + * numIdent {OUT} number of identity in the list + * ppidentity {OUT} Target of identity + * + * NOTES + * + * RETURNS + * NZERROR_OK succeeded + * others failed + * + */ +nzerror nztiDupIdentList( nzctx *, nzttIdentity *, ub4 *, + nzttIdentity ** ); + +/*--------------------- nztFreeIdentList ---------------------*/ + +/* + * NAME + * nztFreeIdentList - Free memory for a list of Identities + * + * PARAMETERS + * Name {IN/OUT} Description + * osscntxt {IN} OSS context. + * identity {IN} identity context + * + * NOTES + * + * RETURNS + * NZERROR_OK succeeded + * others failed + * + */ +nzerror nztFreeIdentList( nzctx *, nzttIdentity ** ); +#endif /* NZ_OLD_TOOLS */ + +/*--------------------- nztCheckVaLidity ---------------------*/ + +/* + * NAME + * nztCheckVaLidity - Check the validity of certificate + * + * PARAMETERS + * Name {IN/OUT} Description + * osscntxt {IN} OSS context. + * start_time Start time of the certificate + * end_time End time of the certificate + * + * NOTES + * + * RETURNS + * NZERROR_OK succeeded + * others failed + * + */ +nzerror nztCheckValidity( nzctx *, ub4 , ub4 ); + +/*--------------------- nztwCreateWallet ---------------------*/ + +/* + * NAME + * nztwCreateWallet - Create a new wallet. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * wrllen {IN} Length of wallet resource locator. + * wrl {IN} WRL. + * pwdlen {IN} Length of password (see notes below). + * pwd {IN} Password. + * wallet {IN/OUT} Wallet. + * + * NOTES + * It is an error to try to create a wallet that already exists. + * The previously existing wallet must be destroyed first. + * + * The wallet itself is not encrypted. Rather, all the personas in + * the wallet are encrypted under the same password. A hash of the + * password is stored in the wallet. + * + * Upon success, an empty open wallet is stored in the wallet + * parameter. + * + * RETURNS + * NZERROR_OK Sucess. + * NZERROR_TK_WALLET_EXISTS Wallet already exists. + * NZERROR_RIO_OPEN RIO could not create wallet (see trace file). + */ +nzerror nztwCreateWallet( nzctx *, ub4, text *, ub4, text *, + nzttWallet * ); + + +/*--------------------- nztwDestroyWallet ---------------------*/ + +/* + * NAME + * nztwDestroyWallet - Destroy an existing wallet. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * wrllen {IN} Length of wallet resource locator. + * wrl {IN} WRL. + * pwdlen {IN} Length of password. + * pwd {IN} Password. + * NOTES + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_PASSWORD Password verification failed. + * NZERROR_RIO_OPEN RIO could not open wallet (see trace file). + * NZERROR_RIO_DELETE Delete failed (see trace file). + */ +nzerror nztwDestroyWallet( nzctx *, ub4, text *, ub4, text * ); + +/*--------------------- nzteStorePersona ---------------------*/ + +/* + * NAME + * nzteStorePersona - Store an open persona in a wallet. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN/OUT} Persona. + * wallet {IN/OUT} Wallet. + * + * NOTES + * If the open persona is not associated with any wallet (it was + * created via the nzteClosePersona function), then storing the + * persona creates that association. The wallet will also have an + * updated persona list that reflects this association. + * + * If the open persona was associated with wallet 'A' (it was + * opened via the nztwOpenWallet function), and is stored back into + * wallet 'A', then then the old persona is overwritten by the new + * persona if the password can be verified. Recall that all + * personas have a unique identity id. If that id changes then + * storing the persona will put a new persona in the wallet. + * + * If the open persona was associated with wallet 'A' and is stored + * into wallet 'B', and if wallet 'B' does not contain a persona + * with that unique identity id, then the persona will be copied + * into wallet 'B', wallet 'B''s persona list will be updated, and + * the persona structure will be updated to be associated with + * wallet 'B'. If wallet 'B' already contained the persona, it + * would be overwritten by the new persona. + * + * The persona parameter is doubly indirect so that at the + * conclusion of the function call, the pointer can be directed to + * the persona in the wallet. + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_PASSWORD Password verification failed. + * NZERROR_RIO_STORE Store failed (see network trace file). + */ +nzerror nzteStorePersona( nzctx *, nzttPersona **, nzttWallet * ); + +/*--------------------- nzteRemovePersona ---------------------*/ + +/* + * NAME + * nzteRemovePersona - Remove a persona from the wallet. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN/OUT} Persona. + * + * NOTES + * The password is verified before trying to remove the persona. + * + * If the persona is open, it is closed. The persona is removed + * from the wallet list and the persona pointer is set to NULL. + * + * A double indirect pointer to the persona is required so that the + * persona pointer can be set to NULL upon completion. + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_PASSWORD Password verification failed. + * NZERROR_RIO_DELETE Delete failed. + */ +nzerror nzteRemovePersona( nzctx *, nzttPersona ** ); + +/*--------------------- nzteCreatePersona ---------------------*/ + +/* + * NAME + * nzteCreatePersona - Create a persona. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * itype {IN} Identity type. + * ctype {IN} Cipher type. + * desc {IN} Persona description. + * persona {OUT} Persona. + * + * NOTES + * The resulting persona is created in the open state, but it will + * not be associated with a wallet. + * + * The memory for the persona is allocated by the function. + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_TYPE Unsupported itype/ctype combination. + * NZERROR_TK_PARMS Error in persona description. + */ +nzerror nzteCreatePersona( nzctx *, nzttVersion, nzttCipherType, + nzttPersonaDesc *, nzttPersona ** ); + + +/*----------------- nztiStoreTrustedIdentity -----------------*/ + +/* + * NAME + * nztiStoreTrustedIdentity - Store an identity into a persona. + * + * PARAMETERS + * osscntxt {IN} Success. + * identity {IN/OUT} Trusted Identity. + * persona {IN/OUT} Persona. + * + * NOTES + * The identity is not saved with the persona in the wallet until + * the persona is stored. + * + * The identity parameter is double indirect so that it can point + * into the persona at the conclusion of the call. + * + * RETURNS + * NZERROR_OK Success. + */ +nzerror nztiStoreTrustedIdentity( nzctx *, nzttIdentity **, + nzttPersona * ); + +/*--------------------- nzteSetProtection ---------------------*/ + +/* + * NAME + * nzteSetProtection - Set the protection type for a CE function. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN/OUT} Persona. + * func {IN} CE function. + * tdufmt {IN} TDU Format. + * protinfo {IN} Protection information specific to this format. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_PROTECTION Unsupported protection. + * NZERROR_TK_PARMS Error in protection info. + */ +nzerror nzteSetProtection( nzctx *, nzttPersona *, nzttcef, nztttdufmt, + nzttProtInfo * ); + +/*--------------------- nzteGetProtection ---------------------*/ + +/* + * NAME + * nzteGetProtection - Get the protection type for a CE function. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Persona. + * func {IN} CE function. + * tdufmt {OUT} TDU format. + * protinfo {OUT} Protection information. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + */ +nzerror nzteGetProtection( nzctx *, nzttPersona *, nzttcef, nztttdufmt *, + nzttProtInfo * ); + +/*-------------------- nztiRemoveIdentity --------------------*/ + +/* + * NAME + * nztiRemoveIdentity - Remove an identity from an open persona. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * identity {IN/OUT} Identity. + * + * NOTES + * If the persona is not stored, this identity will still be in the + * persona stored in the wallet. + * + * The identity parameter is doubly indirect so that at the + * conclusion of the function, the pointer can be set to NULL. + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_NOTFOUND Identity not found. + * NZERROR_TK_NOTOPEN Persona is not open. + */ +nzerror nztiRemoveIdentity( nzctx *, nzttIdentity ** ); + +/*----------------- nztifdn -----------------*/ + +/* + * NAME + * nztifdn - create an Identity From a Distinguished Name + * + * PARAMETERS + * osscntxt {IN} OSS context. + * length {IN} Length of the distinguished name + * distinguished_name {IN} distinguished name string + * ppidentity {OUT} created identity + * + * NOTES + * Given a distinguished name, return the identity that corresponds to it. + * + * RETURNS + * NZERROR_OK Success. + */ +nzerror nztifdn( nzctx *ossctx, + ub4 length, + text *distinguished_name, + nzttIdentity **ppidentity ); + +/*--------------------- nztxSignExpansion ---------------------*/ + +/* + * NAME + * nztxSignExpansion - Determine the size of the attached signature buffer. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Persona. + * inlen {IN} Length of input. + * tdulen {OUT} Buffer needed for signature. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_NOTOPEN Persona is not open. + * NZERROR_TK_NOTSUPP Function not supported with persona. + */ +nzerror nztxSignExpansion( nzctx *, nzttPersona *, ub4, ub4 * ); + +/*--------------- nztxsd_SignDetachedExpansion ---------------*/ + +/* + * NAME + * nztxsd_SignDetachedExpansion - Determine the size of buffer needed. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Persona. + * inlen {IN} Length of input. + * tdulen {OUT} Buffer needed for signature. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_NOTOPEN Persona is not open. + * NZERROR_TK_NOTSUPP Function not supported with persona. + */ +nzerror nztxsd_SignDetachedExpansion( nzctx *, nzttPersona *, ub4, + ub4 * ); + +/*------------------------ nztEncrypt ------------------------*/ + +/* + * NAME + * nztEncrypt - Symmetrically encrypt + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Persona. + * inlen {IN} Length of this input part. + * in {IN} This input part. + * tdubuf {IN/OUT} TDU buffer. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_CANTGROW Needed to grow TDU buffer but could not. + * NZERROR_TK_NOTOPEN Persona is not open. + * NZERROR_TK_NOTSUPP Function not supported with persona. + */ +nzerror nztEncrypt( nzctx *, nzttPersona *, nzttces, ub4, ub1 *, + nzttBufferBlock * ); + +/*------------------- nztxEncryptExpansion -------------------*/ + +/* + * NAME + * nztxEncryptExpansion - Determine the size of the TDU to encrypt. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Persona. + * inlen {IN} Length of this input part. + * tdulen {OUT} Length of TDU. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_NOTOPEN Persona is not open. + * NZERROR_TK_NOTSUPP Function not supported with persona. + */ +nzerror nztxEncryptExpansion( nzctx *, nzttPersona *, ub4, ub4 * ); + +/*------------------------ nztDecrypt ------------------------*/ + +/* + * NAME + * nztDecrypt - Decrypt an Encrypted message. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Persona. + * state {IN} State of decryption. + * inlen {IN} Length of this input part. + * in {IN} This input part. + * out {IN/OUT} Cleartext message. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_CANTGROW Needed to grow TDU buffer but could not. + * NZERROR_TK_NOTOPEN Persona is not open. + * NZERROR_TK_NOTSUPP Function not supported with persona. + */ +nzerror nztDecrypt( nzctx *, nzttPersona *, nzttces, ub4, ub1 *, + nzttBufferBlock * ); + +/*------------------------ nztEnvelope ------------------------*/ + +/* + * NAME + * nztEnvelope - Sign and PKEncrypt a message. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Persona. + * nrecipients {IN} Number of recipients for this encryption. + * recipients {IN} List of recipients. + * state {IN} State of encryption. + * inlen {IN} Length of this input part. + * in {IN} This input part. + * tdubuf {IN/OUT} TDU buffer. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_CANTGROW Needed to grow output buffer but could not. + * NZERROR_TK_NOTOPEN Persona is not open. + * NZERROR_TK_NOTSUPP Function not supported with persona. + */ +nzerror nztEnvelope( nzctx *, nzttPersona *, ub4, nzttIdentity *, + nzttces, ub4, ub1 *, nzttBufferBlock * ); + +/*----------------------- nztDeEnvelope -----------------------*/ + +/* + * NAME + * nztDeEnvelope - PKDecrypt and verify a message. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Persona. + * state {IN} State of encryption. + * inlen {IN} Length of this input part. + * in {IN} This input part. + * out {OUT} Message from TDU. + * verified {OUT} TRUE if verified. + * validated {OUT} TRUE if validated. + * sender {OUT} Identity of sender. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_CANTGROW Needed to grow TDU buffer but could not. + * NZERROR_TK_NOTOPEN Persona is not open. + * NZERROR_TK_NOTSUPP Function not supported with persona. + */ +nzerror nztDeEnvelope( nzctx *, nzttPersona *, nzttces, ub4, ub1 *, + nzttBufferBlock *, boolean *, boolean *, + nzttIdentity ** ); + +/*----------------------- nztKeyedHash -----------------------*/ + +/* + * NAME + * nztKeyedHash - Generate a keyed hash. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Persona. + * state {IN} State of hash. + * inlen {IN} Length of this input. + * in {IN} This input. + * tdu {IN/OUT} Output tdu. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_CANTGROW Needed to grow TDU buffer but could not. + * NZERROR_TK_NOTOPEN Persona is not open. + * NZERROR_TK_NOTSUPP Function not supported with persona. + */ +nzerror nztKeyedHash( nzctx *, nzttPersona *, nzttces, ub4, ub1 *, + nzttBufferBlock * ); + +/*------------------ nztxKeyedHashExpansion ------------------*/ + +/* + * NAME + * nztxKeyedHashExpansion - Determine the space needed for a keyed hash. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Persona. + * inlen {IN} Length of this input. + * tdulen {OUT} TDU length. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_NOTOPEN Persona is not open. + * NZERROR_TK_NOTSUPP Function not supported with persona. + */ +nzerror nztxKeyedHashExpansion( nzctx *, nzttPersona *, ub4, + ub4 * ); + +/*--------------------- nztxHashExpansion ---------------------*/ + +/* + * NAME + * nztxHashExpansion - Determine the size of the TDU for a hash. + * + * PARAMETERS + * osscntxt {IN} OSS context. + * persona {IN} Persona. + * inlen {IN} Length of this input. + * tdulen {OUT} TDU length. + * + * NOTES + * + * RETURNS + * NZERROR_OK Success. + * NZERROR_TK_NOTOPEN Persona is not open. + * NZERROR_TK_NOTSUPP Function not supported with persona. + */ +nzerror nztxHashExpansion( nzctx *, nzttPersona *, ub4, ub4 * ); + +/*---------------- nztiae_IsAuthEnabled ----------------*/ + +/* + * NAME + * nztiae_IsAuthEnabled - Checks to see if Authentication is Enabled + * in the current Cipher Spec. + * + * PARAMETERS + * ctx {IN} Oracle SSL Context + * ncipher {IN} CipherSuite + * authEnabled {OUT} Boolean for is Auth Enabled? + * + * NOTES + * + * RETURNS + * NZERROR_OK on success. + * NZERROR_TK_INV_CIPHR_TYPE if Cipher Spec is not Recognized. + */ + +nzerror nztiae_IsAuthEnabled( nzctx *ctx, + ub2 ncipher, + boolean *authEnabled ); + +/*---------------- nztiee_IsEncrEnabled ----------------*/ +/* + * NAME + * nztiee_IsEncrEnabled - Checks to see if Encryption is Enabled + * in the current Cipher Spec. + * + * PARAMETERS + * ctx {IN} Oracle SSL Context + * ncipher {IN} CipherSuite + * EncrEnabled {OUT} Boolean for is Auth Enabled? + * + * NOTES + * + * RETURNS + * NZERROR_OK on success. + * NZERROR_TK_INV_CIPHR_TYPE if Cipher Spec is not Recognized. + */ + +nzerror nztiee_IsEncrEnabled( nzctx *ctx, + ub2 ncipher, + boolean *EncrEnabled ); + +/*---------------- nztihe_IsHashEnabled ----------------*/ +/* + * NAME + * nztihe_IsHashEnabled - Checks to see if HAshing is Enabled + * in the current Cipher Spec. + * + * PARAMETERS + * ctx {IN} Oracle SSL Context + * ncipher {IN} CipherSuite + * hashEnabled {OUT} Boolean for is Auth Enabled? + * + * NOTES + * + * RETURNS + * NZERROR_OK on success. + * NZERROR_TK_INV_CIPHR_TYPE if Cipher Spec is not Recognized. + */ + +nzerror nztihe_IsHashEnabled( nzctx *ctx, + ub2 ncipher, + boolean *hashEnabled ); + +/* + * + */ + +nzerror nztGetIssuerName( nzctx *ctx, + nzttIdentity *identity, + ub1 **issuername, + ub4 *issuernamelen ); + +nzerror nztGetSubjectName( nzctx *ctx, + nzttIdentity *identity, + ub1 **subjectname, + ub4 *subjectnamelen ); + +nzerror nztGetBase64Cert( nzctx *ctx, + nzttIdentity *identity, + ub1 **b64cert, + ub4 *b64certlen ); + +nzerror nztGetSerialNumber( nzctx *ctx, + nzttIdentity *identity, + ub1 **serialnum, + ub4 *serialnumlen ); + +nzerror nztGetValidDate( nzctx *ctx, + nzttIdentity *identity, + ub4 *startdate, + ub4 *enddate ); + +nzerror nztGetVersion( nzctx *ctx, + nzttIdentity *identity, + nzstrc *pVerStr ); + +nzerror nztGetPublicKey( nzctx *ctx, + nzttIdentity *identity, + ub1 **pubKey, + ub4 *pubKeylen ); + +nzerror nztGenericDestroy( nzctx *ctx, + ub1 **var ); + +nzerror nztSetAppDefaultLocation( nzctx *ctx, + text *, + size_t ); + +nzerror nztSearchNZDefault( nzctx *ctx, + boolean *search ); + +nzerror nztSetLightWeight(nzctx *ctx, + boolean flag); + +#endif /* NZT_ORACLE */ + diff --git a/libodbc/include/ora_linux/occi.h b/libodbc/include/ora_linux/occi.h new file mode 100644 index 0000000000..e593341574 --- /dev/null +++ b/libodbc/include/ora_linux/occi.h @@ -0,0 +1,78 @@ +/* Copyright (c) 2000, 2002, Oracle Corporation. All rights reserved. */ + +/* + NAME + occi.h - Oracle C++ Interface header files. + + DESCRIPTION + + + RELATED DOCUMENTS + + + EXPORT FUNCTION(S) + + + INTERNAL FUNCTION(S) + + + EXAMPLES + + NOTES + + + MODIFIED (MM/DD/YY) + vvinay 08/19/02 - + aahluwal 06/03/02 - bug 2360115 + gayyappa 01/03/01 - removed inclusions before occiCommon.h + kmohan 04/11/00 - include oci.h and occiCommon.h also + rkasamse 04/03/00 - header file for all the OCCI classes + rkasamse 04/03/00 - Creation + +*/ + +#ifndef OCCI_ORACLE +# define OCCI_ORACLE + +#ifndef OCCICOMMON_ORACLE +#include +#endif + +#ifndef OCCIDATA_ORACLE +#include +#endif + +#ifndef OCCICONTROL_ORACLE +#include +#endif + +#ifndef OCCIOBJECTS_ORACLE +#include +#endif + +#ifndef OCCIAQ_ORACLE +#include +#endif + +/*--------------------------------------------------------------------------- + PUBLIC TYPES AND CONSTANTS + ---------------------------------------------------------------------------*/ + + +/*--------------------------------------------------------------------------- + PRIVATE TYPES AND CONSTANTS + ---------------------------------------------------------------------------*/ + + +/*--------------------------------------------------------------------------- + EXPORT FUNCTIONS + ---------------------------------------------------------------------------*/ + + +/*--------------------------------------------------------------------------- + INTERNAL FUNCTIONS + ---------------------------------------------------------------------------*/ + + +#endif /* OCCI_ORACLE */ diff --git a/libodbc/include/ora_linux/occiAQ.h b/libodbc/include/ora_linux/occiAQ.h new file mode 100644 index 0000000000..422978a025 --- /dev/null +++ b/libodbc/include/ora_linux/occiAQ.h @@ -0,0 +1,374 @@ +/* Copyright (c) 2002, 2005, Oracle. All rights reserved. */ + +/* + NAME + occiAQ.h - Header file for occi AQ classes + + DESCRIPTION + Class declarations for Producer, Consumer, Message, Agent + Listener, Subscription + + RELATED DOCUMENTS + + + EXPORT FUNCTION(S) + + + INTERNAL FUNCTION(S) + + + EXAMPLES + + NOTES + + + MODIFIED (MM/DD/YY) + cparampa 10/12/02 - creation + +*/ + +#ifndef _olint /* disable olint check */ + +#ifndef OCCIAQ_ORACLE +# define OCCIAQ_ORACLE + +#ifndef OCCICOMMON_ORACLE +#include +#endif + +namespace oracle { +namespace occi { +namespace aq{ + +/*--------------------------------------------------------------------------- + PUBLIC TYPES AND CONSTANTS + ---------------------------------------------------------------------------*/ + +class Message +{ + public: + + enum MessageState + { + MSG_READY = OCI_MSG_READY, + MSG_WAITING = OCI_MSG_WAITING, + MSG_PROCESSED = OCI_MSG_PROCESSED, + MSG_EXPIRED = OCI_MSG_EXPIRED + }; + enum PayloadType + { + RAW, + ANYDATA, + OBJECT + }; + + Message( const Environment *env ); + Message( const Message& rhs); + ~Message(); + + void operator=(const Message& rhs); + int getAttemptsToDequeue() const ; + void setCorrelationId( const OCCI_STD_NAMESPACE::string& corr_id ) ; + OCCI_STD_NAMESPACE::string getCorrelationId() const ; + void setDelay( int delay ) ; + int getDelay() const ; + Date getMessageEnqueuedTime() const ; + void setExceptionQueueName( const OCCI_STD_NAMESPACE::string& queue ) ; + OCCI_STD_NAMESPACE::string getExceptionQueueName() const ; + void setExpiration( int exp ) ; + int getExpiration() const ; + MessageState getMessageState() const ; + void setPriority( int priority ) ; + int getPriority() const ; + void setRecipientList( OCCI_STD_NAMESPACE::vector& ag_list ) ; + void setSenderId( const Agent& sender ) ; + Agent getSenderId() const ; + void setOriginalMessageId( const Bytes& queue ) ; + Bytes getOriginalMessageId() const ; + void setNull(); + bool isNull() const; + + void setBytes( const Bytes& bytes); + void setObject( PObject* pobj); + void setAnyData( const AnyData& any); + + Bytes getBytes() const ; + PObject *getObject() ; + AnyData getAnyData() const ; + + PayloadType getPayloadType( ) const; + + private: + Ptr ptr; + OCIAQMsgProperties* getOCIMsgProperties() const; + Message( const Environment *env, const Connection *con, + OCIAQMsgProperties *msgprop, void *data, unsigned int dataLen, + bool isNull, PayloadType pType); + friend class ConsumerImpl; + friend class ProducerImpl; + friend class NotifyResult; +}; + +class Producer +{ + public: + + enum EnqueueSequence + { + ENQ_BEFORE = OCI_ENQ_BEFORE, + ENQ_TOP = OCI_ENQ_TOP + }; + enum Visibility + { + ENQ_IMMEDIATE = OCI_ENQ_IMMEDIATE, + ENQ_ON_COMMIT = OCI_ENQ_ON_COMMIT + }; + + Producer( const Connection *conn ); + Producer( const Connection *conn, + const OCCI_STD_NAMESPACE::string& queue ); + Producer( const Producer& rhs); + ~Producer(); + + void operator=(const Producer& prod); + void setRelativeMessageId( const Bytes& msgid ); + Bytes getRelativeMessageId() const; + void setSequenceDeviation( EnqueueSequence option ); + EnqueueSequence getSequenceDeviation() const; + void setVisibility( Visibility option ); + Visibility getVisibility() const; + void setQueueName( const OCCI_STD_NAMESPACE::string& queue ); + OCCI_STD_NAMESPACE::string getQueueName() const; + void setTransformation( const OCCI_STD_NAMESPACE::string& fName); + OCCI_STD_NAMESPACE::string getTransformation() const; + Bytes send( Message& msg, const OCCI_STD_NAMESPACE::string& queue ); + Bytes send( Message& msg ); + void setNull(); + bool isNull() const; + + private: + Ptr ptr; +}; + +class Consumer +{ + public: + + enum DequeueMode + { + DEQ_BROWSE = OCI_DEQ_BROWSE, + DEQ_LOCKED = OCI_DEQ_LOCKED, + DEQ_REMOVE = OCI_DEQ_REMOVE, + DEQ_REMOVE_NODATA = OCI_DEQ_REMOVE_NODATA + }; + enum Navigation + { + DEQ_FIRST_MSG = OCI_DEQ_FIRST_MSG, + DEQ_NEXT_TRANSACTION = OCI_DEQ_NEXT_TRANSACTION, + DEQ_NEXT_MSG = OCI_DEQ_NEXT_MSG + }; + enum Visibility + { + DEQ_IMMEDIATE = OCI_DEQ_IMMEDIATE, + DEQ_ON_COMMIT = OCI_DEQ_ON_COMMIT + }; + enum + { + DEQ_WAIT_FOREVER = OCI_DEQ_WAIT_FOREVER, + DEQ_NO_WAIT = OCI_DEQ_NO_WAIT + }; + + Consumer( const Connection *conn ); + Consumer( const Connection * conn, const Agent& agent); + Consumer( const Connection *conn, + const OCCI_STD_NAMESPACE::string& queue ); + Consumer(const Consumer& con); + ~Consumer(); + + void operator=(const Consumer& con); + void setAgent(const Agent& agent); + void setConsumerName( const OCCI_STD_NAMESPACE::string& name ); + OCCI_STD_NAMESPACE::string getConsumerName() const; + void setCorrelationId( const OCCI_STD_NAMESPACE::string& cor_id ); + OCCI_STD_NAMESPACE::string getCorrelationId() const; + void setDequeueMode( DequeueMode mode ); + DequeueMode getDequeueMode() const; + void setMessageIdToDequeue( const Bytes& msgid ); + Bytes getMessageIdToDequeue() const; + void setPositionOfMessage( Navigation pos ); + Navigation getPositionOfMessage() const; + void setVisibility( Visibility option ); + Visibility getVisibility() const; + void setWaitTime( unsigned int wait ); + unsigned int getWaitTime() const; + void setQueueName( const OCCI_STD_NAMESPACE::string& queue ); + OCCI_STD_NAMESPACE::string getQueueName() const; + void setTransformation( const OCCI_STD_NAMESPACE::string& fName); + OCCI_STD_NAMESPACE::string getTransformation() const; + Message receive( Message::PayloadType pType, + const OCCI_STD_NAMESPACE::string& type="", + const OCCI_STD_NAMESPACE::string& schema=""); + void setNull(); + bool isNull() const; + + private: + Ptr ptr; +}; + +class Agent +{ + public: + Agent( const Environment *env ); + Agent( const Environment *env, + const OCCI_STD_NAMESPACE::string& name, + const OCCI_STD_NAMESPACE::string& address, + unsigned int protocol=0 ) ; + Agent(const Agent& a); + ~Agent() ; + + void operator=(const Agent& a); + void setName( const OCCI_STD_NAMESPACE::string& name ); + OCCI_STD_NAMESPACE::string getName() const; + void setAddress( const OCCI_STD_NAMESPACE::string& addr ); + OCCI_STD_NAMESPACE::string getAddress() const; + void setProtocol(unsigned int protocol = 0); + unsigned int getProtocol() const; + void setNull(); + bool isNull() const; + OCIAQAgent* getOCIAQAgent() const; + + private: + Ptr ptr; + Agent( const Environment *env, OCIAQAgent *rhs, bool toFree = false ); + friend class Listener; + friend class MessageImpl; +}; + +class Listener +{ + public: + Listener( const Connection *conn ); + Listener( const Connection *conn, + OCCI_STD_NAMESPACE::vector &agList, + int waitTime=0 ); + ~Listener(); + + Agent listen(); + void setAgentList(OCCI_STD_NAMESPACE::vector &agList); + void setTimeOutForListen(int waitTime); + OCCI_STD_NAMESPACE::vector getAgentList() const; + int getTimeOutForListen() const; + + private: + const ConnectionImpl *conn; + OCIAQAgent** agentList; + unsigned int numAgents; + int timeOut; + void *listenerExt; +}; + + +class Subscription +{ + public: + enum Presentation + { + PRES_DEFAULT = OCI_SUBSCR_PRES_DEFAULT, + PRES_XML = OCI_SUBSCR_PRES_XML + }; + enum Protocol + { + PROTO_CBK = OCI_SUBSCR_PROTO_OCI, + PROTO_MAIL = OCI_SUBSCR_PROTO_MAIL, + PROTO_SERVER = OCI_SUBSCR_PROTO_SERVER, + PROTO_HTTP = OCI_SUBSCR_PROTO_HTTP + }; + enum Namespace + { + NS_ANONYMOUS = OCI_SUBSCR_NAMESPACE_ANONYMOUS, + NS_AQ = OCI_SUBSCR_NAMESPACE_AQ + }; + + Subscription(const Environment* env); + Subscription(const Environment* env, OCISubscription* sub); + Subscription(const Subscription& sub); + ~Subscription(); + + void operator=(const Subscription& sub); + unsigned int getDatabaseServersCount() const; + void setDatabaseServerNames( + const OCCI_STD_NAMESPACE::vector& dbsrv); + OCCI_STD_NAMESPACE::vector + getDatabaseServerNames() const ; + void setNotifyCallback(unsigned int (*callback)(Subscription& sub, + NotifyResult *nr)); + unsigned int (*getNotifyCallback() const)(Subscription& sub, + NotifyResult *nr); + void setCallbackContext(void* ctx); + void* getCallbackContext() const; + void setSubscriptionName(const OCCI_STD_NAMESPACE::string& name); + OCCI_STD_NAMESPACE::string getSubscriptionName() const ; + void setSubscriptionNamespace(Namespace nameSpace); + Namespace getSubscriptionNamespace() const ; + void setPayload(const Bytes& payload); + Bytes getPayload() const ; + void setRecipientName( const OCCI_STD_NAMESPACE::string& name); + OCCI_STD_NAMESPACE::string getRecipientName() const; + void setPresentation( Presentation pres) ; + Presentation getPresentation() const ; + void setProtocol( Protocol prot) ; + Protocol getProtocol() const ; + OCISubscription* getOCISubscription() const; + void setNull(); + bool isNull() const; + Environment* getEnvironment() const; + + private: + Ptr ptr; +}; + +class NotifyResult +{ + public: + Bytes getPayload() const; + Message getMessage() const; + Bytes getMessageId() const; + OCCI_STD_NAMESPACE::string getConsumerName() const; + OCCI_STD_NAMESPACE::string getQueueName() const; + + private: + const EnvironmentImpl *env; + void *payload; + unsigned int payloadLen; + void *desc; + ub4 mode; + void *notifyResultExt; + + //private constructor + NotifyResult(const Environment *env, void *payload, ub4 payloadLen, + void *pdescriptor, ub4 mode); + + friend class SubscriptionImpl; +}; + +/*--------------------------------------------------------------------------- + PRIVATE TYPES AND CONSTANTS + ---------------------------------------------------------------------------*/ + + +/*--------------------------------------------------------------------------- + EXPORT FUNCTIONS + ---------------------------------------------------------------------------*/ + + +/*--------------------------------------------------------------------------- + INTERNAL FUNCTIONS + ---------------------------------------------------------------------------*/ +} /* end of namespace aq */ +} /* end of namespace occi */ +} /* end of namespace oracle */ + +#endif /* OCCIAQ_ORACLE */ + +#endif /* _olint */ diff --git a/libodbc/include/ora_linux/occiCommon.h b/libodbc/include/ora_linux/occiCommon.h new file mode 100644 index 0000000000..1774c0f95f --- /dev/null +++ b/libodbc/include/ora_linux/occiCommon.h @@ -0,0 +1,982 @@ +/* Copyright (c) 2000, 2007, Oracle. All rights reserved. */ + +/* + NAME + occiCommon.h - header file for doing forward references + + DESCRIPTION + Just declare all the classes + + RELATED DOCUMENTS + OCCI Programmer's Guide + + EXPORT FUNCTION(S) + none + + INTERNAL FUNCTION(S) + none + + EXAMPLES + + NOTES + none + +*/ + + +#ifndef OCCICOMMON_ORACLE +# define OCCICOMMON_ORACLE + +#ifndef _olint + +#ifndef OCI_ORACLE +#include +#endif + +#ifndef ORASTRINGSTL +#define ORASTRINGSTL +#include +#endif + +#ifndef ORAVECTORSTL +#include +#define ORAVECTORSTL +#endif + +#ifndef ORALISTSTL +#include +#define ORALISTSTL +#endif + +#define OCCI_STD_NAMESPACE std +#define OCCI_HAVE_STD_NAMESPACE 1 + +// version definitions +#define OCCI_MAJOR_VERSION OCI_MAJOR_VERSION +#define OCCI_MINOR_VERSION OCI_MINOR_VERSION + +namespace oracle { +namespace occi { + +//UString is the class for UTF16 characterset +//check for version = 3.2 or 3.3 +#if (__GNUC__ == 3 && (__GNUC_MINOR__ == 2 || __GNUC_MINOR__ == 3)) + //char_traits specialization for utext for gcc 3.2.3 + struct utext_char_traits + { + typedef utext char_type; + typedef unsigned int int_type; + + typedef OCCI_STD_NAMESPACE::streampos pos_type; + typedef OCCI_STD_NAMESPACE::streamoff off_type; + typedef OCCI_STD_NAMESPACE::mbstate_t state_type; + + //assign one char to another + static void assign(char_type& c1, const char_type& c2) + { + c1 = c2; + } + + //are 2 chars equal ? + static bool eq(const char_type& c1, const char_type& c2) + { + return c1 == c2; + } + + //is char c1 less then c2 ? + static bool lt(const char_type& c1, const char_type& c2) + { + return c1 < c2; + } + + //compare 2 strings of char + static int compare(const char_type* s1, const char_type* s2, size_t n) + { + for (size_t i = 0; i < n; ++i) + if (!eq(s1[i], s2[i])) + return s1[i] < s2[i] ? -1 : 1; + return 0; + } + + //length of a char string + static size_t length(const char_type* s) + { + const char_type nullchar = char_type(0); + size_t i = 0; + + while (!eq(*s++, nullchar)) i++; + return i; + } + + //find a character in the char string + static const char_type* find(const char_type* s, + size_t n, const char_type& c) + { + for ( ; n > 0 ; ++s, --n) + if (eq(*s, c)) + return s; + return 0; + } + + //move n chars from s2 to s1 + static char_type* move(char_type* s1, const char_type* s2, size_t n) + { + memmove(s1, s2, n * sizeof(char_type)); + return s1; + } + + //copy n chars from s2 to s1 + static char_type* copy(char_type* s1, const char_type* s2, size_t n) + { + memcpy(s1, s2, n * sizeof(char_type)); + return s1; + } + + //fill char c into s + static char_type* assign(char_type* s, size_t n, char_type c) + { + for (size_t i = 0; i < n; ++i) + assign(s[i], c); + return s; + } + + //is the int representation eof ? + static int_type not_eof(const int_type& c) + { + if (c == eof()) + return 0; + else + return c; + } + + //cast a int type to char + static char_type to_char_type(const int_type& c) + { + return static_cast(c); + } + + //cast char to int type + static int_type to_int_type(const char_type& c) + { + return static_cast(c); + } + + //eq operator when the chars are represented as ints + static bool eq_int_type(const int_type& c1, const int_type& c2) + { + return c1 == c2; + } + + //eof character + static int_type eof() + { + return static_cast(-1); + } + + + }; //end char_traits + +typedef OCCI_STD_NAMESPACE::basic_string UString; +#else +//for non gcc 3.2.3 platforms +typedef OCCI_STD_NAMESPACE::basic_string UString; +#endif /* if gcc 3.2.3 */ + +class Environment; +class EnvironmentImpl; +class Connection; +class ConnectionImpl; +class ConnectionPool; +class ConnectionPoolImpl; +class StatelessConnectionPool; +class StatelessConnectionPoolImpl; +class Statement; +class StatementImpl; +class ResultSet; +class ResultSetImpl; +class SQLException; +class SQLExceptionImpl; +class BatchSQLException; +class BatchSQLExceptionImpl; +class Stream; +class PObject; +class Number; +class Bytes; +class BytesImpl; +class Date; +class Timestamp; + +class MetaData; +class MetaDataImpl; +template class Ref; +class RefImpl; +class RefAny; +class Blob; +class Bfile; +class Clob; +class LobStreamImpl; +class AnyData; +class AnyDataImpl; +class Map; +class IntervalDS; +class IntervalYM; + +namespace aq { +class Message; +class MessageImpl; +class Agent; +class AgentImpl; +class Producer; +class ProducerImpl; +class Consumer; +class ConsumerImpl; +class Listener; +class Subscription; +class SubscriptionImpl; +class NotifyResult; +} + +typedef struct BFloat BFloat; +typedef struct BDouble BDouble; + +/*--------------------------------------------------------------------------- + ENUMERATORS + ---------------------------------------------------------------------------*/ +enum Type +{ + OCCI_SQLT_CHR=SQLT_CHR, + OCCI_SQLT_NUM=SQLT_NUM, + OCCIINT = SQLT_INT, + OCCIFLOAT = SQLT_FLT, + OCCIBFLOAT = SQLT_BFLOAT, + OCCIBDOUBLE = SQLT_BDOUBLE, + OCCIIBFLOAT = SQLT_IBFLOAT, + OCCIIBDOUBLE = SQLT_IBDOUBLE, + OCCI_SQLT_STR=SQLT_STR, + OCCI_SQLT_VNU=SQLT_VNU, + OCCI_SQLT_PDN=SQLT_PDN, + OCCI_SQLT_LNG=SQLT_LNG, + OCCI_SQLT_VCS=SQLT_VCS, + OCCI_SQLT_NON=SQLT_NON, + OCCI_SQLT_RID=SQLT_RID, + OCCI_SQLT_DAT=SQLT_DAT, + OCCI_SQLT_VBI=SQLT_VBI, + OCCI_SQLT_BIN=SQLT_BIN, + OCCI_SQLT_LBI=SQLT_LBI, + OCCIUNSIGNED_INT = SQLT_UIN, + OCCI_SQLT_SLS=SQLT_SLS, + OCCI_SQLT_LVC=SQLT_LVC, + OCCI_SQLT_LVB=SQLT_LVB, + OCCI_SQLT_AFC=SQLT_AFC, + OCCI_SQLT_AVC=SQLT_AVC, + OCCI_SQLT_CUR=SQLT_CUR, + OCCI_SQLT_RDD=SQLT_RDD, + OCCI_SQLT_LAB=SQLT_LAB, + OCCI_SQLT_OSL=SQLT_OSL, + OCCI_SQLT_NTY=SQLT_NTY, + OCCI_SQLT_REF=SQLT_REF, + OCCI_SQLT_CLOB=SQLT_CLOB, + OCCI_SQLT_BLOB=SQLT_BLOB, + OCCI_SQLT_BFILEE=SQLT_BFILEE, + OCCI_SQLT_CFILEE=SQLT_CFILEE, + OCCI_SQLT_RSET=SQLT_RSET, + OCCI_SQLT_NCO=SQLT_NCO, + OCCI_SQLT_VST=SQLT_VST, + OCCI_SQLT_ODT=SQLT_ODT, + OCCI_SQLT_DATE=SQLT_DATE, + OCCI_SQLT_TIME=SQLT_TIME, + OCCI_SQLT_TIME_TZ=SQLT_TIME_TZ, + OCCI_SQLT_TIMESTAMP=SQLT_TIMESTAMP, + OCCI_SQLT_TIMESTAMP_TZ=SQLT_TIMESTAMP_TZ, + OCCI_SQLT_INTERVAL_YM=SQLT_INTERVAL_YM, + OCCI_SQLT_INTERVAL_DS=SQLT_INTERVAL_DS, + OCCI_SQLT_TIMESTAMP_LTZ=SQLT_TIMESTAMP_LTZ, + OCCI_SQLT_FILE=SQLT_FILE, + OCCI_SQLT_CFILE=SQLT_CFILE, + OCCI_SQLT_BFILE=SQLT_BFILE, + + OCCICHAR = 32 *1024, + OCCIDOUBLE, + OCCIBOOL, + OCCIANYDATA , + OCCINUMBER, + OCCIBLOB, + OCCIBFILE, + OCCIBYTES, + OCCICLOB , + OCCIVECTOR, + OCCIMETADATA, + OCCIPOBJECT, + OCCIREF , + OCCIREFANY, + OCCISTRING , + OCCISTREAM , + OCCIDATE , + OCCIINTERVALDS , + OCCIINTERVALYM , + OCCITIMESTAMP, + OCCIROWID, + OCCICURSOR + + +}; + +enum LockOptions {OCCI_LOCK_NONE = OCI_LOCK_NONE, + OCCI_LOCK_X = OCI_LOCK_X, + OCCI_LOCK_X_NOWAIT = OCI_LOCK_X_NOWAIT + }; + +enum {OCCI_MAX_PREFETCH_DEPTH = UB4MAXVAL}; + +enum TypeCode +{ + +OCCI_TYPECODE_REF = OCI_TYPECODE_REF, +OCCI_TYPECODE_DATE = OCI_TYPECODE_DATE, +OCCI_TYPECODE_REAL = OCI_TYPECODE_REAL, +OCCI_TYPECODE_DOUBLE = OCI_TYPECODE_DOUBLE, +OCCI_TYPECODE_BDOUBLE = OCI_TYPECODE_BDOUBLE, +OCCI_TYPECODE_FLOAT = OCI_TYPECODE_FLOAT, +OCCI_TYPECODE_BFLOAT = OCI_TYPECODE_BFLOAT, +OCCI_TYPECODE_NUMBER = OCI_TYPECODE_NUMBER, +OCCI_TYPECODE_DECIMAL = OCI_TYPECODE_DECIMAL, +OCCI_TYPECODE_OCTET = OCI_TYPECODE_OCTET, +OCCI_TYPECODE_INTEGER = OCI_TYPECODE_INTEGER, +OCCI_TYPECODE_SMALLINT= OCI_TYPECODE_SMALLINT, +OCCI_TYPECODE_RAW = OCI_TYPECODE_RAW, +OCCI_TYPECODE_VARCHAR2 = OCI_TYPECODE_VARCHAR2, +OCCI_TYPECODE_VARCHAR = OCI_TYPECODE_VARCHAR, +OCCI_TYPECODE_CHAR = OCI_TYPECODE_CHAR, +OCCI_TYPECODE_VARRAY= OCI_TYPECODE_VARRAY, +OCCI_TYPECODE_TABLE = OCI_TYPECODE_TABLE, +OCCI_TYPECODE_CLOB = OCI_TYPECODE_CLOB, +OCCI_TYPECODE_BLOB = OCI_TYPECODE_BLOB, +OCCI_TYPECODE_BFILE = OCI_TYPECODE_BFILE, +OCCI_TYPECODE_OBJECT = OCI_TYPECODE_OBJECT, +OCCI_TYPECODE_NAMEDCOLLECTION = OCI_TYPECODE_NAMEDCOLLECTION +}; + +enum CharSetForm +{ + OCCI_SQLCS_IMPLICIT = SQLCS_IMPLICIT // use local db char set + ,OCCI_SQLCS_NCHAR = SQLCS_NCHAR // use local db nchar set + ,OCCI_SQLCS_EXPLICIT = SQLCS_EXPLICIT // char set explicitly specified + ,OCCI_SQLCS_FLEXIBLE = SQLCS_FLEXIBLE // pl/sql flexible parameter +}; + +enum LobOpenMode +{ OCCI_LOB_READONLY = OCI_LOB_READONLY + ,OCCI_LOB_READWRITE = OCI_LOB_READWRITE + ,OCCI_LOB_WRITEONLY = OCI_LOB_WRITEONLY + ,OCCI_LOB_APPENDONLY = OCI_LOB_APPENDONLY + ,OCCI_LOB_FULLOVERWRITE = OCI_LOB_FULLOVERWRITE + ,OCCI_LOB_FULLREAD = OCI_LOB_FULLREAD +}; + +enum LobOptionType +{ + OCCI_LOB_OPT_NONE = 0, + OCCI_LOB_OPT_COMPRESS = OCI_LOB_OPT_COMPRESS, + OCCI_LOB_OPT_ENCRYPT = OCI_LOB_OPT_ENCRYPT, + OCCI_LOB_OPT_DEDUPLICATE = OCI_LOB_OPT_DEDUPLICATE, + OCCI_LOB_OPT_ALLOCSIZE = OCI_LOB_OPT_ALLOCSIZE, + OCCI_LOB_OPT_MIMETYPE = OCI_LOB_OPT_MIMETYPE, + OCCI_LOB_OPT_MODTIME = OCI_LOB_OPT_MODTIME +}; + +enum LobOptionValue +{ + // Compression Options + OCCI_LOB_COMPRESS_OFF = OCI_LOB_COMPRESS_OFF, + OCCI_LOB_COMPRESS_ON = OCI_LOB_COMPRESS_ON, + // Encryption Options + OCCI_LOB_ENCRYPT_OFF = OCI_LOB_ENCRYPT_OFF, + OCCI_LOB_ENCRYPT_ON = OCI_LOB_ENCRYPT_ON, + // Sharing Options + OCCI_LOB_DEDUPLICATE_OFF = OCI_LOB_DEDUPLICATE_OFF, + OCCI_LOB_DEDUPLICATE_ON = OCI_LOB_DEDUPLICATE_ON +}; + +class RefCounted { +public: + RefCounted(); + virtual ~RefCounted(){} + const RefCounted * newRef() const; + void deleteRef() const; + +private: + + void onZeroReferences(); + unsigned long references_; + }; + +template +class ConstPtr +{ + +public: + +ConstPtr( const T* ptr = 0 ); +ConstPtr( const ConstPtr& mp ); +~ConstPtr(); +const T * operator->() const; +const T* rawPtr() const; + +#ifdef MEMBER_TEMPLATE +template operator ConstPtr(); +#endif + +protected: + +void operator=( const ConstPtr& mp ); +const T* rawPtr_; + +}; + +template +class Ptr : public ConstPtr { + +public: + +Ptr( T* ptr = 0 ); +Ptr( const Ptr& mp ); +void operator=( const Ptr& mp ); +const T * operator->() const; +T * operator->(); +T* rawPtr() ; +const T* rawPtr() const; + + + +#ifdef MEMBER_TEMPLATE + template + operator Ptr(); +#endif + +}; + +/*--------------------------------------------------------------------------- + EXPORT FUNCTIONS + ---------------------------------------------------------------------------*/ + + void getVector(const AnyData &any, + OCCI_STD_NAMESPACE::vector &vect); + void getVector(const AnyData &any, + OCCI_STD_NAMESPACE::vector &vect); + void getVector( const AnyData &any, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector( const AnyData &any, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector( const AnyData &any, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector( const AnyData &any, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector( const AnyData &any, + OCCI_STD_NAMESPACE::vector &vect); + void getVector(const AnyData &any, + OCCI_STD_NAMESPACE::vector &vect); + void getVector( const AnyData &any, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector( const AnyData &any, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector( const AnyData &any, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector( const AnyData &any, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector( const AnyData &any, + OCCI_STD_NAMESPACE::vector &vect) ; + template + void getVectorOfRefs( const AnyData &any, + OCCI_STD_NAMESPACE::vector< Ref > &vect) ; + + #if !defined(WIN32COMMON) && !defined(__MVS__) + template + void getVector(const AnyData &any, + OCCI_STD_NAMESPACE::vector< Ref > &vect) ; + #endif + #if defined(WIN32COMMON) || defined(__MVS__) + template + void getVector(const AnyData &any, + OCCI_STD_NAMESPACE::vector &vect, + void *(*rSQL)(void *)); + #else + template + void getVector(const AnyData &any, + OCCI_STD_NAMESPACE::vector &vect, + void *(*rSQL)(void *)); + #endif + + void setVector( AnyData &any, + const OCCI_STD_NAMESPACE::vector &vect) ; + void setVector( AnyData &any, + const OCCI_STD_NAMESPACE::vector &vect) ; + void setVector( AnyData &any, + const OCCI_STD_NAMESPACE::vector &vect) ; + void setVector( AnyData &any, + const OCCI_STD_NAMESPACE::vector &vect) ; + void setVector( AnyData &any, + const OCCI_STD_NAMESPACE::vector &vect) ; + void setVector( AnyData &any, + const OCCI_STD_NAMESPACE::vector &vect) ; + void setVector( AnyData &any, + const OCCI_STD_NAMESPACE::vector &vect) ; + void setVector( AnyData &any, + const OCCI_STD_NAMESPACE::vector &vect) ; + void setVector( AnyData &any, + const OCCI_STD_NAMESPACE::vector &vect) ; + void setVector( AnyData &any, + const OCCI_STD_NAMESPACE::vector &vect) ; + void setVector( AnyData &any, + const OCCI_STD_NAMESPACE::vector &vect) ; + void setVector( AnyData &any, + const OCCI_STD_NAMESPACE::vector &vect) ; + void setVector( AnyData &any, + const OCCI_STD_NAMESPACE::vector &vect) ; + template + void setVectorOfRefs( AnyData &any, + const OCCI_STD_NAMESPACE::vector< Ref > &vect) ; + #if !defined(WIN32COMMON) && !defined(__MVS__) + template + void setVector( AnyData &any, + const OCCI_STD_NAMESPACE::vector< Ref > &vect) ; + #endif + #if defined(WIN32COMMON) || defined(__MVS__) + template + void setVector( AnyData &any, + const OCCI_STD_NAMESPACE::vector< T > &vect) ; + #else + template + void setVector( AnyData &any, + const OCCI_STD_NAMESPACE::vector< T* > &vect) ; + #endif + + void getVector( ResultSet *rs, unsigned int index, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector( ResultSet *rs, unsigned int index, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector( ResultSet *rs, unsigned int index, + OCCI_STD_NAMESPACE::vector &vect) ;//UTF16 support + void getVector(ResultSet *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector(ResultSet *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect); + void getVector(ResultSet *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect); + void getVector(ResultSet *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect); + void getVector(ResultSet *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect); + void getVector(ResultSet *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector(ResultSet *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector(ResultSet *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector(ResultSet *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector(ResultSet *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector(ResultSet *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector(ResultSet *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector(ResultSet *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector(ResultSet *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + template + void getVectorOfRefs(ResultSet *rs, unsigned int, + OCCI_STD_NAMESPACE::vector > &vect) ; + #if !defined(WIN32COMMON) && !defined(__MVS__) + template + void getVector(ResultSet *rs, unsigned int, + OCCI_STD_NAMESPACE::vector > &vect) ; + #endif + #if defined(WIN32COMMON) || defined(__MVS__) + template + void getVector( ResultSet *rs, unsigned int index, + OCCI_STD_NAMESPACE::vector< T > &vect) ; + #else + template + void getVector( ResultSet *rs, unsigned int index, + OCCI_STD_NAMESPACE::vector< T* > &vect) ; + #endif + + + void getVector(Statement *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector(Statement *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector(Statement *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector(Statement *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector(Statement *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector(Statement *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector(Statement *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector( Statement *rs, unsigned int index, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector( Statement *rs, unsigned int index, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector( Statement *rs, unsigned int index, + OCCI_STD_NAMESPACE::vector &vect) ;//UTF16 support + void getVector(Statement *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector(Statement *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector(Statement *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector(Statement *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector(Statement *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector(Statement *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVector(Statement *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + template + void getVectorOfRefs(Statement *rs, unsigned int, + OCCI_STD_NAMESPACE::vector > &vect) ; + #if !defined(WIN32COMMON) && !defined(__MVS__) + template + void getVector(Statement *rs, unsigned int, + OCCI_STD_NAMESPACE::vector > &vect) ; + #endif + #if defined(WIN32COMMON) || defined(__MVS__) + template + void getVector( Statement *rs, unsigned int index, + OCCI_STD_NAMESPACE::vector< T > &vect) ; + #else + template + void getVector( Statement *rs, unsigned int index, + OCCI_STD_NAMESPACE::vector< T* > &vect) ; + #endif + + + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &sqltype) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &sqltype) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &sqltype) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &sqltype) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &sqltype) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &sqltype) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &sqltype); + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &sqltype) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &sqltype) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &sqltype) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &sqltype) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &sqltype) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &sqltype) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &sqltype) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &sqltype) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &sqltype) ; + template + void setVectorOfRefs(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector > &vect, + const OCCI_STD_NAMESPACE::string &sqltype) ; + #if !defined(WIN32COMMON) && !defined(__MVS__) + template + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector > &vect, + const OCCI_STD_NAMESPACE::string &sqltype) ; + #endif + #if defined(WIN32COMMON) || defined(__MVS__) + template + void setVector( Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector< T > &vect, + const OCCI_STD_NAMESPACE::string &sqltype) ; + #else + template + void setVector( Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &sqltype) ; + #endif + +/* ------------------------------------------------------------------------ + Statement setVector functions, schema & type separate + arguments - multibyte support + ------------------------------------------------------------------------ +*/ + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &schemaName, + const OCCI_STD_NAMESPACE::string &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &schemaName, + const OCCI_STD_NAMESPACE::string &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &schemaName, + const OCCI_STD_NAMESPACE::string &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &schemaName, + const OCCI_STD_NAMESPACE::string &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &schemaName, + const OCCI_STD_NAMESPACE::string &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &schemaName, + const OCCI_STD_NAMESPACE::string &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &schemaName, + const OCCI_STD_NAMESPACE::string &typeName); + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &schemaName, + const OCCI_STD_NAMESPACE::string &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &schemaName, + const OCCI_STD_NAMESPACE::string &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &schemaName, + const OCCI_STD_NAMESPACE::string &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &schemaName, + const OCCI_STD_NAMESPACE::string &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &schemaName, + const OCCI_STD_NAMESPACE::string &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &schemaName, + const OCCI_STD_NAMESPACE::string &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &schemaName, + const OCCI_STD_NAMESPACE::string &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &schemaName, + const OCCI_STD_NAMESPACE::string &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &schemaName, + const OCCI_STD_NAMESPACE::string &typeName) ; + template + void setVectorOfRefs(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector > &vect, + const OCCI_STD_NAMESPACE::string &schemaName, + const OCCI_STD_NAMESPACE::string &typeName) ; + + #if !defined(WIN32COMMON) && !defined(__MVS__) + template + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector > &vect, + const OCCI_STD_NAMESPACE::string &schemaName, + const OCCI_STD_NAMESPACE::string &typeName) ; + #endif + + #if defined(WIN32COMMON) || defined(__MVS__) + template + void setVector( Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector< T > &vect, + const OCCI_STD_NAMESPACE::string &schemaName, + const OCCI_STD_NAMESPACE::string &typeName) ; + #else + template + void setVector( Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, const OCCI_STD_NAMESPACE::string + &schemaName, const OCCI_STD_NAMESPACE::string &typeName) ; + #endif + +/*------------------------------------------------------------------------- + Statement setVector function - UTF16 support + ------------------------------------------------------------------------- +*/ + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const UString &schemaName, + const UString &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const UString &schemaName, + const UString &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const UString &schemaName, + const UString &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const UString &schemaName, + const UString &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const UString &schemaName, + const UString &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const UString &schemaName, + const UString &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const UString &schemaName, + const UString &typeName); + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const UString &schemaName, + const UString &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &schemaName, + const OCCI_STD_NAMESPACE::string &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const UString &schemaName, + const UString &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const UString &schemaName, + const UString &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const UString &schemaName, + const UString &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const UString &schemaName, + const UString &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const UString &schemaName, + const UString &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const UString &schemaName, + const UString &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const UString &schemaName, + const UString &typeName) ; + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const UString &schemaName, + const UString &typeName) ; + template + void setVectorOfRefs(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector > &vect, + const UString &schemaName, + const UString &typeName) ; + + #if !defined(WIN32COMMON) && !defined(__MVS__) + template + void setVector(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector > &vect, + const UString &schemaName, + const UString &typeName) ; + #endif + + #if defined(WIN32COMMON) || defined(__MVS__) + template + void setVector( Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector< T > &vect, + const UString &schemaName, + const UString &typeName) ; + #else + template + void setVector( Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, const UString + &schemaName, const UString &typeName) ; + #endif + + +/* Global method for array pins */ +template +void pinVectorOfRefs( const Connection *conn, +OCCI_STD_NAMESPACE::vector > &vect, +OCCI_STD_NAMESPACE::vector &vectObj, +LockOptions lockOpt = OCCI_LOCK_NONE ); + +template +void pinVectorOfRefs( const Connection *conn, +OCCI_STD_NAMESPACE::vector > &vect, +LockOptions lockOpt = OCCI_LOCK_NONE ); + +#ifdef ORAXB8_DEFINED + void readVectorOfBfiles(const Connection *conn, + OCCI_STD_NAMESPACE::vector &vec, + oraub8 *byte_amts, oraub8 *offsets, + unsigned char *buffers[], oraub8 *buffer_lens); + + void readVectorOfBlobs(const Connection *conn, + OCCI_STD_NAMESPACE::vector &vec, + oraub8 *byte_amts, oraub8 *offsets, + unsigned char *buffers[], oraub8 *buffer_lens); + void writeVectorOfBlobs(const Connection *conn, + OCCI_STD_NAMESPACE::vector &vec, + oraub8 *byte_amts, oraub8 *offsets, + unsigned char *buffers[], oraub8 *buffer_lens); + + void readVectorOfClobs(const Connection *conn, + OCCI_STD_NAMESPACE::vector &vec, + oraub8 *byte_amts, oraub8 *char_amts, oraub8 *offsets, + unsigned char *buffers[], oraub8 *buffer_lens); + void writeVectorOfClobs(const Connection *conn, + OCCI_STD_NAMESPACE::vector &vec, + oraub8 *byte_amts, oraub8 *char_amts, oraub8 *offsets, + unsigned char *buffers[], oraub8 *buffer_lens); + void readVectorOfClobs(const Connection *conn, + OCCI_STD_NAMESPACE::vector &vec, + oraub8 *byte_amts, oraub8 *char_amts, oraub8 *offsets, + utext *buffers[], oraub8 *buffer_lens); + void writeVectorOfClobs(const Connection *conn, + OCCI_STD_NAMESPACE::vector &vec, + oraub8 *byte_amts, oraub8 *char_amts, oraub8 *offsets, + utext *buffers[], oraub8 *buffer_lens); +#endif + + +/*--------------------------------------------------------------------------- + INTERNAL FUNCTIONS + ---------------------------------------------------------------------------*/ + + +} /* end of namespace occi */ +} /* end of namespace oracle */ + + +#endif /* _olint */ + +#endif /* OCCICOMMON_ORACLE */ diff --git a/libodbc/include/ora_linux/occiControl.h b/libodbc/include/ora_linux/occiControl.h new file mode 100644 index 0000000000..86e687e55a --- /dev/null +++ b/libodbc/include/ora_linux/occiControl.h @@ -0,0 +1,2133 @@ +/* Copyright Oracle Corporation 2000, 2006. All Rights Reserved. */ + +/* + NAME + occiControl.h - header file for OCCI control classes + + DESCRIPTION + Class definitions for MetaData,SQLException,Environment, + Connection,Statement, ConnectionPool, StatelessConnectionPool + + RELATED DOCUMENTS + + + EXPORT FUNCTION(S) + + + INTERNAL FUNCTION(S) + + + EXAMPLES + + NOTES + + + +*/ + +#ifndef _olint /* disable olint check */ + +#ifndef OCCICONTROL_ORACLE +# define OCCICONTROL_ORACLE + +#ifndef OCCICOMMON_ORACLE +#include +#endif + +#ifndef ORAEXCEPTION +#define ORAEXCEPTION +#include +#endif + +namespace oracle { +namespace occi { +/*--------------------------------------------------------------------------- + PUBLIC TYPES AND CONSTANTS + ---------------------------------------------------------------------------*/ + +class MetaData +{ + public : + + enum AttrId + {ATTR_PTYPE = OCI_ATTR_PTYPE, + ATTR_TIMESTAMP = OCI_ATTR_TIMESTAMP, + ATTR_OBJ_ID = OCI_ATTR_OBJ_ID, + ATTR_OBJ_NAME = OCI_ATTR_OBJ_NAME, + ATTR_OBJ_SCHEMA = OCI_ATTR_OBJ_SCHEMA, + ATTR_OBJID = OCI_ATTR_OBJID, + ATTR_NUM_COLS = OCI_ATTR_NUM_COLS, + ATTR_LIST_COLUMNS = OCI_ATTR_LIST_COLUMNS, + ATTR_REF_TDO = OCI_ATTR_REF_TDO, + ATTR_IS_TEMPORARY = OCI_ATTR_IS_TEMPORARY, + ATTR_IS_TYPED = OCI_ATTR_IS_TYPED, + ATTR_DURATION = OCI_ATTR_DURATION, + ATTR_COLLECTION_ELEMENT = OCI_ATTR_COLLECTION_ELEMENT, + ATTR_RDBA = OCI_ATTR_RDBA, + ATTR_TABLESPACE = OCI_ATTR_TABLESPACE, + ATTR_CLUSTERED = OCI_ATTR_CLUSTERED, + ATTR_PARTITIONED = OCI_ATTR_PARTITIONED, + ATTR_INDEX_ONLY = OCI_ATTR_INDEX_ONLY, + ATTR_LIST_ARGUMENTS = OCI_ATTR_LIST_ARGUMENTS, + ATTR_IS_INVOKER_RIGHTS = OCI_ATTR_IS_INVOKER_RIGHTS, + ATTR_LIST_SUBPROGRAMS = OCI_ATTR_LIST_SUBPROGRAMS, + ATTR_NAME = OCI_ATTR_NAME, + ATTR_OVERLOAD_ID = OCI_ATTR_OVERLOAD_ID, + ATTR_TYPECODE = OCI_ATTR_TYPECODE, + ATTR_COLLECTION_TYPECODE = OCI_ATTR_COLLECTION_TYPECODE, + ATTR_VERSION = OCI_ATTR_VERSION, + ATTR_IS_INCOMPLETE_TYPE = OCI_ATTR_IS_INCOMPLETE_TYPE, + ATTR_IS_SYSTEM_TYPE = OCI_ATTR_IS_SYSTEM_TYPE, + ATTR_IS_PREDEFINED_TYPE = OCI_ATTR_IS_PREDEFINED_TYPE, + ATTR_IS_TRANSIENT_TYPE = OCI_ATTR_IS_TRANSIENT_TYPE, + ATTR_IS_SYSTEM_GENERATED_TYPE = + OCI_ATTR_IS_SYSTEM_GENERATED_TYPE, + ATTR_HAS_NESTED_TABLE = OCI_ATTR_HAS_NESTED_TABLE, + ATTR_HAS_LOB = OCI_ATTR_HAS_LOB, + ATTR_HAS_FILE = OCI_ATTR_HAS_FILE, + ATTR_NUM_TYPE_ATTRS = OCI_ATTR_NUM_TYPE_ATTRS, + ATTR_LIST_TYPE_ATTRS = OCI_ATTR_LIST_TYPE_ATTRS, + ATTR_NUM_TYPE_METHODS = OCI_ATTR_NUM_TYPE_METHODS, + ATTR_LIST_TYPE_METHODS = OCI_ATTR_LIST_TYPE_METHODS, + ATTR_MAP_METHOD = OCI_ATTR_MAP_METHOD, + ATTR_ORDER_METHOD = OCI_ATTR_ORDER_METHOD, + ATTR_DATA_SIZE = OCI_ATTR_DATA_SIZE, + ATTR_DATA_TYPE = OCI_ATTR_DATA_TYPE, + ATTR_PRECISION = OCI_ATTR_PRECISION, + ATTR_SCALE = OCI_ATTR_SCALE, + ATTR_TYPE_NAME = OCI_ATTR_TYPE_NAME, + ATTR_SCHEMA_NAME = OCI_ATTR_SCHEMA_NAME, + ATTR_CHARSET_ID = OCI_ATTR_CHARSET_ID, + ATTR_CHARSET_FORM = OCI_ATTR_CHARSET_FORM, + ATTR_ENCAPSULATION = OCI_ATTR_ENCAPSULATION, + ATTR_IS_CONSTRUCTOR = OCI_ATTR_IS_CONSTRUCTOR, + ATTR_IS_DESTRUCTOR = OCI_ATTR_IS_DESTRUCTOR, + ATTR_IS_OPERATOR = OCI_ATTR_IS_OPERATOR, + ATTR_IS_SELFISH = OCI_ATTR_IS_SELFISH, + ATTR_IS_MAP = OCI_ATTR_IS_MAP, + ATTR_IS_ORDER = OCI_ATTR_IS_ORDER, + ATTR_IS_RNDS = OCI_ATTR_IS_RNDS, + ATTR_IS_RNPS = OCI_ATTR_IS_RNPS, + ATTR_IS_WNDS = OCI_ATTR_IS_WNDS, + ATTR_IS_WNPS = OCI_ATTR_IS_WNPS, + ATTR_NUM_ELEMS = OCI_ATTR_NUM_ELEMS, + ATTR_LINK = OCI_ATTR_LINK, + ATTR_MIN = OCI_ATTR_MIN, + ATTR_MAX = OCI_ATTR_MAX, + ATTR_INCR = OCI_ATTR_INCR, + ATTR_CACHE = OCI_ATTR_CACHE, + ATTR_ORDER = OCI_ATTR_ORDER, + ATTR_HW_MARK = OCI_ATTR_HW_MARK, + ATTR_IS_NULL = OCI_ATTR_IS_NULL, + ATTR_POSITION = OCI_ATTR_POSITION, + ATTR_HAS_DEFAULT = OCI_ATTR_HAS_DEFAULT, + ATTR_LEVEL = OCI_ATTR_LEVEL, + ATTR_IOMODE = OCI_ATTR_IOMODE, + ATTR_RADIX = OCI_ATTR_RADIX, + ATTR_SUB_NAME = OCI_ATTR_SUB_NAME, + ATTR_LIST_OBJECTS = OCI_ATTR_LIST_OBJECTS, + ATTR_NCHARSET_ID = OCI_ATTR_NCHARSET_ID, + ATTR_LIST_SCHEMAS = OCI_ATTR_LIST_SCHEMAS, + ATTR_MAX_PROC_LEN = OCI_ATTR_MAX_PROC_LEN, + ATTR_MAX_COLUMN_LEN = OCI_ATTR_MAX_COLUMN_LEN, + ATTR_CURSOR_COMMIT_BEHAVIOR = + OCI_ATTR_CURSOR_COMMIT_BEHAVIOR, + ATTR_MAX_CATALOG_NAMELEN = OCI_ATTR_MAX_CATALOG_NAMELEN, + ATTR_CATALOG_LOCATION = OCI_ATTR_CATALOG_LOCATION, + ATTR_SAVEPOINT_SUPPORT = OCI_ATTR_SAVEPOINT_SUPPORT, + ATTR_NOWAIT_SUPPORT = OCI_ATTR_NOWAIT_SUPPORT, + ATTR_AUTOCOMMIT_DDL = OCI_ATTR_AUTOCOMMIT_DDL, + ATTR_LOCKING_MODE = OCI_ATTR_LOCKING_MODE, + ATTR_IS_FINAL_TYPE = OCI_ATTR_IS_FINAL_TYPE, + ATTR_IS_INSTANTIABLE_TYPE = OCI_ATTR_IS_INSTANTIABLE_TYPE, + ATTR_IS_SUBTYPE = OCI_ATTR_IS_SUBTYPE, + ATTR_SUPERTYPE_SCHEMA_NAME = OCI_ATTR_SUPERTYPE_SCHEMA_NAME, + ATTR_SUPERTYPE_NAME = OCI_ATTR_SUPERTYPE_NAME, + ATTR_FSPRECISION = OCI_ATTR_FSPRECISION, + ATTR_LFPRECISION = OCI_ATTR_LFPRECISION, + ATTR_IS_FINAL_METHOD = OCI_ATTR_IS_FINAL_METHOD, + ATTR_IS_INSTANTIABLE_METHOD = OCI_ATTR_IS_INSTANTIABLE_METHOD, + ATTR_IS_OVERRIDING_METHOD = OCI_ATTR_IS_OVERRIDING_METHOD, + ATTR_CHAR_USED = OCI_ATTR_CHAR_USED, + ATTR_CHAR_SIZE = OCI_ATTR_CHAR_SIZE, + ATTR_COL_ENC = OCI_ATTR_COL_ENC, + ATTR_COL_ENC_SALT = OCI_ATTR_COL_ENC_SALT, + ATTR_TABLE_ENC = OCI_ATTR_TABLE_ENC, + ATTR_TABLE_ENC_ALG = OCI_ATTR_TABLE_ENC_ALG, + ATTR_TABLE_ENC_ALG_ID = OCI_ATTR_TABLE_ENC_ALG_ID + }; + + enum ParamType + { + PTYPE_TABLE = OCI_PTYPE_TABLE + ,PTYPE_VIEW = OCI_PTYPE_VIEW + ,PTYPE_PROC = OCI_PTYPE_PROC + ,PTYPE_FUNC = OCI_PTYPE_FUNC + ,PTYPE_PKG = OCI_PTYPE_PKG + ,PTYPE_TYPE = OCI_PTYPE_TYPE + ,PTYPE_TYPE_ATTR = OCI_PTYPE_TYPE_ATTR + ,PTYPE_TYPE_COLL = OCI_PTYPE_TYPE_COLL + ,PTYPE_TYPE_METHOD = OCI_PTYPE_TYPE_METHOD + ,PTYPE_SYN = OCI_PTYPE_SYN + ,PTYPE_SEQ = OCI_PTYPE_SEQ + ,PTYPE_COL = OCI_PTYPE_COL + ,PTYPE_ARG = OCI_PTYPE_ARG + ,PTYPE_TYPE_ARG = OCI_PTYPE_TYPE_ARG + ,PTYPE_TYPE_RESULT = OCI_PTYPE_TYPE_RESULT + ,PTYPE_SCHEMA = OCI_PTYPE_SCHEMA + ,PTYPE_DATABASE = OCI_PTYPE_DATABASE + ,PTYPE_UNK = OCI_PTYPE_UNK + }; + + + enum { DURATION_SESSION = OCI_DURATION_SESSION + ,DURATION_TRANS = OCI_DURATION_TRANS + ,DURATION_NULL = OCI_DURATION_NULL + ,TYPEENCAP_PRIVATE = OCI_TYPEENCAP_PRIVATE + ,TYPEENCAP_PUBLIC = OCI_TYPEENCAP_PUBLIC + ,TYPEPARAM_IN = OCI_TYPEPARAM_IN + ,TYPEPARAM_OUT = OCI_TYPEPARAM_OUT + ,TYPEPARAM_INOUT = OCI_TYPEPARAM_INOUT + ,CURSOR_OPEN = OCI_CURSOR_OPEN + ,CURSOR_CLOSED = OCI_CURSOR_CLOSED + ,CL_START = OCI_CL_START + ,CL_END = OCI_CL_END + ,SP_SUPPORTED = OCI_SP_SUPPORTED + ,SP_UNSUPPORTED = OCI_SP_UNSUPPORTED + ,NW_SUPPORTED = OCI_NW_SUPPORTED + ,NW_UNSUPPORTED = OCI_NW_UNSUPPORTED + ,AC_DDL = OCI_AC_DDL + ,NO_AC_DDL = OCI_NO_AC_DDL + ,LOCK_IMMEDIATE = OCI_LOCK_IMMEDIATE + ,LOCK_DELAYED = OCI_LOCK_DELAYED + }; + + MetaData(const MetaData &omd); + unsigned int getAttributeCount() const + ; + AttrId getAttributeId(unsigned int attributenum) const + ; + Type getAttributeType(unsigned int attributenum) const + ; + int getInt(MetaData::AttrId attrid) const + ; + bool getBoolean(MetaData::AttrId attrid) const + ; + unsigned int getUInt(MetaData::AttrId attrid) const + ; + OCCI_STD_NAMESPACE::string getString(MetaData::AttrId attrid) const + ; + UString getUString(MetaData::AttrId attrid) const + ; + Number getNumber(MetaData::AttrId attrid) const + ; + RefAny getRef(MetaData::AttrId attrid) const + ; + Timestamp getTimestamp(MetaData::AttrId attrid) const + ; + MetaData getMetaData(MetaData::AttrId attrid) const + ; + OCCI_STD_NAMESPACE::vector getVector(MetaData::AttrId attrid) + const ; + void operator =(const MetaData &omd); + + ~MetaData(); + + private: + + enum ociAttrType { OCI_UB1, + OCI_UB2, + OCI_UB4, + OCI_SB1, + OCI_WORD, + OCI_UB1_BOOL, + OCI_UB1PTR_TIMESTAMP, + OCI_UB1PTR_NUMBER, + OCI_TEXTPTR, + OCI_DVOIDPTR_PARAM, + OCI_DVOIDPTR_PARAMLIST, + OCI_OCIREFPTR, + OCI_OCIDURATION, + OCI_OCITYPECODE, + OCI_OCITYPEENCAP, + OCI_OCITYPEPARAMMODE, + OCI_OCIPRECISION + }; + + enum AttrCount {COMMON_ATTR_COUNT = 5, + TABLE_ATTR_COUNT = 15, + VIEW_ATTR_COUNT = 7, + FUNCPROC_ATTR_COUNT = 4, + PKG_ATTR_COUNT = 2, + TYP_ATTR_COUNT = 27, + TYPEATTR_ATTR_COUNT = 14, + TYPEMTHD_ATTR_COUNT = 16, + COLL_ATTR_COUNT = 12, + SYN_ATTR_COUNT = 4, + SEQ_ATTR_COUNT = 7, + COL_ATTR_COUNT = 15, + ARG_TYPARG_TYPRES_ATTR_COUNT = 20, + SCHEMA_ATTR_COUNT = 1, + DATABASE_ATTR_COUNT = 13, + UNK_ATTR_COUNT = 0 + }; + + static const AttrId commonAttrId[COMMON_ATTR_COUNT]; + static const ociAttrType commonAttrType[COMMON_ATTR_COUNT]; + static const AttrId tableAttrId[TABLE_ATTR_COUNT]; + static const ociAttrType tableAttrType[TABLE_ATTR_COUNT]; + static const AttrId viewAttrId[VIEW_ATTR_COUNT]; + static const ociAttrType viewAttrType[VIEW_ATTR_COUNT]; + static const AttrId funcprocAttrId[FUNCPROC_ATTR_COUNT]; + static const ociAttrType funcprocAttrType[FUNCPROC_ATTR_COUNT]; + static const AttrId pkgAttrId[PKG_ATTR_COUNT]; + static const ociAttrType pkgAttrType[PKG_ATTR_COUNT]; + static const AttrId typAttrId[TYP_ATTR_COUNT]; + static const ociAttrType typAttrType[TYP_ATTR_COUNT]; + static const AttrId typeattrAttrId[TYPEATTR_ATTR_COUNT]; + static const ociAttrType typeattrAttrType[TYPEATTR_ATTR_COUNT]; + static const AttrId typmethdAttrId[TYPEMTHD_ATTR_COUNT]; + static const ociAttrType typemthdAttrType[TYPEMTHD_ATTR_COUNT]; + static const AttrId collAttrId[COLL_ATTR_COUNT]; + static const ociAttrType collAttrType[COLL_ATTR_COUNT]; + static const AttrId synAttrId[SYN_ATTR_COUNT]; + static const ociAttrType synAttrType[SYN_ATTR_COUNT]; + static const AttrId seqAttrId[SEQ_ATTR_COUNT]; + static const ociAttrType seqAttrType[SEQ_ATTR_COUNT]; + static const AttrId colAttrId[COL_ATTR_COUNT]; + static const ociAttrType colAttrType[COL_ATTR_COUNT]; + static const AttrId argtargtresAttrId[ARG_TYPARG_TYPRES_ATTR_COUNT]; + static const ociAttrType argtargtresAttrType[ + ARG_TYPARG_TYPRES_ATTR_COUNT]; + static const AttrId schemaAttrId[SCHEMA_ATTR_COUNT]; + static const ociAttrType schemaAttrType[SCHEMA_ATTR_COUNT]; + static const AttrId databaseAttrId[DATABASE_ATTR_COUNT]; + static const ociAttrType databaseAttrType[DATABASE_ATTR_COUNT]; + + Ptr metaDataImplPtr; + const OCIParam* paramhp; + const ConnectionImpl* sesn; + const AttrId* attrIdArray; + const ociAttrType* attrTypeArray; + AttrCount attrCount; + + MetaData(const Connection *sessp, const OCCI_STD_NAMESPACE::string& objName, + ParamType prmtyp ) ; + MetaData(const Connection *sessp, const UString& objName, + ParamType prmtyp ) ; + MetaData(const Connection *sessp, + const RefAny& ref) ; + MetaData(const Connection *sessp, MetaDataImpl *implPtr, + OCIParam* parm) ; + MetaData(const Connection *sessp, MetaDataImpl *implPtr, + OCIParam *parm, ub1 parmTyp) ; + ub1 getParamType(OCIParam* prm) const ; + const AttrId* getAttrIdArrayAddr(ub1 prmTyp) const; + const ociAttrType* getAttrTypeArrayAddr(ub1 prmTyp) const; + AttrCount getAttrCount(ub1 prmTyp) const; + Type getType(ociAttrType typ) const; + bool isListTypeAttribute(AttrId attrid,ub1 ptyp) const; + boolean isInvalidAttrId(AttrId attrid,sb4* pos, + boolean* isTypeSpecificAttrPtr) const; + ociAttrType getValidAttrType(sb4 index, boolean isTypeSpecificAttr) + const; + + int getListType (const OCIParam *plist) const; + unsigned int getLowerBound(int ltype) const; + unsigned int getUpperBound(unsigned int ltype, + unsigned int paramnum) const; + friend class ConnectionImpl; + friend class ResultSetImpl; + +}; + +//return codes for user callbacks +enum +{ + OCCI_SUCCESS = OCI_SUCCESS, + FO_RETRY = OCI_FO_RETRY +}; + + +class Connection +{ + public : + + // specifies the type of proxy to be created, + // used for future enhancements + enum ProxyType + {PROXY_DEFAULT + }; + + enum FailOverType + { + FO_NONE = OCI_FO_NONE, + FO_SESSION = OCI_FO_SESSION, + FO_SELECT = OCI_FO_SELECT + }; + + enum FailOverEventType + { + FO_BEGIN = OCI_FO_BEGIN, + FO_END = OCI_FO_END, + FO_ABORT = OCI_FO_ABORT, + FO_REAUTH = OCI_FO_REAUTH, + FO_ERROR = OCI_FO_ERROR + }; + + enum Purity + { + DEFAULT = OCI_ATTR_PURITY_DEFAULT, + NEW = OCI_ATTR_PURITY_NEW, + SELF = OCI_ATTR_PURITY_SELF + }; + + virtual ~Connection() { } + virtual Statement* createStatement( + const OCCI_STD_NAMESPACE::string &sql = "") + =0; + virtual void terminateStatement(Statement *statement) =0; + virtual void commit() =0; + virtual void rollback() =0; + virtual MetaData getMetaData(const OCCI_STD_NAMESPACE::string &object, + MetaData::ParamType prmtyp + = MetaData::PTYPE_UNK) const + =0; + virtual MetaData getMetaData(const RefAny &ref) const + =0; + virtual OCCI_STD_NAMESPACE::string getClientCharSet() const + =0; + virtual OCCI_STD_NAMESPACE::string getClientNCHARCharSet() const + =0; + virtual void changePassword(const OCCI_STD_NAMESPACE::string &user, + const OCCI_STD_NAMESPACE::string &oldPassword, + const OCCI_STD_NAMESPACE::string &newPassword) + =0; + virtual void flushCache() =0; + + virtual OCIServer* getOCIServer() const =0; + virtual OCISvcCtx* getOCIServiceContext() const =0; + virtual OCISession* getOCISession() const =0; + + //new interfaces + + virtual Statement* createStatement(const UString &sql) = 0; + virtual MetaData getMetaData(const UString &object, + MetaData::ParamType prmtyp + = MetaData::PTYPE_UNK) const + =0; + virtual UString getClientCharSetUString() const + =0; + virtual UString getClientNCHARCharSetUString() const + =0; + virtual void changePassword(const UString &user, + const UString &oldPassword, + const UString &newPassword) + =0; + virtual OCCI_STD_NAMESPACE::string getTag() const =0; + virtual void setStmtCacheSize(unsigned int cacheSize) = 0; + virtual unsigned int getStmtCacheSize() const =0; + virtual Statement* createStatement(const OCCI_STD_NAMESPACE::string &sql, + const OCCI_STD_NAMESPACE::string &tag) = 0; + virtual void terminateStatement(Statement* stmt, + const OCCI_STD_NAMESPACE::string &tag) = 0; + virtual bool isCached(const OCCI_STD_NAMESPACE::string &sql, + const OCCI_STD_NAMESPACE::string &tag = "") = 0; + virtual void registerSubscriptions( + const OCCI_STD_NAMESPACE::vector& sub) =0; + virtual void unregisterSubscription(const aq::Subscription& sub) =0; + virtual void postToSubscriptions( + const OCCI_STD_NAMESPACE::vector& sub) =0; + virtual Statement* createStatement(const UString &sql, + const UString &tag) = 0; + virtual void terminateStatement(Statement* stmt, + const UString &tag) = 0; + virtual bool isCached(const UString &sql, + const UString &tag) = 0; + virtual void setTAFNotify( + int (*notifyFn)(Environment *env, Connection *conn, void *ctx, + FailOverType foType, FailOverEventType foEvent), + void *ctx) = 0; + virtual OCCI_STD_NAMESPACE::string getServerVersion() const =0; + virtual UString getServerVersionUString() const =0; + virtual void cancel() =0; +}; + +class StatelessConnectionPool +{ + public : + + enum PoolType + { + HETEROGENEOUS = OCI_DEFAULT, + HOMOGENEOUS = OCI_SPC_HOMOGENEOUS, + NO_RLB = OCI_SPC_NO_RLB + }; + + enum BusyOption + { + WAIT = OCI_SPOOL_ATTRVAL_WAIT, + NOWAIT = OCI_SPOOL_ATTRVAL_NOWAIT, + FORCEGET = OCI_SPOOL_ATTRVAL_FORCEGET + }; + + enum DestroyMode + { + DEFAULT = OCI_DEFAULT, + SPD_FORCE = OCI_SPD_FORCE + }; + + virtual ~StatelessConnectionPool() {} + virtual unsigned int getBusyConnections() const =0; + virtual unsigned int getOpenConnections() const =0; + virtual unsigned int getMinConnections() const =0; + virtual unsigned int getMaxConnections() const =0; + virtual unsigned int getIncrConnections() const =0; + virtual OCCI_STD_NAMESPACE::string getPoolName() const =0; + virtual unsigned int getTimeOut() const =0; + virtual void setBusyOption(BusyOption busyOption) =0; + virtual BusyOption getBusyOption() const =0; + virtual void setTimeOut(unsigned int connTimeOut =0) =0; + virtual void setPoolSize(unsigned int maxConn =1, + unsigned int minConn =0, unsigned int incrConn =1) =0; + virtual Connection* getConnection( + const OCCI_STD_NAMESPACE::string &tag ="") =0; + virtual Connection* getConnection( + const OCCI_STD_NAMESPACE::string &userName, + const OCCI_STD_NAMESPACE::string &password, + const OCCI_STD_NAMESPACE::string &tag = "") =0; + virtual Connection* getAnyTaggedConnection( + const OCCI_STD_NAMESPACE::string &tag = "") =0; + virtual Connection* getAnyTaggedConnection( + const OCCI_STD_NAMESPACE::string &userName, + const OCCI_STD_NAMESPACE::string &Password, + const OCCI_STD_NAMESPACE::string &tag = "") =0; + virtual Connection* getProxyConnection( + const OCCI_STD_NAMESPACE::string &name, + OCCI_STD_NAMESPACE::string roles[], unsigned int numRoles, + const OCCI_STD_NAMESPACE::string &tag = "", + Connection::ProxyType proxyType = Connection::PROXY_DEFAULT) =0; + virtual Connection* getProxyConnection( + const OCCI_STD_NAMESPACE::string &name, + const OCCI_STD_NAMESPACE::string &tag = "" , + Connection::ProxyType proxyType = Connection::PROXY_DEFAULT) =0; + virtual Connection* getAnyTaggedProxyConnection( + const OCCI_STD_NAMESPACE::string &name, + OCCI_STD_NAMESPACE::string roles[], unsigned int numRoles, + const OCCI_STD_NAMESPACE::string &tag = "", + Connection::ProxyType proxyType = Connection::PROXY_DEFAULT) =0; + virtual Connection* getAnyTaggedProxyConnection( + const OCCI_STD_NAMESPACE::string &name, + const OCCI_STD_NAMESPACE::string &tag="", + Connection::ProxyType proxyType = Connection::PROXY_DEFAULT ) =0; + virtual void releaseConnection (Connection *connection, + const OCCI_STD_NAMESPACE::string &tag = "") =0; + virtual void terminateConnection (Connection *connection) =0; + virtual void setStmtCacheSize(unsigned int cacheSize) =0; + virtual unsigned int getStmtCacheSize() const =0; + + virtual Connection* getConnection(const UString &tag)=0; + virtual Connection* getConnection(const UString &userName, + const UString &password, + const UString &tag)=0; + virtual Connection* getAnyTaggedConnection(const UString &tag)=0; + virtual Connection* getAnyTaggedConnection( const UString &userName, + const UString &Password, const UString &tag)=0 ; + virtual Connection* getProxyConnection(const UString &name, + OCCI_STD_NAMESPACE::string roles[], unsigned int numRoles, + const UString &tag, + Connection::ProxyType proxyType = Connection::PROXY_DEFAULT)=0; + virtual Connection* getProxyConnection(const UString &name, + const UString &tag, Connection::ProxyType + proxyType = Connection::PROXY_DEFAULT)=0; + virtual Connection* getAnyTaggedProxyConnection(const UString &name, + OCCI_STD_NAMESPACE::string roles[], unsigned int numRoles, + const UString &tag, + Connection::ProxyType proxyType = Connection::PROXY_DEFAULT)=0; + virtual Connection* getAnyTaggedProxyConnection(const UString &name, + const UString &tag, + Connection::ProxyType proxyType = Connection::PROXY_DEFAULT )=0; + virtual void releaseConnection(Connection *connection, + const UString &tag)=0; + + + virtual Connection* getConnection( + const OCCI_STD_NAMESPACE::string &connectionClass, + const Connection::Purity purity, + const OCCI_STD_NAMESPACE::string &tag = "") =0; + + virtual Connection* getConnection( + const OCCI_STD_NAMESPACE::string &userName, + const OCCI_STD_NAMESPACE::string &password, + const OCCI_STD_NAMESPACE::string &connectionClass, + const Connection::Purity purity, + const OCCI_STD_NAMESPACE::string &tag = "") =0; + + virtual Connection* getAnyTaggedConnection( + const OCCI_STD_NAMESPACE::string &connectionClass, + const Connection::Purity purity, + const OCCI_STD_NAMESPACE::string &tag = "") =0; + + virtual Connection* getAnyTaggedConnection( + const OCCI_STD_NAMESPACE::string &userName, + const OCCI_STD_NAMESPACE::string &Password, + const OCCI_STD_NAMESPACE::string &connectionClass, + const Connection::Purity purity, + const OCCI_STD_NAMESPACE::string &tag = "")= 0; + + virtual Connection* getProxyConnection( + const OCCI_STD_NAMESPACE::string &name, + OCCI_STD_NAMESPACE::string roles[], unsigned int numRoles, + const OCCI_STD_NAMESPACE::string &connectionClass, + const Connection::Purity purity, + const OCCI_STD_NAMESPACE::string &tag = "", + Connection::ProxyType proxyType = Connection::PROXY_DEFAULT) = 0; + + virtual Connection* getProxyConnection( + const OCCI_STD_NAMESPACE::string &name, + const OCCI_STD_NAMESPACE::string &connectionClass, + const Connection::Purity purity, + const OCCI_STD_NAMESPACE::string &tag = "", + Connection::ProxyType proxyType = Connection::PROXY_DEFAULT) = 0; + + virtual Connection* getAnyTaggedProxyConnection( + const OCCI_STD_NAMESPACE::string &name, + OCCI_STD_NAMESPACE::string roles[], unsigned int numRoles, + const OCCI_STD_NAMESPACE::string &connectionClass, + const Connection::Purity purity, + const OCCI_STD_NAMESPACE::string &tag = "", + Connection::ProxyType proxyType = Connection::PROXY_DEFAULT) = 0; + + + virtual Connection* getAnyTaggedProxyConnection( + const OCCI_STD_NAMESPACE::string &name, + const OCCI_STD_NAMESPACE::string &connectionClass, + const Connection::Purity purity, + const OCCI_STD_NAMESPACE::string &tag = "", + Connection::ProxyType proxyType = Connection::PROXY_DEFAULT) = 0; + + + virtual Connection* getConnection( + const UString &connectionClass, + const Connection::Purity purity, + const UString &tag) = 0; + + + + virtual Connection* getConnection(const UString &userName, + const UString &password, + const UString &connectionClass, + const Connection::Purity purity, + const UString &tag) = 0; + + virtual Connection* getAnyTaggedConnection( + const UString &connectionClass, + const Connection::Purity purity, + const UString &tag) =0; + + + + virtual Connection* getAnyTaggedConnection( const UString &userName, + const UString &Password, + const UString &connectionClass, + const Connection::Purity purity, + const UString &tag) =0; + + virtual Connection* getProxyConnection(const UString &name, + OCCI_STD_NAMESPACE::string roles[], unsigned int numRoles, + const UString &connectionClass, + const Connection::Purity purity, + const UString &tag, Connection::ProxyType proxyType) =0; + + virtual Connection* getProxyConnection(const UString &name, + const UString &connectionClass, + const Connection::Purity purity, + const UString &tag, Connection::ProxyType proxyType) = 0; + + + virtual Connection* getAnyTaggedProxyConnection(const UString &name, + OCCI_STD_NAMESPACE::string roles[], unsigned int numRoles, + const UString &connectionClass, + const Connection::Purity purity, + const UString &tag, + Connection::ProxyType proxyType) = 0; + + virtual Connection* getAnyTaggedProxyConnection(const UString &name, + const UString &connectionClass, + const Connection::Purity purity, + const UString &tag, + Connection::ProxyType proxyType ) =0; + +}; + + +class ConnectionPool +{ + public : + + virtual ~ConnectionPool() {} + virtual unsigned int getBusyConnections() const + =0; + virtual unsigned int getOpenConnections() const + =0; + virtual unsigned int getMinConnections() const + =0; + virtual unsigned int getMaxConnections() const + =0; + virtual unsigned int getIncrConnections() const + =0; + virtual OCCI_STD_NAMESPACE::string getPoolName() const + =0; + virtual unsigned int getTimeOut() const + =0; + virtual void setErrorOnBusy() + =0; + virtual void setTimeOut(unsigned int connTimeOut =0) + =0; + virtual void setPoolSize(unsigned int minConn =0, + unsigned int maxConn =1, unsigned int incrConn =1) + =0; + virtual Connection* createConnection( + const OCCI_STD_NAMESPACE::string &userName, + const OCCI_STD_NAMESPACE::string &password) =0; + + virtual Connection* createProxyConnection( + const OCCI_STD_NAMESPACE::string &name, + OCCI_STD_NAMESPACE::string roles[], unsigned int numRoles, + Connection::ProxyType proxyType = + Connection::PROXY_DEFAULT) =0; + + virtual Connection* createProxyConnection( + const OCCI_STD_NAMESPACE::string &name, + Connection::ProxyType proxyType = + Connection::PROXY_DEFAULT) =0; + + virtual void terminateConnection + (Connection *connection) =0; + + //new interfaces + + virtual Connection* createConnection( + const UString &userName, + const UString &password) =0; + + virtual Connection* createProxyConnection(const UString &name, + OCCI_STD_NAMESPACE::string roles[], unsigned int numRoles, + Connection::ProxyType proxyType = + Connection::PROXY_DEFAULT) =0; + + virtual Connection* createProxyConnection(const UString &name, + Connection::ProxyType proxyType = + Connection::PROXY_DEFAULT) =0; + + virtual void setStmtCacheSize(unsigned int cacheSize) =0; + virtual unsigned int getStmtCacheSize() const =0; + + virtual UString getPoolNameUString() const + =0; +}; + +class Environment +{ + public: + // class constants + + enum Mode + { + DEFAULT = OCI_DEFAULT, + OBJECT = OCI_OBJECT, + SHARED = OCI_SHARED, + NO_USERCALLBACKS = OCI_NO_UCB, + THREADED_MUTEXED = OCI_THREADED, + THREADED_UNMUTEXED = OCI_THREADED | OCI_NO_MUTEX, + EVENTS = OCI_EVENTS, + USE_LDAP = OCI_USE_LDAP + }; + + virtual ~Environment(){} + + // public methods + + static Environment * createEnvironment( + Mode mode = DEFAULT, + void *ctxp = 0, + void *(*malocfp)(void *ctxp, size_t size) = 0, + void *(*ralocfp)(void *ctxp, void *memptr, + size_t newsize) = 0, + void (*mfreefp)(void *ctxp, void *memptr) = 0); + + static Environment * createEnvironment( + const OCCI_STD_NAMESPACE::string &charset, + const OCCI_STD_NAMESPACE::string &ncharset, + Mode mode = DEFAULT, + void *ctxp = 0, + void *(*malocfp)(void *ctxp, size_t size) = 0, + void *(*ralocfp)(void *ctxp, void *memptr, + size_t newsize) = 0, + void (*mfreefp)(void *ctxp, void *memptr) = 0); + + static void terminateEnvironment(Environment *env); + + static Environment* getXAEnvironment(const + OCCI_STD_NAMESPACE::string& dbname); + + static void releaseXAEnvironment(Environment *env); + + static void getClientVersion( int &majorVersion, int &minorVersion, + int &updateNum, int &patchNum, + int &portUpdateNum ); + + + virtual Connection * createConnection( + const OCCI_STD_NAMESPACE::string &userName, + const OCCI_STD_NAMESPACE::string &password, + const OCCI_STD_NAMESPACE::string &connectString = "") = 0; + + virtual void terminateConnection(Connection *connection) = 0; + + virtual ConnectionPool* createConnectionPool( + const OCCI_STD_NAMESPACE::string &poolUserName, + const OCCI_STD_NAMESPACE::string &poolPassword, + const OCCI_STD_NAMESPACE::string &connectString ="", + unsigned int minConn =0, + unsigned int maxConn =1, unsigned int incrConn =1) = 0; + + virtual void terminateConnectionPool(ConnectionPool *poolp) = 0; + + virtual unsigned int getCurrentHeapSize() const = 0; + + virtual OCIEnv * getOCIEnvironment() const = 0; + + virtual Map *getMap() const = 0; + + virtual void setCacheMaxSize(unsigned int maxSize) = 0; + + virtual unsigned int getCacheMaxSize() const = 0; + + virtual void setCacheOptSize(unsigned int OptSize) = 0; + + virtual unsigned int getCacheOptSize() const = 0; + + + //new interfaces + + virtual Connection * createConnection(const UString &userName, + const UString &password, const UString &connectString) = 0; + + virtual ConnectionPool* createConnectionPool( + const UString &poolUserName, + const UString &poolPassword, const UString &connectString, + unsigned int minConn =0, + unsigned int maxConn =1, unsigned int incrConn =1) = 0; + + virtual Connection* getXAConnection(const + OCCI_STD_NAMESPACE::string& dbname) = 0; + + virtual void releaseXAConnection(Connection* conn) =0; + + virtual StatelessConnectionPool* createStatelessConnectionPool( + const OCCI_STD_NAMESPACE::string &poolUserName, + const OCCI_STD_NAMESPACE::string &poolPassword, + const OCCI_STD_NAMESPACE::string &connectString = "", + unsigned int maxConn = 1, unsigned int minConn = 0, + unsigned int incrConn = 1, + StatelessConnectionPool::PoolType pType + = StatelessConnectionPool::HETEROGENEOUS) = 0; + + virtual StatelessConnectionPool* createStatelessConnectionPool( + const UString &poolUserName, + const UString &poolPassword, + const UString &connectString, + unsigned int maxConn = 1, unsigned int minConn = 0, + unsigned int incrConn = 1, + StatelessConnectionPool::PoolType pType + = StatelessConnectionPool::HETEROGENEOUS) = 0; + + virtual void terminateStatelessConnectionPool(StatelessConnectionPool *poolp, + StatelessConnectionPool::DestroyMode mode = StatelessConnectionPool::DEFAULT) + = 0; + virtual void setLDAPAuthentication(unsigned int mode) =0; + + virtual unsigned int getLDAPAuthentication() const =0; + + virtual void setLDAPLoginNameAndPassword( + const OCCI_STD_NAMESPACE::string &login, + const OCCI_STD_NAMESPACE::string &passwd) =0; + + virtual void setLDAPAdminContext(const OCCI_STD_NAMESPACE::string &ctx)=0; + + virtual OCCI_STD_NAMESPACE::string getLDAPAdminContext() const =0; + + virtual void setLDAPHostAndPort(const OCCI_STD_NAMESPACE::string &host, + unsigned int port) =0; + + virtual OCCI_STD_NAMESPACE::string getLDAPHost() const =0; + + virtual unsigned int getLDAPPort() const =0; + + virtual void registerSubscriptions( + const OCCI_STD_NAMESPACE::vector& sub) =0; + + virtual void unregisterSubscription(const aq::Subscription& sub) =0; + + virtual void enableSubscription(const aq::Subscription& sub) =0; + + virtual void disableSubscription(const aq::Subscription& sub) =0; + + virtual bool getCacheSortedFlush() const = 0; + + virtual void setCacheSortedFlush(bool flag) = 0; + + virtual Connection * createConnection( + const OCCI_STD_NAMESPACE::string &userName, + const OCCI_STD_NAMESPACE::string &password, + const OCCI_STD_NAMESPACE::string &connectString, + const OCCI_STD_NAMESPACE::string &connectionClass, + const Connection::Purity purity) = 0; + + virtual Connection * createConnection(const UString &userName, + const UString &password, const UString &connectString, + const UString &connectionclass, + const Connection::Purity purity) =0; + + private: + +}; + + + +class Map +{ + public: + + virtual ~Map(){} + virtual void put(const OCCI_STD_NAMESPACE::string&, void *(*)(void *), + void (*)(void *, void *)) = 0; + virtual void getReadSQL( + void *, unsigned int, void *, unsigned int, void **) const = 0; + virtual void getWriteSQL( + void *, unsigned int, void *, unsigned int, void **) const = 0; + virtual void put(const OCCI_STD_NAMESPACE::string&, + const OCCI_STD_NAMESPACE::string&, void *(*)(void *), + void (*)(void *, void *)) = 0; + virtual void putUTF16(const OCCI_STD_NAMESPACE::string&, + const OCCI_STD_NAMESPACE::string&, void *(*)(void *), + void (*)(void *, void *)) = 0; + + private: +}; + + + +class SQLException : public OCCI_STD_NAMESPACE::exception +{ + public: + + virtual int getErrorCode() const; + + virtual OCCI_STD_NAMESPACE::string getMessage() const; + + const char *what() const throw(); + + virtual void setErrorCtx(void *ctx); + + SQLException(); + + SQLException(const SQLException &e); + + void operator=(const SQLException &other); + + virtual ~SQLException() throw(); + + virtual int getXAErrorCode(const OCCI_STD_NAMESPACE::string& dbname) const; + + virtual UString getUStringMessage() const; + + virtual OCCI_STD_NAMESPACE::string getNLSMessage(Environment *env) const; + + virtual UString getNLSUStringMessage(Environment *env) const; + + protected: + + Ptr ptr_; + SQLException(SQLExceptionImpl *ptr); + + friend SQLException SQLExceptionCreate(int errorCode); + friend SQLException SQLExceptionCreate(void *handle, + int handleType); + friend class BatchSQLException; +}; + +class BatchSQLException : public SQLException +{ + public: + virtual ~BatchSQLException() throw(); + + unsigned int getFailedRowCount() const; + unsigned int getRowNum( unsigned int index ) const; + SQLException getException ( unsigned int index ) const; + + private: + BatchSQLException(); + + BatchSQLException(SQLExceptionImpl *ptr); + friend BatchSQLException BatchSQLExceptionCreate(void *handle); +}; + +class Statement +{ + public: + // class constants + + virtual ~Statement() {} + + enum Status + { + UNPREPARED, + PREPARED, + RESULT_SET_AVAILABLE, + UPDATE_COUNT_AVAILABLE, + NEEDS_STREAM_DATA, + STREAM_DATA_AVAILABLE + }; + + // common methods + + virtual void setSQL(const OCCI_STD_NAMESPACE::string &sql) = 0; + + virtual OCCI_STD_NAMESPACE::string getSQL() const = 0; + + virtual Status execute(const OCCI_STD_NAMESPACE::string &sql = "") = 0; + + virtual ResultSet * getResultSet() = 0; + + virtual unsigned int getUpdateCount() const = 0; + + virtual ResultSet * executeQuery( + const OCCI_STD_NAMESPACE::string &sql = "") = 0; + + virtual unsigned int executeUpdate( + const OCCI_STD_NAMESPACE::string &sql = "") = 0; + + virtual Status status() const = 0; + + virtual void closeResultSet(ResultSet *resultSet) = 0; + + virtual void setPrefetchRowCount(unsigned int rowCount) = 0; + + virtual void setPrefetchMemorySize(unsigned int bytes) = 0; + + virtual void setAutoCommit(bool autoCommit) = 0; + + virtual bool getAutoCommit() const = 0; + + virtual OCIStmt * getOCIStatement() const = 0; + + + // methods for prepared statements with IN + // parameters + + virtual void setMaxParamSize(unsigned int paramIndex,unsigned int maxSize)=0; + + virtual unsigned int getMaxParamSize(unsigned int paramIndex) const = 0; + + virtual void setNull(unsigned int paramIndex, Type type) = 0; + + virtual void setInt(unsigned int paramIndex, int x) = 0; + + virtual void setUInt(unsigned int paramIndex, unsigned int x) = 0; + + virtual void setFloat(unsigned int paramIndex, float x) = 0; + + virtual void setDouble(unsigned int paramIndex, double x) = 0; + + virtual void setNumber(unsigned int paramIndex, const Number &x) = 0; + + virtual void setString(unsigned int paramIndex, + const OCCI_STD_NAMESPACE::string &x) = 0; + + virtual void setBytes(unsigned int paramIndex, const Bytes &x) = 0; + + virtual void setDate(unsigned int paramIndex, const Date &x) = 0; + + virtual void setTimestamp(unsigned int paramIndex, const Timestamp &x) = 0; + + virtual void setBlob(unsigned int paramIndex, const Blob &x) = 0; + + virtual void setClob(unsigned int paramIndex, const Clob &x) = 0; + + virtual void setBfile(unsigned int paramIndex, const Bfile &x) = 0; + + virtual void setIntervalYM(unsigned int paramIndex, const IntervalYM &x) = 0; + + virtual void setIntervalDS(unsigned int paramIndex, const IntervalDS &x) = 0; + + virtual void setRowid(unsigned int paramIndex, const Bytes &x) = 0; + + virtual void setRef(unsigned int paramIndex, const RefAny &x) = 0; + + virtual void setObject(unsigned int paramIndex, PObject * x) = 0; + + virtual void setDataBuffer(unsigned int paramIndex, void *buffer, + Type type, + sb4 size, ub2 *length, sb2 *ind = NULL, + ub2 *rc = NULL) = 0; + + virtual void setDataBufferArray(unsigned int paramIndex, void *buffer, + Type type, + ub4 arraySize, ub4 *arrayLength, + sb4 elementSize, + ub2 *elementLength, sb2 *ind = NULL, + ub2 *rc = NULL) = 0; + + virtual void setCharSet(unsigned int paramIndex, + const OCCI_STD_NAMESPACE::string & charSet) = 0; + + virtual OCCI_STD_NAMESPACE::string getCharSet(unsigned int paramIndex) + const = 0; + + virtual void setDatabaseNCHARParam( + unsigned int paramIndex, bool isNCHAR) = 0; + + virtual bool getDatabaseNCHARParam(unsigned int paramIndex) const = 0; + + virtual void closeStream(Stream *stream) =0; + + virtual Stream * getStream(unsigned int paramIndex) = 0; + + virtual unsigned int getCurrentStreamParam() const = 0; + + virtual unsigned int getCurrentStreamIteration() const = 0; + + virtual void setBinaryStreamMode(unsigned int colIndex, + unsigned int size) =0; + + virtual void setCharacterStreamMode(unsigned int colIndex, + unsigned int size) =0; + + virtual void setMaxIterations(unsigned int maxIterations) = 0; + + virtual unsigned int getMaxIterations() const = 0; + + virtual void addIteration() = 0; + + virtual unsigned int getCurrentIteration() const = 0; + + virtual Status executeArrayUpdate(unsigned int arrayLength) = 0; + + + // methods for Callable Statements + + virtual void registerOutParam(unsigned int paramIndex, Type type, + unsigned int maxSize=0, const OCCI_STD_NAMESPACE::string &sqltype="") = 0; + + virtual bool isNull(unsigned int paramIndex) const = 0; + + virtual bool isTruncated(unsigned int paramIndex) const + =0; + + + virtual void setErrorOnNull(unsigned int paramIndex, + bool causeException) = 0; + + virtual void setErrorOnTruncate(unsigned int paramIndex, + bool causeException) = 0; + + virtual int preTruncationLength(unsigned int paramIndex) const + =0; + + + virtual int getInt(unsigned int paramIndex) = 0; + + virtual unsigned int getUInt(unsigned int paramIndex) = 0; + + virtual float getFloat(unsigned int paramIndex) = 0; + + virtual double getDouble(unsigned int paramIndex) = 0; + + virtual Number getNumber(unsigned int paramIndex) = 0; + + virtual OCCI_STD_NAMESPACE::string getString(unsigned int paramIndex) = 0; + + virtual Bytes getBytes(unsigned int paramIndex) = 0; + + virtual Date getDate(unsigned int paramIndex) = 0; + + virtual Timestamp getTimestamp(unsigned int paramIndex) = 0; + + virtual Bytes getRowid(unsigned int paramIndex) = 0; + + virtual PObject * getObject(unsigned int paramIndex) = 0; + + virtual Blob getBlob(unsigned int paramIndex) = 0; + + virtual Clob getClob(unsigned int paramIndex) = 0; + + virtual Bfile getBfile(unsigned int paramIndex) = 0; + + virtual IntervalYM getIntervalYM(unsigned int paramIndex) = 0; + + virtual IntervalDS getIntervalDS(unsigned int paramIndex) = 0; + + virtual RefAny getRef(unsigned int paramIndex) = 0; + + virtual ResultSet * getCursor(unsigned int paramIndex) = 0; + + virtual Connection* getConnection() const =0; + + //new interfaces + + virtual void setRef(unsigned int paramIndex, const RefAny &x, + const OCCI_STD_NAMESPACE::string &typName, + const OCCI_STD_NAMESPACE::string &schName = "") = 0; + + virtual void setSQLUString(const UString &sql) = 0; + + virtual UString getSQLUString() const = 0; + + virtual Status execute(const UString &sql) = 0; + + virtual ResultSet * executeQuery( + const UString &sql) = 0; + + virtual unsigned int executeUpdate( + const UString &sql) = 0; + + virtual void setBFloat(unsigned int paramIndex, const BFloat &fval) = 0; + + virtual void setBDouble(unsigned int paramIndex, const BDouble &dval) = 0; + + virtual void setUString(unsigned int paramIndex, + const UString &x) = 0; + + virtual void setCharSetUString(unsigned int paramIndex, + const UString & charSet) = 0; + + virtual UString getCharSetUString(unsigned int paramIndex) + const = 0; + + virtual void registerOutParam(unsigned int paramIndex, Type type, + unsigned int maxSize, const OCCI_STD_NAMESPACE::string &typName, + const OCCI_STD_NAMESPACE::string &schName) = 0; + + virtual void registerOutParam(unsigned int paramIndex, Type type, + unsigned int maxSize, const UString &typName, + const UString &schName) = 0; + + virtual BFloat getBFloat(unsigned int paramIndex) = 0; + + virtual BDouble getBDouble(unsigned int paramIndex) = 0; + + virtual UString getUString(unsigned int paramIndex) = 0; + + virtual void disableCaching() =0; + + virtual void setRef(unsigned int paramIndex, const RefAny &x, + const UString &typName, + const UString &schName) = 0; + + virtual void setBinaryStreamMode(unsigned int colIndex, + unsigned int size, bool INArg) =0; + + virtual void setCharacterStreamMode(unsigned int colIndex, + unsigned int size, bool INArg) =0; + + virtual void setNull(unsigned int paramIndex, Type type, + const OCCI_STD_NAMESPACE::string &typeName, + const OCCI_STD_NAMESPACE::string &schemaName = "") = 0; + + virtual void setNull(unsigned int paramIndex, Type type, + UString &typeName, UString &schemaName) = 0; + + virtual void setBatchErrorMode( bool batchErrorMode ) =0; + + virtual bool getBatchErrorMode( ) const =0; + +}; + + + +class ResultSet +{ + public: + // class constants + + enum Status + { + END_OF_FETCH = 0, + DATA_AVAILABLE, + STREAM_DATA_AVAILABLE + }; + virtual ~ResultSet(){} + + // public methods + + virtual Status next(unsigned int numRows = 1) = 0; + + virtual Status status() const = 0; + + virtual unsigned int getNumArrayRows() const = 0; + + virtual void cancel() = 0; + + virtual void setMaxColumnSize(unsigned int colIndex, unsigned int max) = 0; + + virtual unsigned int getMaxColumnSize(unsigned int colIndex) const = 0; + + virtual bool isNull(unsigned int colIndex) const = 0; + + virtual bool isTruncated(unsigned int paramIndex) const + =0; + + virtual void setErrorOnNull(unsigned int colIndex, bool causeException) = 0; + virtual void setErrorOnTruncate(unsigned int paramIndex, + bool causeException) =0; + + virtual int preTruncationLength(unsigned int paramIndex) const + =0; + + virtual int getInt(unsigned int colIndex) = 0; + + virtual unsigned int getUInt(unsigned int colIndex) = 0; + + virtual float getFloat(unsigned int colIndex) = 0; + + virtual double getDouble(unsigned int colIndex) = 0; + + virtual Number getNumber(unsigned int colIndex) = 0; + + virtual OCCI_STD_NAMESPACE::string getString(unsigned int colIndex) = 0; + + virtual Bytes getBytes(unsigned int colIndex) = 0; + + virtual Date getDate(unsigned int colIndex) = 0; + + virtual Timestamp getTimestamp(unsigned int colIndex) = 0; + + virtual Bytes getRowid(unsigned int colIndex) = 0; + + virtual PObject * getObject(unsigned int colIndex) = 0; + + virtual Blob getBlob(unsigned int colIndex) = 0; + + virtual Clob getClob(unsigned int colIndex) =0; + + virtual Bfile getBfile(unsigned int colIndex) = 0; + + virtual IntervalYM getIntervalYM(unsigned int colIndex) =0; + + virtual IntervalDS getIntervalDS(unsigned int colIndex) =0; + + virtual RefAny getRef(unsigned int colIndex) = 0; + + virtual Bytes getRowPosition() const = 0; + + virtual ResultSet * getCursor(unsigned int colIndex) = 0; + + virtual void setDataBuffer(unsigned int colIndex, void *buffer, Type type, + sb4 size = 0, ub2 *length = NULL, + sb2 *ind = NULL, ub2 *rc = NULL) = 0; + + virtual void setCharSet(unsigned int colIndex, + const OCCI_STD_NAMESPACE::string & charSet) = 0; + + virtual OCCI_STD_NAMESPACE::string getCharSet(unsigned int colIndex) + const = 0; + + virtual void setBinaryStreamMode(unsigned int colIndex, unsigned int size) + = 0; + + virtual void setCharacterStreamMode(unsigned int colIndex, unsigned int size) + = 0; + + virtual void setDatabaseNCHARParam(unsigned int paramIndex, + bool isNCHAR) = 0; + + virtual bool getDatabaseNCHARParam(unsigned int paramIndex) const = 0; + + virtual Stream * getStream(unsigned int colIndex) = 0; + + virtual void closeStream(Stream *stream) =0; + + virtual unsigned int getCurrentStreamColumn() const= 0; + + virtual unsigned int getCurrentStreamRow() const= 0; + + virtual OCCI_STD_NAMESPACE::vector getColumnListMetaData() const + = 0; + + virtual Statement* getStatement() const=0; + + //new interfaces + + virtual BFloat getBFloat(unsigned int colIndex) = 0; + + virtual BDouble getBDouble(unsigned int colIndex) = 0; + + virtual UString getUString(unsigned int colIndex) = 0; + + virtual void setCharSetUString(unsigned int colIndex, + const UString & charSet) = 0; + + virtual UString getCharSetUString(unsigned int colIndex) + const = 0; + +}; + + +class Stream +{ + public : + + enum Status {READY_FOR_READ, READY_FOR_WRITE, INACTIVE}; + + virtual ~Stream(){} + virtual int readBuffer(char *buffer, unsigned int size) + =0; + virtual int readLastBuffer(char *buffer, unsigned int size) + =0; + virtual void writeBuffer(char *buffer, unsigned int size) + =0; + virtual void writeLastBuffer(char *buffer, unsigned int size) + =0; + virtual Status status() const =0; + +}; + +/*--------------------------------------------------------------------------- + PROTOTYPES USED BY FUNCTION TEMPLATES + -------------------------------------------------------------------------*/ + void getVectorOfPObjects( ResultSet *rs, unsigned int index, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVectorOfOCIRefs(ResultSet *rs, unsigned int index, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVectorOfPObjects( Statement *rs, unsigned int index, + OCCI_STD_NAMESPACE::vector &vect) ; + void getVectorOfOCIRefs(Statement *rs, unsigned int index, + OCCI_STD_NAMESPACE::vector &vect) ; + void setVectorOfPObjects( Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &sqltype) ; + void setVectorOfPObjects( Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &schemaName, + const OCCI_STD_NAMESPACE::string &typeName) ; + void setVectorOfPObjects( Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const UString &schemaName, + const UString &typeName) ; + void setVectorOfOCIRefs(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::vector &vecind, + const OCCI_STD_NAMESPACE::string &sqltype) ; + void setVectorOfOCIRefs(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::vector &vecind, + const OCCI_STD_NAMESPACE::string &schemaName, + const OCCI_STD_NAMESPACE::string &typeName) ; + void setVectorOfOCIRefs(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::vector &vecind, + const UString &schemaName, + const UString &typeName) ; + void pinVectorOfOCIRefs(const Connection *conn, + OCCI_STD_NAMESPACE::vector & vecRef, + OCCI_STD_NAMESPACE::vector & vecCor, + OCCI_STD_NAMESPACE::vector &vecPObj,LockOptions &lockOpt ); + + +/*--------------------------------------------------------------------------- + EXPORT FUNCTIONS + ---------------------------------------------------------------------------*/ + +/*------------------------ getVector for objects ---------------------------*/ +/* + NAME + getVector - overloaded function. Retrieves the attribute in the current +position as a vector of objects + + PARAMETERS + rs - ResultSet + vect- reference to vector of objects(OUT parameter). + + DESCRIPTION + Retrieves the column in the specified position as a vector of RefAny. + The attribute at the current position should be a collection type (varray or + nested table). The SQL type of the elements in the collection should be + compatible with objects. + + RETURNS + nothing + + NOTES + compatible SQL types : NTY + + will call getVector(..., vector) +*/ +#if defined(WIN32COMMON) || defined(__MVS__) +// and other platforms that do not support +// partial function template specialization + +template +void getVector( ResultSet *rs, unsigned int index,OCCI_STD_NAMESPACE::vector +& vect) +{ + OCCI_STD_NAMESPACE::vector vec_pobj; + getVectorOfPObjects(rs, index, vec_pobj); + + vect.clear(); + unsigned int size = vec_pobj.size(); + vect.reserve( size ); + for ( unsigned int i=0; i< size; i++) + vect.push_back((T)vec_pobj[i]); +} + +#else +template +void getVector( ResultSet *rs, unsigned int index, OCCI_STD_NAMESPACE::vector &vect) +{ + OCCI_STD_NAMESPACE::vector vec_pobj; + getVectorOfPObjects(rs, index, vec_pobj); + + vect.clear(); + unsigned int size = vec_pobj.size(); + vect.reserve( size ); + for (unsigned int i=0; i< size; i++) + vect.push_back((T *)vec_pobj[i]); +} +#endif + +/*------------------------ getVector for objects ---------------------------*/ +/* + NAME + getVector - overloaded function. Retrieves the attribute in the current +position as a vector of objects + + PARAMETERS + stmt - Statement + vect- reference to vector of objects(OUT parameter). + + DESCRIPTION + Retrieves the column in the specified position as a vector of RefAny. + The attribute at the current position should be a collection type (varray or + nested table). The SQL type of the elements in the collection should be + compatible with objects. + + RETURNS + nothing + + NOTES + compatible SQL types : NTY + + will call getVector(..., vector) +*/ +#if defined(WIN32COMMON) || defined(__MVS__) +// and other platforms that do not support +// partial function template specialization + +template +void getVector( Statement *stmt, unsigned int index, +OCCI_STD_NAMESPACE::vector &vect) +{ + OCCI_STD_NAMESPACE::vector vec_pobj; + getVectorOfPObjects(stmt, index, vec_pobj); + vect.clear(); + unsigned int size = vec_pobj.size(); + vect.reserve( size ); + for (unsigned int i=0; i< size; i++) + vect.push_back((T)vec_pobj[i]); +} +#else +template +void getVector( Statement *stmt, unsigned int index, +OCCI_STD_NAMESPACE::vector &vect) +{ + OCCI_STD_NAMESPACE::vector vec_pobj; + getVectorOfPObjects(stmt, index, vec_pobj); + vect.clear(); + unsigned int size = vec_pobj.size(); + vect.reserve( size ); + for (unsigned int i=0; i< size; i++) + vect.push_back((T *)vec_pobj[i]); +} +#endif + +/*------------------------ getVector for Ref ---------------------------*/ +/* + NAME + getVector - overloaded function. Retrieves the attribute in the current +position as a vector of Ref + + PARAMETERS + rs - ResultSet + vect- reference to vector of Ref(OUT parameter). + + DESCRIPTION + Retrieves the column in the specified position as a vector of Ref. + The attribute at the current position should be a collection type (varray or + nested table). The SQL type of the elements in the collection should be + compatible with Ref. + + RETURNS + nothing + + NOTES + compatible SQL types : REF +*/ +#if !defined(WIN32COMMON) && !defined(__MVS__) +template +void getVector( ResultSet *rs, unsigned int index, + OCCI_STD_NAMESPACE::vector > &vect) +{ + OCCI_STD_NAMESPACE::vector vec_ref; + getVectorOfOCIRefs(rs, index, vec_ref); + + const Connection *sess = rs->getStatement()->getConnection(); + + vect.clear(); + unsigned int size = vec_ref.size(); + vect.reserve( size ); + for (unsigned int i=0; i< size; i++) + { + if (vec_ref[i] == (OCIRef *)0) + vect.push_back(Ref()); // pushing a default-constructed Ref + else + vect.push_back(Ref(sess, (OCIRef *)vec_ref[i], FALSE)); + } +} +#endif + +/*------------------------ setVector for PObject*---------------------------*/ +/* + NAME + SetVector - overloaded function. Binds the attribute in the current + position with a vector of objects. + + PARAMETERS + rs - ResultSet + vect- reference to vector of objects(OUT parameter). + + DESCRIPTION + Binds the column in the specified position with a vector of signed int . + The column at the current position should be a collection type (varray or + nested table). The SQL type of the elements in the collection should be + compatible with objects . + + RETURNS + nothing + + NOTES + compatible SQL types : SQLT_NTY + + This will be calling setVector(..., vector,..) + +*/ +#if defined(WIN32COMMON) || defined(__MVS__) +// and other platforms that do not support +// partial function template specialization + +template +void setVector( Statement *stmt, unsigned int index, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::string &sqltype) +{ + OCCI_STD_NAMESPACE::vector vec_pobj; + unsigned int size = vect.size(); + vec_pobj.reserve( size ); + + for (unsigned int i = 0; i < size; i++) + vec_pobj.push_back((PObject *)vect[i]); + + setVectorOfPObjects(stmt, index, vec_pobj, sqltype); +} + +template +void setVector( Statement *stmt, unsigned int index, const OCCI_STD_NAMESPACE:: +vector &vect, const OCCI_STD_NAMESPACE::string &schemaName, +const OCCI_STD_NAMESPACE::string &typeName) +{ + OCCI_STD_NAMESPACE::vector vec_pobj; + unsigned int size = vect.size(); + vec_pobj.reserve( size ); + + for (unsigned int i = 0; i < size; i++) + vec_pobj.push_back((PObject *)vect[i]); + + setVectorOfPObjects(stmt, index, vec_pobj, schemaName, typeName); +} + +template +void setVector( Statement *stmt, unsigned int index, const OCCI_STD_NAMESPACE:: +vector &vect, const UString &schemaName, +const UString &typeName) +{ + OCCI_STD_NAMESPACE::vector vec_pobj; + unsigned int size = vect.size(); + vec_pobj.reserve( size ); + + for (unsigned int i = 0; i < size; i++) + vec_pobj.push_back((PObject *)vect[i]); + + setVectorOfPObjects(stmt, index, vec_pobj, schemaName, typeName); +} +#else +template +void setVector( Statement *stmt, unsigned int index, const OCCI_STD_NAMESPACE:: +vector &vect, const OCCI_STD_NAMESPACE::string &sqltype) +{ + OCCI_STD_NAMESPACE::vector vec_pobj; + unsigned int size = vect.size(); + vec_pobj.reserve( size ); + + for (unsigned int i = 0; i < size; i++) + vec_pobj.push_back((PObject *)vect[i]); + + setVectorOfPObjects(stmt, index, vec_pobj, sqltype); +} + +template +void setVector( Statement *stmt, unsigned int index, const OCCI_STD_NAMESPACE:: +vector &vect, const OCCI_STD_NAMESPACE::string &schemaName, +const OCCI_STD_NAMESPACE::string &typeName) +{ + OCCI_STD_NAMESPACE::vector vec_pobj; + unsigned int size = vect.size(); + vec_pobj.reserve( size ); + + for (unsigned int i = 0; i < size; i++) + vec_pobj.push_back((PObject *)vect[i]); + + setVectorOfPObjects(stmt, index, vec_pobj, schemaName, typeName); +} + +template +void setVector( Statement *stmt, unsigned int index, const OCCI_STD_NAMESPACE:: +vector &vect, const UString &schemaName, +const UString &typeName) +{ + OCCI_STD_NAMESPACE::vector vec_pobj; + unsigned int size = vect.size(); + vec_pobj.reserve( size ); + + for (unsigned int i = 0; i < size; i++) + vec_pobj.push_back((PObject *)vect[i]); + + setVectorOfPObjects(stmt, index, vec_pobj, schemaName, typeName); +} +#endif + +/*------------------------ setVector for Ref---------------------------*/ +/* + NAME + setVector - overloaded function. Binds the attribute in the current + position with a vector of Ref. + + PARAMETERS + rs - ResultSet + vect- reference to vector of REF + + DESCRIPTION + Binds the column in the specified position with a vector of signed int . + The column at the current position should be a collection type (varray or + nested table). The SQL type of the elements in the collection should be + compatible with OCIRef* . + + RETURNS + nothing + + NOTES + compatible SQL types : REF + + This will just call setVector(..., vector,..) + + +*/ +#if !defined(WIN32COMMON) && !defined(__MVS__) +template +void setVector( Statement *stmt, unsigned int index, + const OCCI_STD_NAMESPACE::vector > &vect, + const OCCI_STD_NAMESPACE::string &sqltype) +{ + OCCI_STD_NAMESPACE::vector vec_ref; + OCCI_STD_NAMESPACE::vector vec_ind; + unsigned int size = vect.size(); + vec_ref.reserve( size ); + vec_ind.reserve( size ); + + for (unsigned int i = 0; i < size; i++) + { + vec_ref.push_back((void *)vect[i].getRef()); + vec_ind.push_back( vect[i].isNull() ? OCI_IND_NULL : OCI_IND_NOTNULL); + } + + setVectorOfOCIRefs(stmt, index, vec_ref, vec_ind, sqltype); +} + +template +void setVector( Statement *stmt, unsigned int index, + const OCCI_STD_NAMESPACE::vector > &vect, + const OCCI_STD_NAMESPACE::string &schemaName, + const OCCI_STD_NAMESPACE::string &typeName) +{ + OCCI_STD_NAMESPACE::vector vec_ref; + OCCI_STD_NAMESPACE::vector vec_ind; + unsigned int size = vect.size(); + vec_ref.reserve( size ); + vec_ind.reserve( size ); + + for (unsigned int i = 0; i < size; i++) + { + vec_ref.push_back((void *)vect[i].getRef()); + vec_ind.push_back( vect[i].isNull() ? OCI_IND_NULL : OCI_IND_NOTNULL); + } + + setVectorOfOCIRefs(stmt, index, vec_ref, vec_ind, schemaName, typeName); +} + +template +void setVector( Statement *stmt, unsigned int index, + const OCCI_STD_NAMESPACE::vector > &vect, + const UString &schemaName, + const UString &typeName) +{ + OCCI_STD_NAMESPACE::vector vec_ref; + OCCI_STD_NAMESPACE::vector vec_ind; + unsigned int size = vect.size(); + vec_ref.reserve( size ); + vec_ind.reserve( size ); + + for (unsigned int i = 0; i < size; i++) + { + vec_ref.push_back((void *)vect[i].getRef()); + vec_ind.push_back( vect[i].isNull() ? OCI_IND_NULL : OCI_IND_NOTNULL); + } + + setVectorOfOCIRefs(stmt, index, vec_ref, vec_ind, schemaName, typeName); +} +#endif + +/*------------------------ getVector for Ref ---------------------------*/ +/* + NAME + getVector - overloaded function. Retrieves the attribute in the current +position as a vector of Ref + + PARAMETERS + stmt - Statement + vect- reference to vector of Ref(OUT parameter). + + DESCRIPTION + Retrieves the column in the specified position as a vector of Ref. + The attribute at the current position should be a collection type (varray or + nested table). The SQL type of the elements in the collection should be + compatible with Ref. + + RETURNS + nothing + + NOTES + compatible SQL types : REF +*/ +#if !defined(WIN32COMMON) && !defined(__MVS__) +template +void getVector( Statement *stmt, unsigned int index, + OCCI_STD_NAMESPACE::vector > &vect) +{ + OCCI_STD_NAMESPACE::vector vec_ref; + getVectorOfOCIRefs(stmt, index, vec_ref); + + const Connection *sess = stmt->getConnection(); + + vect.clear(); + unsigned int size = vec_ref.size(); + vect.reserve( size ); + for (unsigned int i=0; i< size; i++) + { + if (vec_ref[i] == (OCIRef *)0) + vect.push_back(Ref ()); // pushing a default-constructed Ref + else + vect.push_back(Ref (sess, (OCIRef *)vec_ref[i], FALSE)); + } + +} +#endif + +// Platform independent get/setVectorOfRefs method added +// get(set)Vector of Ref and get(set)VectorOfRefs are identical +// in functionality. + +/*------------------------ getVectorOfRefs for Ref ----------------------*/ +/* + NAME + getVectorOfRefs - overloaded function. Retrieves the attribute in the + current position as a vector of Ref + + PARAMETERS + rs - ResultSet + vect- reference to vector of Ref(OUT parameter). + + DESCRIPTION + Retrieves the column in the specified position as a vector of Ref. + The attribute at the current position should be a collection type (varray or + nested table). The SQL type of the elements in the collection should be + compatible with Ref. + + RETURNS + nothing + + NOTES + compatible SQL types : REF +*/ + +template +void getVectorOfRefs( ResultSet *rs, unsigned int index, +OCCI_STD_NAMESPACE::vector > &vect) +{ + OCCI_STD_NAMESPACE::vector vec_ref; + getVectorOfOCIRefs(rs, index, vec_ref); + + const Connection *sess = rs->getStatement()->getConnection(); + + vect.clear(); + unsigned int size = vec_ref.size(); + vect.reserve( size ); + for (unsigned int i=0; i< size; i++) + { + if (vec_ref[i] == (OCIRef *)0) + vect.push_back(Ref()); // pushing a default-constructed Ref + else + vect.push_back(Ref(sess, (OCIRef *)vec_ref[i], FALSE)); + } +} + +/*------------------------ setVectorOfRefs for Ref-----------------------*/ +/* + NAME + setVectorOfRefs - overloaded function. Binds the attribute in the current + position with a vector of Ref. + + PARAMETERS + rs - ResultSet + vect- reference to vector of REF + + DESCRIPTION + Binds the column in the specified position with a vector of signed int . + The column at the current position should be a collection type (varray or + nested table). The SQL type of the elements in the collection should be + compatible with OCIRef* . + + RETURNS + nothing + + NOTES + compatible SQL types : REF + + This will just call setVector(..., vector,..) + + +*/ + +template +void setVectorOfRefs( Statement *stmt, unsigned int index, +const OCCI_STD_NAMESPACE::vector > &vect, +const OCCI_STD_NAMESPACE::string &sqltype) +{ + OCCI_STD_NAMESPACE::vector vec_ref; + OCCI_STD_NAMESPACE::vector vec_ind; + unsigned int size = vect.size(); + vec_ref.reserve( size ); + vec_ind.reserve( size ); + + for (unsigned int i = 0; i < size; i++) + { + vec_ref.push_back((void *)vect[i].getRef()); + vec_ind.push_back( vect[i].isNull() ? OCI_IND_NULL : OCI_IND_NOTNULL); + } + + setVectorOfOCIRefs(stmt, index, vec_ref, vec_ind, sqltype); +} + +template +void setVectorOfRefs( Statement *stmt, unsigned int index, +const OCCI_STD_NAMESPACE::vector > &vect, +const OCCI_STD_NAMESPACE::string &schemaName, +const OCCI_STD_NAMESPACE::string &typeName) +{ + OCCI_STD_NAMESPACE::vector vec_ref; + OCCI_STD_NAMESPACE::vector vec_ind; + unsigned int size = vect.size(); + vec_ref.reserve( size ); + vec_ind.reserve( size ); + + for (unsigned int i = 0; i < size; i++) + { + vec_ref.push_back((void *)vect[i].getRef()); + vec_ind.push_back( vect[i].isNull() ? OCI_IND_NULL : OCI_IND_NOTNULL); + } + + setVectorOfOCIRefs(stmt, index, vec_ref, vec_ind, schemaName, typeName); +} + +template +void setVectorOfRefs( Statement *stmt, unsigned int index, +const OCCI_STD_NAMESPACE::vector > &vect, +const UString &schemaName, +const UString &typeName) +{ + OCCI_STD_NAMESPACE::vector vec_ref; + OCCI_STD_NAMESPACE::vector vec_ind; + unsigned int size = vect.size(); + vec_ref.reserve( size ); + vec_ind.reserve( size ); + + for (unsigned int i = 0; i < size; i++) + { + vec_ref.push_back((void *)vect[i].getRef()); + vec_ind.push_back( vect[i].isNull() ? OCI_IND_NULL : OCI_IND_NOTNULL); + } + + setVectorOfOCIRefs(stmt, index, vec_ref, vec_ind, schemaName, typeName); +} + +/*------------------------ getVectorOfRefs for Ref ----------------------*/ +/* + NAME + getVectorOfRefs - overloaded function. Retrieves the attribute in the + current position as a vector of Ref + + PARAMETERS + stmt - Statement + vect- reference to vector of Ref(OUT parameter). + + DESCRIPTION + Retrieves the column in the specified position as a vector of Ref. + The attribute at the current position should be a collection type (varray or + nested table). The SQL type of the elements in the collection should be + compatible with Ref. + + RETURNS + nothing + + NOTES + compatible SQL types : REF +*/ + +template +void getVectorOfRefs( Statement *stmt, unsigned int index, +OCCI_STD_NAMESPACE::vector > &vect) +{ + OCCI_STD_NAMESPACE::vector vec_ref; + getVectorOfOCIRefs(stmt, index, vec_ref); + + const Connection *sess = stmt->getConnection(); + + vect.clear(); + unsigned int size = vec_ref.size(); + vect.reserve( size ); + for (unsigned int i=0; i< size; i++) + { + if (vec_ref[i] == (OCIRef *)0) + vect.push_back(Ref ()); // pushing a default-constructed Ref + else + vect.push_back(Ref (sess, (OCIRef *)vec_ref[i], FALSE)); + } +} +/*----------------------------- pinVectorOfRefs---------------------*/ +/* + NAME + pinVectorOfRefs - array pin implementation + + PARAMETERS + conn- Connection object + vecRef - vector of OCIRefs * + vecCor - vector of OCIComplexObject * + vecPOBj - vector of PObject * ( OUT ) + + DESCRIPTION + implements the array pin of refs passed and returns the corresponding + PObject s + + RETURNS + + NOTES +*/ +template +void pinVectorOfRefs( const Connection *conn, +OCCI_STD_NAMESPACE::vector > &vect, +OCCI_STD_NAMESPACE::vector &vectObj, LockOptions lockOpt) +{ + + OCCI_STD_NAMESPACE::vector vecRef; + OCCI_STD_NAMESPACE::vector vecCor; + OCCI_STD_NAMESPACE::vector vecPObj; + unsigned int sz = vect.size(); + vecRef.reserve( sz ); + vecCor.reserve( sz ); + + for ( unsigned int i=0; i < sz; i++) + { + vecRef.push_back((void *)vect[i].getRef()); + vecCor.push_back((void *)vect[i].getCor()); + } + pinVectorOfOCIRefs(conn, vecRef, vecCor, vecPObj, lockOpt); + for ( unsigned int k=0; k < sz; k++) + { + vectObj.push_back((T *)vecPObj[k]); + vect[k].setPinnedObject(vecPObj[k]); + } +} + +/*----------------------------- pinVectorOfRefs---------------------*/ +/* + NAME + pinVectorOfRefs - array pin implementation + + PARAMETERS + conn- Connection object + vecRef - vector of OCIRefs * + vecCor - vector of OCIComplexObject * + + DESCRIPTION + implements the array pin of refs passed + + RETURNS + + NOTES +*/ +template +void pinVectorOfRefs( const Connection *conn, +OCCI_STD_NAMESPACE::vector > &vect, +LockOptions lockOpt) +{ + + OCCI_STD_NAMESPACE::vector vecRef; + OCCI_STD_NAMESPACE::vector vecCor; + OCCI_STD_NAMESPACE::vector vecPObj; + unsigned int sz = vect.size(); + vecRef.reserve( sz ); + vecCor.reserve( sz ); + + for ( unsigned int i=0; i < sz; i++) + { + vecRef.push_back((void *)vect[i].getRef()); + vecCor.push_back((void *)vect[i].getCor()); + } + pinVectorOfOCIRefs(conn, vecRef, vecCor,vecPObj, lockOpt); + for ( unsigned int k=0; k < sz; k++) + vect[k].setPinnedObject(vecPObj[k]); +} + + + +/*--------------------------------------------------------------------------- + INTERNAL FUNCTIONS + ---------------------------------------------------------------------------*/ + + +} /* end of namespace occi */ +} /* end of namespace oracle */ +#endif /* OCCICONTROL_ORACLE */ + +#endif /* _olint */ diff --git a/libodbc/include/ora_linux/occiData.h b/libodbc/include/ora_linux/occiData.h new file mode 100644 index 0000000000..c0865a9362 --- /dev/null +++ b/libodbc/include/ora_linux/occiData.h @@ -0,0 +1,1162 @@ +/* Copyright (c) 2000, 2006, Oracle. All rights reserved. */ + +/* + NAME + occiData.h - header file for OCCI data classes + + DESCRIPTION + Class definitions for Stream, Blob, Clob ,Bfile, + Number, Date, IntervalYM, IntervalDS, Time, + Timestamp + + RELATED DOCUMENTS + + + EXPORT FUNCTION(S) + + + INTERNAL FUNCTION(S) + + + EXAMPLES + + NOTES + + + MODIFIED (MM/DD/YY) + slynn 09/14/06 - Remove string.clear() + slynn 07/28/06 - Migrate to new 11g LOB terminology + slynn 06/21/06 - Add LobRegion + slynn 05/25/06 - New NG Lob Functionality. + cparampa 09/06/04 - Date changes + shiyer 10/31/03 - Timestamp constructors issue + rvallam 10/07/03 - bug 3089939 - add private method in Date to compute + hour and min component in daysBetween to be passed + to set method of IntervalDS. + cparampa 08/21/03 - added toCopy to IntervalDS and IntervalYM + cparampa 07/14/03 - make SubscriptionImpl friend of Bytes class. + rvallam 02/12/03 - modified BFloat/BDouble interface - BFloat/BDouble + type is now a struct + cparampa 01/20/03 - made ProducerImpl friend of Bytes class + rvallam 11/19/02 - objects support for interval class + shiyer 11/15/02 - Add UTF16 support to IntervalYM & IntervalDS + cparampa 12/11/02 - removed references to class Payload + cparampa 10/12/02 - AQ additions + shiyer 10/12/02 - Added UTF16 version of get/set CharsetId in Clob + shiyer 09/06/02 - OCCI globalization support + aahluwal 06/04/02 - bug 2360115 + vvinay 02/21/02 - operator= added for Bytes + gayyappa 10/23/01 - fix bug 2073327 , use string instead of + enum CharSet + vvinay 12/21/01 - signed char constructor and cast operator + (bug 2073334) + binary operator methods not friends any more + gayyappa 15/10/01 - add parameter toCopy to Lob/Timestamp private + constructors + rvallam 04/09/01 - change private constructor in Number to pass + parameter by reference and made it const + chliang 03/05/01 - disable olint + rvallam 01/27/02 - remove #include + gayyappa 01/17/01 - add methods/operators to Interval and + timestamp classes.. + gayyappa 12/15/00 - interface changes in set methods + rvallam 11/29/00 - change method signature in Bytes + added 3 new methods in Number + rvallam 10/20/00 - change method signatures in Date + rvallam 09/15/00 - make StmtImpl/ResultSetImpl friend to + interval classes + gayyappa 08/21/00 - modified timestamp, interval headers. + add OCIEnv to constructor of Bytes., + removed getOCIRaw from Bytes. + add const to setVector mthds of anydata. + add void* data member to Timestamp/Interval. + rvallam 08/10/00 - modified CORE class headers to add friends , + added private constructor in Bytes + slari 08/02/00 - comment out Stream + rratnam 08/04/00 - updated the LOB stream interface + rkasamse 08/07/00 - make getVector friend of Time + slari 07/31/00 - add const to Bytes methods + slari 07/25/00 - disable Bytes(Bytes *) + slari 07/23/00 - add Bytes + gayyappa 07/26/00 - update Timestamp, IntervalYM, IntervalDS. + gayyappa 07/04/00 - for fixing a problem in occiNumber + rratnam 06/13/00 - Updated LOB class headers + kmohan 05/31/00 - Change Environment to Environment * in + Date constructor + kmohan 05/29/00 - No string + rkasamse 04/25/00 - Added string class header + etucker 04/19/00 - Added CORE class headers + kmohan 04/11/00 - Creation + +*/ + +#ifndef _olint /* disable olint check */ + +#ifndef OCCIDATA_ORACLE +# define OCCIDATA_ORACLE + +#ifndef OCCICOMMON_ORACLE +#include +#endif + +#ifndef OCCICONTROL_ORACLE +#include +#endif + +namespace oracle { +namespace occi { +class Bytes +{ + + public: + + Bytes(const Environment *env = NULL); // default constructor + + Bytes(unsigned char *value, unsigned int count, + unsigned int offset = 0, const Environment *env = NULL); + + Bytes(const Bytes &e); // copy constructor + + + // public methods + + void getBytes(unsigned char *dst, unsigned int count, + unsigned int srcBegin = 0, + unsigned int dstBegin = 0) const; + + unsigned int length() const; + + unsigned char byteAt(unsigned int index) const; + + bool isNull() const; + + void setNull(); + + void operator=(const Bytes &other); + + ~Bytes(); + +private: + // private data members + Bytes(OCIEnv *,OCIRaw *) ; + Bytes(Ptr bytesPtr) ; + Ptr ptr_; + friend class AnyDataImpl; + friend class aq::MessageImpl; + friend class aq::ProducerImpl; + friend class aq::SubscriptionImpl; + friend void getVector(const AnyData &any, + OCCI_STD_NAMESPACE::vector &vect) ; + friend void setVector(AnyData &any, + const OCCI_STD_NAMESPACE::vector &vect) ; + +}; + +class Bfile +{ + public : + + Bfile(); + Bfile(const Connection *connectionp) ; + Bfile(const Bfile &srcBfile) ; + ~Bfile(); + unsigned int length() const ; + OCCI_STD_NAMESPACE::string getDirAlias() const ; + UString getUStringDirAlias() const ; + OCCI_STD_NAMESPACE::string getFileName() const ; + UString getUStringFileName() const ; + void setName(const OCCI_STD_NAMESPACE::string &dirAlias, + const OCCI_STD_NAMESPACE::string &fileName) ; + void setName(const UString &dirAlias, const UString &fileName) ; + bool fileExists() const ; + Bfile& operator =(const Bfile &srcBfile) ; + bool operator ==(const Bfile &srcBfile) const ; + bool operator !=(const Bfile &srcBfile) const ; + void setNull() ; + bool isNull() const ; + bool isInitialized() const; + void open() ; + void close() ; + bool isOpen() const ; + unsigned int read(unsigned int amt, unsigned char *buffer, + unsigned int bufsize, unsigned int offset = 1) const ; + Stream* getStream(unsigned int offset = 1, + unsigned int amount =0) ; + void closeStream(Stream *stream); + + private: + + //Data Members: + + // pointer to the FILE locator + OCIBFileLocator *filep; + + // pointer to the ConnectionImpl instance + const ConnectionImpl *connp; + + // pointer to the LobStreamImpl instance obtained from this FILE + LobStreamImpl *streamp; + + void *bfileExt; + + //Enumerations: + enum {MAXDIRNAMELEN = 32, MAXFILENAMELEN = 256}; + + //Constructor: + Bfile(const Connection *connectionp, + OCIBFileLocator *locatorp, bool toCopy = true) ; + + //Methods: + OCIBFileLocator* getLocator() const; + void do_getDirAlias( void * dirAlias, ub2 * dirAliasLen) const ; + void do_getFileName( void * fileName, ub2 * fileNameLen) const ; + void do_setName( void * alias, ub2 aliasLen, + void *fileName, ub2 fileNameLen); + // Friends + friend class AnyDataImpl; + friend class StatementImpl; + friend class ResultSetImpl; + friend class Blob; + friend class Clob; + friend class aq::MessageImpl; + + friend void getVector(const AnyData&, OCCI_STD_NAMESPACE::vector&) ; + friend void getVector(Statement*, unsigned int, + OCCI_STD_NAMESPACE::vector&) ; + friend void getVector(ResultSet*, unsigned int , + OCCI_STD_NAMESPACE::vector&) ; + friend void setVector(AnyData&, const OCCI_STD_NAMESPACE::vector&) ; + friend void do_setVectorOfBfile(Statement*, unsigned int, + const OCCI_STD_NAMESPACE::vector&, void *, unsigned int, + void *, unsigned int ) ; + +#ifdef ORAXB8_DEFINED + friend void readVectorOfBfiles(const Connection *conn, + OCCI_STD_NAMESPACE::vector &vec, + oraub8 *byte_amts, oraub8 *offsets, + unsigned char *buffers[], oraub8 *buffer_lens); +#endif +}; + + +#ifdef ORAXB8_DEFINED +// See the end of this file for implementation of LobRegion +template < typename lobType > class LobRegion +{ + private: + lobType *_primary; + oraub8 _primaryOffset; + oraub8 _offset; + oraub8 _length; + OCCI_STD_NAMESPACE::string _mimeType; + + void setPrimary(const ConnectionImpl *connp, + OCILobLocator *locator); + + public: + LobRegion(); + ~LobRegion(); + lobType *getPrimary(); + oraub8 getPrimaryOffset(); + oraub8 getOffset(); + oraub8 getLength(); + OCCI_STD_NAMESPACE::string getMimeType(); + + friend class Blob; + friend class Clob; +}; + +typedef LobRegion BlobRegion; +typedef LobRegion ClobRegion; +#endif + + +class Blob +{ + public: + + Blob(); + Blob(const Connection *connectionp) ; + Blob(const Blob &srcBlob) ; + ~Blob(); + unsigned int getChunkSize() const ; + unsigned int length() const ; + Blob& operator =(const Blob &srcBlob) ; + bool operator ==(const Blob &srcBlob) const ; + bool operator !=(const Blob &srcBlob) const ; + void setNull() ; + bool isNull() const ; + void setEmpty() ; + void setEmpty(const Connection *connectionp) ; + bool isInitialized() const; + void open(LobOpenMode mode=OCCI_LOB_READWRITE) ; + void close() ; + bool isOpen() const ; + void copy(const Blob &srcBlob, unsigned int numBytes, + unsigned int dstOffset =1, unsigned int srcOffset =1) ; + void copy(const Bfile &srcBfile, unsigned int numBytes, + unsigned int dstOffset =1, unsigned int srcOffset =1) ; + void append(const Blob &srcBlob) ; + unsigned int read(unsigned int amt, unsigned char *buffer, + unsigned int bufsize, unsigned int offset = 1) const ; + unsigned int write(unsigned int amt, unsigned char *buffer, + unsigned int bufsize, unsigned int offset = 1) ; + unsigned int writeChunk(unsigned int amt, unsigned char *buffer, + unsigned int bufsize, unsigned int offset = 1) ; + void trim(unsigned int newlen) ; + Stream* getStream(unsigned int offset = 1, + unsigned int amount =0) ; + void closeStream(Stream *stream); + LobOptionValue getOptions(LobOptionType optType); + void setOptions(LobOptionType optType, LobOptionValue value); + + void getDeduplicateRegions(OCCI_STD_NAMESPACE::vector ®ions); + private: + + //Data Members: + + // pointer to the BLOB locator + OCIBlobLocator *lobp; + + // pointer to the ConnectionImpl instance + const ConnectionImpl *connp; + + // pointer to the LobStreamImpl instance obtained from this LOB + LobStreamImpl *streamp; + + //for future use ! + void *blobExt; + + //Constructor: + Blob(const Connection *connectionp, + OCIBlobLocator *locatorp, bool toCopy=true) ; + + //Methods: + OCIBlobLocator* getLocator() const; + + // Friends + friend class AnyDataImpl; + friend class StatementImpl; + friend class ResultSetImpl; + +#ifdef ORAXB8_DEFINED + friend void + LobRegion::setPrimary(const ConnectionImpl *connp, + OCILobLocator *locator); +#endif + friend void getVector(const AnyData&, OCCI_STD_NAMESPACE::vector&) ; + friend void getVector(Statement*, unsigned int, + OCCI_STD_NAMESPACE::vector&) ; + friend void getVector(ResultSet*, unsigned int, + OCCI_STD_NAMESPACE::vector&) ; + friend void setVector(AnyData&, const OCCI_STD_NAMESPACE::vector&) ; + friend void do_setVectorOfBlob(Statement*, unsigned int, + const OCCI_STD_NAMESPACE::vector&, void *, + unsigned int, void *, unsigned int ) ; +#ifdef ORAXB8_DEFINED + friend void readVectorOfBlobs(const Connection *conn, + OCCI_STD_NAMESPACE::vector &vec, + oraub8 *byte_amts, oraub8 *offsets, + unsigned char *buffers[], oraub8 *buffer_lens); + friend void writeVectorOfBlobs(const Connection *conn, + OCCI_STD_NAMESPACE::vector &vec, + oraub8 *byte_amts, oraub8 *offsets, + unsigned char *buffers[], oraub8 *buffer_lens); +#endif +}; + +class Clob +{ + public: + + Clob(); + Clob(const Connection *connectionp) ; + Clob(const Clob &srcClob) ; + ~Clob(); + unsigned int getChunkSize() const ; + unsigned int length() const ; + OCCI_STD_NAMESPACE::string getCharSetId() const; + CharSetForm getCharSetForm() const; + void setCharSetId( const OCCI_STD_NAMESPACE::string &charset) ; + void setCharSetForm( CharSetForm csfrm) ; + Clob& operator =(const Clob &srcClob) ; + bool operator ==(const Clob &srcClob) const ; + bool operator !=(const Clob &srcClob) const ; + void setNull() ; + bool isNull() const ; + void setEmpty() ; + void setEmpty(const Connection *connectionp) ; + bool isInitialized() const; + void open(LobOpenMode mode=OCCI_LOB_READWRITE) ; + void close() ; + bool isOpen() const ; + void copy(const Clob &srcClob, unsigned int numBytes, + unsigned int dstOffset = 1, unsigned int srcOffset = 1) ; + void copy(const Bfile &srcBfile, unsigned int numBytes, + unsigned int dstOffset = 1, unsigned int srcOffset = 1) ; + void append(const Clob &srcClob) ; + unsigned int read(unsigned int amt, unsigned char *buffer, + unsigned int bufsize, unsigned int offset = 1) const; + unsigned int read(unsigned int amt, utext *buffer, + unsigned int bufsize, unsigned int offset = 1) const; + unsigned int write(unsigned int amt, unsigned char *buffer, + unsigned int bufsize, unsigned int offset = 1 ); + unsigned int write(unsigned int amt, utext *buffer, + unsigned int bufsize, unsigned int offset = 1 ); + unsigned int writeChunk(unsigned int amt, unsigned char *buffer, + unsigned int bufsize, unsigned int offset = 1 ); + unsigned int writeChunk(unsigned int amt, utext *buffer, + unsigned int bufsize, unsigned int offset = 1 ); + void trim(unsigned int newlen) ; + Stream* getStream(unsigned int offset = 1, + unsigned int amount =0 ); + void closeStream(Stream *stream); + LobOptionValue getOptions(LobOptionType optType); + void setOptions(LobOptionType optType, LobOptionValue value); + + UString getCharSetIdUString() const; + void setCharSetIdUString( const UString &charset) ; + + void getDeduplicateRegions(OCCI_STD_NAMESPACE::vector ®ions); + + private: + + //Data Members: + + // pointer to the CLOB locator + OCIClobLocator *lobp; + + // pointer to the ConnectionImpl instance + const ConnectionImpl *connp; + + // pointer to the LobStreamImpl instance obtained from this LOB + LobStreamImpl *streamp; + + //charset id + ub2 charsetId; + + //charset form + CharSetForm charsetForm; + + //for future use ! + void *clobExt; + + //Constructor: + Clob(const Connection *connectionp, + OCIClobLocator *locatorp, bool toCopy =true ) ; + + //Methods: + OCIClobLocator* getLocator() const; + unsigned int do_read( unsigned int amt, void *buffer, + unsigned int bufsize, unsigned int offset) const; + unsigned int do_write( unsigned int amt, void *buffer, + unsigned int bufsize, unsigned int offset) ; + unsigned int do_writeChunk( unsigned int amt, void *buffer, + unsigned int bufsize, unsigned int offset) ; + + // Friends + friend class AnyDataImpl; + friend class StatementImpl; + friend class ResultSetImpl; + +#ifdef ORAXB8_DEFINED + friend void + LobRegion::setPrimary(const ConnectionImpl *connp, + OCILobLocator *locator); +#endif + friend void getVector(const AnyData&, OCCI_STD_NAMESPACE::vector&) ; + friend void getVector(Statement*, unsigned int, + OCCI_STD_NAMESPACE::vector&) ; + friend void getVector(ResultSet*, unsigned int, + OCCI_STD_NAMESPACE::vector&) ; + friend void setVector(AnyData&, const OCCI_STD_NAMESPACE::vector&) ; + friend void do_setVectorOfClob(Statement*, unsigned int, + const OCCI_STD_NAMESPACE::vector&, void *, + unsigned int, void *, unsigned int ) ; +#ifdef ORAXB8_DEFINED + friend void readVectorOfClobs(const Connection *conn, + OCCI_STD_NAMESPACE::vector &vec, + oraub8 *byte_amts, oraub8 *char_amts, oraub8 *offsets, + unsigned char *buffers[], oraub8 *buffer_lens); + friend void writeVectorOfClobs(const Connection *conn, + OCCI_STD_NAMESPACE::vector &vec, + oraub8 *byte_amts, oraub8 *char_amts, oraub8 *offsets, + unsigned char *buffers[], oraub8 *buffer_lens); + friend void readVectorOfClobs(const Connection *conn, + OCCI_STD_NAMESPACE::vector &vec, + oraub8 *byte_amts, oraub8 *char_amts, oraub8 *offsets, + utext *buffers[], oraub8 *buffer_lens); + friend void writeVectorOfClobs(const Connection *conn, + OCCI_STD_NAMESPACE::vector &vec, + oraub8 *byte_amts, oraub8 *char_amts, oraub8 *offsets, + utext *buffers[], oraub8 *buffer_lens); +#endif +}; + +class Number +{ + + public: + + // Constructors + /* default constructor added */ + Number(); + Number(const Number &srcNum); + Number(long double val) ; + Number(double val) ; + Number(float val) ; + Number(long val) ; + Number(int val) ; + Number(short val) ; + Number(char val) ; + Number(signed char val); + Number(unsigned long val) ; + Number(unsigned int val) ; + Number(unsigned short val) ; + Number(unsigned char val) ; + + ~Number(); + // Methods + const Number abs() const ; + // unary negate + const Number operator-() ; + // unary increment + Number& operator++() ; + const Number operator++(int) ; + // unary decrement + Number& operator--() ; + const Number operator--(int) ; + // assigment operator + Number& operator=(const Number &a); + // add and assign + Number& operator+=(const Number &a) ; + // subtract and assign + Number& operator-=(const Number &a) ; + // Mulitply an assign + Number& operator*=(const Number &a) ; + // divide and assign + Number& operator/=(const Number &a) ; + // Modulo and assign + Number& operator%=(const Number &a) ; + // casting operators + operator long() const; + operator int() const; + operator short() const; + operator char() const; + operator signed char() const; + operator unsigned long() const; + operator unsigned int() const; + operator unsigned short() const; + operator unsigned char() const; + operator long double() const; + operator double() const; + operator float() const; + // Decimal shift + const Number shift(int val) const ; + // Integer Power + const Number intPower(int val) const ; + const Number ceil() const ; + const Number floor() const ; + const Number squareroot() const ; + int sign() const ; + // conversion routines + // Format Number and return as a OCCI_STD_NAMESPACE::string + OCCI_STD_NAMESPACE::string toText(const Environment *envp, + const OCCI_STD_NAMESPACE::string &fmt, + const OCCI_STD_NAMESPACE::string &nlsParam="") const + ; + UString toText(const Environment *envp, + const UString &fmt,const UString &nlsParam) const + ; + // Create an Number from formatted text + void fromText(const Environment *envp, + const OCCI_STD_NAMESPACE::string &number, + const OCCI_STD_NAMESPACE::string &fmt, + const OCCI_STD_NAMESPACE::string &nlsParam = "") + ; + void fromText(const Environment *envp, + const UString &number, + const UString &fmt, const UString &nlsParam); + void fromBytes(const Bytes &s) ; + Bytes toBytes() const; + // truncate digits + const Number trunc(int decplace) const ; + // round to the decplace place. + const Number round(int decplace) const ; + // returns an Number with digits decimal digits + const Number prec(int digits) const ; + const Number sin() const ; + const Number cos() const ; + const Number tan() const ; + const Number hypSin() const ; + const Number hypCos() const ; + const Number hypTan() const ; + const Number arcSin() const ; + const Number arcCos() const ; + const Number arcTan() const ; + const Number arcTan2(const Number &val) const; + const Number power(const Number &val) const; + const Number exp() const ; + const Number ln() const ; + const Number log(const Number &val) const; + bool isNull() const; + void setNull(); + private: + /* Private constructor for constructing number from methods inside */ + Number(const OCINumber &result); + OCINumber getOCINumber() const; + + OCINumber data; + /* a flag to indicate if the Number is null */ + bool numberIsNull; + void *numberExt; + + // a >= b + friend bool operator>=(const Number &a, const Number &b); + // a < = b + friend bool operator<=(const Number &a, const Number &b); + // a > b + friend bool operator>(const Number &a, const Number &b); + // a < b + friend bool operator<(const Number &a, const Number &b); + + friend class IntervalDS; + friend class IntervalYM; + friend const IntervalYM operator*(const IntervalYM &a, + const Number& factor) ; + friend const IntervalDS operator*(const IntervalDS &a, + const Number& factor) ; + friend const IntervalYM operator/(const IntervalYM &a, + const Number &factor) ; + friend const IntervalDS operator/(const IntervalDS &a, + const Number &factor) ; + friend class ResultSetImpl; + friend class StatementImpl; + friend class AnyDataImpl; + friend void getVector(const AnyData &any, + OCCI_STD_NAMESPACE::vector &vect); + friend void setVector(AnyData &any, + const OCCI_STD_NAMESPACE::vector &vect) ; + friend Number MetaData::getNumber(MetaData::AttrId attrid) const ; + friend void getVector(Statement *stmt, unsigned int paramIndex, + OCCI_STD_NAMESPACE::vector &vect) ; + friend void do_setVectorOfNumber(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, void *schemaName, + unsigned int schemaNameLen, + void *typeName, unsigned int typeNameLen); + friend void getVector(ResultSet *rs, unsigned int colIndex, + OCCI_STD_NAMESPACE::vector &vect); + +}; + +class Date +{ + public: + + // Constructors + Date(); + Date(const Date &a); + Date(const Environment *envp,int year = 1,unsigned int month = 1, + unsigned int day = 1,unsigned int hour = 0, + unsigned int minute = 0, unsigned int seconds = 0); + ~Date(); + // Methods + + void setDate(int year = 1,unsigned int month = 1,unsigned int day = 1, + unsigned int hour = 0,unsigned int minute = 0, + unsigned int seconds = 0); + void getDate(int &year,unsigned int &month,unsigned int &day, + unsigned int &hour ,unsigned int &min ,unsigned int &sec) const; + Bytes toBytes() const ; + void fromBytes(const Bytes &byteStream, + const Environment *envp = NULL); + OCCI_STD_NAMESPACE::string toText( + const OCCI_STD_NAMESPACE::string &fmt = "", + const OCCI_STD_NAMESPACE::string &nlsParam = "") const; + UString toText( + const UString &fmt , + const UString &nlsParam ) const; + void fromText(const OCCI_STD_NAMESPACE::string &datestr, + const OCCI_STD_NAMESPACE::string &fmt = "", + const OCCI_STD_NAMESPACE::string &nlsParam = "", + const Environment *envp = NULL); + void fromText(const UString &datestr, + const UString &fmt , const UString &nlsParam , + const Environment *envp = NULL); + Date toZone(const OCCI_STD_NAMESPACE::string &zone1, + const OCCI_STD_NAMESPACE::string &zone2) const; + Date& operator=(const Date &d); + Date addMonths(int i) const; + Date addDays(int i) const ; + Date lastDay() const ; + IntervalDS daysBetween(const Date &d) const; + Date nextDay(const OCCI_STD_NAMESPACE::string &dow) const; + Date nextDay(const UString &dow) const; + bool isNull() const; + void setNull(); + static Date getSystemDate(const Environment *envp) ; + + private: + OCIDate date; + const EnvironmentImpl *envp; + bool dateIsNull; + void *dateExt; + + /* private constructor */ + Date(const Environment *env,OCIDate dateval); + OCIDate getOCIDate() const; + void constructHourAndMinute(sb4 &seconds, sb4 &hours, sb4 &minutes) const; + friend bool operator==(const Date &a,const Date &b); + friend bool operator>(const Date &a,const Date &b); + friend bool operator<(const Date &a,const Date &b); + friend bool operator!=(const Date &a,const Date &b); + friend bool operator>=(const Date &a,const Date &b); + friend bool operator<=(const Date &a,const Date &b); + friend class ResultSetImpl; + friend class StatementImpl; + friend class AnyDataImpl; + friend class aq::MessageImpl; + friend void getVector(const AnyData &any, + OCCI_STD_NAMESPACE::vector &vect) ; + friend void setVector(AnyData &any, + const OCCI_STD_NAMESPACE::vector &vect); + friend void getVector(Statement *stmt, unsigned int paramIndex, + OCCI_STD_NAMESPACE::vector &vect) ; + friend void do_setVectorOfDate(Statement *stmt, unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, void *schemaName, + unsigned int schemaNameLen,void *typeName, unsigned int typeNameLen) ; + friend void getVector(ResultSet *rs, unsigned int colIndex, + OCCI_STD_NAMESPACE::vector &vect) ; + +}; //class Date + +class Timestamp +{ + public: + Timestamp() ; + + Timestamp( const Environment *env, int year=1, + unsigned int month=1, unsigned int day=1, unsigned int hour=0, + unsigned int min=0 ,unsigned int sec=0, unsigned int fs=0, + int tzhour=0, int tzmin=0) ; + Timestamp( const Environment *env, int year, + unsigned int month, unsigned int day, unsigned int hour, + unsigned int min ,unsigned int sec, unsigned int fs, + const OCCI_STD_NAMESPACE::string &timezone); + Timestamp( const Environment *env, int year, + unsigned int month, unsigned int day, unsigned int hour, + unsigned int min ,unsigned int sec, unsigned int fs, + const UString &timezone); + Timestamp( const Timestamp &src) ; + ~Timestamp(); + + void getTimeZoneOffset( int &hour, int &minute) const ; + void getTime( unsigned int &hour, unsigned int &minute, + unsigned int &second, unsigned int &fs) const ; + void getDate( int &year, unsigned int &month, unsigned int &day )const ; + OCCI_STD_NAMESPACE::string toText(const OCCI_STD_NAMESPACE::string &fmt, + unsigned int fsprec, + const OCCI_STD_NAMESPACE::string &nlsParam ="") const ; + UString toText(const UString &fmt, + unsigned int fsprec, const UString &nlsParam ) const ; + void setTimeZoneOffset( int hour, int minute) ; + void setTime( unsigned int hour, unsigned int minute, + unsigned int second, unsigned int fs) ; + void setDate( int year, unsigned int month, unsigned int day ) ; + void setNull() ; + void fromText( const OCCI_STD_NAMESPACE::string ×tmpStr, + const OCCI_STD_NAMESPACE::string &fmt , + const OCCI_STD_NAMESPACE::string &nlsParam= "", + const Environment *env =NULL); + void fromText( const UString ×tmpStr, + const UString &fmt , const UString &nlsParam, + const Environment *env =NULL); + bool isNull() const; + Timestamp & operator =( const Timestamp &src) ; + const IntervalYM subYM(const Timestamp& val) const ; + const IntervalDS subDS(const Timestamp& val) const ; + const Timestamp intervalAdd(const IntervalDS& val) const ; + const Timestamp intervalSub(const IntervalDS& val) const ; + const Timestamp intervalAdd(const IntervalYM& val) const ; + const Timestamp intervalSub(const IntervalYM& val) const ; + + friend bool operator==(const Timestamp &a,const Timestamp &b); + friend bool operator>(const Timestamp &a,const Timestamp &b); + friend bool operator<(const Timestamp &a,const Timestamp &b); + friend bool operator !=(const Timestamp &a,const Timestamp &b); + friend bool operator >=(const Timestamp &a,const Timestamp &b); + friend bool operator <=(const Timestamp &a,const Timestamp &b); + + friend class ResultSetImpl; + friend class StatementImpl; + friend class AnyDataImpl; + + private: + OCIDateTime *ocidatetime; + OCIEnv *ocienv; + void *timestampExt; + + OCIDateTime *getOCIDateTime() const; + Timestamp( OCIEnv *env, OCIDateTime *dt, bool toCopy = true) ; + void allocateDataMembers( OCIEnv *env) ; + void do_TimestampConstruct( const Environment *env, int year, + unsigned int month, unsigned int day, unsigned int hour, unsigned int min, + unsigned int sec, unsigned int fs, void *tzinter); + + friend void getVector(const AnyData &any, + OCCI_STD_NAMESPACE::vector &vect); + friend void setVector(AnyData &any, + const OCCI_STD_NAMESPACE::vector &vect) ; + friend Timestamp MetaData::getTimestamp( + MetaData::AttrId attrid) const ; + friend void getVector(ResultSet *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + friend void getVector(Statement *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + friend void do_setVectorOfTimestamp(Statement *stmt, + unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + void *schemaName, unsigned int schemaNameLen, + void *typeName, unsigned int typeNameLen) ; +}; // class Timestamp + +class IntervalDS +{ + + public: + IntervalDS() ; + IntervalDS( const Environment *env,int day=0, + int hour=0, int minute=0, int second=0, + int fs=0) ; + IntervalDS( const IntervalDS &src) ; + + ~IntervalDS(); + + int getDay () const ; + int getHour () const ; + int getMinute () const ; + int getSecond() const ; + int getFracSec () const ; + void set( int day, int hour, int minute, int second, int fracsec) ; + void setNull() ; + void fromText( const OCCI_STD_NAMESPACE::string &inpstr, + const OCCI_STD_NAMESPACE::string &nlsParam ="", + const Environment *env=NULL) ; + OCCI_STD_NAMESPACE::string toText( unsigned int lfprec, unsigned int fsprec, + const OCCI_STD_NAMESPACE::string &nlsParam="") const ; + bool isNull() const; + IntervalDS& operator =( const IntervalDS &src) ; + IntervalDS& operator +=( const IntervalDS &a); + IntervalDS& operator -=( const IntervalDS &a); + IntervalDS& operator *=( const Number &factor); + IntervalDS& operator /=( const Number &factor); + + friend bool operator>(const IntervalDS &a, + const IntervalDS &b) ; + friend bool operator<(const IntervalDS &a, + const IntervalDS &b) ; + friend bool operator >=( const IntervalDS &a, + const IntervalDS &b); + friend bool operator <=( const IntervalDS &a, + const IntervalDS &b); + + //UTF16 support + void fromUText( const UString &inpstr, const Environment *env=NULL ); + UString toUText( unsigned int lfprec, unsigned int fsprec) const; + + private: + OCIInterval *ociinter; + OCIEnv *ocienv; + void *intervalDSExt; + + IntervalDS( OCIEnv *env, OCIInterval *inter, bool toCopy = true) ; + OCIInterval * getOCIInterval() const; + + void allocateDataMembers( OCIEnv *env) ; + friend const IntervalDS Timestamp::subDS( + const Timestamp& val) const ; + friend const Timestamp Timestamp::intervalAdd( + const IntervalDS& val) const ; + friend const Timestamp Timestamp::intervalSub( + const IntervalDS& val) const ; + friend class Date; + friend void getVector(ResultSet *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + friend void getVector(Statement *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + friend void do_setVectorOfIntervalDS(Statement *stmt, + unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + void *schemaName, unsigned int schemaNameLen, + void *typeName, unsigned int typeNameLen) ; + friend class StatementImpl; + friend class ResultSetImpl; + friend class AnyDataImpl; + friend void getVector(const AnyData &any, + OCCI_STD_NAMESPACE::vector &vect); + friend void setVector(AnyData &any, + const OCCI_STD_NAMESPACE::vector &vect) ; + + +}; //class IntervalDS + +class IntervalYM +{ + + public: + IntervalYM() ; + IntervalYM( const Environment *env,int year=0, int month=0) ; + IntervalYM( const IntervalYM &src) ; + ~IntervalYM(); + + int getYear() const ; + int getMonth() const ; + + void set( int year, int month) ; + void setNull() ; + void fromText( const OCCI_STD_NAMESPACE::string &inpstr, + const OCCI_STD_NAMESPACE::string &nlsParam="", + const Environment *env=NULL) ; + OCCI_STD_NAMESPACE::string toText( unsigned int lfprec, + const OCCI_STD_NAMESPACE::string &nlsParam="") const; + bool isNull() const; + IntervalYM & operator =( const IntervalYM &src) ; + IntervalYM& operator +=( const IntervalYM &a); + IntervalYM& operator -=( const IntervalYM &a); + IntervalYM& operator *=( const Number &factor); + IntervalYM& operator /=( const Number &factor); + + friend bool operator>(const IntervalYM &a, const IntervalYM &b) ; + friend bool operator<( const IntervalYM &a, const IntervalYM &b) ; + friend bool operator >=(const IntervalYM &a, const IntervalYM &b); + friend bool operator <=(const IntervalYM &a, const IntervalYM &b); + + //UTF16 support + void fromUText( const UString &inpstr, const Environment *env=NULL ); + UString toUText( unsigned int lfprec ) const; + + private: + OCIInterval *ociinter; + OCIEnv *ocienv; + void *intervalYMExt; + + IntervalYM( OCIEnv *env, OCIInterval *inter, bool toCopy = true) ; + OCIInterval *getOCIInterval() const; + void allocateDataMembers( OCIEnv *env) ; + friend const IntervalYM Timestamp :: subYM( + const Timestamp& val) const ; + friend const Timestamp Timestamp::intervalAdd( + const IntervalYM &val) const ; + friend const Timestamp Timestamp::intervalSub( + const IntervalYM &val) const ; + + friend void getVector(ResultSet *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + friend void getVector(Statement *rs, unsigned int, + OCCI_STD_NAMESPACE::vector &vect) ; + friend void do_setVectorOfIntervalYM(Statement *stmt, + unsigned int paramIndex, + const OCCI_STD_NAMESPACE::vector &vect, + void *schemaName, unsigned int schemaNameLen, + void *typeName, unsigned int typeNameLen) ; + + friend class StatementImpl; + friend class ResultSetImpl; + friend class AnyDataImpl; + friend void getVector(const AnyData &any, + OCCI_STD_NAMESPACE::vector &vect); + friend void setVector(AnyData &any, + const OCCI_STD_NAMESPACE::vector &vect) ; + +}; //class IntervalYM + + +Number operator+(const Number &a, const Number &b) ; +Number operator/(const Number ÷nd, const Number &divisor) ; +Number operator*(const Number &a, const Number &b) ; +Number operator%(const Number &a, const Number &b) ; +Number operator-(const Number &subtrahend, const Number &subtractor) ; +bool operator==(const Number &a, const Number &b); +bool operator!=(const Number &a, const Number &b); + +const IntervalYM operator+(const IntervalYM &a, const IntervalYM &b) ; +const IntervalYM operator-(const IntervalYM &a, const IntervalYM &b) ; +const IntervalYM operator*(const IntervalYM &a, const Number& factor); +const IntervalYM operator/(const IntervalYM &a, const Number &factor); +bool operator==(const IntervalYM &a, const IntervalYM &b) ; +bool operator!=(const IntervalYM &a, const IntervalYM &b) ; + +const IntervalDS operator+(const IntervalDS &a, const IntervalDS &b) ; +const IntervalDS operator-(const IntervalDS &a, const IntervalDS &b) ; +const IntervalDS operator*(const IntervalDS &a, const Number& factor); +const IntervalDS operator/(const IntervalDS &a, const Number &factor); +bool operator==(const IntervalDS &a, const IntervalDS &b) ; +bool operator!=(const IntervalDS &a, const IntervalDS &b) ; + + +typedef struct BFloat +{ + float value; + bool isNull; + + BFloat() + { + isNull = false; + value = 0.; + } +} BFloat; + +typedef struct BDouble +{ + double value; + bool isNull; + + BDouble() + { + isNull = false; + value = 0.; + } +} BDouble; + +/*--------------------------------------------------------------------------- + EXPORT FUNCTIONS + ---------------------------------------------------------------------------*/ + + +/*--------------------------------------------------------------------------- + INTERNAL FUNCTIONS + ---------------------------------------------------------------------------*/ + + +#ifdef ORAXB8_DEFINED +/* + NAME + Lob Region class + + DESCRIPTION + Contains the implementation of the Lob Region template Class. + This class is the underlying implementation for the BlobRegion and + ClobRegion classes. + + RELATED DOCUMENTS + Functional/Design Specifications: + 18209 - Next Generation LOBs: API + 18206 - Next Generation LOBs: Comb. Storage, Compressio & Encryption + + EXPORT FUNCTION(S) + LobRegion() - constructors + ~LobRegion() - destructor + getPrimary() - Get the Primary Lob object + getPrimaryOffset() - Get the offset of this region in the Primary Lob. + getOffset() - Get the offset of this region in this lob. + getLength() - Get the length of this region + getMimeType() - Get the mime type of this region + + PUBLIC IMPLEMENTATION FUNCTION(S) + + INTERNAL FUNCTION(S) + none + + EXAMPLES + + NOTES +*/ + +/*------------------------------ LobRegion ------------------*/ +/* + NAME + LobRegion - constructor for the class + + PARAMETERS + none + + DESCRIPTION + default constructor + + RETURNS + Nothing + + NOTES +*/ +template +LobRegion::LobRegion() +{ + _primary = (lobType *)0; + _primaryOffset = 0; + _offset = 0; + _length = 0; +} + +/*------------------------------ ~LobRegion ------------------*/ +/* + NAME + ~LobRegion - destructor for the class + + PARAMETERS + none + + DESCRIPTION + default constructor + + RETURNS + Nothing + + NOTES +*/ +template +LobRegion::~LobRegion() +{ + if (_primary != (lobType *)0) + { + delete _primary; + } +} + +template +lobType *LobRegion::getPrimary() +{ + return _primary; +} + +template +oraub8 LobRegion::getPrimaryOffset() +{ + return _primaryOffset; +} + +template +oraub8 LobRegion::getOffset() +{ + return _offset; +} + +template +oraub8 LobRegion::getLength() +{ + return _length; +} + +template +OCCI_STD_NAMESPACE::string LobRegion::getMimeType() +{ + return _mimeType; +} + +template +void LobRegion::setPrimary(const ConnectionImpl *connp, + OCILobLocator *locator) +{ + if (locator != (OCILobLocator *)0) + { + _primary = new lobType(connp, locator, true); + } +} + +#endif /* ORAXB8_DEFINED */ + +} /* end of namespace occi */ +} /* end of namespace oracle */ +#endif /* OCCIDATA_ORACLE */ + +#endif /* _olint */ diff --git a/libodbc/include/ora_linux/occiObjects.h b/libodbc/include/ora_linux/occiObjects.h new file mode 100644 index 0000000000..bcc3d6625a --- /dev/null +++ b/libodbc/include/ora_linux/occiObjects.h @@ -0,0 +1,910 @@ +/* Copyright (c) 2000, 2007, Oracle. All rights reserved. */ + +/* + NAME + occiObjects.h - header file for OCCI object classes + + DESCRIPTION + Class definitions for Ref, RefAny, AnyData + + RELATED DOCUMENTS + + + EXPORT FUNCTION(S) + + + INTERNAL FUNCTION(S) + + + EXAMPLES + + NOTES + + + +*/ + +#ifndef _olint /* disable olint check */ + +#ifndef OCCIOBJECTS_ORACLE +# define OCCIOBJECTS_ORACLE + +#ifndef OCCICOMMON_ORACLE +#include +#endif + +namespace oracle { +namespace occi { +struct AnyDataCtx { + ConnectionImpl *occiSession; + OCIAnyData *anyData; + void *objHeader; + ub4 errNum; +}; +typedef struct AnyDataCtx AnyDataCtx; + +class PObject +{ + public: + enum LockOption {OCCI_LOCK_WAIT, OCCI_LOCK_NOWAIT}; + enum UnpinOption {OCCI_PINCOUNT_DECR, OCCI_PINCOUNT_RESET}; + static void destroy(void *); + static void refresh(void *); + PObject(); + PObject(const void *ctx); + PObject(const PObject& obj); + virtual ~PObject(); + PObject& operator=(const PObject& obj); + void *operator new(size_t size); + void *operator new(size_t size, const Connection *x, + const OCCI_STD_NAMESPACE::string& tablename, + const char *typeName); + void *operator new(size_t size, const Connection *sess, + const OCCI_STD_NAMESPACE::string& tablename, + const OCCI_STD_NAMESPACE::string& typName , + const OCCI_STD_NAMESPACE::string& schTabName="", + const OCCI_STD_NAMESPACE::string& schTypName = ""); + void *operator new(size_t size, const Connection *sess, + const UString& tablename, const UString &typName, + const UString& schTabName, const UString& schTypName); + void *operator new(size_t size, void *adctx); + void operator delete(void *obj, size_t size); + RefAny getRef() const; + bool isLocked() const; + void unpin(UnpinOption mode=OCCI_PINCOUNT_DECR); + void pin(); + void lock(PObject::LockOption lock_option); + void unmark(); + void flush(); + void markDelete(); + void markModified(); + bool isNull() const; + void setNull(); + const Connection *getConnection() const; + virtual OCCI_STD_NAMESPACE::string getSQLTypeName() const = 0; + virtual void getSQLTypeName(Environment *env, void **schName, + unsigned int &schNameLen, void **typeName, + unsigned int &typeNameLen) const = 0; + void getSQLTypeName(Environment *env, void *(*rSQL)(void *), + void **schname, unsigned int &schnamelen, + void **typname, unsigned int &typnamelen) const; + virtual void writeSQL(AnyData& stream) = 0; + virtual void readSQL(AnyData& stream) = 0; + private: + static void initialise( void * obj, const Connection * sess, + void *schTabName, unsigned int schTabLen, + void *tableName, unsigned int tabLen, + void *schTypName, unsigned int schTypLen, + void *typeName, unsigned int typLen); + + ConnectionImpl *occiSession_; + void *objHeader_; + ub2 customNewed_; + enum {CUSTOM_NEWED = 0x5cde}; + ub2 flags_; + enum {NULL_INFO = 0x0001, GARBAGE_COLLECTED = 0x0002, + REFRESH_OBJECT = 0x0004, + CACHED_OBJECT = 0xBAF8}; + //check PObject implementation for CACHED_OBJECT flag + // for future use + void *pobjectExt; + friend class RefImpl; +}; + +class AnyData +{ + public: + ~AnyData(); + AnyData(void *any) ; + AnyData(const Connection *sessp); + AnyData(const Connection *sessp, OCIAnyData *any, bool freeImg = true) ; + + AnyData(const AnyData &src); + AnyData& operator = (const AnyData &src); + + OCIAnyData* getOCIAnyData() const; + const Connection* getConnection() const; + + + bool isNull() const ; + void setNull() ; + OCCI_STD_NAMESPACE::string getString() const ; + UString getUString() const ; + Blob getBlob() const ; + Clob getClob() const ; + Bfile getBfile() const ; + BFloat getBFloat() const ; + BDouble getBDouble() const ; + Number getNumber() const ; + Bytes getBytes() const ; + Date getDate() const ; + Timestamp getTimestamp() const ; + IntervalYM getIntervalYM() const ; + IntervalDS getIntervalDS() const ; + PObject *getObject(void *(*rSQL)(void *)) const ; + RefAny getRef() const ; + + void setString(const OCCI_STD_NAMESPACE::string &str) ; + void setUString(const UString &str) ; + void setBlob(const Blob &blob) ; + void setClob(const Clob &clob) ; + void setBfile(const Bfile &bfile) ; + void setBFloat(const BFloat &n) ; + void setBDouble(const BDouble &n) ; + void setNumber(const Number &n) ; + void setBytes(const Bytes &bytes) ; + void setDate(const Date &date) ; + void setTimestamp(const Timestamp ×tamp) ; + void setIntervalYM(const IntervalYM &intervalym) ; + void setIntervalDS(const IntervalDS &intervalds) ; + void setObject(const PObject *objptr) ; + void setRef(const RefAny &ref) ; + + void setFromString(const OCCI_STD_NAMESPACE::string &str) ; + void setFromBfile(const Bfile &bfile) ; + void setFromBFloat(const BFloat &n) ; + void setFromBDouble(const BDouble &n) ; + void setFromNumber(const Number &n) ; + void setFromBytes(const Bytes &bytes) ; + void setFromDate(const Date &date) ; + void setFromTimestamp(const Timestamp ×tamp) ; + void setFromIntervalYM(const IntervalYM &intervalym) ; + void setFromIntervalDS(const IntervalDS &intervalds) ; + void setFromObject(const PObject *objptr) ; + void setFromRef(const RefAny &ref, + const OCCI_STD_NAMESPACE::string &typname, + const OCCI_STD_NAMESPACE::string &schname) ; + + OCCI_STD_NAMESPACE::string getAsString() const ; + Bfile getAsBfile() const ; + BFloat getAsBFloat() const ; + BDouble getAsBDouble() const ; + Number getAsNumber() const ; + Bytes getAsBytes() const ; + Date getAsDate() const ; + Timestamp getAsTimestamp() const ; + IntervalYM getAsIntervalYM() const ; + IntervalDS getAsIntervalDS() const ; + PObject *getAsObject() const ; + RefAny getAsRef() const ; + + TypeCode getType() const; + + private: + + + // private data members + Ptr anyDataImplPtr; + + +}; + +template +class Ref +{ + public: + + Ref(); + Ref(const T *obj) ; + Ref(const RefAny &refAny) ; + Ref(const Ref &src) ; + Ref(const Connection *sessp, OCIRef *tref, bool copy=TRUE) + ; + ~Ref(); + Ref& operator=(const Ref &src) + ; + Ref& operator=(const T *obj) ; + Ref& operator=(const RefAny &src); + T * operator->() ; + T * ptr() ; + T & operator *() ; + const T * operator->() const; + const T * ptr() const; + const T & operator *() const ; + void markDelete() ; + void unmarkDelete() ; + void setNull(); + bool isNull() const; + void clear() ; + bool isClear() const; + void setPrefetch(const OCCI_STD_NAMESPACE::string &typeName, + unsigned int depth); + void setPrefetch(const OCCI_STD_NAMESPACE::string &schName, + const OCCI_STD_NAMESPACE::string &typeName, + unsigned int depth); + void setPrefetch(const UString &schName, + const UString &typeName, + unsigned int depth); + void setPrefetch(unsigned int depth) ; + void setLock(LockOptions ); + operator RefAny() const; + OCIRef *getRef() const; + const Connection *getConnection() const; + bool operator == (const Ref &ref) const; + bool operator != (const Ref &ref) const; + bool operator == (const RefAny &refAnyR) const ; + bool operator != (const RefAny &refAnyR) const ; + OCIComplexObject *getCor() const; + void setPinnedObject(PObject *objPtr); + private: + + RefImpl *rimplPtr; +}; + + +class RefImpl +{ + public: + + RefImpl(); + RefImpl(PObject *obj) ; + RefImpl(const RefAny &refAny) ; + RefImpl(const RefImpl &src) ; + RefImpl(const Connection *sessp, OCIRef *tref, + bool copy=TRUE) ; + ~RefImpl(); + bool isNull() const ; + void setNull() ; + void markDelete() ; + void unmarkDelete() ; + void clear() ; + bool isClear() const ; + void setPrefetch(const OCCI_STD_NAMESPACE::string &typeName, + unsigned int depth) ; + void setPrefetch(const OCCI_STD_NAMESPACE::string &schName, + const OCCI_STD_NAMESPACE::string &typeName, + unsigned int depth); + void setPrefetch(const UString &schName, + const UString &typeName, + unsigned int depth); + void setPrefetch(unsigned int depth) ; + void setLock(LockOptions lckOption) ; + PObject *pin() ; + void unpin(PObject *obj) ; + void setRefFromObjPtr(const PObject *obj) ; + OCIRef* getRef() const; + void setRefImpl(RefImpl *rptr); + const Connection * getConnection() const; + bool operator == (const RefImpl &refI) const ; + bool operator == (const RefAny &refAnyR) const ; + void assignObj(PObject *newObjPtr) ; + void assignRefAny(const RefAny &src) ; + // added following methods + bool isEqual(PObject *obj); + void operator = ( const RefImpl &src); + OCIComplexObject *getCor() const; + void setPinnedObject( PObject *objPtr); + private: + + OCIRef *ref; + const ConnectionImpl *sessp; + OCIComplexObject *corhp; + OCCI_STD_NAMESPACE::list descriptorList; + LockOptions lockOption; + // added data member for object header + void *objHeader; + //common implementation function for setPrefetch + void do_setPrefetch(void *schName, unsigned int schNameLen, + void *typeName, unsigned int typeNameLen, + unsigned int depth); +}; + + +class RefAny +{ + public: + + RefAny(); + RefAny (const Connection *sessptr, const OCIRef *ref); + RefAny (const Connection *sessptr, const OCIRef *ref, bool isowner); + ~RefAny() ; + RefAny(const RefAny& src) ; + RefAny& operator=(const RefAny& src) ; + void markDelete() ; + void unmarkDelete() ; + void clear() ; + bool isNull() const; + OCIRef * getRef() const; + const Connection * getConnection() const; + bool operator == (const RefAny &refAnyR) const; + bool operator != (const RefAny &refAnyR) const; + bool isOwner() const; + + private: + + OCIRef *ref; + const ConnectionImpl *sessp; + // for future use + void *refanyExt; + bool owner; + + friend RefAny MetaData::getRef(MetaData::AttrId) const; + friend RefAny PObject::getRef() const; + friend class AnyDataImpl; + friend class ResultSetImpl; + friend class StatementImpl; + friend void getVector(const ResultSet *rs, + unsigned int colIndex, + OCCI_STD_NAMESPACE::vector &vect) ; + friend void getVector(const Statement *stmt, + unsigned int colIndex, + OCCI_STD_NAMESPACE::vector &vect) ; +}; + +template +Ref::Ref() +{ + rimplPtr = new RefImpl(); +} + +template +Ref::Ref(const T *obj) +{ + rimplPtr = new RefImpl((PObject *)obj); +} + +template +Ref::Ref(const RefAny &refAny) + +{ + rimplPtr = new RefImpl(refAny); +} + +template +Ref::Ref(const Ref& src) + +{ + rimplPtr = new RefImpl(*(src.rimplPtr)); +} + +template +Ref::Ref(const Connection *sessp, OCIRef *tref, bool copy) + +{ + rimplPtr = new RefImpl(sessp, tref, copy); +} + +template +Ref::~Ref() +{ + delete rimplPtr; +} + + +template +Ref& Ref::operator=(const Ref &src) +{ + if (&src == this) + return *this; + *rimplPtr = *(src.rimplPtr); + return *this; +} + +template +Ref& Ref::operator=(const T *obj) +{ + if (rimplPtr->isEqual((PObject *)obj)) + return *this; + rimplPtr->assignObj((PObject *)obj); + return *this; +} + +template +Ref& Ref::operator=(const RefAny &src) +{ + rimplPtr->assignRefAny(src); + return *this; +} + +template +T* Ref::operator->() +{ + return ((T *)rimplPtr->pin()); +} + +template +T* Ref::ptr() +{ + return ((T *)rimplPtr->pin()); +} + +template +T& Ref::operator * () +{ + return ((T &)(*(rimplPtr->pin()))); +} + +template +const T* Ref::operator->() const +{ + return ((const T *)rimplPtr->pin()); +} + +template +const T* Ref::ptr() const +{ + return ((const T *)rimplPtr->pin()); +} + +template +const T& Ref::operator * () const +{ + return ((const T &)(*(rimplPtr->pin()))); +} + +template +void Ref::markDelete () +{ + rimplPtr->markDelete(); +} + +template +void Ref::unmarkDelete () +{ + rimplPtr->unmarkDelete(); +} + +template +void Ref::setNull() +{ + rimplPtr->setNull(); +} + +template +bool Ref::isNull() const +{ + return rimplPtr->isNull(); +} + +template +void Ref::clear () +{ + rimplPtr->clear(); +} + +template +bool Ref::isClear() const +{ + return rimplPtr->isClear(); +} + +template +void Ref::setPrefetch (const OCCI_STD_NAMESPACE::string &typeName, +unsigned int depth) + +{ + rimplPtr->setPrefetch(typeName,depth); +} + +template +void Ref::setPrefetch (const OCCI_STD_NAMESPACE::string &schemaName, +const OCCI_STD_NAMESPACE::string &typeName, +unsigned int depth) + +{ + rimplPtr->setPrefetch(schemaName,typeName,depth); +} + +template +void Ref::setPrefetch (const UString &schemaName, +const UString &typeName, +unsigned int depth) + +{ + rimplPtr->setPrefetch(schemaName,typeName,depth); +} + +template +void Ref::setPrefetch (unsigned int depth) + +{ + rimplPtr->setPrefetch(depth); +} + +template +void Ref::setLock (LockOptions lckOption) +{ + rimplPtr->setLock(lckOption); +} + +template +OCIRef* Ref::getRef() const +{ + return (rimplPtr->getRef()); +} + +template +const Connection* Ref::getConnection () const +{ + return (rimplPtr->getConnection()); +} + +template +Ref::operator RefAny () const +{ + if (isNull()) + return RefAny(); + return (RefAny(rimplPtr->getConnection(), rimplPtr->getRef())); +} + +template +bool Ref::operator ==(const Ref &ref) const + +{ + return ( (*rimplPtr) == (*(ref.rimplPtr)) ); +} + +template +bool Ref::operator !=(const Ref &ref) const + +{ + return ( !((*rimplPtr) == (*(ref.rimplPtr))) ); +} + +template +bool Ref::operator == (const RefAny & refAnyR) const + +{ + return ( (*rimplPtr) == refAnyR ); +} + +template +bool Ref::operator != (const RefAny & refAnyR) const + +{ + return ( !((*rimplPtr) == refAnyR )); +} + +template +OCIComplexObject * Ref::getCor() const +{ + return (rimplPtr->getCor()); +} + +template < class T> +void Ref::setPinnedObject( PObject *objPtr) +{ + rimplPtr->setPinnedObject(objPtr); +} + +/*--------------------------------------------------------------------------- + PROTOTYPES USED BY FUNCTION TEMPLATES + ---------------------------------------------------------------------------*/ + void getVectorOfOCIRefs( const AnyData &any, + OCCI_STD_NAMESPACE::vector &vect); + void getVectorOfPObjects( const AnyData &any, + OCCI_STD_NAMESPACE::vector< PObject* > &vect, + void *(*rSQL)(void *)) ; + void setVectorOfOCIRefs( AnyData &any, + const OCCI_STD_NAMESPACE::vector &vect, + const OCCI_STD_NAMESPACE::vector< OCIInd> &vec_ind) ; + void setVectorOfPObjects( AnyData &any, + const OCCI_STD_NAMESPACE::vector< PObject* > &vect) ; + +/*--------------------------------------------------------------------------- + EXPORT FUNCTIONS + ---------------------------------------------------------------------------*/ + +/*------------------- getVector for POBject----------------------------*/ +/* + NAME + getVector - overloaded function. Retrieves the attribute in the + current position as a vector of PObject + + PARAMETERS + any - AnyData + vect- reference to vector of PObject (OUT parameter). + + DESCRIPTION + Retrieves the attribute in the current position as a vector + of PObject + The attribute at the current position should be a collection + type (varray or nested table). The SQL type of the elements in + the collection should be compatible with PObject + + RETURNS + nothing + + NOTES + compatible SQL types : user defined types (SQLT_NTY) etc. +*/ + +#if defined(WIN32COMMON) || defined(__MVS__) +// and other platforms that do not support +// partial function template specialization + template + void getVector(const AnyData &any, OCCI_STD_NAMESPACE::vector &vect, + void *(*rSQL)(void *)) + { + OCCI_STD_NAMESPACE::vector< PObject *> vec_pobj; + getVectorOfPObjects( any, vec_pobj, rSQL); + + vect.clear(); + unsigned int size= vec_pobj.size(); + vect.reserve( size ); + for( unsigned int i=0; i< size; i++) + vect.push_back( (T)vec_pobj[i] ); + } +#else + template + void getVector(const AnyData &any, OCCI_STD_NAMESPACE::vector &vect, + void *(*rSQL)(void *)) + { + OCCI_STD_NAMESPACE::vector< PObject *> vec_pobj; + getVectorOfPObjects( any, vec_pobj, rSQL); + + vect.clear(); + unsigned int size= vec_pobj.size(); + vect.reserve( size ); + for( unsigned int i=0; i< size; i++) + vect.push_back( (T*)vec_pobj[i] ); + } +#endif /* end of #ifdef WIN32COMMON */ + + /*------------------- getVector for Ref----------------------------*/ +/* + NAME + getVector - overloaded function. Retrieves the attribute in the + current position as a vector of PObject + + PARAMETERS + any - AnyData + vect- reference to vector of PObject (OUT parameter). + + DESCRIPTION + Retrieves the attribute in the current position as a vector + of PObject + The attribute at the current position should be a collection + type (varray or nested table). The SQL type of the elements in + the collection should be compatible with PObject + + RETURNS + nothing + + NOTES + compatible SQL types : user defined types (SQLT_NTY) etc. +*/ +#if !defined(WIN32COMMON) && !defined(__MVS__) + template + void getVector(const AnyData &any,OCCI_STD_NAMESPACE::vector< Ref > &vect) + { + OCCI_STD_NAMESPACE::vector< void *> vec_ref; + getVectorOfOCIRefs( any, vec_ref); + + vect.clear(); + unsigned int size = vec_ref.size(); + vect.reserve( size ); + const Connection *sess = any.getConnection(); + + for (unsigned int i=0; i< size; i++) + { + if (vec_ref[i] == (OCIRef *)0) + vect.push_back(Ref()); // pushing a default-constructed Ref + else + vect.push_back(Ref(sess, (OCIRef *)vec_ref[i], FALSE)); + } + } +#endif /* end of #ifndef WIN32COMMON */ + +/*-----------------------setVector for PObject--------------------------*/ +/* + NAME + setVector - overloaded function. sets the attribute in the current + position of anydata with the vector elements. + + PARAMETERS + none. + + DESCRIPTION + sets the attribute in the current position in anydata with the + vector elements. + The attribute in the current position of anydata should be a + collection type. If the collection type is a varray, the input vector + size should be equal to the size of the varray. Also the SQL type of + the collection's elements should be compatible with PObject. + + RETURNS + nothing. + + NOTES + compatible SQL types : SQLT_NTY (user defined types). +*/ +#if defined(WIN32COMMON) || defined(__MVS__) +// and other platforms that do not support +// partial function template specialization + + template + void setVector(AnyData &any, const OCCI_STD_NAMESPACE::vector &vect) + { + OCCI_STD_NAMESPACE::vector< PObject *> vec_pobj; + unsigned int size= vect.size(); + vec_pobj.reserve( size ); + for( unsigned int i=0; i< size; i++) + vec_pobj.push_back( vect[i] ); + setVectorOfPObjects( any, vec_pobj); + + } + +#else + + template + void setVector(AnyData &any, const OCCI_STD_NAMESPACE::vector &vect) + { + OCCI_STD_NAMESPACE::vector< PObject *> vec_pobj; + unsigned int size= vect.size(); + vec_pobj.reserve( size ); + for( unsigned int i=0; i< size; i++) + vec_pobj.push_back( vect[i] ); + setVectorOfPObjects( any, vec_pobj); + + } +#endif /* end of #ifdef WIN32COMMON */ + +/*-----------------------setVector for Ref--------------------------*/ +/* + NAME + setVector - overloaded function. sets the attribute in the current + position of anydata with the vector elements. + + PARAMETERS + none. + + DESCRIPTION + sets the attribute in the current position in anydata with the + vector elements. + The attribute in the current position of anydata should be a + collection type. If the collection type is a varray, the input vector + size should be equal to the size of the varray. Also the SQL type of + the collection's elements should be compatible with PObject. + + RETURNS + nothing. + + NOTES + compatible SQL types : SQLT_NTY (user defined types). +*/ +#if !defined(WIN32COMMON) && !defined(__MVS__) + template + void setVector(AnyData &any, const OCCI_STD_NAMESPACE::vector< Ref > &vect) + { + OCCI_STD_NAMESPACE::vector< void *> vec_ref; + OCCI_STD_NAMESPACE::vector vec_ind; + + unsigned int size= vect.size(); + vec_ref.reserve( size ); + vec_ind.reserve( size ); + for( unsigned int i=0; i< size; i++) + { + vec_ref.push_back( vect[i].getRef() ); + vec_ind.push_back(vect[i].isNull() ? OCI_IND_NULL : OCI_IND_NOTNULL); + } + setVectorOfOCIRefs( any, vec_ref, vec_ind); + + } +#endif /* end of #ifndef WIN32COMMON */ + +// Platform independent get/setVectorOfRefs method added +// get(set)Vector of Ref and get(set)VectorOfRefs are identical +// in functionality. + + /*------------------- getVectorOfRefs for Ref----------------------------*/ +/* + NAME + getVectorOfRefs - overloaded function. Retrieves the attribute in the + current position as a vector of PObject + + PARAMETERS + any - AnyData + vect- reference to vector of PObject (OUT parameter). + + DESCRIPTION + Retrieves the attribute in the current position as a vector + of PObject + The attribute at the current position should be a collection + type (varray or nested table). The SQL type of the elements in + the collection should be compatible with PObject + + RETURNS + nothing + + NOTES + compatible SQL types : user defined types (SQLT_NTY) etc. +*/ + + template + void getVectorOfRefs(const AnyData &any, + OCCI_STD_NAMESPACE::vector< Ref > &vect) + { + OCCI_STD_NAMESPACE::vector< void *> vec_ref; + getVectorOfOCIRefs( any, vec_ref); + + vect.clear(); + unsigned int size = vec_ref.size(); + vect.reserve( size ); + const Connection *sess = any.getConnection(); + + for (unsigned int i=0; i< size; i++) + { + if (vec_ref[i] == (OCIRef *)0) + vect.push_back(Ref()); // pushing a default-constructed Ref + else + vect.push_back(Ref(sess, (OCIRef *)vec_ref[i], FALSE)); + } + } + +/*-----------------------setVectorOfRefs for Ref--------------------------*/ +/* + NAME + setVectorOfRefs - overloaded function. sets the attribute in the current + position of anydata with the vector elements. + + PARAMETERS + none. + + DESCRIPTION + sets the attribute in the current position in anydata with the + vector elements. + The attribute in the current position of anydata should be a + collection type. If the collection type is a varray, the input vector + size should be equal to the size of the varray. Also the SQL type of + the collection's elements should be compatible with PObject. + + RETURNS + nothing. + + NOTES + compatible SQL types : SQLT_NTY (user defined types). +*/ + + template + void setVectorOfRefs(AnyData &any, + const OCCI_STD_NAMESPACE::vector< Ref > &vect) + + { + OCCI_STD_NAMESPACE::vector< void *> vec_ref; + OCCI_STD_NAMESPACE::vector vec_ind; + + unsigned int size= vect.size(); + vec_ref.reserve( size ); + vec_ind.reserve( size ); + for( unsigned int i=0; i< size; i++) + { + vec_ref.push_back( vect[i].getRef() ); + vec_ind.push_back(vect[i].isNull() ? OCI_IND_NULL : OCI_IND_NOTNULL); + } + setVectorOfOCIRefs( any, vec_ref, vec_ind); + + } + + +/*--------------------------------------------------------------------------- + INTERNAL FUNCTIONS + ---------------------------------------------------------------------------*/ + + +} /* end of namespace occi */ +} /* end of namespace oracle */ +#endif /* OCCIOBJECTS_ORACLE */ + +#endif /* _olint */ diff --git a/libodbc/include/ora_linux/oci.h b/libodbc/include/ora_linux/oci.h new file mode 100644 index 0000000000..51f731de1a --- /dev/null +++ b/libodbc/include/ora_linux/oci.h @@ -0,0 +1,2985 @@ +/* Copyright (c) 1995, 2008, Oracle. All rights reserved. */ + +/* + NAME + oci.h - V8 Oracle Call Interface public definitions + + DESCRIPTION + This file defines all the constants and structures required by a V8 + OCI programmer. + + RELATED DOCUMENTS + V8 OCI Functional Specification + Oracle Call Interface Programmer's Guide Vol 1 and 2 + + INSPECTION STATUS + Inspection date: + Inspection status: + Estimated increasing cost defects per page: + Rule sets: + + ACCEPTANCE REVIEW STATUS + Review date: + Review status: + Reviewers: + + PUBLIC FUNCTION(S) + None + + PRIVATE FUNCTION(S) + None + + EXAMPLES + + NOTES + + + MODIFIED (MM/DD/YY) + nikeda 05/13/08 - Backport nikeda_bug-6964328 from main + umabhat 09/20/07 - bug6119750 added OCI_FNCODE_APPCTXSET & + OCI_FNCODE_APPCTXCLEARALL + msakayed 05/24/07 - Bug #5095734: add OCI_ATTR_DIRPATH_RESERVED_19 + schoi 03/02/07 - Get/SetOptions API change + ebatbout 03/30/07 - 5598333: Add OCI_ATTR_DIRPATH_RESERVED_18 + nikeda 03/21/07 - Add OCI_ATTR_RESERVED_37 + abande 03/06/07 - Remove attributes for global stmt cache and + metadata cache + rphillip 02/20/07 - Add OCI_ATTR_DIRPATH_RESERVED_17 + shan 11/16/06 - bug 5595911. + msakayed 12/04/06 - Bug #5660845: add OCI_DIRPATH_INPUT_OCI + gviswana 10/26/06 - Remove OCI_ATTR_CURRENT_EDITION + maramali 09/29/06 - bug 5568492, added OCI_NLS_LOCALE_A2_ISO_2_ORA + gviswana 09/29/06 - CURRENT_EDITION -> EDITION + aramappa 09/20/06 - Update major and minor version information + slynn 07/28/06 - Migrate to new 11g LOB terminiology + debanerj 07/20/06 - Add OCI_ATTR_LOBPREFETCH_LENGTH + mbastawa 06/25/06 - add OCI_ATTR_RESERVED_36 + hqian 05/22/06 - 11gR1 proj-18303: add OCI_SYSASM + dkogan 04/06/06 - disable charset validation by default + jhealy 05/15/06 - Add TimesTen OCI adapter. + slynn 06/20/06 - GetSharedRegions + rthammai 06/13/06 - add reserved attribute + msakayed 06/15/06 - Project 20586: interval partitioning support + debanerj 10/25/05 - LOB prefetch + slynn 05/25/06 - New NG Lob Functionality. + yujwang 05/16/06 - Add OCI_ATTR_RESERVED_33, OCI_ATTR_RESERVED_34 + abande 04/25/06 - 18297: Add attributes for global stmt cache and + metadata cache + ssvemuri 04/26/06 - Constants for Query Notification support + jgiloni 05/05/06 - Add OCI_ATCH_RESERVED_7 + mxyang 02/01/06 - Added OCI_ATTR_CURRENT_EDITION attribute + hqian 05/04/06 - new runtime capability attribute for asm volume + nikeda 06/06/06 - OCI_TT: Add new OCIP attributes + aramappa 04/17/06 - Added OCI_FNCODE_ARRAYDESCRIPTORALLOC and + OCI_FNCODE_ARRAYDESCRIPTORFREE + debanerj 05/04/06 - 18313: OCI Net Fusion + rupsingh 05/26/06 - + jacao 05/11/06 - + absaxena 04/17/06 - add notification grouping attributes + rpingte 02/02/06 - add OCI_ATCH_RESERVED_6 + rpingte 04/27/06 - Add OCI_ATTR_DRIVER_NAME + jawilson 02/14/06 - add OCI_FNCODE_AQENQSTREAM + kneel 04/03/06 - Adding support in kjhn for critical severity + rphillip 03/31/06 - Add OCI_ATTR_DIRPATH_RESERVED_14 + mxyang 02/01/06 - Added OCI_ATTR_APPLICATION_EDITION attribute + rphillip 01/30/06 - Add new DPAPI attrs + ebatbout 11/03/05 - Add direct path support for multiple subtypes + porangas 02/22/06 - 5055398: Define OCI_STMT_CALL + mbastawa 01/31/06 - add OCI_ATTR_RESERVED_26 + yohu 01/27/06 - align Execution Modes macros + sjanardh 01/25/06 - add OCI_EXEC_RESERVED_6 + sichandr 01/18/06 - add OCI_ATTR_XMLTYPE_BINARY_XML + yohu 12/22/05 - add OCI_TRANS_PROMOTE + srseshad 09/12/05 - stmtcache: callback + krajan 10/25/05 - Added ENABLE_BEQUEATH attach flag + mbastawa 09/16/05 - dbhygiene + porangas 07/20/04 - 1175350: adding attribute for ognfd + chliang 06/30/05 - add OCI_SUPPRESS_NLS_VALIDATION mode + aahluwal 03/15/05 - [Bug 4235014]:add ASM, Preconnect events + ssappara 08/12/04 - Bug3669429 add OCI_ATTR_DESC_SYNBAS + absaxena 03/24/05 - remove OCI_AQ_RESERVED_5 + mbastawa 03/01/05 - add OCI_EXEC_RESERVED_5 + msakayed 02/15/05 - Bug #3147299: Add OCI_ATTR_CURRENT_ERRCOL + aahluwal 01/11/05 - [Bug 3944589]: add OCI_AUTH_RESERVED_5 + nikeda 11/15/04 - Add OCIP_IIO + rvissapr 11/10/04 - bug 3843644 - isencrypted + hohung 11/22/04 - add OCI_BIND_RESERVED_3 + cchui 10/25/04 - add OCI_ATTR_PROXY_CLIENT + aahluwal 09/27/04 - add incarnation, reason, cardinality to event handle + msakayed 09/14/04 - column encryption support (project id 5578) + jacao 08/17/04 - Add OCI_ATTR_DB_CHARSET_ID + mhho 08/29/04 - resolve conflicting mode declaration + sgollapu 05/28/04 - Add OCI_AUTH_RESERVED_3 + mbastawa 08/05/04 - add OCI_ATTR_RESERVED_21 + ebatbout 07/27/04 - add OCI_ATTR_DIRPATH_RESERVED_9 and move all direct + path attributes into a separate area in this file. + clei 06/29/04 - add OCI_ATTR_ENCC_SIZE + weiwang 05/06/04 - add OCIAQListenOpts and OCIAQLisMsgProps + weiwang 04/30/04 - add OCI_AQ_RESERVED_5 + nbhatt 04/27/04 - add new attribute + ssvemuri 06/19/04 - change notification descriptors and attributes + ksurlake 06/01/04 - grabtrans 'ksurlake_txn_skmishra_clone' + ksurlake 05/13/04 - add subscriber handle attributes + mbastawa 06/01/04 - add 3 more OCI_FETCH_RESERVED modes + chliang 05/28/04 - add nchar literal replacement modes + nikeda 05/14/04 - [OLS on RAC] new authentication mode + debanerj 05/17/04 - 13064: add fncodes for LOB array Read and Write + nikeda 05/20/04 - [OCI Events] Add incarnation, cardinality,reason + nikeda 05/18/04 - [OCI Events] Add OCI_ATTR_SERVICENAME + nikeda 05/17/04 - Add event handle + nikeda 05/13/04 - [OCI Events] Rename HACBK->EVTCBK, HACTX->EVTCTX + nikeda 05/10/04 - [OCI Events] code review changes + nikeda 04/15/04 - [OCI Events] OCI_SESSRLS_DROPSESS_FORCE + nikeda 04/12/04 - [OCI Events] Add OCI_ATTR_USER_MEMORY + aahluwal 04/12/04 - add OCI_HNDLFR_RESERVED5 + vraja 04/28/04 - add options for redo sync on commit + aahluwal 05/29/04 - [OCI Events]: add support for svc, svc member events + nikeda 05/28/04 - grabtrans 'nikeda_oci_events_copy' + nikeda 05/18/04 - [OCI Events] Add OCI_ATTR_SERVICENAME + nikeda 05/17/04 - Add event handle + nikeda 05/13/04 - [OCI Events] Rename HACBK->EVTCBK, HACTX->EVTCTX + nikeda 05/10/04 - [OCI Events] code review changes + nikeda 04/15/04 - [OCI Events] OCI_SESSRLS_DROPSESS_FORCE + nikeda 04/12/04 - [OCI Events] Add OCI_ATTR_USER_MEMORY + aahluwal 04/12/04 - add OCI_HNDLFR_RESERVED5 + jciminsk 04/28/04 - merge from RDBMS_MAIN_SOLARIS_040426 + jacao 03/06/04 - add OCI_ATTR_CURRENT_SCHEMA + aahluwal 01/20/04 - remove OCI_KEEP_FETCH_STATE + aahluwal 03/25/04 - [OCI Events] add OCI_HTYPE_HAEVENT and related attrs + nikeda 03/19/04 - [OCI Events] Add OCI_ATTR_HACBK and OCI_ATTR_HACTX + dfrumkin 12/04/03 - Add database startup/shutdown + chliang 12/22/03 - grid/main merge: add OCI_ATTR_RESERVED_20 + jciminsk 12/12/03 - merge from RDBMS_MAIN_SOLARIS_031209 + sgollapu 09/19/03 - Add fetch modes + sgollapu 07/30/03 - Add TSM attributes + sgollapu 06/26/03 - Add OCI_MUTEX_TRY + aime 06/23/03 - sync grid with main + sgollapu 06/07/03 - Add reserved attribute + sgollapu 06/05/03 - Add reserved auth flag + rpingte 05/22/03 - Add OCI_ATCH_RESERVED_5 + sgollapu 05/06/03 - Add TSM attributes + sgollapu 04/10/03 - Session migration Flags/interfaces + dfrumkin 04/23/04 - add OCI_PREP2_RESERVED_1 + rpingte 05/06/04 - add major and minor version information + bsinha 04/06/04 - add new OCI_TRANS flag + chliang 11/26/03 - add OCI_ATTR_RESERVED_19 + preilly 10/23/03 - Make OCI_ATTR_DIRPATH_METADATA_BUF private + chliang 08/07/03 - add OCI_ATTR_SKIP_BUFFER + srseshad 03/12/03 - convert public oci api to ansi + weiwang 05/14/03 - remove iot creation for rule sets + rkoti 04/15/03 - [2746515] add fntcodes for Unlimited size LOB 6003 + tcruanes 05/13/03 - add slave SQL OCI execution mode + rkoti 02/21/03 - [2761455] add OCI_FNCODE_AQENQARRAY, + OCI_FNCODE_AQDEQARRAY and update OCI_FNCODE_MAXFCN + tkeefe 01/29/03 - bug-2773794: Add new interface for setting Kerb attrs + aahluwal 02/06/03 - add OCI_ATTR_TRANSFORMATION_NO + weiwang 12/05/02 - add OCI_ATTR_USER_PROPERTY + ataracha 01/03/03 - include ocixmldb.h + preilly 12/05/02 - Add wait attribute for locking when using dir path + tkeefe 01/03/03 - bug-2623771: Added OCI_ATTR_KERBEROS_KEY + lchidamb 12/13/02 - end-to-end tracing attributes + msakayed 10/28/02 - Bug #2643907: add OCI_ATTR_DIRPATH_SKIPINDEX_METHOD + rphillip 11/13/02 - Add OCIP_ATTR_DIRPATH_INDEX + sagrawal 10/13/02 - liniting + sagrawal 10/03/02 - PL/SQL Compiler warnings + jstenois 11/07/02 - remove ocixad.h + chliang 10/21/02 - add OCI_ATTR_RESERVED_16,17 + hsbedi 10/30/02 - grabtrans 'jstenois_fix_xt_convert' + aahluwal 10/12/02 - add OCI_ATTR_AQ_NUM_E_ERRORS/OCI_ATTR_AQ_ERROR_INDEX + bdagevil 10/21/02 - add SQL analyze internal exec mode + csteinba 10/11/02 - add OCI_ATTR_RESERVED_16 + chliang 10/12/02 - add bind row callback attributes + preilly 10/25/02 - Add new reserved parameters + tkeefe 10/31/02 - bug-2623771: Added OCI_ATTR_AUDIT_SESSION_ID + csteinba 10/04/02 - Add OCI_ATTR_RESERVED_15 + mhho 10/11/02 - add new credential constant + thoang 09/25/02 - Add OCI_XMLTYPE_CREATE_CLOB + skaluska 10/07/02 - describe rules objects + csteinba 09/16/02 - Remove OCI_CACHE + gtarora 10/03/02 - OCI_ATTR_COL_SUBS => OCI_ATTR_OBJ_SUBS + msakayed 09/09/02 - Bug #2482469: add OCI_ATTR_DIRPATH_RESERVED_[3-6] + aahluwal 08/30/02 - adding dequeue across txn group + srseshad 04/24/02 - Add attribute OCI_ATTR_SPOOL_STMTCACHESIZE. + ebatbout 07/22/02 - Remove OCI_ATTR_RESERVED_11. + abande 01/17/02 - Bug 1788921; Add external attribute. + aahluwal 06/04/02 - bug 2360115 + pbagal 05/24/02 - Incorporate review comments + pbagal 05/22/02 - Introduce instance type attribute. + whe 07/01/02 - add OCI_BIND_DEFINE_SOFT flags + gtarora 07/01/02 - Add OCI_ATTR_COL_SUBS + tkeefe 05/30/02 - Add support for new proxy authentication credentials + dgprice 12/18/01 - bug 2102779 add reserved force describe + schandir 11/19/01 - add/modify modes. + schandir 11/15/01 - add OCI_SPC_STMTCACHE. + schandir 12/06/01 - change mode value of OCI_SPOOL. + msakayed 11/02/01 - Bug #2094292: add OCI_ATTR_DIRPATH_INPUT + dsaha 11/09/01 - add OCI_DTYPE_RESERVED1 + skabraha 11/05/01 - new method flag + skabraha 10/25/01 - another flag for XML + skabraha 10/11/01 - describe flags for subtypes + nbhatt 09/18/01 - new reserved AQ flags + celsbern 10/19/01 - merge LOG to MAIN + ksurlake 10/12/01 - add OCI_ATTR_RESERVED_13 + ksurlake 08/13/01 - add OCI_ATTR_RESERVED_12 + schandir 09/24/01 - Adding stmt caching + abande 09/04/01 - Adding session pooling + sagrawal 10/23/01 - add new bit for OCIPHandleFree + preilly 10/25/01 - Add support for specifying metadata on DirPathCtx + skabraha 09/24/01 - describe flags for XML type + schandir 09/24/01 - Adding stmt caching + abande 09/04/01 - Adding session pooling + stakeda 09/17/01 - add OCI_NLS_CHARSET_ID + whe 09/19/01 - add OCIXMLType create options + rpingte 09/11/01 - add OCI_MUTEX_ENV_ONLY and OCI_NO_MUTEX_STMT + cmlim 08/28/01 - mod datecache attrs to use same naming as dpapi attrs + wzhang 08/24/01 - Add new keywords for OCINlsNameMap. + rphillip 05/02/01 - Add date cache attributes + rphillip 08/22/01 - Add new stream version + ebatbout 04/13/01 - add definition, OCI_ATTR_RESERVED_11 + chliang 04/12/01 - add shortnames for newer oci funcation + wzhang 04/11/01 - Add new OCI NLS constants. + cmlim 04/13/01 - remove attrs not used by dpapi (151 & 152 avail) + rkambo 03/23/01 - bugfix 1421793 + cmlim 04/02/01 - remove OCI_ATTR_DIRPATH_{NESTED_TBL, SUBST_OBJ_TBL} + - note: attribute #s 186 & 205 available + whe 03/28/01 - add OCI_AFC_PAD_ON/OFF mode + preilly 03/05/01 - Add stream versioning support to DirPath context + schandir 12/18/00 - remove attr CONN_INCR_DELAY. + schandir 12/12/00 - change mode from OCI_POOL to OCI_CPOOL. + cbarclay 01/12/01 - add atribute for OCIP_ATTR_TMZ + whe 01/07/01 - add attributes related to UTF16 env mode + slari 12/29/00 - add blank line + slari 12/28/00 - OCI_ATTR_RESERVED_10 + whe 12/19/00 - add OCI_ENVCR_RESERVED3 + rpang 11/29/00 - Added OCI_ATTR_ORA_DEBUG_JDWP attribute + cmlim 11/28/00 - support substitutable object tables in dpapi + akatti 10/09/00 - [198379]:add OCIRowidToChar + sgollapu 10/11/00 - Add OCI_PREP_RESERVED_1 + sgollapu 08/27/00 - add attribute to get erroneous column + sgollapu 07/29/00 - Add snapshot attributes + kmohan 09/18/00 - add OCI_FNCODE_LOGON2 + abrumm 10/08/00 - include ocixad.h + mbastawa 10/04/00 - add OCI_ATTR_ROWS_FETCHED + nbhatt 08/24/00 - add transformation attribute + dmwong 08/22/00 - OCI_ATTR_CID_VALUE -> OCI_ATTR_CLIENT_IDENTIFIER. + cmlim 08/30/00 - add OCI_ATTR_DIRPATH_SID + dsaha 08/18/00 - add OCI_ATTR_RESERVED_5 + amangal 08/17/00 - Merge into 8.2 : 1194361 + slari 08/03/00 - add OCI_ATTR_HANDLE_POSITION + dsaha 07/20/00 - 2rt exec + sgollapu 07/04/00 - Add virtual session flag + cmlim 07/07/00 - add OCI_ATTR_DIRPATH_OID, OCI_ATTR_DIRPATH_NESTED_TBL + etucker 07/28/00 - add OCIIntervalFromTZ + rwessman 06/26/00 - N-tier: added new credential attributes + whe 07/27/00 - add OCI_UTF16 mode + vjayaram 07/18/00 - add connection pooling changes + etucker 07/12/00 - add dls apis + cmlim 07/07/00 - add OCI_ATTR_DIRPATH_OID, OCI_ATTR_DIRPATH_NESTED_TBL + sgollapu 07/04/00 - Add virtual session flag + najain 05/01/00 - AQ Signature support + sgollapu 06/14/00 - Add reserved OCI mode + rkambo 06/08/00 - notification presentation support + sagrawal 06/04/00 - ref cursor to c + ksurlake 06/07/00 - define OCI_POOL + mbastawa 06/05/00 - added scrollable cursor attributes + weiwang 03/31/00 - add LDAP support + whe 05/30/00 - add OCI_ATTR_MAXCHAR_SIZE + whe 05/23/00 - validate OCI_NO_CACHE mode + dsaha 02/02/00 - Add no-cache attr in statement handle + whe 05/23/00 - add OCIP_ICACHE + allee 05/17/00 - describe support for JAVA implmented TYPE + preilly 05/30/00 - Continue adding support for objects in direct path lo + cmlim 05/16/00 - 8.2 dpapi support of ADTs + rxgovind 05/04/00 - OCIAnyDataSet changes + rkasamse 05/25/00 - add OCIAnyDataCtx + rmurthy 04/26/00 - describe support for inheritance + ksurlake 04/18/00 - Add credential type + whe 05/24/00 - add OCI_ATTR_CHAR_ attrs + rkambo 04/19/00 - subscription enhancement + rmurthy 04/26/00 - describe support for inheritance + delson 03/28/00 - add OCI_ATTR_RESERVED_2 + abrumm 03/31/00 - external table support + rkasamse 03/13/00 - add declarations for OCIAnyData + najain 02/24/00 - support for dequeue as select + dsaha 03/10/00 - Add OCI_ALWAYS_BLOCKING + esoyleme 04/25/00 - separated transactions + sgollapu 12/23/99 - OCIServerAttach extensions + slari 08/23/99 - add OCI_DTYPE_UCB + slari 08/20/99 - add OCI_UCBTYPE_REPLACE + hsbedi 08/31/99 - Memory Stats . + sgollapu 08/02/99 - oci sql routing + slari 08/06/99 - rename values for OCI_SERVER_STATUS + slari 08/02/99 - add OCI_ATTR_SERVER_STATUS + tnbui 07/28/99 - Remove OCI_DTYPE_TIMESTAMP_ITZ + amangal 07/19/99 - Merge into 8.1.6 : bug 785797 + tnbui 07/07/99 - Change ADJUSTMENT modes + dsaha 07/07/99 - OCI_SAHRED_EXT + dmwong 06/08/99 - add OCI_ATTR_APPCTX_* + vyanaman 06/23/99 - + vyanaman 06/21/99 - Add new OCI Datetime and Interval descriptors + esoyleme 06/29/99 - expose MTS performance enhancements + rshaikh 04/23/99 - add OCI_SQL_VERSION_* + tnbui 05/24/99 - Remove OCIAdjStr + dsaha 05/21/99 - Add OCI_ADJUST_UNK + mluong 05/17/99 - fix merge + tnbui 04/05/99 - ADJUSTMENT values + abrumm 04/16/99 - dpapi: more attributes + dsaha 02/24/99 - Add OCI_SHOW_DML_WARNINGS + jiyang 12/07/98 - Add OCI_NLS_DUAL_CURRENCY + slari 12/07/98 - change OCI_NOMUTEX to OCI_NO_MUTEX + aroy 11/30/98 - change OCI_NOCALLBACK to OCI_NO_UCB + aroy 11/13/98 - add env modes to process modes + slari 09/08/98 - add OCI_FNCODE_SVC2HST and _SVCRH + aroy 09/04/98 - Add OCI_ATTR_MIGSESSION + skray 08/14/98 - server groups for session switching + mluong 08/11/98 - add back OCI_HTYPE_LAST. + aroy 05/25/98 - add process handle type + aroy 04/06/98 - add shared mode + slari 07/13/98 - merge forward to 8.1.4 + slari 07/09/98 - add OCI_BIND_RESERVED_2 + slari 07/08/98 - add OCI_EXACT_FETCH_RESERVED_1 + dsaha 07/07/98 - Add OCI_PARSE_ONLY + dsaha 06/29/98 - Add OCI_PARSE_ONLY + slari 07/01/98 - add OCI_BIND_RESERVED_2 + sgollapu 06/25/98 - Fix bug 683565 + slari 06/17/98 - remove OC_FETCH_RESERVED_2 + slari 06/11/98 - add OCI_FETCH_RESERVED_1 and 2 + jhasenbe 05/27/98 - Remove definitions for U-Calls (Unicode) + jiyang 05/18/98 - remove OCI_ATTR_CARTLANG + nbhatt 05/20/98 - OCI_DEQ_REMOVE_NODATA + nbhatt 05/19/98 - correct AQ opcode + skmishra 05/06/98 - Add precision attribute to Attributes list + aroy 04/20/98 - merge forward 8.0.5 -> 8.1.3 + schandra 05/01/98 - OCI sender id + sgollapu 02/19/98 - enhanced array DML + nbhatt 05/15/98 - AQ listen call + sgollapu 04/27/98 - more attributes + skaluska 04/06/98 - Add OCI_PTYPE_SCHEMA, OCI_PTYPE_DATABASE + slari 04/28/98 - add OCI_ATTR_PDPRC + lchidamb 05/05/98 - change OCI_NAMESPACE_AQ to 1 + nbhatt 04/27/98 - AQ Notification Descriptor + abrumm 06/24/98 - more direct path attributes + abrumm 05/27/98 - OCI direct path interface support + abrumm 05/08/98 - OCI direct path interface support + lchidamb 03/02/98 - client notification additions + kkarun 04/17/98 - Add more Interval functions + vyanaman 04/16/98 - Add get/set TZ + kkarun 04/14/98 - Add OCI Datetime shortnames + vyanaman 04/13/98 - Add OCI DateTime and Interval check error codes + kkarun 04/07/98 - Add OCI_DTYPE_DATETIME and OCI_DTYPE_INTERVAL + esoyleme 12/15/97 - support failover callback retry + esoyleme 04/22/98 - merge support for failover callback retry + mluong 04/16/98 - add OCI_FNCODE_LOBLOCATORASSIGN + rkasamse 04/17/98 - add short names for OCIPickler(Memory/Ctx) cart servi + slari 04/10/98 - add OCI_FNCODE_SVCCTXTOLDA + slari 04/09/98 - add OCI_FNCODE_RESET + slari 04/07/98 - add OCI_FNCODE_LOBFILEISOPEN + slari 04/06/98 - add OCI_FNCODE_LOBOPEN + slari 03/20/98 - change OCI_CBTYPE_xxx to OCI_UCBTYPE_xxx + slari 03/18/98 - add OCI_FNCODE_MAXFCN + slari 02/12/98 - add OCI_ENV_NO_USRCB + skabraha 04/09/98 - adding shortnames for OCIFile + rhwu 04/03/98 - Add short names for the OCIThread package + tanguyen 04/03/98 - add OCI_ATTR_xxxx for type inheritance + rkasamse 04/02/98 - add OCI_ATTR_UCI_REFRESH + nramakri 04/01/98 - Add short names for the OCIExtract package + ewaugh 03/31/98 - Add short names for the OCIFormat package. + jhasenbe 04/06/98 - Add definitions for U-Calls (Unicode) + (OCI_TEXT, OCI_UTEXT, OCI_UTEXT4) + skmishra 03/03/98 - Add OCI_ATTR_PARSE_ERROR_OFFSET + rwessman 03/11/98 - Added OCI_CRED_PROXY for proxy authentication + abrumm 03/31/98 - OCI direct path interface support + nmallava 03/03/98 - add constants for temp lob apis + skotsovo 03/05/98 - resolve merge conflicts + skotsovo 02/24/98 - add OCI_DTYPE_LOC + skaluska 01/21/98 - Add OCI_ATTR_LTYPE + rkasamse 01/06/98 - add OCI_ATTR* for obj cache enhancements + dchatter 01/08/98 - more comments + skabraha 12/02/97 - moved oci1.h to the front of include files. + jiyang 12/18/97 - Add OCI_NLS_MAX_BUFSZ + rhwu 12/02/97 - move oci1.h up + ewaugh 12/15/97 - Add short names for the OCIFormat package. + rkasamse 12/02/97 - Add a constant for memory cartridge services -- OCI_M + nmallava 12/31/97 - open/close for internal lobs + khnguyen 11/27/97 - add OCI_ATTR_LFPRECISION, OCI_ATTR_FSPRECISION + rkasamse 11/03/97 - add types for pickler cartridge services + mluong 11/20/97 - changed ubig_ora to ub4 per skotsovo + ssamu 11/14/97 - add oci1.h + jiyang 11/13/97 - Add NLS service for cartridge + esoyleme 12/15/97 - support failover callback retry + jwijaya 10/21/97 - change OCILobOffset/Length from ubig_ora to ub4 + cxcheng 07/28/97 - fix compile with SLSHORTNAME + schandra 06/25/97 - AQ OCI interface + sgollapu 07/25/97 - Add OCI_ATTR_DESC_PUBLIC + cxcheng 06/16/97 - add OCI_ATTR_TDO + skotsovo 06/05/97 - add fntcodes for lob buffering subsystem + esoyleme 05/13/97 - move failover callback prototype + skmishra 05/06/97 - stdc compiler fixes + skmishra 04/22/97 - Provide C++ compatibility + lchidamb 04/19/97 - add OCI_ATTR_SESSLANG + ramkrish 04/15/97 - Add OCI_LOB_BUFFER_(NO)FREE + sgollapu 04/18/97 - Add OCI_ATTR_TABLESPACE + skaluska 04/17/97 - Add OCI_ATTR_SUB_NAME + schandra 04/10/97 - Use long OCI names + aroy 03/27/97 - add OCI_DTYPE_FILE + sgollapu 03/26/97 - Add OCI_OTYPEs + skmishra 04/09/97 - Added constant OCI_ROWID_LEN + dchatter 03/21/97 - add attr OCI_ATTR_IN_V8_MODE + lchidamb 03/21/97 - add OCI_COMMIT_ON_SUCCESS execution mode + skmishra 03/20/97 - Added OCI_ATTR_LOBEMPTY + sgollapu 03/19/97 - Add OCI_ATTR_OVRLD_ID + aroy 03/17/97 - add postprocessing callback + sgollapu 03/15/97 - Add OCI_ATTR_PARAM + cxcheng 02/07/97 - change OCI_PTYPE codes for type method for consistenc + cxcheng 02/05/97 - add OCI_PTYPE_TYPE_RESULT + cxcheng 02/04/97 - rename OCI_PTYPE constants to be more consistent + cxcheng 02/03/97 - add OCI_ATTR, OCI_PTYPE contants for describe type + esoyleme 01/23/97 - merge neerja callback + sgollapu 12/30/96 - Remove OCI_DTYPE_SECURITY + asurpur 12/26/96 - CHanging OCI_NO_AUTH to OCI_AUTH + sgollapu 12/23/96 - Add more attrs to COL, ARG, and SEQ + sgollapu 12/12/96 - Add OCI_DESCRIBE_ONLY + slari 12/11/96 - change prototype of OCICallbackInBind + nbhatt 12/05/96 - "callback" + lchidamb 11/19/96 - handle subclassing + sgollapu 11/09/96 - OCI_PATTR_* + dchatter 11/04/96 - add attr OCI_ATTR_CHRCNT + mluong 11/01/96 - test + cxcheng 10/31/96 - add #defines for OCILobLength etc + dchatter 10/31/96 - add lob read write call back fp defs + dchatter 10/30/96 - more changes + rhari 10/30/96 - Include ociextp.h at the very end + lchidamb 10/22/96 - add fdo attribute for bind/server handle + dchatter 10/22/96 - change attr defn for prefetch parameters & lobs/file + calls + slari 10/21/96 - add OCI_ENV_NO_MUTEX + rhari 10/25/96 - Include ociextp.h + rxgovind 10/25/96 - add OCI_LOBMAXSIZE, remove OCI_FILE_READWRITE + sgollapu 10/24/96 - Correct OCILogon and OCILogoff + sgollapu 10/24/96 - Correct to OCILogon and OCILogoff + sgollapu 10/21/96 - Add ocilon and ociloff + skaluska 10/31/96 - Add OCI_PTYPE values + sgollapu 10/17/96 - correct OCI_ATTR_SVCCTX to OCI_ATTR_SERVER + rwessman 10/16/96 - Added security functions and fixed olint errors. + sthakur 10/14/96 - add more COR attributes + cxcheng 10/14/96 - re-enable LOB functions + sgollapu 10/10/96 - Add ocibdp and ocibdn + slari 10/07/96 - add back OCIRowid + aroy 10/08/96 - add typedef ocibfill for PRO*C + mluong 10/11/96 - replace OCI_ATTR_CHARSET* with OCI_ATTR_CHARSET_* + cxcheng 10/10/96 - temporarily take out #define for lob functions + sgollapu 10/02/96 - Rename OCI functions and datatypes + skotsovo 10/01/96 - move orl lob fnts to oci + aroy 09/10/96 - fix merge errors + aroy 08/19/96 - NCHAR support + jboonleu 09/05/96 - add OCI attributes for object cache + dchatter 08/20/96 - HTYPE ranges from 1-50; DTYPE from 50-255 + slari 08/06/96 - define OCI_DTYPE_ROWID + sthakur 08/14/96 - complex object support + schandra 06/17/96 - Convert XA to use new OCI + abrik 08/15/96 - OCI_ATTR_HEAPALLOC added + aroy 07/17/96 - terminology change: ocilobd => ocilobl + aroy 07/03/96 - add lob typedefs for Pro*C + slari 06/28/96 - add OCI_ATTR_STMT_TYPE + lchidamb 06/26/96 - reorg #ifndef + schandra 05/31/96 - attribute types for internal and external client name + asurpur 05/30/96 - Changing the value of mode + schandra 05/18/96 - OCI_TRANS_TWOPHASE -> 0x00000001 to 0x00100000 + slari 05/30/96 - add callback function prototypes + jbellemo 05/23/96 - remove ociisc + schandra 04/23/96 - loosely-coupled branches + asurpur 05/15/96 - New mode for ocicpw + aroy 04/24/96 - making ocihandles opaque + slari 04/18/96 - add missing defines + schandra 03/27/96 - V8OCI - add transaction related calls + dchatter 04/01/96 - add OCI_FILE options + dchatter 03/21/96 - add oci2lda conversion routines + dchatter 03/07/96 - add OCI piece definition + slari 03/12/96 - add describe attributes + slari 03/12/96 - add OCI_OTYPE_QUERY + aroy 02/28/96 - Add column attributes + slari 02/09/96 - add OCI_OBJECT + slari 02/07/96 - add OCI_HYTPE_DSC + aroy 01/10/96 - adding function code defines... + dchatter 01/03/96 - define OCI_NON_BLOCKING + dchatter 01/02/96 - Add Any descriptor + dchatter 01/02/96 - Add Select List descriptor + dchatter 12/29/95 - V8 OCI definitions + dchatter 12/29/95 - Creation + +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef ORATYPES +#include +#endif + +#ifndef OCIDFN +#include +#endif + +#ifndef OCI_ORACLE +# define OCI_ORACLE + + +/*--------------------------------------------------------------------------- + Short names provided for platforms which do not allow extended symbolic names + ---------------------------------------------------------------------------*/ + +#ifdef SLSHORTNAME +/* Translation of the long function/type names to short names for IBM only */ +/* maybe lint will use this too */ +#define OCISessionEnd ocitac +#define OCIResultSetToStmt ocirs2sh +#define OCISessionBegin ociauth +#define OCIServerAttach ociatch +#define OCIDescriptorAlloc ocigdesc +#define OCIServerDetach ocidtch +#define OCIDescriptorFree ocifdesc +#define OCIServerVersion ocivers +#define OCIDescribeAny ocidsca +#define OCIBindDynamic ocibda +#define OCIBindByName ocibdn +#define OCIBindByPos ocibdp +#define OCIErrorGet ocigdr +#define OCIBindArrayOfStruct ocibsa +#define OCIEnvInit ociinit +#define OCIBindObject ocibndt +#define OCIHandleAlloc ocighndl +#define OCIHandleFree ocifhndl +#define OCIRowidToChar ociri2c +#ifdef NEVER +#define OCIStmtBindByPos ocibndp +#define OCIStmtBindByName ocibndn +#endif +#define OCIAttrGet ocigattr +#define OCIDefineByPos ocidfne +#define OCIAttrSet ocisattr +#define OCIDefineDynamic ociddf +#define OCILdaToSvcCtx ocild2sv +#define OCIDefineArrayOfStruct ocidarr +#define OCIInitialize ocipi +#define OCIDefineObject ocidndt +#define OCIStmtExecute ociexec +#define OCILobAppend ocilfap +#define OCILobOpenFile ocifopn +#define OCILobCloseFile ocifcls +#define OCILobLocator ocilobd +#define OCILobGetDeduplicateRegions ocilgshr +#define OCILobRegion ocilregd +#define OCILobCopy ocilfcp +#define OCILobFileCreate ocifcrt +#define OCILobFileDelete ocifdel +#define OCILobGetLength ocilfln +#define OCILobWrite ocilfwr +#define OCILobRead ocilfrd +#define OCILobErase ocilfer +#define OCILobTrim ocilftr +#define OCILobSetOptions ocinglso +#define OCILobGetOptions ocinglgo +#define OCILobFragmentInsert ocinglfi +#define OCILobFragmentDelete ocinglfd +#define OCILobFragmentMove ocinglfm +#define OCILobFragmentReplace ocinglfr + +#define OCIStmtFetch ocifch +#define OCIStmtGetBindInfo ocigbp +#define OCIStmtGetPieceInfo ocigpi +#define OCIStmtPrepare ocireq +#define OCIStmtSetPieceInfo ocispi +#define OCISvcCtxToLda ocisv2ld +#define OCITransCommit ocitxcm +#define OCITransDetach ocitxdt +#define OCITransForget ocitxfgt +#define OCITransPrepare ocitxpre +#define OCITransRollback ocitxrl +#define OCIPasswordChange ocicpw +#define OCITransStart ocitxst +#define OCITransMultiPrepare ocitxmp + +#define OCIBreak ocibreak +#define OCIParamGet ocigparm +#define OCIParamSet ocisparm + +#define OCISecurityOpenWallet ocizwOpenWallet +#define OCISecurityCloseWallet ocizwCloseWallet +#define OCISecurityCreateWallet ocizwCreateWallet +#define OCISecurityDestroyWallet ocizwDestroyWallet +#define OCISecurityStorePersona ocizeStorePersona +#define OCISecurityOpenPersona ocizeOpenPersona +#define OCISecurityClosePersona ocizeClosePersona +#define OCISecurityRemovePersona ocizeRemovePersona +#define OCISecurityCreatePersona ocizeCreatePersona +#define OCISecuritySetProtection ocizeSetProtection +#define OCISecurityGetProtection ocizeGetProtection +#define OCISecurityRemoveIdentity ociziRemoveIdentity +#define OCISecurityCreateIdentity ociziCreateIdentity +#define OCISecurityAbortIdentity ociziAbortIdentity +#define OCISecurityFreeIdentity ociziFreeIdentity +#define OCISecurityStoreTrustedIdentity ociziStoreTrustedIdentity +#define OCISecuritySign ocizSign +#define OCISecuritySignExpansion ocizxSignExpansion +#define OCISecurityVerify ocizVerify +#define OCISecurityValidate ocizValidate +#define OCISecuritySignDetached ocizsd_SignDetached +#define OCISecuritySignDetExpansion ocizxsd_SignDetachedExpansion +#define OCISecurityVerifyDetached ocizved_VerifyDetached +#define OCISecurity_PKEncrypt ocizkec_PKEncrypt +#define OCISecurityPKEncryptExpansion ocizxkec_PKEncryptExpansion +#define OCISecurityPKDecrypt ocizkdc_PKDecrypt +#define OCISecurityEncrypt ocizEncrypt +#define OCISecurityEncryptExpansion ocizxEncryptExpansion +#define OCISecurityDecrypt ocizDecrypt +#define OCISecurityEnvelope ocizEnvelope +#define OCISecurityDeEnvelope ocizDeEnvelope +#define OCISecurityKeyedHash ocizKeyedHash +#define OCISecurityKeyedHashExpansion ocizxKeyedHashExpansion +#define OCISecurityHash ocizHash +#define OCISecurityHashExpansion ocizxHashExpansion +#define OCISecuritySeedRandom ocizSeedRandom +#define OCISecurityRandomBytes ocizrb_RandomBytes +#define OCISecurityRandomNumber ocizrn_RandomNumber +#define OCISecurityInitBlock ocizibInitBlock +#define OCISecurityReuseBlock ocizrbReuseBlock +#define OCISecurityPurgeBlock ocizpbPurgeBlock +#define OCISecuritySetBlock ocizsbSetBlock +#define OCISecurityGetIdentity ocizgi_GetIdentity + +#define OCIExtractInit ocixeini +#define OCIExtractTerm ocixetrm +#define OCIExtractReset ocixerst +#define OCIExtractSetNumKeys ocixesnk +#define OCIExtractSetKey ocixesk +#define OCIExtractFromFile ocixeff +#define OCIExtractFromStr ocixefs +#define OCIExtractToInt ocixeti +#define OCIExtractToBool ocixetb +#define OCIExtractToStr ocixets +#define OCIExtractToOCINum ocixeton +#define OCIExtractToList ocixetl +#define OCIExtractFromList ocixefl + +#define OCIDateTimeGetTime ocidt01_GetTime +#define OCIDateTimeGetDate ocidt02_GetDate +#define OCIDateTimeGetTimeZoneOffset ocidt03_GetTZ +#define OCIDateTimeSysTimeStamp ocidt07_SysTS +#define OCIDateTimeAssign ocidt08_Assign +#define OCIDateTimeToText ocidt09_ToText +#define OCIDateTimeFromText ocidt10_FromText +#define OCIDateTimeCompare ocidt11_Compare +#define OCIDateTimeCheck ocidt12_Check +#define OCIDateTimeConvert ocidt13_Convert +#define OCIDateTimeSubtract ocidt14_Subtract +#define OCIDateTimeIntervalAdd ocidt15_IntervalAdd +#define OCIDateTimeIntervalSub ocidt16_IntervalSub +#define OCIDateTimeGetTimeZoneName ocidt17_Gettzname +#define OCIDateTimeToArray ocidt18_ToArray +#define OCIDateTimeFromArray ocidt19_FromArray + +#define OCIIntervalSubtract ociint01_Subtract +#define OCIIntervalAdd ociint02_Add +#define OCIIntervalMultiply ociint03_Multiply +#define OCIIntervalDivide ociint04_Divide +#define OCIIntervalCompare ociint05_Compare +#define OCIIntervalFromText ociint06_FromText +#define OCIIntervalToText ociint07_ToText +#define OCIIntervalToNumber ociint08_ToNumber +#define OCIIntervalCheck ociint09_Check +#define OCIIntervalAssign ociint10_Assign +#define OCIIntervalGetYearMonth ociint11_GetYearMonth +#define OCIIntervalSetYearMonth ociint12_SetYearMonth +#define OCIIntervalGetDaySecond ociint13_GetDaySecond +#define OCIIntervalSetDaySecond ociint14_SetDaySecond +#define OCIIntervalFromNumber ociint15_FromNumber +#define OCIIntervalFromTZ ociint16_FromTZ + +#define OCIFormatInit ocixs01_Init +#define OCIFormatString ocixs02_Format +#define OCIFormatTerm ocixs03_Term +#define OCIFormatTUb1 ocixs04_TUb1 +#define OCIFormatTUb2 ocixs05_TUb2 +#define OCIFormatTUb4 ocixs06_TUb4 +#define OCIFormatTUword ocixs07_TUword +#define OCIFormatTUbig_ora ocixs08_TUbig_ora +#define OCIFormatTSb1 ocixs09_TSb1 +#define OCIFormatTSb2 ocixs10_TSb2 +#define OCIFormatTSb4 ocixs11_TSb4 +#define OCIFormatTSword ocixs12_TSword +#define OCIFormatTSbig_ora ocixs13_TSbig_ora +#define OCIFormatTEb1 ocixs14_TEb1 +#define OCIFormatTEb2 ocixs15_TEb2 +#define OCIFormatTEb4 ocixs16_TEb4 +#define OCIFormatTEword ocixs17_TEword +#define OCIFormatTChar ocixs18_TChar +#define OCIFormatTText ocixs19_TText +#define OCIFormatTDouble ocixs20_TDouble +#define OCIFormatTDvoid ocixs21_TDvoid +#define OCIFormatTEnd ocixs22_TEnd + +#define OCIFileInit ocifinit +#define OCIFileTerm ocifterm +#define OCIFileOpen ocifopen +#define OCIFileClose ocifclose +#define OCIFileRead ocifread +#define OCIFileWrite ocifwrite +#define OCIFileSeek ocifseek +#define OCIFileExists ocifexists +#define OCIFileGetLength ocifglen +#define OCIFileFlush ocifflush + + +/* OCIThread short name */ +#define OCIThreadProcessInit ocitt01_ProcessInit +#define OCIThreadInit ocitt02_Init +#define OCIThreadTerm ocitt03_Term +#define OCIThreadIsMulti ocitt04_IsMulti +#define OCIThreadMutexInit ocitt05_MutexInit +#define OCIThreadMutexDestroy ocitt06_MutexDestroy +#define OCIThreadMutexAcquire ocitt07_MutexAcquire +#define OCIThreadMutexRelease ocitt08_MutexRelease +#define OCIThreadKeyInit ocitt09_KeyInit +#define OCIThreadKeyDestroy ocitt10_KeyDestroy +#define OCIThreadKeyGet ocitt11_KeyGet +#define OCIThreadKeySet ocitt12_KeySet +#define OCIThreadIdInit ocitt13_IdInit +#define OCIThreadIdDestroy ocitt14_IdDestroy +#define OCIThreadIdSet ocitt15_IdSet +#define OCIThreadIdSetNull ocitt16_IdSetNull +#define OCIThreadIdGet ocitt17_IdGet +#define OCIThreadIdSame ocitt18_IdSame +#define OCIThreadIdNull ocitt19_IdNull +#define OCIThreadHndInit ocitt20_HndInit +#define OCIThreadHndDestroy ocitt21_HndDestroy +#define OCIThreadCreate ocitt22_Create +#define OCIThreadJoin ocitt23_Join +#define OCIThreadClose ocitt24_Close +#define OCIThreadHandleGet ocitt25_HandleGet + +/* Translation between the old and new datatypes */ + +#define OCISession ociusrh +#define OCIBind ocibndh +#define OCIDescribe ocidsch +#define OCIDefine ocidfnh +#define OCIEnv ocienvh +#define OCIError ocierrh + +#define OCICPool ocicpool + +#define OCISPool ocispool +#define OCIAuthInfo ociauthinfo + + +#define OCILob ocilobd +#define OCILobLength ocillen +#define OCILobMode ocilmo +#define OCILobOffset ociloff + +#define OCILobLocator ocilobd +#define OCIBlobLocator ociblobl +#define OCIClobLocator ociclobl +#define OCILobRegion ocilregd +#define OCIBFileLocator ocibfilel + +#define OCIParam ocipard +#define OCIResult ocirstd +#define OCISnapshot ocisnad +#define OCIServer ocisrvh +#define OCIStmt ocistmh +#define OCISvcCtx ocisvch +#define OCITrans ocitxnh +#define OCICallbackInBind ocibicfp +#define OCICallbackOutBind ocibocfp +#define OCICallbackDefine ocidcfp +#define OCICallbackLobRead ocilrfp +#define OCICallbackLobWrite ocilwfp +#define OCICallbackLobGetDededuplicateRegions ocilgshr +#define OCISecurity ociossh +#define OCIComplexObject ocicorh +#define OCIComplexObjectComp ocicord +#define OCIRowid ociridd + +#define OCIAQDeq ociaqdeq +#define OCIAQEnq ociaqenq +#define OCIConnectionPoolCreate ociconpc +#define OCIConnectionPoolDestroy ociconpd +#define OCIEnvCreate ocienvct +#define OCILobAssign ociloass +#define OCILobCharSetForm ocilocfm +#define OCILobCharSetId ocilocid +#define OCILobDisableBuffering ocilodbf +#define OCILobEnableBuffering ociloebf +#define OCILobFileClose ocilofcl +#define OCILobFileCloseAll ocilofca +#define OCILobFileExists ocilofex +#define OCILobFileGetName ocilofgn +#define OCILobFileIsOpen ocifiopn +#define OCILobFileOpen ocilofop +#define OCILobFileSetName ocilofsn +#define OCILobFlushBuffer ocilofbf +#define OCILobIsEqual ociloieq +#define OCILobLoadFromFile ocilolff +#define OCILobLocatorIsInit ocilolii +#define OCILobLocatorAssign ocilolas +#define OCILogon ocilogon +#define OCILogon2 ocilgon2 +#define OCILogoff ocilgoff +#endif /* ifdef SLSHORTNAME */ + +/*--------------------------------------------------------------------------- + PUBLIC TYPES AND CONSTANTS + ---------------------------------------------------------------------------*/ + +/*-----------------------------Handle Types----------------------------------*/ + /* handle types range from 1 - 49 */ +#define OCI_HTYPE_FIRST 1 /* start value of handle type */ +#define OCI_HTYPE_ENV 1 /* environment handle */ +#define OCI_HTYPE_ERROR 2 /* error handle */ +#define OCI_HTYPE_SVCCTX 3 /* service handle */ +#define OCI_HTYPE_STMT 4 /* statement handle */ +#define OCI_HTYPE_BIND 5 /* bind handle */ +#define OCI_HTYPE_DEFINE 6 /* define handle */ +#define OCI_HTYPE_DESCRIBE 7 /* describe handle */ +#define OCI_HTYPE_SERVER 8 /* server handle */ +#define OCI_HTYPE_SESSION 9 /* authentication handle */ +#define OCI_HTYPE_AUTHINFO OCI_HTYPE_SESSION /* SessionGet auth handle */ +#define OCI_HTYPE_TRANS 10 /* transaction handle */ +#define OCI_HTYPE_COMPLEXOBJECT 11 /* complex object retrieval handle */ +#define OCI_HTYPE_SECURITY 12 /* security handle */ +#define OCI_HTYPE_SUBSCRIPTION 13 /* subscription handle */ +#define OCI_HTYPE_DIRPATH_CTX 14 /* direct path context */ +#define OCI_HTYPE_DIRPATH_COLUMN_ARRAY 15 /* direct path column array */ +#define OCI_HTYPE_DIRPATH_STREAM 16 /* direct path stream */ +#define OCI_HTYPE_PROC 17 /* process handle */ +#define OCI_HTYPE_DIRPATH_FN_CTX 18 /* direct path function context */ +#define OCI_HTYPE_DIRPATH_FN_COL_ARRAY 19 /* dp object column array */ +#define OCI_HTYPE_XADSESSION 20 /* access driver session */ +#define OCI_HTYPE_XADTABLE 21 /* access driver table */ +#define OCI_HTYPE_XADFIELD 22 /* access driver field */ +#define OCI_HTYPE_XADGRANULE 23 /* access driver granule */ +#define OCI_HTYPE_XADRECORD 24 /* access driver record */ +#define OCI_HTYPE_XADIO 25 /* access driver I/O */ +#define OCI_HTYPE_CPOOL 26 /* connection pool handle */ +#define OCI_HTYPE_SPOOL 27 /* session pool handle */ +#define OCI_HTYPE_ADMIN 28 /* admin handle */ +#define OCI_HTYPE_EVENT 29 /* HA event handle */ + +#define OCI_HTYPE_LAST 29 /* last value of a handle type */ + +/*---------------------------------------------------------------------------*/ + + +/*-------------------------Descriptor Types----------------------------------*/ + /* descriptor values range from 50 - 255 */ +#define OCI_DTYPE_FIRST 50 /* start value of descriptor type */ +#define OCI_DTYPE_LOB 50 /* lob locator */ +#define OCI_DTYPE_SNAP 51 /* snapshot descriptor */ +#define OCI_DTYPE_RSET 52 /* result set descriptor */ +#define OCI_DTYPE_PARAM 53 /* a parameter descriptor obtained from ocigparm */ +#define OCI_DTYPE_ROWID 54 /* rowid descriptor */ +#define OCI_DTYPE_COMPLEXOBJECTCOMP 55 + /* complex object retrieval descriptor */ +#define OCI_DTYPE_FILE 56 /* File Lob locator */ +#define OCI_DTYPE_AQENQ_OPTIONS 57 /* enqueue options */ +#define OCI_DTYPE_AQDEQ_OPTIONS 58 /* dequeue options */ +#define OCI_DTYPE_AQMSG_PROPERTIES 59 /* message properties */ +#define OCI_DTYPE_AQAGENT 60 /* aq agent */ +#define OCI_DTYPE_LOCATOR 61 /* LOB locator */ +#define OCI_DTYPE_INTERVAL_YM 62 /* Interval year month */ +#define OCI_DTYPE_INTERVAL_DS 63 /* Interval day second */ +#define OCI_DTYPE_AQNFY_DESCRIPTOR 64 /* AQ notify descriptor */ +#define OCI_DTYPE_DATE 65 /* Date */ +#define OCI_DTYPE_TIME 66 /* Time */ +#define OCI_DTYPE_TIME_TZ 67 /* Time with timezone */ +#define OCI_DTYPE_TIMESTAMP 68 /* Timestamp */ +#define OCI_DTYPE_TIMESTAMP_TZ 69 /* Timestamp with timezone */ +#define OCI_DTYPE_TIMESTAMP_LTZ 70 /* Timestamp with local tz */ +#define OCI_DTYPE_UCB 71 /* user callback descriptor */ +#define OCI_DTYPE_SRVDN 72 /* server DN list descriptor */ +#define OCI_DTYPE_SIGNATURE 73 /* signature */ +#define OCI_DTYPE_RESERVED_1 74 /* reserved for internal use */ +#define OCI_DTYPE_AQLIS_OPTIONS 75 /* AQ listen options */ +#define OCI_DTYPE_AQLIS_MSG_PROPERTIES 76 /* AQ listen msg props */ +#define OCI_DTYPE_CHDES 77 /* Top level change notification desc */ +#define OCI_DTYPE_TABLE_CHDES 78 /* Table change descriptor */ +#define OCI_DTYPE_ROW_CHDES 79 /* Row change descriptor */ +#define OCI_DTYPE_CQDES 80 /* Query change descriptor */ +#define OCI_DTYPE_LOB_REGION 81 /* LOB Share region descriptor */ +#define OCI_DTYPE_LAST 81 /* last value of a descriptor type */ + +/*---------------------------------------------------------------------------*/ + +/*--------------------------------LOB types ---------------------------------*/ +#define OCI_TEMP_BLOB 1 /* LOB type - BLOB ------------------ */ +#define OCI_TEMP_CLOB 2 /* LOB type - CLOB ------------------ */ +/*---------------------------------------------------------------------------*/ + +/*-------------------------Object Ptr Types----------------------------------*/ +#define OCI_OTYPE_NAME 1 /* object name */ +#define OCI_OTYPE_REF 2 /* REF to TDO */ +#define OCI_OTYPE_PTR 3 /* PTR to TDO */ +/*---------------------------------------------------------------------------*/ + +/*=============================Attribute Types===============================*/ +/* + Note: All attributes are global. New attibutes should be added to the end + of the list. Before you add an attribute see if an existing one can be + used for your handle. + + If you see any holes please use the holes first. + +*/ +/*===========================================================================*/ + + +#define OCI_ATTR_FNCODE 1 /* the OCI function code */ +#define OCI_ATTR_OBJECT 2 /* is the environment initialized in object mode */ +#define OCI_ATTR_NONBLOCKING_MODE 3 /* non blocking mode */ +#define OCI_ATTR_SQLCODE 4 /* the SQL verb */ +#define OCI_ATTR_ENV 5 /* the environment handle */ +#define OCI_ATTR_SERVER 6 /* the server handle */ +#define OCI_ATTR_SESSION 7 /* the user session handle */ +#define OCI_ATTR_TRANS 8 /* the transaction handle */ +#define OCI_ATTR_ROW_COUNT 9 /* the rows processed so far */ +#define OCI_ATTR_SQLFNCODE 10 /* the SQL verb of the statement */ +#define OCI_ATTR_PREFETCH_ROWS 11 /* sets the number of rows to prefetch */ +#define OCI_ATTR_NESTED_PREFETCH_ROWS 12 /* the prefetch rows of nested table*/ +#define OCI_ATTR_PREFETCH_MEMORY 13 /* memory limit for rows fetched */ +#define OCI_ATTR_NESTED_PREFETCH_MEMORY 14 /* memory limit for nested rows */ +#define OCI_ATTR_CHAR_COUNT 15 + /* this specifies the bind and define size in characters */ +#define OCI_ATTR_PDSCL 16 /* packed decimal scale */ +#define OCI_ATTR_FSPRECISION OCI_ATTR_PDSCL + /* fs prec for datetime data types */ +#define OCI_ATTR_PDPRC 17 /* packed decimal format */ +#define OCI_ATTR_LFPRECISION OCI_ATTR_PDPRC + /* fs prec for datetime data types */ +#define OCI_ATTR_PARAM_COUNT 18 /* number of column in the select list */ +#define OCI_ATTR_ROWID 19 /* the rowid */ +#define OCI_ATTR_CHARSET 20 /* the character set value */ +#define OCI_ATTR_NCHAR 21 /* NCHAR type */ +#define OCI_ATTR_USERNAME 22 /* username attribute */ +#define OCI_ATTR_PASSWORD 23 /* password attribute */ +#define OCI_ATTR_STMT_TYPE 24 /* statement type */ +#define OCI_ATTR_INTERNAL_NAME 25 /* user friendly global name */ +#define OCI_ATTR_EXTERNAL_NAME 26 /* the internal name for global txn */ +#define OCI_ATTR_XID 27 /* XOPEN defined global transaction id */ +#define OCI_ATTR_TRANS_LOCK 28 /* */ +#define OCI_ATTR_TRANS_NAME 29 /* string to identify a global transaction */ +#define OCI_ATTR_HEAPALLOC 30 /* memory allocated on the heap */ +#define OCI_ATTR_CHARSET_ID 31 /* Character Set ID */ +#define OCI_ATTR_CHARSET_FORM 32 /* Character Set Form */ +#define OCI_ATTR_MAXDATA_SIZE 33 /* Maximumsize of data on the server */ +#define OCI_ATTR_CACHE_OPT_SIZE 34 /* object cache optimal size */ +#define OCI_ATTR_CACHE_MAX_SIZE 35 /* object cache maximum size percentage */ +#define OCI_ATTR_PINOPTION 36 /* object cache default pin option */ +#define OCI_ATTR_ALLOC_DURATION 37 + /* object cache default allocation duration */ +#define OCI_ATTR_PIN_DURATION 38 /* object cache default pin duration */ +#define OCI_ATTR_FDO 39 /* Format Descriptor object attribute */ +#define OCI_ATTR_POSTPROCESSING_CALLBACK 40 + /* Callback to process outbind data */ +#define OCI_ATTR_POSTPROCESSING_CONTEXT 41 + /* Callback context to process outbind data */ +#define OCI_ATTR_ROWS_RETURNED 42 + /* Number of rows returned in current iter - for Bind handles */ +#define OCI_ATTR_FOCBK 43 /* Failover Callback attribute */ +#define OCI_ATTR_IN_V8_MODE 44 /* is the server/service context in V8 mode */ +#define OCI_ATTR_LOBEMPTY 45 /* empty lob ? */ +#define OCI_ATTR_SESSLANG 46 /* session language handle */ + +#define OCI_ATTR_VISIBILITY 47 /* visibility */ +#define OCI_ATTR_RELATIVE_MSGID 48 /* relative message id */ +#define OCI_ATTR_SEQUENCE_DEVIATION 49 /* sequence deviation */ + +#define OCI_ATTR_CONSUMER_NAME 50 /* consumer name */ +#define OCI_ATTR_DEQ_MODE 51 /* dequeue mode */ +#define OCI_ATTR_NAVIGATION 52 /* navigation */ +#define OCI_ATTR_WAIT 53 /* wait */ +#define OCI_ATTR_DEQ_MSGID 54 /* dequeue message id */ + +#define OCI_ATTR_PRIORITY 55 /* priority */ +#define OCI_ATTR_DELAY 56 /* delay */ +#define OCI_ATTR_EXPIRATION 57 /* expiration */ +#define OCI_ATTR_CORRELATION 58 /* correlation id */ +#define OCI_ATTR_ATTEMPTS 59 /* # of attempts */ +#define OCI_ATTR_RECIPIENT_LIST 60 /* recipient list */ +#define OCI_ATTR_EXCEPTION_QUEUE 61 /* exception queue name */ +#define OCI_ATTR_ENQ_TIME 62 /* enqueue time (only OCIAttrGet) */ +#define OCI_ATTR_MSG_STATE 63/* message state (only OCIAttrGet) */ + /* NOTE: 64-66 used below */ +#define OCI_ATTR_AGENT_NAME 64 /* agent name */ +#define OCI_ATTR_AGENT_ADDRESS 65 /* agent address */ +#define OCI_ATTR_AGENT_PROTOCOL 66 /* agent protocol */ +#define OCI_ATTR_USER_PROPERTY 67 /* user property */ +#define OCI_ATTR_SENDER_ID 68 /* sender id */ +#define OCI_ATTR_ORIGINAL_MSGID 69 /* original message id */ + +#define OCI_ATTR_QUEUE_NAME 70 /* queue name */ +#define OCI_ATTR_NFY_MSGID 71 /* message id */ +#define OCI_ATTR_MSG_PROP 72 /* message properties */ + +#define OCI_ATTR_NUM_DML_ERRORS 73 /* num of errs in array DML */ +#define OCI_ATTR_DML_ROW_OFFSET 74 /* row offset in the array */ + + /* AQ array error handling uses DML method of accessing errors */ +#define OCI_ATTR_AQ_NUM_ERRORS OCI_ATTR_NUM_DML_ERRORS +#define OCI_ATTR_AQ_ERROR_INDEX OCI_ATTR_DML_ROW_OFFSET + +#define OCI_ATTR_DATEFORMAT 75 /* default date format string */ +#define OCI_ATTR_BUF_ADDR 76 /* buffer address */ +#define OCI_ATTR_BUF_SIZE 77 /* buffer size */ + +/* For values 78 - 80, see DirPathAPI attribute section in this file */ + +#define OCI_ATTR_NUM_ROWS 81 /* number of rows in column array */ + /* NOTE that OCI_ATTR_NUM_COLS is a column + * array attribute too. + */ +#define OCI_ATTR_COL_COUNT 82 /* columns of column array + processed so far. */ +#define OCI_ATTR_STREAM_OFFSET 83 /* str off of last row processed */ +#define OCI_ATTR_SHARED_HEAPALLOC 84 /* Shared Heap Allocation Size */ + +#define OCI_ATTR_SERVER_GROUP 85 /* server group name */ + +#define OCI_ATTR_MIGSESSION 86 /* migratable session attribute */ + +#define OCI_ATTR_NOCACHE 87 /* Temporary LOBs */ + +#define OCI_ATTR_MEMPOOL_SIZE 88 /* Pool Size */ +#define OCI_ATTR_MEMPOOL_INSTNAME 89 /* Instance name */ +#define OCI_ATTR_MEMPOOL_APPNAME 90 /* Application name */ +#define OCI_ATTR_MEMPOOL_HOMENAME 91 /* Home Directory name */ +#define OCI_ATTR_MEMPOOL_MODEL 92 /* Pool Model (proc,thrd,both)*/ +#define OCI_ATTR_MODES 93 /* Modes */ + +#define OCI_ATTR_SUBSCR_NAME 94 /* name of subscription */ +#define OCI_ATTR_SUBSCR_CALLBACK 95 /* associated callback */ +#define OCI_ATTR_SUBSCR_CTX 96 /* associated callback context */ +#define OCI_ATTR_SUBSCR_PAYLOAD 97 /* associated payload */ +#define OCI_ATTR_SUBSCR_NAMESPACE 98 /* associated namespace */ + +#define OCI_ATTR_PROXY_CREDENTIALS 99 /* Proxy user credentials */ +#define OCI_ATTR_INITIAL_CLIENT_ROLES 100 /* Initial client role list */ + +#define OCI_ATTR_UNK 101 /* unknown attribute */ +#define OCI_ATTR_NUM_COLS 102 /* number of columns */ +#define OCI_ATTR_LIST_COLUMNS 103 /* parameter of the column list */ +#define OCI_ATTR_RDBA 104 /* DBA of the segment header */ +#define OCI_ATTR_CLUSTERED 105 /* whether the table is clustered */ +#define OCI_ATTR_PARTITIONED 106 /* whether the table is partitioned */ +#define OCI_ATTR_INDEX_ONLY 107 /* whether the table is index only */ +#define OCI_ATTR_LIST_ARGUMENTS 108 /* parameter of the argument list */ +#define OCI_ATTR_LIST_SUBPROGRAMS 109 /* parameter of the subprogram list */ +#define OCI_ATTR_REF_TDO 110 /* REF to the type descriptor */ +#define OCI_ATTR_LINK 111 /* the database link name */ +#define OCI_ATTR_MIN 112 /* minimum value */ +#define OCI_ATTR_MAX 113 /* maximum value */ +#define OCI_ATTR_INCR 114 /* increment value */ +#define OCI_ATTR_CACHE 115 /* number of sequence numbers cached */ +#define OCI_ATTR_ORDER 116 /* whether the sequence is ordered */ +#define OCI_ATTR_HW_MARK 117 /* high-water mark */ +#define OCI_ATTR_TYPE_SCHEMA 118 /* type's schema name */ +#define OCI_ATTR_TIMESTAMP 119 /* timestamp of the object */ +#define OCI_ATTR_NUM_ATTRS 120 /* number of sttributes */ +#define OCI_ATTR_NUM_PARAMS 121 /* number of parameters */ +#define OCI_ATTR_OBJID 122 /* object id for a table or view */ +#define OCI_ATTR_PTYPE 123 /* type of info described by */ +#define OCI_ATTR_PARAM 124 /* parameter descriptor */ +#define OCI_ATTR_OVERLOAD_ID 125 /* overload ID for funcs and procs */ +#define OCI_ATTR_TABLESPACE 126 /* table name space */ +#define OCI_ATTR_TDO 127 /* TDO of a type */ +#define OCI_ATTR_LTYPE 128 /* list type */ +#define OCI_ATTR_PARSE_ERROR_OFFSET 129 /* Parse Error offset */ +#define OCI_ATTR_IS_TEMPORARY 130 /* whether table is temporary */ +#define OCI_ATTR_IS_TYPED 131 /* whether table is typed */ +#define OCI_ATTR_DURATION 132 /* duration of temporary table */ +#define OCI_ATTR_IS_INVOKER_RIGHTS 133 /* is invoker rights */ +#define OCI_ATTR_OBJ_NAME 134 /* top level schema obj name */ +#define OCI_ATTR_OBJ_SCHEMA 135 /* schema name */ +#define OCI_ATTR_OBJ_ID 136 /* top level schema object id */ + +/* For values 137 - 141, see DirPathAPI attribute section in this file */ + + +#define OCI_ATTR_TRANS_TIMEOUT 142 /* transaction timeout */ +#define OCI_ATTR_SERVER_STATUS 143/* state of the server handle */ +#define OCI_ATTR_STATEMENT 144 /* statement txt in stmt hdl */ + +/* For value 145, see DirPathAPI attribute section in this file */ + +#define OCI_ATTR_DEQCOND 146 /* dequeue condition */ +#define OCI_ATTR_RESERVED_2 147 /* reserved */ + + +#define OCI_ATTR_SUBSCR_RECPT 148 /* recepient of subscription */ +#define OCI_ATTR_SUBSCR_RECPTPROTO 149 /* protocol for recepient */ + +/* For values 150 - 151, see DirPathAPI attribute section in this file */ + +#define OCI_ATTR_LDAP_HOST 153 /* LDAP host to connect to */ +#define OCI_ATTR_LDAP_PORT 154 /* LDAP port to connect to */ +#define OCI_ATTR_BIND_DN 155 /* bind DN */ +#define OCI_ATTR_LDAP_CRED 156 /* credentials to connect to LDAP */ +#define OCI_ATTR_WALL_LOC 157 /* client wallet location */ +#define OCI_ATTR_LDAP_AUTH 158 /* LDAP authentication method */ +#define OCI_ATTR_LDAP_CTX 159 /* LDAP adminstration context DN */ +#define OCI_ATTR_SERVER_DNS 160 /* list of registration server DNs */ + +#define OCI_ATTR_DN_COUNT 161 /* the number of server DNs */ +#define OCI_ATTR_SERVER_DN 162 /* server DN attribute */ + +#define OCI_ATTR_MAXCHAR_SIZE 163 /* max char size of data */ + +#define OCI_ATTR_CURRENT_POSITION 164 /* for scrollable result sets*/ + +/* Added to get attributes for ref cursor to statement handle */ +#define OCI_ATTR_RESERVED_3 165 /* reserved */ +#define OCI_ATTR_RESERVED_4 166 /* reserved */ + +/* For value 167, see DirPathAPI attribute section in this file */ + +#define OCI_ATTR_DIGEST_ALGO 168 /* digest algorithm */ +#define OCI_ATTR_CERTIFICATE 169 /* certificate */ +#define OCI_ATTR_SIGNATURE_ALGO 170 /* signature algorithm */ +#define OCI_ATTR_CANONICAL_ALGO 171 /* canonicalization algo. */ +#define OCI_ATTR_PRIVATE_KEY 172 /* private key */ +#define OCI_ATTR_DIGEST_VALUE 173 /* digest value */ +#define OCI_ATTR_SIGNATURE_VAL 174 /* signature value */ +#define OCI_ATTR_SIGNATURE 175 /* signature */ + +/* attributes for setting OCI stmt caching specifics in svchp */ +#define OCI_ATTR_STMTCACHESIZE 176 /* size of the stm cache */ + +/* --------------------------- Connection Pool Attributes ------------------ */ +#define OCI_ATTR_CONN_NOWAIT 178 +#define OCI_ATTR_CONN_BUSY_COUNT 179 +#define OCI_ATTR_CONN_OPEN_COUNT 180 +#define OCI_ATTR_CONN_TIMEOUT 181 +#define OCI_ATTR_STMT_STATE 182 +#define OCI_ATTR_CONN_MIN 183 +#define OCI_ATTR_CONN_MAX 184 +#define OCI_ATTR_CONN_INCR 185 + +/* For value 187, see DirPathAPI attribute section in this file */ + +#define OCI_ATTR_NUM_OPEN_STMTS 188 /* open stmts in session */ +#define OCI_ATTR_DESCRIBE_NATIVE 189 /* get native info via desc */ + +#define OCI_ATTR_BIND_COUNT 190 /* number of bind postions */ +#define OCI_ATTR_HANDLE_POSITION 191 /* pos of bind/define handle */ +#define OCI_ATTR_RESERVED_5 192 /* reserverd */ +#define OCI_ATTR_SERVER_BUSY 193 /* call in progress on server*/ + +/* For value 194, see DirPathAPI attribute section in this file */ + +/* notification presentation for recipient */ +#define OCI_ATTR_SUBSCR_RECPTPRES 195 +#define OCI_ATTR_TRANSFORMATION 196 /* AQ message transformation */ + +#define OCI_ATTR_ROWS_FETCHED 197 /* rows fetched in last call */ + +/* --------------------------- Snapshot attributes ------------------------- */ +#define OCI_ATTR_SCN_BASE 198 /* snapshot base */ +#define OCI_ATTR_SCN_WRAP 199 /* snapshot wrap */ + +/* --------------------------- Miscellanous attributes --------------------- */ +#define OCI_ATTR_RESERVED_6 200 /* reserved */ +#define OCI_ATTR_READONLY_TXN 201 /* txn is readonly */ +#define OCI_ATTR_RESERVED_7 202 /* reserved */ +#define OCI_ATTR_ERRONEOUS_COLUMN 203 /* position of erroneous col */ +#define OCI_ATTR_RESERVED_8 204 /* reserved */ +#define OCI_ATTR_ASM_VOL_SPRT 205 /* ASM volume supported? */ + +/* For value 206, see DirPathAPI attribute section in this file */ + +#define OCI_ATTR_INST_TYPE 207 /* oracle instance type */ +/******USED attribute 208 for OCI_ATTR_SPOOL_STMTCACHESIZE*******************/ + +#define OCI_ATTR_ENV_UTF16 209 /* is env in utf16 mode? */ +#define OCI_ATTR_RESERVED_9 210 /* reserved */ +#define OCI_ATTR_RESERVED_10 211 /* reserved */ + +/* For values 212 and 213, see DirPathAPI attribute section in this file */ + +#define OCI_ATTR_RESERVED_12 214 /* reserved */ +#define OCI_ATTR_RESERVED_13 215 /* reserved */ +#define OCI_ATTR_IS_EXTERNAL 216 /* whether table is external */ + + +/* -------------------------- Statement Handle Attributes ------------------ */ + +#define OCI_ATTR_RESERVED_15 217 /* reserved */ +#define OCI_ATTR_STMT_IS_RETURNING 218 /* stmt has returning clause */ +#define OCI_ATTR_RESERVED_16 219 /* reserved */ +#define OCI_ATTR_RESERVED_17 220 /* reserved */ +#define OCI_ATTR_RESERVED_18 221 /* reserved */ + +/* --------------------------- session attributes ---------------------------*/ +#define OCI_ATTR_RESERVED_19 222 /* reserved */ +#define OCI_ATTR_RESERVED_20 223 /* reserved */ +#define OCI_ATTR_CURRENT_SCHEMA 224 /* Current Schema */ +#define OCI_ATTR_RESERVED_21 415 /* reserved */ + +/* ------------------------- notification subscription ----------------------*/ +#define OCI_ATTR_SUBSCR_QOSFLAGS 225 /* QOS flags */ +#define OCI_ATTR_SUBSCR_PAYLOADCBK 226 /* Payload callback */ +#define OCI_ATTR_SUBSCR_TIMEOUT 227 /* Timeout */ +#define OCI_ATTR_SUBSCR_NAMESPACE_CTX 228 /* Namespace context */ +#define OCI_ATTR_SUBSCR_CQ_QOSFLAGS 229 + /* change notification (CQ) specific QOS flags */ +#define OCI_ATTR_SUBSCR_CQ_REGID 230 + /* change notification registration id */ +#define OCI_ATTR_SUBSCR_NTFN_GROUPING_CLASS 231/* ntfn grouping class */ +#define OCI_ATTR_SUBSCR_NTFN_GROUPING_VALUE 232/* ntfn grouping value */ +#define OCI_ATTR_SUBSCR_NTFN_GROUPING_TYPE 233 /* ntfn grouping type */ +#define OCI_ATTR_SUBSCR_NTFN_GROUPING_START_TIME 234/* ntfn grp start time */ +#define OCI_ATTR_SUBSCR_NTFN_GROUPING_REPEAT_COUNT 235 /* ntfn grp rep count */ +#define OCI_ATTR_AQ_NTFN_GROUPING_MSGID_ARRAY 236 /* aq grp msgid array */ +#define OCI_ATTR_AQ_NTFN_GROUPING_COUNT 237 /* ntfns recd in grp */ + +/* ----------------------- row callback attributes ------------------------- */ +#define OCI_ATTR_BIND_ROWCBK 301 /* bind row callback */ +#define OCI_ATTR_BIND_ROWCTX 302 /* ctx for bind row callback */ +#define OCI_ATTR_SKIP_BUFFER 303 /* skip buffer in array ops */ + +/*----- Db Change Notification (CQ) statement handle attributes------------ */ +#define OCI_ATTR_CQ_QUERYID 304 +/* ------------- DB Change Notification reg handle attributes ---------------*/ +#define OCI_ATTR_CHNF_TABLENAMES 401 /* out: array of table names */ +#define OCI_ATTR_CHNF_ROWIDS 402 /* in: rowids needed */ +#define OCI_ATTR_CHNF_OPERATIONS 403 + /* in: notification operation filter*/ +#define OCI_ATTR_CHNF_CHANGELAG 404 + /* txn lag between notifications */ + +/* DB Change: Notification Descriptor attributes -----------------------*/ +#define OCI_ATTR_CHDES_DBNAME 405 /* source database */ +#define OCI_ATTR_CHDES_NFYTYPE 406 /* notification type flags */ +#define OCI_ATTR_CHDES_XID 407 /* XID of the transaction */ +#define OCI_ATTR_CHDES_TABLE_CHANGES 408/* array of table chg descriptors*/ + +#define OCI_ATTR_CHDES_TABLE_NAME 409 /* table name */ +#define OCI_ATTR_CHDES_TABLE_OPFLAGS 410 /* table operation flags */ +#define OCI_ATTR_CHDES_TABLE_ROW_CHANGES 411 /* array of changed rows */ +#define OCI_ATTR_CHDES_ROW_ROWID 412 /* rowid of changed row */ +#define OCI_ATTR_CHDES_ROW_OPFLAGS 413 /* row operation flags */ + +/* Statement handle attribute for db change notification */ +#define OCI_ATTR_CHNF_REGHANDLE 414 /* IN: subscription handle */ +#define OCI_ATTR_NETWORK_FILE_DESC 415 /* network file descriptor */ + +/* client name for single session proxy */ +#define OCI_ATTR_PROXY_CLIENT 416 + +/* 415 is already taken - see OCI_ATTR_RESERVED_21 */ + +/* TDE attributes on the Table */ +#define OCI_ATTR_TABLE_ENC 417/* does table have any encrypt columns */ +#define OCI_ATTR_TABLE_ENC_ALG 418 /* Table encryption Algorithm */ +#define OCI_ATTR_TABLE_ENC_ALG_ID 419 /* Internal Id of encryption Algorithm*/ + +/* -------- Attributes related to Statement cache callback ----------------- */ +#define OCI_ATTR_STMTCACHE_CBKCTX 420 /* opaque context on stmt */ +#define OCI_ATTR_STMTCACHE_CBK 421 /* callback fn for stmtcache */ + +/*---------------- Query change descriptor attributes -----------------------*/ +#define OCI_ATTR_CQDES_OPERATION 422 +#define OCI_ATTR_CQDES_TABLE_CHANGES 423 +#define OCI_ATTR_CQDES_QUERYID 424 + + +#define OCI_ATTR_CHDES_QUERIES 425 /* Top level change desc array of queries */ + +/* Please use from 143 */ + +/* -------- Internal statement attributes ------- */ +#define OCI_ATTR_RESERVED_26 422 + +/* 424 is used by OCI_ATTR_DRIVER_NAME */ +/* --------- Attributes added to support server side session pool ---------- */ +#define OCI_ATTR_CONNECTION_CLASS 425 +#define OCI_ATTR_PURITY 426 + +#define OCI_ATTR_PURITY_DEFAULT 0x00 +#define OCI_ATTR_PURITY_NEW 0x01 +#define OCI_ATTR_PURITY_SELF 0x02 + +/* -------- Attributes for Times Ten --------------------------*/ +#define OCI_ATTR_RESERVED_28 426 /* reserved */ +#define OCI_ATTR_RESERVED_29 427 /* reserved */ +#define OCI_ATTR_RESERVED_30 428 /* reserved */ +#define OCI_ATTR_RESERVED_31 429 /* reserved */ +#define OCI_ATTR_RESERVED_32 430 /* reserved */ +#define OCI_ATTR_RESERVED_41 454 /* reserved */ + + +/* ----------- Reserve internal attributes for workload replay ------------ */ +#define OCI_ATTR_RESERVED_33 433 +#define OCI_ATTR_RESERVED_34 434 + +/* statement attribute */ +#define OCI_ATTR_RESERVED_36 444 + +/* -------- Attributes for Network Session Time Out--------------------------*/ +#define OCI_ATTR_SEND_TIMEOUT 435 /* NS send timeout */ +#define OCI_ATTR_RECEIVE_TIMEOUT 436 /* NS receive timeout */ + +/*--------- Attributes related to LOB prefetch------------------------------ */ +#define OCI_ATTR_DEFAULT_LOBPREFETCH_SIZE 438 /* default prefetch size */ +#define OCI_ATTR_LOBPREFETCH_SIZE 439 /* prefetch size */ +#define OCI_ATTR_LOBPREFETCH_LENGTH 440 /* prefetch length & chunk */ + +/*--------- Attributes related to LOB Deduplicate Regions ------------------ */ +#define OCI_ATTR_LOB_REGION_PRIMARY 442 /* Primary LOB Locator */ +#define OCI_ATTR_LOB_REGION_PRIMOFF 443 /* Offset into Primary LOB */ +#define OCI_ATTR_LOB_REGION_OFFSET 445 /* Region Offset */ +#define OCI_ATTR_LOB_REGION_LENGTH 446 /* Region Length Bytes/Chars */ +#define OCI_ATTR_LOB_REGION_MIME 447 /* Region mime type */ + +/*--------------------Attribute to fetch ROWID ------------------------------*/ +#define OCI_ATTR_FETCH_ROWID 448 + +/* server attribute */ +#define OCI_ATTR_RESERVED_37 449 + +/* DB Change: Event types ---------------*/ +#define OCI_EVENT_NONE 0x0 /* None */ +#define OCI_EVENT_STARTUP 0x1 /* Startup database */ +#define OCI_EVENT_SHUTDOWN 0x2 /* Shutdown database */ +#define OCI_EVENT_SHUTDOWN_ANY 0x3 /* Startup instance */ +#define OCI_EVENT_DROP_DB 0x4 /* Drop database */ +#define OCI_EVENT_DEREG 0x5 /* Subscription deregistered */ +#define OCI_EVENT_OBJCHANGE 0x6 /* Object change notification */ +#define OCI_EVENT_QUERYCHANGE 0x7 /* query result change */ + +/* DB Change: Operation types -----------*/ +#define OCI_OPCODE_ALLROWS 0x1 /* all rows invalidated */ +#define OCI_OPCODE_ALLOPS 0x0 /* interested in all operations */ +#define OCI_OPCODE_INSERT 0x2 /* INSERT */ +#define OCI_OPCODE_UPDATE 0x4 /* UPDATE */ +#define OCI_OPCODE_DELETE 0x8 /* DELETE */ +#define OCI_OPCODE_ALTER 0x10 /* ALTER */ +#define OCI_OPCODE_DROP 0x20 /* DROP TABLE */ +#define OCI_OPCODE_UNKNOWN 0x40 /* GENERIC/ UNKNOWN*/ + +/* -------- client side character and national character set ids ----------- */ +#define OCI_ATTR_ENV_CHARSET_ID OCI_ATTR_CHARSET_ID /* charset id in env */ +#define OCI_ATTR_ENV_NCHARSET_ID OCI_ATTR_NCHARSET_ID /* ncharset id in env */ + +/* ----------------------- ha event callback attributes -------------------- */ +#define OCI_ATTR_EVTCBK 304 /* ha callback */ +#define OCI_ATTR_EVTCTX 305 /* ctx for ha callback */ + +/* ------------------ User memory attributes (all handles) ----------------- */ +#define OCI_ATTR_USER_MEMORY 306 /* pointer to user memory */ + +/* ------- unauthorised access and user action auditing banners ------------ */ +#define OCI_ATTR_ACCESS_BANNER 307 /* access banner */ +#define OCI_ATTR_AUDIT_BANNER 308 /* audit banner */ + +/* ----------------- port no attribute in subscription handle ------------- */ +#define OCI_ATTR_SUBSCR_PORTNO 390 /* port no to listen */ + +#define OCI_ATTR_RESERVED_35 437 + +/*------------- Supported Values for protocol for recepient -----------------*/ +#define OCI_SUBSCR_PROTO_OCI 0 /* oci */ +#define OCI_SUBSCR_PROTO_MAIL 1 /* mail */ +#define OCI_SUBSCR_PROTO_SERVER 2 /* server */ +#define OCI_SUBSCR_PROTO_HTTP 3 /* http */ +#define OCI_SUBSCR_PROTO_MAX 4 /* max current protocols */ + +/*------------- Supported Values for presentation for recepient -------------*/ +#define OCI_SUBSCR_PRES_DEFAULT 0 /* default */ +#define OCI_SUBSCR_PRES_XML 1 /* xml */ +#define OCI_SUBSCR_PRES_MAX 2 /* max current presentations */ + +/*------------- Supported QOS values for notification registrations ---------*/ +#define OCI_SUBSCR_QOS_RELIABLE 0x01 /* reliable */ +#define OCI_SUBSCR_QOS_PAYLOAD 0x02 /* payload delivery */ +#define OCI_SUBSCR_QOS_REPLICATE 0x04 /* replicate to director */ +#define OCI_SUBSCR_QOS_SECURE 0x08 /* secure payload delivery */ +#define OCI_SUBSCR_QOS_PURGE_ON_NTFN 0x10 /* purge on first ntfn */ +#define OCI_SUBSCR_QOS_MULTICBK 0x20 /* multi instance callback */ + +/* ----QOS flags specific to change notification/ continuous queries CQ -----*/ +#define OCI_SUBSCR_CQ_QOS_QUERY 0x01 /* query level notification */ +#define OCI_SUBSCR_CQ_QOS_BEST_EFFORT 0x02 /* best effort notification */ +#define OCI_SUBSCR_CQ_QOS_CLQRYCACHE 0x04 /* client query caching */ + +/*------------- Supported Values for notification grouping class ------------*/ +#define OCI_SUBSCR_NTFN_GROUPING_CLASS_TIME 1 /* time */ + +/*------------- Supported Values for notification grouping type -------------*/ +#define OCI_SUBSCR_NTFN_GROUPING_TYPE_SUMMARY 1 /* summary */ +#define OCI_SUBSCR_NTFN_GROUPING_TYPE_LAST 2 /* last */ + +/* ----- Temporary attribute value for UCS2/UTF16 character set ID -------- */ +#define OCI_UCS2ID 1000 /* UCS2 charset ID */ +#define OCI_UTF16ID 1000 /* UTF16 charset ID */ + +/*============================== End OCI Attribute Types ====================*/ + +/*---------------- Server Handle Attribute Values ---------------------------*/ + +/* OCI_ATTR_SERVER_STATUS */ +#define OCI_SERVER_NOT_CONNECTED 0x0 +#define OCI_SERVER_NORMAL 0x1 + +/*---------------------------------------------------------------------------*/ + +/*------------------------- Supported Namespaces ---------------------------*/ +#define OCI_SUBSCR_NAMESPACE_ANONYMOUS 0 /* Anonymous Namespace */ +#define OCI_SUBSCR_NAMESPACE_AQ 1 /* Advanced Queues */ +#define OCI_SUBSCR_NAMESPACE_DBCHANGE 2 /* change notification */ +#define OCI_SUBSCR_NAMESPACE_MAX 3 /* Max Name Space Number */ + + +/*-------------------------Credential Types----------------------------------*/ +#define OCI_CRED_RDBMS 1 /* database username/password */ +#define OCI_CRED_EXT 2 /* externally provided credentials */ +#define OCI_CRED_PROXY 3 /* proxy authentication */ +#define OCI_CRED_RESERVED_1 4 /* reserved */ +#define OCI_CRED_RESERVED_2 5 /* reserved */ +/*---------------------------------------------------------------------------*/ + +/*------------------------Error Return Values--------------------------------*/ +#define OCI_SUCCESS 0 /* maps to SQL_SUCCESS of SAG CLI */ +#define OCI_SUCCESS_WITH_INFO 1 /* maps to SQL_SUCCESS_WITH_INFO */ +#define OCI_RESERVED_FOR_INT_USE 200 /* reserved */ +#define OCI_NO_DATA 100 /* maps to SQL_NO_DATA */ +#define OCI_ERROR -1 /* maps to SQL_ERROR */ +#define OCI_INVALID_HANDLE -2 /* maps to SQL_INVALID_HANDLE */ +#define OCI_NEED_DATA 99 /* maps to SQL_NEED_DATA */ +#define OCI_STILL_EXECUTING -3123 /* OCI would block error */ +/*---------------------------------------------------------------------------*/ + +/*--------------------- User Callback Return Values -------------------------*/ +#define OCI_CONTINUE -24200 /* Continue with the body of the OCI function */ +#define OCI_ROWCBK_DONE -24201 /* done with user row callback */ +/*---------------------------------------------------------------------------*/ + +/*------------------DateTime and Interval check Error codes------------------*/ + +/* DateTime Error Codes used by OCIDateTimeCheck() */ +#define OCI_DT_INVALID_DAY 0x1 /* Bad day */ +#define OCI_DT_DAY_BELOW_VALID 0x2 /* Bad DAy Low/high bit (1=low)*/ +#define OCI_DT_INVALID_MONTH 0x4 /* Bad MOnth */ +#define OCI_DT_MONTH_BELOW_VALID 0x8 /* Bad MOnth Low/high bit (1=low) */ +#define OCI_DT_INVALID_YEAR 0x10 /* Bad YeaR */ +#define OCI_DT_YEAR_BELOW_VALID 0x20 /* Bad YeaR Low/high bit (1=low) */ +#define OCI_DT_INVALID_HOUR 0x40 /* Bad HouR */ +#define OCI_DT_HOUR_BELOW_VALID 0x80 /* Bad HouR Low/high bit (1=low) */ +#define OCI_DT_INVALID_MINUTE 0x100 /* Bad MiNute */ +#define OCI_DT_MINUTE_BELOW_VALID 0x200 /*Bad MiNute Low/high bit (1=low) */ +#define OCI_DT_INVALID_SECOND 0x400 /* Bad SeCond */ +#define OCI_DT_SECOND_BELOW_VALID 0x800 /*bad second Low/high bit (1=low)*/ +#define OCI_DT_DAY_MISSING_FROM_1582 0x1000 + /* Day is one of those "missing" from 1582 */ +#define OCI_DT_YEAR_ZERO 0x2000 /* Year may not equal zero */ +#define OCI_DT_INVALID_TIMEZONE 0x4000 /* Bad Timezone */ +#define OCI_DT_INVALID_FORMAT 0x8000 /* Bad date format input */ + + +/* Interval Error Codes used by OCIInterCheck() */ +#define OCI_INTER_INVALID_DAY 0x1 /* Bad day */ +#define OCI_INTER_DAY_BELOW_VALID 0x2 /* Bad DAy Low/high bit (1=low) */ +#define OCI_INTER_INVALID_MONTH 0x4 /* Bad MOnth */ +#define OCI_INTER_MONTH_BELOW_VALID 0x8 /*Bad MOnth Low/high bit (1=low) */ +#define OCI_INTER_INVALID_YEAR 0x10 /* Bad YeaR */ +#define OCI_INTER_YEAR_BELOW_VALID 0x20 /*Bad YeaR Low/high bit (1=low) */ +#define OCI_INTER_INVALID_HOUR 0x40 /* Bad HouR */ +#define OCI_INTER_HOUR_BELOW_VALID 0x80 /*Bad HouR Low/high bit (1=low) */ +#define OCI_INTER_INVALID_MINUTE 0x100 /* Bad MiNute */ +#define OCI_INTER_MINUTE_BELOW_VALID 0x200 + /*Bad MiNute Low/high bit(1=low) */ +#define OCI_INTER_INVALID_SECOND 0x400 /* Bad SeCond */ +#define OCI_INTER_SECOND_BELOW_VALID 0x800 + /*bad second Low/high bit(1=low) */ +#define OCI_INTER_INVALID_FRACSEC 0x1000 /* Bad Fractional second */ +#define OCI_INTER_FRACSEC_BELOW_VALID 0x2000 + /* Bad fractional second Low/High */ + + +/*------------------------Parsing Syntax Types-------------------------------*/ +#define OCI_V7_SYNTAX 2 /* V815 language - for backwards compatibility */ +#define OCI_V8_SYNTAX 3 /* V815 language - for backwards compatibility */ +#define OCI_NTV_SYNTAX 1 /* Use what so ever is the native lang of server */ + /* these values must match the values defined in kpul.h */ +/*---------------------------------------------------------------------------*/ + +/*------------------------(Scrollable Cursor) Fetch Options------------------- + * For non-scrollable cursor, the only valid (and default) orientation is + * OCI_FETCH_NEXT + */ +#define OCI_FETCH_CURRENT 0x00000001 /* refetching current position */ +#define OCI_FETCH_NEXT 0x00000002 /* next row */ +#define OCI_FETCH_FIRST 0x00000004 /* first row of the result set */ +#define OCI_FETCH_LAST 0x00000008 /* the last row of the result set */ +#define OCI_FETCH_PRIOR 0x00000010 /* previous row relative to current */ +#define OCI_FETCH_ABSOLUTE 0x00000020 /* absolute offset from first */ +#define OCI_FETCH_RELATIVE 0x00000040 /* offset relative to current */ +#define OCI_FETCH_RESERVED_1 0x00000080 /* reserved */ +#define OCI_FETCH_RESERVED_2 0x00000100 /* reserved */ +#define OCI_FETCH_RESERVED_3 0x00000200 /* reserved */ +#define OCI_FETCH_RESERVED_4 0x00000400 /* reserved */ +#define OCI_FETCH_RESERVED_5 0x00000800 /* reserved */ + +/*---------------------------------------------------------------------------*/ + +/*------------------------Bind and Define Options----------------------------*/ +#define OCI_SB2_IND_PTR 0x00000001 /* unused */ +#define OCI_DATA_AT_EXEC 0x00000002 /* data at execute time */ +#define OCI_DYNAMIC_FETCH 0x00000002 /* fetch dynamically */ +#define OCI_PIECEWISE 0x00000004 /* piecewise DMLs or fetch */ +#define OCI_DEFINE_RESERVED_1 0x00000008 /* reserved */ +#define OCI_BIND_RESERVED_2 0x00000010 /* reserved */ +#define OCI_DEFINE_RESERVED_2 0x00000020 /* reserved */ +#define OCI_BIND_SOFT 0x00000040 /* soft bind or define */ +#define OCI_DEFINE_SOFT 0x00000080 /* soft bind or define */ +#define OCI_BIND_RESERVED_3 0x00000100 /* reserved */ +#define OCI_IOV 0x00000200 /* For scatter gather bind/define */ +/*---------------------------------------------------------------------------*/ + +/*----------------------------- Various Modes ------------------------------*/ +#define OCI_DEFAULT 0x00000000 + /* the default value for parameters and attributes */ +/*-------------OCIInitialize Modes / OCICreateEnvironment Modes -------------*/ +#define OCI_THREADED 0x00000001 /* appl. in threaded environment */ +#define OCI_OBJECT 0x00000002 /* application in object environment */ +#define OCI_EVENTS 0x00000004 /* application is enabled for events */ +#define OCI_RESERVED1 0x00000008 /* reserved */ +#define OCI_SHARED 0x00000010 /* the application is in shared mode */ +#define OCI_RESERVED2 0x00000020 /* reserved */ +/* The following *TWO* are only valid for OCICreateEnvironment call */ +#define OCI_NO_UCB 0x00000040 /* No user callback called during ini */ +#define OCI_NO_MUTEX 0x00000080 /* the environment handle will not be */ + /* protected by a mutex internally */ +#define OCI_SHARED_EXT 0x00000100 /* Used for shared forms */ +/************************** 0x00000200 free **********************************/ +#define OCI_ALWAYS_BLOCKING 0x00000400 /* all connections always blocking */ +/************************** 0x00000800 free **********************************/ +#define OCI_USE_LDAP 0x00001000 /* allow LDAP connections */ +#define OCI_REG_LDAPONLY 0x00002000 /* only register to LDAP */ +#define OCI_UTF16 0x00004000 /* mode for all UTF16 metadata */ +#define OCI_AFC_PAD_ON 0x00008000 + /* turn on AFC blank padding when rlenp present */ +#define OCI_ENVCR_RESERVED3 0x00010000 /* reserved */ +#define OCI_NEW_LENGTH_SEMANTICS 0x00020000 /* adopt new length semantics */ + /* the new length semantics, always bytes, is used by OCIEnvNlsCreate */ +#define OCI_NO_MUTEX_STMT 0x00040000 /* Do not mutex stmt handle */ +#define OCI_MUTEX_ENV_ONLY 0x00080000 /* Mutex only the environment handle */ +#define OCI_SUPPRESS_NLS_VALIDATION 0x00100000 /* suppress nls validation */ + /* nls validation suppression is on by default; + use OCI_ENABLE_NLS_VALIDATION to disable it */ +#define OCI_MUTEX_TRY 0x00200000 /* try and acquire mutex */ +#define OCI_NCHAR_LITERAL_REPLACE_ON 0x00400000 /* nchar literal replace on */ +#define OCI_NCHAR_LITERAL_REPLACE_OFF 0x00800000 /* nchar literal replace off*/ +#define OCI_ENABLE_NLS_VALIDATION 0x01000000 /* enable nls validation */ + + +/*---------------------------------------------------------------------------*/ +/*------------------------OCIConnectionpoolCreate Modes----------------------*/ + +#define OCI_CPOOL_REINITIALIZE 0x111 + +/*---------------------------------------------------------------------------*/ +/*--------------------------------- OCILogon2 Modes -------------------------*/ + +#define OCI_LOGON2_SPOOL 0x0001 /* Use session pool */ +#define OCI_LOGON2_CPOOL OCI_CPOOL /* Use connection pool */ +#define OCI_LOGON2_STMTCACHE 0x0004 /* Use Stmt Caching */ +#define OCI_LOGON2_PROXY 0x0008 /* Proxy authentiaction */ + +/*---------------------------------------------------------------------------*/ +/*------------------------- OCISessionPoolCreate Modes ----------------------*/ + +#define OCI_SPC_REINITIALIZE 0x0001 /* Reinitialize the session pool */ +#define OCI_SPC_HOMOGENEOUS 0x0002 /* Session pool is homogeneneous */ +#define OCI_SPC_STMTCACHE 0x0004 /* Session pool has stmt cache */ +#define OCI_SPC_NO_RLB 0x0008 /* Do not enable Runtime load balancing. */ + +/*---------------------------------------------------------------------------*/ +/*--------------------------- OCISessionGet Modes ---------------------------*/ + +#define OCI_SESSGET_SPOOL 0x0001 /* SessionGet called in SPOOL mode */ +#define OCI_SESSGET_CPOOL OCI_CPOOL /* SessionGet called in CPOOL mode */ +#define OCI_SESSGET_STMTCACHE 0x0004 /* Use statement cache */ +#define OCI_SESSGET_CREDPROXY 0x0008 /* SessionGet called in proxy mode */ +#define OCI_SESSGET_CREDEXT 0x0010 +#define OCI_SESSGET_SPOOL_MATCHANY 0x0020 +#define OCI_SESSGET_PURITY_NEW 0x0040 +#define OCI_SESSGET_PURITY_SELF 0x0080 + +/*---------------------------------------------------------------------------*/ +/*------------------------ATTR Values for Session Pool-----------------------*/ +/* Attribute values for OCI_ATTR_SPOOL_GETMODE */ +#define OCI_SPOOL_ATTRVAL_WAIT 0 /* block till you get a session */ +#define OCI_SPOOL_ATTRVAL_NOWAIT 1 /* error out if no session avaliable */ +#define OCI_SPOOL_ATTRVAL_FORCEGET 2 /* get session even if max is exceeded */ + +/*---------------------------------------------------------------------------*/ +/*--------------------------- OCISessionRelease Modes -----------------------*/ + +#define OCI_SESSRLS_DROPSESS 0x0001 /* Drop the Session */ +#define OCI_SESSRLS_RETAG 0x0002 /* Retag the session */ + +/*---------------------------------------------------------------------------*/ +/*----------------------- OCISessionPoolDestroy Modes -----------------------*/ + +#define OCI_SPD_FORCE 0x0001 /* Force the sessions to terminate. + Even if there are some busy + sessions close them */ + +/*---------------------------------------------------------------------------*/ +/*----------------------------- Statement States ----------------------------*/ + +#define OCI_STMT_STATE_INITIALIZED 0x0001 +#define OCI_STMT_STATE_EXECUTED 0x0002 +#define OCI_STMT_STATE_END_OF_FETCH 0x0003 + +/*---------------------------------------------------------------------------*/ + +/*----------------------------- OCIMemStats Modes ---------------------------*/ +#define OCI_MEM_INIT 0x01 +#define OCI_MEM_CLN 0x02 +#define OCI_MEM_FLUSH 0x04 +#define OCI_DUMP_HEAP 0x80 + +#define OCI_CLIENT_STATS 0x10 +#define OCI_SERVER_STATS 0x20 + +/*----------------------------- OCIEnvInit Modes ----------------------------*/ +/* NOTE: NO NEW MODES SHOULD BE ADDED HERE BECAUSE THE RECOMMENDED METHOD + * IS TO USE THE NEW OCICreateEnvironment MODES. + */ +#define OCI_ENV_NO_UCB 0x01 /* A user callback will not be called in + OCIEnvInit() */ +#define OCI_ENV_NO_MUTEX 0x08 /* the environment handle will not be protected + by a mutex internally */ + +/*---------------------------------------------------------------------------*/ + +/*------------------------ Prepare Modes ------------------------------------*/ +#define OCI_NO_SHARING 0x01 /* turn off statement handle sharing */ +#define OCI_PREP_RESERVED_1 0x02 /* reserved */ +#define OCI_PREP_AFC_PAD_ON 0x04 /* turn on blank padding for AFC */ +#define OCI_PREP_AFC_PAD_OFF 0x08 /* turn off blank padding for AFC */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ + +/*----------------------- Execution Modes -----------------------------------*/ +#define OCI_BATCH_MODE 0x00000001 /* batch the oci stmt for exec */ +#define OCI_EXACT_FETCH 0x00000002 /* fetch exact rows specified */ +/* #define 0x00000004 available */ +#define OCI_STMT_SCROLLABLE_READONLY \ + 0x00000008 /* if result set is scrollable */ +#define OCI_DESCRIBE_ONLY 0x00000010 /* only describe the statement */ +#define OCI_COMMIT_ON_SUCCESS 0x00000020 /* commit, if successful exec */ +#define OCI_NON_BLOCKING 0x00000040 /* non-blocking */ +#define OCI_BATCH_ERRORS 0x00000080 /* batch errors in array dmls */ +#define OCI_PARSE_ONLY 0x00000100 /* only parse the statement */ +#define OCI_EXACT_FETCH_RESERVED_1 0x00000200 /* reserved */ +#define OCI_SHOW_DML_WARNINGS 0x00000400 + /* return OCI_SUCCESS_WITH_INFO for delete/update w/no where clause */ +#define OCI_EXEC_RESERVED_2 0x00000800 /* reserved */ +#define OCI_DESC_RESERVED_1 0x00001000 /* reserved */ +#define OCI_EXEC_RESERVED_3 0x00002000 /* reserved */ +#define OCI_EXEC_RESERVED_4 0x00004000 /* reserved */ +#define OCI_EXEC_RESERVED_5 0x00008000 /* reserved */ +#define OCI_EXEC_RESERVED_6 0x00010000 /* reserved */ +#define OCI_RESULT_CACHE 0x00020000 /* hint to use query caching */ +#define OCI_NO_RESULT_CACHE 0x00040000 /*hint to bypass query caching*/ + +/*---------------------------------------------------------------------------*/ + +/*------------------------Authentication Modes-------------------------------*/ +#define OCI_MIGRATE 0x00000001 /* migratable auth context */ +#define OCI_SYSDBA 0x00000002 /* for SYSDBA authorization */ +#define OCI_SYSOPER 0x00000004 /* for SYSOPER authorization */ +#define OCI_PRELIM_AUTH 0x00000008 /* for preliminary authorization */ +#define OCIP_ICACHE 0x00000010 /* Private OCI cache mode */ +#define OCI_AUTH_RESERVED_1 0x00000020 /* reserved */ +#define OCI_STMT_CACHE 0x00000040 /* enable OCI Stmt Caching */ +#define OCI_STATELESS_CALL 0x00000080 /* stateless at call boundary */ +#define OCI_STATELESS_TXN 0x00000100 /* stateless at txn boundary */ +#define OCI_STATELESS_APP 0x00000200 /* stateless at user-specified pts */ +#define OCI_AUTH_RESERVED_2 0x00000400 /* reserved */ +#define OCI_AUTH_RESERVED_3 0x00000800 /* reserved */ +#define OCI_AUTH_RESERVED_4 0x00001000 /* reserved */ +#define OCI_AUTH_RESERVED_5 0x00002000 /* reserved */ +#define OCI_SYSASM 0x00008000 /* for SYSASM authorization */ +#define OCI_AUTH_RESERVED_6 0x00010000 /* reserved */ + +/*---------------------------------------------------------------------------*/ + +/*------------------------Session End Modes----------------------------------*/ +#define OCI_SESSEND_RESERVED_1 0x0001 /* reserved */ +#define OCI_SESSEND_RESERVED_2 0x0002 /* reserved */ +/*---------------------------------------------------------------------------*/ + +/*------------------------Attach Modes---------------------------------------*/ + +/* The following attach modes are the same as the UPI modes defined in + * UPIDEF.H. Do not use these values externally. + */ + +#define OCI_FASTPATH 0x0010 /* Attach in fast path mode */ +#define OCI_ATCH_RESERVED_1 0x0020 /* reserved */ +#define OCI_ATCH_RESERVED_2 0x0080 /* reserved */ +#define OCI_ATCH_RESERVED_3 0x0100 /* reserved */ +#define OCI_CPOOL 0x0200 /* Attach using server handle from pool */ +#define OCI_ATCH_RESERVED_4 0x0400 /* reserved */ +#define OCI_ATCH_RESERVED_5 0x2000 /* reserved */ +#define OCI_ATCH_ENABLE_BEQ 0x4000 /* Allow bequeath connect strings */ +#define OCI_ATCH_RESERVED_6 0x8000 /* reserved */ +#define OCI_ATCH_RESERVED_7 0x10000 /* reserved */ +#define OCI_ATCH_RESERVED_8 0x20000 /* reserved */ + +#define OCI_SRVATCH_RESERVED5 0x01000000 /* reserved */ +#define OCI_SRVATCH_RESERVED6 0x02000000 /* reserved */ + +/*---------------------OCIStmtPrepare2 Modes---------------------------------*/ +#define OCI_PREP2_CACHE_SEARCHONLY 0x0010 /* ONly Search */ +#define OCI_PREP2_GET_PLSQL_WARNINGS 0x0020 /* Get PL/SQL warnings */ +#define OCI_PREP2_RESERVED_1 0x0040 /* reserved */ + +/*---------------------OCIStmtRelease Modes----------------------------------*/ +#define OCI_STRLS_CACHE_DELETE 0x0010 /* Delete from Cache */ + +/*---------------------OCIHanlde Mgmt Misc Modes-----------------------------*/ +#define OCI_STM_RESERVED4 0x00100000 /* reserved */ + +/*-----------------------------End Various Modes ----------------------------*/ + +/*------------------------Piece Information----------------------------------*/ +#define OCI_PARAM_IN 0x01 /* in parameter */ +#define OCI_PARAM_OUT 0x02 /* out parameter */ +/*---------------------------------------------------------------------------*/ + +/*------------------------ Transaction Start Flags --------------------------*/ +/* NOTE: OCI_TRANS_JOIN and OCI_TRANS_NOMIGRATE not supported in 8.0.X */ +#define OCI_TRANS_NEW 0x00000001 /* start a new local or global txn */ +#define OCI_TRANS_JOIN 0x00000002 /* join an existing global txn */ +#define OCI_TRANS_RESUME 0x00000004 /* resume the global txn branch */ +#define OCI_TRANS_PROMOTE 0x00000008 /* promote the local txn to global */ +#define OCI_TRANS_STARTMASK 0x000000ff /* mask for start operation flags */ + +#define OCI_TRANS_READONLY 0x00000100 /* start a readonly txn */ +#define OCI_TRANS_READWRITE 0x00000200 /* start a read-write txn */ +#define OCI_TRANS_SERIALIZABLE 0x00000400 /* start a serializable txn */ +#define OCI_TRANS_ISOLMASK 0x0000ff00 /* mask for start isolation flags */ + +#define OCI_TRANS_LOOSE 0x00010000 /* a loosely coupled branch */ +#define OCI_TRANS_TIGHT 0x00020000 /* a tightly coupled branch */ +#define OCI_TRANS_TYPEMASK 0x000f0000 /* mask for branch type flags */ + +#define OCI_TRANS_NOMIGRATE 0x00100000 /* non migratable transaction */ +#define OCI_TRANS_SEPARABLE 0x00200000 /* separable transaction (8.1.6+) */ +#define OCI_TRANS_OTSRESUME 0x00400000 /* OTS resuming a transaction */ +#define OCI_TRANS_OTHRMASK 0xfff00000 /* mask for other start flags */ + + +/*---------------------------------------------------------------------------*/ + +/*------------------------ Transaction End Flags ----------------------------*/ +#define OCI_TRANS_TWOPHASE 0x01000000 /* use two phase commit */ +#define OCI_TRANS_WRITEBATCH 0x00000001 /* force cmt-redo for local txns */ +#define OCI_TRANS_WRITEIMMED 0x00000002 /* no force cmt-redo */ +#define OCI_TRANS_WRITEWAIT 0x00000004 /* no sync cmt-redo */ +#define OCI_TRANS_WRITENOWAIT 0x00000008 /* sync cmt-redo for local txns */ +/*---------------------------------------------------------------------------*/ + +/*------------------------- AQ Constants ------------------------------------ + * NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE + * The following constants must match the PL/SQL dbms_aq constants + * NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE + */ +/* ------------------------- Visibility flags -------------------------------*/ +#define OCI_ENQ_IMMEDIATE 1 /* enqueue is an independent transaction */ +#define OCI_ENQ_ON_COMMIT 2 /* enqueue is part of current transaction */ + +/* ----------------------- Dequeue mode flags -------------------------------*/ +#define OCI_DEQ_BROWSE 1 /* read message without acquiring a lock */ +#define OCI_DEQ_LOCKED 2 /* read and obtain write lock on message */ +#define OCI_DEQ_REMOVE 3 /* read the message and delete it */ +#define OCI_DEQ_REMOVE_NODATA 4 /* delete message w'o returning payload */ +#define OCI_DEQ_GETSIG 5 /* get signature only */ + +/* ----------------- Dequeue navigation flags -------------------------------*/ +#define OCI_DEQ_FIRST_MSG 1 /* get first message at head of queue */ +#define OCI_DEQ_NEXT_MSG 3 /* next message that is available */ +#define OCI_DEQ_NEXT_TRANSACTION 2 /* get first message of next txn group */ +#define OCI_DEQ_MULT_TRANSACTION 5 /* array dequeue across txn groups */ + +/* ----------------- Dequeue Option Reserved flags ------------------------- */ +#define OCI_DEQ_RESERVED_1 0x000001 + +/* --------------------- Message states -------------------------------------*/ +#define OCI_MSG_WAITING 1 /* the message delay has not yet completed */ +#define OCI_MSG_READY 0 /* the message is ready to be processed */ +#define OCI_MSG_PROCESSED 2 /* the message has been processed */ +#define OCI_MSG_EXPIRED 3 /* message has moved to exception queue */ + +/* --------------------- Sequence deviation ---------------------------------*/ +#define OCI_ENQ_BEFORE 2 /* enqueue message before another message */ +#define OCI_ENQ_TOP 3 /* enqueue message before all messages */ + +/* ------------------------- Visibility flags -------------------------------*/ +#define OCI_DEQ_IMMEDIATE 1 /* dequeue is an independent transaction */ +#define OCI_DEQ_ON_COMMIT 2 /* dequeue is part of current transaction */ + +/* ------------------------ Wait --------------------------------------------*/ +#define OCI_DEQ_WAIT_FOREVER -1 /* wait forever if no message available */ +#define OCI_NTFN_GROUPING_FOREVER -1 /* send grouping notifications forever */ +#define OCI_DEQ_NO_WAIT 0 /* do not wait if no message is available */ + +#define OCI_FLOW_CONTROL_NO_TIMEOUT -1 + /* streaming enqueue: no timeout for flow control */ + +/* ------------------------ Delay -------------------------------------------*/ +#define OCI_MSG_NO_DELAY 0 /* message is available immediately */ + +/* ------------------------- Expiration -------------------------------------*/ +#define OCI_MSG_NO_EXPIRATION -1 /* message will never expire */ + +#define OCI_MSG_PERSISTENT_OR_BUFFERED 3 +#define OCI_MSG_BUFFERED 2 +#define OCI_MSG_PERSISTENT 1 + +/* ----------------------- Reserved/AQE pisdef flags ------------------------*/ +/* see aqeflg defines in kwqp.h */ +#define OCI_AQ_RESERVED_1 0x0002 +#define OCI_AQ_RESERVED_2 0x0004 +#define OCI_AQ_RESERVED_3 0x0008 +#define OCI_AQ_RESERVED_4 0x0010 + +#define OCI_AQ_STREAMING_FLAG 0x02000000 + +/* ------------------------------ Replay Info -------------------------------*/ +#define OCI_AQ_LAST_ENQUEUED 0 +#define OCI_AQ_LAST_ACKNOWLEDGED 1 + +/* -------------------------- END AQ Constants ----------------------------- */ + +/* --------------------END DateTime and Interval Constants ------------------*/ + +/*-----------------------Object Types----------------------------------------*/ +/*-----------Object Types **** Not to be Used **** --------------------------*/ +/* Deprecated */ +#define OCI_OTYPE_UNK 0 +#define OCI_OTYPE_TABLE 1 +#define OCI_OTYPE_VIEW 2 +#define OCI_OTYPE_SYN 3 +#define OCI_OTYPE_PROC 4 +#define OCI_OTYPE_FUNC 5 +#define OCI_OTYPE_PKG 6 +#define OCI_OTYPE_STMT 7 +/*---------------------------------------------------------------------------*/ + +/*=======================Describe Handle Parameter Attributes ===============*/ +/* + These attributes are orthogonal to the other set of attributes defined + above. These attrubutes are to be used only for the describe handle. +*/ +/*===========================================================================*/ +/* Attributes common to Columns and Stored Procs */ +#define OCI_ATTR_DATA_SIZE 1 /* maximum size of the data */ +#define OCI_ATTR_DATA_TYPE 2 /* the SQL type of the column/argument */ +#define OCI_ATTR_DISP_SIZE 3 /* the display size */ +#define OCI_ATTR_NAME 4 /* the name of the column/argument */ +#define OCI_ATTR_PRECISION 5 /* precision if number type */ +#define OCI_ATTR_SCALE 6 /* scale if number type */ +#define OCI_ATTR_IS_NULL 7 /* is it null ? */ +#define OCI_ATTR_TYPE_NAME 8 + /* name of the named data type or a package name for package private types */ +#define OCI_ATTR_SCHEMA_NAME 9 /* the schema name */ +#define OCI_ATTR_SUB_NAME 10 /* type name if package private type */ +#define OCI_ATTR_POSITION 11 + /* relative position of col/arg in the list of cols/args */ +/* complex object retrieval parameter attributes */ +#define OCI_ATTR_COMPLEXOBJECTCOMP_TYPE 50 +#define OCI_ATTR_COMPLEXOBJECTCOMP_TYPE_LEVEL 51 +#define OCI_ATTR_COMPLEXOBJECT_LEVEL 52 +#define OCI_ATTR_COMPLEXOBJECT_COLL_OUTOFLINE 53 + +/* Only Columns */ +#define OCI_ATTR_DISP_NAME 100 /* the display name */ +#define OCI_ATTR_ENCC_SIZE 101 /* encrypted data size */ +#define OCI_ATTR_COL_ENC 102 /* column is encrypted ? */ +#define OCI_ATTR_COL_ENC_SALT 103 /* is encrypted column salted ? */ + +/*Only Stored Procs */ +#define OCI_ATTR_OVERLOAD 210 /* is this position overloaded */ +#define OCI_ATTR_LEVEL 211 /* level for structured types */ +#define OCI_ATTR_HAS_DEFAULT 212 /* has a default value */ +#define OCI_ATTR_IOMODE 213 /* in, out inout */ +#define OCI_ATTR_RADIX 214 /* returns a radix */ +#define OCI_ATTR_NUM_ARGS 215 /* total number of arguments */ + +/* only named type attributes */ +#define OCI_ATTR_TYPECODE 216 /* object or collection */ +#define OCI_ATTR_COLLECTION_TYPECODE 217 /* varray or nested table */ +#define OCI_ATTR_VERSION 218 /* user assigned version */ +#define OCI_ATTR_IS_INCOMPLETE_TYPE 219 /* is this an incomplete type */ +#define OCI_ATTR_IS_SYSTEM_TYPE 220 /* a system type */ +#define OCI_ATTR_IS_PREDEFINED_TYPE 221 /* a predefined type */ +#define OCI_ATTR_IS_TRANSIENT_TYPE 222 /* a transient type */ +#define OCI_ATTR_IS_SYSTEM_GENERATED_TYPE 223 /* system generated type */ +#define OCI_ATTR_HAS_NESTED_TABLE 224 /* contains nested table attr */ +#define OCI_ATTR_HAS_LOB 225 /* has a lob attribute */ +#define OCI_ATTR_HAS_FILE 226 /* has a file attribute */ +#define OCI_ATTR_COLLECTION_ELEMENT 227 /* has a collection attribute */ +#define OCI_ATTR_NUM_TYPE_ATTRS 228 /* number of attribute types */ +#define OCI_ATTR_LIST_TYPE_ATTRS 229 /* list of type attributes */ +#define OCI_ATTR_NUM_TYPE_METHODS 230 /* number of type methods */ +#define OCI_ATTR_LIST_TYPE_METHODS 231 /* list of type methods */ +#define OCI_ATTR_MAP_METHOD 232 /* map method of type */ +#define OCI_ATTR_ORDER_METHOD 233 /* order method of type */ + +/* only collection element */ +#define OCI_ATTR_NUM_ELEMS 234 /* number of elements */ + +/* only type methods */ +#define OCI_ATTR_ENCAPSULATION 235 /* encapsulation level */ +#define OCI_ATTR_IS_SELFISH 236 /* method selfish */ +#define OCI_ATTR_IS_VIRTUAL 237 /* virtual */ +#define OCI_ATTR_IS_INLINE 238 /* inline */ +#define OCI_ATTR_IS_CONSTANT 239 /* constant */ +#define OCI_ATTR_HAS_RESULT 240 /* has result */ +#define OCI_ATTR_IS_CONSTRUCTOR 241 /* constructor */ +#define OCI_ATTR_IS_DESTRUCTOR 242 /* destructor */ +#define OCI_ATTR_IS_OPERATOR 243 /* operator */ +#define OCI_ATTR_IS_MAP 244 /* a map method */ +#define OCI_ATTR_IS_ORDER 245 /* order method */ +#define OCI_ATTR_IS_RNDS 246 /* read no data state method */ +#define OCI_ATTR_IS_RNPS 247 /* read no process state */ +#define OCI_ATTR_IS_WNDS 248 /* write no data state method */ +#define OCI_ATTR_IS_WNPS 249 /* write no process state */ + +#define OCI_ATTR_DESC_PUBLIC 250 /* public object */ + +/* Object Cache Enhancements : attributes for User Constructed Instances */ +#define OCI_ATTR_CACHE_CLIENT_CONTEXT 251 +#define OCI_ATTR_UCI_CONSTRUCT 252 +#define OCI_ATTR_UCI_DESTRUCT 253 +#define OCI_ATTR_UCI_COPY 254 +#define OCI_ATTR_UCI_PICKLE 255 +#define OCI_ATTR_UCI_UNPICKLE 256 +#define OCI_ATTR_UCI_REFRESH 257 + +/* for type inheritance */ +#define OCI_ATTR_IS_SUBTYPE 258 +#define OCI_ATTR_SUPERTYPE_SCHEMA_NAME 259 +#define OCI_ATTR_SUPERTYPE_NAME 260 + +/* for schemas */ +#define OCI_ATTR_LIST_OBJECTS 261 /* list of objects in schema */ + +/* for database */ +#define OCI_ATTR_NCHARSET_ID 262 /* char set id */ +#define OCI_ATTR_LIST_SCHEMAS 263 /* list of schemas */ +#define OCI_ATTR_MAX_PROC_LEN 264 /* max procedure length */ +#define OCI_ATTR_MAX_COLUMN_LEN 265 /* max column name length */ +#define OCI_ATTR_CURSOR_COMMIT_BEHAVIOR 266 /* cursor commit behavior */ +#define OCI_ATTR_MAX_CATALOG_NAMELEN 267 /* catalog namelength */ +#define OCI_ATTR_CATALOG_LOCATION 268 /* catalog location */ +#define OCI_ATTR_SAVEPOINT_SUPPORT 269 /* savepoint support */ +#define OCI_ATTR_NOWAIT_SUPPORT 270 /* nowait support */ +#define OCI_ATTR_AUTOCOMMIT_DDL 271 /* autocommit DDL */ +#define OCI_ATTR_LOCKING_MODE 272 /* locking mode */ + +/* for externally initialized context */ +#define OCI_ATTR_APPCTX_SIZE 273 /* count of context to be init*/ +#define OCI_ATTR_APPCTX_LIST 274 /* count of context to be init*/ +#define OCI_ATTR_APPCTX_NAME 275 /* name of context to be init*/ +#define OCI_ATTR_APPCTX_ATTR 276 /* attr of context to be init*/ +#define OCI_ATTR_APPCTX_VALUE 277 /* value of context to be init*/ + +/* for client id propagation */ +#define OCI_ATTR_CLIENT_IDENTIFIER 278 /* value of client id to set*/ + +/* for inheritance - part 2 */ +#define OCI_ATTR_IS_FINAL_TYPE 279 /* is final type ? */ +#define OCI_ATTR_IS_INSTANTIABLE_TYPE 280 /* is instantiable type ? */ +#define OCI_ATTR_IS_FINAL_METHOD 281 /* is final method ? */ +#define OCI_ATTR_IS_INSTANTIABLE_METHOD 282 /* is instantiable method ? */ +#define OCI_ATTR_IS_OVERRIDING_METHOD 283 /* is overriding method ? */ + +#define OCI_ATTR_DESC_SYNBASE 284 /* Describe the base object */ + + +#define OCI_ATTR_CHAR_USED 285 /* char length semantics */ +#define OCI_ATTR_CHAR_SIZE 286 /* char length */ + +/* SQLJ support */ +#define OCI_ATTR_IS_JAVA_TYPE 287 /* is java implemented type ? */ + +/* N-Tier support */ +#define OCI_ATTR_DISTINGUISHED_NAME 300 /* use DN as user name */ +#define OCI_ATTR_KERBEROS_TICKET 301 /* Kerberos ticket as cred. */ + +/* for multilanguage debugging */ +#define OCI_ATTR_ORA_DEBUG_JDWP 302 /* ORA_DEBUG_JDWP attribute */ + +#define OCI_ATTR_EDITION 288 /* ORA_EDITION */ + +#define OCI_ATTR_RESERVED_14 303 /* reserved */ + + +/*---------------------------End Describe Handle Attributes -----------------*/ + +/* For values 303 - 307, see DirPathAPI attribute section in this file */ + +/* ----------------------- Session Pool Attributes ------------------------- */ +#define OCI_ATTR_SPOOL_TIMEOUT 308 /* session timeout */ +#define OCI_ATTR_SPOOL_GETMODE 309 /* session get mode */ +#define OCI_ATTR_SPOOL_BUSY_COUNT 310 /* busy session count */ +#define OCI_ATTR_SPOOL_OPEN_COUNT 311 /* open session count */ +#define OCI_ATTR_SPOOL_MIN 312 /* min session count */ +#define OCI_ATTR_SPOOL_MAX 313 /* max session count */ +#define OCI_ATTR_SPOOL_INCR 314 /* session increment count */ +#define OCI_ATTR_SPOOL_STMTCACHESIZE 208 /*Stmt cache size of pool */ +/*------------------------------End Session Pool Attributes -----------------*/ +/*---------------------------- For XML Types ------------------------------- */ +/* For table, view and column */ +#define OCI_ATTR_IS_XMLTYPE 315 /* Is the type an XML type? */ +#define OCI_ATTR_XMLSCHEMA_NAME 316 /* Name of XML Schema */ +#define OCI_ATTR_XMLELEMENT_NAME 317 /* Name of XML Element */ +#define OCI_ATTR_XMLSQLTYPSCH_NAME 318 /* SQL type's schema for XML Ele */ +#define OCI_ATTR_XMLSQLTYPE_NAME 319 /* Name of SQL type for XML Ele */ +#define OCI_ATTR_XMLTYPE_STORED_OBJ 320 /* XML type stored as object? */ +#define OCI_ATTR_XMLTYPE_BINARY_XML 422 /* XML type stored as binary? */ + +/*---------------------------- For Subtypes ------------------------------- */ +/* For type */ +#define OCI_ATTR_HAS_SUBTYPES 321 /* Has subtypes? */ +#define OCI_ATTR_NUM_SUBTYPES 322 /* Number of subtypes */ +#define OCI_ATTR_LIST_SUBTYPES 323 /* List of subtypes */ + +/* XML flag */ +#define OCI_ATTR_XML_HRCHY_ENABLED 324 /* hierarchy enabled? */ + +/* Method flag */ +#define OCI_ATTR_IS_OVERRIDDEN_METHOD 325 /* Method is overridden? */ + +/* For values 326 - 335, see DirPathAPI attribute section in this file */ + +/*------------- Attributes for 10i Distributed Objects ----------------------*/ +#define OCI_ATTR_OBJ_SUBS 336 /* obj col/tab substitutable */ + +/* For values 337 - 338, see DirPathAPI attribute section in this file */ + +/*---------- Attributes for 10i XADFIELD (NLS language, territory -----------*/ +#define OCI_ATTR_XADFIELD_RESERVED_1 339 /* reserved */ +#define OCI_ATTR_XADFIELD_RESERVED_2 340 /* reserved */ +/*------------- Kerberos Secure Client Identifier ---------------------------*/ +#define OCI_ATTR_KERBEROS_CID 341 /* Kerberos db service ticket*/ + + +/*------------------------ Attributes for Rules objects ---------------------*/ +#define OCI_ATTR_CONDITION 342 /* rule condition */ +#define OCI_ATTR_COMMENT 343 /* comment */ +#define OCI_ATTR_VALUE 344 /* Anydata value */ +#define OCI_ATTR_EVAL_CONTEXT_OWNER 345 /* eval context owner */ +#define OCI_ATTR_EVAL_CONTEXT_NAME 346 /* eval context name */ +#define OCI_ATTR_EVALUATION_FUNCTION 347 /* eval function name */ +#define OCI_ATTR_VAR_TYPE 348 /* variable type */ +#define OCI_ATTR_VAR_VALUE_FUNCTION 349 /* variable value function */ +#define OCI_ATTR_VAR_METHOD_FUNCTION 350 /* variable method function */ +#define OCI_ATTR_ACTION_CONTEXT 351 /* action context */ +#define OCI_ATTR_LIST_TABLE_ALIASES 352 /* list of table aliases */ +#define OCI_ATTR_LIST_VARIABLE_TYPES 353 /* list of variable types */ +#define OCI_ATTR_TABLE_NAME 356 /* table name */ + +/* For values 357 - 359, see DirPathAPI attribute section in this file */ + +#define OCI_ATTR_MESSAGE_CSCN 360 /* message cscn */ +#define OCI_ATTR_MESSAGE_DSCN 361 /* message dscn */ + +/*--------------------- Audit Session ID ------------------------------------*/ +#define OCI_ATTR_AUDIT_SESSION_ID 362 /* Audit session ID */ + +/*--------------------- Kerberos TGT Keys -----------------------------------*/ +#define OCI_ATTR_KERBEROS_KEY 363 /* n-tier Kerberos cred key */ +#define OCI_ATTR_KERBEROS_CID_KEY 364 /* SCID Kerberos cred key */ + + +#define OCI_ATTR_TRANSACTION_NO 365 /* AQ enq txn number */ + +/*----------------------- Attributes for End To End Tracing -----------------*/ +#define OCI_ATTR_MODULE 366 /* module for tracing */ +#define OCI_ATTR_ACTION 367 /* action for tracing */ +#define OCI_ATTR_CLIENT_INFO 368 /* client info */ +#define OCI_ATTR_COLLECT_CALL_TIME 369 /* collect call time */ +#define OCI_ATTR_CALL_TIME 370 /* extract call time */ +#define OCI_ATTR_ECONTEXT_ID 371 /* execution-id context */ +#define OCI_ATTR_ECONTEXT_SEQ 372 /*execution-id sequence num */ + + +/*------------------------------ Session attributes -------------------------*/ +#define OCI_ATTR_SESSION_STATE 373 /* session state */ +#define OCI_SESSION_STATELESS 1 /* valid states */ +#define OCI_SESSION_STATEFUL 2 + +#define OCI_ATTR_SESSION_STATETYPE 374 /* session state type */ +#define OCI_SESSION_STATELESS_DEF 0 /* valid state types */ +#define OCI_SESSION_STATELESS_CAL 1 +#define OCI_SESSION_STATELESS_TXN 2 +#define OCI_SESSION_STATELESS_APP 3 + +#define OCI_ATTR_SESSION_STATE_CLEARED 376 /* session state cleared */ +#define OCI_ATTR_SESSION_MIGRATED 377 /* did session migrate */ +#define OCI_ATTR_SESSION_PRESERVE_STATE 388 /* preserve session state */ +#define OCI_ATTR_DRIVER_NAME 424 /* Driver Name */ + +/* -------------------------- Admin Handle Attributes ---------------------- */ + +#define OCI_ATTR_ADMIN_PFILE 389 /* client-side param file */ + +/*----------------------- Attributes for End To End Tracing -----------------*/ +/* -------------------------- HA Event Handle Attributes ------------------- */ + +#define OCI_ATTR_HOSTNAME 390 /* SYS_CONTEXT hostname */ +#define OCI_ATTR_DBNAME 391 /* SYS_CONTEXT dbname */ +#define OCI_ATTR_INSTNAME 392 /* SYS_CONTEXT instance name */ +#define OCI_ATTR_SERVICENAME 393 /* SYS_CONTEXT service name */ +#define OCI_ATTR_INSTSTARTTIME 394 /* v$instance instance start time */ +#define OCI_ATTR_HA_TIMESTAMP 395 /* event time */ +#define OCI_ATTR_RESERVED_22 396 /* reserved */ +#define OCI_ATTR_RESERVED_23 397 /* reserved */ +#define OCI_ATTR_RESERVED_24 398 /* reserved */ +#define OCI_ATTR_DBDOMAIN 399 /* db domain */ +#define OCI_ATTR_RESERVED_27 425 /* reserved */ + +#define OCI_ATTR_EVENTTYPE 400 /* event type */ +#define OCI_EVENTTYPE_HA 0 /* valid value for OCI_ATTR_EVENTTYPE */ + +#define OCI_ATTR_HA_SOURCE 401 +/* valid values for OCI_ATTR_HA_SOURCE */ +#define OCI_HA_SOURCE_INSTANCE 0 +#define OCI_HA_SOURCE_DATABASE 1 +#define OCI_HA_SOURCE_NODE 2 +#define OCI_HA_SOURCE_SERVICE 3 +#define OCI_HA_SOURCE_SERVICE_MEMBER 4 +#define OCI_HA_SOURCE_ASM_INSTANCE 5 +#define OCI_HA_SOURCE_SERVICE_PRECONNECT 6 + +#define OCI_ATTR_HA_STATUS 402 +#define OCI_HA_STATUS_DOWN 0 /* valid values for OCI_ATTR_HA_STATUS */ +#define OCI_HA_STATUS_UP 1 + +#define OCI_ATTR_HA_SRVFIRST 403 + +#define OCI_ATTR_HA_SRVNEXT 404 +/* ------------------------- Server Handle Attributes -----------------------*/ + +#define OCI_ATTR_TAF_ENABLED 405 + +/* Extra notification attributes */ +#define OCI_ATTR_NFY_FLAGS 406 + +#define OCI_ATTR_MSG_DELIVERY_MODE 407 /* msg delivery mode */ +#define OCI_ATTR_DB_CHARSET_ID 416 /* database charset ID */ +#define OCI_ATTR_DB_NCHARSET_ID 417 /* database ncharset ID */ +#define OCI_ATTR_RESERVED_25 418 /* reserved */ + +#define OCI_ATTR_FLOW_CONTROL_TIMEOUT 423 /* AQ: flow control timeout */ +/*---------------------------------------------------------------------------*/ +/* ------------------DirPathAPI attribute Section----------------------------*/ +/* All DirPathAPI attributes are in this section of the file. Existing */ +/* attributes prior to this section being created are assigned values < 2000 */ +/* Add new DirPathAPI attributes to this section and their assigned value */ +/* should be whatever the last entry is + 1. */ + +/*------------- Supported Values for Direct Path Stream Version -------------*/ +#define OCI_DIRPATH_STREAM_VERSION_1 100 +#define OCI_DIRPATH_STREAM_VERSION_2 200 +#define OCI_DIRPATH_STREAM_VERSION_3 300 /* default */ + + +#define OCI_ATTR_DIRPATH_MODE 78 /* mode of direct path operation */ +#define OCI_ATTR_DIRPATH_NOLOG 79 /* nologging option */ +#define OCI_ATTR_DIRPATH_PARALLEL 80 /* parallel (temp seg) option */ + +#define OCI_ATTR_DIRPATH_SORTED_INDEX 137 /* index that data is sorted on */ + + /* direct path index maint method (see oci8dp.h) */ +#define OCI_ATTR_DIRPATH_INDEX_MAINT_METHOD 138 + + /* parallel load: db file, initial and next extent sizes */ + +#define OCI_ATTR_DIRPATH_FILE 139 /* DB file to load into */ +#define OCI_ATTR_DIRPATH_STORAGE_INITIAL 140 /* initial extent size */ +#define OCI_ATTR_DIRPATH_STORAGE_NEXT 141 /* next extent size */ + /* direct path index maint method (see oci8dp.h) */ +#define OCI_ATTR_DIRPATH_SKIPINDEX_METHOD 145 + + /* 8.2 dpapi support of ADTs */ +#define OCI_ATTR_DIRPATH_EXPR_TYPE 150 /* expr type of OCI_ATTR_NAME */ + +/* For the direct path API there are three data formats: + * TEXT - used mainly by SQL*Loader, data is in textual form + * STREAM - used by datapump, data is in stream loadable form + * OCI - used by OCI programs utilizing the DpApi, data is in binary form + */ +#define OCI_ATTR_DIRPATH_INPUT 151 +#define OCI_DIRPATH_INPUT_TEXT 0x01 /* text */ +#define OCI_DIRPATH_INPUT_STREAM 0x02 /* stream (datapump) */ +#define OCI_DIRPATH_INPUT_OCI 0x04 /* binary (oci) */ +#define OCI_DIRPATH_INPUT_UNKNOWN 0x08 + +#define OCI_ATTR_DIRPATH_FN_CTX 167 /* fn ctx ADT attrs or args */ + +#define OCI_ATTR_DIRPATH_OID 187 /* loading into an OID col */ +#define OCI_ATTR_DIRPATH_SID 194 /* loading into an SID col */ +#define OCI_ATTR_DIRPATH_OBJ_CONSTR 206 /* obj type of subst obj tbl */ + +/* Attr to allow setting of the stream version PRIOR to calling Prepare */ +#define OCI_ATTR_DIRPATH_STREAM_VERSION 212 /* version of the stream*/ + +#define OCIP_ATTR_DIRPATH_VARRAY_INDEX 213 /* varray index column */ + +/*------------- Supported Values for Direct Path Date cache -----------------*/ +#define OCI_ATTR_DIRPATH_DCACHE_NUM 303 /* date cache entries */ +#define OCI_ATTR_DIRPATH_DCACHE_SIZE 304 /* date cache limit */ +#define OCI_ATTR_DIRPATH_DCACHE_MISSES 305 /* date cache misses */ +#define OCI_ATTR_DIRPATH_DCACHE_HITS 306 /* date cache hits */ +#define OCI_ATTR_DIRPATH_DCACHE_DISABLE 307 /* on set: disable datecache + * on overflow. + * on get: datecache disabled? + * could be due to overflow + * or others */ + +/*------------- Attributes for 10i Updates to the DirPath API ---------------*/ +#define OCI_ATTR_DIRPATH_RESERVED_7 326 /* reserved */ +#define OCI_ATTR_DIRPATH_RESERVED_8 327 /* reserved */ +#define OCI_ATTR_DIRPATH_CONVERT 328 /* stream conversion needed? */ +#define OCI_ATTR_DIRPATH_BADROW 329 /* info about bad row */ +#define OCI_ATTR_DIRPATH_BADROW_LENGTH 330 /* length of bad row info */ +#define OCI_ATTR_DIRPATH_WRITE_ORDER 331 /* column fill order */ +#define OCI_ATTR_DIRPATH_GRANULE_SIZE 332 /* granule size for unload */ +#define OCI_ATTR_DIRPATH_GRANULE_OFFSET 333 /* offset to last granule */ +#define OCI_ATTR_DIRPATH_RESERVED_1 334 /* reserved */ +#define OCI_ATTR_DIRPATH_RESERVED_2 335 /* reserved */ + +/*------ Attributes for 10i DirPathAPI conversion (NLS lang, terr, cs) ------*/ +#define OCI_ATTR_DIRPATH_RESERVED_3 337 /* reserved */ +#define OCI_ATTR_DIRPATH_RESERVED_4 338 /* reserved */ +#define OCI_ATTR_DIRPATH_RESERVED_5 357 /* reserved */ +#define OCI_ATTR_DIRPATH_RESERVED_6 358 /* reserved */ + +#define OCI_ATTR_DIRPATH_LOCK_WAIT 359 /* wait for lock in dpapi */ + +#define OCI_ATTR_DIRPATH_RESERVED_9 2000 /* reserved */ + +/*------ Attribute for 10iR2 for column encryption for Direct Path API ------*/ +#define OCI_ATTR_DIRPATH_RESERVED_10 2001 /* reserved */ +#define OCI_ATTR_DIRPATH_RESERVED_11 2002 /* reserved */ + +/*------ Attribute to determine last column successfully converted ----------*/ +#define OCI_ATTR_CURRENT_ERRCOL 2003 /* current error column */ + + /*--Attributes for 11gR1 for multiple subtype support in Direct Path API - */ +#define OCI_ATTR_DIRPATH_SUBTYPE_INDEX 2004 /* sbtyp indx for attribute */ + +#define OCI_ATTR_DIRPATH_RESERVED_12 2005 /* reserved */ +#define OCI_ATTR_DIRPATH_RESERVED_13 2006 /* reserver */ + + /*--Attribute for partitioning constraint optimization in Direct Path API */ +#define OCI_ATTR_DIRPATH_RESERVED_14 2007 /* reserved */ + + /*--Attribute for interval partitioning in Direct Path API */ +#define OCI_ATTR_DIRPATH_RESERVED_15 2008 /* reserved */ + + /*--Attribute for interval partitioning in Direct Path API */ +#define OCI_ATTR_DIRPATH_RESERVED_16 2009 /* reserved */ + +/*--Attribute for allowing parallel lob loads in Direct Path API */ +#define OCI_ATTR_DIRPATH_RESERVED_17 2010 /* reserved */ + +/*--Attribute for process order number of table being loaded/unloaded */ +#define OCI_ATTR_DIRPATH_RESERVED_18 2011 /* reserved */ + +#define OCI_ATTR_DIRPATH_RESERVED_19 2012 /* reserved */ + +/* Add DirPathAPI attributes above. Next value to be assigned is 2013 */ + +/* ------------------End of DirPathAPI attribute Section --------------------*/ +/*---------------------------------------------------------------------------*/ + + +/*---------------- Describe Handle Parameter Attribute Values ---------------*/ + +/* OCI_ATTR_CURSOR_COMMIT_BEHAVIOR */ +#define OCI_CURSOR_OPEN 0 +#define OCI_CURSOR_CLOSED 1 + +/* OCI_ATTR_CATALOG_LOCATION */ +#define OCI_CL_START 0 +#define OCI_CL_END 1 + +/* OCI_ATTR_SAVEPOINT_SUPPORT */ +#define OCI_SP_SUPPORTED 0 +#define OCI_SP_UNSUPPORTED 1 + +/* OCI_ATTR_NOWAIT_SUPPORT */ +#define OCI_NW_SUPPORTED 0 +#define OCI_NW_UNSUPPORTED 1 + +/* OCI_ATTR_AUTOCOMMIT_DDL */ +#define OCI_AC_DDL 0 +#define OCI_NO_AC_DDL 1 + +/* OCI_ATTR_LOCKING_MODE */ +#define OCI_LOCK_IMMEDIATE 0 +#define OCI_LOCK_DELAYED 1 + +/* ------------------- Instance type attribute values -----------------------*/ +#define OCI_INSTANCE_TYPE_UNKNOWN 0 +#define OCI_INSTANCE_TYPE_RDBMS 1 +#define OCI_INSTANCE_TYPE_OSM 2 + +/* ---------------- ASM Volume Device Support attribute values --------------*/ +#define OCI_ASM_VOLUME_UNSUPPORTED 0 +#define OCI_ASM_VOLUME_SUPPORTED 1 + +/*---------------------------------------------------------------------------*/ + +/*---------------------------OCIPasswordChange-------------------------------*/ +#define OCI_AUTH 0x08 /* Change the password but do not login */ + + +/*------------------------Other Constants------------------------------------*/ +#define OCI_MAX_FNS 100 /* max number of OCI Functions */ +#define OCI_SQLSTATE_SIZE 5 +#define OCI_ERROR_MAXMSG_SIZE 1024 /* max size of an error message */ +#define OCI_LOBMAXSIZE MINUB4MAXVAL /* maximum lob data size */ +#define OCI_ROWID_LEN 23 +/*---------------------------------------------------------------------------*/ + +/*------------------------ Fail Over Events ---------------------------------*/ +#define OCI_FO_END 0x00000001 +#define OCI_FO_ABORT 0x00000002 +#define OCI_FO_REAUTH 0x00000004 +#define OCI_FO_BEGIN 0x00000008 +#define OCI_FO_ERROR 0x00000010 +/*---------------------------------------------------------------------------*/ + +/*------------------------ Fail Over Callback Return Codes ------------------*/ +#define OCI_FO_RETRY 25410 +/*---------------------------------------------------------------------------*/ + +/*------------------------- Fail Over Types ---------------------------------*/ +#define OCI_FO_NONE 0x00000001 +#define OCI_FO_SESSION 0x00000002 +#define OCI_FO_SELECT 0x00000004 +#define OCI_FO_TXNAL 0x00000008 +/*---------------------------------------------------------------------------*/ + +/*-----------------------Function Codes--------------------------------------*/ +#define OCI_FNCODE_INITIALIZE 1 /* OCIInitialize */ +#define OCI_FNCODE_HANDLEALLOC 2 /* OCIHandleAlloc */ +#define OCI_FNCODE_HANDLEFREE 3 /* OCIHandleFree */ +#define OCI_FNCODE_DESCRIPTORALLOC 4 /* OCIDescriptorAlloc */ +#define OCI_FNCODE_DESCRIPTORFREE 5 /* OCIDescriptorFree */ +#define OCI_FNCODE_ENVINIT 6 /* OCIEnvInit */ +#define OCI_FNCODE_SERVERATTACH 7 /* OCIServerAttach */ +#define OCI_FNCODE_SERVERDETACH 8 /* OCIServerDetach */ +/* unused 9 */ +#define OCI_FNCODE_SESSIONBEGIN 10 /* OCISessionBegin */ +#define OCI_FNCODE_SESSIONEND 11 /* OCISessionEnd */ +#define OCI_FNCODE_PASSWORDCHANGE 12 /* OCIPasswordChange */ +#define OCI_FNCODE_STMTPREPARE 13 /* OCIStmtPrepare */ + /* unused 14- 16 */ +#define OCI_FNCODE_BINDDYNAMIC 17 /* OCIBindDynamic */ +#define OCI_FNCODE_BINDOBJECT 18 /* OCIBindObject */ + /* 19 unused */ +#define OCI_FNCODE_BINDARRAYOFSTRUCT 20 /* OCIBindArrayOfStruct */ +#define OCI_FNCODE_STMTEXECUTE 21 /* OCIStmtExecute */ + /* unused 22-24 */ +#define OCI_FNCODE_DEFINEOBJECT 25 /* OCIDefineObject */ +#define OCI_FNCODE_DEFINEDYNAMIC 26 /* OCIDefineDynamic */ +#define OCI_FNCODE_DEFINEARRAYOFSTRUCT 27 /* OCIDefineArrayOfStruct */ +#define OCI_FNCODE_STMTFETCH 28 /* OCIStmtFetch */ +#define OCI_FNCODE_STMTGETBIND 29 /* OCIStmtGetBindInfo */ + /* 30, 31 unused */ +#define OCI_FNCODE_DESCRIBEANY 32 /* OCIDescribeAny */ +#define OCI_FNCODE_TRANSSTART 33 /* OCITransStart */ +#define OCI_FNCODE_TRANSDETACH 34 /* OCITransDetach */ +#define OCI_FNCODE_TRANSCOMMIT 35 /* OCITransCommit */ + /* 36 unused */ +#define OCI_FNCODE_ERRORGET 37 /* OCIErrorGet */ +#define OCI_FNCODE_LOBOPENFILE 38 /* OCILobFileOpen */ +#define OCI_FNCODE_LOBCLOSEFILE 39 /* OCILobFileClose */ + /* 40 was LOBCREATEFILE, unused */ + /* 41 was OCILobFileDelete, unused */ +#define OCI_FNCODE_LOBCOPY 42 /* OCILobCopy */ +#define OCI_FNCODE_LOBAPPEND 43 /* OCILobAppend */ +#define OCI_FNCODE_LOBERASE 44 /* OCILobErase */ +#define OCI_FNCODE_LOBLENGTH 45 /* OCILobGetLength */ +#define OCI_FNCODE_LOBTRIM 46 /* OCILobTrim */ +#define OCI_FNCODE_LOBREAD 47 /* OCILobRead */ +#define OCI_FNCODE_LOBWRITE 48 /* OCILobWrite */ + /* 49 unused */ +#define OCI_FNCODE_SVCCTXBREAK 50 /* OCIBreak */ +#define OCI_FNCODE_SERVERVERSION 51 /* OCIServerVersion */ + +#define OCI_FNCODE_KERBATTRSET 52 /* OCIKerbAttrSet */ + +/* unused 53 */ + +#define OCI_FNCODE_ATTRGET 54 /* OCIAttrGet */ +#define OCI_FNCODE_ATTRSET 55 /* OCIAttrSet */ +#define OCI_FNCODE_PARAMSET 56 /* OCIParamSet */ +#define OCI_FNCODE_PARAMGET 57 /* OCIParamGet */ +#define OCI_FNCODE_STMTGETPIECEINFO 58 /* OCIStmtGetPieceInfo */ +#define OCI_FNCODE_LDATOSVCCTX 59 /* OCILdaToSvcCtx */ + /* 60 unused */ +#define OCI_FNCODE_STMTSETPIECEINFO 61 /* OCIStmtSetPieceInfo */ +#define OCI_FNCODE_TRANSFORGET 62 /* OCITransForget */ +#define OCI_FNCODE_TRANSPREPARE 63 /* OCITransPrepare */ +#define OCI_FNCODE_TRANSROLLBACK 64 /* OCITransRollback */ +#define OCI_FNCODE_DEFINEBYPOS 65 /* OCIDefineByPos */ +#define OCI_FNCODE_BINDBYPOS 66 /* OCIBindByPos */ +#define OCI_FNCODE_BINDBYNAME 67 /* OCIBindByName */ +#define OCI_FNCODE_LOBASSIGN 68 /* OCILobAssign */ +#define OCI_FNCODE_LOBISEQUAL 69 /* OCILobIsEqual */ +#define OCI_FNCODE_LOBISINIT 70 /* OCILobLocatorIsInit */ + +#define OCI_FNCODE_LOBENABLEBUFFERING 71 /* OCILobEnableBuffering */ +#define OCI_FNCODE_LOBCHARSETID 72 /* OCILobCharSetID */ +#define OCI_FNCODE_LOBCHARSETFORM 73 /* OCILobCharSetForm */ +#define OCI_FNCODE_LOBFILESETNAME 74 /* OCILobFileSetName */ +#define OCI_FNCODE_LOBFILEGETNAME 75 /* OCILobFileGetName */ +#define OCI_FNCODE_LOGON 76 /* OCILogon */ +#define OCI_FNCODE_LOGOFF 77 /* OCILogoff */ +#define OCI_FNCODE_LOBDISABLEBUFFERING 78 /* OCILobDisableBuffering */ +#define OCI_FNCODE_LOBFLUSHBUFFER 79 /* OCILobFlushBuffer */ +#define OCI_FNCODE_LOBLOADFROMFILE 80 /* OCILobLoadFromFile */ + +#define OCI_FNCODE_LOBOPEN 81 /* OCILobOpen */ +#define OCI_FNCODE_LOBCLOSE 82 /* OCILobClose */ +#define OCI_FNCODE_LOBISOPEN 83 /* OCILobIsOpen */ +#define OCI_FNCODE_LOBFILEISOPEN 84 /* OCILobFileIsOpen */ +#define OCI_FNCODE_LOBFILEEXISTS 85 /* OCILobFileExists */ +#define OCI_FNCODE_LOBFILECLOSEALL 86 /* OCILobFileCloseAll */ +#define OCI_FNCODE_LOBCREATETEMP 87 /* OCILobCreateTemporary */ +#define OCI_FNCODE_LOBFREETEMP 88 /* OCILobFreeTemporary */ +#define OCI_FNCODE_LOBISTEMP 89 /* OCILobIsTemporary */ + +#define OCI_FNCODE_AQENQ 90 /* OCIAQEnq */ +#define OCI_FNCODE_AQDEQ 91 /* OCIAQDeq */ +#define OCI_FNCODE_RESET 92 /* OCIReset */ +#define OCI_FNCODE_SVCCTXTOLDA 93 /* OCISvcCtxToLda */ +#define OCI_FNCODE_LOBLOCATORASSIGN 94 /* OCILobLocatorAssign */ + +#define OCI_FNCODE_UBINDBYNAME 95 + +#define OCI_FNCODE_AQLISTEN 96 /* OCIAQListen */ + +#define OCI_FNCODE_SVC2HST 97 /* reserved */ +#define OCI_FNCODE_SVCRH 98 /* reserved */ + /* 97 and 98 are reserved for Oracle internal use */ + +#define OCI_FNCODE_TRANSMULTIPREPARE 99 /* OCITransMultiPrepare */ + +#define OCI_FNCODE_CPOOLCREATE 100 /* OCIConnectionPoolCreate */ +#define OCI_FNCODE_CPOOLDESTROY 101 /* OCIConnectionPoolDestroy */ +#define OCI_FNCODE_LOGON2 102 /* OCILogon2 */ +#define OCI_FNCODE_ROWIDTOCHAR 103 /* OCIRowidToChar */ + +#define OCI_FNCODE_SPOOLCREATE 104 /* OCISessionPoolCreate */ +#define OCI_FNCODE_SPOOLDESTROY 105 /* OCISessionPoolDestroy */ +#define OCI_FNCODE_SESSIONGET 106 /* OCISessionGet */ +#define OCI_FNCODE_SESSIONRELEASE 107 /* OCISessionRelease */ +#define OCI_FNCODE_STMTPREPARE2 108 /* OCIStmtPrepare2 */ +#define OCI_FNCODE_STMTRELEASE 109 /* OCIStmtRelease */ +#define OCI_FNCODE_AQENQARRAY 110 /* OCIAQEnqArray */ +#define OCI_FNCODE_AQDEQARRAY 111 /* OCIAQDeqArray */ +#define OCI_FNCODE_LOBCOPY2 112 /* OCILobCopy2 */ +#define OCI_FNCODE_LOBERASE2 113 /* OCILobErase2 */ +#define OCI_FNCODE_LOBLENGTH2 114 /* OCILobGetLength2 */ +#define OCI_FNCODE_LOBLOADFROMFILE2 115 /* OCILobLoadFromFile2 */ +#define OCI_FNCODE_LOBREAD2 116 /* OCILobRead2 */ +#define OCI_FNCODE_LOBTRIM2 117 /* OCILobTrim2 */ +#define OCI_FNCODE_LOBWRITE2 118 /* OCILobWrite2 */ +#define OCI_FNCODE_LOBGETSTORAGELIMIT 119 /* OCILobGetStorageLimit */ +#define OCI_FNCODE_DBSTARTUP 120 /* OCIDBStartup */ +#define OCI_FNCODE_DBSHUTDOWN 121 /* OCIDBShutdown */ +#define OCI_FNCODE_LOBARRAYREAD 122 /* OCILobArrayRead */ +#define OCI_FNCODE_LOBARRAYWRITE 123 /* OCILobArrayWrite */ +#define OCI_FNCODE_AQENQSTREAM 124 /* OCIAQEnqStreaming */ +#define OCI_FNCODE_AQGETREPLAY 125 /* OCIAQGetReplayInfo */ +#define OCI_FNCODE_AQRESETREPLAY 126 /* OCIAQResetReplayInfo */ +#define OCI_FNCODE_ARRAYDESCRIPTORALLOC 127 /*OCIArrayDescriptorAlloc */ +#define OCI_FNCODE_ARRAYDESCRIPTORFREE 128 /* OCIArrayDescriptorFree */ +#define OCI_FNCODE_LOBGETOPT 129 /* OCILobGetCptions */ +#define OCI_FNCODE_LOBSETOPT 130 /* OCILobSetCptions */ +#define OCI_FNCODE_LOBFRAGINS 131 /* OCILobFragementInsert */ +#define OCI_FNCODE_LOBFRAGDEL 132 /* OCILobFragementDelete */ +#define OCI_FNCODE_LOBFRAGMOV 133 /* OCILobFragementMove */ +#define OCI_FNCODE_LOBFRAGREP 134 /* OCILobFragementReplace */ +#define OCI_FNCODE_LOBGETDEDUPLICATEREGIONS 135/* OCILobGetDeduplicateRegions */ +#define OCI_FNCODE_APPCTXSET 136 /* OCIAppCtxSet */ +#define OCI_FNCODE_APPCTXCLEARALL 137 /* OCIAppCtxClearAll */ + +#define OCI_FNCODE_MAXFCN 137 /* maximum OCI function code */ + +/*---------------Statement Cache callback modes-----------------------------*/ +#define OCI_CBK_STMTCACHE_STMTPURGE 0x01 + +/*---------------------------------------------------------------------------*/ + +/*-----------------------Handle Definitions----------------------------------*/ +typedef struct OCIEnv OCIEnv; /* OCI environment handle */ +typedef struct OCIError OCIError; /* OCI error handle */ +typedef struct OCISvcCtx OCISvcCtx; /* OCI service handle */ +typedef struct OCIStmt OCIStmt; /* OCI statement handle */ +typedef struct OCIBind OCIBind; /* OCI bind handle */ +typedef struct OCIDefine OCIDefine; /* OCI Define handle */ +typedef struct OCIDescribe OCIDescribe; /* OCI Describe handle */ +typedef struct OCIServer OCIServer; /* OCI Server handle */ +typedef struct OCISession OCISession; /* OCI Authentication handle */ +typedef struct OCIComplexObject OCIComplexObject; /* OCI COR handle */ +typedef struct OCITrans OCITrans; /* OCI Transaction handle */ +typedef struct OCISecurity OCISecurity; /* OCI Security handle */ +typedef struct OCISubscription OCISubscription; /* subscription handle */ + +typedef struct OCICPool OCICPool; /* connection pool handle */ +typedef struct OCISPool OCISPool; /* session pool handle */ +typedef struct OCIAuthInfo OCIAuthInfo; /* auth handle */ +typedef struct OCIAdmin OCIAdmin; /* admin handle */ +typedef struct OCIEvent OCIEvent; /* HA event handle */ + +/*-----------------------Descriptor Definitions------------------------------*/ +typedef struct OCISnapshot OCISnapshot; /* OCI snapshot descriptor */ +typedef struct OCIResult OCIResult; /* OCI Result Set Descriptor */ +typedef struct OCILobLocator OCILobLocator; /* OCI Lob Locator descriptor */ +typedef struct OCILobRegion OCILobRegion; /* OCI Lob Regions descriptor */ +typedef struct OCIParam OCIParam; /* OCI PARameter descriptor */ +typedef struct OCIComplexObjectComp OCIComplexObjectComp; + /* OCI COR descriptor */ +typedef struct OCIRowid OCIRowid; /* OCI ROWID descriptor */ + +typedef struct OCIDateTime OCIDateTime; /* OCI DateTime descriptor */ +typedef struct OCIInterval OCIInterval; /* OCI Interval descriptor */ + +typedef struct OCIUcb OCIUcb; /* OCI User Callback descriptor */ +typedef struct OCIServerDNs OCIServerDNs; /* OCI server DN descriptor */ + +/*-------------------------- AQ Descriptors ---------------------------------*/ +typedef struct OCIAQEnqOptions OCIAQEnqOptions; /* AQ Enqueue Options hdl */ +typedef struct OCIAQDeqOptions OCIAQDeqOptions; /* AQ Dequeue Options hdl */ +typedef struct OCIAQMsgProperties OCIAQMsgProperties; /* AQ Mesg Properties */ +typedef struct OCIAQAgent OCIAQAgent; /* AQ Agent descriptor */ +typedef struct OCIAQNfyDescriptor OCIAQNfyDescriptor; /* AQ Nfy descriptor */ +typedef struct OCIAQSignature OCIAQSignature; /* AQ Siganture */ +typedef struct OCIAQListenOpts OCIAQListenOpts; /* AQ listen options */ +typedef struct OCIAQLisMsgProps OCIAQLisMsgProps; /* AQ listen msg props */ + +/*---------------------------------------------------------------------------*/ + +/* Lob typedefs for Pro*C */ +typedef struct OCILobLocator OCIClobLocator; /* OCI Character LOB Locator */ +typedef struct OCILobLocator OCIBlobLocator; /* OCI Binary LOB Locator */ +typedef struct OCILobLocator OCIBFileLocator; /* OCI Binary LOB File Locator */ +/*---------------------------------------------------------------------------*/ + +/* Undefined value for tz in interval types*/ +#define OCI_INTHR_UNK 24 + + /* These defined adjustment values */ +#define OCI_ADJUST_UNK 10 +#define OCI_ORACLE_DATE 0 +#define OCI_ANSI_DATE 1 + +/*------------------------ Lob-specific Definitions -------------------------*/ + +/* + * ociloff - OCI Lob OFFset + * + * The offset in the lob data. The offset is specified in terms of bytes for + * BLOBs and BFILes. Character offsets are used for CLOBs, NCLOBs. + * The maximum size of internal lob data is 4 gigabytes. FILE LOB + * size is limited by the operating system. + */ +typedef ub4 OCILobOffset; + +/* + * ocillen - OCI Lob LENgth (of lob data) + * + * Specifies the length of lob data in bytes for BLOBs and BFILes and in + * characters for CLOBs, NCLOBs. The maximum length of internal lob + * data is 4 gigabytes. The length of FILE LOBs is limited only by the + * operating system. + */ +typedef ub4 OCILobLength; +/* + * ocilmo - OCI Lob open MOdes + * + * The mode specifies the planned operations that will be performed on the + * FILE lob data. The FILE lob can be opened in read-only mode only. + * + * In the future, we may include read/write, append and truncate modes. Append + * is equivalent to read/write mode except that the FILE is positioned for + * writing to the end. Truncate is equivalent to read/write mode except that + * the FILE LOB data is first truncated to a length of 0 before use. + */ +enum OCILobMode +{ + OCI_LOBMODE_READONLY = 1, /* read-only */ + OCI_LOBMODE_READWRITE = 2 /* read_write for internal lobs only */ +}; +typedef enum OCILobMode OCILobMode; + +/*---------------------------------------------------------------------------*/ + + +/*----------------------------Piece Definitions------------------------------*/ + +/* if ocidef.h is being included in the app, ocidef.h should precede oci.h */ + +/* + * since clients may use oci.h, ocidef.h and ocidfn.h the following defines + * need to be guarded, usually internal clients + */ + +#ifndef OCI_FLAGS +#define OCI_FLAGS +#define OCI_ONE_PIECE 0 /* one piece */ +#define OCI_FIRST_PIECE 1 /* the first piece */ +#define OCI_NEXT_PIECE 2 /* the next of many pieces */ +#define OCI_LAST_PIECE 3 /* the last piece */ +#endif +/*---------------------------------------------------------------------------*/ + +/*--------------------------- FILE open modes -------------------------------*/ +#define OCI_FILE_READONLY 1 /* readonly mode open for FILE types */ +/*---------------------------------------------------------------------------*/ +/*--------------------------- LOB open modes --------------------------------*/ +#define OCI_LOB_READONLY 1 /* readonly mode open for ILOB types */ +#define OCI_LOB_READWRITE 2 /* read write mode open for ILOBs */ +#define OCI_LOB_WRITEONLY 3 /* Writeonly mode open for ILOB types*/ +#define OCI_LOB_APPENDONLY 4 /* Appendonly mode open for ILOB types */ +#define OCI_LOB_FULLOVERWRITE 5 /* Completely overwrite ILOB */ +#define OCI_LOB_FULLREAD 6 /* Doing a Full Read of ILOB */ + +/*----------------------- LOB Buffering Flush Flags -------------------------*/ +#define OCI_LOB_BUFFER_FREE 1 +#define OCI_LOB_BUFFER_NOFREE 2 +/*---------------------------------------------------------------------------*/ + +/*---------------------------LOB Option Types -------------------------------*/ +#define OCI_LOB_OPT_COMPRESS 1 /* SECUREFILE Compress */ +#define OCI_LOB_OPT_ENCRYPT 2 /* SECUREFILE Encrypt */ +#define OCI_LOB_OPT_DEDUPLICATE 4 /* SECUREFILE Deduplicate */ +#define OCI_LOB_OPT_ALLOCSIZE 8 /* SECUREFILE Allocation Size */ +#define OCI_LOB_OPT_MIMETYPE 16 /* SECUREFILE MIME Type */ +#define OCI_LOB_OPT_MODTIME 32 /* SECUREFILE Modification Time */ + +/*------------------------ LOB Option Values ------------------------------*/ +/* Compression */ +#define OCI_LOB_COMPRESS_OFF 0 /* Compression off */ +#define OCI_LOB_COMPRESS_ON 1 /* Compression on */ +/* Encryption */ +#define OCI_LOB_ENCRYPT_OFF 0 /* Encryption Off */ +#define OCI_LOB_ENCRYPT_ON 2 /* Encryption On */ +/* Deduplciate */ +#define OCI_LOB_DEDUPLICATE_OFF 0 /* Deduplicate Off */ +#define OCI_LOB_DEDUPLICATE_ON 4 /* Deduplicate Lobs */ + +/*--------------------------- OCI Statement Types ---------------------------*/ + +#define OCI_STMT_UNKNOWN 0 /* Unknown statement */ +#define OCI_STMT_SELECT 1 /* select statement */ +#define OCI_STMT_UPDATE 2 /* update statement */ +#define OCI_STMT_DELETE 3 /* delete statement */ +#define OCI_STMT_INSERT 4 /* Insert Statement */ +#define OCI_STMT_CREATE 5 /* create statement */ +#define OCI_STMT_DROP 6 /* drop statement */ +#define OCI_STMT_ALTER 7 /* alter statement */ +#define OCI_STMT_BEGIN 8 /* begin ... (pl/sql statement)*/ +#define OCI_STMT_DECLARE 9 /* declare .. (pl/sql statement ) */ +#define OCI_STMT_CALL 10 /* corresponds to kpu call */ +/*---------------------------------------------------------------------------*/ + +/*--------------------------- OCI Parameter Types ---------------------------*/ +#define OCI_PTYPE_UNK 0 /* unknown */ +#define OCI_PTYPE_TABLE 1 /* table */ +#define OCI_PTYPE_VIEW 2 /* view */ +#define OCI_PTYPE_PROC 3 /* procedure */ +#define OCI_PTYPE_FUNC 4 /* function */ +#define OCI_PTYPE_PKG 5 /* package */ +#define OCI_PTYPE_TYPE 6 /* user-defined type */ +#define OCI_PTYPE_SYN 7 /* synonym */ +#define OCI_PTYPE_SEQ 8 /* sequence */ +#define OCI_PTYPE_COL 9 /* column */ +#define OCI_PTYPE_ARG 10 /* argument */ +#define OCI_PTYPE_LIST 11 /* list */ +#define OCI_PTYPE_TYPE_ATTR 12 /* user-defined type's attribute */ +#define OCI_PTYPE_TYPE_COLL 13 /* collection type's element */ +#define OCI_PTYPE_TYPE_METHOD 14 /* user-defined type's method */ +#define OCI_PTYPE_TYPE_ARG 15 /* user-defined type method's arg */ +#define OCI_PTYPE_TYPE_RESULT 16/* user-defined type method's result */ +#define OCI_PTYPE_SCHEMA 17 /* schema */ +#define OCI_PTYPE_DATABASE 18 /* database */ +#define OCI_PTYPE_RULE 19 /* rule */ +#define OCI_PTYPE_RULE_SET 20 /* rule set */ +#define OCI_PTYPE_EVALUATION_CONTEXT 21 /* evaluation context */ +#define OCI_PTYPE_TABLE_ALIAS 22 /* table alias */ +#define OCI_PTYPE_VARIABLE_TYPE 23 /* variable type */ +#define OCI_PTYPE_NAME_VALUE 24 /* name value pair */ + +/*---------------------------------------------------------------------------*/ + +/*----------------------------- OCI List Types ------------------------------*/ +#define OCI_LTYPE_UNK 0 /* unknown */ +#define OCI_LTYPE_COLUMN 1 /* column list */ +#define OCI_LTYPE_ARG_PROC 2 /* procedure argument list */ +#define OCI_LTYPE_ARG_FUNC 3 /* function argument list */ +#define OCI_LTYPE_SUBPRG 4 /* subprogram list */ +#define OCI_LTYPE_TYPE_ATTR 5 /* type attribute */ +#define OCI_LTYPE_TYPE_METHOD 6 /* type method */ +#define OCI_LTYPE_TYPE_ARG_PROC 7 /* type method w/o result argument list */ +#define OCI_LTYPE_TYPE_ARG_FUNC 8 /* type method w/result argument list */ +#define OCI_LTYPE_SCH_OBJ 9 /* schema object list */ +#define OCI_LTYPE_DB_SCH 10 /* database schema list */ +#define OCI_LTYPE_TYPE_SUBTYPE 11 /* subtype list */ +#define OCI_LTYPE_TABLE_ALIAS 12 /* table alias list */ +#define OCI_LTYPE_VARIABLE_TYPE 13 /* variable type list */ +#define OCI_LTYPE_NAME_VALUE 14 /* name value list */ + +/*---------------------------------------------------------------------------*/ + +/*-------------------------- Memory Cartridge Services ---------------------*/ +#define OCI_MEMORY_CLEARED 1 + +/*-------------------------- Pickler Cartridge Services ---------------------*/ +typedef struct OCIPicklerTdsCtx OCIPicklerTdsCtx; +typedef struct OCIPicklerTds OCIPicklerTds; +typedef struct OCIPicklerImage OCIPicklerImage; +typedef struct OCIPicklerFdo OCIPicklerFdo; +typedef ub4 OCIPicklerTdsElement; + +typedef struct OCIAnyData OCIAnyData; + +typedef struct OCIAnyDataSet OCIAnyDataSet; +typedef struct OCIAnyDataCtx OCIAnyDataCtx; + +/*---------------------------------------------------------------------------*/ + +/*--------------------------- User Callback Constants -----------------------*/ +#define OCI_UCBTYPE_ENTRY 1 /* entry callback */ +#define OCI_UCBTYPE_EXIT 2 /* exit callback */ +#define OCI_UCBTYPE_REPLACE 3 /* replacement callback */ + +/*---------------------------------------------------------------------------*/ + +/*--------------------- NLS service type and constance ----------------------*/ +#define OCI_NLS_DAYNAME1 1 /* Native name for Monday */ +#define OCI_NLS_DAYNAME2 2 /* Native name for Tuesday */ +#define OCI_NLS_DAYNAME3 3 /* Native name for Wednesday */ +#define OCI_NLS_DAYNAME4 4 /* Native name for Thursday */ +#define OCI_NLS_DAYNAME5 5 /* Native name for Friday */ +#define OCI_NLS_DAYNAME6 6 /* Native name for for Saturday */ +#define OCI_NLS_DAYNAME7 7 /* Native name for for Sunday */ +#define OCI_NLS_ABDAYNAME1 8 /* Native abbreviated name for Monday */ +#define OCI_NLS_ABDAYNAME2 9 /* Native abbreviated name for Tuesday */ +#define OCI_NLS_ABDAYNAME3 10 /* Native abbreviated name for Wednesday */ +#define OCI_NLS_ABDAYNAME4 11 /* Native abbreviated name for Thursday */ +#define OCI_NLS_ABDAYNAME5 12 /* Native abbreviated name for Friday */ +#define OCI_NLS_ABDAYNAME6 13 /* Native abbreviated name for for Saturday */ +#define OCI_NLS_ABDAYNAME7 14 /* Native abbreviated name for for Sunday */ +#define OCI_NLS_MONTHNAME1 15 /* Native name for January */ +#define OCI_NLS_MONTHNAME2 16 /* Native name for February */ +#define OCI_NLS_MONTHNAME3 17 /* Native name for March */ +#define OCI_NLS_MONTHNAME4 18 /* Native name for April */ +#define OCI_NLS_MONTHNAME5 19 /* Native name for May */ +#define OCI_NLS_MONTHNAME6 20 /* Native name for June */ +#define OCI_NLS_MONTHNAME7 21 /* Native name for July */ +#define OCI_NLS_MONTHNAME8 22 /* Native name for August */ +#define OCI_NLS_MONTHNAME9 23 /* Native name for September */ +#define OCI_NLS_MONTHNAME10 24 /* Native name for October */ +#define OCI_NLS_MONTHNAME11 25 /* Native name for November */ +#define OCI_NLS_MONTHNAME12 26 /* Native name for December */ +#define OCI_NLS_ABMONTHNAME1 27 /* Native abbreviated name for January */ +#define OCI_NLS_ABMONTHNAME2 28 /* Native abbreviated name for February */ +#define OCI_NLS_ABMONTHNAME3 29 /* Native abbreviated name for March */ +#define OCI_NLS_ABMONTHNAME4 30 /* Native abbreviated name for April */ +#define OCI_NLS_ABMONTHNAME5 31 /* Native abbreviated name for May */ +#define OCI_NLS_ABMONTHNAME6 32 /* Native abbreviated name for June */ +#define OCI_NLS_ABMONTHNAME7 33 /* Native abbreviated name for July */ +#define OCI_NLS_ABMONTHNAME8 34 /* Native abbreviated name for August */ +#define OCI_NLS_ABMONTHNAME9 35 /* Native abbreviated name for September */ +#define OCI_NLS_ABMONTHNAME10 36 /* Native abbreviated name for October */ +#define OCI_NLS_ABMONTHNAME11 37 /* Native abbreviated name for November */ +#define OCI_NLS_ABMONTHNAME12 38 /* Native abbreviated name for December */ +#define OCI_NLS_YES 39 /* Native string for affirmative response */ +#define OCI_NLS_NO 40 /* Native negative response */ +#define OCI_NLS_AM 41 /* Native equivalent string of AM */ +#define OCI_NLS_PM 42 /* Native equivalent string of PM */ +#define OCI_NLS_AD 43 /* Native equivalent string of AD */ +#define OCI_NLS_BC 44 /* Native equivalent string of BC */ +#define OCI_NLS_DECIMAL 45 /* decimal character */ +#define OCI_NLS_GROUP 46 /* group separator */ +#define OCI_NLS_DEBIT 47 /* Native symbol of debit */ +#define OCI_NLS_CREDIT 48 /* Native sumbol of credit */ +#define OCI_NLS_DATEFORMAT 49 /* Oracle date format */ +#define OCI_NLS_INT_CURRENCY 50 /* International currency symbol */ +#define OCI_NLS_LOC_CURRENCY 51 /* Locale currency symbol */ +#define OCI_NLS_LANGUAGE 52 /* Language name */ +#define OCI_NLS_ABLANGUAGE 53 /* Abbreviation for language name */ +#define OCI_NLS_TERRITORY 54 /* Territory name */ +#define OCI_NLS_CHARACTER_SET 55 /* Character set name */ +#define OCI_NLS_LINGUISTIC_NAME 56 /* Linguistic name */ +#define OCI_NLS_CALENDAR 57 /* Calendar name */ +#define OCI_NLS_DUAL_CURRENCY 78 /* Dual currency symbol */ +#define OCI_NLS_WRITINGDIR 79 /* Language writing direction */ +#define OCI_NLS_ABTERRITORY 80 /* Territory Abbreviation */ +#define OCI_NLS_DDATEFORMAT 81 /* Oracle default date format */ +#define OCI_NLS_DTIMEFORMAT 82 /* Oracle default time format */ +#define OCI_NLS_SFDATEFORMAT 83 /* Local string formatted date format */ +#define OCI_NLS_SFTIMEFORMAT 84 /* Local string formatted time format */ +#define OCI_NLS_NUMGROUPING 85 /* Number grouping fields */ +#define OCI_NLS_LISTSEP 86 /* List separator */ +#define OCI_NLS_MONDECIMAL 87 /* Monetary decimal character */ +#define OCI_NLS_MONGROUP 88 /* Monetary group separator */ +#define OCI_NLS_MONGROUPING 89 /* Monetary grouping fields */ +#define OCI_NLS_INT_CURRENCYSEP 90 /* International currency separator */ +#define OCI_NLS_CHARSET_MAXBYTESZ 91 /* Maximum character byte size */ +#define OCI_NLS_CHARSET_FIXEDWIDTH 92 /* Fixed-width charset byte size */ +#define OCI_NLS_CHARSET_ID 93 /* Character set id */ +#define OCI_NLS_NCHARSET_ID 94 /* NCharacter set id */ + +#define OCI_NLS_MAXBUFSZ 100 /* Max buffer size may need for OCINlsGetInfo */ + +#define OCI_NLS_BINARY 0x1 /* for the binary comparison */ +#define OCI_NLS_LINGUISTIC 0x2 /* for linguistic comparison */ +#define OCI_NLS_CASE_INSENSITIVE 0x10 /* for case-insensitive comparison */ + +#define OCI_NLS_UPPERCASE 0x20 /* convert to uppercase */ +#define OCI_NLS_LOWERCASE 0x40 /* convert to lowercase */ + +#define OCI_NLS_CS_IANA_TO_ORA 0 /* Map charset name from IANA to Oracle */ +#define OCI_NLS_CS_ORA_TO_IANA 1 /* Map charset name from Oracle to IANA */ +#define OCI_NLS_LANG_ISO_TO_ORA 2 /* Map language name from ISO to Oracle */ +#define OCI_NLS_LANG_ORA_TO_ISO 3 /* Map language name from Oracle to ISO */ +#define OCI_NLS_TERR_ISO_TO_ORA 4 /* Map territory name from ISO to Oracle*/ +#define OCI_NLS_TERR_ORA_TO_ISO 5 /* Map territory name from Oracle to ISO*/ +#define OCI_NLS_TERR_ISO3_TO_ORA 6 /* Map territory name from 3-letter ISO */ + /* abbreviation to Oracle */ +#define OCI_NLS_TERR_ORA_TO_ISO3 7 /* Map territory name from Oracle to */ + /* 3-letter ISO abbreviation */ +#define OCI_NLS_LOCALE_A2_ISO_TO_ORA 8 + /*Map locale name from A2 ISO to oracle*/ +#define OCI_NLS_LOCALE_A2_ORA_TO_ISO 9 + /*Map locale name from oracle to A2 ISO*/ + +typedef struct OCIMsg OCIMsg; +typedef ub4 OCIWchar; + +#define OCI_XMLTYPE_CREATE_OCISTRING 1 +#define OCI_XMLTYPE_CREATE_CLOB 2 +#define OCI_XMLTYPE_CREATE_BLOB 3 + +/*------------------------- Kerber Authentication Modes ---------------------*/ +#define OCI_KERBCRED_PROXY 1 /* Apply Kerberos Creds for Proxy */ +#define OCI_KERBCRED_CLIENT_IDENTIFIER 2/*Apply Creds for Secure Client ID */ + +/*------------------------- Database Startup Flags --------------------------*/ +#define OCI_DBSTARTUPFLAG_FORCE 0x00000001 /* Abort running instance, start */ +#define OCI_DBSTARTUPFLAG_RESTRICT 0x00000002 /* Restrict access to DBA */ + +/*------------------------- Database Shutdown Modes -------------------------*/ +#define OCI_DBSHUTDOWN_TRANSACTIONAL 1 /* Wait for all the transactions */ +#define OCI_DBSHUTDOWN_TRANSACTIONAL_LOCAL 2 /* Wait for local transactions */ +#define OCI_DBSHUTDOWN_IMMEDIATE 3 /* Terminate and roll back */ +#define OCI_DBSHUTDOWN_ABORT 4 /* Terminate and don't roll back */ +#define OCI_DBSHUTDOWN_FINAL 5 /* Orderly shutdown */ + +/*------------------------- Version information -----------------------------*/ +#define OCI_MAJOR_VERSION 11 /* Major release version */ +#define OCI_MINOR_VERSION 1 /* Minor release version */ + +/*---------------------- OCIIOV structure definitions -----------------------*/ +struct OCIIOV +{ + void *bfp; /* The Pointer to the data buffer */ + ub4 bfl; /* Length of the Data Buffer */ +}; +typedef struct OCIIOV OCIIOV; + +/*--------------------------------------------------------------------------- + PRIVATE TYPES AND CONSTANTS + ---------------------------------------------------------------------------*/ + +/* None */ + +/*--------------------------------------------------------------------------- + PUBLIC FUNCTIONS + ---------------------------------------------------------------------------*/ + +/* see ociap.h or ocikp.h */ + +/*--------------------------------------------------------------------------- + PRIVATE FUNCTIONS + ---------------------------------------------------------------------------*/ + +/* None */ + + +#endif /* OCI_ORACLE */ + + +/* more includes */ + +#ifndef OCI1_ORACLE +#include +#endif + +#ifndef ORO_ORACLE +#include +#endif + +#ifndef ORI_ORACLE +#include +#endif + +#ifndef ORL_ORACLE +#include +#endif + +#ifndef ORT_ORACLE +#include +#endif + +#ifndef OCIEXTP_ORACLE +#include +#endif + +#include +#include + +#ifndef OCIXMLDB_ORACLE +#include +#endif + +#ifndef OCI8DP_ORACLE +#include /* interface definitions for the direct path api */ +#endif + +#ifndef OCIEXTP_ORACLE +#include +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + diff --git a/libodbc/include/ora_linux/oci1.h b/libodbc/include/ora_linux/oci1.h new file mode 100644 index 0000000000..7f8d6c0a31 --- /dev/null +++ b/libodbc/include/ora_linux/oci1.h @@ -0,0 +1,182 @@ + +/* Copyright (c) 1997, 2005, Oracle. All rights reserved. */ + +/* NOTE: See 'header_template.doc' in the 'doc' dve under the 'forms' + directory for the header file template that includes instructions. +*/ + +/* + NAME + oci1.h - Cartridge Service definitions + + DESCRIPTION + + + RELATED DOCUMENTS + + INSPECTION STATUS + Inspection date: + Inspection status: + Estimated increasing cost defects per page: + Rule sets: + + ACCEPTANCE REVIEW STATUS + Review date: + Review status: + Reviewers: + + PUBLIC FUNCTION(S) + + + PRIVATE FUNCTION(S) + + + EXAMPLES + + NOTES + + + MODIFIED (MM/DD/YY) + mbastawa 09/16/05 - dbhygiene + dmukhin 06/29/05 - ANSI prototypes; miscellaneous cleanup + nramakri 01/16/98 - remove #ifdef NEVER clause + ewaugh 12/18/97 - Turn type wrappers into functions. + skabraha 12/02/97 - Adding data structures & constants for OCIFile + rhwu 12/02/97 - OCI Thread + nramakri 12/15/97 - move to core4 + ewaugh 12/11/97 - add OCIFormat package constants + ssamu 12/10/97 - do not include s.h + nramakri 11/19/97 - add OCIExtract definitions + ssamu 11/14/97 - creation + +*/ + + +#ifndef OCI1_ORACLE +# define OCI1_ORACLE + +# ifndef ORATYPES +# include +# endif + + +/*--------------------------------------------------------------------------- + PUBLIC TYPES AND CONSTANTS + ---------------------------------------------------------------------------*/ + +/* Constants required by the OCIFormat package. */ + +#define OCIFormatUb1(variable) OCIFormatTUb1(), &(variable) +#define OCIFormatUb2(variable) OCIFormatTUb2(), &(variable) +#define OCIFormatUb4(variable) OCIFormatTUb4(), &(variable) +#define OCIFormatUword(variable) OCIFormatTUword(), &(variable) +#define OCIFormatUbig_ora(variable) OCIFormatTUbig_ora(), &(variable) +#define OCIFormatSb1(variable) OCIFormatTSb1(), &(variable) +#define OCIFormatSb2(variable) OCIFormatTSb2(), &(variable) +#define OCIFormatSb4(variable) OCIFormatTSb4(), &(variable) +#define OCIFormatSword(variable) OCIFormatTSword(), &(variable) +#define OCIFormatSbig_ora(variable) OCIFormatTSbig_ora(), &(variable) +#define OCIFormatEb1(variable) OCIFormatTEb1(), &(variable) +#define OCIFormatEb2(variable) OCIFormatTEb2(), &(variable) +#define OCIFormatEb4(variable) OCIFormatTEb4(), &(variable) +#define OCIFormatEword(variable) OCIFormatTEword(), &(variable) +#define OCIFormatChar(variable) OCIFormatTChar(), &(variable) +#define OCIFormatText(variable) OCIFormatTText(), (variable) +#define OCIFormatDouble(variable) OCIFormatTDouble(), &(variable) +#define OCIFormatDvoid(variable) OCIFormatTDvoid(), (variable) +#define OCIFormatEnd OCIFormatTEnd() + +#define OCIFormatDP 6 + + +/*----------------- Public Constants for OCIFile -------------------------*/ + +/* flags for open.*/ +/* flags for mode */ +#define OCI_FILE_READ_ONLY 1 /* open for read only */ +#define OCI_FILE_WRITE_ONLY 2 /* open for write only */ +#define OCI_FILE_READ_WRITE 3 /* open for read & write */ +/* flags for create */ +#define OCI_FILE_EXIST 0 /* the file should exist */ +#define OCI_FILE_CREATE 1 /* create if the file doesn't exist */ +#define OCI_FILE_EXCL 2 /* the file should not exist */ +#define OCI_FILE_TRUNCATE 4 /* create if the file doesn't exist, + else truncate file the file to 0 */ +#define OCI_FILE_APPEND 8 /* open the file in append mode */ + +/* flags for seek */ +#define OCI_FILE_SEEK_BEGINNING 1 /* seek from the beginning of the file */ +#define OCI_FILE_SEEK_CURRENT 2 /* seek from the current position */ +#define OCI_FILE_SEEK_END 3 /* seek from the end of the file */ + +#define OCI_FILE_FORWARD 1 /* seek forward */ +#define OCI_FILE_BACKWARD 2 /* seek backward */ + +/* file type */ +#define OCI_FILE_BIN 0 /* binary file */ +#define OCI_FILE_TEXT 1 /* text file */ +#define OCI_FILE_STDIN 2 /* standard i/p */ +#define OCI_FILE_STDOUT 3 /* standard o/p */ +#define OCI_FILE_STDERR 4 /* standard error */ + +/* Represents an open file */ +typedef struct OCIFileObject OCIFileObject; + + +/*--------------------- OCI Thread Object Definitions------------------------*/ + +/* OCIThread Context */ +typedef struct OCIThreadContext OCIThreadContext; + +/* OCIThread Mutual Exclusion Lock */ +typedef struct OCIThreadMutex OCIThreadMutex; + +/* OCIThread Key for Thread-Specific Data */ +typedef struct OCIThreadKey OCIThreadKey; + +/* OCIThread Thread ID */ +typedef struct OCIThreadId OCIThreadId; + +/* OCIThread Thread Handle */ +typedef struct OCIThreadHandle OCIThreadHandle; + + +/*-------------------- OCI Thread Callback Function Pointers ----------------*/ + +/* OCIThread Key Destructor Function Type */ +typedef void (*OCIThreadKeyDestFunc)( void * ); + + +/* Flags passed into OCIExtractFromXXX routines to direct processing */ +#define OCI_EXTRACT_CASE_SENSITIVE 0x1 /* matching is case sensitive */ +#define OCI_EXTRACT_UNIQUE_ABBREVS 0x2 /* unique abbreviations for keys + are allowed */ +#define OCI_EXTRACT_APPEND_VALUES 0x4 /* if multiple values for a key + exist, this determines if the + new value should be appended + to (or replace) the current + list of values */ + +/* Constants passed into OCIExtractSetKey routine */ +#define OCI_EXTRACT_MULTIPLE 0x8 /* key can accept multiple values */ +#define OCI_EXTRACT_TYPE_BOOLEAN 1 /* key type is boolean */ +#define OCI_EXTRACT_TYPE_STRING 2 /* key type is string */ +#define OCI_EXTRACT_TYPE_INTEGER 3 /* key type is integer */ +#define OCI_EXTRACT_TYPE_OCINUM 4 /* key type is ocinum */ + +/*--------------------------------------------------------------------------- + PRIVATE TYPES AND CONSTANTS + ---------------------------------------------------------------------------*/ + + +/*--------------------------------------------------------------------------- + PUBLIC FUNCTIONS + ---------------------------------------------------------------------------*/ + + +/*--------------------------------------------------------------------------- + PRIVATE FUNCTIONS + ---------------------------------------------------------------------------*/ + + +#endif /* OCI1_ORACLE */ diff --git a/libodbc/include/ora_linux/oci8dp.h b/libodbc/include/ora_linux/oci8dp.h new file mode 100644 index 0000000000..070651081f --- /dev/null +++ b/libodbc/include/ora_linux/oci8dp.h @@ -0,0 +1,317 @@ +/* + * + */ + +/* Copyright (c) 1998, 2005, Oracle. All rights reserved. */ + +/* + NAME + oci8dp.h - OCI: Direct Path API interface prototypes. + + DESCRIPTION + Public types, constants, and interfaces to the direct path API. + + RELATED DOCUMENTS + + NOTES + This file is not directly included by the application, this file + is included by "oci.h", which the application should include. + + MODIFIED (MM/DD/YY) + dmukhin 06/29/05 - ANSI prototypes; miscellaneous cleanup + rphillip 02/27/04 - Add OCI_DIRPATH_COL_ERROR + srseshad 03/12/03 - convert oci public api to ansi + msakayed 10/28/02 - Bug #2643907: add OCI_ATTR_DIRPATH_SKIPINDEX_METHOD + cmlim 04/13/01 - remove OCIDirPathStreamToStream - not used by dpapi + cmlim 04/02/01 - OCI_DIRPATH_EXPR_OPQ_SQL_FN to OCI_DIRPATH_EXPR_SQL + ebatbout 01/22/01 - PARTIAL value for OCIDirPathDataSave action parameter + cmlim 07/20/00 - support opaques/sql strings in 8.2 dpapi + cmlim 08/14/00 - support refs in 8.2 dpapi + cmlim 04/17/00 - add defines for OCIDirPathFuncCtx handle & OCI_ATTR_D + whe 09/01/99 - 976457:check __cplusplus for C++ code + abrumm 04/16/99 - dpapi: more attributes + abrumm 02/26/99 - add defines for DataSave action + abrumm 10/04/98 - clen must be a ub4 + abrumm 05/27/98 - add column array flag values + abrumm 05/12/98 - direct path api support + abrumm 03/31/98 - OCI direct path interface support + abrumm 03/18/98 - Creation + +*/ + +#ifndef OCI8DP_ORACLE +# define OCI8DP_ORACLE + +#ifndef ORATYPES +#include +#endif + +#ifndef OCIDFN +#include +#endif + +#ifndef OCI_ORACLE +#include +#endif + + +/*--------------------------------------------------------------------------- + PUBLIC TYPES AND CONSTANTS + ---------------------------------------------------------------------------*/ + +/*----- Handles and descriptors for direct path operations (OCIDirPath*) ----*/ + +typedef struct OCIDirPathCtx OCIDirPathCtx; /* context */ +typedef struct OCIDirPathFuncCtx OCIDirPathFuncCtx; /* function context */ +typedef struct OCIDirPathColArray OCIDirPathColArray; /* column array */ +typedef struct OCIDirPathStream OCIDirPathStream; /* stream */ +typedef struct OCIDirPathDesc OCIDirPathDesc; /* direct path descriptor */ + + /*----- Defines for Direct Path Options -----*/ + + /* values for OCI_ATTR_DIRPATH_MODE attribute */ +#define OCI_DIRPATH_LOAD 1 /* direct path load operation */ +#define OCI_DIRPATH_UNLOAD 2 /* direct path unload operation */ +#define OCI_DIRPATH_CONVERT 3 /* direct path convert only operation */ + + /*----- values for OCI_ATTR_DIRPATH_INDEX_MAINT_METHOD attribute -----*/ +#define OCI_DIRPATH_INDEX_MAINT_SINGLE_ROW 1 + +/* Note that there are two attributes dealing with index maintenance - + * OCI_ATTR_DIRPATH_INDEX_MAINT_METHOD and OCI_ATTR_DIRPATH_SKIPINDEX_METHOD. + * OCI_ATTR_DIRPATH_SKIPINDEX_METHOD exists to isolate the behavior for + * skipping index maintenance since maintenance of unusable indexes is + * orthogonal to that of single row insertion. + * For backwards compatibility we still allow users to specify skip + * methods in OCI_ATTR_DIRPATH_INDEX_MAINT_METHOD so make sure the + * enumerations for the two attributes are distinct. + */ + /*----- values for OCI_ATTR_DIRPATH_SKIPINDEX_METHOD attribute -----*/ +#define OCI_DIRPATH_INDEX_MAINT_SKIP_UNUSABLE 2 +#define OCI_DIRPATH_INDEX_MAINT_DONT_SKIP_UNUSABLE 3 +#define OCI_DIRPATH_INDEX_MAINT_SKIP_ALL 4 + + /* values for OCI_ATTR_STATE attribute of OCIDirPathCtx */ +#define OCI_DIRPATH_NORMAL 1 /* can accept rows, last row complete */ +#define OCI_DIRPATH_PARTIAL 2 /* last row was partial */ +#define OCI_DIRPATH_NOT_PREPARED 3 /* direct path context is not prepared */ + + /*----- values for cflg argument to OCIDirpathColArrayEntrySet -----*/ +#define OCI_DIRPATH_COL_COMPLETE 0 /* column data is complete */ +#define OCI_DIRPATH_COL_NULL 1 /* column is null */ +#define OCI_DIRPATH_COL_PARTIAL 2 /* column data is partial */ +#define OCI_DIRPATH_COL_ERROR 3 /* column error, ignore row */ + /*----- values for action parameter to OCIDirPathDataSave -----*/ +#define OCI_DIRPATH_DATASAVE_SAVEONLY 0 /* data save point only */ +#define OCI_DIRPATH_DATASAVE_FINISH 1 /* execute finishing logic */ +/* save portion of input data (before space error occurred) and finish */ +#define OCI_DIRPATH_DATASAVE_PARTIAL 2 + + /*- OCI_ATTR_DIRPATH_EXPR_TYPE values (describes OCI_ATTR_NAME expr type) -*/ +#define OCI_DIRPATH_EXPR_OBJ_CONSTR 1 /* NAME is an object constructor */ +#define OCI_DIRPATH_EXPR_SQL 2 /* NAME is an opaque or sql function */ +#define OCI_DIRPATH_EXPR_REF_TBLNAME 3 /* NAME is table name if ref is scoped*/ + + +/*--------------------------------------------------------------------------- + PUBLIC FUNCTIONS + ---------------------------------------------------------------------------*/ + +/*------------------------ OCIDirPathCtx Operations -------------------------*/ + +/* + NAME + OCIDirPathAbort - OCI: Abort a direct path operation. + + DESCRIPTION + Aborts a direct path operation. Upon successful completion + the direct path context is no longer valid. + + RETURNS + An OCI error code, Oracle errors are returned via the error handle. + NOTES + */ +sword +OCIDirPathAbort( OCIDirPathCtx *dpctx, OCIError *errhp ); + +/* + NAME + OCIDirPathDataSave - OCI: Execute a data save point. + + DESCRIPTION + Successful return of this function indicates that a data save + point has been executed. + + RETURNS + An OCI error code, Oracle errors are returned via the error handle. + NOTES + */ +sword +OCIDirPathDataSave( OCIDirPathCtx *dpctx, OCIError *errhp, ub4 action ); + +/* + NAME + OCIDirPathFinish - OCI: Finish a direct path operation. + + DESCRIPTION + Finishes a direct path operation. + + RETURNS + An OCI error code, Oracle errors are returned via the error handle. + NOTES + */ +sword +OCIDirPathFinish( OCIDirPathCtx *dpctx, OCIError *errhp ); + +/* + NAME + OCIDirPathFlushRow - OCI: Flush a partial row from the server. + + DESCRIPTION + Flushes a partially loaded row from the server. + + RETURNS + An OCI error code, Oracle errors are returned via the error handle. + NOTES + */ +sword +OCIDirPathFlushRow( OCIDirPathCtx *dpctx, OCIError *errhp ); + +/* + NAME + OCIDirPathPrepare - OCI: Prepare a direct path operation. + + DESCRIPTION + Prepares a table/partition for a direct path operation. + + RETURNS + An OCI error code, Oracle errors are returned via the error handle. + NOTES + */ +sword +OCIDirPathPrepare( OCIDirPathCtx *dpctx, OCISvcCtx *svchp, + OCIError *errhp ); + +/* + NAME + OCIDirPathLoadStream - OCI: Load a direct path stream. + + DESCRIPTION + Load a direct path stream to the object associated with + the direct path context. + + RETURNS + An OCI error code, Oracle errors are returned via the error handle. + NOTES + */ +sword +OCIDirPathLoadStream( OCIDirPathCtx *dpctx, OCIDirPathStream *dpstr, + OCIError *errhp ); + + +/*---------------------- OCIDirPathColArray Operations ----------------------*/ + +/* + NAME + OCIDirPathColArrayEntryGet - OCI: Get column array entry. + + DESCRIPTION + Column array function which is used to get a specified entry in + a column array. + + RETURNS + An OCI error code, Oracle errors are returned via the error handle. + NOTES + */ +sword +OCIDirPathColArrayEntryGet( OCIDirPathColArray *dpca, OCIError *errhp, + ub4 rownum, ub2 colIdx, ub1 **cvalpp, ub4 *clenp, + ub1 *cflgp ); + +/* + NAME + OCIDirPathColArrayEntrySet - OCI: Set column array entry. + + DESCRIPTION + Column array function which is used to set a specified entry in + a column array. + + RETURNS + An OCI error code, Oracle errors are returned via the error handle. + NOTES + */ +sword +OCIDirPathColArrayEntrySet( OCIDirPathColArray *dpca, OCIError *errhp, + ub4 rownum, ub2 colIdx, ub1 *cvalp, ub4 clen, + ub1 cflg ); + +/* + NAME + OCIDirPathColArrayRowGet - OCI: Get column array row pointers. + + DESCRIPTION + Column array function which is used to get the base row pointers + for a specified row in a column array. + To be used in lieu of OCIDirPathColArrayEntryGet() and + OCIDirPathColArrayEntrySet(). + + RETURNS + An OCI error code, Oracle errors are returned via the error handle. + NOTES + */ +sword +OCIDirPathColArrayRowGet( OCIDirPathColArray *dpca, OCIError *errhp, + ub4 rownum, ub1 ***cvalppp, ub4 **clenpp, + ub1 **cflgpp ); + +/* + NAME + OCIDirPathColArrayReset - OCI: Reset Column Array State + + DESCRIPTION + Function which resets the column array state. + + RETURNS + An OCI error code, Oracle errors are returned via the error handle. + NOTES + Resetting the column array state is necessary when piecing in a large + column and an error occurs in the middle of loading the column. + */ +sword +OCIDirPathColArrayReset( OCIDirPathColArray *dpca, OCIError *errhp ); + +/* + NAME + OCIDirPathColArrayToStream - OCI: Convert Column Array to Stream Format. + + DESCRIPTION + Convert from column array format to stream format which is suitable + for loading via OCIDirPathLoadStream(). + + RETURNS + An OCI error code, Oracle errors are returned via the error handle. + NOTES + */ +sword +OCIDirPathColArrayToStream( OCIDirPathColArray *dpca, OCIDirPathCtx *dpctx, + OCIDirPathStream *dpstr, OCIError *errhp, + ub4 rowcnt, ub4 rowoff ); + + + +/*----------------------- OCIDirPathStream Operations -----------------------*/ + +/* + NAME + OCIDirPathStreamReset - OCI: + + DESCRIPTION + + RETURNS + An OCI error code, Oracle errors are returned via the error handle. + NOTES + */ +sword +OCIDirPathStreamReset( OCIDirPathStream *dpstr, OCIError *errhp ); + +#endif /* OCI8DP_ORACLE */ diff --git a/libodbc/include/ora_linux/ociap.h b/libodbc/include/ora_linux/ociap.h new file mode 100644 index 0000000000..c3bcba8021 --- /dev/null +++ b/libodbc/include/ora_linux/ociap.h @@ -0,0 +1,11034 @@ +/* Copyright (c) 1996, 2007, Oracle. All rights reserved. */ + +/* + NAME + ociap.h + + DESCRIPTION + Oracle Call Interface - Ansi Prototypes + + RELATED DOCUMENTS + + INSPECTION STATUS + Inspection date: + Inspection status: + Estimated increasing cost defects per page: + Rule sets: + + ACCEPTANCE REVIEW STATUS + Review date: + Review status: + Reviewers: + + PUBLIC FUNCTION(S) + OCIAttrGet + OCIAttrSet + OCIBindArrayOfStruct + OCIBindByName + OCIBindByPos + OCIBindDynamic + OCIBindObject + OCIBreak + OCIConnectionPoolCreate + OCISessionPoolCreate + OCISessionGet + OCISessionRelease + OCIDateTimeAssign + OCIDateTimeCheck + OCIDateTimeCompare + OCIDateTimeConvert + OCIDateTimeFromText + OCIDateTimeGetDate + OCIDateTimeGetTime + OCIDateTimeGetTime + OCIDateTimeGetTimeZoneOffset + OCIDateTimeSysTimeStamp + OCIDateTimeIntervalAdd + OCIDateTimeIntervalSub + OCIDateTimeConstruct + OCIDateTimeSubtract + OCIDateTimeToText + OCIDateTimeGetTimeZoneName + OCIDateTimeToArray + OCIDateTimeFromArray + OCIRowidToChar + OCIDefineArrayOfStruct + OCIDefineByPos + OCIDefineDynamic + OCIDefineObject + OCIDescAlloc + OCIDescFree + OCIDescribeAny + OCIEnvCreate + OCIEnvNlsCreate + OCIEnvInit + OCIErrorGet + OCIExtractSetKey + OCIExtractFromFile + OCIIntervalSubtract + OCIIntervalMultiply + OCIIntervalToNumber + OCIIntervalToText + OCIIntervalFromTZ + OCIKerbAttrSet + OCILdaToSvcCtx + OCILobAppend + OCILobAssign + OCILobCharSetForm + OCILobCharSetId + OCILobCopy + OCILobCreateTemporary + OCILobDisableBuffering + OCILobEnableBuffering + OCILobErase + OCILobOpen + OCILobClose + OCILobFileClose + OCILobFileCLoseAll + OCILobFileExists + OCILobFileGetName + OCILobFileIsOpen + OCILobFileOpen + OCILobFileSetName + OCILobFlushBuffer + OCILobFreeTemporary + OCILobGetChunkSize + OCILobGetLength + OCILobIsEqual + OCILobIsTemporary + OCILobLoadFromFile + OCILobLocatorAssign + OCILobLocatorIsInit + OCILobRead + OCILobTrim + OCILobWrite + OCILobWriteAppend + OCILobGetStorageLimit + OCILobGetOptions + OCILobSetOptions + OCILogoff + OCILogon + OCILogon2 + OCIMemoryFree + OCIParamGet + OCIParamGet + OCIPasswordChange + OCIReset + OCIResultSetToStmt + OCIServerAttach + OCIServerDetach + OCIServerVersion + OCISessionBegin + OCISessionEnd + OCIStmtExecute + OCIStmtFetch + OCIStmtFetch2 + OCIStmtGetPieceInfo + OCIStmtPrepare + OCIStmtPrepare2 + OCIStmtRelease + OCIStmtSetPieceInfo + OCIFormatString + OCISvcCtxToLda + OCITransCommit + OCITransDetach + OCITransForget + OCITransMultiPrepare + OCITransPrepare + OCITransRollback + OCITransStart + OCIInitialize + OCIEnvCreate + OCIEnvNlsCreate + OCIFEnvCreate + OCIHandleAlloc + OCIDescriptorAlloc + OCIDescriptorFree + OCIArrayDescriptorAlloc + OCIArrayDescriptorFree + OCIEnvInit + OCIServerAttach + OCISessionBegin + OCISessionEnd + OCILogon + OCILogon2 + OCIPasswordChange + OCIStmtPrepare + OCIStmtPrepare2 + OCIStmtRelease + OCIBindByPos + OCIBindByName + OCIBindObject + OCIBindDynamic + OCIBindArrayOfStruct + OCIStmtGetPieceInfo + OCIStmtSetPieceInfo + OCIStmtExecute + OCIDefineByPos + OCIDefineObject + OCIDefineDynamic + OCIRowidToChar + OCIDefineArrayOfStruct + OCIStmtFetch + OCIStmtFetch2 + OCIStmtGetBindInfo + OCIDescribeAny + OCIParamGet + OCIParamSet + OCITransStart + OCITransMultiPrepare + OCIErrorGet + OCILobAppend + OCILobAssign + OCILobCharSetForm + OCILobCharSetId + OCILobCopy + OCILobCreateTemporary + OCILobClose + OCILobDisableBuffering + OCILobEnableBuffering + OCILobErase + OCILobFileClose + OCILobFileExists + OCILobFileGetName + OCILobFileIsOpen + OCILobFileOpen + OCILobFileSetName + OCILobFlushBuffer + OCILobFreeTemporary + OCILobGetChunkSize + OCILobGetLength + OCILobIsEqual + OCILobIsOpen + OCILobIsTemporary + OCILobLoadFromFile + OCILobLocatorAssign + OCILobLocatorIsInit + OCILobOpen + OCILobRead + OCILobTrim + OCILobWrite + OCILobWriteAppend + OCIServerVersion + OCIServerRelease + OCIAttrGet + OCIAttrSet + OCIUserCallbackRegister + OCIUserCallbackGet + OCISharedLibInit + OCIFileExists + OCIFileGetLength + OCIFileOpen + OCIFileRead + OCIFileSeek + OCIFileWrite + OCILobCopy2 + OCILobErase2 + OCILobGetLength2 + OCILobLoadFromFile2 + OCILobRead2 + OCILobArrayRead + OCILobTrim2 + OCILobWrite2 + OCILobArrayWrite + OCILobWriteAppend2 + OCILobGetStorageLimit + OCISecurityOpenWallet + OCISecurityCloseWallet + OCISecurityCreateWallet + OCISecurityDestroyWallet + OCISecurityStorePersona + OCISecurityOpenPersona + OCISecurityClosePersona + OCISecurityRemovePersona + OCISecurityCreatePersona + OCISecuritySetProtection + OCISecurityGetProtection + OCISecurityRemoveIdentity + OCISecurityCreateIdentity + OCISecurityAbortIdentity + OCISecurityFreeIdentity + OCISecurityStoreTrustedIdentity + OCISecuritySign + OCISecuritySignExpansion + OCISecurityVerify + OCISecurityValidate + OCISecuritySignDetached + OCISecuritySignDetExpansion + OCISecurityVerifyDetached + OCISecurity_PKEncrypt + OCISecurityPKEncryptExpansion + OCISecurityPKDecrypt + OCISecurityEncrypt + OCISecurityEncryptExpansion + OCISecurityDecrypt + OCISecurityEnvelope + OCISecurityDeEnvelope + OCISecurityKeyedHash + OCISecurityKeyedHashExpansion + OCISecurityHash + OCISecurityHashExpansion + OCISecuritySeedRandom + OCISecurityRandomBytes + OCISecurityRandomNumber + OCISecurityInitBlock + OCISecurityReuseBlock + OCISecurityPurgeBlock + OCISecuritySetBlock + OCISecurityGetIdentity + OCIAQEnq + OCIAQDeq + OCIAQEnqArray + OCIAQEnqStreaming + OCIAQDeqArray + OCIAQListen + OCIAQListen2 + OCIExtractSetKey + OCIExtractFromFile + OCIExtractToInt + OCIExtractToBool + OCIExtractToStr + OCIExtractToOCINum + OCIExtractFromList + OCIMemoryAlloc + OCIMemoryResize + OCIContextSetValue + OCIContextGetValue + OCIContextClearValue + OCIMemorySetCurrentIDs + OCIPicklerTdsCtxInit + OCIPicklerTdsInit + OCIPicklerTdsCreateElementNumber + OCIPicklerTdsCreateElementChar + OCIPicklerTdsCreateElementVarchar + OCIPicklerTdsCreateElementRaw + OCIPicklerTdsCreateElement + OCIPicklerTdsAddAttr + OCIPicklerTdsGenerate + OCIPicklerTdsGetAttr + OCIPicklerFdoInit + OCIPicklerFdoFree + OCIPicklerImageInit + OCIPicklerImageFree + OCIPicklerImageAddScalar + OCIPicklerImageAddNullScalar + OCIPicklerImageGenerate + OCIPicklerImageGetScalarSize + OCIPicklerImageGetScalar + OCIPicklerImageCollBegin + OCIPicklerImageCollAddScalar + OCIPicklerImageCollEnd + OCIPicklerImageCollBeginScan + OCIPicklerImageCollGetScalarSize + OCIPicklerImageCollGetScalar + OCIAnyDataGetType + OCIAnyDataIsNull + OCIAnyDataConvert + OCIAnyDataBeginCreate + OCIAnyDataAttrSet + OCIAnyDataCollAddElem + OCIAnyDataEndCreate + OCIAnyDataAccess + OCIAnyDataGetCurrAttrNum + OCIAnyDataAttrGet + OCIAnyDataCollGetElem + OCIPicklerTdsCtxInit + OCIPicklerTdsInit + OCIPicklerTdsCreateElementNumber + OCIPicklerTdsCreateElementChar + OCIPicklerTdsCreateElementVarchar + OCIPicklerTdsCreateElementRaw + OCIPicklerTdsCreateElement + OCIPicklerTdsAddAttr + OCIPicklerTdsGenerate + OCIPicklerTdsGetAttr + OCIPicklerFdoInit + OCIPicklerFdoFree + OCIPicklerImageInit + OCIPicklerImageFree + OCIPicklerImageAddScalar + OCIPicklerImageAddNullScalar + OCIPicklerImageGenerate + OCIPicklerImageGetScalarSize + OCIPicklerImageGetScalar + OCIPicklerImageCollBegin + OCIPicklerImageCollAddScalar + OCIPicklerImageCollEnd + OCIPicklerImageCollBeginScan + OCIPicklerImageCollGetScalarSize + OCIPicklerImageCollGetScalar + OCIAnyDataGetType + OCIAnyDataIsNull + OCIAnyDataConvert + OCIAnyDataBeginCreate + OCIAnyDataAttrSet + OCIAnyDataCollAddElem + OCIAnyDataEndCreate + OCIAnyDataAccess + OCIAnyDataGetCurrAttrNum + OCIAnyDataAttrGet + OCIAnyDataCollGetElem + OCIPicklerTdsCtxInit + OCIPicklerTdsInit + OCIPicklerTdsCreateElementNumber + OCIPicklerTdsCreateElementChar + OCIPicklerTdsCreateElementVarchar + OCIPicklerTdsCreateElementRaw + OCIPicklerTdsCreateElement + OCIPicklerTdsAddAttr + OCIPicklerTdsGenerate + OCIPicklerTdsGetAttr + OCIPicklerFdoInit + OCIPicklerFdoFree + OCIPicklerImageInit + OCIPicklerImageFree + OCIPicklerImageAddScalar + OCIPicklerImageAddNullScalar + OCIPicklerImageGenerate + OCIPicklerImageGetScalarSize + OCIPicklerImageGetScalar + OCIPicklerImageCollBegin + OCIPicklerImageCollAddScalar + OCIPicklerImageCollEnd + OCIPicklerImageCollBeginScan + OCIPicklerImageCollGetScalarSize + OCIPicklerImageCollGetScalar + OCIAnyDataGetType + OCIAnyDataIsNull + OCIAnyDataConvert + OCIAnyDataBeginCreate + OCIAnyDataAttrSet + OCIAnyDataCollAddElem + OCIAnyDataEndCreate + OCIAnyDataAccess + OCIAnyDataGetCurrAttrNum + OCIAnyDataAttrGet + OCIAnyDataCollGetElem + OCIAnyDataSetBeginCreate + OCIAnyDataSetDestroy + OCIAnyDataSetAddInstance + OCIAnyDataSetEndCreate + OCIAnyDataSetGetType + OCIAnyDataSetGetCount + OCIAnyDataSetGetInstance + OCIFormatString + OCINlsGetInfo + OCINlsNameMap + OCIMultiByteToWideChar + OCIMultiByteInSizeToWideChar + OCIWideCharToMultiByte + OCIWideCharInSizeToMultiByte + OCIWideCharStrcmp + OCIWideCharStrncmp + OCIWideCharStrcat + *OCIWideCharStrchr + OCIWideCharStrcpy + OCIWideCharStrncat + OCIWideCharStrncpy + *OCIWideCharStrrchr + OCIWideCharStrCaseConversion + OCIMultiByteStrcmp + OCIMultiByteStrncmp + OCIMultiByteStrcat + OCIMultiByteStrcpy + OCIMultiByteStrncat + OCIMultiByteStrncpy + OCIMultiByteStrnDisplayLength + OCIMultiByteStrCaseConversion + OCICharSetToUnicode + OCIUnicodeToCharSet + OCINlsCharSetConvert + OCINlsEnvironmentVariableGet + OCIMessageOpen + OCIMessageGet + OCIThreadMutexInit + OCIThreadMutexDestroy + OCIThreadMutexAcquire + OCIThreadMutexRelease + OCIThreadKeyInit + OCIThreadKeyDestroy + OCIThreadKeyGet + OCIThreadKeySet + OCIThreadIdSet + OCIThreadIdSetNull + OCIThreadIdGet + OCIThreadIdSame + OCIThreadIdNull + OCIThreadHndInit + OCIThreadHndDestroy + OCIThreadCreate + OCIThreadHandleGet + OCIThreadMutexInit + OCIThreadMutexDestroy + OCIThreadMutexAcquire + OCIThreadMutexRelease + OCIThreadKeyInit + OCIThreadKeyDestroy + OCIThreadKeyGet + OCIThreadKeySet + OCIThreadIdSet + OCIThreadIdSame + OCIThreadIdNull + OCIThreadCreate + OCISubscriptionRegister + OCISubscriptionPost + OCISubscriptionUnRegister + OCISubscriptionDisable + OCISubscriptionEnable + OCIDateTimeGetTime + OCIDateTimeGetDate + OCIDateTimeGetTimeZoneOffset + OCIDateTimeConstruct + OCIDateTimeSysTimeStamp + OCIDateTimeAssign + OCIDateTimeToText + OCIDateTimeFromText + OCIDateTimeCompare + OCIDateTimeCheck + OCIDateTimeConvert + OCIDateTimeSubtract + OCIDateTimeIntervalAdd + OCIDateTimeIntervalSub + OCIIntervalSubtract + OCIIntervalAdd + OCIIntervalMultiply + OCIIntervalDivide + OCIIntervalCompare + OCIIntervalFromNumber + OCIIntervalFromText + OCIIntervalToText + OCIIntervalToNumber + OCIIntervalCheck + OCIIntervalAssign + OCIIntervalSetYearMonth + OCIIntervalGetYearMonth + OCIIntervalSetDaySecond + OCIIntervalGetDaySecond + OCIDateTimeToArray + OCIDateTimeFromArray + OCIDateTimeGetTimeZoneName + OCIIntervalFromTZ + OCIConnectionPoolCreate + OCIConnectionPoolDestroy + OCISessionPoolCreate + OCISessionPoolDestroy + OCISessionGet + OCISessionRelease + OCIAppCtxSet + OCIAppCtxClearAll + OCIMemStats + OCIKerbAttrSet + OCIDBStartup + OCIDBShutdown + OCIClientVersion + OCIInitEventHandle + OCIStmtBindByPos + OCIStmtBindByName + + PRIVATE FUNCTION(S) + + EXAMPLES + + NOTES + + MODIFIED (MM/DD/YY) + schoi 02/27/07 - OCILobGet/SetOptions API change + slynn 07/28/06 - Migrate to new 11g LOB terminology + hqian 05/22/06 - add OCI_SYSASM + slynn 06/21/06 - Add Lob Get Shared Regions Functionality + slynn 05/25/06 - New NG Lob Functionality. + jawilson 05/22/06 - add TDO out parameter for streaming enq callback + aramappa 01/19/06 - Added OCIArrayDescriptorAlloc, + OCIArrayDescriptorFree + jawilson 02/09/06 - add OCIAQEnqStreaming + mxu 03/08/06 - Fix bug 5037807 + srseshad 09/12/05 - stmtcache: callback + mbastawa 09/16/05 - dbhygiene + dmukhin 06/29/05 - ANSI prototypes; miscellaneous cleanup + nbhatt 06/17/04 - merge conflicts + nbhatt 05/24/04 - merge conflicts + weiwang 05/06/04 - add OCIAQListen2 + rvissapr 06/21/04 - add OCIAppCtx API + debanerj 05/17/04 - 13064: LOB array Read and Write + aahluwal 06/02/04 - [OCI Events]: add OCIInitEventHandle + nikeda 05/28/04 - grabtrans 'nikeda_oci_events_copy' + nikeda 05/13/04 - [OCI Events] Rename HACBK->EVTCBK, HACTX->EVTCTX + nikeda 05/10/04 - [OCI Events] code review changes + aahluwal 04/09/04 - [OCI Events]: add OCIHAServerHandleGet + nikeda 03/18/04 - [OCI Events] New Server Handle Callback + dfrumkin 12/04/03 - Add OCIDBStartup, OCIDBShutdown + jciminsk 12/12/03 - merge from RDBMS_MAIN_SOLARIS_031209 + sgollapu 06/26/03 - Change OCIPing prototype + sgollapu 05/05/03 - Add OCIPing + debanerj 01/16/03 - Bug 2753018: Lob Locator parameter for + OCILobGetStorageLimit + rpingte 05/06/04 - add OCIClientVersion + debanerj 08/26/03 - 6003: Lob interface changes + sgollapu 06/23/03 - Add OCIPing + debanerj 01/16/03 - Bug 2753018: Lob Locator parameter for + OCILobGetStorageLimit + tkeefe 02/17/03 - bug-2773794: Add new interface for setting Kerb attrs + ataracha 01/03/03 - Move OCIXMLType functions to ocixml.h + akatti 11/28/02 - [2521361]:add OCIRowidToChar prototype + chliang 10/23/02 - add OCIFetchRowCallback + cparampa 10/13/02 - Fix the prototype of OCIAQListen(ansi prototype) + chliang 10/12/02 - add OCIBindRowCallback + debanerj 09/30/02 - Unlimited size LOB 6003 + thoang 09/25/02 - Add csid to XMLType create functions + thoang 04/19/02 - Add OCIXMLTypeGetNS + aahluwal 08/09/02 - adding OCIAQDeqArray + aahluwal 06/03/02 - bug 2360115 + skabraha 04/16/02 - fix compiler warnings + sichandr 02/12/02 - fix OCIXMLTypeExists + gayyappa 02/01/02 - fix 2210776 : change Dom to DOM + sichandr 10/24/01 - OCISvcCtx for XMLType create routines + schandir 09/14/01 - Add prototypes for Stmt Caching + abande 09/04/01 - Add Prototypes for Session Pooling Methods + stakeda 09/12/01 - add OCINlsCharSetConvert + whe 08/28/01 - add OCIEnvNlsCreate + wzhang 08/22/01 - Add OCINlsCharSetNameToId. + whe 10/05/01 - add prototype for OCIXMLType functions + mdmehta 04/06/01 - Bug 1683763, OCIDateTimeToText: buf_size to ub4* + schandir 12/12/00 - modify the ociconnectionpoolcreate() interface. + porangas 12/04/00 - Forward merge bug#974710 to 9i + rpingte 11/29/00 - Fix bug# 1485795. + gtarora 11/30/00 - fix comment for OCILobIsTemporary + akatti 11/07/00 - [1198379]:add OCIRowidToChar + bpalaval 10/15/00 - Forward merge 892654. + kmohan 09/18/00 - add OCILogon2 + etucker 07/28/00 - add OCIIntervalFromTZ + vjayaram 07/18/00 - add connection pooling changes + etucker 07/13/00 - add dls apis for oci + hmasaki 07/05/00 - fix 1230846: forward merge into 8.2 + mbastawa 06/05/00 - add OCIStmtFetch2 + rxgovind 06/07/00 - update OCIAnyData interfaces + rxgovind 05/04/00 - add OCIAnyDataSet interfaces + rkasamse 05/01/00 - remove attrno from OCIAnyDataAttrGet + rkasamse 03/13/00 - add prototype s for OCCIAnyData + slari 09/01/99 - remove OCIEnvCallback + slari 08/23/99 - add OCIUcb in user callback functions + dsaha 07/07/99 - Add OCIFEnvCreate for forms + vyanaman 06/21/99 - Change OCI DateTime/Interval APIs. + esoyleme 07/01/99 - expose MTS performance enhancements + whe 06/14/99 - bug727872:add CONST to match definitions + kkarun 02/23/99 - Fix OCIDateTime APIs + jiyang 12/07/98 - Add comments for OCI_NLS_DUAL_CURRENCY + aroy 12/01/98 - add OCIEnvCreate + slari 11/23/98 - use ORASTDARG + slari 11/21/98 - replace ellipsis by arglist in OCIUserCallback + thchang 10/20/98 - correct comment on OCILobCreateTemporary + slari 09/08/98 - allow envh to receive error info also in CallbackReg/ + kkarun 09/02/98 - Change const to CONST + aroy 08/04/98 - add OCITerminate calls + nramakri 06/25/98 - remove CONST from some OCIPickler APIs + jiyang 06/22/98 - Fix a lint error + nmallava 06/08/98 - ociistemporary -> envhp + jhasenbe 05/27/98 - Remove definitions for U-Calls (Unicode) + nmallava 05/18/98 - add comments + sgollapu 05/19/98 - Change text to OraText + aroy 04/20/98 - merge forward 8.0.5 -> 8.1.3 + nbhatt 05/14/98 - aq listen call + lchidamb 03/02/98 - Client Notification prototypes + vyanaman 04/19/98 - System Timestamp + kkarun 04/17/98 - Add more Interval functions + vyanaman 04/17/98 - Fix min (proc error) + vyanaman 04/16/98 - Add get/set TZ + kkarun 04/13/98 - Add Datetime prototypes + rkasamse 04/13/98 - change OCIEnv* to dvoid* for context/memory cart serv + rkasamse 04/15/98 - chage pickler cart interface + slari 03/20/98 - change proto of OCIUserCallback + slari 02/17/98 - add OCIUserCallback + jiyang 04/02/98 - Accept both env and user handles for NLS + rkasamse 03/20/98 - remove prototypes for OCIMemoryDuration* functions. + tsaulys 03/20/98 - use environment or session handle + nmallava 04/09/98 - OCILobLocatorAssign + nmallava 04/07/98 - lobgetchunksize and writeappend apis + jhasenbe 04/06/98 - Add new interfaces for Unicode support + nmallava 03/17/98 - add interfaces + nmallava 03/16/98 - add open/close apis + nmallava 03/10/98 - add temporary lobs apis + sgollapu 07/10/97 - Add OCIReset + sgollapu 02/09/98 - OCI non-blocking + nramakri 01/16/98 - remove #ifdef NEVER clause for OCIExtract + rmurthy 01/08/98 - OCIContextGenerateKey: change ub1 to ub4 + ewaugh 12/18/97 - Turn type wrappers into functions. + skabraha 12/02/97 - adding OCIFile functions + rhwu 12/02/97 - add OCI Thread + nramakri 12/15/97 - move to core4 + nramakri 12/11/97 - modify OCIExtract prototype + ewaugh 12/10/97 - add OCIFormat prototypes + nmallava 12/17/97 - Add ilob open and close apis + rkasamse 12/03/97 - Change some of the function names for pickler cartrid + nramakri 11/12/97 - add OCIExtract prototypes + rkasamse 11/21/97 - add prototypes for memory cartridge services and cont + rkasamse 11/03/97 - Add pickler cartridge interfaces. + jiyang 11/11/97 - Add NLS service for cartridge + tanguyen 08/19/97 - + cxcheng 07/30/97 - replace OCISvcCtx with OCISvcCtx + schandra 06/25/97 - AQ OCI interface + bnainani 07/21/97 - add prototypes for Oracle XA extensions + esoyleme 05/13/97 - move failover callback prototype + skmishra 05/06/97 - stdc compiler fixes + skmishra 04/24/97 - C++ Compatibility changes + skotsovo 04/21/97 - make lob parameter names consistent + rwhitman 04/16/97 - Fix LOB prototypes - Olint OCI 8.0.3 + ramkrish 04/15/97 - Add free flag to OCILobFlushBuffer + dchatter 04/10/97 - add nzt.h inclusion + cxcheng 04/09/97 - change objnamp from CONST text* to dvoid* + cxcheng 04/08/97 - fix prototype of OCIDescribeAny() + skotsovo 03/31/97 - remove OCILobLocatorSize + skotsovo 03/27/97 - add OCILobLoadFromFile + bcchang 02/18/97 - Fix syntax error + dchatter 01/13/97 - fix comments on LOB calls + aroy 01/10/97 - remove ocilobfilecreate delete + sgollapu 12/27/96 - Correct OCILogon prototype + dchatter 01/04/97 - comments to describe the functions + sgollapu 11/25/96 - Change OCILobFileIsExistent + schandra 11/18/96 - Remove xa.h include + sgollapu 11/09/96 - Change prototype of OCIDescribeAny + dchatter 10/31/96 - delete CONST from lob write cb fn + dchatter 10/30/96 - more changes + dchatter 10/26/96 - lob/file long name corrections + slari 10/16/96 - delete unused calls + rwessman 10/29/96 - Fixed OCISecurityGetIdentity prototype + bcchang 10/25/96 - Fix syntax error + sgollapu 10/22/96 - Add OCILogon and OCILogoff + rwessman 10/16/96 - Added cryptographic and digital signature functions + sgollapu 10/10/96 - Add ocibdp and ocibdn + rxgovind 10/07/96 - add oci file calls + skotsovo 10/01/96 - move orl lob fnts to oci + skotsovo 09/20/96 - in OCILobGetLength(), remove the 'isnull' parameter. + aroy 08/29/96 - change prototype for Nchar Lob support + dchatter 08/21/96 - OCIResultSetToStmt prototype change + sthakur 08/14/96 - add OCIParamSet + schandra 07/26/96 - TX OCI return values - sb4->sword + aroy 07/17/96 - terminology change: OCILobLocator => OCILobLocator + dchatter 07/01/96 - create ANSI prototypes + dchatter 07/01/96 - Creation + +*/ + + +#ifndef OCIAP_ORACLE +# define OCIAP_ORACLE + +# ifndef ORATYPES +# include +# endif + +#ifndef ORASTDARG +#include +#define ORASTDARG +#endif + +#ifndef OCIDFN +#include +#endif + +#ifndef NZT_ORACLE +#include +#endif /* NZT_ORACLE */ + +#ifndef OCI_ORACLE +#include +#endif + +#ifndef ORT_ORACLE +#include +#endif + + + +/*--------------------------------------------------------------------------- + PUBLIC TYPES AND CONSTANTS + ---------------------------------------------------------------------------*/ + + +/*--------------------------------------------------------------------------- + PRIVATE TYPES AND CONSTANTS + ---------------------------------------------------------------------------*/ + + +/*--------------------------------------------------------------------------- + PUBLIC FUNCTIONS + ---------------------------------------------------------------------------*/ + +/***************************************************************************** + DESCRIPTION +****************************************************************************** +Note: the descriptions of the functions are alphabetically arranged. Please +maintain the arrangement when adding a new function description. The actual +prototypes are below this comment section and donot follow any alphabetical +ordering. + + +--------------------------------OCIAttrGet------------------------------------ + +OCIAttrGet() +Name +OCI Attribute Get +Purpose +This call is used to get a particular attribute of a handle. +Syntax +sword OCIAttrGet ( const void *trgthndlp, + ub4 trghndltyp, + void *attributep, + ub4 *sizep, + ub4 attrtype, + OCIError *errhp ); +Comments +This call is used to get a particular attribute of a handle. +See Appendix B, "Handle Attributes", for a list of handle types and their +readable attributes. +Parameters +trgthndlp (IN) - is the pointer to a handle type. +trghndltyp (IN) - is the handle type. +attributep (OUT) - is a pointer to the storage for an attribute value. The +attribute value is filled in. +sizep (OUT) - is the size of the attribute value. +This can be passed in as NULL for most parameters as the size is well known. +For text* parameters, a pointer to a ub4 must be passed in to get the length +of the string. +attrtype (IN) - is the type of attribute. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +Related Functions +OCIAttrSet() + +--------------------------------OCIAttrSet------------------------------------ + + +OCIAttrSet() +Name +OCI Attribute Set +Purpose +This call is used to set a particular attribute of a handle or a descriptor. +Syntax +sword OCIAttrSet ( void *trgthndlp, + ub4 trghndltyp, + void *attributep, + ub4 size, + ub4 attrtype, + OCIError *errhp ); +Comments +This call is used to set a particular attribute of a handle or a descriptor. +See Appendix B for a list of handle types and their writeable attributes. +Parameters +trghndlp (IN/OUT) - the pointer to a handle type whose attribute gets +modified. +trghndltyp (IN/OUT) - is the handle type. +attributep (IN) - a pointer to an attribute value. +The attribute value is copied into the target handle. If the attribute value +is a pointer, then only the pointer is copied, not the contents of the pointer. +size (IN) - is the size of an attribute value. This can be passed in as 0 for +most attributes as the size is already known by the OCI library. For text* +attributes, a ub4 must be passed in set to the length of the string. +attrtype (IN) - the type of attribute being set. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +Related Functions +OCIAttrGet() + + + +--------------------------------OCIBindArrayOfStruct-------------------------- + + + +OCIBindArrayOfStruct() +Name +OCI Bind for Array of Structures +Purpose +This call sets up the skip parameters for a static array bind. +Syntax +sword OCIBindArrayOfStruct ( OCIBind *bindp, + OCIError *errhp, + ub4 pvskip, + ub4 indskip, + ub4 alskip, + ub4 rcskip ); +Comments +This call sets up the skip parameters necessary for a static array bind. +This call follows a call to OCIBindByName() or OCIBindByPos(). The bind +handle returned by that initial bind call is used as a parameter for the +OCIBindArrayOfStruct() call. +For information about skip parameters, see the section "Arrays of Structures" +on page 4-16. +Parameters +bindp (IN) - the handle to a bind structure. +errhp (IN) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +pvskip (IN) - skip parameter for the next data value. +indskip (IN) - skip parameter for the next indicator value or structure. +alskip (IN) - skip parameter for the next actual length value. +rcskip (IN) - skip parameter for the next column-level return code value. +Related Functions +OCIAttrGet() + + +--------------------------------OCIBindByName--------------------------------- + +OCIBindByName() +Name +OCI Bind by Name +Purpose +Creates an association between a program variable and a placeholder in a SQL +statement or PL/SQL block. +Syntax +sword OCIBindByName ( + OCIStmt *stmtp, + OCIBind **bindp, + OCIError *errhp, + const OraText *placeholder, + sb4 placeh_len, + void *valuep, + sb4 value_sz, + ub2 dty, + void *indp, + ub2 *alenp, + ub2 *rcodep, + ub4 maxarr_len, + ub4 *curelep, + ub4 mode ); +Description +This call is used to perform a basic bind operation. The bind creates an +association between the address of a program variable and a placeholder in a +SQL statement or PL/SQL block. The bind call also specifies the type of data +which is being bound, and may also indicate the method by which data will be +provided at runtime. +This function also implicitly allocates the bind handle indicated by the bindp +parameter. +Data in an OCI application can be bound to placeholders statically or +dynamically. Binding is static when all the IN bind data and the OUT bind +buffers are well-defined just before the execute. Binding is dynamic when the +IN bind data and the OUT bind buffers are provided by the application on +demand at execute time to the client library. Dynamic binding is indicated by +setting the mode parameter of this call to OCI_DATA_AT_EXEC. +Related Functions: For more information about dynamic binding, see +the section "Runtime Data Allocation and Piecewise Operations" on +page 5-16. +Both OCIBindByName() and OCIBindByPos() take as a parameter a bind handle, +which is implicitly allocated by the bind call A separate bind handle is +allocated for each placeholder the application is binding. +Additional bind calls may be required to specify particular attributes +necessary when binding certain data types or handling input data in certain +ways: +If arrays of structures are being utilized, OCIBindArrayOfStruct() must +be called to set up the necessary skip parameters. +If data is being provided dynamically at runtime, and the application +will be using user-defined callback functions, OCIBindDynamic() must +be called to register the callbacks. +If a named data type is being bound, OCIBindObject() must be called to +specify additional necessary information. +Parameters +stmth (IN/OUT) - the statement handle to the SQL or PL/SQL statement +being processed. +bindp (IN/OUT) - a pointer to a pointer to a bind handle which is implicitly +allocated by this call. The bind handle maintains all the bind information +for this particular input value. The handle is feed implicitly when the +statement handle is deallocated. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +placeholder (IN) - the placeholder attributes are specified by name if +ocibindn() is being called. +placeh_len (IN) - the length of the placeholder name specified in placeholder. +valuep (IN/OUT) - a pointer to a data value or an array of data values of the +type specified in the dty parameter. An array of data values can be specified +for mapping into a PL/SQL table or for providing data for SQL multiple-row +operations. When an array of bind values is provided, this is called an array +bind in OCI terms. Additional attributes of the array bind (not bind to a +column of ARRAY type) are set up in OCIBindArrayOfStruct() call. +For a REF, named data type bind, the valuep parameter is used only for IN +bind data. The pointers to OUT buffers are set in the pgvpp parameter +initialized by OCIBindObject(). For named data type and REF binds, the bind +values are unpickled into the Object Cache. The OCI object navigational calls +can then be used to navigate the objects and the refs in the Object Cache. +If the OCI_DATA_AT_EXEC mode is specified in the mode parameter, valuep +is ignored for all data types. OCIBindArrayOfStruct() cannot be used and +OCIBindDynamic() must be invoked to provide callback functions if desired. +value_sz (IN) - the size of a data value. In the case of an array bind, this is +the maximum size of any element possible with the actual sizes being specified +in the alenp parameter. +If the OCI_DATA_AT_EXEC mode is specified, valuesz defines the maximum +size of the data that can be ever provided at runtime for data types other than +named data types or REFs. +dty (IN) - the data type of the value(s) being bound. Named data types +(SQLT_NTY) and REFs (SQLT_REF) are valid only if the application has been +initialized in object mode. For named data types, or REFs, additional calls +must be made with the bind handle to set up the datatype-specific attributes. +indp (IN/OUT) - pointer to an indicator variable or array. For scalar data +types, this is a pointer to sb2 or an array of sb2s. For named data types, +this pointer is ignored and the actual pointer to the indicator structure or +an array of indicator structures is initialized by OCIBindObject(). +Ignored for dynamic binds. +See the section "Indicator Variables" on page 2-43 for more information about +indicator variables. +alenp (IN/OUT) - pointer to array of actual lengths of array elements. Each +element in alenp is the length of the data in the corresponding element in the +bind value array before and after the execute. This parameter is ignored for +dynamic binds. +rcodep (OUT) - pointer to array of column level return codes. This parameter +is ignored for dynamic binds. +maxarr_len (IN) - the maximum possible number of elements of type dty in a +PL/SQL binds. This parameter is not required for non-PL/SQL binds. If +maxarr_len is non-zero, then either OCIBindDynamic() or +OCIBindArrayOfStruct() can be invoked to set up additional bind attributes. +curelep(IN/OUT) - a pointer to the actual number of elements. This parameter +is only required for PL/SQL binds. +mode (IN) - the valid modes for this parameter are: +OCI_DEFAULT. This is default mode. +OCI_DATA_AT_EXEC. When this mode is selected, the value_sz +parameter defines the maximum size of the data that can be ever +provided at runtime. The application must be ready to provide the OCI +library runtime IN data buffers at any time and any number of times. +Runtime data is provided in one of the two ways: +callbacks using a user-defined function which must be registered +with a subsequent call to OCIBindDynamic(). +a polling mechanism using calls supplied by the OCI. This mode +is assumed if no callbacks are defined. +For more information about using the OCI_DATA_AT_EXEC mode, see +the section "Runtime Data Allocation and Piecewise Operations" on +page 5-16. +When the allocated buffers are not required any more, they should be +freed by the client. +Related Functions +OCIBindDynamic(), OCIBindObject(), OCIBindArrayOfStruct(), OCIAttrGet() + + + +-------------------------------OCIBindByPos----------------------------------- + + +OCIBindByPos() +Name +OCI Bind by Position +Purpose +Creates an association between a program variable and a placeholder in a SQL +statement or PL/SQL block. +Syntax +sword OCIBindByPos ( + OCIStmt *stmtp, + OCIBind **bindp, + OCIError *errhp, + ub4 position, + void *valuep, + sb4 value_sz, + ub2 dty, + void *indp, + ub2 *alenp, + ub2 *rcodep, + ub4 maxarr_len, + ub4 *curelep, + ub4 mode); + +Description +This call is used to perform a basic bind operation. The bind creates an +association between the address of a program variable and a placeholder in a +SQL statement or PL/SQL block. The bind call also specifies the type of data +which is being bound, and may also indicate the method by which data will be +provided at runtime. +This function also implicitly allocates the bind handle indicated by the bindp +parameter. +Data in an OCI application can be bound to placeholders statically or +dynamically. Binding is static when all the IN bind data and the OUT bind +buffers are well-defined just before the execute. Binding is dynamic when the +IN bind data and the OUT bind buffers are provided by the application on +demand at execute time to the client library. Dynamic binding is indicated by +setting the mode parameter of this call to OCI_DATA_AT_EXEC. +Related Functions: For more information about dynamic binding, see +the section "Runtime Data Allocation and Piecewise Operations" on +page 5-16 +Both OCIBindByName() and OCIBindByPos() take as a parameter a bind handle, +which is implicitly allocated by the bind call A separate bind handle is +allocated for each placeholder the application is binding. +Additional bind calls may be required to specify particular attributes +necessary when binding certain data types or handling input data in certain +ways: +If arrays of structures are being utilized, OCIBindArrayOfStruct() must +be called to set up the necessary skip parameters. +If data is being provided dynamically at runtime, and the application +will be using user-defined callback functions, OCIBindDynamic() must +be called to register the callbacks. +If a named data type is being bound, OCIBindObject() must be called to +specify additional necessary information. +Parameters +stmth (IN/OUT) - the statement handle to the SQL or PL/SQL statement +being processed. +bindp (IN/OUT) - a pointer to a pointer to a bind handle which is implicitly +allocated by this call. The bind handle maintains all the bind information +for this particular input value. The handle is feed implicitly when the +statement handle is deallocated. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +position (IN) - the placeholder attributes are specified by position if +ocibindp() is being called. +valuep (IN/OUT) - a pointer to a data value or an array of data values of the +type specified in the dty parameter. An array of data values can be specified +for mapping into a PL/SQL table or for providing data for SQL multiple-row +operations. When an array of bind values is provided, this is called an array +bind in OCI terms. Additional attributes of the array bind (not bind to a +column of ARRAY type) are set up in OCIBindArrayOfStruct() call. +For a REF, named data type bind, the valuep parameter is used only for IN +bind data. The pointers to OUT buffers are set in the pgvpp parameter +initialized by OCIBindObject(). For named data type and REF binds, the bind +values are unpickled into the Object Cache. The OCI object navigational calls +can then be used to navigate the objects and the refs in the Object Cache. +If the OCI_DATA_AT_EXEC mode is specified in the mode parameter, valuep +is ignored for all data types. OCIBindArrayOfStruct() cannot be used and +OCIBindDynamic() must be invoked to provide callback functions if desired. +value_sz (IN) - the size of a data value. In the case of an array bind, this is +the maximum size of any element possible with the actual sizes being specified +in the alenp parameter. +If the OCI_DATA_AT_EXEC mode is specified, valuesz defines the maximum +size of the data that can be ever provided at runtime for data types other than +named data types or REFs. +dty (IN) - the data type of the value(s) being bound. Named data types +(SQLT_NTY) and REFs (SQLT_REF) are valid only if the application has been +initialized in object mode. For named data types, or REFs, additional calls +must be made with the bind handle to set up the datatype-specific attributes. +indp (IN/OUT) - pointer to an indicator variable or array. For scalar data +types, this is a pointer to sb2 or an array of sb2s. For named data types, +this pointer is ignored and the actual pointer to the indicator structure or +an array of indicator structures is initialized by OCIBindObject(). Ignored +for dynamic binds. +See the section "Indicator Variables" on page 2-43 for more information about +indicator variables. +alenp (IN/OUT) - pointer to array of actual lengths of array elements. Each +element in alenp is the length of the data in the corresponding element in the +bind value array before and after the execute. This parameter is ignored for +dynamic binds. +rcodep (OUT) - pointer to array of column level return codes. This parameter +is ignored for dynamic binds. +maxarr_len (IN) - the maximum possible number of elements of type dty in a +PL/SQL binds. This parameter is not required for non-PL/SQL binds. If +maxarr_len is non-zero, then either OCIBindDynamic() or +OCIBindArrayOfStruct() can be invoked to set up additional bind attributes. +curelep(IN/OUT) - a pointer to the actual number of elements. This parameter +is only required for PL/SQL binds. +mode (IN) - the valid modes for this parameter are: +OCI_DEFAULT. This is default mode. +OCI_DATA_AT_EXEC. When this mode is selected, the value_sz +parameter defines the maximum size of the data that can be ever +provided at runtime. The application must be ready to provide the OCI +library runtime IN data buffers at any time and any number of times. +Runtime data is provided in one of the two ways: +callbacks using a user-defined function which must be registered +with a subsequent call to OCIBindDynamic() . +a polling mechanism using calls supplied by the OCI. This mode +is assumed if no callbacks are defined. +For more information about using the OCI_DATA_AT_EXEC mode, see +the section "Runtime Data Allocation and Piecewise Operations" on +page 5-16. +When the allocated buffers are not required any more, they should be +freed by the client. +Related Functions +OCIBindDynamic(), OCIBindObject(), OCIBindArrayOfStruct(), OCIAttrGet() + + + +-------------------------------OCIBindDynamic--------------------------------- + +OCIBindDynamic() +Name +OCI Bind Dynamic Attributes +Purpose +This call is used to register user callbacks for dynamic data allocation. +Syntax +sword OCIBindDynamic( OCIBind *bindp, + OCIError *errhp, + void *ictxp, + OCICallbackInBind (icbfp)( + void *ictxp, + OCIBind *bindp, + ub4 iter, + ub4 index, + void **bufpp, + ub4 *alenp, + ub1 *piecep, + void **indp ), + void *octxp, + OCICallbackOutBind (ocbfp)( + void *octxp, + OCIBind *bindp, + ub4 iter, + ub4 index, + void **bufp, + ub4 **alenpp, + ub1 *piecep, + void **indpp, + ub2 **rcodepp) ); +Comments +This call is used to register user-defined callback functions for providing +data for an UPDATE or INSERT if OCI_DATA_AT_EXEC mode was specified in a +previous call to OCIBindByName() or OCIBindByPos(). +The callback function pointers must return OCI_CONTINUE if it the call is +successful. Any return code other than OCI_CONTINUE signals that the client +wishes to abort processing immediately. +For more information about the OCI_DATA_AT_EXEC mode, see the section +"Runtime Data Allocation and Piecewise Operations" on page 5-16. +Parameters +bindp (IN/OUT) - a bind handle returned by a call to OCIBindByName() or +OCIBindByPos(). +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +ictxp (IN) - the context pointer required by the call back function icbfp. +icbfp (IN) - the callback function which returns a pointer to the IN bind +value or piece at run time. The callback takes in the following parameters. +ictxp (IN/OUT) - the context pointer for this callback function. +bindp (IN) - the bind handle passed in to uniquely identify this bind +variable. +iter (IN) - 1-based execute iteration value. +index (IN) - index of the current array, for an array bind. 1 based not +greater than curele parameter of the bind call. +index (IN) - index of the current array, for an array bind. This parameter +is 1-based, and may not be greater than curele parameter of the bind call. +bufpp (OUT) - the pointer to the buffer. +piecep (OUT) - which piece of the bind value. This can be one of the +following values - OCI_ONE_PIECE, OCI_FIRST_PIECE, +OCI_NEXT_PIECE and OCI_LAST_PIECE. +indp (OUT) - contains the indicator value. This is apointer to either an +sb2 value or a pointer to an indicator structure for binding named data +types. +indszp (OUT) - contains the indicator value size. A pointer containing +the size of either an sb2 or an indicator structure pointer. +octxp (IN) - the context pointer required by the callback function ocbfp. +ocbfp (IN) - the callback function which returns a pointer to the OUT bind +value or piece at run time. The callback takes in the following parameters. +octxp (IN/OUT) - the context pointer for this call back function. +bindp (IN) - the bind handle passed in to uniquely identify this bind +variable. +iter (IN) - 1-based execute iteration value. +index (IN) - index of the current array, for an array bind. This parameter +is 1-based, and must not be greater than curele parameter of the bind call. +bufpp (OUT) - a pointer to a buffer to write the bind value/piece. +buflp (OUT) - returns the buffer size. +alenpp (OUT) - a pointer to a storage for OCI to fill in the size of the bind +value/piece after it has been read. +piecep (IN/OUT) - which piece of the bind value. It will be set by the +library to be one of the following values - OCI_ONE_PIECE or +OCI_NEXT_PIECE. The callback function can leave it unchanged or set +it to OCI_FIRST_PIECE or OCI_LAST_PIECE. By default - +OCI_ONE_PIECE. +indpp (OUT) - returns a pointer to contain the indicator value which +either an sb2 value or a pointer to an indicator structure for named data +types. +indszpp (OUT) - returns a pointer to return the size of the indicator +value which is either size of an sb2 or size of an indicator structure. +rcodepp (OUT) - returns a pointer to contains the return code. +Related Functions +OCIAttrGet() + + +---------------------------------OCIBindObject-------------------------------- + + +OCIBindObject() +Name +OCI Bind Object +Purpose +This function sets up additional attributes which are required for a named +data type (object) bind. +Syntax +sword OCIBindObject ( OCIBind *bindp, + OCIError *errhp, + const OCIType *type, + void **pgvpp, + ub4 *pvszsp, + void **indpp, + ub4 *indszp, ); +Comments +This function sets up additional attributes which binding a named data type +or a REF. An error will be returned if this function is called when the OCI +environment has been initialized in non-object mode. +This call takes as a paramter a type descriptor object (TDO) of datatype +OCIType for the named data type being defined. The TDO can be retrieved +with a call to OCITypeByName(). +If the OCI_DATA_AT_EXEC mode was specified in ocibindn() or ocibindp(), the +pointers to the IN buffers are obtained either using the callback icbfp +registered in the OCIBindDynamic() call or by the OCIStmtSetPieceInfo() call. +The buffers are dynamically allocated for the OUT data and the pointers to +these buffers are returned either by calling ocbfp() registered by the +OCIBindDynamic() or by setting the pointer to the buffer in the buffer passed +in by OCIStmtSetPieceInfo() called when OCIStmtExecute() returned +OCI_NEED_DATA. The memory of these client library- allocated buffers must be +freed when not in use anymore by using the OCIObjectFreee() call. +Parameters +bindp ( IN/OUT) - the bind handle returned by the call to OCIBindByName() +or OCIBindByPos(). +errhp ( IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +type ( IN) - points to the TDO which describes the type of the program +variable being bound. Retrieved by calling OCITypeByName(). +pgvpp ( IN/OUT) - points to a pointer to the program variable buffer. For an +array, pgvpp points to an array of pointers. When the bind variable is also an +OUT variable, the OUT Named Data Type value or REF is allocated +(unpickled) in the Object Cache, and a pointer to the value or REF is returned, +At the end of execute, when all OUT values have been received, pgvpp points +to an array of pointer(s) to these newly allocated named data types in the +object cache. +pgvpp is ignored if the OCI_DATA_AT_EXEC mode is set. Then the Named +Data Type buffers are requested at runtime. For static array binds, skip +factors may be specified using the OCIBindArrayOfStruct() call. The skip +factors are used to compute the address of the next pointer to the value, the +indicator structure and their sizes. +pvszsp ( IN/OUT) - points to the size of the program variable. The size of the +named data type is not required on input. For an array, pvszsp is an array of +ub4s. On return, for OUT bind variables, this points to size(s) of the Named +Data Types and REFs received. pvszsp is ignored if the OCI_DATA_AT_EXEC +mode is set. Then the size of the buffer is taken at runtime. +indpp ( IN/OUT) - points to a pointer to the program variable buffer +containing the parallel indicator structure. For an array, points to an array +of pointers. When the bind variable is also an OUT bind variable, memory is +allocated in the object cache, to store the unpickled OUT indicator values. At +the end of the execute when all OUT values have been received, indpp points +to the pointer(s) to these newly allocated indicator structure(s). +indpp is ignored if the OCI_DATA_AT_EXEC mode is set. Then the indicator +is requested at runtime. +indszp ( IN/OUT) - points to the size of the IN indicator structure program +variable. For an array, it is an array of sb2s. On return for OUT bind +variables, this points to size(s) of the received OUT indicator structures. +indszp is ignored if the OCI_DATA_AT_EXEC mode is set. Then the indicator +size is requested at runtime. +Related Functions +OCIAttrGet() + + + +----------------------------------OCIBreak------------------------------------ + + +OCIBreak() +Name +OCI Break +Purpose +This call performs an immediate (asynchronous) abort of any currently +executing OCI function that is associated with a server . +Syntax +sword OCIBreak ( void *hndlp, + OCIError *errhp); +Comments +This call performs an immediate (asynchronous) abort of any currently +executing OCI function that is associated with a server. It is normally used +to stop a long-running OCI call being processed on the server. +This call can take either the service context handle or the server context +handle as a parameter to identify the function to be aborted. +Parameters +hndlp (IN) - the service context handle or the server context handle. +errhp (IN) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +Related Functions + +-----------------------------OCIConnectionPoolCreate -------------------------- +Name: +OCIConnectionPoolCreate + +Purpose: +Creates the connections in the pool + +Syntax: +OCIConnectionPoolCreate (OCIEnv *envhp, OCIError *errhp, OCICPool *poolhp, + OraText **poolName, sb4 *poolNameLen, + const Oratext *dblink, sb4 dblinkLen, + ub4 connMin, ub4 connMax, ub4 connIncr, + const OraText *poolUsername, sb4 poolUserLen, + const OraText *poolPassword, sb4 poolPassLen, + ub4 mode) +Comments: +This call is used to create a connection pool. conn_min connections +to the database are started on calling OCIConnectionPoolCreate. + +Parameters: +envhp (IN/OUT) - A pointer to the environment where the Conencton Pool + is to be created +errhp (IN/OUT) - An error handle which can be passed to OCIErrorGet(). +poolhp (IN/OUT) - An uninitialiazed pool handle. +poolName (OUT) - The connection pool name. +poolNameLen (OUT) - The length of the connection pool name +dblink (IN/OUT) - Specifies the database(server) to connect. This will also + be used as the default pool name. +dblinkLen (IN) - The length of the string pointed to by dblink. +connMin (IN) - Specifies the minimum number of connections in the + Connection Pool at any instant. + connMin number of connections are started when + OCIConnectionPoolCreate() is called. +connMax (IN) - Specifies the maximum number of connections that can be + opened to the database. Once this value is reached, no + more connections are opened. +connIncr (IN) - Allows application to set the next increment for + connections to be opened to the database if the current + number of connections are less than conn_max. +poolUsername (IN/OUT) - Connection pooling requires an implicit proxy + session and this attribute provides a username + for that session. +poolUserLen (IN) - This represents the length of pool_username. +poolPassword (IN/OUT) - The password for the parameter pool_username passed + above. +poolPassLen (IN) - This represents the length of pool_password. + +mode (IN) - The modes supported are OCI_DEFAULT and +OCI_CPOOL_REINITIALIZE + +Related Functions +OCIConnectionPoolDestroy() + +--------------------------------------------------------------------------- + +----------------------------OCIConnectionPoolDestroy------------------------- +Name: +OCIConnectionPoolDestroy + +Purpose: +Terminates the connections in the pool + +Syntax: +OCIConnectionPoolDestroy (OCICPool *poolhp, OCIError *errhp, ub4 mode) + +Comments: +On calling OCIConnectionPoolDestroy, all the open connections in the pool +are closed and the pool is destroyed. + +Parameters: +poolhp (IN/OUT) - An initialiazed pool handle. +errhp (IN/OUT) - An error handle which can be passed to OCIErrorGet(). +mode (IN) - Currently, OCIConnectionPoolDestroy() will support only + the OCI_DEFAULT mode. + +Related Functions: +OCIConnectionPoolCreate() + +----------------------------------------------------------------------------- +----------------------------OCISessionPoolCreate----------------------------- +Name: +OCISessionPoolCreate + +Purpose: +Creates the sessions in the session pool. + +Syntax: +sword OCISessionPoolCreate (OCIEnv *envhp, OCIError *errhp, OCISpool *spoolhp, + OraText **poolName, ub4 *poolNameLen, + const OraText *connStr, ub4 connStrLen, + ub4 sessMin, ub4 sessMax, ub4 sessIncr, + OraText *userid, ub4 useridLen, + OraText *password, ub4 passwordLen, + ub4 mode) + +Comments: +When OCISessionPoolCreate is called, a session pool is initialized for +the associated environment and the database specified by the +connStr parameter. This pool is named uniquely and the name +is returned to the user in the poolname parameter. + +Parameters: +envhp (IN/OUT) - A pointer to the environment handle in which the session + pool needs to be created. +errhp (IN/OUT) - An error handle which can be passed to OCIErrorGet(). +spoolhp (IN/OUT) - A pointer to the session pool handle that is created. +poolName (OUT) - Session pool name returned to the user. +poolNameLen (OUT) - Length of the PoolName +connStr (IN) - The TNS alias of the database to connect to. +connStrLen (IN) - Length of the connStr. +sessMin (IN) - Specifies the minimum number of sessions in the Session Pool. + These are the number of sessions opened in the beginning, if + in Homogeneous mode. Else, the parameter is ignored. +sessMax (IN) - Specifies the maximum number of sessions in the Session Pool. + Once this value is reached, no more sessions are opened, + unless the OCI_ATTR_SPOOL_FORCEGET is set. +userid (IN) - Specifies the userid with which to start up the sessions. +useridLen (IN) - Length of userid. +password (IN) - Specifies the password for the corresponding userid. +passwordLen (IN) - Specifies the length of the password +mode(IN) - May be OCI_DEFAULT, OCI_SPC_SPOOL_REINITIALIZE, or + OCI_SPC_SPOOL_HOMOGENEOUS. + +Returns: +SUCCESS - If pool could be allocated and created successfully. +ERROR - If above conditions could not be met. + +Related Functions: +OCISessionPoolDestroy() +----------------------------------------------------------------------------- +-----------------------------OCISessionPoolDestroy--------------------------- +Name: +OCISessionPoolDestroy + +Purpose: +Terminates all the sessions in the session pool. + +Syntax: +sword OCISessionPoolDestroy (OCISPool *spoolhp, OCIError *errhp, ub4 mode) + +Comments: +spoolhp (IN/OUT) - The pool handle of the session pool to be destroyed. +errhp (IN/OUT) - An error handle which can be passed to OCIErrorGet(). +mode (IN) - Currently only OCI_DEFAULT mode is supported. + +Returns: +SUCCESS - All the sessions could be closed. +ERROR - If the above condition is not met. + +Related Functions: +OCISessionPoolCreate() +----------------------------------------------------------------------------- +-------------------------------OCISessionGet--------------------------------- +Name: +OCISessionGet + +Purpose: +Get a session. This could be from a session pool, connection pool or +a new standalone session. + +Syntax: +sword OCISessionGet(OCIenv *envhp, OCIError *errhp, OCISvcCtx **svchp, + OCIAuthInfo *authhp, + OraText *poolName, ub4 poolName_len, + const OraText *tagInfo, ub4 tagInfo_len, + OraText **retTagInfo, ub4 *retTagInfo_len, + boolean *found, + ub4 mode) + +Comments: +envhp (IN/OUT) - OCI environment handle. +errhp (IN/OUT) - OCI error handle to be passed to OCIErrorGet(). +svchp (IN/OUT) - Address of an OCI service context pointer. This will be + filled with a server and session handle, attached to the + pool. +authhp (IN/OUT) - OCI Authentication Information handle. +poolName (IN) - This indicates the session/connection pool to get the + session/connection from in the OCI_SPOOL/OCI_CPOOL mode. + In the OCI_DEFAULT mode it refers to the connect string. +poolName_len (IN) - length of poolName. +tagInfo (IN) - indicates the tag of the session that the user wants. If the + user wants a default session, he must specify a NULL here. + Only used for Session Pooling. +tagInfo_len (IN) - the length of tagInfo. +retTagInfo (OUT) - This indicates the type of session that is returned to + the user. Only used for Session Pooling. +retTagInfo_len (OUT) - the length of retTagInfo. +found (OUT) - set to true if the user gets a session he had requested, else + set to false. Only used for Session Pooling. +mode (IN) - The supported modes are OCI_DEFAULT, OCI_CRED_PROXY and + OCI_GET_SPOOL_MATCHANY, OCI_SPOOL and OCI_CPOOL. OCI_SPOOL and + OCI_CPOOL are mutually exclusive. + +Returns: +SUCCESS - if a session was successfully returned into svchp. +SUCCESS_WITH_INFO - if a session was successfully returned into svchp and the + total number of sessions > maxsessions. Only valid for + Session Pooling. +ERROR - If a session could not be retrieved. + +Related Functions: +OCISessionRelease() +----------------------------------------------------------------------------- +---------------------------OCISessionRelease--------------------------------- +Name: +OCISessionRelease + +Purpose: +Release the session. + +Syntax: +sword OCISessionRelease ( OCISvcCtx *svchp, OCIError *errhp, + OraText *tag, ub4 tag_len, + ub4 mode); + +Comments: +svchp (IN/OUT) - The service context associated with the session/connection. +errhp (IN/OUT) - OCI error handle to be passed to OCIErrorGet(). +tag (IN) - Only used for Session Pooling. + This parameter will be ignored unless mode OCI_RLS_SPOOL_RETAG is + specified. In this case, the session is labelled with this tag and + returned to the pool. If this is NULL, then the session is untagged. +tag_len (IN) - Length of the tag. This is ignored unless mode + OCI_RLS_SPOOL_RETAG is set. +mode (IN) - The supported modes are OCI_DEFAULT, OCI_RLS_SPOOL_DROPSESS, + OCI_RLS_SPOOL_RETAG. The last 2 are only valid for Session Pooling. + When OCI_RLS_SPOOL_DROPSESS is specified, the session + will be removed from the session pool. If OCI_RLS_SPOOL_RETAG + is set, the tag on the session will be altered. If this mode is + not set, the tag and tag_len parameters will be ignored. + +Returns: +ERROR - If the session could not be released successfully. +SUCCESS - In all other cases. + +Related Functions: +OCISessionGet(). +----------------------------------------------------------------------------- +------------------------------OCIDateTimeAssign -------------------------- +sword OCIDateTimeAssign(void *hndl, OCIError *err, const OCIDateTime *from, + OCIDateTime *to); +NAME: OCIDateTimeAssign - OCIDateTime Assignment +PARAMETERS: +hndl (IN) - Session/Env handle. +err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). +from (IN) - datetime to be assigned +to (OUT) - lhs of assignment +DESCRIPTION: + Performs date assignment. The type of the output will be same as that + of input + +------------------------------OCIDateTimeCheck---------------------------- +sword OCIDateTimeCheck(void *hndl, OCIError *err, const OCIDateTime *date, + ub4 *valid ); +NAME: OCIDateTimeCheck - OCIDateTime CHecK if the given date is valid +PARAMETERS: +hndl (IN) - Session/Env handle. +err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). +date (IN) - date to be checked +valid (OUT) - returns zero for a valid date, otherwise + the ORed combination of all error bits specified below: + Macro name Bit number Error + ---------- ---------- ----- + OCI_DATE_INVALID_DAY 0x1 Bad day + OCI_DATE_DAY_BELOW_VALID 0x2 Bad DAy Low/high bit (1=low) + OCI_DATE_INVALID_MONTH 0x4 Bad MOnth + OCI_DATE_MONTH_BELOW_VALID 0x8 Bad MOnth Low/high bit (1=low) + OCI_DATE_INVALID_YEAR 0x10 Bad YeaR + OCI_DATE_YEAR_BELOW_VALID 0x20 Bad YeaR Low/high bit (1=low) + OCI_DATE_INVALID_HOUR 0x40 Bad HouR + OCI_DATE_HOUR_BELOW_VALID 0x80 Bad HouR Low/high bit (1=low) + OCI_DATE_INVALID_MINUTE 0x100 Bad MiNute + OCI_DATE_MINUTE_BELOW_VALID 0x200 Bad MiNute Low/high bit (1=low) + OCI_DATE_INVALID_SECOND 0x400 Bad SeCond + OCI_DATE_SECOND_BELOW_VALID 0x800 bad second Low/high bit (1=low) + OCI_DATE_DAY_MISSING_FROM_1582 0x1000 Day is one of those "missing" + from 1582 + OCI_DATE_YEAR_ZERO 0x2000 Year may not equal zero + OCI_DATE_INVALID_TIMEZONE 0x4000 Bad Timezone + OCI_DATE_INVALID_FORMAT 0x8000 Bad date format input + + So, for example, if the date passed in was 2/0/1990 25:61:10 in + (month/day/year hours:minutes:seconds format), the error returned + would be OCI_DATE_INVALID_DAY | OCI_DATE_DAY_BELOW_VALID | + OCI_DATE_INVALID_HOUR | OCI_DATE_INVALID_MINUTE + +DESCRIPTION: + Check if the given date is valid. +RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + 'date' and 'valid' pointers are NULL pointers + +------------------------------- OCIDateTimeCompare---------------------------- +sword OCIDateTimeCompare(void *hndl, OCIError *err, const OCIDateTime *date1, + const OCIDateTime *date2, sword *result ); +NAME: OCIDateTimeCompare - OCIDateTime CoMPare dates +PARAMETERS: +hndl (IN) - Session/Env handle. +err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). +date1, date2 (IN) - dates to be compared +result (OUT) - comparison result, 0 if equal, -1 if date1 < date2, + 1 if date1 > date2 +DESCRIPTION: +The function OCIDateCompare compares two dates. It returns -1 if +date1 is smaller than date2, 0 if they are equal, and 1 if date1 is +greater than date2. +RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + invalid date + input dates are not mutually comparable + +------------------------------OCIDateTimeConvert---------------------- +sword OCIDateTimeConvert(void *hndl, OCIError *err, OCIDateTime *indate, + OCIDateTime *outdate); +NAME: OCIDateTimeConvert - Conversion between different DATETIME types +PARAMETERS: +hndl (IN) - Session/Env handle. +err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). +indate (IN) - pointer to input date +outdate (OUT) - pointer to output datetime +DESCRIPTION: Converts one datetime type to another. The result type is + the type of the 'outdate' descriptor. +RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + conversion not possible. + +---------------------------- OCIDateTimeFromText----------------------- +sword OCIDateTimeFromText(void *hndl, OCIError *err, const OraText *date_str, + size_t d_str_length, const OraText *fmt, ub1 fmt_length, + const OraText *lang_name, size_t lang_length, OCIDateTime *date ); +NAME: OCIDateTimeFromText - OCIDateTime convert String FROM Date +PARAMETERS: +hndl (IN) - Session/Env handle. If Session Handle is passed, the + conversion takes place in session NLS_LANGUAGE and + session NLS_CALENDAR, otherwise the default is used. +err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). +date_str (IN) - input string to be converted to Oracle date +d_str_length (IN) - size of the input string, if the length is -1 + then 'date_str' is treated as a null terminated string +fmt (IN) - conversion format; if 'fmt' is a null pointer, then + the string is expected to be in the default format for + the datetime type. +fmt_length (IN) - length of the 'fmt' parameter +lang_name (IN) - language in which the names and abbreviations of + days and months are specified, if null i.e. (OraText *)0, + the default language of session is used, +lang_length (IN) - length of the 'lang_name' parameter +date (OUT) - given string converted to date +DESCRIPTION: + Converts the given string to Oracle datetime type set in the + OCIDateTime descriptor according to the specified format. Refer to + "TO_DATE" conversion function described in "Oracle SQL Language + Reference Manual" for a description of format. +RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + invalid format + unknown language + invalid input string + +--------------------------- OCIDateTimeGetDate------------------------- +sword OCIDateTimeGetDate(void *hndl, OCIError *err, const OCIDateTime *date, + sb2 *year, ub1 *month, ub1 *day ); +NAME: OCIDateTimeGetDate - OCIDateTime Get Date (year, month, day) + portion of DATETIME. +PARAMETERS: +hndl (IN) - Session/Env handle. +err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). +datetime (IN) - Pointer to OCIDateTime +year (OUT) - year value +month (OUT) - month value +day (OUT) - day value + +--------------------------- OCIDateTimeGetTime ------------------------ +sword OCIDateTimeGetTime(void *hndl, OCIError *err, OCIDateTime *datetime, + ub1 *hour, ub1 *minute, ub1 *sec, ub4 *fsec); +NAME: OCIDateTimeGetTime - OCIDateTime Get Time (hour, min, second, + fractional second) of DATETIME. +PARAMETERS: +hndl (IN) - Session/Env handle. +err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). +datetime (IN) - Pointer to OCIDateTime +hour (OUT) - hour value +minute (OUT) - minute value +sec (OUT) - second value +fsec (OUT) - Fractional Second value + +--------------------------- OCIDateTimeGetTimeZoneOffset ---------------------- +sword OCIDateTimeGetTimeZoneOffset(void *hndl,OCIError *err,const + OCIDateTime *datetime,sb1 *hour,sb1 *minute); + +NAME: OCIDateTimeGetTimeZoneOffset - OCIDateTime Get TimeZone (hour, minute) + portion of DATETIME. +PARAMETERS: +hndl (IN) - Session/Env handle. +err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). +datetime (IN) - Pointer to OCIDateTime +hour (OUT) - TimeZone Hour value +minute (OUT) - TimeZone Minute value + +--------------------------- OCIDateTimeSysTimeStamp--------------------- +sword OCIDateTimeSysTimeStamp(void *hndl, OCIError *err, + OCIDateTime *sys_date ); + +NAME: OCIDateTimeSysTimeStamp - Returns system date/time as a TimeStamp with + timezone +PARAMETERS: +hndl (IN) - Session/Env handle. +err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). +sys_date (OUT) - Pointer to output timestamp + +DESCRIPTION: + Gets the system current date and time as a timestamp with timezone +RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + + +------------------------------OCIDateTimeIntervalAdd---------------------- +sword OCIDateTimeIntervalAdd(void *hndl, OCIError *err, OCIDateTime *datetime, + OCIInterval *inter, OCIDateTime *outdatetime); +NAME: OCIDateTimeIntervalAdd - Adds an interval to datetime +PARAMETERS: +hndl (IN) - Session/Env handle. +err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). +datetime (IN) - pointer to input datetime +inter (IN) - pointer to interval +outdatetime (IN) - pointer to output datetime. The output datetime + will be of same type as input datetime +DESCRIPTION: + Adds an interval to a datetime to produce a resulting datetime +RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if: + resulting date is before Jan 1, -4713 + resulting date is after Dec 31, 9999 + +------------------------------OCIDateTimeIntervalSub---------------------- +sword OCIDateTimeIntervalSub(void *hndl, OCIError *err, OCIDateTime *datetime, + OCIInterval *inter, OCIDateTime *outdatetime); +NAME: OCIDateTimeIntervalSub - Subtracts an interval from a datetime +PARAMETERS: +hndl (IN) - Session/Env handle. +err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). +datetime (IN) - pointer to input datetime +inter (IN) - pointer to interval +outdatetime (IN) - pointer to output datetime. The output datetime + will be of same type as input datetime +DESCRIPTION: + Subtracts an interval from a datetime and stores the result in a + datetime +RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if: + resulting date is before Jan 1, -4713 + resulting date is after Dec 31, 9999 + +--------------------------- OCIDateTimeConstruct------------------------- +sword OCIDateTimeConstruct(void *hndl,OCIError *err,OCIDateTime *datetime, + sb2 year,ub1 month,ub1 day,ub1 hour,ub1 min,ub1 sec,ub4 fsec, + OraText *timezone,size_t timezone_length); + +NAME: OCIDateTimeConstruct - Construct an OCIDateTime. Only the relevant + fields for the OCIDateTime descriptor types are used. +PARAMETERS: + hndl (IN) - Session/Env handle. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + datetime (IN) - Pointer to OCIDateTime + year (IN) - year value + month (IN) - month value + day (IN) - day value + hour (IN) - hour value + min (IN) - minute value + sec (IN) - second value + fsec (IN) - Fractional Second value + timezone (IN) - Timezone string + timezone_length(IN) - Length of timezone string + +DESCRIPTION: + Constructs a DateTime descriptor. The type of the datetime is the + type of the OCIDateTime descriptor. Only the relevant fields based + on the type are used. For Types with timezone, the date and time + fields are assumed to be in the local time of the specified timezone. + If timezone is not specified, then session default timezone is + assumed. +RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_ERROR if datetime is not valid. + +------------------------------OCIDateTimeSubtract----------------------- +sword OCIDateTimeSubtract(void *hndl, OCIError *err, OCIDateTime *indate1, + OCIDateTime *indate2, OCIInterval *inter); +NAME: OCIDateTimeSubtract - subtracts two datetimes to return an interval +PARAMETERS: +hndl (IN) - Session/Env handle. +err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). +indate1(IN) - pointer to subtrahend +indate2(IN) - pointer to minuend +inter (OUT) - pointer to output interval +DESCRIPTION: + Takes two datetimes as input and stores their difference in an + interval. The type of the interval is the type of the 'inter' + descriptor. +RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + datetimes are not comparable. + +--------------------------- OCIDateTimeToText-------------------------- +sword OCIDateTimeToText(void *hndl, OCIError *err, const OCIDateTime *date, + const OraText *fmt, ub1 fmt_length, ub1 fsprec, + const OraText *lang_name, size_t lang_length, + ub4 *buf_size, OraText *buf ); +NAME: OCIDateTimeToText - OCIDateTime convert date TO String +PARAMETERS: +hndl (IN) - Session/Env handle. If Session Handle is passed, the + conversion takes place in session NLS_LANGUAGE and + session NLS_CALENDAR, otherwise the default is used. +err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). +date (IN) - Oracle datetime to be converted +fmt (IN) - conversion format, if null string pointer (OraText*)0, then + the date is converted to a character string in the + default format for that type. +fmt_length (IN) - length of the 'fmt' parameter +fsprec (IN) - specifies the fractional second precision in which the + fractional seconds is returned. +lang_name (IN) - specifies the language in which the names and + abbreviations of months and days are returned; + default language of session is used if 'lang_name' + is null i.e. (OraText *)0 +lang_length (IN) - length of the 'nls_params' parameter +buf_size (IN/OUT) - size of the buffer; size of the resulting string + is returned via this parameter +buf (OUT) - buffer into which the converted string is placed +DESCRIPTION: + Converts the given date to a string according to the specified format. + Refer to "TO_DATE" conversion function described in + "Oracle SQL Language Reference Manual" for a description of format + and NLS arguments. The converted null-terminated date string is + stored in the buffer 'buf'. +RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + buffer too small + invalid format + unknown language + overflow error + +----------------------------OCIDateTimeGetTimeZoneName------------------------ +sword OCIDateTimeGetTimeZoneName(void *hndl, + OCIError *err, + const OCIDateTime *datetime, + ub1 *buf, + ub4 *buflen); +NAME OCIDateTimeGetTimeZoneName - OCI DateTime Get the Time Zone Name +PARAMETERS: +hndl (IN) - Session/Env handle. +err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). +datetime (IN) - Pointer to an OCIDateTime. +buf (OUT) - User allocated storage for name string. +buflen (IN/OUT) - length of buf on input, length of name on out +DESCRIPTION: + Returns either the timezone region name or the absolute hour and minute + offset. If the DateTime was created with a region id then the region + name will be returned in the buf. If the region id is zero, then the + hour and minute offset is returned as "[-]HH:MM". +RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + buffer too small + error retrieving timezone data + invalid region + invalid LdiDateTime type + +---------------------------------OCIDateTimeToArray---------------------------- +sword OCIDateTimeToArray(void *hndl, + OCIError *err, + const OCIDateTime *datetime, + const OCIInterval *reftz, + ub1 *outarray, + ub4 *len + ub1 *fsprec); +NAME OCIDateTimeToArray - OCI DateTime convert To Array format +PARAMETERS: +hndl (IN) - Session/Env handle. +err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). +datetime (IN) - Pointer to OCIDateTime to be converted. +outarray (OUT) - Result array storage +len (OUT) - pointer to length of outarray. +fsprec (IN) - Number of fractional seconds digits. +DESCRIPTION: + Returns an array representing the input DateTime descriptor. +RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + buffer too small + error retrieving timezone data + invalid region + invalid LdiDateTime type + +--------------------------------OCIDateTimeFromArray--------------------------- +sword OCIDateTimeFromArray(void *hndl, + OCIError *err, + ub1 *inarray, + ub4 len + ub1 type + OCIDateTime *datetime, + OCIInterval *reftz, + ub1 fsprec); +NAME OCIDateTimeFromArray - OCI DateTime convert From Array format +PARAMETERS: +hndl (IN) - Session/Env handle. +err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). +inarray (IN) - Pointer to input array representtion of DateTime +len (IN) - len of inarray. +type (IN) - One of SQLT_DATE, SQLT_TIME, SQLT_TIME_TZ, SQLT_TIMESTAMP, + SQLT_TIMESTAMP_TZ, or SQLT_TIMESTAMP_LTZ. +datetime (OUT) - Pointer to the result OCIDateTime. +reftz (IN) - timezone interval used with SQLT_TIMESTAMP_LTZ. +fsprec (IN) - fractionl seconds digits of precision (0-9). +DESCRIPTION: + Returns a pointer to an OCIDateTime of type type converted from + the inarray. +RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + buffer too small + error retrieving timezone data + invalid region + invalid LdiDateTime type + +----------------------------------OCIRowidToChar----------------------------- +Name +OCIRowidToChar + +Purpose +Converts physical/logical (universal) ROWID to chracter extended (Base 64) +representation into user provided buffer outbfp of length outbflp. After +execution outbflp contains amount of bytes converted.In case of truncation +error, outbflp contains required size to make this conversion successful +and returns ORA-1405. + +Syntax +sword OCIRowidToChar( OCIRowid *rowidDesc, + OraText *outbfp, + ub2 *outbflp, + OCIError *errhp) + +Comments +After this conversion, ROWID in character format can be bound using +OCIBindByPos or OCIBindByName call and used to query a row at a +desired ROWID. + +Parameters +rowidDesc (IN) - rowid DESCriptor which is allocated from OCIDescritorAlloc + and populated by a prior SQL statement execution +outbfp (OUT) - pointer to the buffer where converted rowid in character + representation is stored after successful execution. +outbflp (IN/OUT) - pointer to output buffer length variable. + Before execution (IN mode) *outbflp contains the size of + outbfp, after execution (OUT mode) *outbflp contains amount + of bytes converted. In an event of truncation during + conversion *outbflp contains the required length to make + conversion successful. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for + diagnostic information in the event of an error. + +------------------------------OCIDefineArrayOfStruct-------------------------- + + +OCIDefineArrayOfStruct() +Name +OCI Define for Array of Structures +Purpose +This call specifies additional attributes necessary for a static array define. +Syntax +sword OCIDefineArrayOfStruct ( OCIDefine *defnp, + OCIError *errhp, + ub4 pvskip, + ub4 indskip, + ub4 rlskip, + ub4 rcskip ); +Comments +This call specifies additional attributes necessary for an array define, +used in an array of structures (multi-row, multi-column) fetch. +For more information about skip parameters, see the section "Skip Parameters" +on page 4-17. +Parameters +defnp (IN) - the handle to the define structure which was returned by a call +to OCIDefineByPos(). +errhp (IN) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +pvskip (IN) - skip parameter for the next data value. +indskip (IN) - skip parameter for the next indicator location. +rlskip (IN) - skip parameter for the next return length value. +rcskip (IN) - skip parameter for the next return code. +Related Functions +OCIAttrGet() + + + + + +OCIDefineByPos() +Name +OCI Define By Position +Purpose +Associates an item in a select-list with the type and output data buffer. +Syntax +sb4 OCIDefineByPos ( + OCIStmt *stmtp, + OCIDefine **defnp, + OCIError *errhp, + ub4 position, + void *valuep, + sb4 value_sz, + ub2 dty, + void *indp, + ub2 *rlenp, + ub2 *rcodep, + ub4 mode ); +Comments +This call defines an output buffer which will receive data retreived from +Oracle. The define is a local step which is necessary when a SELECT statement +returns data to your OCI application. +This call also implicitly allocates the define handle for the select-list item. +Defining attributes of a column for a fetch is done in one or more calls. The +first call is to OCIDefineByPos(), which defines the minimal attributes +required to specify the fetch. +This call takes as a parameter a define handle, which must have been +previously allocated with a call to OCIHandleAlloc(). +Following the call to OCIDefineByPos() additional define calls may be +necessary for certain data types or fetch modes: +A call to OCIDefineArrayOfStruct() is necessary to set up skip parameters +for an array fetch of multiple columns. +A call to OCIDefineObject() is necessary to set up the appropriate +attributes of a named data type fetch. In this case the data buffer pointer +in ocidefn() is ignored. +Both OCIDefineArrayOfStruct() and OCIDefineObject() must be called +after ocidefn() in order to fetch multiple rows with a column of named +data types. +For a LOB define, the buffer pointer must be a lob locator of type +OCILobLocator , allocated by the OCIDescAlloc() call. LOB locators, and not +LOB values, are always returned for a LOB column. LOB values can then be +fetched using OCI LOB calls on the fetched locator. +For NCHAR (fixed and varying length), the buffer pointer must point to an +array of bytes sufficient for holding the required NCHAR characters. +Nested table columns are defined and fetched like any other named data type. +If the mode parameter is this call is set to OCI_DYNAMIC_FETCH, the client +application can fetch data dynamically at runtime. +Runtime data can be provided in one of two ways: +callbacks using a user-defined function which must be registered with a +subsequent call to OCIDefineDynamic(). When the client library needs a +buffer to return the fetched data, the callback will be invoked and the +runtime buffers provided will return a piece or the whole data. +a polling mechanism using calls supplied by the OCI. This mode is +assumed if no callbacks are defined. In this case, the fetch call returns the +OCI_NEED_DATA error code, and a piecewise polling method is used +to provide the data. +Related Functions: For more information about using the +OCI_DYNAMIC_FETCH mode, see the section "Runtime Data +Allocation and Piecewise Operations" on page 5-16 of Volume 1.. +For more information about the define step, see the section "Defining" +on page 2-30. +Parameters +stmtp (IN) - a handle to the requested SQL query operation. +defnp (IN/OUT) - a pointer to a pointer to a define handle which is implicitly +allocated by this call. This handle is used to store the define information +for this column. +errhp (IN) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +position (IN) - the position of this value in the select list. Positions are +1-based and are numbered from left to right. For example, in the SELECT +statement +SELECT empno, ssn, mgrno FROM employees; +empno is at position 1, ssn is at position 2, and mgrno is at position 3. +valuep (IN/OUT) - a pointer to a buffer or an array of buffers of the type +specified in the dty parameter. A number of buffers can be specified when +results for more than one row are desired in a single fetch call. +value_sz (IN) - the size of each valuep buffer in bytes. If the data is stored +internally in VARCHAR2 format, the number of characters desired, if different +from the buffer size in bytes, may be additionally specified by the using +OCIAttrSet(). +In an NLS conversion environment, a truncation error will be generated if the +number of bytes specified is insufficient to handle the number of characters +desired. +dty (IN) - the data type. Named data type (SQLT_NTY) and REF (SQLT_REF) +are valid only if the environment has been intialized with in object mode. +indp - pointer to an indicator variable or array. For scalar data types, +pointer to sb2 or an array of sb2s. Ignored for named data types. For named +data types, a pointer to a named data type indicator structure or an array of +named data type indicator structures is associated by a subsequent +OCIDefineObject() call. +See the section "Indicator Variables" on page 2-43 for more information about +indicator variables. +rlenp (IN/OUT) - pointer to array of length of data fetched. Each element in +rlenp is the length of the data in the corresponding element in the row after +the fetch. +rcodep (OUT) - pointer to array of column-level return codes +mode (IN) - the valid modes are: +OCI_DEFAULT. This is the default mode. +OCI_DYNAMIC_FETCH. For applications requiring dynamically +allocated data at the time of fetch, this mode must be used. The user may +additionally call OCIDefineDynamic() to set up a callback function that +will be invoked to receive the dynamically allocated buffers and to set +up the memory allocate/free callbacks and the context for the callbacks. +valuep and value_sz are ignored in this mode. +Related Functions +OCIDefineArrayOfStruct(), OCIDefineDynamic(), OCIDefineObject() + + + + +OCIDefineDynamic() +Name +OCI Define Dynamic Fetch Attributes +Purpose +This call is used to set the additional attributes required if the +OCI_DYNAMIC_FETCH mode was selected in OCIDefineByPos(). +Syntax +sword OCIDefineDynamic( OCIDefine *defnp, + OCIError *errhp, + void *octxp, + OCICallbackDefine (ocbfp)( + void *octxp, + OCIDefine *defnp, + ub4 iter, + void **bufpp, + ub4 **alenpp, + ub1 *piecep, + void **indpp, + ub2 **rcodep) ); +Comments +This call is used to set the additional attributes required if the +OCI_DYNAMIC_FETCH mode has been selected in a call to +OCIDefineByPos(). +When the OCI_DYNAMIC_FETCH mode is selected, buffers will be +dynamically allocated for REF, and named data type, values to receive the +data. The pointers to these buffers will be returned. +If OCI_DYNAMIC_FETCH mode was selected, and the call to +OCIDefineDynamic() is skipped, then the application can fetch data piecewise +using OCI calls. +For more information about OCI_DYNAMIC_FETCH mode, see the section +"Runtime Data Allocation and Piecewise Operations" on page 5-16. +Parameters +defnp (IN/OUT) - the handle to a define structure returned by a call to +OCIDefineByPos(). +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +octxp (IN) - points to a context for the callback function. +ocbfp (IN) - points to a callback function. This is invoked at runtime to get +a pointer to the buffer into which the fetched data or a piece of it will be +retreived. The callback also specifies the indicator, the return code and the +lengths of the data piece and indicator. The callback has the following +parameters: +octxp (IN) - a context pointer passed as an argument to all the callback +functions. +defnp (IN) - the define handle. +iter (IN) - which row of this current fetch. +bufpp (OUT) - returns a pointer to a buffer to store the column value, ie. +*bufp points to some appropriate storage for the column value. +alenpp (OUT) - returns a pointer to the length of the buffer. *alenpp +contains the size of the buffer after return from callback. Gets set to +actual data size after fetch. +piecep (IN/OUT) - returns a piece value, as follows: +The IN value can be OCI_ONE_PIECE, OCI_FIRST_PIECE or +OCI_NEXT_PIECE. +The OUT value can be OCI_ONE_PIECE if the IN value was +OCI_ONE_PIECE. +The OUT value can be OCI_ONE_PIECE or OCI_FIRST_PIECE if +the IN value was OCI_FIRST_PIECE. +The OUT value can only be OCI_NEXT_PIECE or +OCI_LAST_PIECE if the IN value was OCI_NEXT_PIECE. +indpp (IN) - indicator variable pointer +rcodep (IN) - return code variable pointer +Related Functions +OCIAttrGet() +OCIDefineObject() + + + + +OCIDefineObject() +Name +OCI Define Named Data Type attributes +Purpose +Sets up additional attributes necessary for a Named Data Type define. +Syntax +sword OCIDefineObject ( OCIDefine *defnp, + OCIError *errhp, + const OCIType *type, + void **pgvpp, + ub4 *pvszsp, + void **indpp, + ub4 *indszp ); +Comments +This call sets up additional attributes necessary for a Named Data Type define. +An error will be returned if this function is called when the OCI environment +has been initialized in non-Object mode. +This call takes as a paramter a type descriptor object (TDO) of datatype +OCIType for the named data type being defined. The TDO can be retrieved +with a call to OCITypeByName(). +See the description of OCIInitialize() on page 13 - 43 for more information +about initializing the OCI process environment. +Parameters +defnp (IN/OUT) - a define handle previously allocated in a call to +OCIDefineByPos(). +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +type (IN, optional) - points to the Type Descriptor Object (TDO) which +describes the type of the program variable. Only used for program variables +of type SQLT_NTY. This parameter is optional, and may be passed as NULL +if it is not being used. +pgvpp (IN/OUT) - points to a pointer to a program variable buffer. For an +array, pgvpp points to an array of pointers. Memory for the fetched named data +type instance(s) is dynamically allocated in the object cache. At the end of +the fetch when all the values have been received, pgvpp points to the +pointer(s) to these newly allocated named data type instance(s). The +application must call OCIObjectMarkDel() to deallocate the named data type +instance(s) when they are no longer needed. +pvszsp (IN/OUT) - points to the size of the program variable. For an array, it +is an array of ub4s. On return points to the size(s) of unpickled fetched +values. +indpp (IN/OUT) - points to a pointer to the program variable buffer +containing the parallel indicator structure. For an array, points to an array +of pointers. Memory is allocated to store the indicator structures in the +object cache. At the end of the fetch when all values have been received, +indpp points to the pointer(s) to these newly allocated indicator structure(s). +indszp (IN/OUT) - points to the size(s) of the indicator structure program +variable. For an array, it is an array of ub4s. On return points to the size(s) +of the unpickled fetched indicator values. +Related Functions +OCIAttrGet() + + + +OCIDescAlloc() +Name +OCI Get DESCriptor or lob locator +Purpose +Allocates storage to hold certain data types. The descriptors can be used as +bind or define variables. +Syntax +sword OCIDescAlloc ( const void *parenth, + void **descpp, + ub4 type, + size_t xtramem_sz, + void **usrmempp); +Comments +Returns a pointer to an allocated and initialized structure, corresponding to +the type specified in type. A non-NULL descriptor or LOB locator is returned +on success. No diagnostics are available on error. +This call returns OCI_SUCCESS if successful, or OCI_INVALID_HANDLE if +an out-of-memory error occurs. +Parameters +parenth (IN) - an environment handle. +descpp (OUT) - returns a descriptor or LOB locator of desired type. +type (IN) - specifies the type of descriptor or LOB locator to be allocated. +The specific types are: +OCI_DTYPE_SNAP - specifies generation of snapshot descriptor of C +type - OCISnapshot +OCI_DTYPE_LOB - specifies generation of a LOB data type locator of C +type - OCILobLocator +OCI_DTYPE_RSET - specifies generation of a descriptor of C type +OCIResult that references a result set (a number of rows as a result of a +query). This descriptor is bound to a bind variable of data type +SQLT_RSET (result set). The descriptor has to be converted into a +statement handle using a function - OCIResultSetToStmt() - which can +then be passed to OCIDefineByPos() and OCIStmtFetch() to retrieve the +rows of the result set. +OCI_DTYPE_ROWID - specifies generation of a ROWID descriptor of C +type OCIRowid. +OCI_DTYPE_COMPLEXOBJECTCOMP - specifies generation of a +complex object retrieval descriptor of C type +OCIComplexObjectComp. +xtramemsz (IN) - specifies an amount of user memory to be allocated for use +by the application. +usrmempp (OUT) - returns a pointer to the user memory of size xtramemsz +allocated by the call for the user. +Related Functions +OCIDescFree() + + + + +OCIDescFree() +Name +OCI Free DESCriptor +Purpose +Deallocates a previously allocated descriptor. +Syntax +sword OCIDescFree ( void *descp, + ub4 type); +Comments +This call frees up storage associated with the descriptor, corresponding to the +type specified in type. Returns OCI_SUCCESS or OCI_INVALID_HANDLE. +All descriptors must be explicitly deallocated. OCI will not deallocate a +descriptor if the environment handle is deallocated. +Parameters +descp (IN) - an allocated descriptor. +type (IN) - specifies the type of storage to be freed. The specific types are: +OCI_DTYPE_SNAP - snapshot descriptor +OCI_DTYPE_LOB - a LOB data type descriptor +OCI_DTYPE_RSET - a descriptor that references a result set (a number +of rows as a result of a query). +OCI_DTYPE_ROWID - a ROWID descriptor +OCI_DTYPE_COMPLEXOBJECTCOMP - a complex object retrieval +descriptor +Related Functions +OCIDescAlloc() + + + +OCIDescribeAny() +Name +OCI DeSCribe Any +Purpose +Describes existing schema objects. +Syntax +sword OCIDescribeAny ( OCISvcCtx *svchp, + OCIError *errhp, + void *objptr, + ub4 objnm_len, + ub1 objptr_typ, + ub1 info_level, + ub1 objtype, + OCIDesc *dschp ); +Comments +This is a generic describe call that describes existing schema objects: tables, +views, synonyms, procedures, functions, packages, sequences, and types. As a +result of this call, the describe handle is populated with the object-specific +attributes which can be obtained through an OCIAttrGet() call. +An OCIParamGet() on the describe handle returns a parameter descriptor for a +specified position. Parameter positions begin with 1. Calling OCIAttrGet() on +the parameter descriptor returns the specific attributes of a stored procedure +or function parameter or a table column descriptor as the case may be. +These subsequent calls do not need an extra round trip to the server because +the entire schema object description cached on the client side by +OCIDescribeAny(). Calling OCIAttrGet() on the describe handle can also return +the total number of positions. +See the section "Describing" on page 2-33 for more information about describe +operations. +Parameters +TO BE UPDATED +svchp (IN/OUT) - a service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +objptr (IN) - the name of the object (a null-terminated string) to be +described. Only procedure or function names are valid when connected to an +Oracle7 Server. +objptr_len (IN) - the length of the string. Must be non-zero. +objptr_typ (IN) - Must be OCI_OTYPE_NAME, OCI_OTYPE_REF, or OCI_OTYPE_PTR. +info_level (IN) - reserved for future extensions. Pass OCI_DEFAULT. +objtype (IN/OUT) - object type. +dschp (IN/OUT) - a describe handle that is populated with describe +information about the object after the call. +Related Functions +OCIAttrGet() + + + +OCIEnvCreate() +Name +OCI ENVironment CREATE +Purpose +This function creates and initializes an environment for the rest of +the OCI functions to work under. This call is a replacement for both +the OCIInitialize and OCIEnvInit calls. +Syntax +sword OCIEnvCreate ( OCIEnv **envhpp, + ub4 mode, + const void *ctxp, + const void *(*malocfp) + (void *ctxp, + size_t size), + const void *(*ralocfp) + (void *ctxp, + void *memptr, + size_t newsize), + const void (*mfreefp) + ( void *ctxp, + void *memptr)) + size_t xtramemsz, + void **usrmempp ); + +Comments +This call creates an environment for all the OCI calls using the modes +specified by the user. This call can be used instead of the two calls +OCIInitialize and OCIEnvInit. This function returns an environment handle +which is then used by the remaining OCI functions. There can be multiple +environments in OCI each with its own environment modes. This function +also performs any process level initialization if required by any mode. +For example if the user wants to initialize an environment as OCI_THREADED, +then all libraries that are used by OCI are also initialized in the +threaded mode. + +This call should be invoked before anny other OCI call and should be used +instead of the OCIInitialize and OCIEnvInit calls. This is the recommended +call, although OCIInitialize and OCIEnvInit calls will still be supported +for backward compatibility. + +envpp (OUT) - a pointer to a handle to the environment. +mode (IN) - specifies initialization of the mode. The valid modes are: +OCI_DEFAULT - default mode. +OCI_THREADED - threaded environment. In this mode, internal data +structures are protected from concurrent accesses by multiple threads. +OCI_OBJECT - will use navigational object interface. +ctxp (IN) - user defined context for the memory call back routines. +malocfp (IN) - user-defined memory allocation function. If mode is +OCI_THREADED, this memory allocation routine must be thread safe. +ctxp - context pointer for the user-defined memory allocation function. +size - size of memory to be allocated by the user-defined memory +allocation function +ralocfp (IN) - user-defined memory re-allocation function. If mode is +OCI_THREADED, this memory allocation routine must be thread safe. +ctxp - context pointer for the user-defined memory reallocation +function. +memp - pointer to memory block +newsize - new size of memory to be allocated +mfreefp (IN) - user-defined memory free function. If mode is +OCI_THREADED, this memory free routine must be thread safe. +ctxp - context pointer for the user-defined memory free function. +memptr - pointer to memory to be freed +xtramemsz (IN) - specifies the amount of user memory to be allocated. +usrmempp (OUT) - returns a pointer to the user memory of size xtramemsz +allocated by the call for the user. + +Example + +Related Functions +OCIInitialize, OCIEnvInit + +OCIEnvNlsCreate() +Name +OCI ENVironment CREATE with NLS info +Purpose +This function does almost everything OCIEnvCreate does, plus enabling setting +of charset and ncharset programmatically, except OCI_UTF16 mode. +Syntax +sword OCIEnvNlsCreate(OCIEnv **envhpp, + ub4 mode, + void *ctxp, + void *(*malocfp) + (void *ctxp, + size_t size), + void *(*ralocfp) + (void *ctxp, + void *memptr, + size_t newsize), + void (*mfreefp) + (void *ctxp, + void *memptr), + size_t xtramemsz, + void **usrmempp, + ub2 charset, + ub2 ncharset) +Comments +The charset and ncharset must be both zero or non-zero. +The parameters have the same meaning as the ones in OCIEnvCreate(). +When charset or ncharset is non-zero, the corresponding character set will +be used to replace the ones specified in NLS_LANG or NLS_NCHAR. Moreover, +OCI_UTF16ID is allowed to be set as charset and ncharset. +On the other hand, OCI_UTF16 mode is deprecated with this function. +Applications can achieve the same effects by setting +both charset and ncharset as OCI_UTF16ID. + + +OCIEnvInit() +Name +OCI INITialize environment +Purpose +This call initializes the OCI environment handle. +Syntax +sword OCIEnvInit ( OCIEnv **envp, + ub4 mode, + size_t xtramemsz, + void **usrmempp ); +Comments +Initializes the OCI environment handle. No changes are done on an initialized +handle. If OCI_ERROR or OCI_SUCCESS_WITH_INFO is returned, the +environment handle can be used to obtain ORACLE specific errors and +diagnostics. +This call is processed locally, without a server round-trip. +Parameters +envpp (OUT) - a pointer to a handle to the environment. +mode (IN) - specifies initialization of an environment mode. The only valid +mode is OCI_DEFAULT for default mode +xtramemsz (IN) - specifies the amount of user memory to be allocated. +usrmempp (OUT) - returns a pointer to the user memory of size xtramemsz +allocated by the call for the user. +Example +See the description of OCISessionBegin() on page 13-84 for an example showing +the use of OCIEnvInit(). +Related Functions + + + + +OCIErrorGet() +Name +OCI Get Diagnostic Record +Purpose +Returns an error message in the buffer provided and an ORACLE error. +Syntax +sword OCIErrorGet ( void *hndlp, + ub4 recordno, + OraText *sqlstate, + ub4 *errcodep, + OraText *bufp, + ub4 bufsiz, + ub4 type ); +Comments +Returns an error message in the buffer provided and an ORACLE error. +Currently does not support SQL state. This call can be called a multiple +number of times if there are more than one diagnostic record for an error. +The error handle is originally allocated with a call to OCIHandleAlloc(). +Parameters +hndlp (IN) - the error handle, in most cases, or the environment handle (for +errors on OCIEnvInit(), OCIHandleAlloc()). +recordno (IN) - indicates the status record from which the application seeks +info. Starts from 1. +sqlstate (OUT) - Not supported in Version 8.0. +errcodep (OUT) - an ORACLE Error is returned. +bufp (OUT) - the error message text is returned. +bufsiz (IN) - the size of the buffer provide to get the error message. +type (IN) - the type of the handle. +Related Functions +OCIHandleAlloc() + +OCIExtractInit +Name +OCI Extract Initialize +Purpose +This function initializes the parameter manager. +Syntax +sword OCIExtractInit(void *hndl, OCIError *err); +Comments +It must be called before calling any other parameter manager routine. The NLS +information is stored inside the parameter manager context and used in +subsequent calls to OCIExtract routines. +Returns OCI_SUCCESS, OCI_INVALID_HANDLE, or OCI_ERROR +Parameters +hndl (IN/OUT) - The OCI environment or session handle. +err (IN/OUT) - The OCI error handle. If there is an error, it is recorded in + err and this function returns OCI_ERROR. Diagnostic information + can be obtained by calling OCIErrorGet(). +Related Functions +OCIExtractTerm() + +OCIExtractTerm +Name +OCI Extract Terminate +Purpose +This function releases all dynamically allocated storage and may perform +other internal bookkeeping functions. +Syntax +sword OCIExtractTerm(void *hndl, OCIError *err); +Comments +It must be called when the parameter manager is no longer being used. +Returns OCI_SUCCESS, OCI_INVALID_HANDLE, or OCI_ERROR +Parameters +hndl (IN/OUT) - The OCI environment or session handle. +err (IN/OUT) - The OCI error handle. If there is an error, it is recorded in + err and this function returns OCI_ERROR. Diagnostic information + can be obtained by calling OCIErrorGet(). +Related Functions +OCIExtractInit() + +OCIExtractReset +Name +OCI Extract Reset +Purpose +The memory currently used for parameter storage, key definition storage, and +parameter value lists is freed and the structure is reinitialized. +Syntax +sword OCIExtractReset(void *hndl, OCIError *err); +Comments +Returns OCI_SUCCESS, OCI_INVALID_HANDLE, or OCI_ERROR +Parameters +hndl (IN/OUT) - The OCI environment or session handle. +err (IN/OUT) - The OCI error handle. If there is an error, it is recorded in + err and this function returns OCI_ERROR. Diagnostic information + can be obtained by calling OCIErrorGet(). +Related Functions + +OCIExtractSetNumKeys +Name +OCI Extract Set Number of Keys +Purpose +Informs the parameter manager of the number of keys that will be registered. +Syntax +sword OCIExtractSetNumKeys(void *hndl, OCIError *err, uword numkeys); +Comments +This routine must be called prior to the first call of OCIExtractSetKey(). +Returns OCI_SUCCESS, OCI_INVALID_HANDLE, or OCI_ERROR +Parameters +hndl (IN/OUT) - The OCI environment or session handle. +err (IN/OUT) - The OCI error handle. If there is an error, it is recorded in + err and this function returns OCI_ERROR. Diagnostic information + can be obtained by calling OCIErrorGet(). +numkeys (IN) - The number of keys that will be registered with + OCIExtractSetKey(). +Related Functions +OCIExtractSetKey() + +OCIExtractSetKey +Name +OCI Extract Set Key definition +Purpose +Registers information about a key with the parameter manager. +Syntax +sword OCIExtractSetKey(void *hndl, OCIError *err, const OraText *name, + ub1 type, ub4 flag, const void *defval, + const sb4 *intrange, const OraText *const *strlist); +Comments +This routine must be called after calling OCIExtractSetKey() and before +calling OCIExtractFromFile() or OCIExtractFromStr(). +Returns OCI_SUCCESS, OCI_INVALID_HANDLE, or OCI_ERROR +Parameters +hndl (IN/OUT) - The OCI environment or session handle. +err (IN/OUT) - The OCI error handle. If there is an error, it is recorded in + err and this function returns OCI_ERROR. Diagnostic information + can be obtained by calling OCIErrorGet(). +name (IN) - The name of the key. +type (IN) - The type of the key (OCI_EXTRACT_TYPE_INTEGER, + OCI_EXTRACT_TYPE_OCINUM, OCI_EXTRACT_TYPE_STRING, or + OCI_EXTRACT_TYPE_BOOLEAN). +flag (IN) - Set to OCI_EXTRACT_MULTIPLE if the key can take multiple values + or 0 otherwise. +defval (IN) - Set to the default value for the key. May be NULL if there is + no default. A string default must be a (text*) type, an + integer default must be an (sb4*) type, and a boolean default + must be a (ub1*) type. +intrange (IN) - Starting and ending values for the allowable range of integer + values. May be NULL if the key is not an integer type or if + all integer values are acceptable. +strlist (IN) - List of all acceptable text strings for the key. May be NULL + if the key is not a string type or if all text values are + acceptable. +Related Functions +OCIExtractSetNumKeys() + +OCIExtractFromFile +Name +OCI Extract parameters From File +Purpose +The keys and their values in the given file are processed. +Syntax +sword OCIExtractFromFile(void *hndl, OCIError *err, ub4 flag, + OraText *filename); +Comments +Returns OCI_SUCCESS, OCI_INVALID_HANDLE, or OCI_ERROR +Parameters +hndl (IN/OUT) - The OCI environment or session handle. +err (IN/OUT) - The OCI error handle. If there is an error, it is recorded in + err and this function returns OCI_ERROR. Diagnostic information + can be obtained by calling OCIErrorGet(). +flag (IN) - Zero or has one or more of the following bits set: + OCI_EXTRACT_CASE_SENSITIVE, OCI_EXTRACT_UNIQUE_ABBREVS, or + OCI_EXTRACT_APPEND_VALUES. +filename (IN) - Null-terminated filename string. +Related Functions + +OCIExtractFromStr +Name +OCI Extract parameters From String +Purpose +The keys and their values in the given string are processed. +Syntax +sword OCIExtractFromStr(void *hndl, OCIError *err, ub4 flag, OraText *input); +Comments +Returns OCI_SUCCESS, OCI_INVALID_HANDLE, or OCI_ERROR +Parameters +hndl (IN/OUT) - The OCI environment or session handle. +err (IN/OUT) - The OCI error handle. If there is an error, it is recorded in + err and this function returns OCI_ERROR. Diagnostic information + can be obtained by calling OCIErrorGet(). +flag (IN) - Zero or has one or more of the following bits set: + OCI_EXTRACT_CASE_SENSITIVE, OCI_EXTRACT_UNIQUE_ABBREVS, or + OCI_EXTRACT_APPEND_VALUES. +input (IN) - Null-terminated input string. +Related Functions + +OCIExtractToInt +Name +OCI Extract To Integer +Purpose +Gets the integer value for the specified key. +Syntax +sword OCIExtractToInt(void *hndl, OCIError *err, OraText *keyname, + uword valno, sb4 *retval); +Comments +The valno'th value (starting with 0) is returned. +Returns OCI_SUCCESS, OCI_INVALID_HANDLE, OCI_NO_DATA, or OCI_ERROR. +OCI_NO_DATA means that there is no valno'th value for this key. +Parameters +hndl (IN) - The OCI environment or session handle. +err (IN/OUT) - The OCI error handle. If there is an error, it is recorded in + err and this function returns OCI_ERROR. Diagnostic information + can be obtained by calling OCIErrorGet(). +keyname (IN) - Key name. +valno (IN) - Which value to get for this key. +retval (OUT) - The actual integer value. +Related Functions + +OCIExtractToBool +Name +OCI Extract To Boolean +Purpose +Gets the boolean value for the specified key. +Syntax +sword OCIExtractToBool(void *hndl, OCIError *err, OraText *keyname, + uword valno, ub1 *retval); +Comments +The valno'th value (starting with 0) is returned. +Returns OCI_SUCCESS, OCI_INVALID_HANDLE, OCI_NO_DATA, or OCI_ERROR. +OCI_NO_DATA means that there is no valno'th value for this key. +Parameters +hndl (IN) - The OCI environment or session handle. +err (IN/OUT) - The OCI error handle. If there is an error, it is recorded in + err and this function returns OCI_ERROR. Diagnostic information + can be obtained by calling OCIErrorGet(). +keyname (IN) - Key name. +valno (IN) - Which value to get for this key. +retval (OUT) - The actual boolean value. +Related Functions + +OCIExtractToStr +Name +OCI Extract To String +Purpose +Gets the string value for the specified key. +Syntax +sword OCIExtractToStr(void *hndl, OCIError *err, OraText *keyname, + uword valno, OraText *retval, uword buflen); +Comments +The valno'th value (starting with 0) is returned. +Returns OCI_SUCCESS, OCI_INVALID_HANDLE, OCI_NO_DATA, or OCI_ERROR. +OCI_NO_DATA means that there is no valno'th value for this key. +Parameters +hndl (IN) - The OCI environment or session handle. +err (IN/OUT) - The OCI error handle. If there is an error, it is recorded in + err and this function returns OCI_ERROR. Diagnostic information + can be obtained by calling OCIErrorGet(). +keyname (IN) - Key name. +valno (IN) - Which value to get for this key. +retval (OUT) - The actual null-terminated string value. +buflen (IN) - The length of the buffer for retval. +Related Functions + +Note: The following OCIExtract functions are unavailable in this release + +OCIExtractToOCINum +Name +OCI Extract To OCI Number +Purpose +Gets the OCINumber value for the specified key. +Syntax +sword OCIExtractToOCINum(void *hndl, OCIError *err, OraText *keyname, + uword valno, OCINumber *retval); +Comments +The valno'th value (starting with 0) is returned. +Returns OCI_SUCCESS, OCI_INVALID_HANDLE, OCI_NO_DATA, or OCI_ERROR. +OCI_NO_DATA means that there is no valno'th value for this key. +Parameters +hndl (IN) - The OCI environment or session handle. +err (IN/OUT) - The OCI error handle. If there is an error, it is recorded in + err and this function returns OCI_ERROR. Diagnostic information + can be obtained by calling OCIErrorGet(). +keyname (IN) - Key name. +valno (IN) - Which value to get for this key. +retval (OUT) - The actual OCINumber value. +Related Functions + +OCIExtractToList +Name +OCI Extract To parameter List +Purpose +Generates a list of parameters from the parameter structures that are stored +in memory. +Syntax +sword OCIExtractToList(void *hndl, OCIError *err, uword *numkeys); +Comments +Must be called before OCIExtractValues() is called. +Returns OCI_SUCCESS, OCI_INVALID_HANDLE, or OCI_ERROR +Parameters +hndl (IN) - The OCI environment or session handle. +err (IN/OUT) - The OCI error handle. If there is an error, it is recorded in + err and this function returns OCI_ERROR. Diagnostic information + can be obtained by calling OCIErrorGet(). +numkeys (OUT) - Number of distinct keys stored in memory. +Related Functions +OCIExtractFromList() + +OCIExtractFromList +Name +OCI Extract From parameter List +Purpose +Generates a list of values for the a parameter in the parameter list. +Syntax +sword OCIExtractFromList(void *hndl, OCIError *err, uword index, + OraText *name, ub1 *type, uword *numvals, + void ***values); +Comments +Parameters are specified by an index. OCIExtractToList() must be called prior +to calling this routine to generate the parameter list from the parameter +structures that are stored in memory. +Returns OCI_SUCCESS, OCI_INVALID_HANDLE, or OCI_ERROR +Parameters +hndl (IN) - The OCI environment or session handle. +err (IN/OUT) - The OCI error handle. If there is an error, it is recorded in + err and this function returns OCI_ERROR. Diagnostic information + can be obtained by calling OCIErrorGet(). +name (OUT) - Name of the key for the current parameter. +type (OUT) - Type of the current parameter (OCI_EXTRACT_TYPE_STRING, + OCI_EXTRACT_TYPE_INTEGER, OCI_EXTRACT_TYPE_OCINUM, or + OCI_EXTRACT_TYPE_BOOLEAN) +numvals (OUT) - Number of values for this parameter. +values (OUT) - The values for this parameter. +Related Functions +OCIExtractToList() + + +************************ OCIFileClose() *********************************** + +Name + OCIFileClose - Oracle Call Interface FILE i/o CLOSE + +Purpose + Close a previously opened file. + +Syntax + sword OCIFileClose ( void *hndl, + OCIError *err, + OCIFileObject *filep ) + +Comments + This function will close a previously opened file. If the function succeeds + then OCI_SUCCESS will be returned, else OCI_ERROR. + +Parameters + hndl (IN) - the OCI environment or session handle. + err (OUT) - the OCI error handle + filep (IN) - the OCIFile file object + +Related Functions + OCIFileOpen. + + + +********************* OCIFileExists() ************************************** + +Name + OCIFileExists - Oracle Call Interface FILE i/o EXIST + +Purpose + Check to see if the file exists. + +Syntax + sword OCIFileExists ( void *hndl, + OCIError *err, + OraText *filename, + OraText *path, + ub1 *flag ) + +Comments + This function will set the flag to TRUE if the file exists else it will + be set to FALSE. + The function will return OCI_ERROR if any error is encountered, else + it will return OCI_ERROR. + +Parameters + hndl(IN) - OCI environment or session handle + err(OUT) - OCI error handle + filename(IN) - filename + path(IN) - path of the file + flag(OUT) - whether the file exists or not + +Related Functions. + None. + + + **************************** OCIFileFlush() ****************************** + + +Name + OCIFileFlush - Oracle Call Interface File i/o FLUSH + +Purpose + Flush the buffers associated with the file to the disk. + +Syntax + sword OCIFileFlush ( void *hndl, + OCIError *err, + OCIFileObject *filep ) + +Comments + The function will return OCI_ERROR if any error is encountered, else + it will return OCI_ERROR. + +Parameters + hndl (IN) - the OCI environment or session handle. + err (OUT) - the OCI error handle + filep (IN) - the OCIFile file object + +Related Functions + OCIFileOpen, OCIFileWrite + + + + *************************** OCIFileGetLength() **************************** + +Name + OCIFileGetLength - Oracle Call Interface FILE i/o GET file LENGTH + +Purpose + Get the length of a file. + +Syntax + OCIFileGetLength(void *hndl, + OCIError *err, + OraText *filename, + OraText *path, + ubig_ora *lenp ) + +Comments + The length of the file will be returned in lenp. + The function will return OCI_ERROR if any error is encountered, else + it will return OCI_ERROR. + +Parameters + hndl (IN) - the OCI environment or session handle. + err (OUT) - the OCI error handle. If there is an error, it is recorded + in err and this function returns OCI_ERROR. Diagnostic information can be + obtained by calling OCIErrorGet(). + filename (IN) - file name. + path (IN) - path of the file. + lenp (OUT) - On output, it is the length of the file in bytes. + is the number of bytes in the file. + +Related Functions + None. + + + +******************************** OCIFileInit() ***************************** + +Name + OCIFileInit - Oracle Call Interface FILE i/o INITialize + +Purpose + Initialize the OCI File I/O package and create the OCIFile context. + +Syntax + sword OCIFileInit ( void *hndl, + OCIError *err) + +Comments + This function should be called before any of the OCIFile functions are + used. + The function will return OCI_ERROR if any error is encountered, else + it will return OCI_ERROR. + +Parameters + hndl(IN) - OCI environment or session handle. + err(OUT) - OCI error structure. + +Related Functions + OCIFileTerm + + + +********************************* OCIFileOpen() ***************************** + +Name + OCIFileOpen - Oracle Call Interface File i/o OPEN + +Purpose + Open a file. + +Syntax + sword OCIFileOpen ( void *hndl, + OCIError *err, + OCIFileObject **filep, + OraText *filename, + OraText *path, + ub4 mode, + ub4 create, + ub4 type ) + +Comments + OCIFileOpen returns a handle to the open file in filep if the file is + successfully opened. + If one wants to use the standard file objects (stdin, stdout & stderr) + then OCIFileOpen whould be called with the type filed containing the + appropriate type (see the parameter type). If any of the standard files + are specified then filename, path, mode and create are ignored. + The function will return OCI_ERROR if any error is encountered, else + it will return OCI_ERROR. + +Parameters + hndl (OUT) - the OCI environment or session handle. + err (OUT) - the OCI error handle. If there is an error, it is recorded + in err and this function returns OCI_ERROR. Diagnostic information can be + obtained by calling OCIErrorGet(). + filep (OUT) - the file object to be returned. + filename (IN) - file name (NULL terminated string). + path (IN) - path of the file (NULL terminated string). + mode - mode in which to open the file (valid modes are OCI_FILE_READONLY, + OCI_FILE_WRITEONLY, OCI_FILE_READ_WRITE). + create - should the file be created if it does not exist. Valid values + are: + OCI_FILE_TRUNCATE - create a file regardless of whether or not it exists. + If the file already exists overwrite it. + OCI_FILE_EXIST - open it if it exists, else fail. + OCI_FILE_EXCL - fail if the file exists, else create. + OCI_FILE_CREATE - open the file if it exists, and create it if it doesn't. + OCI_FILE_APPEND - set the file pointer to the end of the file prior to + writing(this flag can be OR'ed with OCI_FILE_EXIST or + OCI_FILE_CREATE). +type - file type. Valid values are OCI_FILE_TEXT, OCI_FILE_BIN, + OCI_FILE_STDIN, OCI_FILE_STDOUT and OCI_FILE_STDERR. + If any of the standard files are specified then filename, path, mode + and create are ignored. + +Related Functions. + OCIFileClose + + + +************************** OCIFileRead() ************************************ + +Name + OCIFileRead - Oracle Call Interface FILE i/o READ + +Purpose + Read from a file into a buffer. + +Syntax + sword OCIFileRead ( void *hndl, + OCIError *err, + OCIFileObject *filep, + void *bufp, + ub4 bufl, + ub4 *bytesread ) + +Comments + Upto bufl bytes from the file will be read into bufp. The user should + allocate memory for the buffer. + The number of bytes read would be in bytesread. + The function will return OCI_ERROR if any error is encountered, else + it will return OCI_ERROR. + +Parameters + hndl (IN) - the OCI environment or session handle. + err (OUT) - the OCI error handle. If there is an error, it is recorded + in err and this function returns OCI_ERROR. Diagnostic information can be + obtained by calling OCIErrorGet(). + filep (IN/OUT) - a File Object that uniquely references the file. + bufp (IN) - the pointer to a buffer into which the data will be read. The + length of the allocated memory is assumed to be bufl. + bufl - the length of the buffer in bytes. + bytesread (OUT) - the number of bytes read. + +Related Functions + OCIFileOpen, OCIFileSeek, OCIFileWrite + + + +****************************** OCIFileSeek() ****************************** + +Name + OCIFileSeek - Oracle Call Interface FILE i/o SEEK + +Purpose + Perfom a seek to a byte position. + +Syntax + sword OCIFileSeek ( void *hndl, + OCIError *err, + OCIFileObject *filep, + uword origin, + ubig_ora offset, + sb1 dir) + +Comments + The function will return OCI_ERROR if any error is encountered, else + it will return OCI_ERROR. + +Parameters + hndl (IN) - the OCI environment or session handle. + err (OUT) - the OCI error handle. If there is an error, it is recorded + in err and this function returns OCI_ERROR. Diagnostic information can be + obtained by calling OCIErrorGet(). + filep (IN/OUT) - a file handle that uniquely references the file. + origin - The starting point we want to seek from. NOTE: The starting + point may be OCI_FILE_SEEK_BEGINNING (beginning), OCI_FILE_SEEK_CURRENT + (current position), or OCI_FILE_SEEK_END (end of file). + offset - The number of bytes from the origin we want to start reading from. + dir - The direction we want to go from the origin. NOTE: The direction + can be either OCI_FILE_FORWARD or OCI_FILE_BACKWARD. + +Related Function + OCIFileOpen, OCIFileRead, OCIFileWrite + + + +*************************** OCIFileTerm() ********************************** + +Name + OCIFileTerm - Oracle Call Interface FILE i/o TERMinate + +Purpose + Terminate the OCI File I/O package and destroy the OCI File context. + +Syntax + sword OCIFileTerm ( void *hndl, + OCIError *err ) + +Comments + After this function has been called no OCIFile function should be used. + The function will return OCI_ERROR if any error is encountered, else + it will return OCI_ERROR. + +Parameters + hndl(IN) - OCI environment or session handle. + err(OUT) - OCI error structure. + +Related Functions + OCIFileInit + + +********************************* OCIFileWrite() **************************** + +Name + OCIFileWrite - Oracle Call Interface FILE i/o WRITE + +Purpose + Write data from buffer into a file. + +Syntax + sword OCIFileWrite ( void *hndl, + OCIError *err, + OCIFileObject *filep, + void *bufp, + ub4 buflen + ub4 *byteswritten ) + +Comments + The number of bytes written will be in *byteswritten. + The function will return OCI_ERROR if any error is encountered, else + it will return OCI_ERROR. + +Parameters + hndl (IN) - the OCI environment or session handle. + err (OUT) - the OCI error handle. If there is an error, it is recorded + in err and this function returns OCI_ERROR. Diagnostic information can be + obtained by calling OCIErrorGet(). + filep (IN/OUT) - a file handle that uniquely references the file. + bufp (IN) - the pointer to a buffer from which the data will be written. + The length of the allocated memory is assumed to be the value passed + in bufl. + bufl - the length of the buffer in bytes. + byteswritten (OUT) - the number of bytes written. + +Related Functions + OCIFileOpen, OCIFileSeek, OCIFileRead + + + + + +OCIHandleAlloc() +Name +OCI Get HaNDLe +Purpose +This call returns a pointer to an allocated and initialized handle. +Syntax +sword OCIHandleAlloc ( const void *parenth, + void **hndlpp, + ub4 type, + size_t xtramem_sz, + void **usrmempp); +Comments +Returns a pointer to an allocated and initialized structure, corresponding to +the type specified in type. A non-NULL handle is returned on success. Bind +handle and define handles are allocated with respect to a statement handle. All +other handles are allocated with respect to an environment handle which is +passed in as a parent handle. +No diagnostics are available on error. This call returns OCI_SUCCESS if +successful, or OCI_INVALID_HANDLE if an out-of-memory error occurs. +Handles must be allocated using OCIHandleAlloc() before they can be passed +into an OCI call. +Parameters +parenth (IN) - an environment or a statement handle. +hndlpp (OUT) - returns a handle to a handle type. +type (IN) - specifies the type of handle to be allocated. The specific types +are: +OCI_HTYPE_ERROR - specifies generation of an error report handle of +C type OCIError +OCI_HTYPE_SVCCTX - specifies generation of a service context handle +of C type OCISvcCtx +OCI_HTYPE_STMT - specifies generation of a statement (application +request) handle of C type OCIStmt +OCI_HTYPE_BIND - specifies generation of a bind information handle +of C type OCIBind +OCI_HTYPE_DEFINE - specifies generation of a column definition +handle of C type OCIDefine +OCI_HTYPE_DESCRIBE - specifies generation of a select list +description handle of C type OCIDesc +OCI_HTYPE_SERVER - specifies generation of a server context handle +of C type OCIServer +OCI_HTYPE_SESSION - specifies generation of an authentication +context handle of C type OCISession +OCI_HTYPE_TRANS - specifies generation of a transaction context +handle of C type OCITrans +OCI_HTYPE_COMPLEXOBJECT - specifies generation of a complex +object retrieval handle of C type OCIComplexObject +OCI_HTYPE_SECURITY - specifies generation of a security handle of C +type OCISecurity +xtramem_sz (IN) - specifies an amount of user memory to be allocated. +usrmempp (OUT) - returns a pointer to the user memory of size xtramemsz +allocated by the call for the user. +Related Functions +OCIHandleFree() + + + +OCIHandleFree() +Name +OCI Free HaNDLe +Purpose +This call explicitly deallocates a handle. +Syntax +sword OCIHandleFree ( void *hndlp, + ub4 type); +Comments +This call frees up storage associated with a handle, corresponding to the type +specified in the type parameter. +This call returns either OCI_SUCCESS or OCI_INVALID_HANDLE. +All handles must be explicitly deallocated. OCI will not deallocate a child +handle if the parent is deallocated. +Parameters +hndlp (IN) - an opaque pointer to some storage. +type (IN) - specifies the type of storage to be allocated. The specific types +are: +OCI_HTYPE_ENV - an environment handle +OCI_HTYPE_ERROR - an error report handle +OCI_HTYPE_SVCCTX - a service context handle +OCI_HTYPE_STMT - a statement (application request) handle +OCI_HTYPE_BIND - a bind information handle +OCI_HTYPE_DEFINE - a column definition handle +OCI_HTYPE_DESCRIBE - a select list description handle +OCI_HTYPE_SERVER - a server handle +OCI_HTYPE_SESSION - a user authentication handle +OCI_HTYPE_TRANS - a transaction handle +OCI_HTYPE_COMPLEXOBJECT - a complex object retrieval handle +OCI_HTYPE_SECURITY - a security handle +Related Functions +OCIHandleAlloc() + + + + +OCIInitialize() +Name +OCI Process Initialize +Purpose +Initializes the OCI process environment. +Syntax +sword OCIInitialize ( ub4 mode, + const void *ctxp, + const void *(*malocfp) + ( void *ctxp, + size_t size ), + const void *(*ralocfp) + ( void *ctxp, + void *memp, + size_t newsize ), + const void (*mfreefp) + ( void *ctxp, + void *memptr )); +Comments +This call initializes the OCI process environment. +OCIInitialize() must be invoked before any other OCI call. +Parameters +mode (IN) - specifies initialization of the mode. The valid modes are: +OCI_DEFAULT - default mode. +OCI_THREADED - threaded environment. In this mode, internal data +structures are protected from concurrent accesses by multiple threads. +OCI_OBJECT - will use navigational object interface. +ctxp (IN) - user defined context for the memory call back routines. +malocfp (IN) - user-defined memory allocation function. If mode is +OCI_THREADED, this memory allocation routine must be thread safe. +ctxp - context pointer for the user-defined memory allocation function. +size - size of memory to be allocated by the user-defined memory +allocation function +ralocfp (IN) - user-defined memory re-allocation function. If mode is +OCI_THREADED, this memory allocation routine must be thread safe. +ctxp - context pointer for the user-defined memory reallocation +function. +memp - pointer to memory block +newsize - new size of memory to be allocated +mfreefp (IN) - user-defined memory free function. If mode is +OCI_THREADED, this memory free routine must be thread safe. +ctxp - context pointer for the user-defined memory free function. +memptr - pointer to memory to be freed +Example +See the description of OCIStmtPrepare() on page 13-96 for an example showing +the use of OCIInitialize(). +Related Functions + +-------------------------------OCITerminate------------------------------------ + +OCITerminate() +Name +OCI process Terminate +Purpose +Do cleanup before process termination +Syntax +sword OCITerminate (ub4 mode); + +Comments +This call performs OCI related clean up before the OCI process terminates. +If the process is running in shared mode then the OCI process is disconnected +from the shared memory subsystem. + +OCITerminate() should be the last OCI call in any process. + +Parameters +mode (IN) - specifies different termination modes. + +OCI_DEFAULT - default mode. + +Example + +Related Functions +OCIInitialize() + +------------------------ OCIAppCtxSet-------------------------------------- +Name +OCI Application context Set +Purpose +Set an attribute and its value for a particular application context + namespace +Syntax + (sword) OCIAppCtxSet((void *) sesshndl, (void *)nsptr,(ub4) nsptrlen, + (void *)attrptr, (ub4) attrptrlen, (void *)valueptr, + (ub4) valueptrlen, errhp, (ub4)mode); + +Comments +Please note that the information set on the session handle is sent to the +server during the next OCIStatementExecute or OCISessionBegin. + +This information is cleared from the session handle, once the information + has been sent over to the server,and should be setup again if needed. + +Parameters + sesshndl (IN/OUT) - Pointer to a session handle + nsptr (IN) - Pointer to namespace string + nsptrlen (IN) - length of the nsptr + attrptr (IN) - Pointer to attribute string + attrptrlen (IN) - length of the attrptr + valueptr (IN) - Pointer to value string + valueptrlen(IN) - length of the valueptr + errhp (OUT) - Error from the API + mode (IN) - mode of operation (OCI_DEFAULT) + +Returns + error if any +Example + +Related Functions + OCIAppCtxClearAll + + +------------------------ OCIAppCtxClearAll--------------------------------- +Name + OCI Application Context Clear all attributes in a namespace +Purpose + To clear the values all attributes in a namespace +Syntax + (sword) OCIAppCtxClearAll((void *) sesshndl, (void *)nsptr, (ub4) nsptrlen, + (OCIError *)errhp, (ub4)mode); + +Comments +This will clean up the context information on the server side during the +next piggy-back to the server. + +Parameters + sesshndl (IN/OUT) - Pointer to a session handle + nsptr (IN) - Pointer to namespace string where the values of all + attributes are cleared + nsptrlen (IN) - length of the nsptr + errhp (OUT) - Error from the API + mode (IN) - mode of operation (OCI_DEFAULT) +Example + +Returns + error if any + +Related Functions + OCIAppCtxSet +---------------------- OCIIntervalAssign --------------------------------- +sword OCIIntervalAssign(void *hndl, OCIError *err, + const OCIInterval *inpinter, OCIInterval *outinter ); + + DESCRIPTION + Copies one interval to another to create a replica + PARAMETERS + hndl (IN) - Session/Env handle. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + (IN) inpinter - Input Interval + (OUT) outinter - Output Interval + RETURNS + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_SUCCESS otherwise + + ---------------------- OCIIntervalCheck ------------------------------------ +sword OCIIntervalCheck(void *hndl, OCIError *err, const OCIInterval *interval, + ub4 *valid ); + + DESCRIPTION + Checks the validity of an interval + PARAMETERS + hndl (IN) - Session/Env handle. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + (IN) interval - Interval to be checked + (OUT) valid - Zero if the interval is valid, else returns an Ored + combination of the following codes. + + Macro name Bit number Error + ---------- ---------- ----- + OCI_INTER_INVALID_DAY 0x1 Bad day + OCI_INTER_DAY_BELOW_VALID 0x2 Bad DAy Low/high bit (1=low) + OCI_INTER_INVALID_MONTH 0x4 Bad MOnth + OCI_INTER_MONTH_BELOW_VALID 0x8 Bad MOnth Low/high bit (1=low) + OCI_INTER_INVALID_YEAR 0x10 Bad YeaR + OCI_INTER_YEAR_BELOW_VALID 0x20 Bad YeaR Low/high bit (1=low) + OCI_INTER_INVALID_HOUR 0x40 Bad HouR + OCI_INTER_HOUR_BELOW_VALID 0x80 Bad HouR Low/high bit (1=low) + OCI_INTER_INVALID_MINUTE 0x100 Bad MiNute + OCI_INTER_MINUTE_BELOW_VALID 0x200 Bad MiNute Low/high bit(1=low) + OCI_INTER_INVALID_SECOND 0x400 Bad SeCond + OCI_INTER_SECOND_BELOW_VALID 0x800 bad second Low/high bit(1=low) + OCI_INTER_INVALID_FRACSEC 0x1000 Bad Fractional second + OCI_INTER_FRACSEC_BELOW_VALID 0x2000 Bad fractional second Low/High + + + RETURNS + OCI_SUCCESS if interval is okay + OCI_INVALID_HANDLE if 'err' is NULL. + + ---------------------- OCIIntervalCompare ----------------------------------- +sword OCIIntervalCompare(void *hndl, OCIError *err, OCIInterval *inter1, + OCIInterval *inter2, sword *result ); + + DESCRIPTION + Compares two intervals, returns 0 if equal, -1 if inter1 < inter2, + 1 if inter1 > inter2 + PARAMETERS + hndl (IN) - Session/Env handle. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + inter1 (IN) - Interval to be compared + inter2 (IN) - Interval to be compared + result (OUT) - comparison result, 0 if equal, -1 if inter1 < inter2, + 1 if inter1 > inter2 + + RETURNS + OCI_SUCCESS on success + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + the two input datetimes are not mutually comparable. + +---------------------- OCIIntervalDivide ------------------------------------ +sword OCIIntervalDivide(void *hndl, OCIError *err, OCIInterval *dividend, + OCINumber *divisor, OCIInterval *result ); + + DESCRIPTION + Divides an interval by an Oracle Number to produce an interval + PARAMETERS + hndl (IN) - Session/Env handle. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + dividend (IN) - Interval to be divided + divisor (IN) - Oracle Number dividing `dividend' + result (OUT) - resulting interval (dividend / divisor) + RETURNS + OCI_SUCCESS on success + OCI_INVALID_HANDLE if 'err' is NULL. + + ---------------------- OCIIntervalFromNumber -------------------- +sword OCIIntervalFromNumber(void *hndl, OCIError *err, + OCIInterval *inter, OCINumber *number); + DESCRIPTION + Converts an interval to an Oracle Number + PARAMETERS + hndl (IN) - Session/Env handle. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + (OUT) interval - Interval to be converted + (IN) number - Oracle number result (in years for YEARMONTH interval + and in days for DAYSECOND) + RETURNS + OCI_SUCCESS on success + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR on error. + NOTES + Fractional portions of the date (for instance, minutes and seconds if + the unit chosen is hours) will be included in the Oracle number produced. + Excess precision will be truncated. + + ---------------------- OCIIntervalFromText --------------------------------- +sword OCIIntervalFromText( void *hndl, OCIError *err, const OraText *inpstr, + size_t str_len, OCIInterval *result ); + + DESCRIPTION + Given an interval string produce the interval represented by the string. + The type of the interval is the type of the 'result' descriptor. + PARAMETERS + + hndl (IN) - Session/Env handle. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + (IN) inpstr - Input string + (IN) str_len - Length of input string + (OUT) result - Resultant interval + RETURNS + OCI_SUCCESS on success + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + there are too many fields in the literal string + the year is out of range (-4713 to 9999) + if the month is out of range (1 to 12) + if the day of month is out of range (1 to 28...31) + if hour is not in range (0 to 23) + if hour is not in range (0 to 11) + if minute is not in range (0 to 59) + if seconds in minute not in range (0 to 59) + if seconds in day not in range (0 to 86399) + if the interval is invalid + + + ---------------------- OCIIntervalGetDaySecond -------------------- + + DESCRIPTION + Gets values of day second interval + PARAMETERS + hndl (IN) - Session/Env handle. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + day (OUT) - number of days + hour (OUT) - number of hours + min (OUT) - number of mins + sec (OUT) - number of secs + fsec (OUT) - number of fractional seconds + result (IN) - resulting interval + RETURNS + OCI_SUCCESS on success + OCI_INVALID_HANDLE if 'err' is NULL. + + + ---------------------- OCIIntervalGetYearMonth -------------------- + + DESCRIPTION + Gets year month from an interval + PARAMETERS + hndl (IN) - Session/Env handle. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + year (OUT) - year value + month (OUT) - month value + result (IN) - resulting interval + RETURNS + OCI_SUCCESS on success + OCI_INVALID_HANDLE if 'err' is NULL. + + + +-------------------------- OCIIntervalAdd ------------------------------ +sword OCIIntervalAdd(void *hndl, OCIError *err, OCIInterval *addend1, + OCIInterval *addend2, OCIInterval *result ); +NAME OCIIntervalAdd - Adds two intervals +PARAMETERS +hndl (IN) - Session/Env handle. +err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). +addend1 (IN) - Interval to be added +addend2 (IN) - Interval to be added +result (OUT) - resulting interval (addend1 + addend2) +DESCRIPTION + Adds two intervals to produce a resulting interval +RETURNS + OCI_SUCCESS on success + OCI_ERROR if: + the two input intervals are not mutually comparable. + the resulting year would go above SB4MAXVAL + the resulting year would go below SB4MINVAL + OCI_INVALID_HANDLE if 'err' is NULL. +NOTES + The two input intervals must be mutually comparable + + ---------------------- OCIIntervalSubtract ------------------------------- +sword OCIIntervalSubtract(void *hndl, OCIError *err, OCIInterval *minuend, + OCIInterval *subtrahend, OCIInterval *result ); +NAME - OCIIntervalSubtract - subtracts two intervals +PARAMETERS +hndl (IN) - Session/Env handle. +err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). +minuend (IN) - interval to be subtracted from +subtrahend (IN) - interval subtracted from minuend +result (OUT) - resulting interval (minuend - subtrahend) +DESCRIPTION + Subtracts two intervals and stores the result in an interval +RETURNS + OCI_SUCCESS on success + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if: + the two input intervals are not mutually comparable. + the resulting leading field would go below SB4MINVAL + the resulting leading field would go above SB4MAXVAL + +---------------------- OCIIntervalMultiply --------------------------------- +sword OCIIntervalMultiply(void *hndl, OCIError *err, const OCIInterval *inter, + OCINumber *nfactor, OCIInterval *result ); + + DESCRIPTION + Multiplies an interval by an Oracle Number to produce an interval + PARAMETERS + hndl (IN) - Session/Env handle. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + inter (IN) - Interval to be multiplied + nfactor (IN) - Oracle Number to be multiplied + result (OUT) - resulting interval (ifactor * nfactor) + RETURNS + OCI_SUCCESS on success + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if: + the resulting year would go above SB4MAXVAL + the resulting year would go below SB4MINVAL + + + ---------------------- OCIIntervalSetDaySecond -------------------- + + DESCRIPTION + Sets day second interval + PARAMETERS + hndl (IN) - Session/Env handle. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + day (IN) - number of days + hour (IN) - number of hours + min (IN) - number of mins + sec (IN) - number of secs + fsec (IN) - number of fractional seconds + result (OUT) - resulting interval + RETURNS + OCI_SUCCESS on success + OCI_INVALID_HANDLE if 'err' is NULL. + + + ---------------------- OCIIntervalSetYearMonth -------------------- + + DESCRIPTION + Sets year month interval + PARAMETERS + hndl (IN) - Session/Env handle. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + year (IN) - year value + month (IN) - month value + result (OUT) - resulting interval + RETURNS + OCI_SUCCESS on success + OCI_INVALID_HANDLE if 'err' is NULL. + + +----------------------- OCIIntervalToNumber --------------------------------- +sword OCIIntervalToNumber(void *hndl, OCIError *err, const OCIInterval *inter, + OCINumber *number); + + DESCRIPTION + Converts an interval to an Oracle Number + PARAMETERS + hndl (IN) - Session/Env handle. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + (IN) inter - Interval to be converted + (OUT) number - Oracle number result (in years for YEARMONTH interval + and in days for DAYSECOND) + RETURNS + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_SUCCESS on success + NOTES + Fractional portions of the date (for instance, minutes and seconds if + the unit chosen is hours) will be included in the Oracle number produced. + Excess precision will be truncated. + +------------------------------- OCIIntervalToText ------------------------- +sword OCIIntervalToText( void *hndl, OCIError *err, const OCIInterval *inter, + ub1 lfprec, ub1 fsprec, OraText *buffer, + size_t buflen, size_t *resultlen ); + + DESCRIPTION + Given an interval, produces a string representing the interval. + PARAMETERS + hndl (IN) - Session/Env handle. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + (IN) inter - Interval to be converted + (IN) lfprec - Leading field precision. Number of digits used to + represent the leading field. + (IN) fsprec - Fractional second precision of the interval. Number of + digits used to represent the fractional seconds. + (OUT) buffer - buffer to hold result + (IN) buflen - length of above buffer + (OUT) resultlen - length of result placed into buffer + + RETURNS + OCI_SUCCESS on success + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR + if the buffer is not large enough to hold the result + NOTES + The interval literal will be output as `year' or `[year-]month' for + YEAR-MONTH intervals and as `seconds' or `minutes[:seconds]' or + `hours[:minutes[:seconds]]' or `days[ hours[:minutes[:seconds]]]' for + DAY-TIME intervals (where optional fields are surrounded by brackets). + + ---------------------- OCIIntervalFromTZ -------------------- +sword OCIIntervalFromTZ(void *hndl, OCIError *err, const oratext *inpstring, + size_t str_len, OCIInterval *result); + + DESCRIPTION + Retuns an OCI_DTYPE_INTERVAL_DS OCIInterval with the region id (if + the region is specified in the input string) set and the current + absolute offset or an absolut offset with the region id set to 0. + PARAMETERS + hndl (IN) - Session/Env handle. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + inpstring (IN) - pointer to the input string + str_len (IN) - inpstring length + result - Output Interval + RETURNS + OCI_SUCCESS on success + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR on error + Bad interval type + Timezone errors + NOTES + The input string must be of the form [+/-]TZH:TZM or 'TZR [TZD]' + + ----------------------- OCIKerbAttrSet --------------------- +sword OCIKerbAttrSet(OCISession *trgthndlp, ub4 auth_mode, + ub1 *ftgt_ticket, ub4 ftgt_ticket_len, + ub1 *ftgt_sesskey, ub4 ftgt_sesskey_len, + ub2 ftgt_keytype, ub4 ftgt_ticket_flags, + sb4 ftgt_auth_time, sb4 ftgt_start_time, + sb4 ftgt_end_time, sb4 ftgt_renew_time, + oratext *ftgt_principal, ub4 ftgt_principal_len, + oratext *ftgt_realm, ub4 ftgt_realm_len, + OCIError *errhp); + + DESCRIPTION + This call sets the attributes required for Kerberos authentication + on the user handle. + + PARAMETERS + trgthndlp (IN) - The pointer to a user handle. + auth_mode (IN) - Indicates what type of Kerberos credentials should + be set. Options are: + + OCI_KERBCRED_PROXY + - Set Kerberos credentials for use with + proxy authentication. + OCI_KERBCRED_CLIENT_IDENTIFIER + - Set Kerberos credentials for use + with secure client identifier. + + ftgt_ticket (IN) - Forwardable Ticket Granting Ticket (FTGT). + ftgt_ticket_len (IN) - Length of FTGT. + ftgt_sesskey(IN) - Session Key associated with FTGT. + ftgt_sesskey_len (IN) - Length of session key. + ftgt_keytype (IN) - Type of encryption key used to encrypt FTGT. + ftgt_ticket_flags (IN) - Flags associated with encryption of FTGT. + ftgt_auth_time (IN) - Authentication time compatible with that in FTGT. + ftgt_start_time (IN) - Start time compatible with that indicated in FTGT. + ftgt_end_time (IN) - End time compatible with that indicated in FTGT. + ftgt_renew_time (IN) - Renew time compatible with that indicated in FTGT. + ftgt_principal (IN) - Client principal name from FTGT. + ftgt_principal_len (IN) - Length of client principal name. + ftgt_realm (IN) - Client realm name from FTGT. + ftgt_realm_len (IN) - Client realm name length. + errhp (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + RETURNS + OCI_SUCCESS on success + OCI_ERROR on error + NOTES + +OCILdaToSvcCtx() +Name +OCI toggle version 7 Lda_Def to SerVice context handle +Purpose +Converts a V7 Lda_Def to a V8 service context handle. +Syntax +sword OCILdaToSvcCtx ( OCISvcCtx **svchpp, + OCIError *errhp, + Lda_Def *ldap ); +Comments +Converts a V7 Lda_Def to a V8 service context handle. The action of this call +can be reversed by passing the resulting service context handle to the +OCISvcCtxToLda() function. +Parameters +svchpp (IN/OUT) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +ldap (IN/OUT) - the V7 logon data area returned by OCISvcCtxToLda() from +this service context. +Related Functions +OCISvcCtxToLda() + + + + +OCILobAppend() + +Name +OCI Lob APpend + +Purpose +Appends a LOB value at the end of another LOB. + +Syntax +sword OCILobAppend ( OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *dst_locp, + OCILobLocator *src_locp ); +Comments +Appends a LOB value at the end of LOB. The data is +copied from the source to the destination at the end of the destination. The +source and the destination must already exist. The destination LOB is +extended to accommodate the newly written data. + +It is an error to extend the destination LOB beyond the maximum length +allowed or to try to copy from a NULL LOB. + +Parameters +svchp (IN) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +dst_locp (IN/OUT) - a locator uniquely referencing the destination LOB. +src_locp (IN/OUT) - a locator uniquely referencing the source LOB. + +Related Functions +OCILobTrim() +OCIErrorGet() +OCILobWrite() +OCILobCopy() + + + +OCILobAssign() + +Name +OCI Lob ASsiGn + +Purpose +Assigns one LOB/FILE locator to another. + +Syntax +sword OCILobAssign ( OCIEnv *envhp, + OCIError *errhp, + const OCILobLocator *src_locp, + OCILobLocator **dst_locpp ); + +Comments +Assign source locator to destination locator. After the assignment, both +locators refer to the same LOB data. For internal LOBs, the source locator's +LOB data gets copied to the destination locator's LOB data only when the +destination locator gets stored in the table. Therefore, issuing a flush of +the object containing the destination locator will copy the LOB data. For +FILEs only the locator that refers to the OS file is copied to the table. The +OS file is not copied. +Note: The only difference between this and OCILobLocatorAssign is that this +takes an environment handle whereas OCILobLocatorAssign takes an OCI service +handle + +Parameters +envhp (IN/OUT) - OCI environment handle initialized in object mode. +errhp (IN/OUT) - The OCI error handle. If there is an error, it is recorded +in errhp and this function returns OCI_ERROR. Diagnostic information can be +obtained by calling OCIErrorGet(). +src_locp (IN) - LOB locator to copy from. +dst_locpp (IN/OUT) - LOB locator to copy to. The caller must allocate space +for the OCILobLocator by calling OCIDescriptorAlloc(). + +See also +OCIErrorGet() +OCILobIsEqual() +OCILobLocatorIsInit() +OCILobLocatorAssign() + + +OCILobCharSetForm() + +Name +OCI Lob Get Character Set Form + +Purpose +Gets the LOB locator's character set fpr,, if any. + +Syntax +sword OCILobCharSetForm ( OCIEnv *envhp, + OCIError *errhp, + const OCILobLocator *locp, + ub1 *csfrm ); + +Comments +Returns the character set form of the input LOB locator in the csfrm output +parameter. + +Parameters +envhp (IN/OUT) - OCI environment handle initialized in object mode. +errhp (IN/OUT) - error handle. The OCI error handle. If there is an error, it +is recorded in err and this function returns OCI_ERROR. Diagnostic +information can be obtained by calling OCIErrorGet(). +locp (IN) - LOB locator for which to get the character set form. +csfrm(OUT) - character set form of the input LOB locator. If the input +locator is for a BLOB or a BFILE, csfrm is set to 0 since there is no concept +of a character set for binary LOBs/FILEs. The caller must allocate space for +the csfrm (ub1) and not write into the space. +See also +OCIErrorGet(), OCILobCharSetId(), OCILobLocatorIsInit + + + +OCILobCharSetId() + +Name +OCI Lob get Character Set IDentifier + +Purpose +Gets the LOB locator's character set ID, if any. + +Syntax +sword OCILobCharSetId ( OCIEnv *envhp, + OCIError *errhp, + const OCILobLocator *locp, + ub2 *csid ); + +Comments +Returns the character set ID of the input LOB locator in the cid output +parameter. + +Parameters +envhp (IN/OUT) - OCI environment handle initialized in object mode. +errhp (IN/OUT) - error handle. The OCI error handle. If there is an error, it +is recorded in err and this function returns OCI_ERROR. Diagnostic +information can be obtained by calling OCIErrorGet(). +locp (IN) - LOB locator for which to get the character set ID. +csid (OUT) - character set ID of the input LOB locator. If the input locator +is for a BLOB or a BFILE, csid is set to 0 since there is no concept of a +character set for binary LOBs/FILEs. The caller must allocate space for the +character set id of type ub2 and not write into the space. + +See also +OCIErrorGet(), OCILobCharSetForm(), OCILobLocatorIsInit() + + + +OCILobCopy() + +Name +OCI Lob Copy + +Purpose +Copies a portion of a LOB value into another LOB value. + +Syntax +sword OCILobCopy ( OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *dst_locp, + OCILobLocator *src_locp, + ub4 amount, + ub4 dst_offset, + ub4 src_offset ); + +Comments +Copies a portion of a LOB value into another LOB as specified. The data +is copied from the source to the destination. The source (src_locp) and the +destination (dlopb) LOBs must already exist. +If the data already exists at the destination's start position, it is +overwritten with the source data. If the destination's start position is +beyond the end of the current data, a hole is created from the end of the data +to the beginning of the newly written data from the source. The destination +LOB is extended to accommodate the newly written data if it extends +beyond the current length of the destination LOB. +It is an error to extend the destination LOB beyond the maximum length +allowed or to try to copy from a NULL LOB. +Parameters +svchp (IN) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +dst_locp (IN/OUT) - a locator uniquely referencing the destination LOB. +src_locp (IN/OUT) - a locator uniquely referencing the source LOB. +amount (IN) - the number of character or bytes, as appropriate, to be copied. +dst_offset (IN) - this is the absolute offset for the destination LOB. +For character LOBs it is the number of characters from the beginning of the +LOB at which to begin writing. For binary LOBs it is the number of bytes from +the beginning of the lob from which to begin reading. The offset starts at 1. +src_offset (IN) - this is the absolute offset for the source LOB. +For character LOBs it is the number of characters from the beginning of the +LOB, for binary LOBs it is the number of bytes. Starts at 1. + +See Also +OCIErrorGet(), OCILobAppend(), OCILobWrite(), OCILobTrim() + +OCILobCreateTemporary() + +Name +OCI Lob Create Temporary + +Purpose +Create a Temporary Lob + +Syntax +sword OCILobCreateTemporary(OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp, + ub2 csid, + ub1 csfrm, + ub1 lobtype, + boolean cache, + OCIDuration duration); + + +Comments +svchp (IN) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +locp (IN/OUT) - a locator which points to the temporary Lob +csid (IN) - the character set id +csfrm(IN) - the character set form +lobtype (IN) - the lob type - one of the three constants OCI_TEMP_BLOB, + OCI_TEMP_CLOB and OCI_TEMP_NCLOB +cache(IN)- TRUE if the temporary LOB goes through the cache; FALSE, if not. +duration(IN)- duration of the temporary LOB; Can be a valid duration id or one + of the values: OCI_DURATION_SESSION, OCI_DURATION_CALL + Note: OCI_DURATION_TRANSACTION is NOT supported in 8.1 +Related functions +OCILobFreeTemporary() +OCILobIsTemporary() + +OCILobDisableBuffering() + +Name +OCI Lob Disable Buffering + +Purpose +Disable lob buffering for the input locator. + + +Syntax +sword OCILobDisableBuffering ( OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp); + +Comments + +Disable lob buffering for the input locator. The next time data is +read/written from/to the lob through the input locator, the lob +buffering subsystem is *not* used. Note that this call does *not* +implicitly flush the changes made in the buffering subsystem. The +user must explicitly call OCILobFlushBuffer() to do this. + +Parameters +svchp (IN) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +locp (IN/OUT) - a locator uniquely referencing the LOB. + +Related Functions +OCILobEnableBuffering() +OCIErrorGet() +OCILobFlushBuffer() + + + + +OCILobEnableBuffering() + +Name +OCI Lob Enable Buffering + +Purpose +Enable lob buffering for the input locator. + + +Syntax +sword OCILobEnableBuffering ( OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp); + +Comments + +Enable lob buffering for the input locator. The next time data is +read/written from/to the lob through the input locator, the lob +buffering subsystem is used. + +Once lob buffering is enabled for a locator, if that locator is passed to +one of the following routines, an error is returned: + OCILobCopy, OCILobAppend, OCILobErase, OCILobGetLength, OCILobTrim + +Parameters +svchp (IN) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +locp (IN/OUT) - a locator uniquely referencing the LOB. + +Related Functions +OCILobDisableBuffering() +OCIErrorGet() +OCILobWrite() +OCILobRead() +OCILobFlushBuffer() + + + + +OCILobErase() + +Name +OCI Lob ERase + +Purpose +Erases a specified portion of the LOB data starting at a specified offset. + +Syntax +sword OCILobErase ( OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp, + ub4 *amount, + ub4 offset ); + +Comments +Erases a specified portion of the LOB data starting at a specified offset. +The actual number of characters/bytes erased is returned. The actual number +of characters/bytes and the requested number of characters/bytes will differ +if the end of the LOB data is reached before erasing the requested number of +characters/bytes. +If a section of data from the middle of the LOB data is erased, a hole is +created. When data from that hole is read, 0's are returned. If the LOB is +NULL, this routine will indicate that 0 characters/bytes were erased. + +Parameters +svchp (IN) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +locp (IN/OUT) - the LOB for which to erase a section of data. +amount (IN/OUT) - On IN, the number of characters/bytes to erase. On OUT, +the actual number of characters/bytes erased. +offset (IN) - absolute offset from the beginning of the LOB data from which +to start erasing data. Starts at 1. + +See Also +OCIErrorGet(), OCILobRead(), OCILobWrite() + +OCILobOpen() + +Name +OCI Lob Open + +Purpose +Opens an internal or external Lob. + +Syntax +sword OCILobOpen( OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp, + ub1 mode ); + +Comments +It is an error if the same lob is opened more than once in +the same transaction. Lobs are opened implicitly if they are +not opened before using them. A LOB has to be closed before +the transaction commits else the transaction is rolled back. +Open locators are closed if the transaction aborts. Multiple +users can open the same lob on different locators. +Parameters +svchp (IN) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +locp (IN/OUT) - locator points to the LOB to be opened +mode (IN) - mode in which to open the lob. The valid modes are +read-only - OCI_FILE_READONLY, read-write - OCI_FILE_READWRITE + +OCILobClose() + +Name +OCI Lob Close + +Purpose +Closes an open internal or external Lob. + +Syntax +sword OCILobClose( OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp ); + + +Comments +It is an error if the lob is not open at this time. All LOBs +that have been opened in a transaction have to be closed +before the transaction commits, else the transaction gets +rolled back. + +Parameters +svchp (IN) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +locp (IN) - A locator that was opened using OCILobOpen() + + +OCILobFileClose() + +Name +OCI Lob File CLoSe + +Purpose +Closes a previously opened FILE. + +Syntax +sword OCILobFileClose ( OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *filep ); + +Comments +Closes a previously opened FILE. It is an error if this function is called for +an internal LOB. No error is returned if the FILE exists but is not opened. +Parameters +svchp (IN) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +filep (IN/OUT) - a pointer to a FILE locator to be closed. + +See Also +OCIErrorGet(), OCILobFileOpen(), OCILobFileCloseAll(), OCILobFileIsOpen(), +OCILobFileExists(), CREATE DIRECTORY DDL + + + + +OCILobFileCloseAll() + +Name +OCI LOB FILE Close All + +Purpose +Closes all open FILEs on a given service context. + +Syntax +sword OCILobFileCLoseAll ( OCISvcCtx *svchp, + OCIError *errhp ); + +Comments +Closes all open FILEs on a given service context. + +Parameters +svchp (IN) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. + +See also +OCILobFileClose(), +OCIErrorGet(), OCILobFileOpen(), OCILobFileIsOpen(), +OCILobFileExists(), CREATE DIRECTORY DDL + + + + +OCILobFileExists() + +Name +OCI LOB FILE exists + +Purpose +Tests to see if the FILE exists on the server + +Syntax +sword OCILobFileExists ( OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *filep, + boolean *flag ); + +Comments +Checks to see if a FILE exists for on the server. + +Parameters +svchp (IN) - the OCI service context handle. +errhp (IN/OUT) - error handle. The OCI error handle. If there is an error, +it is recorded in err and this function returns OCI_ERROR. Diagnostic +information can be obtained by calling OCIErrorGet(). +filep (IN) - pointer to the FILE locator that refers to the file. +flag (OUT) - returns TRUE if the FILE exists; FALSE if it does not. + +See also +OCIErrorGet, CREATE DIRECTORY (DDL) + + + + +OCILobFileGetName() + +Name +OCI LOB FILE Get file Name + +Purpose +Gets the FILE locator's directory alias and file name. + +Syntax +sword OCILobFileGetName ( OCIEnv *envhp, + OCIError *errhp, + const OCILobLocator *filep, + OraText *dir_alias, + ub2 *d_length, + OraText *filename, + ub2 *f_length ); + +Comments +Returns the directory alias and file name associated with this file locator. + +Parameters +envhp (IN/OUT) - OCI environment handle initialized in object mode. +errhp (IN/OUT) -The OCI error handle. If there is an error, it is recorded in +errhp and this function returns OCI_ERROR. Diagnostic information can be +obtained by calling OCIErrorGet(). +filep (IN) - FILE locator for which to get the directory alias and file name. +dir_alias (OUT) - buffer into which the directory alias name is placed. The +caller must allocate enough space for the directory alias name and must not +write into the space. +d_length (IN/OUT) + - IN: length of the input dir_alias string; + - OUT: length of the returned dir_alias string. +filename (OUT) - buffer into which the file name is placed. The caller must +allocate enough space for the file name and must not write into the space. +f_length (IN/OUT) + - IN: length of the input filename string; + - OUT: lenght of the returned filename string. + +See also +OCILobFileSetName(), OCIErrorGet() + + + + +OCILobFileIsOpen() + +Name +OCI LOB FILE Is Open? + +Purpose +Tests to see if the FILE is open + +Syntax +sword OCILobFileIsOpen ( OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *filep, + boolean *flag ); + +Comments +Checks to see if the FILE on the server is open for a given LobLocator. + +Parameters +svchp (IN) - the OCI service context handle. +errhp (IN/OUT) - error handle. The OCI error handle. If there is an error, it +is recorded in err and this function returns OCI_ERROR. Diagnostic +information can be obtained by calling OCIErrorGet(). +filep (IN) - pointer to the FILE locator being examined. If the input file +locator was never passed to OCILobFileOpen(), the file is considered not to +be opened by this locator. However, a different locator may have opened the +file. More than one file opens can be performed on the same file using +different locators. +flag (OUT) - returns TRUE if the FILE is opened using this locator; FALSE if +it is not. + +See also +OCIErrorGet, OCILobFileOpen, OCILobFileClose, OCILobFileCloseAll, CREATE +DIRECTORY SQL command + + +OCILobFileOpen() + +Name +OCI LOB FILE open + +Purpose +Opens a FILE for read-only access + +Syntax +sword OCILobFileOpen ( OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *filep, + ub1 mode ); + +Comments +Opens a FILE. The FILE can be opened for read-only access only. FILEs may not +be written to throough ORACLE. + +Parameters +svchp (IN) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +filep (IN/OUT) - the FILE to open. Error if the locator does not refer to a +FILE. +mode (IN) - mode in which to open the file. The only valid mode is +read-only - OCI_FILE_READONLY. + +See Also +OCILobFileClose, OCIErrorGet, OCILobFileCloseAll, OCILobFileIsOpen, +OCILobFileSetName, CREATE DIRECTORY + + + + +OCILobFileSetName() + +Name +OCI Lob File Set NaMe + +Purpose +Sets directory alias and file name in the FILE locator. + +Syntax +sword OCILobFileSetName ( OCIEnv *envhp, + OCIError *errhp, + OCILobLocator **filepp, + OraText *dir_alias, + ub2 d_length, + OraText *filename, + ub2 f_length ); +Comments +Sets the directory alias and file name in the LOB file locator. +Parameters +envhp (IN/OUT) - OCI environment handle initialized in object mode. +errhp (IN/OUT) - The OCI error handle. If there is an error, it is recorded +in errhp and this function returns OCI_ERROR. Diagnostic information can be +obtained by calling OCIErrorGet(). +filepp (IN/OUT) - FILE locator for which to set the directory alias name. +The caller must have already allocated space for the locator by calling +OCIDescriptorAlloc(). +dir_alias (IN) - buffer that contains the directory alias name to set in the +locator. +d_length (IN) - length of the input dir_alias parameter. +filename (IN) - buffer that contains the file name is placed. +f_length (IN) - length of the input filename parameter. +See also +OCILobFileGetName, OCIErrorGet, CREATE DIRECTORY + + + + +OCILobFlushBuffer() + +Name +OCI Lob Flush all Buffers for this lob. + +Purpose +Flush/write all buffers for this lob to the server. + + +Syntax +sword OCILobFlushBuffer ( OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp, + ub4 flag); + +Comments + +Flushes to the server, changes made to the buffering subsystem that +are associated with the lob referenced by the input locator. This +routine will actually write the data in the buffer to the lob in +the database. Lob buffering must have already been enabled for the +input lob locator. + +This routine, by default, does not free the buffer resources for +reallocation to another buffered LOB operation. However, if you +want to free the buffer explicitly, you can set the flag parameter +to OCI_LOB_BUFFER_FREE. + +Parameters +svchp (IN/OUT) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +locp (IN/OUT) - a locator uniquely referencing the LOB. +flag (IN) - to indicate if the buffer resources need to be freed + after a flush. Default value is OCI_LOB_BUFFER_NOFREE. + Set it to OCI_LOB_BUFFER_FREE if you want the buffer + resources to be freed. +Related Functions +OCILobEnableBuffering() +OCILobDisableBuffering() +OCIErrorGet() +OCILobWrite() +OCILobRead() + + +OCILobFreeTemporary() + +Name +OCI Lob Free Temporary + +Purpose +Free a temporary LOB + +Syntax +sword OCILobFreeTemporary(OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp); + +Comments + Frees the contents of the temporary Lob this locator is pointing to. Note + that the locator itself is not freed until a OCIDescriptorFree is done. + +Parameters +svchp (IN/OUT) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +locp (IN/OUT) - a locator uniquely referencing the LOB + +Related functions +OCILobCreateTemporary() +OCILobIsTemporary() + + +Name +OCI Lob/File Get Chunk Size + +Purpose +When creating the table, the user can specify the chunking factor, which can +be a multiple of Oracle blocks. This corresponds to the chunk size used by the +LOB data layer when accessing/modifying the LOB value. Part of the chunk is +used to store system-related information and the rest stores the LOB value. +This function returns the amount of space used in the LOB chunk to store +the LOB value. + +Syntax +sword OCILobGetChunkSize ( OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp, + ub4 *chunksizep ); + +Comments + Performance will be improved if the user issues read/write +requests using a multiple of this chunk size. For writes, there is an added +benefit since LOB chunks are versioned and, if all writes are done on chunk +basis, no extra/excess versioning is done nor duplicated. Users could batch +up the write until they have enough for a chunk instead of issuing several +write calls for the same chunk. + +Parameters +svchp (IN) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +locp (IN/OUT) - a LOB locator that uniquely references the LOB. For internal +LOBs, this locator must be a locator that was obtained from the server +specified by svchp. For FILEs, this locator can be initialized by a Select or +OCILobFileSetName. +chunksizep (OUT) - On output, it is the length of the LOB if not NULL - for +character LOBs it is the number of characters, for binary LOBs it is the +number of bytes in the LOB. + +Related Functions + +OCILobGetLength() + +Name +OCI Lob/File Length + +Purpose +Gets the length of a LOB/FILE. + +Syntax +sword OCILobGetLength ( OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp, + ub4 *lenp ); + +Comments +Gets the length of a LOB/FILE. If the LOB/FILE is NULL, the length is +undefined. + +Parameters +svchp (IN) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +locp (IN/OUT) - a LOB locator that uniquely references the LOB. For internal +LOBs, this locator must be a locator that was obtained from the server +specified by svchp. For FILEs, this locator can be initialized by a Select or +OCILobFileSetName. +lenp (OUT) - On output, it is the length of the LOB if not NULL - for +character LOBs it is the number of characters, for binary LOBs it is the +number of bytes in the LOB. + +Related Functions +OCIErrorGet, OCIFileSetName + + + +OCILobIsEqual() + +Name + +OCI Lob Is Equal + +Purpose +Compares two LOB locators for equality. + +Syntax +sword OCILobIsEqual ( OCIEnv *envhp, + const OCILobLocator *x, + const OCILobLocator *y, + boolean *is_equal ); + +Comments +Compares the given LOB locators for equality. Two LOB locators are equal if +and only if they both refer to the same LOB data. +Two NULL locators are considered not equal by this function. +Parameters +envhp (IN) - the OCI environment handle. +x (IN) - LOB locator to compare. +y (IN) - LOB locator to compare. +is_equal (OUT) - TRUE, if the LOB locators are equal; FALSE if they are not. + +See also +OCILobAssign, OCILobLocatorIsInit +OCILobLocatorAssign, +OCILobIsOpen() + +Name + +OCI Lob Is Open +sword OCILobIsOpen(svchp, errhp, locp, flag) +OCISvcCtx *svchp; +OCIError *errhp; +OCILobLocator *locp; +boolean *flag; + +Comments + Checks if the LOB locator was opened before. flag is set to TRUE + if opened; FALSE otherwise + + +Parameters +svchp (IN) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +locp (IN) - the locator to test for temporary LOB +flag(OUT) - TRUE, if the LOB locator points to is open + FALSE, if not. + +OCILobIsTemporary() + +Name + +OCI Lob Is Temporary + +Purpose + Tests if this locator points to a temporary LOB + +Syntax +sword OCILobIsTemporary(OCIEnv *envhp, + OCIError *errhp, + OCILobLocator *locp, + boolean *is_temporary); + +Comments +Tests the locator to determine if it points to a temporary LOB. +If so, is_temporary is set to TRUE. If not, is_temporary is set +to FALSE. + +Parameters +envhp (IN) - the environment handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +locp (IN) - the locator to test for temporary LOB +is_temporary(OUT) - TRUE, if the LOB locator points to a temporary LOB; + FALSE, if not. + +See Also +OCILobCreateTemporary, OCILobFreeTemporary + + +OCILobLoadFromFile() + +Name +OCI Lob Load From File + +Purpose +Load/copy all or a portion of the file into an internal LOB. + +Syntax +sword OCILobLoadFromFile ( OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *dst_locp, + OCILobLocator *src_filep, + ub4 amount, + ub4 dst_offset, + ub4 src_offset ); + +Comments +Loads/copies a portion or all of a file value into an internal LOB as +specified. The data is copied from the source file to the destination +internal LOB (BLOB/CLOB). No character set conversions are performed +when copying the bfile data to a clob/nclob. The bfile data must already +be in the same character set as the clob/nclob in the database. No +error checking is performed to verify this. +The source (src_filep) and the destination (dst_locp) LOBs must already exist. +If the data already exists at the destination's start position, it is +overwritten with the source data. If the destination's start position is +beyond the end of the current data, a hole is created from the end of the data +to the beginning of the newly written data from the source. The destination +LOB is extended to accommodate the newly written data if it extends +beyond the current length of the destination LOB. +It is an error to extend the destination LOB beyond the maximum length +allowed or to try to copy from a NULL LOB. +Parameters +svchp (IN) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +dst_locp (IN/OUT) - a locator uniquely referencing the destination internal +LOB which may be of type blob, clob, or nclob. +src_filep (IN/OUT) - a locator uniquely referencing the source BFILE. +amount (IN) - the number of bytes to be copied. +dst_offset (IN) - this is the absolute offset for the destination LOB. +For character LOBs it is the number of characters from the beginning of the +LOB at which to begin writing. For binary LOBs it is the number of bytes from +the beginning of the lob from which to begin reading. The offset starts at 1. +src_offset (IN) - this is the absolute offset for the source BFILE. It is +the number of bytes from the beginning of the LOB. The offset starts at 1. + +See Also +OCIErrorGet(), OCILobAppend(), OCILobWrite(), OCILobTrim(), OCILobCopy() + +OCILobLocatorAssign() + +Name +OCI Lob LOCATOR ASsiGn + +Purpose +Assigns one LOB/FILE locator to another. + +Syntax +sword OCILobLocatorAssign ( OCISvcCtx *svchp, + OCIError *errhp, + const OCILobLocator *src_locp, + OCILobLocator **dst_locpp ); + +Comments +Assign source locator to destination locator. After the assignment, both +locators refer to the same LOB data. For internal LOBs, the source locator's +LOB data gets copied to the destination locator's LOB data only when the +destination locator gets stored in the table. Therefore, issuing a flush of +the object containing the destination locator will copy the LOB data. For +FILEs only the locator that refers to the OS file is copied to the table. The +OS file is not copied. +Note : the only difference between this and OCILobAssign is that this takes +a OCI service handle pointer instead of a OCI environment handle pointer + +Parameters +svchp (IN/OUT) - OCI service handle initialized in object mode. +errhp (IN/OUT) - The OCI error handle. If there is an error, it is recorded +in errhp and this function returns OCI_ERROR. Diagnostic information can be +obtained by calling OCIErrorGet(). +src_locp (IN) - LOB locator to copy from. +dst_locpp (IN/OUT) - LOB locator to copy to. The caller must allocate space +for the OCILobLocator by calling OCIDescriptorAlloc(). + +See also +OCIErrorGet() +OCILobIsEqual() +OCILobLocatorIsInit() +OCILobAssign() + + + + +OCILobLocatorIsInit() + +Name +OCI LOB locator is initialized? + +Purpose +Tests to see if a given LOB locator is initialized. + +Syntax +sword OCILobLocatorIsInit ( OCIEnv *envhp, + OCIError *errhp, + const OCILobLocator *locp, + boolean *is_initialized ); + +Comments +Tests to see if a given LOB locator is initialized. + +Parameters +envhp (IN/OUT) - OCI environment handle initialized in object mode. +errhp (IN/OUT) - error handle. The OCI error handle. If there is an error, it +is recorded in err and this function returns OCI_ERROR. Diagnostic +information can be obtained by calling OCIErrorGet(). +locp (IN) - the LOB locator being tested +is_initialized (OUT) - returns TRUE if the given LOB locator is initialized; +FALSE if it is not. + +See also +OCIErrorGet, OCILobIsEqual + + + + +OCILobRead() + +Name +OCI Lob/File ReaD + +Purpose +Reads a portion of a LOB/FILE as specified by the call into a buffer. + +Syntax +sword OCILobRead ( OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp, + ub4 offset, + ub4 *amtp, + void *bufp, + ub4 bufl, + void *ctxp, + OCICallbackLobRead cbfp, + ub2 csid, + ub1 csfrm ); + +Comments +Reads a portion of a LOB/FILE as specified by the call into a buffer. Data +read from a hole is returned as 0s. It is an error to try to read from a NULL +LOB/FILE. The OS FILE must already exist on the server and must have been +opened using the input locator. Oracle must hav epermission to read the OS +file and user must have read permission on the directory object. + +Parameters +svchp (IN/OUT) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +locp (IN/OUT) - a LOB locator that uniquely references a LOB. +offset (IN) - On input, it is the absolute offset, for character LOBs in the +number of characters from the beginning of the LOB, for binary LOBs it is the +number of bytes. Starts from 1. +amtp (IN/OUT) - On input, the number of character or bytes to be read. On +output, the actual number of bytes or characters read. +If the amount of bytes to be read is larger than the buffer length it is +assumed that the LOB is being read in a streamed mode. On input if this value +is 0, then the data shall be read in streamed mode from the LOB until the end +of LOB. If the data is read in pieces, *amtp always contains the length of +the last piece read. If a callback function is defined, then this callback +function will be invoked each time bufl bytes are read off the pipe. Each +piece will be written into bufp. +If the callback function is not defined, then OCI_NEED_DATA error code will +be returned. The application must invoke the LOB read over and over again to +read more pieces of the LOB until the OCI_NEED_DATA error code is not +returned. The buffer pointer and the length can be different in each call +if the pieces are being read into different sizes and location. +bufp (IN) - the pointer to a buffer into which the piece will be read. The +length of the allocated memory is assumed to be bufl. +bufl (IN) - the length of the buffer in octets. +ctxp (IN) - the context for the call back function. Can be NULL. +cbfp (IN) - a callback that may be registered to be called for each piece. If +this is NULL, then OCI_NEED_DATA will be returned for each piece. +The callback function must return OCI_CONTINUE for the read to continue. +If any other error code is returned, the LOB read is aborted. + ctxp (IN) - the context for the call back function. Can be NULL. + bufp (IN) - a buffer pointer for the piece. + len (IN) - the length of length of current piece in bufp. + piece (IN) - which piece - OCI_FIRST_PIECE, OCI_NEXT_PIECE or + OCI_LAST_PIECE. +csid - the character set ID of the buffer data +csfrm - the character set form of the buffer data + +Related Functions +OCIErrorGet, OCILobWrite, OCILobFileOpen, OCILobFileSetName, CREATE DIRECTORY + + + + +OCILobTrim() + +Name + +OCI Lob Trim + +Purpose +Trims the lob value to a shorter length + +Syntax +sword OCILobTrim ( OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp, + ub4 newlen ); + +Comments +Truncates LOB data to a specified shorter length. + +Parameters +svchp (IN) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +locp (IN/OUT) - a LOB locator that uniquely references the LOB. This locator +must be a locator that was obtained from the server specified by svchp. +newlen (IN) - the new length of the LOB data, which must be less than or equal +to the current length. + +Related Functions +OCIErrorGet, OCILobWrite, OCiLobErase, OCILobAppend, OCILobCopy + + + + + +OCILobWrite() + +Name +OCI Lob Write + +Purpose +Writes a buffer into a LOB + +Syntax +sword OCILobWrite ( OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp, + ub4 offset, + ub4 *amtp, + void *bufp, + ub4 buflen, + ub1 piece, + void *ctxp, + OCICallbackLobWrite (cbfp) + ( + void *ctxp, + void *bufp, + ub4 *lenp, + ub1 *piecep ) + ub2 csid + ub1 csfrm ); + + +Comments +Writes a buffer into a LOB as specified. If LOB data already exists +it is overwritten with the data stored in the buffer. +The buffer can be written to the LOB in a single piece with this call, or +it can be provided piecewise using callbacks or a standard polling method. +If this value of the piece parameter is OCI_FIRST_PIECE, data must be +provided through callbacks or polling. +If a callback function is defined in the cbfp parameter, then this callback +function will be invoked to get the next piece after a piece is written to +the pipe. Each piece will be written from bufp. +If no callback function is defined, then OCILobWrite() returns the +OCI_NEED_DATA error code. The application must all OCILobWrite() again +to write more pieces of the LOB. In this mode, the buffer pointer and the +length can be different in each call if the pieces are of different sizes and +from different locations. A piece value of OCI_LAST_PIECE terminates the +piecewise write. + +Parameters +svchp (IN/OUT) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +locp (IN/OUT) - a LOB locator that uniquely references a LOB. +offset (IN) - On input, it is the absolute offset, for character LOBs in +the number of characters from the beginning of the LOB, for binary LOBs it +is the number of bytes. Starts at 1. +bufp (IN) - the pointer to a buffer from which the piece will be written. The +length of the allocated memory is assumed to be the value passed in bufl. +Even if the data is being written in pieces, bufp must contain the first +piece of the LOB when this call is invoked. +bufl (IN) - the length of the buffer in bytes. +Note: This parameter assumes an 8-bit byte. If your platform uses a +longer byte, the value of bufl must be adjusted accordingly. +piece (IN) - which piece of the buffer is being written. The default value for +this parameter is OCI_ONE_PIECE, indicating the buffer will be written in a +single piece. +The following other values are also possible for piecewise or callback mode: +OCI_FIRST_PIECE, OCI_NEXT_PIECE and OCI_LAST_PIECE. +amtp (IN/OUT) - On input, takes the number of character or bytes to be +written. On output, returns the actual number of bytes or characters written. +If the data is written in pieces, *amtp will contain the total length of the +pieces written at the end of the call (last piece written) and is undefined in +between. +(Note it is different from the piecewise read case) +ctxp (IN) - the context for the call back function. Can be NULL. +cbfp (IN) - a callback that may be registered to be called for each piece in +a piecewise write. If this is NULL, the standard polling method will be used. +The callback function must return OCI_CONTINUE for the write to continue. +If any other error code is returned, the LOB write is aborted. The +callback takes the following parameters: + ctxp (IN) - the context for the call back function. Can be NULL. + bufp (IN/OUT) - a buffer pointer for the piece. + lenp (IN/OUT) - the length of the buffer (in octets) and the length of + current piece in bufp (out octets). + piecep (OUT) - which piece - OCI_NEXT_PIECE or OCI_LAST_PIECE. +csid - the character set ID of the buffer data +csfrm - the character set form of the buffer data +Related Functions + +OCILobWriteAppend() + +Name +OCI Lob Write Append + +Purpose +Writes data to the end of a LOB value. This call provides the ability +to get the length of the data and append it to the end of the LOB in +a single round trip to the server. + +Syntax +sword OCILobWriteAppend ( OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp, + ub4 *amtp, + void *bufp, + ub4 buflen, + ub1 piece, + void *ctxp, + OCICallbackLobWrite (cbfp) + ( + void *ctxp, + void *bufp, + ub4 *lenp, + ub1 *piecep ) + ub2 csid + ub1 csfrm ); + + +Comments +Writes a buffer to the end of a LOB as specified. If LOB data already exists +it is overwritten with the data stored in the buffer. +The buffer can be written to the LOB in a single piece with this call, or +it can be provided piecewise using callbacks or a standard polling method. +If this value of the piece parameter is OCI_FIRST_PIECE, data must be +provided through callbacks or polling. +If a callback function is defined in the cbfp parameter, then this callback +function will be invoked to get the next piece after a piece is written to the +pipe. Each piece will be written from bufp. +If no callback function is defined, then OCILobWriteAppend() returns the +OCI_NEED_DATA error code. The application must all OCILobWriteAppend() again +to write more pieces of the LOB. In this mode, the buffer pointer and the +length can be different in each call if the pieces are of different sizes and +from different locations. A piece value of OCI_LAST_PIECE terminates the +piecewise write. + +Parameters +svchp (IN/OUT) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +locp (IN/OUT) - a LOB locator that uniquely references a LOB. +bufp (IN) - the pointer to a buffer from which the piece will be written. The +length of the allocated memory is assumed to be the value passed in bufl. Even +if the data is being written in pieces, bufp must contain the first piece of +the LOB when this call is invoked. +bufl (IN) - the length of the buffer in bytes. +Note: This parameter assumes an 8-bit byte. If your platform uses a +longer byte, the value of bufl must be adjusted accordingly. +piece (IN) - which piece of the buffer is being written. The default value for +this parameter is OCI_ONE_PIECE, indicating the buffer will be written in a +single piece. +The following other values are also possible for piecewise or callback mode: +OCI_FIRST_PIECE, OCI_NEXT_PIECE and OCI_LAST_PIECE. +amtp (IN/OUT) - On input, takes the number of character or bytes to be +written. On output, returns the actual number of bytes or characters written. +If the data is written in pieces, *amtp will contain the total length of the +pieces written at the end of the call (last piece written) and is undefined in +between. +(Note it is different from the piecewise read case) +ctxp (IN) - the context for the call back function. Can be NULL. +cbfp (IN) - a callback that may be registered to be called for each piece in a +piecewise write. If this is NULL, the standard polling method will be used. +The callback function must return OCI_CONTINUE for the write to continue. +If any other error code is returned, the LOB write is aborted. The +callback takes the following parameters: + ctxp (IN) - the context for the call back function. Can be NULL. + bufp (IN/OUT) - a buffer pointer for the piece. + lenp (IN/OUT) - the length of the buffer (in octets) and the length of + current piece in bufp (out octets). + piecep (OUT) - which piece - OCI_NEXT_PIECE or OCI_LAST_PIECE. +csid - the character set ID of the buffer data +csfrm - the character set form of the buffer data +Related Functions + + + + +OCILobGetStorageLimit() + +Name +OCI Lob Get Storage Limit + +Purpose +To get the maximum Length of a LOB in bytes that can be stored in the database. + +Syntax +sword OCILobGetStorageLimit ( OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp, + oraub8 *limitp); + + +Comments +With unlimited size LOB support the limit for a LOB is no longer restricted +to 4GB. +This interface should be used to get the actual limit for storing data for +a specific +LOB locator. Note that if the compatibality is set to 9.2 or older the limit +would still be 4GB. + +Parameters +svchp (IN/OUT) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +locp (IN/OUT) - a LOB locator that uniquely references a LOB. +limitp (OUT) - The storage limit for a LOB in bytes. +Related Functions + + + + +OCILobGetOptions() + +Name +OCI Lob Get Options + +Purpose +To get the current options set for the given SecureFile. + +Syntax +sword OCILobGetOptions ( OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp, + ub4 optypes, + void *optionsp, + ub4 *optionslenp, + ub4 mode); + + +Comments +This function only works on SecureFiles. All others will get an error. + +Parameters +svchp (IN/OUT) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +locp (IN/OUT) - a LOB locator that uniquely references a LOB. +optypes (IN) - the types of options flags to be retrieved. +optionsp (OUT) - the options flags or value for the given types. +optionslenp (IN/OUT) - the length of option_value buffer +mode (IN) - for future use (pass 0 for now). +Related Functions +OCISetOptions() + +OCILobSetOptions() + +Name +OCI Lob Set Options + +Purpose +To set the options for the given LOCAL Lob. + +Syntax +sword OCILobSetOptions ( OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp, + ub4 optypes, + void *optionsp, + ub4 optionslen, + ub4 mode); + + +Comments +This function only works on LOCAL Lobs. All others will get an error. + +Parameters +svchp (IN/OUT) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +locp (IN/OUT) - a LOB locator that uniquely references a LOB. +optypes (IN) - the types of options flags to be set. +optionsp (IN) - the options flags or value to be set for the given types. +optionslen (IN) - then length of option_value buffer +mode (IN) - for future use (pass 0 for now). +Related Functions +OCILobGetOptions() + + + +OCILogoff() +Name +OCI simplified Logoff +Purpose +This function is used to terminate a session created with OCILogon() or +OCILogon2(). +Syntax +sword OCILogoff ( OCISvcCtx *svchp + OCIError *errhp ); +Comments +This call is used to terminate a session which was created with OCILogon() or +OCILogon2(). +This call implicitly deallocates the server, authentication, and service +context handles. +Note: For more information on logging on and off in an application, +refer to the section "Application Initialization, Connection, and +Authorization" on page 2-16. +Parameters +svchp (IN) - the service context handle which was used in the call to +OCILogon() or OCILogon2(). +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +See Also +OCILogon(), OCILogon2(). + + + + + + +OCILogon() +Name +OCI Service Context Logon +Purpose +This function is used to create a simple logon session. +Syntax +sword OCILogon ( OCIEnv *envhp, + OCIError *errhp, + OCISvcCtx *svchp, + const OraText *username, + ub4 uname_len, + const OraText *password, + ub4 passwd_len, + const OraText *dbname, + ub4 dbname_len ); +Comments +This function is used to create a simple logon session for an application. +Note: Users requiring more complex session (e.g., TP monitor +applications) should refer to the section "Application Initialization, +Connection, and Authorization" on page 2-16. +This call allocates the error and service context handles which are passed to +it. This call also implicitly allocates server and authentication handles +associated with the session. These handles can be retrieved by calling +OCIAttrGet() on the service context handle. +Parameters +envhp (IN) - the OCI environment handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +svchp (OUT) - the service context pointer. +username (IN) - the username. +uname_len (IN) - the length of username. +password (IN) - the user's password. +passwd_len (IN) - the length of password. +dbname (IN) - the name of the database to connect to. +dbname_len (IN) - the length of dbname. +See Also +OCILogoff() + + + + + +OCILogon2() +Name +OCI Service Context Logon +Purpose +This function is used to create a logon session in connection pooling mode. +Syntax +sword OCILogon2 ( OCIEnv *envhp, + OCIError *errhp, + OCISvcCtx **svchp, + const OraText *username, + ub4 uname_len, + const OraText *password, + ub4 passwd_len, + const OraText *dbname, + ub4 dbname_len, + ub4 mode); +Comments +This function is used to create a simple logon session for an application in +Connection Pooling mode. The valid values for mode are currently OCI_POOL and +OCI_DEFAULT. Call to this function with OCI_DEFAULT mode is equivalent to +OCILogon() call. +This call allocates the error and service context handles which are passed to +it. This call also implicitly allocates server and authentication handles +associated with the session. These handles can be retrieved by calling +OCIAttrGet() on the service context handle. This call assumes that +OCIConnectionPoolCreate() has already been called for the same dbname. +Parameters +envhp (IN) - the OCI environment handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +svchp (OUT) - the service context pointer. +username (IN) - the username. +uname_len (IN) - the length of username. +password (IN) - the user's password. If this is null, it is assumed that a + proxy session has to be created and the required grants on + the database are already done. +passwd_len (IN) - the length of password. +dbname (IN) - the name of the database to connect to. +dbname_len (IN) - the length of dbname. +mode (IN) - the mode for doing the server attach. Should be OCI_POOL for + using Connection Pooling. + + +See Also +OCILogoff() + + + + + +OCIMemoryFree() +Name +OCI FREE Memory +Purpose +Frees up storage associated with the pointer. +Syntax +void OCIMemoryFree ( const OCIStmt *stmhp, + void *memptr); +Comments +Frees up dynamically allocated data pointers associated with the pointer using +either the default memory free function or the registered memory free +function, as the case may be. +A user-defined memory free function can be registered during the initial call +to OCIInitialize(). +This call is always successful. +Parameters +stmhp (IN) - statement handle which returned this data buffer. +memptr (IN) - pointer to data allocated by the client library. +Related Functions +OCIInitialize() + + + + + +OCIParamGet() +Name +OCI Get PARaMeter +Purpose +Returns a descriptor of a parameter specified by position in the describe +handle or statement handle. +Syntax +sword OCIParamGet ( const void *hndlp, + ub4 htype, + OCIError *errhp, + void **parmdpp, + ub4 pos ); +Comments +This call returns a descriptor of a parameter specified by position in the +describe handle or statement handle. Parameter descriptors are always +allocated internally by the OCI library. They are read-only. +OCI_NO_DATA may be returned if there are no parameter descriptors for this +position. +See Appendix B for more detailed information about parameter descriptor +attributes. +Parameters +hndlp (IN) - a statement handle or describe handle. The OCIParamGet() +function will return a parameter descriptor for this handle. +htype (IN) - the type of the handle passed in the handle parameter. Valid +types are OCI_HTYPE_DESCRIBE, for a describe handle OCI_HTYPE_STMT, for a +statement handle +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +parmdpp (OUT) - a descriptor of the parameter at the position given in the pos +parameter. +pos (IN) - position number in the statement handle or describe handle. A +parameter descriptor will be returned for this position. +Note: OCI_NO_DATA may be returned if there are no parameter +descriptors for this position. +Related Functions +OCIAttrGet(), OCIAttrSet() + + + + + +OCIParamSet() +Name +OCI Parameter Set in handle +Purpose +Used to set a complex object retrieval descriptor into a complex object +retrieval handle. +Syntax +sword OCIParamGet ( void *hndlp, + ub4 htyp, + OCIError *errhp, + const void *dscp, + ub4 dtyp, + ub4 pos ); +Comments +This call sets a given complex object retrieval descriptor into a complex +object retrieval handle. +The handle must have been previously allocated using OCIHandleAlloc(), and +the descriptor must have been previously allocated using OCIDescAlloc(). +Attributes of the descriptor are set using OCIAttrSet(). +Parameters +hndlp (IN/OUT) - handle pointer. +htype (IN) - handle type. +errhp (IN/OUT) - error handle. +dscp (IN) - complex object retrieval descriptor pointer. +dtyp (IN) - +pos (IN) - position number. +See Also + + + + + +OCIPasswordChange() +Name +OCI Change PassWord +Purpose +This call allows the password of an account to be changed. +Syntax +sword OCIPasswordChange ( OCISvcCtx *svchp, + OCIError *errhp, + const OraText *user_name, + ub4 usernm_len, + const OraText *opasswd, + ub4 opasswd_len, + const OraText *npasswd, + sb4 npasswd_len, + ub4 mode); +Comments +This call allows the password of an account to be changed. This call is +similar to OCISessionBegin() with the following differences: +If the user authentication is already established, it authenticates +the account using the old password and then changes the +password to the new password +If the user authentication is not established, it establishes a user +authentication and authenticates the account using the old +password, then changes the password to the new password. +This call is useful when the password of an account is expired and +OCISessionBegin() returns an error or warning which indicates that the +password has expired. +Parameters +svchp (IN/OUT) - a handle to a service context. The service context handle +must be initialized and have a server context handle associated with it. +errhp (IN) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +user_name (IN) - specifies the user name. It points to a character string, +whose length is specified in usernm_len. This parameter must be NULL if the +service context has been initialized with an authentication handle. +usernm_len (IN) - the length of the user name string specified in user_name. +For a valid user name string, usernm_len must be non-zero. +opasswd (IN) - specifies the user's old password. It points to a character +string, whose length is specified in opasswd_len . +opasswd_len (IN) - the length of the old password string specified in opasswd. +For a valid password string, opasswd_len must be non-zero. +npasswd (IN) - specifies the user's new password. It points to a character +string, whose length is specified in npasswd_len which must be non-zero for a +valid password string. If the password complexity verification routine is +specified in the user's profile to verify the new password's complexity, the +new password must meet the complexity requirements of the verification +function. +npasswd_len (IN) - then length of the new password string specified in +npasswd. For a valid password string, npasswd_len must be non-zero. +mode - pass as OCI_DEFAULT. +Related Functions +OCISessionBegin() + + +----------------------------------OCIReset------------------------------------ + + +OCIReset() +Name +OCI Reset +Purpose +Resets the interrupted asynchronous operation and protocol. Must be called +if a OCIBreak call had been issued while a non-blocking operation was in +progress. +Syntax +sword OCIReset ( void *hndlp, + OCIError *errhp); +Comments +This call is called in non-blocking mode ONLY. Resets the interrupted +asynchronous operation and protocol. Must be called if a OCIBreak call +had been issued while a non-blocking operation was in progress. +Parameters +hndlp (IN) - the service context handle or the server context handle. +errhp (IN) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +Related Functions + + +OCIResultSetToStmt() +Name +OCI convert Result Set to Statement Handle +Purpose +Converts a descriptor to statement handle for fetching rows. +Syntax +sword OCIResultSetToStmt ( OCIResult *rsetdp, + OCIError *errhp ); +Comments +Converts a descriptor to statement handle for fetching rows. +A result set descriptor can be allocated with a call to OCIDescAlloc(). +Parameters +rsetdp (IN/OUT) - a result set descriptor pointer. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +Related Functions +OCIDescAlloc() + + + + +OCIServerAttach() +Name +OCI ATtaCH to server +Purpose +Creates an access path to a data source for OCI operations. +Syntax +sword OCIServerAttach ( OCIServer *srvhp, + OCIError *errhp, + const OraText *dblink, + sb4 dblink_len, + ub4 mode); +Comments +This call is used to create an association between an OCI application and a +particular server. +This call initializes a server context handle, which must have been previously +allocated with a call to OCIHandleAlloc(). +The server context handle initialized by this call can be associated with a +service context through a call to OCIAttrSet(). Once that association has been +made, OCI operations can be performed against the server. +If an application is operating against multiple servers, multiple server +context handles can be maintained. OCI operations are performed against +whichever server context is currently associated with the service context. +Parameters +srvhp (IN/OUT) - an uninitialized server context handle, which gets +initialized by this call. Passing in an initialized server handle causes an +error. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +dblink (IN) - specifies the database (server) to use. This parameter points to +a character string which specifies a connect string or a service point. If the +connect string is NULL, then this call attaches to the default host. The length +of connstr is specified in connstr_len. The connstr pointer may be freed by the +caller on return. +dblink_len (IN) - the length of the string pointed to by connstr. For a valid +connect string name or alias, connstr_len must be non-zero. +mode (IN) - specifies the various modes of operation. For release 8.0, pass as +OCI_DEFAULT - in this mode, calls made to the server on this server context +are made in blocking mode. +Example +See the description of OCIStmtPrepare() on page 13-96 for an example showing +the use of OCIServerAttach(). +Related Functions +OCIServerDetach() + + + +OCIServerDetach() +Name +OCI DeTaCH server +Purpose +Deletes an access to a data source for OCI operations. +Syntax +sword OCIServerDetach ( OCIServer *svrhp, + OCIError *errhp, + ub4 mode); +Comments +This call deletes an access to data source for OCI operations, which was +established by a call to OCIServerAttach(). +Parameters +srvhp (IN) - a handle to an initialized server context, which gets reset to +uninitialized state. The handle is not de-allocated. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +mode (IN) - specifies the various modes of operation. The only valid mode is +OCI_DEFAULT for the default mode. +Related Functions +OCIServerAttach() + + + +OCIServerVersion() +Name +OCI VERSion +Purpose +Returns the version string of the Oracle server. +Syntax +sword OCIServerVersion ( void *hndlp, + OCIError *errhp, + OraText *bufp, + ub4 bufsz + ub1 hndltype ); +Comments +This call returns the version string of the Oracle server. +For example, the following might be returned as the version string if your +application is running against a 7.3.2 server: +Oracle7 Server Release 7.3.2.0.0 - Production Release +PL/SQL Release 2.3.2.0.0 - Production +CORE Version 3.5.2.0.0 - Production +TNS for SEQUENT DYNIX/ptx: Version 2.3.2.0.0 - Production +NLSRTL Version 3.2.2.0.0 - Production + +Parameters +hndlp (IN) - the service context handle or the server context handle. +errhp (IN) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +bufp (IN) - the buffer in which the version information is returned. +bufsz (IN) - the length of the buffer. +hndltype (IN) - the type of handle passed to the function. +Related Functions + + + + + +OCISessionBegin() +Name +OCI Session Begin and authenticate user +Purpose +Creates a user authentication and begins a user session for a given server. +Syntax +sword OCISessionBegin ( OCISvcCtx *svchp, + OCIError *errhp, + OCISession *usrhp, + ub4 credt, + ub4 mode); + +Comments +For Oracle8, OCISessionBegin() must be called for any given server handle +before requests can be made against it. Also, OCISessionBegin() only supports +authenticating the user for access to the Oracle server specified by the +server handle in the service context. In other words, after OCIServerAttach() +is called to initialize a server handle, OCISessionBegin() must be called to +authenticate the user for that given server. +When OCISessionBegin() is called for the first time for the given server +handle, the initialized authentication handle is called a primary +authentication context. A primary authentication context may not be created +with the OCI_MIGRATE mode. Also, only one primary authentication context can +be created for a given server handle and the primary authentication context c +an only ever be used with that server handle. If the primary authentication +context is set in a service handle with a different server handle, then an +error will result. +After OCISessionBegin() has been called for the server handle, and the primary +authentication context is set in the service handle, OCISessionBegin() may be +called again to initialize another authentication handle with different (or +the same) credentials. When OCISessionBegin() is called with a service handle +set with a primary authentication context, the returned authentication context +in authp is called a user authentication context. As many user authentication +contexts may be initialized as desired. +User authentication contexts may be created with the OCI_MIGRATE mode. +If the OCI_MIGRATE mode is not specified, then the user authentication +context can only ever be used with the same server handle set in svchp. If +OCI_MIGRATE mode is specified, then the user authentication may be set +with different server handles. However, the user authentication context is +restricted to use with only server handles which resolve to the same database +instance and that have equivalent primary authentication contexts. Equivalent +authentication contexts are those which were authenticated as the same +database user. +OCI_SYSDBA, OCI_SYSOPER, OCI_SYSASM, and OCI_PRELIM_AUTH may only be used +with a primary authentication context. +To provide credentials for a call to OCISessionBegin(), one of two methods are +supported. The first is to provide a valid username and password pair for +database authentication in the user authentication handle passed to +OCISessionBegin(). This involves using OCIAttrSet() to set the +OCI_ATTR_USERNAME and OCI_ATTR_PASSWORD attributes on the +authentication handle. Then OCISessionBegin() is called with +OCI_CRED_RDBMS. +Note: When the authentication handle is terminated using +OCISessionEnd(), the username and password attributes remain +unchanged and thus can be re-used in a future call to OCISessionBegin(). +Otherwise, they must be reset to new values before the next +OCISessionBegin() call. +The second type of credentials supported are external credentials. No +attributes need to be set on the authentication handle before calling +OCISessionBegin(). The credential type is OCI_CRED_EXT. This is equivalent +to the Oracle7 `connect /' syntax. If values have been set for +OCI_ATTR_USERNAME and OCI_ATTR_PASSWORD, then these are +ignored if OCI_CRED_EXT is used. +Parameters +svchp (IN) - a handle to a service context. There must be a valid server +handle set in svchp. +errhp (IN) - an error handle to the retrieve diagnostic information. +usrhp (IN/OUT) - a handle to an authentication context, which is initialized +by this call. +credt (IN) - specifies the type of credentials to use for authentication. +Valid values for credt are: +OCI_CRED_RDBMS - authenticate using a database username and +password pair as credentials. The attributes OCI_ATTR_USERNAME +and OCI_ATTR_PASSWORD should be set on the authentication +context before this call. +OCI_CRED_EXT - authenticate using external credentials. No username +or password is provided. +mode (IN) - specifies the various modes of operation. Valid modes are: +OCI_DEFAULT - in this mode, the authentication context returned may +only ever be set with the same server context specified in svchp. This +establishes the primary authentication context. +OCI_MIGRATE - in this mode, the new authentication context may be +set in a service handle with a different server handle. This mode +establishes the user authentication context. +OCI_SYSDBA - in this mode, the user is authenticated for SYSDBA +access. +OCI_SYSOPER - in this mode, the user is authenticated for SYSOPER +access. +OCI_SYSASM - in this mode, the user is authenticated for SYSASM +access. Note that only an ASM instance can grant SYSASM access. +OCI_PRELIM_AUTH - this mode may only be used with OCI_SYSDBA, OCI_SYSASM, +or OCI_SYSOPER to authenticate for certain administration tasks. +Related Functions +OCISessionEnd() + + + + + + +OCISessionEnd() +Name +OCI Terminate user Authentication Context +Purpose +Terminates a user authentication context created by OCISessionBegin() +Syntax +sword OCISessionEnd ( OCISvcCtx *svchp, + OCIError *errhp, + OCISession *usrhp, + ub4 mode); + +Comments +The user security context associated with the service context is invalidated +by this call. Storage for the authentication context is not freed. The +transaction specified by the service context is implicitly committed. The +transaction handle, if explicitly allocated, may be freed if not being used. +Resources allocated on the server for this user are freed. +The authentication handle may be reused in a new call to OCISessionBegin(). +Parameters +svchp (IN/OUT) - the service context handle. There must be a valid server +handle and user authentication handle associated with svchp. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +usrhp (IN) - de-authenticate this user. If this parameter is passed as NULL, +the user in the service context handle is de-authenticated. +mode (IN) - the only valid mode is OCI_DEFAULT. +Example +In this example, an authentication context is destroyed. +Related Functions +OCISessionBegin() + + + + +OCIStmtExecute() +Name +OCI EXECute +Purpose +This call associates an application request with a server. +Syntax +sword OCIStmtExecute ( OCISvcCtx *svchp, + OCIStmt *stmtp, + OCIError *errhp, + ub4 iters, + ub4 rowoff, + const OCISnapshot *snap_in, + OCISnapshot *snap_out, + ub4 mode ); +Comments +This function is used to execute a prepared SQL statement. +Using an execute call, the application associates a request with a server. On +success, OCI_SUCCESS is returned. +If a SELECT statement is executed, the description of the select list follows +implicitly as a response. This description is buffered on the client side for +describes, fetches and define type conversions. Hence it is optimal to +describe a select list only after an execute. +Also for SELECT statements, some results are available implicitly. Rows will +be received and buffered at the end of the execute. For queries with small row +count, a prefetch causes memory to be released in the server if the end of +fetch is reached, an optimization that may result in memory usage reduction. +Set attribute call has been defined to set the number of rows to be prefetched +per result set. +For SELECT statements, at the end of the execute, the statement handle +implicitly maintains a reference to the service context on which it is +executed. It is the user's responsibility to maintain the integrity of the +service context. If the attributes of a service context is changed for +executing some operations on this service context, the service context must +be restored to have the same attributes, that a statement was executed with, +prior to a fetch on the statement handle. The implicit reference is maintained +until the statement handle is freed or the fetch is cancelled or an end of +fetch condition is reached. +Note: If output variables are defined for a SELECT statement before a +call to OCIStmtExecute(), the number of rows specified by iters will be +fetched directly into the defined output buffers and additional rows +equivalent to the prefetch count will be prefetched. If there are no +additional rows, then the fetch is complete without calling +OCIStmtFetch(). +The execute call will return errors if the statement has bind data types that +are not supported in an Oracle7 server. +Parameters +svchp (IN/OUT) - service context handle. +stmtp (IN/OUT) - an statement handle - defines the statement and the +associated data to be executed at the server. It is invalid to pass in a +statement handle that has bind of data types only supported in release 8.0 +when srvchp points to an Oracle7 server. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. If the statement is being +batched and it is successful, then this handle will contain this particular +statement execution specific errors returned from the server when the batch is +flushed. +iters (IN) - the number of times this statement is executed for non-Select +statements. For Select statements, if iters is non-zero, then defines must +have been done for the statement handle. The execution fetches iters rows into +these predefined buffers and prefetches more rows depending upon the prefetch +row count. This function returns an error if iters=0 for non-SELECT +statements. +rowoff (IN) - the index from which the data in an array bind is relevant for +this multiple row execution. +snap_in (IN) - this parameter is optional. if supplied, must point to a +snapshot descriptor of type OCI_DTYPE_SNAP. The contents of this descriptor +must be obtained from the snap_out parameter of a previous call. The +descriptor is ignored if the SQL is not a SELECT. This facility allows +multiple service contexts to ORACLE to see the same consistent snapshot of the +database's committed data. However, uncommitted data in one context is not +visible to another context even using the same snapshot. +snap_out (OUT) - this parameter optional. if supplied, must point to a +descriptor of type OCI_DTYPE_SNAP. This descriptor is filled in with an +opaque representation which is the current ORACLE "system change +number" suitable as a snap_in input to a subsequent call to OCIStmtExecute(). +This descriptor should not be used any longer than necessary in order to avoid +"snapshot too old" errors. +mode (IN) - The modes are: +If OCI_DEFAULT_MODE, the default mode, is selected, the request is +immediately executed. Error handle contains diagnostics on error if any. +OCI_EXACT_FETCH - if the statement is a SQL SELECT, this mode is +only valid if the application has set the prefetch row count prior to this +call. In this mode, the OCI library will get up to the number of rows +specified (i.e., prefetch row count plus iters). If the number of rows +returned by the query is greater than this value, OCI_ERROR will be +returned with ORA-01422 as the implementation specific error in a +diagnostic record. If the number of rows returned by the query is +smaller than the prefetch row count, OCI_SUCCESS_WITH_INFO will +be returned with ORA-01403 as the implementation specific error. The +prefetch buffer size is ignored and the OCI library tries to allocate all the +space required to contain the prefetched rows. The exact fetch semantics +apply to only the top level rows. No more rows can be fetched for this +query at the end of the call. +OCI_KEEP_FETCH_STATE - the result set rows (not yet fetched) of this +statement executed in this transaction will be maintained when the +transaction is detached for migration. By default, a query is cancelled +when a transaction is detached for migration. This mode is the default +mode when connected to a V7 server. +Related Functions +OCIStmtPrepare() + + + + + +OCIStmtFetch() +Name +OCI FetCH +Purpose +Fetches rows from a query. +Syntax +sword OCIStmtFetch ( OCIStmt *stmtp, + OCIError *errhp, + ub4 nrows, + ub2 orientation, + ub4 mode); +Comments +The fetch call is a local call, if prefetched rows suffice. However, this is +transparent to the application. If LOB columns are being read, LOB locators +are fetched for subsequent LOB operations to be performed on these locators. +Prefetching is turned off if LONG columns are involved. +A fetch with nrows set to 0 rows effectively cancels the fetch for this +statement. +Parameters +stmtp (IN) - a statement (application request) handle. +errhp (IN) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +nrows (IN) - number of rows to be fetched from the current position. +orientation (IN) - for release 8.0, the only acceptable value is +OCI_FETCH_NEXT, which is also the default value. +mode (IN) - for release 8.0, beta-1, the following mode is defined. +OCI_DEFAULT - default mode +OCI_EOF_FETCH - indicates that it is the last fetch from the result set. +If nrows is non-zero, setting this mode effectively cancels fetching after +retrieving nrows, otherwise it cancels fetching immediately. +Related Functions +OCIAttrGet() + +OCIStmtFetch2() +Name +OCI FetCH2 +Purpose +Fetches rows from a query. +Syntax +sword OCIStmtFetch2 ( OCIStmt *stmtp, + OCIError *errhp, + ub4 nrows, + ub2 orientation, + ub4 scrollOffset, + ub4 mode); +Comments +The fetch call works similar to the OCIStmtFetch call with the +addition of the fetchOffset parameter. It can be used on any +statement handle, whether it is scrollable or not. For a +non-scrollable statement handle, the only acceptable value +will be OCI_FETCH_NEXT, and the fetchOffset parameter will be +ignored. Applications are encouraged to use this new call. + +A fetchOffset with OCI_FETCH_RELATIVE is equivalent to +OCI_FETCH_CURRENT with a value of 0, is equivalent to +OCI_FETCH_NEXT with a value of 1, and equivalent to +OCI_FETCH_PRIOR with a value of -1. Note that the range of +accessible rows is [1,OCI_ATTR_ROW_COUNT] beyond which an +error could be raised if sufficient rows do not exist in + +The fetch call is a local call, if prefetched rows suffice. However, this is +transparent to the application. If LOB columns are being read, LOB locators +are fetched for subsequent LOB operations to be performed on these locators. +Prefetching is turned off if LONG columns are involved. +A fetch with nrows set to 0 rows effectively cancels the fetch for this +statement. +Parameters +stmtp (IN) - a statement (application request) handle. +errhp (IN) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +nrows (IN) - number of rows to be fetched from the current position. +It defaults to 1 for orientation OCI_FETCH_LAST. +orientation (IN) - The acceptable values are as follows, with +OCI_FETCH_NEXT being the default value. +OCI_FETCH_CURRENT gets the current row, +OCI_FETCH_NEXT gets the next row from the current position, +OCI_FETCH_FIRST gets the first row in the result set, +OCI_FETCH_LAST gets the last row in the result set, +OCI_FETCH_PRIOR gets the previous row from the current row in the result set, +OCI_FETCH_ABSOLUTE will fetch the row number (specified by fetchOffset +parameter) in the result set using absolute positioning, +OCI_FETCH_RELATIVE will fetch the row number (specified by fetchOffset +parameter) in the result set using relative positioning. +scrollOffset(IN) - offset used with the OCI_FETCH_ABSOLUTE and +OCI_FETCH_RELATIVE orientation parameters only. It specify +the new current position for scrollable result set. It is +ignored for non-scrollable result sets. +mode (IN) - for release 8.0, beta-1, the following mode is defined. +OCI_DEFAULT - default mode +OCI_EOF_FETCH - indicates that it is the last fetch from the result set. +If nrows is non-zero, setting this mode effectively cancels fetching after +retrieving nrows, otherwise it cancels fetching immediately. +Related Functions +OCIAttrGet() + + + +OCIStmtGetPieceInfo() +Name +OCI Get Piece Information +Purpose +Returns piece information for a piecewise operation. +Syntax +sword OCIStmtGetPieceInfo( const OCIStmt *stmtp, + OCIError *errhp, + void **hndlpp, + ub4 *typep, + ub1 *in_outp, + ub4 *iterp, + ub4 *idxp, + ub1 *piecep ); + +Comments +When an execute/fetch call returns OCI_NEED_DATA to get/return a +dynamic bind/define value or piece, OCIStmtGetPieceInfo() returns the +relevant information: bind/define handle, iteration or index number and +which piece. +See the section "Runtime Data Allocation and Piecewise Operations" on page +5-16 for more information about using OCIStmtGetPieceInfo(). +Parameters +stmtp (IN) - the statement when executed returned OCI_NEED_DATA. +errhp (OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +hndlpp (OUT) - returns a pointer to the bind or define handle of the bind or +define whose runtime data is required or is being provided. +typep (OUT) - the type of the handle pointed to by hndlpp: OCI_HTYPE_BIND +(for a bind handle) or OCI_HTYPE_DEFINE (for a define handle). +in_outp (OUT) - returns OCI_PARAM_IN if the data is required for an IN bind +value. Returns OCI_PARAM_OUT if the data is available as an OUT bind +variable or a define position value. +iterp (OUT) - returns the row number of a multiple row operation. +idxp (OUT) - the index of an array element of a PL/SQL array bind operation. +piecep (OUT) - returns one of the following defined values - +OCI_ONE_PIECE, OCI_FIRST_PIECE, OCI_NEXT_PIECE and +OCI_LAST_PIECE. The default value is always OCI_ONE_PIECE. +Related Functions +OCIAttrGet(), OCIAttrGet(), OCIStmtExecute(), OCIStmtFetch(), +OCIStmtSetPieceInfo() + + + + +OCIStmtPrepare() +Name +OCI Statement REQuest +Purpose +This call defines the SQL/PLSQL statement to be executed. +Syntax +sword OCIStmtPrepare ( OCIStmt *stmtp, + OCIError *errhp, + const OraText *stmt, + ub4 stmt_len, + ub4 language, + ub4 mode); +Comments +This call is used to prepare a SQL or PL/SQL statement for execution. The +OCIStmtPrepare() call defines an application request. +This is a purely local call. Data values for this statement initialized in +subsequent bind calls will be stored in a bind handle which will hang off this +statement handle. +This call does not create an association between this statement handle and any +particular server. +See the section "Preparing Statements" on page 2-21 for more information +about using this call. +Parameters +stmtp (IN) - a statement handle. +errhp (IN) - an error handle to retrieve diagnostic information. +stmt (IN) - SQL or PL/SQL statement to be executed. Must be a null-terminated +string. The pointer to the OraText of the statement must be available as long +as the statement is executed. +stmt_len (IN) - length of the statement. Must not be zero. +language (IN) - V7, V8, or native syntax. Possible values are: +OCI_V7_SYNTAX - V7 ORACLE parsing syntax +OCI_V8_SYNTAX - V8 ORACLE parsing syntax +OCI_NTV_SYNTAX - syntax depending upon the version of the server. +mode (IN) - the only defined mode is OCI_DEFAULT for default mode. +Example +This example demonstrates the use of OCIStmtPrepare(), as well as the OCI +application initialization calls. +Related Functions +OCIAttrGet(), OCIStmtExecute() + + +OCIStmtPrepare2() +Name +OCI Statement REQuest with (a) early binding to svchp and/or +(b) stmt caching +Purpose +This call defines the SQL/PLSQL statement to be executed. +Syntax +sword OCIStmtPrepare2 ( OCISvcCtx *svchp, + OCIStmt **stmtp, + OCIError *errhp, + const OraText *stmt, + ub4 stmt_len, + const OraText *key, + ub4 key_len, + ub4 language, + ub4 mode); +Comments +This call is used to prepare a SQL or PL/SQL statement for execution. The +OCIStmtPrepare() call defines an application request. +This is a purely local call. Data values for this statement initialized in +subsequent bind calls will be stored in a bind handle which will hang off this +statement handle. +This call creates an association between the statement handle and a service +context. It differs from OCIStmtPrepare in that respect.It also supports +stmt caching. The stmt will automatically be cached if the authp of the stmt +has enabled stmt caching. +Parameters +svchp (IN) - the service context handle that contains the session that + this stmt handle belongs to. +stmtp (OUT) - an unallocated stmt handle must be pased in. An allocated + and prepared statement handle will be returned. +errhp (IN) - an error handle to retrieve diagnostic information. +stmt (IN) - SQL or PL/SQL statement to be executed. Must be a null- + terminated string. The pointer to the OraText of the statement + must be available as long as the statement is executed. +stmt_len (IN) - length of the statement. Must not be zero. +key (IN) - This is only Valid for OCI Stmt Caching. It indicates the + key to search with. It thus optimizes the search in the cache. +key_len (IN) - the length of the key. This, too, is onlly valid for stmt + caching. +language (IN) - V7, V8, or native syntax. Possible values are: +OCI_V7_SYNTAX - V7 ORACLE parsing syntax +OCI_V8_SYNTAX - V8 ORACLE parsing syntax +OCI_NTV_SYNTAX - syntax depending upon the version of the server. +mode (IN) - the defined modes are OCI_DEFAULT and OCI_PREP2_CACHE_SEARCHONLY. +Example +Related Functions +OCIStmtExecute(), OCIStmtRelease() + + +OCIStmtRelease() +Name +OCI Statement Release. This call is used to relesae the stmt that +was retreived using OCIStmtPrepare2(). If the stmt is release +using this call, OCIHandleFree() must not be called on the stmt +handle. +Purpose +This call releases the statement obtained by OCIStmtPrepare2 +Syntax +sword OCIStmtRelease ( OCIStmt *stmtp, + OCIError *errhp, + cONST OraText *key, + ub4 key_len, + ub4 mode); +Comments +This call is used to release a handle obtained via OCIStmtPrepare2(). +It also frees the memory associated with the handle. +This is a purely local call. +Parameters +stmtp (IN/OUT) - The statement handle to be released/freed. +errhp (IN) - an error handle to retrieve diagnostic information. +key (IN) - This is only Valid for OCI Stmt Caching. It indicates the + key to tag the stmt with. +key_len (IN) - the length of the key. This, too, is only valid for stmt + caching. +mode (IN) - the defined modes are OCI_DEFAULT for default mode and + OCI_STRLS_CACHE_DELETE (only used for Stmt Caching). +Example +Related Functions +OCIStmtExecute(), OCIStmtPrepare2() + + +OCIStmtSetPieceInfo() +Name +OCI Set Piece Information +Purpose +Sets piece information for a piecewise operation. +Syntax +sword OCIStmtSetPieceInfo ( void *hndlp, + ub4 type, + OCIError *errhp, + const void *bufp, + ub4 *alenp, + ub1 piece, + const void *indp, + ub2 *rcodep ); +Comments +When an execute call returns OCI_NEED_DATA to get a dynamic IN/OUT +bind value or piece, OCIStmtSetPieceInfo() sets the piece information: the +buffer, the length, the indicator and which piece is currently being processed. +For more information about using OCIStmtSetPieceInfo() see the section +"Runtime Data Allocation and Piecewise Operations" on page 5-16. +Parameters +hndlp (IN/OUT) - the bind/define handle. +type (IN) - type of the handle. +errhp (OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +bufp (IN/OUT) - bufp is a pointer to a storage containing the data value or +the piece when it is an IN bind variable, otherwise bufp is a pointer to +storage for getting a piece or a value for OUT binds and define variables. For +named data types or REFs, a pointer to the object or REF is returned. +alenp (IN/OUT) - the length of the piece or the value. +piece (IN) - the piece parameter. The following are valid values: +OCI_ONE_PIECE, OCI_FIRST_PIECE, OCI_NEXT_PIECE, or +OCI_LAST_PIECE. +The default value is OCI_ONE_PIECE. This parameter is used for IN bind +variables only. +indp (IN/OUT) - indicator. A pointer to a sb2 value or pointer to an indicator +structure for named data types (SQLT_NTY) and REFs (SQLT_REF), i.e., *indp +is either an sb2 or a void * depending upon the data type. +rcodep (IN/OUT) - return code. +Related Functions +OCIAttrGet(), OCIAttrGet(), OCIStmtExecute(), OCIStmtFetch(), +OCIStmtGetPieceInfo() + + +OCIFormatInit +Name +OCIFormat Package Initialize +Purpose +Initializes the OCIFormat package. +Syntax +sword OCIFormatInit(void *hndl, OCIError *err); +Comments +This routine must be called before calling any other OCIFormat routine. +Returns OCI_SUCCESS, OCI_INVALID_HANDLE, or OCI_ERROR +Parameters +hndl (IN/OUT) - OCI environment or session handle +err (IN/OUT) - OCI error handle +Related Functions +OCIFormatTerm() + + +OCIFormatString +Name +OCIFormat Package Format String +Purpose +Writes a text string into the supplied text buffer using the argument +list submitted to it and in accordance with the format string given. +Syntax +sword OCIFormatString(void *hndl, OCIError *err, OraText *buffer, + sbig_ora bufferLength, sbig_ora *returnLength, + const OraText *formatString, ...); +Comments +The first call to this routine must be preceded by a call to the +OCIFormatInit routine that initializes the OCIFormat package +for use. When this routine is no longer needed then terminate +the OCIFormat package by a call to the OCIFormatTerm routine. +Returns OCI_SUCCESS, OCI_INVALID_HANDLE, or OCI_ERROR +Parameters +hndl (IN/OUT) - OCI environment or session handle +err (IN/OUT) - OCI error handle +buffer (OUT) - text buffer for the string +bufferLength (IN) - length of the text buffer +returnLength (OUT) - length of the formatted string +formatString (IN) - format specification string +... (IN) - variable argument list +Related Functions + + +OCIFormatTerm +Name +OCIFormat Package Terminate +Purpose +Terminates the OCIFormat package. +Syntax +sword OCIFormatTerm(void *hndl, OCIError *err); +Comments +It must be called after the OCIFormat package is no longer being used. +Returns OCI_SUCCESS, OCI_INVALID_HANDLE, or OCI_ERROR +Parameters +hndl (IN/OUT) - OCI environment or session handle +err (IN/OUT) - OCI error handle +Related Functions +OCIFormatInit() + + +OCIFormatTUb1 +Name +OCIFormat Package ub1 Type +Purpose +Return the type value for the ub1 type. +Syntax +sword OCIFormatTUb1(void); +Comments +None +Parameters +None +Related Functions +None + + +OCIFormatTUb2 +Name +OCIFormat Package ub2 Type +Purpose +Return the type value for the ub2 type. +Syntax +sword OCIFormatTUb2(void); +Comments +None +Parameters +None +Related Functions +None + + +OCIFormatTUb4 +Name +OCIFormat Package ub4 Type +Purpose +Return the type value for the ub4 type. +Syntax +sword OCIFormatTUb4(void); +Comments +None +Parameters +None +Related Functions +None + + +OCIFormatTUword +Name +OCIFormat Package uword Type +Purpose +Return the type value for the uword type. +Syntax +sword OCIFormatTUword(void); +Comments +None +Parameters +None +Related Functions +None + + +OCIFormatTUbig_ora +Name +OCIFormat Package ubig_ora Type +Purpose +Return the type value for the ubig_ora type. +Syntax +sword OCIFormatTUbig_ora(void); +Comments +None +Parameters +None +Related Functions +None + + +OCIFormatTSb1 +Name +OCIFormat Package sb1 Type +Purpose +Return the type value for the sb1 type. +Syntax +sword OCIFormatTSb1(void); +Comments +None +Parameters +None +Related Functions +None + + +OCIFormatTSb2 +Name +OCIFormat Package sb2 Type +Purpose +Return the type value for the sb2 type. +Syntax +sword OCIFormatTSb2(void); +Comments +None +Parameters +None +Related Functions +None + + +OCIFormatTSb4 +Name +OCIFormat Package sb4 Type +Purpose +Return the type value for the sb4 type. +Syntax +sword OCIFormatTSb4(void); +Comments +None +Parameters +None +Related Functions +None + + +OCIFormatTSword +Name +OCIFormat Package sword Type +Purpose +Return the type value for the sword type. +Syntax +sword OCIFormatTSword(void); +Comments +None +Parameters +None +Related Functions +None + + +OCIFormatTSbig_ora +Name +OCIFormat Package sbig_ora Type +Purpose +Return the type value for the sbig_ora type. +Syntax +sword OCIFormatTSbig_ora(void); +Comments +None +Parameters +None +Related Functions +None + + +OCIFormatTEb1 +Name +OCIFormat Package eb1 Type +Purpose +Return the type value for the eb1 type. +Syntax +sword OCIFormatTEb1(void); +Comments +None +Parameters +None +Related Functions +None + + +OCIFormatTEb2 +Name +OCIFormat Package eb2 Type +Purpose +Return the type value for the eb2 type. +Syntax +sword OCIFormatTEb2(void); +Comments +None +Parameters +None +Related Functions +None + + +OCIFormatTEb4 +Name +OCIFormat Package eb4 Type +Purpose +Return the type value for the eb4 type. +Syntax +sword OCIFormatTEb4(void); +Comments +None +Parameters +None +Related Functions +None + + +OCIFormatTEword +Name +OCIFormat Package eword Type +Purpose +Return the type value for the eword type. +Syntax +sword OCIFormatTEword(void); +Comments +None +Parameters +None +Related Functions +None + + +OCIFormatTChar +Name +OCIFormat Package text Type +Purpose +Return the type value for the text type. +Syntax +sword OCIFormatTChar(void); +Comments +None +Parameters +None +Related Functions +None + + +OCIFormatTText +Name +OCIFormat Package *text Type +Purpose +Return the type value for the *text type. +Syntax +sword OCIFormatTText(void); +Comments +None +Parameters +None +Related Functions +None + + +OCIFormatTDouble +Name +OCIFormat Package double Type +Purpose +Return the type value for the double type. +Syntax +sword OCIFormatTDouble(void); +Comments +None +Parameters +None +Related Functions +None + + +OCIFormatDvoid +Name +OCIFormat Package void Type +Purpose +Return the type value for the void type. +Syntax +sword OCIFormatTDvoid(void); +Comments +None +Parameters +None +Related Functions +None + + +OCIFormatTEnd +Name +OCIFormat Package end Type +Purpose +Return the list terminator's "type". +Syntax +sword OCIFormatTEnd(void); +Comments +None +Parameters +None +Related Functions +None + + +OCISvcCtxToLda() +Name +OCI toggle SerVice context handle to Version 7 Lda_Def +Purpose +Toggles between a V8 service context handle and a V7 Lda_Def. +Syntax +sword OCISvcCtxToLda ( OCISvcCtx *srvhp, + OCIError *errhp, + Lda_Def *ldap ); +Comments +Toggles between an Oracle8 service context handle and an Oracle7 Lda_Def. +This function can only be called after a service context has been properly +initialized. +Once the service context has been translated to an Lda_Def, it can be used in +release 7.x OCI calls (e.g., obindps(), ofen()). +Note: If there are multiple service contexts which share the same server +handle, only one can be in V7 mode at any time. +The action of this call can be reversed by passing the resulting Lda_Def to +the OCILdaToSvcCtx() function. +Parameters +svchp (IN/OUT) - the service context handle. +errhp (IN/OUT) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +ldap (IN/OUT) - a Logon Data Area for V7-style OCI calls which is initialized +by this call. +Related Functions +OCILdaToSvcCtx() + + + + +OCITransCommit() +Name +OCI TX (transaction) CoMmit +Purpose +Commits the transaction associated with a specified service context. +Syntax +sword OCITransCommit ( OCISvcCtx *srvcp, + OCIError *errhp, + ub4 flags ); +Comments +The transaction currently associated with the service context is committed. If +it is a distributed transaction that the server cannot commit, this call +additionally retrieves the state of the transaction from the database to be +returned to the user in the error handle. +If the application has defined multiple transactions, this function operates +on the transaction currently associated with the service context. If the +application is working with only the implicit local transaction created when +database changes are made, that implicit transaction is committed. +If the application is running in the object mode, then the modified or updated +objects in the object cache for this transaction are also committed. +The flags parameter is used for one-phase commit optimization in distributed +transactions. If the transaction is non-distributed, the flags parameter is +ignored, and OCI_DEFAULT can be passed as its value. OCI applications +managing global transactions should pass a value of +OCI_TRANS_TWOPHASE to the flags parameter for a two-phase commit. The +default is one-phase commit. +Under normal circumstances, OCITransCommit() returns with a status +indicating that the transaction has either been committed or rolled back. With +distributed transactions, it is possible that the transaction is now in-doubt +(i.e., neither committed nor aborted). In this case, OCITransCommit() +attempts to retrieve the status of the transaction from the server. +The status is returned. +Parameters +srvcp (IN) - the service context handle. +errhp (IN) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +flags -see the "Comments" section above. +Related Functions +OCITransRollback() + + + + +OCITransDetach() +Name +OCI TX (transaction) DeTach +Purpose +Detaches a transaction. +Syntax +sword OCITransDetach ( OCISvcCtx *srvcp, + OCIError *errhp, + ub4 flags); +Comments +Detaches a global transaction from the service context handle. The transaction +currently attached to the service context handle becomes inactive at the end +of this call. The transaction may be resumed later by calling OCITransStart(), +specifying a flags value of OCI_TRANS_RESUME. +When a transaction is detached, the value which was specified in the timeout +parameter of OCITransStart() when the transaction was started is used to +determine the amount of time the branch can remain inactive before being +deleted by the server's PMON process. +Note: The transaction can be resumed by a different process than the one +that detached it, provided that the transaction has the same +authorization. +Parameters +srvcp (IN) - the service context handle. +errhp (IN) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +flags (IN) - you must pass a value of OCI_DEFAULT for this parameter. +Related Functions +OCITransStart() + + + +OCITransForget() +Name +OCI TX (transaction) ForGeT +Purpose +Causes the server to forget a heuristically completed global transaction. +Syntax +sword OCITransForget ( OCISvcCtx *svchp, + OCIError *errhp, + ub4 flags); + +Comments + +Forgets a heuristically completed global transaction. The server deletes the +status of the transaction from the system's pending transaction table. +The XID of the transaction to be forgotten is set as an attribute of the +transaction handle (OCI_ATTR_XID). +Parameters +srvcp (IN) - the service context handle - the transaction is rolled back. +errhp (IN) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +flags (IN) - you must pass OCI_DEFAULT for this parameter. +Related Functions +OCITransCommit(), OCITransRollback() + + +OCITransMultiPrepare() +Name +OCI Trans(action) Multi-Branch Prepare +Purpose +Prepares a transaction with multiple branches in a single call. +Syntax +sword OCITransMultiPrepare ( OCISvcCtx *svchp, + ub4 numBranches, + OCITrans **txns, + OCIError **errhp); + +Comments + +Prepares the specified global transaction for commit. +This call is valid only for distributed transactions. +This call is an advanced performance feature intended for use only in +situations where the caller is responsible for preparing all the branches +in a transaction. +Parameters +srvcp (IN) - the service context handle. +numBranches (IN) - This is the number of branches expected. It is also the +array size for the next two parameters. +txns (IN) - This is the array of transaction handles for the branches to +prepare. They should all have the OCI_ATTR_XID set. The global transaction +ID should be the same. +errhp (IN) - This is the array of error handles. If OCI_SUCCESS is not +returned, then these will indicate which branches received which errors. +Related Functions +OCITransPrepare() + + +OCITransPrepare() +Name +OCI TX (transaction) PREpare +Purpose +Prepares a transaction for commit. +Syntax +sword OCITransPrepare ( OCISvcCtx *svchp, + OCIError *errhp, + ub4 flags); + +Comments + +Prepares the specified global transaction for commit. +This call is valid only for distributed transactions. +The call returns OCI_SUCCESS_WITH_INFO if the transaction has not made +any changes. The error handle will indicate that the transaction is read-only. +The flag parameter is not currently used. +Parameters +srvcp (IN) - the service context handle. +errhp (IN) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +flags (IN) - you must pass OCI_DEFAULT for this parameter. +Related Functions +OCITransCommit(), OCITransForget() + + + + +OCITransRollback() +Name +OCI TX (transaction) RoLlback +Purpose +Rolls back the current transaction. +Syntax +sword OCITransRollback ( void *svchp, + OCIError *errhp, + ub4 flags ); +Comments +The current transaction- defined as the set of statements executed since the +last OCITransCommit() or since OCISessionBegin()-is rolled back. +If the application is running under object mode then the modified or updated +objects in the object cache for this transaction are also rolled back. +An error is returned if an attempt is made to roll back a global transaction +that is not currently active. +Parameters +svchp (IN) - a service context handle. The transaction currently set in the +service context handle is rolled back. +errhp -(IN) - an error handle which can be passed to OCIErrorGet() for +diagnostic information in the event of an error. +flags - you must pass a value of OCI_DEFAULT for this parameter. +Related Functions +OCITransCommit() + + + + +OCITransStart() +Name +OCI TX (transaction) STart +Purpose +Sets the beginning of a transaction. +Syntax +sword OCITransStart ( OCISvcCtx *svchp, + OCIError *errhp, + uword timeout, + ub4 flags); + +Comments +This function sets the beginning of a global or serializable transaction. The +transaction context currently associated with the service context handle is +initialized at the end of the call if the flags parameter specifies that a new +transaction should be started. +The XID of the transaction is set as an attribute of the transaction handle +(OCI_ATTR_XID) +Parameters +svchp (IN/OUT) - the service context handle. The transaction context in the +service context handle is initialized at the end of the call if the flag +specified a new transaction to be started. +errhp (IN/OUT) - The OCI error handle. If there is an error, it is recorded in +err and this function returns OCI_ERROR. Diagnostic information can be +obtained by calling OCIErrorGet(). +timeout (IN) - the time, in seconds, to wait for a transaction to become +available for resumption when OCI_TRANS_RESUME is specified. When +OCI_TRANS_NEW is specified, this value is stored and may be used later by +OCITransDetach(). +flags (IN) - specifies whether a new transaction is being started or an +existing transaction is being resumed. Also specifies serializiability or +read-only status. More than a single value can be specified. By default, +a read/write transaction is started. The flag values are: +OCI_TRANS_NEW - starts a new transaction branch. By default starts a +tightly coupled and migratable branch. +OCI_TRANS_TIGHT - explicitly specifies a tightly coupled branch +OCI_TRANS_LOOSE - specifies a loosely coupled branch +OCI_TRANS_RESUME - resumes an existing transaction branch. +OCI_TRANS_READONLY - start a readonly transaction +OCI_TRANS_SERIALIZABLE - start a serializable transaction +Related Functions +OCITransDetach() + + + + + +******************************************************************************/ +/*-----------------------Dynamic Callback Function Pointers------------------*/ + + +typedef sb4 (*OCICallbackInBind)(void *ictxp, OCIBind *bindp, ub4 iter, + ub4 index, void **bufpp, ub4 *alenp, + ub1 *piecep, void **indp); + +typedef sb4 (*OCICallbackOutBind)(void *octxp, OCIBind *bindp, ub4 iter, + ub4 index, void **bufpp, ub4 **alenp, + ub1 *piecep, void **indp, + ub2 **rcodep); + +typedef sb4 (*OCICallbackDefine)(void *octxp, OCIDefine *defnp, ub4 iter, + void **bufpp, ub4 **alenp, ub1 *piecep, + void **indp, ub2 **rcodep); + +typedef sword (*OCIUserCallback)(void *ctxp, void *hndlp, ub4 type, + ub4 fcode, ub4 when, sword returnCode, + sb4 *errnop, va_list arglist); + +typedef sword (*OCIEnvCallbackType)(OCIEnv *env, ub4 mode, + size_t xtramem_sz, void *usrmemp, + OCIUcb *ucbDesc); + +typedef sb4 (*OCICallbackLobRead)(void *ctxp, const void *bufp, + ub4 len, ub1 piece); + +typedef sb4 (*OCICallbackLobWrite)(void *ctxp, void *bufp, + ub4 *lenp, ub1 *piece); + +#ifdef ORAXB8_DEFINED + +typedef sb4 (*OCICallbackLobRead2)(void *ctxp, const void *bufp, oraub8 len, + ub1 piece, void **changed_bufpp, + oraub8 *changed_lenp); + +typedef sb4 (*OCICallbackLobWrite2)(void *ctxp, void *bufp, oraub8 *lenp, + ub1 *piece, void **changed_bufpp, + oraub8 *changed_lenp); + +typedef sb4 (*OCICallbackLobArrayRead)(void *ctxp, ub4 array_iter, + const void *bufp, oraub8 len, + ub1 piece, void **changed_bufpp, + oraub8 *changed_lenp); + +typedef sb4 (*OCICallbackLobArrayWrite)(void *ctxp, ub4 array_iter, + void *bufp, oraub8 *lenp, + ub1 *piece, void **changed_bufpp, + oraub8 *changed_lenp); +#endif + +typedef sb4 (*OCICallbackLobGetDeduplicateRegions)(void *ctxp, + OCILobRegion *regions, + ub4 count, ub1 piece, + OCILobRegion **changed_reg, + ub4 *changed_count); + +typedef sb4 (*OCICallbackAQEnq)(void *ctxp, void **payload, + void **payload_ind); + +typedef sb4 (*OCICallbackAQEnqStreaming)(void *ctxp, void **payload, + void **payload_ind, + OCIAQMsgProperties **msgprop, + OCIType **tdo); + +typedef sb4 (*OCICallbackAQDeq)(void *ctxp, void **payload, + void **payload_ind); + +/*--------------------------Failover Callback Structure ---------------------*/ +typedef sb4 (*OCICallbackFailover)(void *svcctx, void *envctx, + void *fo_ctx, ub4 fo_type, + ub4 fo_event); + +typedef struct +{ + OCICallbackFailover callback_function; + void *fo_ctx; +} +OCIFocbkStruct; + +/*---------------------Statement Cache callback function ------------------*/ + +typedef sword (*OCICallbackStmtCache)(void *ctx, OCIStmt *stmt, ub4 mode); + +/*--------------------------HA Callback Structure ---------------------*/ +typedef void (*OCIEventCallback)(void *evtctx, OCIEvent *eventhp); + + +/***************************************************************************** + ACTUAL PROTOTYPE DECLARATIONS +******************************************************************************/ + +sword OCIInitialize (ub4 mode, void *ctxp, + void *(*malocfp)(void *ctxp, size_t size), + void *(*ralocfp)(void *ctxp, void *memptr, size_t newsize), + void (*mfreefp)(void *ctxp, void *memptr) ); + +sword OCITerminate( ub4 mode); + +sword OCIEnvCreate (OCIEnv **envp, ub4 mode, void *ctxp, + void *(*malocfp)(void *ctxp, size_t size), + void *(*ralocfp)(void *ctxp, void *memptr, size_t newsize), + void (*mfreefp)(void *ctxp, void *memptr), + size_t xtramem_sz, void **usrmempp); + +sword OCIEnvNlsCreate (OCIEnv **envp, ub4 mode, void *ctxp, + void *(*malocfp)(void *ctxp, size_t size), + void *(*ralocfp)(void *ctxp, void *memptr, size_t newsize), + void (*mfreefp)(void *ctxp, void *memptr), + size_t xtramem_sz, void **usrmempp, + ub2 charset, ub2 ncharset); + +sword OCIFEnvCreate (OCIEnv **envp, ub4 mode, void *ctxp, + void *(*malocfp)(void *ctxp, size_t size), + void *(*ralocfp)(void *ctxp, void *memptr, size_t newsize), + void (*mfreefp)(void *ctxp, void *memptr), + size_t xtramem_sz, void **usrmempp, void *fupg); + +sword OCIHandleAlloc(const void *parenth, void **hndlpp, const ub4 type, + const size_t xtramem_sz, void **usrmempp); + +sword OCIHandleFree(void *hndlp, const ub4 type); + + +sword OCIDescriptorAlloc(const void *parenth, void **descpp, + const ub4 type, const size_t xtramem_sz, + void **usrmempp); + +sword OCIArrayDescriptorAlloc(const void *parenth, void **descpp, + const ub4 type, ub4 array_size, + const size_t xtramem_sz, void **usrmempp); + +sword OCIDescriptorFree(void *descp, const ub4 type); + +sword OCIArrayDescriptorFree(void **descp, const ub4 type); + +sword OCIEnvInit (OCIEnv **envp, ub4 mode, + size_t xtramem_sz, void **usrmempp); + +sword OCIServerAttach (OCIServer *srvhp, OCIError *errhp, + const OraText *dblink, sb4 dblink_len, ub4 mode); + +sword OCIServerDetach (OCIServer *srvhp, OCIError *errhp, ub4 mode); + +sword OCISessionBegin (OCISvcCtx *svchp, OCIError *errhp, OCISession *usrhp, + ub4 credt, ub4 mode); + +sword OCISessionEnd (OCISvcCtx *svchp, OCIError *errhp, OCISession *usrhp, + ub4 mode); + +sword OCILogon (OCIEnv *envhp, OCIError *errhp, OCISvcCtx **svchp, + const OraText *username, ub4 uname_len, + const OraText *password, ub4 passwd_len, + const OraText *dbname, ub4 dbname_len); + +sword OCILogon2 (OCIEnv *envhp, OCIError *errhp, OCISvcCtx **svchp, + const OraText *username, ub4 uname_len, + const OraText *password, ub4 passwd_len, + const OraText *dbname, ub4 dbname_len, + ub4 mode); + +sword OCILogoff (OCISvcCtx *svchp, OCIError *errhp); + + +sword OCIPasswordChange (OCISvcCtx *svchp, OCIError *errhp, + const OraText *user_name, ub4 usernm_len, + const OraText *opasswd, ub4 opasswd_len, + const OraText *npasswd, ub4 npasswd_len, + ub4 mode); + +sword OCIStmtPrepare (OCIStmt *stmtp, OCIError *errhp, const OraText *stmt, + ub4 stmt_len, ub4 language, ub4 mode); + +sword OCIStmtPrepare2 ( OCISvcCtx *svchp, OCIStmt **stmtp, OCIError *errhp, + const OraText *stmt, ub4 stmt_len, const OraText *key, + ub4 key_len, ub4 language, ub4 mode); + +sword OCIStmtRelease ( OCIStmt *stmtp, OCIError *errhp, const OraText *key, + ub4 key_len, ub4 mode); + +sword OCIBindByPos (OCIStmt *stmtp, OCIBind **bindp, OCIError *errhp, + ub4 position, void *valuep, sb4 value_sz, + ub2 dty, void *indp, ub2 *alenp, ub2 *rcodep, + ub4 maxarr_len, ub4 *curelep, ub4 mode); + +sword OCIBindByName (OCIStmt *stmtp, OCIBind **bindp, OCIError *errhp, + const OraText *placeholder, sb4 placeh_len, + void *valuep, sb4 value_sz, ub2 dty, + void *indp, ub2 *alenp, ub2 *rcodep, + ub4 maxarr_len, ub4 *curelep, ub4 mode); + +sword OCIBindObject (OCIBind *bindp, OCIError *errhp, const OCIType *type, + void **pgvpp, ub4 *pvszsp, void **indpp, + ub4 *indszp); + +sword OCIBindDynamic (OCIBind *bindp, OCIError *errhp, void *ictxp, + OCICallbackInBind icbfp, void *octxp, + OCICallbackOutBind ocbfp); + +sword OCIBindArrayOfStruct (OCIBind *bindp, OCIError *errhp, + ub4 pvskip, ub4 indskip, + ub4 alskip, ub4 rcskip); + +sword OCIStmtGetPieceInfo (OCIStmt *stmtp, OCIError *errhp, + void **hndlpp, ub4 *typep, + ub1 *in_outp, ub4 *iterp, ub4 *idxp, + ub1 *piecep); + +sword OCIStmtSetPieceInfo (void *hndlp, ub4 type, OCIError *errhp, + const void *bufp, ub4 *alenp, ub1 piece, + const void *indp, ub2 *rcodep); + +sword OCIStmtExecute (OCISvcCtx *svchp, OCIStmt *stmtp, OCIError *errhp, + ub4 iters, ub4 rowoff, const OCISnapshot *snap_in, + OCISnapshot *snap_out, ub4 mode); + +sword OCIDefineByPos (OCIStmt *stmtp, OCIDefine **defnp, OCIError *errhp, + ub4 position, void *valuep, sb4 value_sz, ub2 dty, + void *indp, ub2 *rlenp, ub2 *rcodep, ub4 mode); + +sword OCIDefineObject (OCIDefine *defnp, OCIError *errhp, + const OCIType *type, void **pgvpp, + ub4 *pvszsp, void **indpp, ub4 *indszp); + +sword OCIDefineDynamic (OCIDefine *defnp, OCIError *errhp, void *octxp, + OCICallbackDefine ocbfp); + +sword OCIRowidToChar (OCIRowid *rowidDesc, OraText *outbfp, ub2 *outbflp, + OCIError *errhp); + +sword OCIDefineArrayOfStruct (OCIDefine *defnp, OCIError *errhp, ub4 pvskip, + ub4 indskip, ub4 rlskip, ub4 rcskip); + +sword OCIStmtFetch (OCIStmt *stmtp, OCIError *errhp, ub4 nrows, + ub2 orientation, ub4 mode); + +sword OCIStmtFetch2 (OCIStmt *stmtp, OCIError *errhp, ub4 nrows, + ub2 orientation, sb4 scrollOffset, ub4 mode); + +sword OCIStmtGetBindInfo (OCIStmt *stmtp, OCIError *errhp, ub4 size, + ub4 startloc, + sb4 *found, OraText *bvnp[], ub1 bvnl[], + OraText *invp[], ub1 inpl[], ub1 dupl[], + OCIBind **hndl); + +sword OCIDescribeAny (OCISvcCtx *svchp, OCIError *errhp, + void *objptr, + ub4 objnm_len, ub1 objptr_typ, ub1 info_level, + ub1 objtyp, OCIDescribe *dschp); + +sword OCIParamGet (const void *hndlp, ub4 htype, OCIError *errhp, + void **parmdpp, ub4 pos); + +sword OCIParamSet(void *hdlp, ub4 htyp, OCIError *errhp, const void *dscp, + ub4 dtyp, ub4 pos); + +sword OCITransStart (OCISvcCtx *svchp, OCIError *errhp, + uword timeout, ub4 flags ); + +sword OCITransDetach (OCISvcCtx *svchp, OCIError *errhp, ub4 flags ); + +sword OCITransCommit (OCISvcCtx *svchp, OCIError *errhp, ub4 flags); + +sword OCITransRollback (OCISvcCtx *svchp, OCIError *errhp, ub4 flags); + +sword OCITransPrepare (OCISvcCtx *svchp, OCIError *errhp, ub4 flags); + +sword OCITransMultiPrepare (OCISvcCtx *svchp, ub4 numBranches, + OCITrans **txns, OCIError **errhp); + +sword OCITransForget (OCISvcCtx *svchp, OCIError *errhp, ub4 flags); + +sword OCIErrorGet (void *hndlp, ub4 recordno, OraText *sqlstate, + sb4 *errcodep, OraText *bufp, ub4 bufsiz, ub4 type); + +sword OCILobAppend (OCISvcCtx *svchp, OCIError *errhp, + OCILobLocator *dst_locp, + OCILobLocator *src_locp); + +sword OCILobAssign (OCIEnv *envhp, OCIError *errhp, + const OCILobLocator *src_locp, + OCILobLocator **dst_locpp); + +sword OCILobCharSetForm (OCIEnv *envhp, OCIError *errhp, + const OCILobLocator *locp, ub1 *csfrm); + +sword OCILobCharSetId (OCIEnv *envhp, OCIError *errhp, + const OCILobLocator *locp, ub2 *csid); + +sword OCILobCopy (OCISvcCtx *svchp, OCIError *errhp, OCILobLocator *dst_locp, + OCILobLocator *src_locp, ub4 amount, ub4 dst_offset, + ub4 src_offset); + +sword OCILobCreateTemporary(OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp, + ub2 csid, + ub1 csfrm, + ub1 lobtype, + boolean cache, + OCIDuration duration); + + +sword OCILobClose( OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp ); + + +sword OCILobDisableBuffering (OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp); + +sword OCILobEnableBuffering (OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp); + +sword OCILobErase (OCISvcCtx *svchp, OCIError *errhp, OCILobLocator *locp, + ub4 *amount, ub4 offset); + +sword OCILobFileClose (OCISvcCtx *svchp, OCIError *errhp, + OCILobLocator *filep); + +sword OCILobFileCloseAll (OCISvcCtx *svchp, OCIError *errhp); + +sword OCILobFileExists (OCISvcCtx *svchp, OCIError *errhp, + OCILobLocator *filep, + boolean *flag); + +sword OCILobFileGetName (OCIEnv *envhp, OCIError *errhp, + const OCILobLocator *filep, + OraText *dir_alias, ub2 *d_length, + OraText *filename, ub2 *f_length); + +sword OCILobFileIsOpen (OCISvcCtx *svchp, OCIError *errhp, + OCILobLocator *filep, + boolean *flag); + +sword OCILobFileOpen (OCISvcCtx *svchp, OCIError *errhp, + OCILobLocator *filep, + ub1 mode); + +sword OCILobFileSetName (OCIEnv *envhp, OCIError *errhp, + OCILobLocator **filepp, + const OraText *dir_alias, ub2 d_length, + const OraText *filename, ub2 f_length); + +sword OCILobFlushBuffer (OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp, + ub4 flag); + +sword OCILobFreeTemporary(OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp); + +sword OCILobGetChunkSize(OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp, + ub4 *chunksizep); + +sword OCILobGetLength (OCISvcCtx *svchp, OCIError *errhp, + OCILobLocator *locp, + ub4 *lenp); + +sword OCILobIsEqual (OCIEnv *envhp, const OCILobLocator *x, + const OCILobLocator *y, + boolean *is_equal); + +sword OCILobIsOpen( OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp, + boolean *flag); + +sword OCILobIsTemporary(OCIEnv *envp, + OCIError *errhp, + OCILobLocator *locp, + boolean *is_temporary); + +sword OCILobLoadFromFile (OCISvcCtx *svchp, OCIError *errhp, + OCILobLocator *dst_locp, + OCILobLocator *src_filep, + ub4 amount, ub4 dst_offset, + ub4 src_offset); + +sword OCILobLocatorAssign (OCISvcCtx *svchp, OCIError *errhp, + const OCILobLocator *src_locp, + OCILobLocator **dst_locpp); + + +sword OCILobLocatorIsInit (OCIEnv *envhp, OCIError *errhp, + const OCILobLocator *locp, + boolean *is_initialized); + +sword OCILobOpen( OCISvcCtx *svchp, + OCIError *errhp, + OCILobLocator *locp, + ub1 mode ); + +sword OCILobRead (OCISvcCtx *svchp, OCIError *errhp, OCILobLocator *locp, + ub4 *amtp, ub4 offset, void *bufp, ub4 bufl, void *ctxp, + OCICallbackLobRead cbfp, ub2 csid, ub1 csfrm); + +sword OCILobTrim (OCISvcCtx *svchp, OCIError *errhp, OCILobLocator *locp, + ub4 newlen); + +sword OCILobWrite (OCISvcCtx *svchp, OCIError *errhp, OCILobLocator *locp, + ub4 *amtp, ub4 offset, void *bufp, ub4 buflen, + ub1 piece, void *ctxp, OCICallbackLobWrite cbfp, + ub2 csid, ub1 csfrm); + +sword OCILobGetDeduplicateRegions(OCISvcCtx *svchp, OCIError *errhp, + OCILobLocator *locp, + OCILobRegion *regp, ub4 *count, ub1 piece, + void *ctxp, + OCICallbackLobGetDeduplicateRegions cbfp); + +sword OCILobWriteAppend(OCISvcCtx *svchp, OCIError *errhp, OCILobLocator *lobp, + ub4 *amtp, void *bufp, ub4 bufl, ub1 piece, + void *ctxp, OCICallbackLobWrite cbfp, ub2 csid, + ub1 csfrm); + +sword OCIBreak (void *hndlp, OCIError *errhp); + +sword OCIReset (void *hndlp, OCIError *errhp); + +sword OCIServerVersion (void *hndlp, OCIError *errhp, OraText *bufp, + ub4 bufsz, + ub1 hndltype); + +sword OCIServerRelease (void *hndlp, OCIError *errhp, OraText *bufp, + ub4 bufsz, + ub1 hndltype, ub4 *version); + +sword OCIAttrGet (const void *trgthndlp, ub4 trghndltyp, + void *attributep, ub4 *sizep, ub4 attrtype, + OCIError *errhp); + +sword OCIAttrSet (void *trgthndlp, ub4 trghndltyp, void *attributep, + ub4 size, ub4 attrtype, OCIError *errhp); + +sword OCISvcCtxToLda (OCISvcCtx *svchp, OCIError *errhp, Lda_Def *ldap); + +sword OCILdaToSvcCtx (OCISvcCtx **svchpp, OCIError *errhp, Lda_Def *ldap); + +sword OCIResultSetToStmt (OCIResult *rsetdp, OCIError *errhp); + +sword OCIFileClose ( void *hndl, OCIError *err, OCIFileObject *filep ); + +sword OCIUserCallbackRegister(void *hndlp, ub4 type, void *ehndlp, + OCIUserCallback callback, void *ctxp, + ub4 fcode, ub4 when, OCIUcb *ucbDesc); + +sword OCIUserCallbackGet(void *hndlp, ub4 type, void *ehndlp, + ub4 fcode, ub4 when, OCIUserCallback *callbackp, + void **ctxpp, OCIUcb *ucbDesc); + +sword OCISharedLibInit(void *metaCtx, void *libCtx, ub4 argfmt, sword argc, + void **argv, OCIEnvCallbackType envCallback); + +sword OCIFileExists ( void *hndl, OCIError *err, OraText *filename, + OraText *path, ub1 *flag ); + +sword OCIFileFlush( void *hndl, OCIError *err, OCIFileObject *filep ); + + +sword OCIFileGetLength( void *hndl, OCIError *err, OraText *filename, + OraText *path, ubig_ora *lenp ); + +sword OCIFileInit ( void *hndl, OCIError *err ); + +sword OCIFileOpen ( void *hndl, OCIError *err, OCIFileObject **filep, + OraText *filename, OraText *path, ub4 mode, ub4 create, + ub4 type ); + +sword OCIFileRead ( void *hndl, OCIError *err, OCIFileObject *filep, + void *bufp, ub4 bufl, ub4 *bytesread ); + +sword OCIFileSeek ( void *hndl, OCIError *err, OCIFileObject *filep, + uword origin, ubig_ora offset, sb1 dir ); + +sword OCIFileTerm ( void *hndl, OCIError *err ); + + +sword OCIFileWrite ( void *hndl, OCIError *err, OCIFileObject *filep, + void *bufp, ub4 buflen, ub4 *byteswritten ); + + +#ifdef ORAXB8_DEFINED + +sword OCILobCopy2 (OCISvcCtx *svchp, OCIError *errhp, + OCILobLocator *dst_locp, + OCILobLocator *src_locp, oraub8 amount, + oraub8 dst_offset, + oraub8 src_offset); + +sword OCILobErase2 (OCISvcCtx *svchp, OCIError *errhp, OCILobLocator *locp, + oraub8 *amount, oraub8 offset); + +sword OCILobGetLength2 (OCISvcCtx *svchp, OCIError *errhp, + OCILobLocator *locp, oraub8 *lenp); + +sword OCILobLoadFromFile2 (OCISvcCtx *svchp, OCIError *errhp, + OCILobLocator *dst_locp, + OCILobLocator *src_filep, + oraub8 amount, oraub8 dst_offset, + oraub8 src_offset); + +sword OCILobRead2 (OCISvcCtx *svchp, OCIError *errhp, OCILobLocator *locp, + oraub8 *byte_amtp, oraub8 *char_amtp, oraub8 offset, + void *bufp, oraub8 bufl, ub1 piece, void *ctxp, + OCICallbackLobRead2 cbfp, ub2 csid, ub1 csfrm); + +sword OCILobArrayRead (OCISvcCtx *svchp, OCIError *errhp, ub4 *array_iter, + OCILobLocator **lobp_arr, oraub8 *byte_amt_arr, + oraub8 *char_amt_arr, oraub8 *offset_arr, + void **bufp_arr, oraub8 *bufl_arr, ub1 piece, + void *ctxp, OCICallbackLobArrayRead cbfp, ub2 csid, + ub1 csfrm); + +sword OCILobTrim2 (OCISvcCtx *svchp, OCIError *errhp, OCILobLocator *locp, + oraub8 newlen); + +sword OCILobWrite2 (OCISvcCtx *svchp, OCIError *errhp, OCILobLocator *locp, + oraub8 *byte_amtp, oraub8 *char_amtp, oraub8 offset, + void *bufp, oraub8 buflen, ub1 piece, void *ctxp, + OCICallbackLobWrite2 cbfp, ub2 csid, ub1 csfrm); + +sword OCILobArrayWrite (OCISvcCtx *svchp, OCIError *errhp, ub4 *array_iter, + OCILobLocator **lobp_arr, oraub8 *byte_amt_arr, + oraub8 *char_amt_arr, oraub8 *offset_arr, + void **bufp_arr, oraub8 *bufl_arr, ub1 piece, + void *ctxp, OCICallbackLobArrayWrite cbfp, ub2 csid, + ub1 csfrm); + +sword OCILobWriteAppend2 (OCISvcCtx *svchp, OCIError *errhp, + OCILobLocator *lobp, + oraub8 *byte_amtp, oraub8 *char_amtp, void *bufp, + oraub8 bufl, ub1 piece, void *ctxp, + OCICallbackLobWrite2 cbfp, ub2 csid, ub1 csfrm); + +sword OCILobGetStorageLimit (OCISvcCtx *svchp, OCIError *errhp, + OCILobLocator *lobp, oraub8 *limitp); + +sword OCILobGetOptions (OCISvcCtx *svchp, OCIError *errhp, + OCILobLocator *lobp, + ub4 optypes, void *optionsp, ub4 *optionslenp, + ub4 mode); + +sword OCILobSetOptions (OCISvcCtx *svchp, OCIError *errhp, + OCILobLocator *lobp, + ub4 optypes, void *optionsp, ub4 optionslen, + ub4 mode); + +#endif + +/* + ** Initialize the security package + */ +sword OCISecurityInitialize (OCISecurity *sechandle, OCIError *error_handle); + +sword OCISecurityTerminate (OCISecurity *sechandle, OCIError *error_handle); + +sword OCISecurityOpenWallet(OCISecurity *osshandle, + OCIError *error_handle, + size_t wrllen, + OraText *wallet_resource_locator, + size_t pwdlen, + OraText *password, + nzttWallet *wallet); + +sword OCISecurityCloseWallet(OCISecurity *osshandle, + OCIError *error_handle, + nzttWallet *wallet); + +sword OCISecurityCreateWallet(OCISecurity *osshandle, + OCIError *error_handle, + size_t wrllen, + OraText *wallet_resource_locator, + size_t pwdlen, + OraText *password, + nzttWallet *wallet); + +sword OCISecurityDestroyWallet(OCISecurity *osshandle, + OCIError *error_handle, + size_t wrllen, + OraText *wallet_resource_locator, + size_t pwdlen, + OraText *password); + +sword OCISecurityStorePersona(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona **persona, + nzttWallet *wallet); + +sword OCISecurityOpenPersona(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona); + +sword OCISecurityClosePersona(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona); + +sword OCISecurityRemovePersona(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona **persona); + +sword OCISecurityCreatePersona(OCISecurity *osshandle, + OCIError *error_handle, + nzttIdentType identity_type, + nzttCipherType cipher_type, + nzttPersonaDesc *desc, + nzttPersona **persona); + +sword OCISecuritySetProtection(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona, + nzttcef crypto_engine_function, + nztttdufmt data_unit_format, + nzttProtInfo *protection_info); + +sword OCISecurityGetProtection(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona, + nzttcef crypto_engine_function, + nztttdufmt * data_unit_format_ptr, + nzttProtInfo *protection_info); + +sword OCISecurityRemoveIdentity(OCISecurity *osshandle, + OCIError *error_handle, + nzttIdentity **identity_ptr); + +sword OCISecurityCreateIdentity(OCISecurity *osshandle, + OCIError *error_handle, + nzttIdentType type, + nzttIdentityDesc *desc, + nzttIdentity **identity_ptr); + +sword OCISecurityAbortIdentity(OCISecurity *osshandle, + OCIError *error_handle, + nzttIdentity **identity_ptr); + +sword OCISecurityFreeIdentity(OCISecurity *osshandle, + OCIError *error_handle, + nzttIdentity **identity_ptr); + + +sword OCISecurityStoreTrustedIdentity(OCISecurity *osshandle, + OCIError *error_handle, + nzttIdentity **identity_ptr, + nzttPersona *persona); + +sword OCISecuritySign(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona, + nzttces signature_state, + size_t input_length, + ub1 *input, + nzttBufferBlock *buffer_block); + +sword OCISecuritySignExpansion(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona, + size_t inputlen, + size_t *signature_length); + +sword OCISecurityVerify(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona, + nzttces signature_state, + size_t siglen, + ub1 *signature, + nzttBufferBlock *extracted_message, + boolean *verified, + boolean *validated, + nzttIdentity **signing_party_identity); + +sword OCISecurityValidate(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona, + nzttIdentity *identity, + boolean *validated); + +sword OCISecuritySignDetached(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona, + nzttces signature_state, + size_t input_length, + ub1 * input, + nzttBufferBlock *signature); + +sword OCISecuritySignDetExpansion(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona, + size_t input_length, + size_t *required_buffer_length); + +sword OCISecurityVerifyDetached(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona, + nzttces signature_state, + size_t data_length, + ub1 *data, + size_t siglen, + ub1 *signature, + boolean *verified, + boolean *validated, + nzttIdentity **signing_party_identity); + +sword OCISecurity_PKEncrypt(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona, + size_t number_of_recipients, + nzttIdentity *recipient_list, + nzttces encryption_state, + size_t input_length, + ub1 *input, + nzttBufferBlock *encrypted_data); + +sword OCISecurityPKEncryptExpansion(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona, + size_t number_recipients, + size_t input_length, + size_t *buffer_length_required); + +sword OCISecurityPKDecrypt(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona, + nzttces encryption_state, + size_t input_length, + ub1 *input, + nzttBufferBlock *encrypted_data); + +sword OCISecurityEncrypt(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona, + nzttces encryption_state, + size_t input_length, + ub1 *input, + nzttBufferBlock *encrypted_data); + +sword OCISecurityEncryptExpansion(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona, + size_t input_length, + size_t *encrypted_data_length); + +sword OCISecurityDecrypt(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona, + nzttces decryption_state, + size_t input_length, + ub1 *input, + nzttBufferBlock *decrypted_data); + +sword OCISecurityEnvelope(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona, + size_t number_of_recipients, + nzttIdentity *identity, + nzttces encryption_state, + size_t input_length, + ub1 *input, + nzttBufferBlock *enveloped_data); + +sword OCISecurityDeEnvelope(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona, + nzttces decryption_state, + size_t input_length, + ub1 *input, + nzttBufferBlock *output_message, + boolean *verified, + boolean *validated, + nzttIdentity **sender_identity); + +sword OCISecurityKeyedHash(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona, + nzttces hash_state, + size_t input_length, + ub1 *input, + nzttBufferBlock *keyed_hash); + +sword OCISecurityKeyedHashExpansion(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona, + size_t input_length, + size_t *required_buffer_length); + +sword OCISecurityHash(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona, + nzttces hash_state, + size_t input, + ub1 *input_length, + nzttBufferBlock *hash); + +sword OCISecurityHashExpansion(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona, + size_t input_length, + size_t *required_buffer_length); + +sword OCISecuritySeedRandom(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona, + size_t seed_length, + ub1 *seed); + +sword OCISecurityRandomBytes(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona, + size_t number_of_bytes_desired, + nzttBufferBlock *random_bytes); + +sword OCISecurityRandomNumber(OCISecurity *osshandle, + OCIError *error_handle, + nzttPersona *persona, + uword *random_number_ptr); + +sword OCISecurityInitBlock(OCISecurity *osshandle, + OCIError *error_handle, + nzttBufferBlock *buffer_block); + +sword OCISecurityReuseBlock(OCISecurity *osshandle, + OCIError *error_handle, + nzttBufferBlock *buffer_block); + +sword OCISecurityPurgeBlock(OCISecurity *osshandle, + OCIError *error_handle, + nzttBufferBlock *buffer_block); + +sword OCISecuritySetBlock(OCISecurity *osshandle, + OCIError *error_handle, + uword flags_to_set, + size_t buffer_length, + size_t used_buffer_length, + ub1 *buffer, + nzttBufferBlock *buffer_block); + +sword OCISecurityGetIdentity(OCISecurity *osshandle, + OCIError *error_handle, + size_t namelen, + OraText *distinguished_name, + nzttIdentity **identity); + +sword OCIAQEnq(OCISvcCtx *svchp, OCIError *errhp, OraText *queue_name, + OCIAQEnqOptions *enqopt, OCIAQMsgProperties *msgprop, + OCIType *payload_tdo, void **payload, void **payload_ind, + OCIRaw **msgid, ub4 flags); + +sword OCIAQDeq(OCISvcCtx *svchp, OCIError *errhp, OraText *queue_name, + OCIAQDeqOptions *deqopt, OCIAQMsgProperties *msgprop, + OCIType *payload_tdo, void **payload, void **payload_ind, + OCIRaw **msgid, ub4 flags); + +sword OCIAQEnqArray(OCISvcCtx *svchp, OCIError *errhp, OraText *queue_name, + OCIAQEnqOptions *enqopt, ub4 *iters, + OCIAQMsgProperties **msgprop, OCIType *payload_tdo, + void **payload, void **payload_ind, OCIRaw **msgid, + void *ctxp, OCICallbackAQEnq enqcbfp, ub4 flags); + +sword OCIAQEnqStreaming(OCISvcCtx *svchp, OCIError *errhp, OraText *queue_name, + OCIAQEnqOptions *enqopt, OCIType *payload_tdo, + void *ctxp, OCICallbackAQEnqStreaming enqcbfp, + ub4 flags); + +sword OCIAQDeqArray(OCISvcCtx *svchp, OCIError *errhp, OraText *queue_name, + OCIAQDeqOptions *deqopt, ub4 *iters, + OCIAQMsgProperties **msgprop, OCIType *payload_tdo, + void **payload, void **payload_ind, OCIRaw **msgid, + void *ctxp, OCICallbackAQDeq deqcbfp, ub4 flags); + +sword OCIAQListen(OCISvcCtx *svchp, OCIError *errhp, + OCIAQAgent **agent_list, ub4 num_agents, + sb4 wait, OCIAQAgent **agent, + ub4 flags); + +sword OCIAQListen2(OCISvcCtx *svchp, OCIError *errhp, + OCIAQAgent **agent_list, ub4 num_agents, + OCIAQListenOpts *lopts, OCIAQAgent **agent, + OCIAQLisMsgProps *lmops, ub4 flags); + +sword OCIAQGetReplayInfo(OCISvcCtx *svchp, OCIError *errhp, + OraText *queue_name, OCIAQAgent *sender, + ub4 replay_attribute, OraText *correlation, + ub2 *corr_len); + +sword OCIAQResetReplayInfo(OCISvcCtx *svchp, OCIError *errhp, + OraText *queue_name, OCIAQAgent *sender, + ub4 replay_attribute); + +sword OCIExtractInit(void *hndl, OCIError *err); + +sword OCIExtractTerm(void *hndl, OCIError *err); + +sword OCIExtractReset(void *hndl, OCIError *err); + +sword OCIExtractSetNumKeys(void *hndl, OCIError *err, uword numkeys); + +sword OCIExtractSetKey(void *hndl, OCIError *err, const OraText *name, + ub1 type, ub4 flag, const void *defval, + const sb4 *intrange, const OraText *const *strlist); + +sword OCIExtractFromFile(void *hndl, OCIError *err, ub4 flag, + OraText *filename); + +sword OCIExtractFromStr(void *hndl, OCIError *err, ub4 flag, OraText *input); + +sword OCIExtractToInt(void *hndl, OCIError *err, OraText *keyname, + uword valno, sb4 *retval); + +sword OCIExtractToBool(void *hndl, OCIError *err, OraText *keyname, + uword valno, ub1 *retval); + +sword OCIExtractToStr(void *hndl, OCIError *err, OraText *keyname, + uword valno, OraText *retval, uword buflen); + +sword OCIExtractToOCINum(void *hndl, OCIError *err, OraText *keyname, + uword valno, OCINumber *retval); + +sword OCIExtractToList(void *hndl, OCIError *err, uword *numkeys); + +sword OCIExtractFromList(void *hndl, OCIError *err, uword index, + OraText **name, + ub1 *type, uword *numvals, void ***values); + +/* Memory Related Service Interfaces */ + +sword OCIMemoryAlloc(void *hdl, OCIError *err, void **mem, + OCIDuration dur, ub4 size, ub4 flags); + +sword OCIMemoryResize(void *hdl, OCIError *err, void **mem, + ub4 newsize, ub4 flags); + +sword OCIMemoryFree(void *hdl, OCIError *err, void *mem); + +sword OCIContextSetValue(void *hdl, OCIError *err, OCIDuration duration, + ub1 *key, ub1 keylen, void *ctx_value); + +sword OCIContextGetValue(void *hdl, OCIError *err, ub1 *key, + ub1 keylen, void **ctx_value); + +sword OCIContextClearValue(void *hdl, OCIError *err, ub1 *key, + ub1 keylen); + +sword OCIContextGenerateKey(void *hdl, OCIError *err, ub4 *key); + +sword OCIMemorySetCurrentIDs(void *hdl, OCIError *err, + ub4 curr_session_id, ub4 curr_trans_id, + ub4 curr_stmt_id); + +sword OCIPicklerTdsCtxInit(OCIEnv *env, OCIError *err, + OCIPicklerTdsCtx **tdsc); + +sword OCIPicklerTdsCtxFree(OCIEnv *env, OCIError *err, OCIPicklerTdsCtx *tdsc); + +sword OCIPicklerTdsInit(OCIEnv *env, OCIError *err, OCIPicklerTdsCtx *tdsc, + OCIPicklerTds **tdsh); + +sword OCIPicklerTdsFree(OCIEnv *env, OCIError *err, OCIPicklerTds *tdsh); + +sword OCIPicklerTdsCreateElementNumber(OCIEnv *env, OCIError *err, + OCIPicklerTds *tdsh, ub1 prec, + sb1 scale, OCIPicklerTdsElement *elt); + +sword OCIPicklerTdsCreateElementChar(OCIEnv *env, OCIError *err, + OCIPicklerTds *tdsh, ub2 len, + OCIPicklerTdsElement *elt); + +sword OCIPicklerTdsCreateElementVarchar(OCIEnv *env, OCIError *err, + OCIPicklerTds *tdsh, ub2 len, + OCIPicklerTdsElement *elt); + +sword OCIPicklerTdsCreateElementRaw(OCIEnv *env, OCIError *err, + OCIPicklerTds *tdsh, ub2 len, + OCIPicklerTdsElement *elt); + +sword OCIPicklerTdsCreateElement(OCIEnv *env, OCIError *err, + OCIPicklerTds *tdsh, OCITypeCode dty, + OCIPicklerTdsElement *elt); + +sword OCIPicklerTdsAddAttr(OCIEnv *env, OCIError *err, + OCIPicklerTds *tdsh, OCIPicklerTdsElement elt); + +sword OCIPicklerTdsGenerate(OCIEnv *env, OCIError *err, + OCIPicklerTds *tdsh); + +sword OCIPicklerTdsGetAttr(OCIEnv *env, OCIError *err, + const OCIPicklerTds *tdsh, ub1 attrno, + OCITypeCode *typ, ub2 *len); + +sword OCIPicklerFdoInit(OCIEnv *env, OCIError *err, + OCIPicklerFdo **fdoh); + +sword OCIPicklerFdoFree(OCIEnv *env, OCIError *err, + OCIPicklerFdo *fdoh); + +sword OCIPicklerImageInit(OCIEnv *env, OCIError *err, + OCIPicklerFdo *fdoh, + OCIPicklerTds *tdsh, + OCIPicklerImage **imgh); + +sword OCIPicklerImageFree(OCIEnv *env, OCIError *err, + OCIPicklerImage *imgh); + +sword OCIPicklerImageAddScalar(OCIEnv *env, OCIError *err, + OCIPicklerImage *imgh, + void *scalar, ub4 len); + +sword OCIPicklerImageAddNullScalar(OCIEnv *env, OCIError *err, + OCIPicklerImage *imgh); + +sword OCIPicklerImageGenerate(OCIEnv *env, OCIError *err, + OCIPicklerImage *imgh); + +sword OCIPicklerImageGetScalarSize(OCIEnv *env, OCIError *err, + OCIPicklerImage *imgh, + ub4 attrno, ub4 *size); + +sword OCIPicklerImageGetScalar(OCIEnv *env, OCIError *err, + OCIPicklerImage *imgh, ub4 attrno, + void *buf, ub4 *len, OCIInd *ind); + +sword OCIPicklerImageCollBegin(OCIEnv *env, OCIError *err, + OCIPicklerImage *imgh, const OCIPicklerTds *colltdsh); + +sword OCIPicklerImageCollAddScalar( OCIEnv *env, OCIError *err, + OCIPicklerImage *imgh, void *scalar, + ub4 buflen, OCIInd ind); + +sword OCIPicklerImageCollEnd(OCIEnv *env, OCIError *err, + OCIPicklerImage *imgh); + +/* should take svcctx for locator stuff */ +sword OCIPicklerImageCollBeginScan(OCIEnv *env, OCIError *err, + OCIPicklerImage *imgh, const OCIPicklerTds *coll_tdsh, + ub4 attrnum, ub4 startidx, OCIInd *ind); + +sword OCIPicklerImageCollGetScalarSize(OCIEnv *env, OCIError *err, + const OCIPicklerTds *coll_tdsh, ub4 *size); + +sword OCIPicklerImageCollGetScalar(OCIEnv *env, OCIError *err, + OCIPicklerImage *imgh, void *buf, + ub4 *buflen, OCIInd *ind); + +sword OCIAnyDataGetType(OCISvcCtx *svchp, OCIError *errhp, OCIAnyData *sdata, + OCITypeCode *tc, OCIType **type); + +sword OCIAnyDataIsNull(OCISvcCtx *svchp, OCIError *errhp, OCIAnyData *sdata, + boolean *isnull); + +sword OCIAnyDataConvert(OCISvcCtx *svchp, OCIError *errhp, OCITypeCode tc, + OCIType *type, OCIDuration dur, void *ind, void *data_val, + ub4 len, OCIAnyData **sdata); + +sword OCIAnyDataBeginCreate(OCISvcCtx *svchp, OCIError *errhp, OCITypeCode tc, + OCIType *type, OCIDuration dur, OCIAnyData **sdata); + +sword OCIAnyDataDestroy(OCISvcCtx *svchp, OCIError *errhp, OCIAnyData *sdata); + +sword OCIAnyDataAttrSet(OCISvcCtx *svchp, OCIError *errhp, OCIAnyData *sdata, + OCITypeCode tc, OCIType *type, void *ind, void *attr_val, + ub4 length, boolean is_any); + +sword OCIAnyDataCollAddElem(OCISvcCtx *svchp, OCIError *errhp, + OCIAnyData *sdata, OCITypeCode tc, OCIType *type, void *ind, + void *attr_val, ub4 length, boolean is_any, boolean last_elem); + +sword OCIAnyDataEndCreate(OCISvcCtx *svchp, OCIError *errhp, + OCIAnyData *sdata); + +sword OCIAnyDataAccess(OCISvcCtx *svchp, OCIError *errhp, OCIAnyData *sdata, + OCITypeCode tc, OCIType *type, void *ind, void *attr_val, + ub4 *length); + +sword OCIAnyDataGetCurrAttrNum(OCISvcCtx *svchp, OCIError *errhp, + OCIAnyData *sdata, ub4 *attrnum); + +sword OCIAnyDataAttrGet(OCISvcCtx *svchp, OCIError *errhp, OCIAnyData *sdata, + OCITypeCode tc, OCIType *type, void *ind, void *attr_val, + ub4 *length, boolean is_any); + +sword OCIAnyDataCollGetElem(OCISvcCtx *svchp, OCIError *errhp, + OCIAnyData *sdata, + OCITypeCode tc, OCIType *type, void *ind, void *celem_val, + ub4 *length, boolean is_any); + + +/*------------------------ OCIAnyDataSet interfaces -------------------------*/ + +/* + NAME + OCIAnyDataSetBeginCreate - OCIAnyDataSet Begin Creation + PARAMETERS + svchp (IN/OUT) - The OCI service context. + errhp (IN/OUT) - The OCI error handle. If there is an error, it is + recorded in errhp and this function returns OCI_ERROR. + Diagnostic information can be obtained by calling + OCIErrorGet(). + typecode - typecode corresponding to the OCIAnyDataSet. + type (IN) - type corresponding to the OCIAnyDataSet. If the typecode + corresponds to a built-in type (OCI_TYPECODE_NUMBER etc.) + , this parameter can be NULL. It should be non NULL for + user defined types (OCI_TYPECODE_OBJECT, + OCI_TYPECODE_REF, collection types etc.) + dur (IN) - duration for which OCIAnyDataSet is allocated. + data_set (OUT) - Initialized OCIAnyDataSet. + RETURNS - error code + NOTES + This call allocates an OCIAnyDataSet for the duration of dur and + initializes it with the type information. The OCIAnyDataSet can hold + multiple instances of the given type. For performance reasons, the + OCIAnyDataSet will end up pointing to the passed in OCIType parameter. + It is the responsibility of the caller to ensure that the OCIType is + longer lived (has allocation duration >= the duration of the OCIAnyData + if the OCIType is a transient one, allocation/pin duration >= duration of + the OCIAnyData if the OCIType is a persistent one). + +*/ +sword OCIAnyDataSetBeginCreate(OCISvcCtx *svchp, OCIError *errhp, + OCITypeCode typecode, const OCIType *type, OCIDuration dur, + OCIAnyDataSet ** data_set); + +/* + NAME + OCIAnyDataSetDestroy - OCIAnyDataSet Destroy + DESCRIPTION + This call frees the OCIAnyDataSet allocated using + OCIAnyDataSetBeginCreate(). + RETURNS + error code. + PARAMETERS + svchp (IN/OUT) - The OCI service context. + errhp (IN/OUT) - The OCI Error handle. + data_set (IN/OUT) - OCIAnyDataSet to be freed. +*/ +sword OCIAnyDataSetDestroy(OCISvcCtx *svchp, OCIError *errhp, + OCIAnyDataSet *data_set); + + +/* + NAME + OCIAnyDataSetAddInstance - OCIAnyDataSet Add an instance + DESCRIPTION + This call adds a new skeleton instance to the OCIAnyDataSet and all the + attributes of the instance are set to NULL. It returns this skeleton + instance through the OCIAnyData parameter which can be constructed + subsequently by invoking the OCIAnyData API. + RETURNS + error code. + PARAMETERS + svchp (IN/OUT) - The OCI service context. + errhp (IN/OUT) - The OCI Error handle. + data_set (IN/OUT) - OCIAnyDataSet to which a new instance is added. + data (IN/OUT) - OCIAnyData corresponding to the newly added + instance. If (*data) is NULL, a new OCIAnyData will + be allocated for same duration as the OCIAnyDataSet. + If (*data) is not NULL, it will get reused. This + OCIAnyData can be subseqently constructed using the + OCIAnyDataConvert() call or it can be constructed + piece-wise using the OCIAnyDataAttrSet and + OCIAnyDataCollAddElem calls. + NOTES + No Destruction of the old value is done here. It is the responsibility of + the caller to destroy the old value pointed to by (*data) and set (*data) + to a null pointer before beginning to make a sequence of this call. No + deep copying (of OCIType information nor the data part.) is done in the + returned OCIAnyData. This OCIAnyData cannot be used beyond the allocation + duration of the OCIAnyDataSet (it is like a reference into the + OCIAnyDataSet). The returned OCIAnyData can be reused on subsequent calls + to this function, to sequentially add new data instances to the + OCIAnyDataSet. +*/ +sword OCIAnyDataSetAddInstance(OCISvcCtx *svchp, OCIError *errhp, + OCIAnyDataSet *data_set, OCIAnyData **data); + +/* + NAME + OCIAnyDataSetEndCreate - OCIAnyDataSet End Creation process. + DESCRIPTION + This call marks the end of OCIAnyDataSet creation. It should be called + after constructing all of its instance(s). + RETURNS + error code. + PARAMETERS + svchp (IN/OUT) - The OCI service context. + errhp (IN/OUT) - The OCI error handle. If there is an error, it is + recorded in errhp and this function returns + OCI_ERROR. Diagnostic information can be obtained + by calling OCIErrorGet(). + data_set (IN/OUT) - OCIAnyDataSet that has been fully constructed. +*/ +sword OCIAnyDataSetEndCreate(OCISvcCtx *svchp, OCIError *errhp, + OCIAnyDataSet *data_set); + +/* + NAME + OCIAnyDataSetGetType - OCIAnyDataSet Get Type of an OCIAnyDataSet + DESCRIPTION + Gets the Type corresponding to an OCIAnyDataSet. It returns the actual + pointer to the type maintained inside an OCIAnyDataSet. No copying is + done for performance reasons. The client is responsible for not using + this type once the OCIAnyDataSet is freed (or its duration ends). + RETURNS + error code. + PARAMETERS + svchp (IN/OUT) - The OCI service context. + errhp (IN/OUT) - The OCI Error handle. + data_set (IN) - Initialized OCIAnyDataSet. + tc (OUT) - The typecode of the type. + type (OUT) - The type corresponding to the OCIAnyDataSet. This + could be null if the OCIAnyData corresponds to a + built-in type. +*/ +sword OCIAnyDataSetGetType (OCISvcCtx *svchp, OCIError *errhp, + OCIAnyDataSet *data_set, OCITypeCode *tc, OCIType **type); + +/* + NAME + OCIAnyDataSetGetCount - OCIAnyDataSet Get Count of instances. + DESCRIPTION + This call gets the number of instances in the OCIAnyDataSet. + RETURNS + error code. + PARAMETERS + svchp (IN/OUT) - OCI Service Context + errhp (IN/OUT) - OCI Error handle + data_set (IN) - Well formed OCIAnyDataSet. + count (OUT) - number of instances in OCIAnyDataSet +*/ +sword OCIAnyDataSetGetCount(OCISvcCtx *svchp, OCIError *errhp, + OCIAnyDataSet *data_set, ub4 *count); + +/* + NAME + OCIAnyDataSetGetInstance - OCIAnyDataSet Get next instance. + DESCRIPTION + Only sequential access to the instances in an OCIAnyDataSet is allowed. + This call returns the OCIAnyData corresponding to an instance at the + current position and updates the current position. Subsequently, the + OCIAnyData access routines may be used to access the instance. + RETURNS + error code. Returns OCI_NO_DATA if the current position is at the end of + the set, OCI_SUCCESS otherwise. + PARAMETERS + svchp (IN/OUT) - OCI Service Context + errhp (IN/OUT) - OCI Error handle + data_set (IN) - Well formed OCIAnyDataSet + data (IN/OUT) - OCIAnyData corresponding to the instance. If (*data) + is NULL, a new OCIAnyData will be allocated for same + duration as the OCIAnyDataSet. If (*data) is not NULL + , it will get reused. This OCIAnyData can be + subsequently accessed using the OCIAnyDataAccess() + call or piece-wise by using the OCIAnyDataAttrGet() + call. + NOTE + No Destruction of the old value is done here. It is the responsibility of + the caller to destroy the old value pointed to by (*data) and set (*data) + to a null pointer before beginning to make a sequence of this call. No deep + copying (of OCIType information nor the data part.) is done in the returned + OCIAnyData. This OCIAnyData cannot be used beyond the allocation duration + of the OCIAnyDataSet (it is like a reference into the OCIAnyDataSet). The + returned OCIAnyData can be reused on subsequent calls to this function to + sequentially access the OCIAnyDataSet. +*/ +sword OCIAnyDataSetGetInstance(OCISvcCtx *svchp, OCIError *errhp, + OCIAnyDataSet *data_set, OCIAnyData **data); + +/*--------------------- End of OCIAnyDataSet interfaces ---------------------*/ + +sword OCIFormatInit(void *hndl, OCIError *err); + +sword OCIFormatString(void *hndl, OCIError *err, OraText *buffer, + sbig_ora bufferLength, sbig_ora *returnLength, + const OraText *formatString, ...); + +sword OCIFormatTerm(void *hndl, OCIError *err); + +sword OCIFormatTUb1(void); +sword OCIFormatTUb2(void); +sword OCIFormatTUb4(void); +sword OCIFormatTUword(void); +sword OCIFormatTUbig_ora(void); +sword OCIFormatTSb1(void); +sword OCIFormatTSb2(void); +sword OCIFormatTSb4(void); +sword OCIFormatTSword(void); +sword OCIFormatTSbig_ora(void); +sword OCIFormatTEb1(void); +sword OCIFormatTEb2(void); +sword OCIFormatTEb4(void); +sword OCIFormatTEword(void); +sword OCIFormatTChar(void); +sword OCIFormatTText(void); +sword OCIFormatTDouble(void); +sword OCIFormatTDvoid(void); +sword OCIFormatTEnd(void); + +/*-------------------------- Extensions to XA interface ---------------------*/ +/* ------------------------- xaosvch ----------------------------------------*/ +/* + NAME + xaosvch - XA Oracle get SerViCe Handle + DESCRIPTION + Given a database name return the service handle that is used by the + XA library + NOTE + This macro has been provided for backward compatibilty with 8.0.2 +*/ +OCISvcCtx *xaosvch(OraText *dbname); + +/* ------------------------- xaoSvcCtx --------------------------------------*/ +/* + NAME + xaoSvcCtx - XA Oracle get SerViCe ConTeXt + DESCRIPTION + Given a database name return the service handle that is used by the + XA library + NOTE + This routine has been provided for APs to get access to the service + handle that XA library uses. Without this routine APs must use SQLLIB + routine sqlld2 to get access to the Logon data area registered by the + XA library +*/ +OCISvcCtx *xaoSvcCtx(OraText *dbname); + +/* ------------------------- xaoEnv -----------------------------------------*/ +/* + NAME + xaoEnv - XA Oracle get ENvironment Handle + DESCRIPTION + Given a database name return the environment handle that is used by the + XA library + NOTE + This routine has been provided for APs to get access to the environment + handle that XA library uses. Without this routine APs must use SQLLIB + routine sqlld2 to get access to the Logon data area registered by the + XA library +*/ +OCIEnv *xaoEnv(OraText *dbname); + +/* ------------------------- xaosterr ---------------------------------------*/ +/* + NAME + xaosterr - XA Oracle get xa STart ERRor code + DESCRIPTION + Given an oracle error code return the XA error code + */ +int xaosterr(OCISvcCtx *svch, sb4 error); +/*-------------------------- End Extensions ---------------------------------*/ +/*---------------------- Extensions to NLS cartridge service ----------------*/ +/* ----------------------- OCINlsGetInfo ------------------------------------*/ +/* + NAME + OCINlsGetInfo - Get NLS info from OCI environment handle + REMARKS + This function generates language information specified by item from OCI + environment handle envhp into an array pointed to by buf within size + limitation as buflen. + RETURNS + OCI_SUCCESS, OCI_INVALID_HANDLE, or OCI_ERROR on wrong item. + envhp(IN/OUT) + OCI environment handle. + errhp(IN/OUT) + The OCI error handle. If there is an error, it is record in errhp and + this function returns a NULL pointer. Diagnostic information can be + obtained by calling OCIErrorGet(). + buf(OUT) + Pointer to the destination buffer. + buflen(IN) + The size of destination buffer. The maximum length for each information + is 32 bytes. + item(IN) + It specifies to get which item in OCI environment handle and can be one + of following values: + OCI_NLS_DAYNAME1 : Native name for Monday. + OCI_NLS_DAYNAME2 : Native name for Tuesday. + OCI_NLS_DAYNAME3 : Native name for Wednesday. + OCI_NLS_DAYNAME4 : Native name for Thursday. + OCI_NLS_DAYNAME5 : Native name for Friday. + OCI_NLS_DAYNAME6 : Native name for for Saturday. + OCI_NLS_DAYNAME7 : Native name for for Sunday. + OCI_NLS_ABDAYNAME1 : Native abbreviated name for Monday. + OCI_NLS_ABDAYNAME2 : Native abbreviated name for Tuesday. + OCI_NLS_ABDAYNAME3 : Native abbreviated name for Wednesday. + OCI_NLS_ABDAYNAME4 : Native abbreviated name for Thursday. + OCI_NLS_ABDAYNAME5 : Native abbreviated name for Friday. + OCI_NLS_ABDAYNAME6 : Native abbreviated name for for Saturday. + OCI_NLS_ABDAYNAME7 : Native abbreviated name for for Sunday. + OCI_NLS_MONTHNAME1 : Native name for January. + OCI_NLS_MONTHNAME2 : Native name for February. + OCI_NLS_MONTHNAME3 : Native name for March. + OCI_NLS_MONTHNAME4 : Native name for April. + OCI_NLS_MONTHNAME5 : Native name for May. + OCI_NLS_MONTHNAME6 : Native name for June. + OCI_NLS_MONTHNAME7 : Native name for July. + OCI_NLS_MONTHNAME8 : Native name for August. + OCI_NLS_MONTHNAME9 : Native name for September. + OCI_NLS_MONTHNAME10 : Native name for October. + OCI_NLS_MONTHNAME11 : Native name for November. + OCI_NLS_MONTHNAME12 : Native name for December. + OCI_NLS_ABMONTHNAME1 : Native abbreviated name for January. + OCI_NLS_ABMONTHNAME2 : Native abbreviated name for February. + OCI_NLS_ABMONTHNAME3 : Native abbreviated name for March. + OCI_NLS_ABMONTHNAME4 : Native abbreviated name for April. + OCI_NLS_ABMONTHNAME5 : Native abbreviated name for May. + OCI_NLS_ABMONTHNAME6 : Native abbreviated name for June. + OCI_NLS_ABMONTHNAME7 : Native abbreviated name for July. + OCI_NLS_ABMONTHNAME8 : Native abbreviated name for August. + OCI_NLS_ABMONTHNAME9 : Native abbreviated name for September. + OCI_NLS_ABMONTHNAME10 : Native abbreviated name for October. + OCI_NLS_ABMONTHNAME11 : Native abbreviated name for November. + OCI_NLS_ABMONTHNAME12 : Native abbreviated name for December. + OCI_NLS_YES : Native string for affirmative response. + OCI_NLS_NO : Native negative response. + OCI_NLS_AM : Native equivalent string of AM. + OCI_NLS_PM : Native equivalent string of PM. + OCI_NLS_AD : Native equivalent string of AD. + OCI_NLS_BC : Native equivalent string of BC. + OCI_NLS_DECIMAL : decimal character. + OCI_NLS_GROUP : group separator. + OCI_NLS_DEBIT : Native symbol of debit. + OCI_NLS_CREDIT : Native sumbol of credit. + OCI_NLS_DATEFORMAT : Oracle date format. + OCI_NLS_INT_CURRENCY: International currency symbol. + OCI_NLS_LOC_CURRENCY : Locale currency symbol. + OCI_NLS_LANGUAGE : Language name. + OCI_NLS_ABLANGUAGE : Abbreviation for language name. + OCI_NLS_TERRITORY : Territory name. + OCI_NLS_CHARACTER_SET : Character set name. + OCI_NLS_LINGUISTIC : Linguistic name. + OCI_NLS_CALENDAR : Calendar name. + OCI_NLS_DUAL_CURRENCY : Dual currency symbol. +*/ +sword OCINlsGetInfo(void *envhp, OCIError *errhp, OraText *buf, + size_t buflen, ub2 item); + +/* ----------------------- OCINlsNumericInfoGet -----------------------------*/ +/* + NAME + OCINlsNumericInfoGet - Get NLS numeric info from OCI environment handle + REMARKS + This function generates numeric language information specified by item + from OCI environment handle envhp into an output number variable. + RETURNS + OCI_SUCCESS, OCI_INVALID_HANDLE, or OCI_ERROR on wrong item. + envhp(IN/OUT) + OCI environment handle. If handle invalid, returns OCI_INVALID_HANDLE. + errhp(IN/OUT) + The OCI error handle. If there is an error, it is record in errhp and + this function returns a NULL pointer. Diagnostic information can be + obtained by calling OCIErrorGet(). + val(OUT) + Pointer to the output number variable. On OCI_SUCCESS return, it will + contain the requested NLS numeric info. + item(IN) + It specifies to get which item in OCI environment handle and can be one + of following values: + OCI_NLS_CHARSET_MAXBYTESZ : Maximum character byte size for OCI + environment or session handle charset + OCI_NLS_CHARSET_FIXEDWIDTH: Character byte size for fixed-width charset; + 0 for variable-width charset +*/ +sword OCINlsNumericInfoGet(void *envhp, OCIError *errhp, sb4 *val, ub2 item); + +/* ----------------------- OCINlsCharSetNameToId ----------------------------*/ +/* + NAME + OCINlsCharSetNameToId - Get Oracle charset id given Oracle charset name + REMARKS + This function will get the Oracle character set id corresponding to + the given Oracle character set name. + RETURNS + Oracle character set id for the given Oracle character set name if + character set name and OCI handle are valid; otherwise returns 0. + envhp(IN/OUT) + OCI environment handle. + name(IN) + Pointer to a null-terminated Oracle character set name whose id + will be returned. +*/ +ub2 OCINlsCharSetNameToId(void *envhp, const oratext *name); + +/* ----------------------- OCINlsCharSetIdToName ----------------------------*/ +/* + NAME + OCINlsCharSetIdToName - Get Oracle charset name given Oracle charset id + REMARKS + This function will get the Oracle character set name corresponding to + the given Oracle character set id. + RETURNS + OCI_SUCCESS, OCI_INVALID_HANDLE, or OCI_ERROR + envhp(IN/OUT) + OCI environment handle. If handle invalid, returns OCI_INVALID_HANDLE. + buf(OUT) + Pointer to the destination buffer. On OCI_SUCCESS return, it will contain + the null-terminated string for character set name. + buflen(IN) + Size of destination buffer. Recommended size is OCI_NLS_MAXBUFSZ for + guarantee to store an Oracle character set name. If it's smaller than + the length of the character set name, the function will return OCI_ERROR. + id(IN) + Oracle character set id. +*/ +sword OCINlsCharSetIdToName(void *envhp, oratext *buf, size_t buflen, ub2 id); + +/* ----------------------- OCINlsNameMap ------------------------------------*/ +/* + NAME + OCINlsNameMap - Map NLS naming from Oracle to other standards and vice + versa + REMARKS + This function will map NLS naming from Oracle to other standards (such + as ISO, IANA) and vice versa. + RETURNS + OCI_SUCCESS, OCI_INVALID_HANDLE, or OCI_ERROR + envhp(IN/OUT) + OCI environment handle. If handle invalid, returns OCI_INVALID_HANDLE. + buf(OUT) + Pointer to the destination buffer. On OCI_SUCCESS return, it will + contain null-terminated string for requested mapped name. + buflen(IN) + The size of destination buffer. Recommended size is OCI_NLS_MAXBUFSZ + for guarantee to store an NLS name. If it is smaller than the length + of the name, the function will return OCI_ERROR. + srcbuf(IN) + Pointer to null-terminated NLS name. If it is not a valid name in its + define scope, the function will return OCI_ERROR. + flag(IN) + It specifies name mapping direction and can take the following values: + OCI_NLS_CS_IANA_TO_ORA : Map character set name from IANA to Oracle + OCI_NLS_CS_ORA_TO_IANA : Map character set name from Oracle to IANA + OCI_NLS_LANG_ISO_TO_ORA : Map language name from ISO to Oracle + OCI_NLS_LANG_ORA_TO_ISO : Map language name from Oracle to ISO + OCI_NLS_TERR_ISO_TO_ORA : Map territory name from ISO to Oracle + OCI_NLS_TERR_ORA_TO_ISO : Map territory name from Oracle to ISO + OCI_NLS_TERR_ISO3_TO_ORA : Map territory name from 3-letter ISO + abbreviation to Oracle + OCI_NLS_TERR_ORA_TO_ISO3 : Map territory name from Oracle to 3-letter + ISO abbreviation +*/ +sword OCINlsNameMap(void *envhp, oratext *buf, size_t buflen, + const oratext *srcbuf, ub4 flag); + +/* -------------------- OCIMultiByteToWideChar ------------------------------*/ +/* + NAME + OCIMultiByteToWideChar - Convert a null terminated multibyte string into + wchar + REMARKS + This routine converts an entire null-terminated string into the wchar + format. The wchar output buffer will be null-terminated. + RETURNS + OCI_SUCCESS, OCI_INVALID_HANDLE or OCI_ERROR + envhp(IN/OUT) + OCI environment handle to determine the character set of string. + dst (OUT) + Destination buffer for wchar. + src (IN) + Source string to be converted. + rsize (OUT) + Number of characters converted including null-terminator. + If it is a NULL pointer, no number return +*/ +sword OCIMultiByteToWideChar(void *envhp, OCIWchar *dst, const OraText *src, + size_t *rsize); + + +/* --------------------- OCIMultiByteInSizeToWideChar -----------------------*/ +/* + NAME + OCIMultiByteInSizeToWideChar - Convert a mulitbyte string in length into + wchar + REMARKS + This routine converts part of string into the wchar format. It will + convert as many complete characters as it can until it reaches output + buffer size or input buffer size or it reaches a null-terminator in + source string. The output buffer will be null-terminated if space permits. + If dstsz is zero, this function will only return number of characters not + including ending null terminator for converted string. + RETURNS + OCI_SUCCESS, OCI_INVALID_HANDLE or OCI_ERROR + envhp(IN/OUT) + OCI environment handle to determine the character set of string. + dst (OUT) + Pointer to a destination buffer for wchar. It can be NULL pointer when + dstsz is zero. + dstsz(IN) + Destination buffer size in character. If it is zero, this function just + returns number of characters will be need for the conversion. + src (IN) + Source string to be converted. + srcsz(IN) + Length of source string in byte. + rsize(OUT) + Number of characters written into destination buffer, or number of + characters for converted string is dstsz is zero. + If it is NULL pointer, nothing to return. +*/ +sword OCIMultiByteInSizeToWideChar(void *envhp, OCIWchar *dst, + size_t dstsz, const OraText *src, + size_t srcsz, size_t *rsize); + + +/* ---------------------- OCIWideCharToMultiByte ----------------------------*/ +/* + NAME + OCIWideCharToMultiByte - Convert a null terminated wchar string into + multibyte + REMARKS + This routine converts an entire null-terminated wide character string into + multi-byte string. The output buffer will be null-terminated. + RETURNS + OCI_SUCCESS, OCI_INVALID_HANDLE or OCI_ERROR + envhp(IN/OUT) + OCI environment handle to determine the character set of string. + dst (OUT) + Destination buffer for multi-byte string. + src (IN) + Source wchar string to be converted. + rsize (OUT) + Number of bytes written into the destination buffer. + If it is NULL pointer, nothing to return. +*/ +sword OCIWideCharToMultiByte(void *envhp, OraText *dst, const OCIWchar *src, + size_t *rsize); + + +/* ---------------------- OCIWideCharInSizeToMultiByte ----------------------*/ +/* + NAME + OCIWideCharInSizeToMultiByte - Convert a wchar string in length into + mulitbyte + REMARKS + This routine converts part of wchar string into the multi-byte format. + It will convert as many complete characters as it can until it reaches + output buffer size or input buffer size or it reaches a null-terminator + in source string. The output buffer will be null-terminated if space + permits. If dstsz is zero, the function just returns the size of byte not + including ending null-terminator need to store the converted string. + RETURNS + OCI_SUCCESS, OCI_INVALID_HANDLE or OCI_ERROR + envhp(IN/OUT) + OCI environment handle to determine the character set of string. + dst (OUT) + Destination buffer for multi-byte. It can be NULL pointer if dstsz is + zero. + dstsz(IN) + Destination buffer size in byte. If it is zero, it just returns the size + of bytes need for converted string. + src (IN) + Source wchar string to be converted. + srcsz(IN) + Length of source string in character. + rsize(OUT) + Number of bytes written into destination buffer, or number of bytes need + to store the converted string if dstsz is zero. + If it is NULL pointer, nothing to return. +*/ +sword OCIWideCharInSizeToMultiByte(void *envhp, OraText *dst, + size_t dstsz, const OCIWchar *src, + size_t srcsz, size_t *rsize); + + + +/* ----------------------- OCIWideCharIsAlnum -------------------------------*/ +/* + NAME + OCIWideCharIsAlnum - test whether wc is a letter or decimal digit + REMARKS + It tests whether wc is a letter or decimal digit. + RETURNS + TRUE or FLASE. + envhp(IN/OUT) + OCI environment handle to determine the character set . + wc(IN) + Wchar for testing. +*/ +boolean OCIWideCharIsAlnum(void *envhp, OCIWchar wc); + + +/* ----------------------- OCIWideCharIsAlpha -------------------------------*/ +/* + NAME + OCIWideCharIsAlpha - test whether wc is an alphabetic letter + REMARKS + It tests whether wc is an alphabetic letter + RETURNS + TRUE or FLASE. + envhp(IN/OUT) + OCI environment handle to determine the character set . + wc(IN) + Wchar for testing. +*/ +boolean OCIWideCharIsAlpha(void *envhp, OCIWchar wc); + + +/* --------------------- OCIWideCharIsCntrl ---------------------------------*/ +/* + NAME + OCIWideCharIsCntrl - test whether wc is a control character + REMARKS + It tests whether wc is a control character. + RETURNS + TRUE or FLASE. + envhp(IN/OUT) + OCI environment handle to determine the character set . + wc(IN) + Wchar for testing. +*/ +boolean OCIWideCharIsCntrl(void *envhp, OCIWchar wc); + + +/* ----------------------- OCIWideCharIsDigit -------------------------------*/ +/* + NAME + OCIWideCharIsDigit - test whether wc is a decimal digit character + REMARKS + It tests whether wc is a decimal digit character. + RETURNS + TRUE or FLASE. + envhp(IN/OUT) + OCI environment handle to determine the character set . + wc(IN) + Wchar for testing. +*/ +boolean OCIWideCharIsDigit(void *envhp, OCIWchar wc); + + +/* ----------------------- OCIWideCharIsGraph -------------------------------*/ +/* + NAME + OCIWideCharIsGraph - test whether wc is a graph character + REMARKS + It tests whether wc is a graph character. A graph character is character + with a visible representation and normally includes alphabetic letter, + decimal digit, and punctuation. + RETURNS + TRUE or FLASE. + envhp(IN/OUT) + OCI environment handle to determine the character set . + wc(IN) + Wchar for testing. +*/ +boolean OCIWideCharIsGraph(void *envhp, OCIWchar wc); + + +/* ----------------------- OCIWideCharIsLower -------------------------------*/ +/* + NAME + OCIWideCharIsLower - test whether wc is a lowercase letter + REMARKS + It tests whether wc is a lowercase letter. + RETURNS + TRUE or FLASE. + envhp(IN/OUT) + OCI environment handle to determine the character set . + wc(IN) + Wchar for testing. +*/ +boolean OCIWideCharIsLower(void *envhp, OCIWchar wc); + + +/* ----------------------- OCIWideCharIsPrint -------------------------------*/ +/* + NAME + OCIWideCharIsPrint - test whether wc is a printable character + REMARKS + It tests whether wc is a printable character. + RETURNS + TRUE or FLASE. + envhp(IN/OUT) + OCI environment handle to determine the character set . + wc(IN) + Wchar for testing. +*/ +boolean OCIWideCharIsPrint(void *envhp, OCIWchar wc); + + +/* ----------------------- OCIWideCharIsPunct -------------------------------*/ +/* + NAME + OCIWideCharIsPunct - test whether wc is a punctuation character + REMARKS + It tests whether wc is a punctuation character. + RETURNS + TRUE or FLASE. + envhp(IN/OUT) + OCI environment handle to determine the character set . + wc(IN) + Wchar for testing. +*/ +boolean OCIWideCharIsPunct(void *envhp, OCIWchar wc); + + +/* ----------------------- OCIWideCharIsSpace -------------------------------*/ +/* + NAME + OCIWideCharIsSpace - test whether wc is a space character + REMARKS + It tests whether wc is a space character. A space character only causes + white space in displayed text(for example, space, tab, carriage return, + newline, vertical tab or form feed). + RETURNS + TRUE or FLASE. + envhp(IN/OUT) + OCI environment handle to determine the character set . + wc(IN) + Wchar for testing. +*/ +boolean OCIWideCharIsSpace(void *envhp, OCIWchar wc); + + +/* ----------------------- OCIWideCharIsUpper -------------------------------*/ +/* + NAME + OCIWideCharIsUpper - test whether wc is a uppercase letter + REMARKS + It tests whether wc is a uppercase letter. + RETURNS + TRUE or FLASE. + envhp(IN/OUT) + OCI environment handle to determine the character set . + wc(IN) + Wchar for testing. +*/ +boolean OCIWideCharIsUpper(void *envhp, OCIWchar wc); + + +/*----------------------- OCIWideCharIsXdigit -------------------------------*/ +/* + NAME + OCIWideCharIsXdigit - test whether wc is a hexadecimal digit + REMARKS + It tests whether wc is a hexadecimal digit ( 0-9, A-F, a-f ). + RETURNS + TRUE or FLASE. + envhp(IN/OUT) + OCI environment handle to determine the character set . + wc(IN) + Wchar for testing. +*/ +boolean OCIWideCharIsXdigit(void *envhp, OCIWchar wc); + + +/* --------------------- OCIWideCharIsSingleByte ----------------------------*/ +/* + NAME + OCIWideCharIsSingleByte - test whether wc is a single-byte character + REMARKS + It tests whether wc is a single-byte character when converted into + multi-byte. + RETURNS + TRUE or FLASE. + envhp(IN/OUT) + OCI environment handle to determine the character set . + wc(IN) + Wchar for testing. +*/ +boolean OCIWideCharIsSingleByte(void *envhp, OCIWchar wc); + + +/* ----------------------- OCIWideCharToLower -------------------------------*/ +/* + NAME + OCIWideCharToLower - Convert a wchar into the lowercase + REMARKS + If there is a lower-case character mapping for wc in the specified locale, + it will return the lower-case in wchar, else return wc itself. + RETURNS + A wchar + envhp(IN/OUT) + OCI environment handle to determine the character set . + wc(IN) + Wchar for lowercase mapping. +*/ +OCIWchar OCIWideCharToLower(void *envhp, OCIWchar wc); + + +/* ----------------------- OCIWideCharToUpper -------------------------------*/ +/* + NAME + OCIWideCharToUpper - Convert a wchar into the uppercase + REMARKS + If there is a upper-case character mapping for wc in the specified locale, + it will return the upper-case in wchar, else return wc itself. + RETURNS + A wchar + envhp(IN/OUT) + OCI environment handle to determine the character set . + wc(IN) + Wchar for uppercase mapping. +*/ +OCIWchar OCIWideCharToUpper(void *envhp, OCIWchar wc); + + +/* ----------------------- OCIWideCharStrcmp --------------------------------*/ +/* + NAME + OCIWideCharStrcmp - compare two null terminated wchar string + REMARKS + It compares two wchar string in binary ( based on wchar encoding value ), + linguistic, or case-insensitive. + RETURNS + 0, if wstr1 == wstr2. + Positive, if wstr1 > wstr2. + Negative, if wstr1 < wstr2. + envhp(IN/OUT) + OCI environment handle to determine the character set. + wstr1(IN) + Pointer to a null-terminated wchar string. + wstr2(IN) + Pointer to a null-terminated wchar string. + flag(IN) + It is used to decide the comparison method. It can be taken one of the + following values: + OCI_NLS_BINARY : for the binary comparison, this is default value. + OCI_NLS_LINGUISTIC : for linguistic comparison specified in the locale. + This flag can be ORed with OCI_NLS_CASE_INSENSITIVE for case-insensitive + comparison. +*/ +int OCIWideCharStrcmp(void *envhp, const OCIWchar *wstr1, + const OCIWchar *wstr2, int flag); + + +/* ----------------------- OCIWideCharStrncmp -------------------------------*/ +/* + NAME + OCIWideCharStrncmp - compare twe wchar string in length + REMARKS + This function is similar to OCIWideCharStrcmp(), except that at most len1 + characters from wstr1 and len2 characters from wstr1 are compared. The + null-terminator will be taken into the comparison. + RETURNS + 0, if wstr1 = wstr2 + Positive, if wstr1 > wstr2 + Negative, if wstr1 < wstr2 + envhp(IN/OUT) + OCI environment handle to determine the character set . + wstr1(IN) + Pointer to the first wchar string + len1(IN) + The length for the first string for comparison + wstr2(IN) + Pointer to the second wchar string + len2(IN) + The length for the second string for comparison. + flag(IN) + It is used to decide the comparison method. It can be taken one of the + following values: + OCI_NLS_BINARY : for the binary comparison, this is default value. + OCI_NLS_LINGUISTIC : for linguistic comparison specified in the locale. + This flag can be ORed with OCI_NLS_CASE_INSENSITIVE for case-insensitive + comparison. +*/ +int OCIWideCharStrncmp(void *envhp, const OCIWchar *wstr1, size_t len1, + const OCIWchar *wstr2, size_t len2, int flag); + + +/* ----------------------- OCIWideCharStrcat --------------------------------*/ +/* + NAME + OCIWideCharStrcat - concatenate two wchar strings + REMARKS + This function appends a copy of the wchar string pointed to by wsrcstr, + including the null-terminator to the end of wchar string pointed to by + wdststr. It returns the number of character in the result string not + including the ending null-terminator. + RETURNS + number of characters in the result string not including the ending + null-terminator. + envhp(IN/OUT) + OCI environment handle to determine the character set . + wdststr(IN/OUT) + Pointer to the destination wchar string for appending. + wsrcstr(IN) + Pointer to the source wchar string to append. +*/ +size_t OCIWideCharStrcat(void *envhp, OCIWchar *wdststr, + const OCIWchar *wsrcstr); + + +/* ----------------------- OCIWideCharStrchr --------------------------------*/ +/* + NAME + OCIWideCharStrchr - Search the first occurrence of wchar in a wchar string + REMARKS + This function searchs for the first occurrence of wc in the wchar string + pointed to by wstr. It returns a pointer to the whcar if successful, or + a null pointer. + RETURNS + wchar pointer if successful, otherwise a null pointer. + envhp(IN/OUT) + OCI environment handle to determine the character set . + wstr(IN) + Pointer to the wchar string to search + wc(IN) + Wchar to search for. +*/ +OCIWchar *OCIWideCharStrchr(void *envhp, const OCIWchar *wstr, + OCIWchar wc); + + +/* ----------------------- OCIWideCharStrcpy --------------------------------*/ +/* + NAME + OCIWideCharStrcpy - copy a wchar string + REMARKS + This function copies the wchar string pointed to by wsrcstr, including the + null-terminator, into the array pointed to by wdststr. It returns the + number of character copied not including the ending null-terminator. + RETURNS + number of characters copied not including the ending null-terminator. + envhp(IN/OUT) + OCI environment handle to determine the character set . + wdststr(OUT) + Pointer to the destination wchar buffer. + wsrcstr(IN) + Pointer to the source wchar string. +*/ +size_t OCIWideCharStrcpy(void *envhp, OCIWchar *wdststr, + const OCIWchar *wsrcstr); + + +/* ----------------------- OCIWideCharStrlen --------------------------------*/ +/* + NAME + OCIWideCharStrlen - Return number of character in a wchar string + REMARKS + This function computes the number of characters in the wchar string + pointed to by wstr, not including the null-terminator, and returns + this number. + RETURNS + number of characters not including ending null-terminator. + envhp(IN/OUT) + OCI environment handle to determine the character set . + wstr(IN) + Pointer to the source wchar string. +*/ +size_t OCIWideCharStrlen(void *envhp, const OCIWchar *wstr); + + +/* ----------------------- OCIWideCharStrncat -------------------------------*/ +/* + NAME + OCIWideCharStrncat - Concatenate wchar string in length + REMARKS + This function is similar to OCIWideCharStrcat(), except that at most n + characters from wsrcstr are appended to wdststr. Note that the + null-terminator in wsrcstr will stop appending. wdststr will be + null-terminated.. + RETURNS + Number of characters in the result string not including the ending + null-terminator. + envhp(IN/OUT) + OCI environment handle to determine the character set . + wdststr(IN/OUT) + Pointer to the destination wchar string for appending. + wsrcstr(IN) + Pointer to the source wchar string to append. + n(IN) + Number of characters from wsrcstr to append. +*/ +size_t OCIWideCharStrncat(void *envhp, OCIWchar *wdststr, + const OCIWchar *wsrcstr, size_t n); + + +/* ----------------------- OCIWideCharStrncpy -------------------------------*/ +/* + NAME + OCIWideCharStrncpy - Copy wchar string in length + REMARKS + This function is similar to OCIWideCharStrcpy(), except that at most n + characters are copied from the array pointed to by wsrcstr to the array + pointed to by wdststr. Note that the null-terminator in wdststr will + stop coping and result string will be null-terminated. + RETURNS + number of characters copied not including the ending null-terminator. + envhp(IN/OUT) + OCI environment handle to determine the character set . + wdststr(OUT) + Pointer to the destination wchar buffer. + wsrcstr(IN) + Pointer to the source wchar string. + n(IN) + Number of characters from wsrcstr to copy. +*/ +size_t OCIWideCharStrncpy(void *envhp, OCIWchar *wdststr, + const OCIWchar *wsrcstr, size_t n); + + +/* ----------------------- OCIWideCharStrrchr -------------------------------*/ +/* + NAME + OCIWideCharStrrchr - search the last occurrence of a wchar in wchar string + REMARKS + This function searchs for the last occurrence of wc in the wchar string + pointed to by wstr. It returns a pointer to the whcar if successful, or + a null pointer. + RETURNS + wchar pointer if successful, otherwise a null pointer. + envhp(IN/OUT) + OCI environment handle to determine the character set . + wstr(IN) + Pointer to the wchar string to search + wc(IN) + Wchar to search for. +*/ +OCIWchar *OCIWideCharStrrchr(void *envhp, const OCIWchar *wstr, + OCIWchar wc); + + +/* --------------------- OCIWideCharStrCaseConversion -----------------------*/ +/* + NAME + OCIWideCharStrCaseConversion - convert a wchar string into lowercase or + uppercase + REMARKS + This function convert the wide char string pointed to by wsrcstr into the + uppercase or lowercase specified by flag and copies the result into the + array pointed to by wdststr. The result string will be null-terminated. + RETURNS + number of characters for result string not including null-terminator. + envhp(IN/OUT) + OCI environment handle. + wdststr(OUT) + Pointer to destination array. + wsrcstr(IN) + Pointer to source string. + flag(IN) + Specify the case to convert: + OCI_NLS_UPPERCASE : convert to uppercase. + OCI_NLS_LOWERCASE: convert to lowercase. + This flag can be ORed with OCI_NLS_LINGUISTIC to specify that the + linguistic setting in the locale will be used for case conversion. +*/ +size_t OCIWideCharStrCaseConversion(void *envhp, OCIWchar *wdststr, + const OCIWchar *wsrcstr, ub4 flag); + + +/*---------------------- OCIWideCharDisplayLength ---------------------------*/ +/* + NAME + OCIWideCharDisplayLength - Calculate the display length for a wchar + REMARKS + This function determines the number of column positions required for wc + in display. It returns number of column positions, or 0 if wc is + null-terminator. + RETURNS + Number of display positions. + envhp(IN/OUT) + OCI environment handle to determine the character set . + wc(IN) + Wchar character. +*/ +size_t OCIWideCharDisplayLength(void *envhp, OCIWchar wc ); + + +/*---------------------- OCIWideCharMultiByteLength -------------------------*/ +/* + NAME + OCIWideCharMultiByteLength - Determine byte size in multi-byte encoding + REMARKS + This function determines the number of byte required for wc in multi-byte + encoding. It returns number of bytes in multi-byte for wc. + RETURNS + Number of bytes. + envhp(IN/OUT) + OCI environment handle to determine the character set . + wc(IN) + Wchar character. +*/ +size_t OCIWideCharMultiByteLength(void *envhp, OCIWchar wc); + + +/* ----------------------- OCIMultiByteStrcmp -------------------------------*/ +/* + NAME + OCIMultiByteStrcmp - Compare two multi-byte strings + REMARKS + It compares two multi-byte strings in binary ( based on encoding value ), + linguistic, or case-insensitive. + RETURNS + 0, if str1 == str2. + Positive, if str1 > str2. + Negative, if str1 < str2. + envhp(IN/OUT) + OCI environment handle to determine the character set. + str1(IN) + Pointer to a null-terminated string. + str2(IN) + Pointer to a null-terminated string. + flag(IN) + It is used to decide the comparison method. It can be taken one of the + following values: + OCI_NLS_BINARY: for the binary comparison, this is default value. + OCI_NLS_LINGUISTIC: for linguistic comparison specified in the locale. + This flag can be ORed with OCI_NLS_CASE_INSENSITIVE for case-insensitive + comparison. +*/ +int OCIMultiByteStrcmp(void *envhp, const OraText *str1, + const OraText *str2, int flag); + + +/*----------------------- OCIMultiByteStrncmp -------------------------------*/ +/* + NAME + OCIMultiByteStrncmp - compare two strings in length + REMARKS + This function is similar to OCIMultiBytestrcmp(), except that at most + len1 bytes from str1 and len2 bytes from str2 are compared. The + null-terminator will be taken into the comparison. + RETURNS + 0, if str1 = str2 + Positive, if str1 > str2 + Negative, if str1 < str2 + envhp(IN/OUT) + OCI environment handle to determine the character set. + str1(IN) + Pointer to the first string + len1(IN) + The length for the first string for comparison + str2(IN) + Pointer to the second string + len2(IN) + The length for the second string for comparison. + flag(IN) + It is used to decide the comparison method. It can be taken one of the + following values: + OCI_NLS_BINARY: for the binary comparison, this is default value. + OCI_NLS_LINGUISTIC: for linguistic comparison specified in the locale. + This flag can be ORed with OCI_NLS_CASE_INSENSITIVE for case-insensitive + comparison. +*/ +int OCIMultiByteStrncmp(void *envhp, const OraText *str1, size_t len1, + OraText *str2, size_t len2, int flag); + + +/*----------------------- OCIMultiByteStrcat --------------------------------*/ +/* + NAME + OCIMultiByteStrcat - concatenate multibyte strings + REMARKS + This function appends a copy of the multi-byte string pointed to by + srcstr, including the null-terminator to the end of string pointed to by + dststr. It returns the number of bytes in the result string not including + the ending null-terminator. + RETURNS + number of bytes in the result string not including the ending + null-terminator. + envhp(IN/OUT) + Pointer to OCI environment handle + dststr(IN/OUT) + Pointer to the destination multi-byte string for appending. + srcstr(IN) + Pointer to the source string to append. +*/ +size_t OCIMultiByteStrcat(void *envhp, OraText *dststr, + const OraText *srcstr); + + +/*------------------------- OCIMultiByteStrcpy ------------------------------*/ +/* + NAME + OCIMultiByteStrcpy - copy multibyte string + REMARKS + This function copies the multi-byte string pointed to by srcstr, + including the null-terminator, into the array pointed to by dststr. It + returns the number of bytes copied not including the ending + null-terminator. + RETURNS + number of bytes copied not including the ending null-terminator. + envhp(IN/OUT) + Pointer to the OCI environment handle. + srcstr(OUT) + Pointer to the destination buffer. + dststr(IN) + Pointer to the source multi-byte string. +*/ +size_t OCIMultiByteStrcpy(void *envhp, OraText *dststr, + const OraText *srcstr); + + +/*----------------------- OCIMultiByteStrlen --------------------------------*/ +/* + NAME + OCIMultiByteStrlen - Calculate multibyte string length + REMARKS + This function computes the number of bytes in the multi-byte string + pointed to by str, not including the null-terminator, and returns this + number. + RETURNS + number of bytes not including ending null-terminator. + str(IN) + Pointer to the source multi-byte string. +*/ +size_t OCIMultiByteStrlen(void *envhp, const OraText *str); + + +/*----------------------- OCIMultiByteStrncat -------------------------------*/ +/* + NAME + OCIMultiByteStrncat - concatenate string in length + REMARKS + This function is similar to OCIMultiBytestrcat(), except that at most n + bytes from srcstr are appended to dststr. Note that the null-terminator in + srcstr will stop appending and the function will append as many character + as possible within n bytes. dststr will be null-terminated. + RETURNS + Number of bytes in the result string not including the ending + null-terminator. + envhp(IN/OUT) + Pointer to OCI environment handle. + srcstr(IN/OUT) + Pointer to the destination multi-byte string for appending. + dststr(IN) + Pointer to the source multi-byte string to append. + n(IN) + Number of bytes from srcstr to append. +*/ +size_t OCIMultiByteStrncat(void *envhp, OraText *dststr, + const OraText *srcstr, size_t n); + + +/*----------------------- OCIMultiByteStrncpy -------------------------------*/ +/* + NAME + OCIMultiByteStrncpy - copy multibyte string in length + REMARKS + This function is similar to OCIMultiBytestrcpy(), except that at most n + bytes are copied from the array pointed to by srcstr to the array pointed + to by dststr. Note that the null-terminator in srcstr will stop coping and + the function will copy as many character as possible within n bytes. The + result string will be null-terminated. + RETURNS + number of bytes copied not including the ending null-terminator. + envhp(IN/OUT) + Pointer to a OCI environment handle. + dststr(IN) + Pointer to the source multi-byte string. + srcstr(OUT) + Pointer to the destination buffer. + n(IN) + Number of bytes from srcstr to copy. +*/ +size_t OCIMultiByteStrncpy(void *envhp, OraText *dststr, + const OraText *srcstr, size_t n); + + +/*----------------------- OCIMultiByteStrnDisplayLength ---------------------*/ +/* + NAME + OCIMultiByteStrnDisplayLength - calculate the display length for a + multibyt string + REMARKS + This function returns the number of display positions occupied by the + complete characters within the range of n bytes. + RETURNS + number of display positions. + envhp(IN/OUT) + OCI environment handle. + str(IN) + Pointer to a multi-byte string. + n(IN) + Number of bytes to examine. +*/ +size_t OCIMultiByteStrnDisplayLength(void *envhp, const OraText *str1, + size_t n); + + +/*---------------------- OCIMultiByteStrCaseConversion ---------------------*/ +/* + NAME + OCIMultiByteStrCaseConversion + REMARKS + This function convert the multi-byte string pointed to by srcstr into the + uppercase or lowercase specified by flag and copies the result into the + array pointed to by dststr. The result string will be null-terminated. + RETURNS + number of bytes for result string not including null-terminator. + envhp(IN/OUT) + OCI environment handle. + dststr(OUT) + Pointer to destination array. + srcstr(IN) + Pointer to source string. + flag(IN) + Specify the case to convert: + OCI_NLS_UPPERCASE: convert to uppercase. + OCI_NLS_LOWERCASE: convert to lowercase. + This flag can be ORed with OCI_NLS_LINGUISTIC to specify that the + linguistic setting in the locale will be used for case conversion. +*/ +size_t OCIMultiByteStrCaseConversion(void *envhp, OraText *dststr, + const OraText *srcstr, ub4 flag); + + +/*------------------------- OCICharSetToUnicode -----------------------------*/ +/* + NAME + OCICharSetToUnicode - convert multibyte string into Unicode as UCS2 + REMARKS + This function converts a multi-byte string pointed to by src to Unicode + into the array pointed to by dst. The conversion will stop when it reach + to the source limitation or destination limitation. + The function will return number of characters converted into Unicode. + If dstlen is zero, it will just return the number of characters for the + result without real conversion. + RETURNS + OCI_SUCCESS, OCI_INVALID_HANDLE or OCI_ERROR + envhp(IN/OUT) + Pointer to an OCI environment handle + dst(OUT) + Pointer to a destination buffer + dstlen(IN) + Size of destination buffer in character + src(IN) + Pointer to multi-byte source string. + srclen(IN) + Size of source string in bytes. + rsize(OUT) + Number of characters converted. + If it is a NULL pointer, nothing to return. +*/ +sword OCICharSetToUnicode(void *envhp, ub2 *dst, size_t dstlen, + const OraText *src, size_t srclen, size_t *rsize); + + +/*------------------------- OCIUnicodeToCharSet -----------------------------*/ +/* + NAME + OCIUnicodeToCharSet - convert Unicode into multibyte + REMARKS + This function converts a Unicode string pointed to by src to multi-byte + into the array pointed to by dst. The conversion will stop when it reach + to the source limitation or destination limitation. The function will + return number of bytes converted into multi-byte. If dstlen is zero, it + will just return the number of bytes for the result without real + conversion. If a Unicode character is not convertible for the character + set specified in OCI environment handle, a replacement character will be + used for it. In this case, OCICharSetConversionIsReplacementUsed() will + return ture. + RETURNS + OCI_SUCCESS, OCI_INVALID_HANDLE or OCI_ERROR + envhp(IN/OUT) + Pointer to an OCI environment handle. + dst(OUT) + Pointer to a destination buffer. + dstlen(IN) + Size of destination buffer in byte. + src(IN) + Pointer to a Unicode string. + srclen(IN) + Size of source string in characters. + rsize(OUT) + Number of bytes converted. + If it is a NULL pointer, nothing to return. +*/ +sword OCIUnicodeToCharSet(void *envhp, OraText *dst, size_t dstlen, + const ub2 *src, size_t srclen, size_t *rsize); + +/*----------------------- OCINlsCharSetConvert ------------------------------*/ +/* + NAME + OCINlsCharSetConvert - convert between any two character set. + REMARKS + This function converts a string pointed to by src in the character set + specified with srcid to the array pointed to by dst in the character set + specified with dstid. The conversion will stop when it reaches the source + limitation or destination limitation. The function will return the number + of bytes converted into the destination buffer. Even though either source + or destination character set id is OCI_UTF16ID, given and return data + length will be represented with the byte length as this function is + intended for generic purpose. Note the conversion will not stop at null + data. + To get character set id from name, OCINlsCharSetNameToId can be used. + To check if derived data in the destination buffer contains any + replacement character resulting from conversion failure, + OCICharSetConversionIsReplacementUsed can be used to get the status. + Data alignment should be guaranteed by a caller. For example, UTF-16 data + should be aligned to ub2 type. + + RETURNS + OCI_SUCCESS or OCI_ERROR. + errhp(IN/OUT) + OCI error handle. If there is an error, it is recorded in errhp and this + function returns a NULL pointer. Diagnostic information can be obtained + by calling OCIErrorGet(). + dstid(IN) + Character set id for the destination buffer. + dstp(OUT) + Pointer to the destination buffer. + dstlen(IN) + The maximum byte size of destination buffer. + srcid(IN) + Character set id for the source buffer. + srcp(IN) + Pointer to the source buffer. + srclen(IN) + The length byte size of source buffer. + rsize(OUT) + The number of characters converted. If it is a NULL pointer, nothing to + return. +*/ +sword OCINlsCharSetConvert(void *envhp, OCIError *errhp, + ub2 dstid, void *dstp, size_t dstlen, + ub2 srcid, const void *srcp, size_t srclen, + size_t *rsize); + + +/* ------------------- OCICharsetConversionIsReplacementUsed ----------------*/ +/* + NAME + OCICharsetConversionIsReplacementUsed - chech if replacement is used in + conversion + REMARKS + This function indicates whether or not the replacement character was used + for nonconvertible characters in character set conversion in last invoke + of OCICharsetUcs2ToMb(). + RETURNS + TRUE is the replacement character was used in last OCICharsetUcs2ToMb() + invoking, else FALSE. + envhp(IN/OUT) + OCI environment handle. This should be the first handle passed to + OCICharsetUcs2ToMb(). +*/ +boolean OCICharSetConversionIsReplacementUsed(void *envhp); + +/*------------------- OCINlsEnvironmentVariableGet -----------------*/ +/* + NAME + OCINlsEnvironmentVariableGet - get a value of NLS environment variable. + + DESCRIPTION + This function retrieves a value of NLS environment variable to the buffer + pointed to by val. Data type is determined by the parameter specified by + item. Either numeric data or string data can be retrieved. + + RETURNS + OCI_SUCCESS or OCI_ERROR. + + PARAMETERS + valp(OUT) - + Pointer to the buffer. + size(IN) - + Size of the buffer. This argument is only applicable to string data type, + but not to numerical data, in such case, it is ignored. + item(IN) - + NLS item value, which can be one of following values: + OCI_NLS_CHARSET_ID - NLS_LANG character set id in ub2 data type. + OCI_NLS_NCHARSET_ID - NLS_NCHAR character set id in ub2 data type. + charset(IN) - + Character set id for retrieved string data. If it is 0, NLS_LANG will be + used. OCI_UTF16ID is a valid id. In case of numeric data, this argument + is ignored. + rsize(OUT) - + Size of return value. + + NOTE + This functions is mainly used for retrieving character set id from either + NLS_LANG or NLS_NCHAR environment variables. If NLS_LANG is not set, + the default character set id is returned. + For future extension, the buffer is capable for storing other data types. +*/ +sword OCINlsEnvironmentVariableGet(void *valp, size_t size, ub2 item, + ub2 charset, size_t *rsize); + + +/*------------------------- OCIMessageOpen ----------------------------------*/ +/* + NAME + OCIMessageOpen - open a locale message file + REMARKS + This function opens a message handle for facility of product in a language + pointed to by envhp. It first try to open the message file corresponding + to envhp for the facility. If it successes, it will use that file to + initialize a message handle, else it will use the default message file + which is for American language for the facility. The function return a + pointer pointed to a message handle into msghp parameter. + RETURNS + OCI_SUCCESS, OCI_INVALID_HANDLE or OCI_ERROR + envhp(IN/OUT) + A pointer to OCI environment handle for message language. + errhp(IN/OUT) + The OCI error handle. If there is an error, it is record in errhp and this + function returns a NULL pointer. Diagnostic information can be obtained by + calling OCIErrorGet(). + msghp(OUT) + a message handle for return + product(IN) + A pointer to a product name. Product name is used to locate the directory + for message in a system dependent way. For example, in Solaris, the + directory of message files for the product `rdbms' is + `${ORACLE_HOME}/rdbms'. + facility(IN) + A pointer to a facility name in the product. It is used to construct a + message file name. A message file name follows the conversion with + facility as prefix. For example, the message file name for facility + `img' in American language will be `imgus.msb' where `us' is the + abbreviation of American language and `msb' as message binary file + extension. + dur(IN) + Duration for memory allocation for the return message handle. It can be + the following values: + OCI_DURATION_CALL + OCI_DURATION_STATEMENT + OCI_DURATION_SESSION + OCI_DURATION_TRANSACTION + For the detail description, please refer to Memory Related Service + Interfaces section. +*/ +sword OCIMessageOpen(void *envhp, OCIError *errhp, OCIMsg **msghp, + const OraText *product, const OraText *facility, + OCIDuration dur); + + +/*------------------------- OCIMessageGet -----------------------------------*/ +/* + NAME + OCIMessageGet - get a locale message from a message handle + REMARKS + This function will get message with message number identified by msgno and + if buflen is not zero, the function will copy the message into the buffer + pointed to by msgbuf. If buflen is zero, the message will be copied into + a message buffer inside the message handle pointed to by msgh. For both + cases. it will return the pointer to the null-terminated message string. + If it cannot get the message required, it will return a NULL pointer. + RETURNS + A pointer to a null-terminated message string on success, otherwise a NULL + pointer. + msgh(IN/OUT) + Pointer to a message handle which was previously opened by + OCIMessageOpen(). + msgno(IN) + The message number for getting message. + msgbuf(OUT) + Pointer to a destination buffer to the message retrieved. If buflen is + zero, it can be NULL pointer. + buflen(IN) + The size of the above destination buffer. +*/ +OraText *OCIMessageGet(OCIMsg *msgh, ub4 msgno, OraText *msgbuf, + size_t buflen); + +/*------------------------- OCIMessageClose ---------------------------------*/ +/* + NAME + OCIMessageClose - close a message handle + REMARKS + This function closes a message handle pointed to by msgh and frees any + memory associated with this handle. + RETURNS + OCI_SUCCESS, OCI_INVALID_HANDLE or OCI_ERROR + envhp(IN/OUT) + A pointer to OCI environment handle for message language. + errhp(IN/OUT) + The OCI error handle. If there is an error, it is record in errhp and this + function returns a NULL pointer. Diagnostic information can be obtained by + calling OCIErrorGet(). + msghp(IN/OUT) + A pointer to a message handle which was previously opened by + OCIMessageOpen(). +*/ +sword OCIMessageClose(void *envhp, OCIError *errhp, OCIMsg *msghp); + +/*--------------- End of Extensions to NLS cartridge service ----------------*/ + + +/*----------------- Extensions to OCI Thread interface ---------------------*/ +/***************************************************************************** + DESCRIPTION +****************************************************************************** +1 Threads Interface + +The OCIThread package provides a number of commonly used threading +primitives for use by Oracle customers. It offers a portable interface to +threading capabilities native to various platforms. It does not implement +threading on platforms which do not have native threading capability. + +OCIThread does not provide a portable implementation of multithreaded +facilities. It only serves as a set of portable covers for native +multithreaded facilities. Therefore, platforms that do not have native +support for multi-threading will only be able to support a limited +implementation of OCIThread. As a result, products that rely on all of +OCIThread's functionality will not port to all platforms. Products that must +port to all platforms must use only a subset of OCIThread's functionality. +This issue is discussed further in later sections of this document. + +The OCIThread API is split into four main parts. Each part is described +briefly here. The following subsections describe each in greater detail. + + 1. Initialization and Termination Calls + + These calls deal with the initialization and termination of OCIThread. + Initialization of OCIThread initializes the OCIThread context which is + a member of the OCI environment or session handle. This context is + required for other OCIThread calls. + + 2. Passive Threading Primitives + + The passive threading primitives include primitives to manipulate mutual + exclusion (mutex) locks, thread ID's, and thread-specific data keys. + + The reason that these primitives are described as 'passive' is that while + their specifications allow for the existence of multiple threads, they do + not require it. This means that it is possible for these primitives to + be implemented according to specification in both single-threaded and + multi-threaded environments. + + As a result, OCIThread clients that use only these primitives will not + require the existence of multiple threads in order to work correctly, + i.e., they will be able to work in single-threaded environments without + branching code. + + 3. Active Threading Primitives + + Active threading primitives include primitives dealing with the creation, + termination, and other manipulation of threads. + + The reason that these primitives are described as 'active' is that they + can only be used in true multi-threaded environments. Their + specifications explicitly require that it be possible to have multiple + threads. If you need to determine at runtime whether or not you are in a + multi-threaded environment, call OCIThreadIsMulti() before calling an + OCIThread active primitive. + + +1.1 Initialization & Termination +================================== + +The types and functions described in this section are associated with the +initialization and termination of the OCIThread package. OCIThread must +be properly initialized before any of its functionality can be used. +OCIThread's process initialization function, 'OCIThreadProcessInit()', +must be called with care; see below. + +The observed behavior of the initialization and termination functions is the +same regardless of whether OCIThread is in single-threaded or multi-threaded +environment. It is OK to call the initialization functions from both generic +and operating system specific (OSD) code. + +1.1.1 Types + + OCIThreadContext - OCIThread Context + ------------------------------------- + + Most calls to OCIThread functions take the OCI environment or session + handle as a parameter. The OCIThread context is part of the OCI + environment or session handle and it must be initialized by calling + 'OCIThreadInit()'. Termination of the OCIThread context occurs by calling + 'OCIThreadTerm()'. + + The OCIThread context is a private data structure. Clients must NEVER + attempt to examine the contents of the context. + +1.1.2 OCIThreadProcessInit + + OCIThreadProcessInit - OCIThread Process INITialization + -------------------------------------------------------- + + Description + + This function should be called to perform OCIThread process + initialization. + + Prototype + + void OCIThreadProcessInit(); + + Returns + + Nothing. + + Notes + + Whether or not this function needs to be called depends on how OCI + Thread is going to be used. + + * In a single-threaded application, calling this function is optional. + If it is called at all, the first call to it must occur before calls + to any other OCIThread functions. Subsequent calls can be made + without restriction; they will not have any effect. + + * In a multi-threaded application, this function MUST be called. The + first call to it MUST occur 'strictly before' any other OCIThread + calls; i.e., no other calls to OCIThread functions (including other + calls to this one) can be concurrent with the first call. + Subsequent calls to this function can be made without restriction; + they will not have any effect. + + +1.1.3 OCIThreadInit + + OCIThreadInit - OCIThread INITialize + ------------------------------------- + + Description + + This initializes OCIThread context. + + Prototype + + sword OCIThreadInit(void *hndl, OCIError *err); + + hndl(IN/OUT): The OCI environment or session handle. + + err(IN/OUT): The OCI error handle. If there is an error and OCI_ERROR + is returned, the error is recorded in err and diagnostic + information can be obtained by calling OCIErrorGet(). + + Returns + + OCI_SUCCESS, OCI_ERROR or OCI_INVALID_HANDLE. + + Notes + + It is illegal for OCIThread clients to try an examine the memory + pointed to by the returned pointer. + + It is safe to make concurrent calls to 'OCIThreadInit()'. Unlike + 'OCIThreadProcessInit()', there is no need to have a first call + that occurs before all the others. + + The first time 'OCIThreadInit()' is called, it initilaizes the OCI + Thread context. It also saves a pointer to the context in some system + dependent manner. Subsequent calls to 'OCIThreadInit()' will return + the same context. + + Each call to 'OCIThreadInit()' must eventually be matched by a call to + 'OCIThreadTerm()'. + + OCIThreadTerm - OCIThread TERMinate + ------------------------------------ + + Description + + This should be called to release the OCIThread context. It should be + called exactly once for each call made to 'OCIThreadInit()'. + + Prototype + + sword OCIThreadTerm(void *hndl, OCIError *err); + + hndl(IN/OUT): The OCI environment or session handle. + + err(IN/OUT): The OCI error handle. If there is an error and OCI_ERROR + is returned, the error is recorded in err and diagnostic + information can be obtained by calling OCIErrorGet(). + + Returns + + OCI_SUCCESS, OCI_ERROR or OCI_INVALID_HANDLE. + + Notes + + It is safe to make concurrent calls to 'OCIThreadTerm()'. + + 'OCIThreadTerm()' will not do anything until it has been called as + many times as 'OCIThreadInit()' has been called. When that happens, + it terminates the OCIThread layer and frees the memory allocated for + the context. Once this happens, the context should not be re-used. + It will be necessary to obtain a new one by calling 'OCIThreadInit()'. + + + OCIThreadIsMulti - OCIThread Is Multi-Threaded? + ------------------------------------------------ + + Description + + This tells the caller whether the application is running in a + multi-threaded environment or a single-threaded environment. + + Prototype + boolean OCIThreadIsMulti(void); + + Returns + + TRUE if the environment is multi-threaded; + FALSE if the environment is single-threaded. + + +1.2 Passive Threading Primitives +================================== + +1.2.1 Types + +The passive threading primitives deal with the manipulation of mutex, +thread ID's, and thread-specific data. Since the specifications of these +primitives do not require the existence of multiple threads, they can be +used both on multithreaded and single-threaded platforms. + +1.2.1.1 OCIThreadMutex - OCIThread Mutual Exclusion Lock +----------------------------------------------------------- + + The type 'OCIThreadMutex' is used to represent a mutual exclusion lock + (mutex). A mutex is typically used for one of two purposes: (i) to + ensure that only one thread accesses a given set of data at a time, or + (ii) to ensure that only one thread executes a given critical section of + code at a time. + + Mutexes pointer can be declared as parts of client structures or as + stand-alone variables. Before they can be used, they must be initialized + using 'OCIThreadMutexInit()'. Once they are no longer needed, they must be + destroyed using 'OCIThreadMutexDestroy()'. A mutex pointer must NOT be + used after it is destroyed. + + A thread can acquire a mutex by using either 'OCIThreadMutexAcquire()' or + 'OCIThreadMutexTry()'. They both ensure that only one thread at a time is + allowed to hold a given mutex. A thread that holds a mutex can release it + by calling 'OCIThreadMutexRelease()'. + + +1.2.1.2 OCIThreadKey - OCIThread Key for Thread-Specific Data +---------------------------------------------------------------- + + A key can be thought of as a process-wide variable that has a + thread-specific value. What this means is that all the threads in a + process can use any given key. However, each thread can examine or modify + that key independently of the other threads. The value that a thread sees + when it examines the key will always be the same as the value that it last + set for the key. It will not see any values set for the key by the other + threads. + + The type of the value held by a key is a 'void *' generic pointer. + + Keys can be created using 'OCIThreadKeyInit()'. When a key is created, its + value is initialized to 'NULL' for all threads. + + A thread can set a key's value using 'OCIThreadKeySet()'. A thread can + get a key's value using 'OCIThreadKeyGet()'. + + The OCIThread key functions will save and retrieve data SPECIFIC TO THE + THREAD. When clients maintain a pool of threads and assign the threads to + different tasks, it *may not* be appropriate for a task to use OCIThread + key functions to save data associated with it. Here is a scenario of how + things can fail: A thread is assigned to execute the initialization of a + task. During the initialization, the task stored some data related to it + in the thread using OCIThread key functions. After the initialization, + the thread is returned back to the threads pool. Later, the threads pool + manager assigned another thread to perform some operations on the task, + and the task needs to retrieve those data it stored earlier in + initialization. Since the task is running in another thread, it will not + be able to retrieve the same data back! Applications that use thread + pools should be aware of this and be cautious when using OCIThread key + functions. + + +1.2.1.3 OCIThreadKeyDestFunc - OCIThread Key Destructor Function Type +------------------------------------------------------------------------ + + This is the type of a pointer to a key's destructor routine. Keys can be + associated with a destructor routine when they are created (see + 'OCIThreadKeyInit()'). + + A key's destructor routine will be called whenever a thread that has a + non-NULL value for the key terminates. + + The destructor routine returns nothing and takes one parameter. The + parameter will be the value that was set for key when the thread + terminated. + + The destructor routine is guaranteed to be called on a thread's value + in the key after the termination of the thread and before process + termination. No more precise guarantee can be made about the timing + of the destructor routine call; thus no code in the process may assume + any post-condition of the destructor routine. In particular, the + destructor is not guaranteed to execute before a join call on the + terminated thread returns. + + +1.2.1.4 OCIThreadId - OCIThread Thread ID +-------------------------------------------- + + Type 'OCIThreadId' is the type that will be used to identify a thread. + At any given time, no two threads will ever have the same 'OCIThreadId'. + However, 'OCIThreadId' values can be recycled; i.e., once a thread dies, + a new thread may be created that has the same 'OCIThreadId' as the one + that died. In particular, the thread ID must uniquely identify a thread + T within a process, and it must be consistent and valid in all threads U + of the process for which it can be guaranteed that T is running + concurrently with U. The thread ID for a thread T must be retrievable + within thread T. This will be done via OCIThreadIdGet(). + + The 'OCIThreadId' type supports the concept of a NULL thread ID: the NULL + thread ID will never be the same as the ID of an actual thread. + + + +1.2.2 Function prototypes for passive primitives +-------------------------------------------------- + +1.2.2.1 Mutex functions +------------------------- + + OCIThreadMutexInit - OCIThread MuteX Initialize + ----------------------------------------------- + + Description + + This allocate and initializes a mutex. All mutexes must be + initialized prior to use. + + Prototype + + sword OCIThreadMutexInit(void *hndl, OCIError *err, + OCIThreadMutex **mutex); + + hndl(IN/OUT): The OCI environment or session handle. + + err(IN/OUT): The OCI error handle. If there is an error and OCI_ERROR + is returned, the error is recorded in err and diagnostic + information can be obtained by calling OCIErrorGet(). + + mutex(OUT): The mutex to initialize. + + Returns + + OCI_SUCCESS, OCI_ERROR or OCI_INVALID_HANDLE. + + Notes + + Multiple threads must not initialize the same mutex simultaneously. + Also, a mutex must not be reinitialized until it has been destroyed (see + 'OCIThreadMutexDestroy()'). + + OCIThreadMutexDestroy - OCIThread MuteX Destroy + ----------------------------------------------- + + Description + + This destroys and deallocate a mutex. Each mutex must be destroyed + once it is no longer needed. + + Prototype + + sword OCIThreadMutexDestroy(void *hndl, OCIError *err, + OCIThreadMutex **mutex); + + hndl(IN/OUT): The OCI environment or session handle. + + err(IN/OUT): The OCI error handle. If there is an error and OCI_ERROR + is returned, the error is recorded in err and diagnostic + information can be obtained by calling OCIErrorGet(). + + mutex(IN/OUT): The mutex to destroy. + + Returns + + OCI_SUCCESS, OCI_ERROR or OCI_INVALID_HANDLE. + + Notes + + It is not legal to destroy a mutex that is uninitialized or is currently + held by a thread. The destruction of a mutex must not occur concurrently + with any other operations on the mutex. A mutex must not be used after + it has been destroyed. + + + OCIThreadMutexAcquire - OCIThread MuteX Acquire + ----------------------------------------------- + + Description + + This acquires a mutex for the thread in which it is called. If the mutex + is held by another thread, the calling thread is blocked until it can + acquire the mutex. + + Prototype + + sword OCIThreadMutexAcquire(void *hndl, OCIError *err, + OCIThreadMutex *mutex); + + hndl(IN/OUT): The OCI environment or session handle. + + err(IN/OUT): The OCI error handle. If there is an error, it is + recorded in err and this function returns OCI_ERROR. + Diagnostic information can be obtained by calling + OCIErrorGet(). + + mutex(IN/OUT): The mutex to acquire. + + Returns + + OCI_SUCCESS, OCI_ERROR or OCI_INVALID_HANDLE. + + Notes + + It is illegal to attempt to acquire an uninitialized mutex. + + This function's behavior is undefined if it is used by a thread to + acquire a mutex that is already held by that thread. + + + + OCIThreadMutexRelease - OCIThread MuteX Release + ----------------------------------------------- + + Description + + This releases a mutex. If there are any threads blocked on the mutex, + one of them will acquire it and become unblocked. + + Prototype + + sword OCIThreadMutexRelease(void *hndl, OCIError *err, + OCIThreadMutex *mutex); + + hndl(IN/OUT): The OCI environment or session handle. + + err(IN/OUT): The OCI error handle. If there is an error and OCI_ERROR + is returned, the error is recorded in err and diagnostic + information can be obtained by calling OCIErrorGet(). + + mutex(IN/OUT): The mutex to release. + + Returns + + OCI_SUCCESS, OCI_ERROR or OCI_INVALID_HANDLE. + + Notes + + It is illegal to attempt to release an uninitialized mutex. It is also + illegal for a thread to release a mutex that it does not hold. + + + OCIThreadKeyInit - OCIThread KeY Initialize + ------------------------------------------- + + Description + + This creates a key. Each call to this routine allocate and generates + a new key that is distinct from all other keys. + + Prototype + + sword OCIThreadKeyInit(void *hndl, OCIError *err, OCIThreadKey **key, + OCIThreadKeyDestFunc destFn); + + hndl(IN/OUT): The OCI environment or session handle. + + err(IN/OUT): The OCI error handle. If there is an error and OCI_ERROR + is returned, the error is recorded in err and diagnostic + information can be obtained by calling OCIErrorGet(). + + key(OUT): The 'OCIThreadKey' in which to create the new key. + + destFn(IN): The destructor for the key. NULL is permitted. + + Returns + + OCI_SUCCESS, OCI_ERROR or OCI_INVALID_HANDLE. + + Notes + + Once this function executes successfully, a pointer to an allocated and + initialized key is return. That key can be used with 'OCIThreadKeyGet()' + and 'OCIThreadKeySet()'. The initial value of the key will be 'NULL' for + all threads. + + It is illegal for this function to be called more than once to create the + same key (i.e., to be called more than once with the same value for the + 'key' parameter). + + If the 'destFn' parameter is not NULL, the routine pointed to by 'destFn' + will be called whenever a thread that has a non-NULL value for the key + terminates. The routine will be called with one parameter. The + parameter will be the key's value for the thread at the time at which the + thread terminated. + If the key does not need a destructor function, pass NULL for 'destFn'. + + + OCIThreadKeyDestroy - OCIThread KeY DESTROY + ------------------------------------------- + + Description + + Destroy and deallocate the key pointed to by 'key'. + + Prototype + + sword OCIThreadKeyDestroy(void *hndl, OCIError *err, + OCIThreadKey **key); + + hndl(IN/OUT): The OCI environment or session handle. + + err(IN/OUT): The OCI error handle. If there is an error and OCI_ERROR + is returned, the error is recorded in err and diagnostic + information can be obtained by calling OCIErrorGet(). + + key(IN/OUT): The 'OCIThreadKey' in which to destroy the key. + + Returns + + OCI_SUCCESS, OCI_ERROR or OCI_INVALID_HANDLE. + + Notes + + This is different from the destructor function callback passed to the + key create routine. This new destroy function 'OCIThreadKeyDestroy' is + used to terminate any resources OCI THREAD acquired when it created + 'key'. [The 'OCIThreadKeyDestFunc' callback type is a key VALUE + destructor; it does in no way operate on the key itself.] + + This must be called once the user has finished using the key. Not + calling the key destroy function may result in memory leaks. + + + + +1.2.2.2 Thread Key operations +------------------------------- + + OCIThreadKeyGet - OCIThread KeY Get value + ----------------------------------------- + + Description + + This gets the calling thread's current value for a key. + + Prototype + + sword OCIThreadKeyGet(void *hndl, OCIError *err, OCIThreadKey *key, + void **pValue); + + hndl(IN/OUT): The OCI environment or session handle. + + err(IN/OUT): The OCI error handle. If there is an error and OCI_ERROR + is returned, the error is recorded in err and diagnostic + information can be obtained by calling OCIErrorGet(). + + key(IN): The key. + + pValue(IN/OUT): The location in which to place the thread-specific + key value. + + Returns + + OCI_SUCCESS, OCI_ERROR or OCI_INVALID_HANDLE. + + Notes + + It is illegal to use this function on a key that has not been created + using 'OCIThreadKeyInit()'. + + If the calling thread has not yet assigned a value to the key, 'NULL' is + placed in the location pointed to by 'pValue'. + + + OCIThreadKeySet - OCIThread KeY Set value + ----------------------------------------- + + Description + + This sets the calling thread's value for a key. + + Prototype + + sword OCIThreadKeySet(void *hndl, OCIError *err, OCIThreadKey *key, + void *value); + + hndl(IN/OUT): The OCI environment or session handle. + + err(IN/OUT): The OCI error handle. If there is an error and OCI_ERROR + is returned, the error is recorded in err and diagnostic + information can be obtained by calling OCIErrorGet(). + + key(IN/OUT): The key. + + value(IN): The thread-specific value to set in the key. + + Returns + + OCI_SUCCESS, OCI_ERROR or OCI_INVALID_HANDLE. + + Notes + + It is illegal to use this function on a key that has not been created + using 'OCIThreadKeyInit()'. + +1.2.2.3 Thread Id +-------------------- + + OCIThreadIdInit - OCIThread Thread Id INITialize + -------------------------------------------------- + + Description + + Allocate and initialize the thread id 'tid'. + + Prototype + + sword OCIThreadIdInit(void *hndl, OCIError *err, OCIThreadId **tid); + + hndl(IN/OUT): The OCI environment or session handle. + + err(IN/OUT): The OCI error handle. If there is an error and OCI_ERROR + is returned, the error is recorded in err and diagnostic + information can be obtained by calling OCIErrorGet(). + + tid (OUT): Pointer to the thread ID to initialize. + + Returns + + OCI_SUCCESS, OCI_ERROR or OCI_INVALID_HANDLE. + + + OCIThreadIdDestroy - OCIThread Thread Id DESTROY + -------------------------------------------------- + + Description + + Destroy and deallocate the thread id 'tid'. + + Prototype + + sword OCIThreadIdDestroy(void *hndl, OCIError *err, OCIThreadId **tid); + + hndl(IN/OUT): The OCI environment or session handle. + + err(IN/OUT): The OCI error handle. If there is an error and OCI_ERROR + is returned, the error is recorded in err and diagnostic + information can be obtained by calling OCIErrorGet(). + + tid(IN/OUT): Pointer to the thread ID to destroy. + + Returns + + OCI_SUCCESS, OCI_ERROR or OCI_INVALID_HANDLE. + + Note + + 'tid' should be initialized by OCIThreadIdInit(). + + + OCIThreadIdSet - OCIThread Thread Id Set + ----------------------------------------- + + Description + + This sets one 'OCIThreadId' to another. + + Prototype + + sword OCIThreadIdSet(void *hndl, OCIError *err, + OCIThreadId *tidDest, + OCIThreadId *tidSrc); + + hndl(IN/OUT): The OCI environment or session handle. + + err(IN/OUT): The OCI error handle. If there is an error and OCI_ERROR + is returned, the error is recorded in err and diagnostic + information can be obtained by calling OCIErrorGet(). + + tidDest(OUT): This should point to the location of the 'OCIThreadId' + to be set to. + + tidSrc(IN): This should point to the 'OCIThreadId' to set from. + + Returns + + OCI_SUCCESS, OCI_ERROR or OCI_INVALID_HANDLE. + + Notes + + 'tid' should be initialized by OCIThreadIdInit(). + + + OCIThreadIdSetNull - OCIThread Thread Id Set Null + --------------------------------------------------------- + + Description + + This sets the NULL thread ID to a given 'OCIThreadId'. + + Prototype + + sword OCIThreadIdSetNull(void *hndl, OCIError *err, + OCIThreadId *tid); + + hndl(IN/OUT): The OCI environment or session handle. + + err(IN/OUT): The OCI error handle. If there is an error, it is + recorded in err and this function returns OCI_ERROR. + Diagnostic information can be obtained by calling + OCIErrorGet(). + + tid(OUT): This should point to the 'OCIThreadId' in which to put + the NULL thread ID. + + Returns + + OCI_SUCCESS, OCI_ERROR or OCI_INVALID_HANDLE. + + Notes + + 'tid' should be initialized by OCIThreadIdInit(). + + + OCIThreadIdGet - OCIThread Thread Id Get + ------------------------------------------ + + Description + + This retrieves the 'OCIThreadId' of the thread in which it is called. + + Prototype + + sword OCIThreadIdGet(void *hndl, OCIError *err, + OCIThreadId *tid); + + hndl(IN/OUT): The OCI environment or session handle. + + err(IN/OUT): The OCI error handle. If there is an error and OCI_ERROR + is returned, the error is recorded in err and diagnostic + information can be obtained by calling OCIErrorGet(). + + tid(OUT): This should point to the location in which to place the + ID of the calling thread. + + Returns + + OCI_SUCCESS, OCI_ERROR or OCI_INVALID_HANDLE. + + Notes + + 'tid' should be initialized by OCIThreadIdInit(). + + When OCIThread is used in a single-threaded environment, + OCIThreadIdGet() will always place the same value in the location + pointed to by 'tid'. The exact value itself is not important. The + important thing is that it is not the same as the NULL thread ID and + that it is always the same value. + + + OCIThreadIdSame - OCIThread Thread Ids Same? + ---------------------------------------------- + + Description + + This determines whether or not two 'OCIThreadId's represent the same + thread. + + Prototype + + sword OCIThreadIdSame(void *hndl, OCIError *err, + OCIThreadId *tid1, OCIThreadId *tid2, + boolean *result); + + hndl(IN/OUT): The OCI environment or session handle. + + err(IN/OUT): The OCI error handle. If there is an error and OCI_ERROR + is returned, the error is recorded in err and diagnostic + information can be obtained by calling OCIErrorGet(). + + tid1(IN): Pointer to the first 'OCIThreadId'. + + tid2(IN): Pointer to the second 'OCIThreadId'. + + result(IN/OUT): Pointer to the result. + + Returns + + OCI_SUCCESS, OCI_ERROR or OCI_INVALID_HANDLE. + + Notes + + If 'tid1' and 'tid2' represent the same thread, 'result' is set to TRUE. + Otherwise, 'result' is set to FALSE. + + 'result' is set to TRUE if both 'tid1' and 'tid2' are the NULL thread ID. + + 'ti1d' and 'tid2' should be initialized by OCIThreadIdInit(). + + + OCIThreadIdNull - OCIThread Thread Id NULL? + --------------------------------------------- + + Description + + This determines whether or not a given 'OCIThreadId' is the NULL thread + ID. + + Prototype + + sword OCIThreadIdNull(void *hndl, OCIError *err, + OCIThreadId *tid, + boolean *result); + + hndl(IN/OUT): The OCI environment or session handle. + + err(IN/OUT): The OCI error handle. If there is an error and OCI_ERROR + is returned, the error is recorded in err and diagnostic + information can be obtained by calling OCIErrorGet(). + + tid(IN): Pointer to the 'OCIThreadId' to check. + + result(IN/OUT): Pointer to the result. + + Returns + + OCI_SUCCESS, OCI_ERROR or OCI_INVALID_HANDLE. + + Notes + + If 'tid' is the NULL thread ID, 'result' is set to TRUE. Otherwise, + 'result' is set to FALSE. + + 'tid' should be initialized by OCIThreadIdInit(). + + +1.3 Active Threading Primitives +================================= + +The active threading primitives deal with the manipulation of actual +threads. Because the specifications of most of these primitives require +that it be possible to have multiple threads, they work correctly only in +the enabled OCIThread; In the disabled OCIThread, they always return +failure. The exception is OCIThreadHandleGet(); it may be called in a +single-threaded environment, in which case it will have no effect. + +Active primitives should only be called by code running in a multi-threaded +environment. You can call OCIThreadIsMulti() to determine whether the +environment is multi-threaded or single-threaded. + + +1.3.1 Types +-------------- + +1.3.1.1 OCIThreadHandle - OCIThread Thread Handle +------------------------------------------------------ + + Type 'OCIThreadHandle' is used to manipulate a thread in the active + primitives: OCIThreadJoin()and OCIThreadClose(). A thread handle opened by + OCIThreadCreate() must be closed in a matching call to + OCIThreadClose(). A thread handle is invalid after the call to + OCIThreadClose(). + + The distinction between a thread ID and a thread handle in OCIThread usage + follows the distinction between the thread ID and the thread handle on + Windows NT. On many platforms, the underlying native types are the same. + + +1.3.2 Functions +------------------ + + OCIThreadHndInit - OCIThread HaNDle Initialize + ---------------------------------------------- + + Description + + Allocate and initialize the thread handle. + + Prototype + + sword OCIThreadHndInit(void *hndl, OCIError *err, + OCIThreadHandle **thnd); + + hndl(IN/OUT): The OCI environment or session handle. + + err(IN/OUT): The OCI error handle. If there is an error and OCI_ERROR + is returned, the error is recorded in err and diagnostic + information can be obtained by calling OCIErrorGet(). + + thnd(OUT): The address of pointer to the thread handle to initialize. + + Returns + + OCI_SUCCESS, OCI_ERROR or OCI_INVALID_HANDLE. + + + OCIThreadHndDestroy - OCIThread HaNDle Destroy + ---------------------------------------------- + + Description + + Destroy and deallocate the thread handle. + + Prototype + + sword OCIThreadHndDestroy(void *hndl, OCIError *err, + OCIThreadHandle **thnd); + + hndl(IN/OUT): The OCI environment or session handle. + + err(IN/OUT): The OCI error handle. If there is an error and OCI_ERROR + is returned, the error is recorded in err and diagnostic + information can be obtained by calling OCIErrorGet(). + + thnd(IN/OUT): The address of pointer to the thread handle to destroy. + + Returns + + OCI_SUCCESS, OCI_ERROR or OCI_INVALID_HANDLE. + + Notes + + 'thnd' should be initialized by OCIThreadHndInit(). + + + OCIThreadCreate - OCIThread Thread Create + ----------------------------------------- + + Description + + This creates a new thread. + + Prototype + + sword OCIThreadCreate(void *hndl, OCIError *err, + void (*start)(void *), void *arg, + OCIThreadId *tid, OCIThreadHandle *tHnd); + + hndl(IN/OUT): The OCI environment or session handle. + + err(IN/OUT): The OCI error handle. If there is an error and OCI_ERROR + is returned, the error is recorded in err and diagnostic + information can be obtained by calling OCIErrorGet(). + + start(IN): The function in which the new thread should begin + execution. + + arg(IN): The argument to give the function pointed to by 'start'. + + tid(IN/OUT): If not NULL, gets the ID for the new thread. + + tHnd(IN/OUT): If not NULL, gets the handle for the new thread. + + Returns + + OCI_SUCCESS, OCI_ERROR or OCI_INVALID_HANDLE. + + Notes + + The new thread will start by executing a call to the function pointed + to by 'start' with the argument given by 'arg'. When that function + returns, the new thread will terminate. The function should not + return a value and should accept one parameter, a 'void *'. + + The call to OCIThreadCreate() must be matched by a call to + OCIThreadClose() if and only if tHnd is non-NULL. + + If tHnd is NULL, a thread ID placed in *tid will not be valid in the + calling thread because the timing of the spawned thread's termination + is unknown. + + 'tid' should be initialized by OCIThreadIdInit(). + + 'thnd' should be initialized by OCIThreadHndInit(). + + + + OCIThreadJoin - OCIThread Thread Join + ------------------------------------- + + Description + + This function allows the calling thread to 'join' with another thread. + It blocks the caller until the specified thread terminates. + + Prototype + + sword OCIThreadJoin(void *hndl, OCIError *err, OCIThreadHandle *tHnd); + + hndl(IN/OUT): The OCI environment or session handle. + + err(IN/OUT): The OCI error handle. If there is an error and OCI_ERROR + is returned, the error is recorded in err and diagnostic + information can be obtained by calling OCIErrorGet(). + + tHnd(IN): The 'OCIThreadHandle' of the thread to join with. + + Returns + + OCI_SUCCESS, OCI_ERROR or OCI_INVALID_HANDLE. + + Notes + + 'thnd' should be initialized by OCIThreadHndInit(). + + The result of multiple threads all trying to join with the same thread is + undefined. + + + OCIThreadClose - OCIThread Thread Close + --------------------------------------- + + Description + + This function should be called to close a thread handle. + + Prototype + + sword OCIThreadClose(void *hndl, OCIError *err, OCIThreadHandle *tHnd); + + hndl(IN/OUT): The OCI environment or session handle. + + err(IN/OUT): The OCI error handle. If there is an error and OCI_ERROR + is returned, the error is recorded in err and diagnostic + information can be obtained by calling OCIErrorGet(). + + tHnd(IN/OUT): The OCIThread thread handle to close. + + Returns + + OCI_SUCCESS, OCI_ERROR or OCI_INVALID_HANDLE. + + Notes + + 'thnd' should be initialized by OCIThreadHndInit(). + + Both thread handle and the thread ID that was returned by the same call + to OCIThreadCreate() are invalid after the call to OCIThreadClose(). + + + + OCIThreadHandleGet - OCIThread Thread Get Handle + ------------------------------------------------ + + Description + + Retrieve the 'OCIThreadHandle' of the thread in which it is called. + + Prototype + + sword OCIThreadHandleGet(void *hndl, OCIError *err, + OCIThreadHandle *tHnd); + + hndl(IN/OUT): The OCI environment or session handle. + + err(IN/OUT): The OCI error handle. If there is an error and OCI_ERROR + is returned, the error is recorded in err and diagnostic + information can be obtained by calling OCIErrorGet(). + + tHnd(IN/OUT): If not NULL, the location to place the thread + handle for the thread. + + Returns + + OCI_SUCCESS, OCI_ERROR or OCI_INVALID_HANDLE. + + Notes + + 'thnd' should be initialized by OCIThreadHndInit(). + + The thread handle 'tHnd' retrieved by this function must be closed + with OCIThreadClose() and destroyed by OCIThreadHndDestroy() after it + is used. + + + + +1.4 Using OCIThread +===================== + +This section summarizes some of the more important details relating to the use +of OCIThread. + + * Process initialization + + OCIThread only requires that the process initialization function + ('OCIThreadProcessInit()') be called when OCIThread is being used in a + multi-threaded application. Failing to call 'OCIThreadProcessInit()' in + a single-threaded application is not an error. + + * OCIThread initialization + + Separate calls to 'OCIThreadInit()' will all return the same OCIThread + context. + + Also, remember that each call to 'OCIThreadInit()' must eventually be + matched by a call to 'OCIThreadTerm()'. + + * Active vs. Passive Threading primitives + + OCIThread client code written without using any active primitives can be + compiled and used without change on both single-threaded and + multi-threaded platforms. + + OCIThread client code written using active primitives will only work + correctly on multi-threaded platforms. In order to write a version of the + same application to run on single-threaded platform, it is necessary to + branch the your code, whether by branching versions of the source file or + by branching at runtime with the OCIThreadIsMulti() call. + +******************************************************************************/ + +/***************************************************************************** + ACTUAL PROTOTYPE DECLARATIONS +******************************************************************************/ + +void OCIThreadProcessInit(); + +sword OCIThreadInit(void *hndl, OCIError *err); + +sword OCIThreadTerm(void *hndl, OCIError *err); + +boolean OCIThreadIsMulti(); + +sword OCIThreadMutexInit(void *hndl, OCIError *err, + OCIThreadMutex **mutex); + +sword OCIThreadMutexDestroy(void *hndl, OCIError *err, + OCIThreadMutex **mutex); + +sword OCIThreadMutexAcquire(void *hndl, OCIError *err, + OCIThreadMutex *mutex); + +sword OCIThreadMutexRelease(void *hndl, OCIError *err, + OCIThreadMutex *mutex); + +sword OCIThreadKeyInit(void *hndl, OCIError *err, OCIThreadKey **key, + OCIThreadKeyDestFunc destFn); + +sword OCIThreadKeyDestroy(void *hndl, OCIError *err, + OCIThreadKey **key); + +sword OCIThreadKeyGet(void *hndl, OCIError *err, OCIThreadKey *key, + void **pValue); + +sword OCIThreadKeySet(void *hndl, OCIError *err, OCIThreadKey *key, + void *value); + +sword OCIThreadIdInit(void *hndl, OCIError *err, OCIThreadId **tid); + +sword OCIThreadIdDestroy(void *hndl, OCIError *err, OCIThreadId **tid); + +sword OCIThreadIdSet(void *hndl, OCIError *err, + OCIThreadId *tidDest, OCIThreadId *tidSrc); + +sword OCIThreadIdSetNull(void *hndl, OCIError *err, OCIThreadId *tid); + +sword OCIThreadIdGet(void *hndl, OCIError *err, OCIThreadId *tid); + +sword OCIThreadIdSame(void *hndl, OCIError *err, + OCIThreadId *tid1, OCIThreadId *tid2, + boolean *result); + +sword OCIThreadIdNull(void *hndl, OCIError *err, + OCIThreadId *tid, boolean *result); + +sword OCIThreadHndInit(void *hndl, OCIError *err, OCIThreadHandle **thnd); + +sword OCIThreadHndDestroy(void *hndl, OCIError *err, OCIThreadHandle **thnd); + +sword OCIThreadCreate(void *hndl, OCIError *err, + void (*start)(void *), void *arg, + OCIThreadId *tid, OCIThreadHandle *tHnd); + +sword OCIThreadJoin(void *hndl, OCIError *err, OCIThreadHandle *tHnd); + +sword OCIThreadClose(void *hndl, OCIError *err, OCIThreadHandle *tHnd); + +sword OCIThreadHandleGet(void *hndl, OCIError *err, OCIThreadHandle *tHnd); +/*----------------- End OCI Thread interface Extensions ---------------------*/ + +/*------------------ Begin OCI Row Callback Interfaces ----------------------*/ + +typedef sword (*OCIBindRowCallback)(void *ctx); +typedef sword (*OCIFetchRowCallback)(void *ctx); + +/*------------------ Begin OCI Row Callback Interfaces ----------------------*/ + +/*--------------- Begin OCI Client Notification Interfaces ------------------*/ + +typedef ub4 (*OCISubscriptionNotify)(void *ctx, OCISubscription *subscrhp, + void *pay, ub4 payl, + void *desc, ub4 mode); + +sword OCISubscriptionRegister(OCISvcCtx *svchp, OCISubscription **subscrhpp, + ub2 count, OCIError *errhp, ub4 mode); + + +sword OCISubscriptionPost(OCISvcCtx *svchp, OCISubscription **subscrhpp, + ub2 count, OCIError *errhp, ub4 mode); + +sword OCISubscriptionUnRegister(OCISvcCtx *svchp, OCISubscription *subscrhp, + OCIError *errhp, ub4 mode); + +sword OCISubscriptionDisable(OCISubscription *subscrhp, + OCIError *errhp, ub4 mode); + +sword OCISubscriptionEnable(OCISubscription *subscrhp, + OCIError *errhp, ub4 mode); + +/*------------------- End OCI Publish/Subscribe Interfaces ------------------*/ + +/*----------------- Extensions to Datetime interfaces -----------------------*/ +/*--------------------- Actual Prototypes -----------------------------------*/ +sword OCIDateTimeGetTime(void *hndl, OCIError *err, OCIDateTime *datetime, + ub1 *hr, ub1 *mm, ub1 *ss, ub4 *fsec); + +sword OCIDateTimeGetDate(void *hndl, OCIError *err, const OCIDateTime *date, + sb2 *yr, ub1 *mnth, ub1 *dy ); + +sword OCIDateTimeGetTimeZoneOffset(void *hndl,OCIError *err, + const OCIDateTime *datetime, + sb1 *hr,sb1 *mm); + +sword OCIDateTimeConstruct(void *hndl,OCIError *err,OCIDateTime *datetime, + sb2 yr,ub1 mnth,ub1 dy,ub1 hr,ub1 mm,ub1 ss,ub4 fsec, + OraText *timezone,size_t timezone_length); + +sword OCIDateTimeSysTimeStamp(void *hndl, OCIError *err, + OCIDateTime *sys_date ); + +sword OCIDateTimeAssign(void *hndl, OCIError *err, const OCIDateTime *from, + OCIDateTime *to); + +sword OCIDateTimeToText(void *hndl, OCIError *err, const OCIDateTime *date, + const OraText *fmt, ub1 fmt_length, ub1 fsprec, + const OraText *lang_name, size_t lang_length, + ub4 *buf_size, OraText *buf ); + +sword OCIDateTimeFromText(void *hndl, OCIError *err, const OraText *date_str, + size_t dstr_length, const OraText *fmt, ub1 fmt_length, + const OraText *lang_name, size_t lang_length, OCIDateTime *date ); + +sword OCIDateTimeCompare(void *hndl, OCIError *err, const OCIDateTime *date1, + const OCIDateTime *date2, sword *result ); + +sword OCIDateTimeCheck(void *hndl, OCIError *err, const OCIDateTime *date, + ub4 *valid ); + +sword OCIDateTimeConvert(void *hndl, OCIError *err, OCIDateTime *indate, + OCIDateTime *outdate); + +sword OCIDateTimeSubtract(void *hndl, OCIError *err, OCIDateTime *indate1, + OCIDateTime *indate2, OCIInterval *inter); + +sword OCIDateTimeIntervalAdd(void *hndl, OCIError *err, OCIDateTime *datetime, + OCIInterval *inter, OCIDateTime *outdatetime); + +sword OCIDateTimeIntervalSub(void *hndl, OCIError *err, OCIDateTime *datetime, + OCIInterval *inter, OCIDateTime *outdatetime); + +sword OCIIntervalSubtract(void *hndl, OCIError *err, OCIInterval *minuend, + OCIInterval *subtrahend, OCIInterval *result ); + +sword OCIIntervalAdd(void *hndl, OCIError *err, OCIInterval *addend1, + OCIInterval *addend2, OCIInterval *result ); + +sword OCIIntervalMultiply(void *hndl, OCIError *err, const OCIInterval *inter, + OCINumber *nfactor, OCIInterval *result ); + +sword OCIIntervalDivide(void *hndl, OCIError *err, OCIInterval *dividend, + OCINumber *divisor, OCIInterval *result ); + +sword OCIIntervalCompare(void *hndl, OCIError *err, OCIInterval *inter1, + OCIInterval *inter2, sword *result ); + +sword OCIIntervalFromNumber(void *hndl, OCIError *err, OCIInterval *inter, + OCINumber *number); + +sword OCIIntervalFromText( void *hndl, OCIError *err, const OraText *inpstr, + size_t str_len, OCIInterval *result ); + +sword OCIIntervalToText( void *hndl, OCIError *err, const OCIInterval *inter, + ub1 lfprec, ub1 fsprec, + OraText *buffer, size_t buflen, size_t *resultlen ); + +sword OCIIntervalToNumber(void *hndl, OCIError *err,const OCIInterval *inter, + OCINumber *number); + +sword OCIIntervalCheck(void *hndl, OCIError *err, const OCIInterval *interval, + ub4 *valid ); + +sword OCIIntervalAssign(void *hndl, OCIError *err, const OCIInterval *ininter, + OCIInterval *outinter ); + +sword OCIIntervalSetYearMonth(void *hndl, OCIError *err, sb4 yr, sb4 mnth, + OCIInterval *result ); + +sword OCIIntervalGetYearMonth(void *hndl, OCIError *err, sb4 *yr, sb4 *mnth, + const OCIInterval *result ); + +sword OCIIntervalSetDaySecond(void *hndl, OCIError *err, sb4 dy, sb4 hr, + sb4 mm, sb4 ss, sb4 fsec, OCIInterval *result ); + +sword OCIIntervalGetDaySecond(void *hndl, OCIError *err, sb4 *dy, sb4 *hr, + sb4 *mm, sb4 *ss, sb4 *fsec, const OCIInterval *result ); + +sword OCIDateTimeToArray(void *hndl, OCIError *err, + const OCIDateTime *datetime, const OCIInterval *reftz, + ub1 *outarray, ub4 *len, ub1 fsprec); + +sword OCIDateTimeFromArray(void *hndl, OCIError *err, ub1 *inarray, ub4 len, + ub1 type, OCIDateTime *datetime, + const OCIInterval *reftz, ub1 fsprec); + +sword OCIDateTimeGetTimeZoneName(void *hndl, OCIError *err, + const OCIDateTime *datetime, + ub1 *buf, ub4 *buflen); + +sword OCIIntervalFromTZ(void *hndl, OCIError *err, const oratext *inpstring, + size_t str_len, OCIInterval *result); + +/*----------------- End Datetime interface Extensions -----------------------*/ + +/*----------------- Connection Pooling prototypes ---------------------------*/ +sword OCIConnectionPoolCreate(OCIEnv *envhp, OCIError *errhp, OCICPool *poolhp, + OraText **poolName, sb4 *poolNameLen, + const OraText *dblink, sb4 dblinkLen, + ub4 connMin, ub4 connMax, ub4 connIncr, + const OraText *poolUserName, sb4 poolUserLen, + const OraText *poolPassword, sb4 poolPassLen, + ub4 mode); + +sword OCIConnectionPoolDestroy(OCICPool *poolhp, + OCIError *errhp, ub4 mode); + +/*----------------- End Connection Pooling prototypes -----------------------*/ + +/*-------------------- Session Pooling prototypes ---------------------------*/ + +sword OCISessionPoolCreate (OCIEnv *envhp, OCIError *errhp, OCISPool *spoolhp, + OraText **poolName, ub4 *poolNameLen, + const OraText *connStr, ub4 connStrLen, + ub4 sessMin, ub4 sessMax, ub4 sessIncr, + OraText *userid, ub4 useridLen, + OraText *password, ub4 passwordLen, + ub4 mode); + +sword OCISessionPoolDestroy (OCISPool *spoolhp, + OCIError *errhp, + ub4 mode); + +sword OCISessionGet (OCIEnv *envhp, OCIError *errhp, OCISvcCtx **svchp, + OCIAuthInfo *authhp, + OraText *poolName, ub4 poolName_len, + const OraText *tagInfo, ub4 tagInfo_len, + OraText **retTagInfo, ub4 *retTagInfo_len, + boolean *found, ub4 mode); + +sword OCISessionRelease (OCISvcCtx *svchp, OCIError *errhp, + OraText *tag, ub4 tag_len, + ub4 mode); + +/*-------------------- End Session Pooling prototypes -----------------------*/ + +/* --------------------- OCI Application Context --------------------------*/ + + +sword OCIAppCtxSet(void * sesshndl, void *nsptr, ub4 nsptrlen, + void *attrptr, ub4 attrptrlen, + void *valueptr, ub4 valueptrlen, + OCIError *errhp, ub4 mode); + +sword OCIAppCtxClearAll(void *sesshndl, void *nsptr, ub4 nsptrlen, + OCIError *errhp, ub4 mode); + +/*-------------------------------- OCIMemStats ------------------------------*/ +sword OCIMemStats(void *hndlp, OCIError *errhp, OCIEnv **envhp, + ub4 mode, ub4 mode1, oratext *tabname); + +/*-------------------------------- OCIPing ----------------------------------*/ +sword OCIPing (OCISvcCtx *svchp, OCIError *errhp, ub4 mode); + +/*----------------- Kerberos Authentication prototypes ----------------------*/ + +sword OCIKerbAttrSet(OCISession *trgthndlp, ub4 cred_use, ub1 *ftgt_ticket, + ub4 ticket_len, ub1 *session_key, ub4 skey_len, + ub2 ftgt_keytype, ub4 ftgt_ticket_flags, + sb4 ftgt_auth_time, sb4 ftgt_start_time, + sb4 ftgt_end_time, sb4 ftgt_renew_time, + oratext *ftgt_client_principal, + ub4 ftgt_client_principal_len, oratext *ftgt_client_realm, + ub4 ftgt_client_realm_len, OCIError *errhp); + +/*------------------- End Kerberos Authentication prototypes ----------------*/ + +/*------------------- Database Startup/Shutdown prototypes ------------------*/ + +sword OCIDBStartup (OCISvcCtx *svchp, + OCIError *errhp, + OCIAdmin *admhp, + ub4 mode, + ub4 flags); + +sword OCIDBShutdown(OCISvcCtx *svchp, + OCIError *errhp, + OCIAdmin *admhp, + ub4 mode); + +/*------------------ End Database Startup/Shutdown prototypes ---------------*/ + +/*----------------------- OCIClientVersion ------------------------------*/ +void OCIClientVersion(sword *major_version, + sword *minor_version, + sword *update_num, + sword *patch_num, + sword *port_update_num); +/*----------------------- End OCIClientVersion --------------------------*/ + +/*----------------------- HA Event prototypes ------------------------------*/ + +sword OCIInitEventHandle(OCIError *errhp, + OCIEvent *event, + text *str, + ub4 size); + +/*----------------------- End HA Event prototypes --------------------------*/ + +/*--------------------------------------------------------------------------- + PRIVATE FUNCTIONS + ---------------------------------------------------------------------------*/ + + /* the following functions are depracated and should not be used */ +#ifdef NEVER +sword OCIStmtBindByPos (OCIStmt *stmtp, OCIBind *bindp, OCIError *errhp, + ub4 position, void *valuep, sb4 value_sz, + ub2 dty, void *indp, ub2 *alenp, ub2 *rcodep, + ub4 maxarr_len, ub4 *curelep, ub4 mode); + + +sword OCIStmtBindByName (OCIStmt *stmtp, OCIBind *bindp, OCIError *errhp, + const OraText *placeholder, sb4 placeh_len, void *valuep, + sb4 value_sz, ub2 dty, void *indp, ub2 *alenp, + ub2 *rcodep, ub4 maxarr_len, ub4 *curelep, ub4 mode); + +sword ocidefn (OCIStmt *stmtp, OCIDefine *defnp, OCIError *errhp, + ub4 position, void *valuep, sb4 value_sz, ub2 dty, + void *indp, ub2 *rlenp, ub2 *rcodep, ub4 mode); +#endif /* NEVER */ + +#endif /* OCIAP_ORACLE */ diff --git a/libodbc/include/ora_linux/ociapr.h b/libodbc/include/ora_linux/ociapr.h new file mode 100644 index 0000000000..0a0443d13e --- /dev/null +++ b/libodbc/include/ora_linux/ociapr.h @@ -0,0 +1,155 @@ +/* Copyright (c) 1991, 2005, Oracle. All rights reserved. */ +/* + NAME + ociapr.h + MODIFIED (MM/DD/YY) + mbastawa 09/16/05 - dbhygiene + dmukhin 06/29/05 - ANSI prototypes; miscellaneous cleanup + dsaha 05/19/00 - Fix lint + sgollapu 05/19/98 - Change text to OraText + dchatter 11/10/95 - add ognfd() - get native fd + lchidamb 04/06/95 - drop maxdsz from obindps/odefinps + slari 04/07/95 - add opinit + dchatter 03/08/95 - osetpi and ogetpi + lchidamb 12/09/94 - add obindps() and odefinps() + dchatter 03/06/95 - merge changes from branch 1.1.720.2 + dchatter 11/14/94 - merge changes from branch 1.1.720.1 + dchatter 02/08/95 - olog call; drop onblon + dchatter 10/31/94 - new functions for non-blocking oci + rkooi2 11/27/92 - Changing datatypes to agree with ocidef.h + rkooi2 10/26/92 - More portability mods + rkooi2 10/18/92 - Changed to agree with oci.c + sjain 03/16/92 - Creation +*/ +/* + * Declare the OCI functions. + * Prototype information is included. + * Use this header for ANSI C compilers. + */ + +#ifndef OCIAPR +#define OCIAPR + +#ifndef ORATYPES +#include +#endif + +#ifndef OCIDFN +#include +#endif + +/* + * Oci BIND (Piecewise or with Skips) + */ +sword obindps(struct cda_def *cursor, ub1 opcode, OraText *sqlvar, + sb4 sqlvl, ub1 *pvctx, sb4 progvl, + sword ftype, sword scale, + sb2 *indp, ub2 *alen, ub2 *arcode, + sb4 pv_skip, sb4 ind_skip, sb4 alen_skip, sb4 rc_skip, + ub4 maxsiz, ub4 *cursiz, + OraText *fmt, sb4 fmtl, sword fmtt); +sword obreak(struct cda_def *lda); +sword ocan (struct cda_def *cursor); +sword oclose(struct cda_def *cursor); +sword ocof (struct cda_def *lda); +sword ocom (struct cda_def *lda); +sword ocon (struct cda_def *lda); + + +/* + * Oci DEFINe (Piecewise or with Skips) + */ +sword odefinps(struct cda_def *cursor, ub1 opcode, sword pos,ub1 *bufctx, + sb4 bufl, sword ftype, sword scale, + sb2 *indp, OraText *fmt, sb4 fmtl, sword fmtt, + ub2 *rlen, ub2 *rcode, + sb4 pv_skip, sb4 ind_skip, sb4 alen_skip, sb4 rc_skip); +sword odessp(struct cda_def *cursor, OraText *objnam, size_t onlen, + ub1 *rsv1, size_t rsv1ln, ub1 *rsv2, size_t rsv2ln, + ub2 *ovrld, ub2 *pos, ub2 *level, OraText **argnam, + ub2 *arnlen, ub2 *dtype, ub1 *defsup, ub1* mode, + ub4 *dtsiz, sb2 *prec, sb2 *scale, ub1 *radix, + ub4 *spare, ub4 *arrsiz); +sword odescr(struct cda_def *cursor, sword pos, sb4 *dbsize, + sb2 *dbtype, sb1 *cbuf, sb4 *cbufl, sb4 *dsize, + sb2 *prec, sb2 *scale, sb2 *nullok); +sword oerhms (struct cda_def *lda, sb2 rcode, OraText *buf, + sword bufsiz); +sword oermsg (sb2 rcode, OraText *buf); +sword oexec (struct cda_def *cursor); +sword oexfet (struct cda_def *cursor, ub4 nrows, + sword cancel, sword exact); +sword oexn (struct cda_def *cursor, sword iters, sword rowoff); +sword ofen (struct cda_def *cursor, sword nrows); +sword ofetch (struct cda_def *cursor); +sword oflng (struct cda_def *cursor, sword pos, ub1 *buf, + sb4 bufl, sword dtype, ub4 *retl, sb4 offset); +sword ogetpi (struct cda_def *cursor, ub1 *piecep, void **ctxpp, + ub4 *iterp, ub4 *indexp); +sword oopt (struct cda_def *cursor, sword rbopt, sword waitopt); +sword opinit (ub4 mode); +sword olog (struct cda_def *lda, ub1* hda, + OraText *uid, sword uidl, + OraText *pswd, sword pswdl, + OraText *conn, sword connl, + ub4 mode); +sword ologof (struct cda_def *lda); +sword oopen (struct cda_def *cursor, struct cda_def *lda, + OraText *dbn, sword dbnl, sword arsize, + OraText *uid, sword uidl); +sword oparse (struct cda_def *cursor, OraText *sqlstm, sb4 sqllen, + sword defflg, ub4 lngflg); +sword orol (struct cda_def *lda); +sword osetpi (struct cda_def *cursor, ub1 piece, void *bufp, ub4 *lenp); + +void sqlld2 (struct cda_def *lda, OraText *cname, sb4 *cnlen); +void sqllda (struct cda_def *lda); + +/* non-blocking functions */ +sword onbset (struct cda_def *lda ); +sword onbtst (struct cda_def *lda ); +sword onbclr (struct cda_def *lda ); +sword ognfd (struct cda_def *lda, void *fdp); + + +/* + * OBSOLETE CALLS + */ + +/* + * OBSOLETE BIND CALLS + */ +sword obndra(struct cda_def *cursor, OraText *sqlvar, sword sqlvl, + ub1 *progv, sword progvl, sword ftype, sword scale, + sb2 *indp, ub2 *alen, ub2 *arcode, ub4 maxsiz, + ub4 *cursiz, OraText *fmt, sword fmtl, sword fmtt); +sword obndrn(struct cda_def *cursor, sword sqlvn, ub1 *progv, + sword progvl, sword ftype, sword scale, sb2 *indp, + OraText *fmt, sword fmtl, sword fmtt); +sword obndrv(struct cda_def *cursor, OraText *sqlvar, sword sqlvl, + ub1 *progv, sword progvl, sword ftype, sword scale, + sb2 *indp, OraText *fmt, sword fmtl, sword fmtt); + +/* + * OBSOLETE DEFINE CALLS + */ +sword odefin(struct cda_def *cursor, sword pos, ub1 *buf, + sword bufl, sword ftype, sword scale, sb2 *indp, + OraText *fmt, sword fmtl, sword fmtt, ub2 *rlen, ub2 *rcode); + +/* older calls ; preferred equivalent calls above */ + +sword oname (struct cda_def *cursor, sword pos, sb1 *tbuf, + sb2 *tbufl, sb1 *buf, sb2 *bufl); +sword orlon (struct cda_def *lda, ub1 *hda, + OraText *uid, sword uidl, + OraText *pswd, sword pswdl, + sword audit); +sword olon (struct cda_def *lda, OraText *uid, sword uidl, + OraText *pswd, sword pswdl, sword audit); +sword osql3 (struct cda_def *cda, OraText *sqlstm, sword sqllen); +sword odsc (struct cda_def *cursor, sword pos, sb2 *dbsize, + sb2 *fsize, sb2 *rcode, sb2 *dtype, sb1 *buf, + sb2 *bufl, sb2 *dsize); + +#endif /* OCIAPR */ diff --git a/libodbc/include/ora_linux/ocidef.h b/libodbc/include/ora_linux/ocidef.h new file mode 100644 index 0000000000..a5002479b1 --- /dev/null +++ b/libodbc/include/ora_linux/ocidef.h @@ -0,0 +1,886 @@ +/* Copyright (c) 1981, 2005, Oracle. All rights reserved. */ +/* Copyright (c) 1984, 2005, Oracle. All rights reserved. */ + +/* +NAME + ocidef +CONTENTS + Oracle Call Interface cursor area and LDA definitions +NOTES + none +OWNER + Oates +DATE + 09/07/82 +MODIFIED + mbastawa 09/16/05 - dbhygiene + dmukhin 06/29/05 - ANSI prototypes; miscellaneous cleanup + srseshad 03/25/03 - convert oci public api to ansi + csteinba 11/05/02 - bug 2521931: redefine OTYACL + aahluwal 06/03/02 - bug 2360115 + bpalaval 02/08/01 - Change text to oratext. + chliang 02/01/01 - fix olint error. + bpalaval 11/16/00 - Bug 1244685 : Fix ALTER CLUSTER issue.. + slari 11/08/00 - remove functions duplicated in ociapr.h + whe 09/01/99 - 976457:check __cplusplus for C++ code + skmishra 04/23/97 - Provide C++ compatibility + lchidamb 06/26/96 - put upidef.h, riddef.h within #ifndef + slari 06/12/96 - add ocigft_getFcnType + dchatter 11/10/95 - ocignfd - oci get native file descriptor + slari 05/11/95 - change OCIEVDEF/OCIEVTSF to UPIEVDEF/UPIEVTSF + dchatter 04/06/95 - add ifdef flags around OCI_flags + lchidamb 04/06/95 - drop maxdsz from ocibndps/ocidfnps + slari 04/07/95 - rename opinit to ocipin + slari 03/13/95 - thread safety changes + dchatter 03/08/95 - piece definitions OCI_*_PIECE + lchidamb 12/06/94 - add support for binding/defining with skips + dchatter 03/06/95 - merge changes from branch 1.12.720.1 + dchatter 02/06/95 - add defines for login mode parameters + dchatter 07/06/94 - Deleting CRSCHK, with refcursor, no way to set this + dchatter 06/13/94 - add a new LDA flag LDANBL + rkooi 11/18/92 - update ocidpr interface + mmoore 10/31/92 - add ocidpr + gpongrac 11/17/92 - fix oexfet prototype + sjain 01/03/92 - Add ocibra + rjenkins 11/04/91 - adding prototypes for oparse and oexfet + sjain 04/15/91 - Change ocistf proto + sjain 04/01/91 - Rearrange oty codes. Add new ones + Jain 12/03/90 - Add #define for new describe call + Jain 11/29/90 - Add new function code for the new oci calls + Mendels 01/20/89 - fix 19170: make ocitbl CONST_DATA + Kabcene 01/27/88 - change interfaces to match V5 + Navab 12/09/87 - add a parameter to ocierr call + Navab 11/30/87 - add ocierr, rename ocioer + Navab 10/08/87 - add prototypes for procedure declarations + Howard 09/07/87 - endif blah + Howard 05/11/87 - Add OTY types + Howard 04/27/87 - move ocldef defines here + Oates 10/15/85 - Add OCANCEL + Oates 09/30/85 - Implement ORA*Net + Oates 06/27/85 - Make datatype compatible with upidef.h + Andy 05/07/85 - delete CSRFBPIC +*/ + +#ifndef UPIDEF +#include +#endif + +#ifndef RIDDEF +#include +#endif + +#include + +#ifndef OCIDEF +#define OCIDEF + + +#define CSRCHECK 172 /* csrdef is a cursor */ +#define LDACHECK 202 /* csrdef is a login data area */ +struct csrdef +{ + sb2 csrrc; /* return code: v2 codes, v4 codes negative */ + ub2 csrft; /* function type */ + ub4 csrrpc; /* rows processed count */ + ub2 csrpeo; /* parse error offset */ + ub1 csrfc; /* function code */ + ub1 csrlfl; /* lda flag to indicate type of login */ + ub2 csrarc; /* actual untranslated return code */ + ub1 csrwrn; /* warning flags */ + ub1 csrflg; /* error action */ + sword csrcn; /* cursor number */ + riddef csrrid; /* rowid structure */ + sword csrose; /* os dependent error code */ + ub1 csrchk; /* check byte = CSRCHECK - in cursor */ + /* check byte = LDACHECK - in LDA */ + struct hstdef *csrhst; /* pointer to the hst */ +}; +typedef struct csrdef csrdef; +typedef struct csrdef ldadef; /* lda is the same as a csr */ + + +/* values for csrlfl */ +#define LDAFLG 1 /* ...via ologon */ +#define LDAFLO 2 /* ...via olon or orlon */ +#define LDANBL 3 /* ...nb logon in progress */ + +/* valuses for crsfc */ +#define csrfpa 2 /* ...OSQL */ +#define csrfex 4 /* ...OEXEC */ +#define csrfbi 6 /* ...OBIND */ +#define csrfdb 8 /* ...ODFINN */ +#define csrfdi 10 /* ...ODSRBN */ +#define csrffe 12 /* ...OFETCH */ +#define csrfop 14 /* ...OOPEN */ +#define csrfcl 16 /* ...OCLOSE */ +#define csrfds 22 /* ...ODSC */ +#define csrfnm 24 /* ...ONAME */ +#define csrfp3 26 /* ...OSQL3 */ +#define csrfbr 28 /* ...OBNDRV */ +#define csrfbx 30 /* ...OBNDRN */ +/*#defe csrfdf 32*/ /* ???? */ +#define csrfso 34 /* ...OOPT */ +#define csrfre 36 /* ...ORESUM */ +#define csrfbn 50 /* ...OBINDN */ +#define csrfca 52 /* ..OCANCEL */ +#define csrfsd 54 /* ..OSQLD */ +#define csrfef 56 /* ..OEXFEN */ +#define csrfln 58 /* ..OFLNG */ +#define csrfdp 60 /* ..ODSCSP */ +#define csrfba 62 /* ..OBNDRA */ +#define csrfbps 63 /*..OBINDPS */ +#define csrfdps 64 /*..ODEFINPS */ +#define csrfgpi 65 /* ...OGETPI */ +#define csrfspi 66 /* ...OSETPI */ + +/* values for csrwrn */ +#define CSRWANY 0x01 /* there is a warning flag set */ +#define CSRWTRUN 0x02 /* a data item was truncated */ +#define CSRWNVIC 0x04 /* NULL values were used in an aggregate function */ +#define CSRWITCE 0x08 /* column count not equal to into list count */ +#define CSRWUDNW 0x10 /* update or delete without where clause */ +#define CSRWRSV0 0x20 +#define CSRWROLL 0x40 /* rollback required */ +#define CSRWRCHG 0x80 /* change after query start on select for update */ + +/* values fro csrflg */ +#define CSRFSPND 0x01 /* current operation suspended */ +#define CSRFATAL 0x02 /* fatal operation: transaction rolled back */ +#define CSRFBROW 0x04 /* current row backed out */ +#define CSRFREFC 0x08 /* ref cursor type CRSCHK disabled for this cursor */ +#define CSRFNOAR 0x10 /* ref cursor type binds, so no array bind/execute */ + +/* define function codes; in order of octdef.h */ +#define OTYCTB 1 /* CREATE TABLE */ +#define OTYSER 2 /* set role */ +#define OTYINS 3 /* INSERT */ +#define OTYSEL 4 /* SELECT */ +#define OTYUPD 5 /* UPDATE */ +#define OTYDRO 6 /* drop role */ +#define OTYDVW 7 /* DROP VIEW */ + /* once was validate index */ + /* once was create partition */ + /* once was alter partition */ +#define OTYDTB 8 /* DROP TABLE */ + /* once was alter space */ + /* once was drop space */ +#define OTYDEL 9 /* DELETE */ +#define OTYCVW 10 /* create view */ +#define OTYDUS 11 /* drop user */ +#define OTYCRO 12 /* create role */ +#define OTYCSQ 13 /* create sequence */ +#define OTYASQ 14 /* alter sequence */ +#define OTYACL 15 /* alter cluster */ +#define OTYDSQ 16 /* drop sequence */ +#define OTYCSC 17 /* create schema */ +#define OTYCCL 18 /* CREATE CLUSTER */ + /* once was alter cluster */ +#define OTYCUS 19 /* create user */ +#define OTYCIX 20 /* CREATE INDEX */ +#define OTYDIX 21 /* DROP INDEX */ +#define OTYDCL 22 /* DROP CLUSTER */ +#define OTYVIX 23 /* validate index */ +#define OTYCPR 24 /* create procedure */ +#define OTYAPR 25 /* alter procedure */ +#define OTYATB 26 /* alter table */ + /* once was evaluate */ +#define OTYXPL 27 /* explain */ +#define OTYGRA 28 /* grant */ +#define OTYREV 29 /* revoke */ +#define OTYCSY 30 /* create synonym */ +#define OTYDSY 31 /* drop synonym */ +#define OTYASY 32 /* alter system switch log */ +#define OTYSET 33 /* set transaction */ +#define OTYPLS 34 /* pl/sql execute */ +#define OTYLTB 35 /* lock */ +#define OTYNOP 36 /* noop */ +#define OTYRNM 37 /* rename */ +#define OTYCMT 38 /* comment */ +#define OTYAUD 39 /* audit */ +#define OTYNOA 40 /* no audit */ +#define OTYAIX 41 /* ALTER INDEX */ +#define OTYCED 42 /* create external database */ +#define OTYDED 43 /* drop external database */ +#define OTYCDB 44 /* create database */ +#define OTYADB 45 /* alter database */ +#define OTYCRS 46 /* create rollback segment */ +#define OTYARS 47 /* alter rollback segment */ +#define OTYDRS 48 /* drop rollback segment */ +#define OTYCTS 49 /* create tablespace */ +#define OTYATS 50 /* alter tablespace */ +#define OTYDTS 51 /* drop tablespace */ +#define OTYASE 52 /* alter session */ +#define OTYAUR 53 /* alter user */ +#define OTYCWK 54 /* commit (work) */ +#define OTYROL 55 /* rollback */ +#define OTYSPT 56 /* savepoint */ + +/* For number greater than 56 the the type is the same as defined in +** octdef.h for that number. So for completion look at octdef.h +*/ + +#define OTYDEV OTYCVW /* old DEFINE VIEW = create view */ + +/* FUNCTION CODES */ +#define OCLFPA 2 /* parse - OSQL */ +#define OCLFEX 4 /* execute - OEXEC */ +#define OCLFBI 6 /* BIND by name - OBIND */ +#define OCLFDB 8 /* define buffer - ODEFIN */ +#define OCLFDI 10 /* describe item - ODSC */ +#define OCLFFE 12 /* fetch - OFETCH */ +#define OCLFOC 14 /* open cursor - OOPEN */ +# define OCLFLI OCLFOC /* old name for open cursor - OOPEN */ +#define OCLFCC 16 /* close cursor - OCLOSE */ +# define OCLFLO OCLFCC /* old name for close cursor - OCLOSE */ +#define OCLFDS 22 /* describe - ODSC */ +#define OCLFON 24 /* get table and column names - ONAME */ +#define OCLFP3 26 /* parse - OSQL3 */ +#define OCLFBR 28 /* bind reference by name - OBNDRV */ +#define OCLFBX 30 /* bind referecne numeric - OBNDRN */ +#define OCLFSO 34 /* special function - OOPT */ +#define OCLFRE 36 /* resume - ORESUM */ +#define OCLFBN 50 /* bindn */ +#define OCLFMX 52 /* maximum function number */ + +#ifdef NEVER /* unused codes */ +# define OCLFLK 18 /* open for kernel operations */ +# define OCLFEK 20 /* execute kernel operations */ +# define OCLFOK 22 /* kernel close */ +# define OCLFIN 28 /* logon to oracle */ +# define OCLFOF 30 /* logoff from oracle */ +# define OCLFAX 32 /* allocate a context area */ +# define OCLFPI 34 /* page in context area */ +# define OCLFIS 36 /* special system logon */ +# define OCLFCO 38 /* cancel the current operation */ +# define OCLFGI 40 /* get database id */ +# define OCLFJN 42 /* journal operation */ +# define OCLFCL 44 /* cleanup prior execute operation */ +# define OCLFMC 46 /* map a cursor area */ +# define OCLFUC 48 /* unmap cursor and restore user maping */ +#endif /*NEVER *//* obsolete codes */ + + +/* values for ocimode in ocipin call */ + +#define OCIEVDEF UPIEVDEF /* default : non-thread safe enivronment */ +#define OCIEVTSF UPIEVTSF /* thread-safe environment */ + + +/* OCIL* flags used to determine the mode of login, using ocilog(). +** Currently defined only for non-blocking and thread-safe logins. +*/ + +#define OCILMDEF UPILMDEF /* default, regular login */ +#define OCILMNBL UPILMNBL /* non-blocking logon */ +#define OCILMESY UPILMESY /* thread safe but external sync */ +#define OCILMISY UPILMISY /* internal sync, we do it */ +#define OCILMTRY UPILMTRY /* try to, but do not block on mutex */ + + +/* + * since sqllib uses both ocidef and ocidfn the following defines + * need to be guarded + */ +#ifndef OCI_FLAGS +#define OCI_FLAGS + +/* OCI_*_PIECE defines the piece types that are returned or set +*/ + +#define OCI_ONE_PIECE UPI_ONE_PIECE /* there or this is the only piece */ +#define OCI_FIRST_PIECE UPI_FIRST_PIECE /* the first of many pieces */ +#define OCI_NEXT_PIECE UPI_NEXT_PIECE /* the next of many pieces */ +#define OCI_LAST_PIECE UPI_LAST_PIECE /* the last piece of this column */ +#endif + +/* +** OCITAB: define return code pairs for version 2 to 3 conversions +*/ +struct ocitab +{ + sb2 ocitv3; /* Version 3/4 return code */ + sb2 ocitv2; /* Version 2 equivalent return code */ +}; +typedef struct ocitab ocitab; + +externref const ocitab ocitbl[]; + +/* macros to check cursors and LDA's. */ +/* macros to set error codes */ + +# define CRSCHK(c) if ((c->csrchk != CSRCHECK)\ + && !bit(c->csrflg, CSRFREFC))\ + return(ocir32(c, OER(1001))) +# define ldaerr(l, e) ( l->csrrc = (sb2)(-( l->csrarc = (ub2)(e)) ) ) +# define LDACHK(l) if (l->csrchk != LDACHECK) \ + return(ldaerr(l, OER(1001))) + + +/************************************************/ +/* OCI PROCEDURE DECLARATIONS */ +/************************************************/ + + + + +/*****************************/ +/* Database logon/logout */ +/*****************************/ +sword ocilog( ldadef *lda, struct hstdef *hst, oratext *uid, sword uidl, + oratext *psw, sword pswl, oratext* conn, sword connl, + ub4 mode ); +sword ocilon( ldadef *lda, oratext *uid, sword uidl, oratext *psw, + sword pswl, sword audit ); +sword ocilgi( ldadef *lda, sb2 areacount ); +sword ocirlo( ldadef *lda, struct hstdef *hst, oratext *uid, sword uidl, + oratext *psw, sword pswl, sword audit ); + /* ocilon - logon to oracle + ** ocilgi - version 2 compatible ORACLE logon call. + ** no login to ORACLE is performed: the LDA is initialized + ** ocirlo - version 5 compatible ORACLE Remote Login call, + ** oracle login is executed. + ** lda - pointer to ldadef + ** uid - user id [USER[/PASSWORD]] + ** uidl - length of uid, if -1 strlen(uid) is used + ** psw - password string; ignored if specified in uid + ** pswl - length of psw, if -1 strlen(psw) is used + ** audit - is not supported; the only permissible value is 0 + ** areacount - unused + */ + +sword ocilof( ldadef *lda ); + /* + ** ocilof - disconnect from ORACLE + ** lda - pointer to ldadef + */ + + +/*********************/ +/* Error Messages */ +/*********************/ +sword ocierr( ldadef *lda, sb2 rcode, oratext *buffer, sword bufl ); +sword ocidhe( sb2 rcode, oratext *buffer ); + /* + ** Move the text explanation for an ORACLE error to a user defined buffer + ** ocierr - will return the message associated with the hstdef stored + ** in the lda. + ** ocidhe - will return the message associated with the default host. + ** lda - lda associated with the login session + ** rcode - error code as returned by V3 call interface + ** buffer - address of a user buffer of at least 132 characters + */ + + +/***********************/ +/* Cursor Open/Close */ +/***********************/ +sword ociope( struct csrdef *cursor, ldadef *lda, oratext *dbn, sword dbnl, + sword areasize, oratext *uid, sword uidl ); + +sword ociclo( struct csrdef *cursor ); + /* + ** open or close a cursor. + ** cursor - pointer to csrdef + ** ldadef - pointer to ldadef + ** dbn - unused + ** dbnl - unused + ** areasize - if (areasize == -1) areasize <- system default initial size + ** else if (areasize IN [1..256]) areasize <- areasize * 1024; + ** most applications should use the default size since context + ** areas are extended as needed until memory is exhausted. + ** uid - user id + ** uidl - userid length + */ + +/***********************************/ +/* CONTROL AND OPTIONS */ +/***********************************/ +sword ocibre( ldadef *lda ); + /* + ** ocibrk - Oracle Call Interface send BReaK Sends a break to + ** oracle. If oracle is active, the current operation is + ** cancelled. May be called asynchronously. DOES NOT SET + ** OERRCD in the hst. This is because ocibrk may be called + ** asynchronously. Callers must test the return code. + ** lda - pointer to a ldadef + */ + +sword ocican( struct csrdef *cursor ); + /* + ** cancel the operation on the cursor, no additional OFETCH calls + ** will be issued for the existing cursor without an intervening + ** OEXEC call. + ** cursor - pointer to csrdef + */ + +sword ocisfe( struct csrdef *cursor, sword erropt, sword waitopt ); + /* + ** ocisfe - user interface set error options + ** set the error and cursor options. + ** allows user to set the options for dealing with fatal dml errors + ** and other cursor related options + ** see oerdef for valid settings + ** cursor - pointer to csrdef + ** erropt - error optionsn + ** waitopr - wait options + */ + + +/***************************************/ +/* COMMIT/ROLLBACK/AUTOCOMMIT */ +/***************************************/ +sword ocicom( ldadef *lda ); +sword ocirol( ldadef *lda ); + /* + ** ocicom - commit the current transaction + ** ocirol - roll back the current transaction + */ + +sword ocicon( ldadef *lda ); +sword ocicof( ldadef *lda ); + /* + ** ocicon - auto Commit ON + ** ocicof - auto Commit OFf + */ + + + +/************************/ +/* parsing */ +/************************/ +sword ocisq3(struct csrdef *cursor, oratext * /* sqlstm */, sword sqllen); + /* + ** ocisq3 - user interface parse sql statement + ** cursor - pointer to csrdef + ** sqlstm - pointer to SQL statement + ** sqllen - length of SQL statement. if -1, strlen(sqlstm) is used + */ + + + +/***************************/ +/* BINDING */ +/***************************/ +/* these are for the opcode in ocibndps, ocidfnps */ +#define OCI_PCWS 0 +#define OCI_SKIP 1 + +sword ocibin( struct csrdef *cursor, oratext *sqlvar, sword sqlvl, + ub1 *progv, sword progvl, sword ftype, sword scale, + oratext *fmt, sword fmtl, sword fmtt ); +sword ocibrv( struct csrdef *cursor, oratext *sqlvar, sword sqlvl, + ub1 *progv, sword progvl, sword ftype, sword scale, sb2 *indp, + oratext *fmt, sword fmtl, sword fmtt ); +sword ocibra( struct csrdef *cursor, oratext *sqlvar, sword sqlvl, + ub1 *progv, sword progvl, sword ftype, sword scale, + sb2 *indp, ub2 *aln, ub2 *rcp, ub4 mal, ub4 *cal, + oratext *fmt, sword fmtl, sword fmtt ); +sword ocibndps( struct csrdef *cursor, ub1 opcode, oratext *sqlvar, + sb4 sqlvl, ub1 *progv, sb4 progvl, sword ftype, + sword scale, sb2 *indp, ub2 *aln, ub2 *rcp, sb4 pv_skip, + sb4 ind_skip, sb4 len_skip, sb4 rc_skip, ub4 mal, + ub4 *cal, oratext *fmt, sb4 fmtl, sword fmtt ); +sword ocibnn ( struct csrdef *cursor, ub2 sqlvn, ub1 *progv, sword progvl, + sword ftype, sword scale, oratext *fmt, sword fmtl, + sword fmtt ); +sword ocibrn( struct csrdef *cursor, sword sqlvn, ub1 *progv, sword progvl, + sword ftype, sword scale, sb2 *indp, oratext *fmt, sword fmtl, + sword fmtt ); + /* + ** ocibin - bind by value by name + ** ocibrv - bind by reference by name + ** ocibra - bind by reference by name (array) + ** ocibndps - bind by reference by name (array) piecewise or with skips + ** ocibnn - bind by value numeric + ** ocibrn - bind by reference numeric + ** + ** the contents of storage specified in bind-by-value calls are + ** evaluated immediately. + ** the addresses of storage specified in bind-by-reference calls are + ** remembered, and the contents are examined at every execute. + ** + ** cursor - pointer to csrdef + ** sqlvn - the number represented by the name of the bind variables + ** for variables of the form :n or &n for n in [1..256) + ** (i.e. &1, :234). unnecessarily using larger numbers + ** in the range wastes space. + ** sqlvar - the name of the bind variable (:name or &name) + ** sqlval - the length of the name; + ** in bindif -1, strlen(bvname) is used + ** progv - pointer to the object to bind. + ** progvl - length of object to bind. + ** in bind-by-value if specified as -1 then strlen(bfa) is + ** used (really only makes sends with character types) + ** in bind-by-value, if specified as -1 then UB2MAXVAL + ** is used. Again this really makes sense only with + ** SQLT_STR. + ** ftype - datatype of object + ** indp - pointer to indicator variable. + ** -1 means to ignore bfa/bfl and bind NULL; + ** not -1 means to bind the contents of bfa/bfl + ** bind the contents pointed to by bfa + ** aln - Alternate length pointer + ** rcp - Return code pointer + ** mal - Maximum array length + ** cal - Current array length pointer + ** fmt - format string + ** fmtl - length of format string; if -1, strlen(fmt) is used + ** fmtt - desired output type after applying forat mask. Not + ** really yet implemented + ** scale - number of decimal digits in a cobol packed decimal (type 7) + ** + ** Note that the length of bfa when bound as SQLT_STR is reduced + ** to strlen(bfa). + ** Note that trailing blanks are stripped of storage of SQLT_STR. + */ + +/***************************/ +/* DESCRIBING */ +/***************************/ +sword ocidsc ( struct csrdef *cursor, sword pos, sb2 *dbsize, sb2 *fsize, + sb2 *rcode, sb2 *dtype, sb1 *buf, sb2 *bufl, sb2 *dsize ); +sword ocidsr( struct csrdef *cursor, sword pos, sb2 *dbsize, sb2 *dtype, + sb2 *fsize ); +sword ocinam( struct csrdef *cursor, sword pos, sb1 *tbuf, sb2 *tbufl, + sb1 *buf, sb2 *bufl ); + /* + ** ocidsc, ocidsr: Obtain information about a column + ** ocinam : get the name of a column + ** cursor - pointer to csrdef + ** pos - position in select list from [1..N] + ** dbsize - place to store the database size + ** fsize - place to store the fetched size + ** rcode - place to store the fetched column returned code + ** dtype - place to store the data type + ** buf - array to store the column name + ** bufl - place to store the column name length + ** dsize - maximum display size + ** tbuf - place to store the table name + ** tbufl - place to store the table name length + */ + +sword ocidsp ( struct csrdef *cursor, sword pos, sb4 *dbsize, sb2 *dbtype, + sb1 *cbuf, sb4 *cbufl, sb4 *dsize, sb2 *pre, sb2 *scl, + sb2 *nul ); + +sword ocidpr( ldadef *lda, oratext *object_name, size_t object_length, + void * reserved1, size_t reserved1_length, void * reserved2, + size_t reserved2_length, ub2 *overload, ub2 *position, + ub2 *level, oratext **argument_name, ub2 *argument_length, + ub2 *datatype, ub1 *default_supplied, ub1 *in_out, + ub4 *length, sb2 *precision, sb2 *scale, ub1 *radix, + ub4 *spare, ub4 *total_elements ); + /* + ** OCIDPR - User Program Interface: Describe Stored Procedure + ** + ** This routine is used to obtain information about the calling + ** arguments of a stored procedure. The client provides the + ** name of the procedure using "object_name" and "database_name" + ** (database name is optional). The client also supplies the + ** arrays for OCIDPR to return the values and indicates the + ** length of array via the "total_elements" parameter. Upon return + ** the number of elements used in the arrays is returned in the + ** "total_elements" parameter. If the array is too small then + ** an error will be returned and the contents of the return arrays + ** are invalid. + ** + ** + ** EXAMPLE : + ** + ** Client provides - + ** + ** object_name - SCOTT.ACCOUNT_UPDATE@BOSTON + ** total_elements - 100 + ** + ** + ** ACCOUNT_UPDATE is an overloaded function with specification : + ** + ** type number_table is table of number index by binary_integer; + ** table account (account_no number, person_id number, + ** balance number(7,2)) + ** table person (person_id number(4), person_nm varchar2(10)) + ** + ** function ACCOUNT_UPDATE (account number, + ** person person%rowtype, amounts number_table, + ** trans_date date) return accounts.balance%type; + ** + ** function ACCOUNT_UPDATE (account number, + ** person person%rowtype, amounts number_table, + ** trans_no number) return accounts.balance%type; + ** + ** + ** Values returned - + ** + ** overload position argument level datatype length prec scale rad + ** ------------------------------------------------------------------- + ** 0 0 0 NUMBER 22 7 2 10 + ** 0 1 ACCOUNT 0 NUMBER 22 0 0 0 + ** 0 2 PERSON 0 RECORD 0 0 0 0 + ** 0 2 PERSON_ID 1 NUMBER 22 4 0 10 + ** 0 2 PERSON_NM 1 VARCHAR2 10 0 0 0 + ** 0 3 AMOUNTS 0 TABLE 0 0 0 0 + ** 0 3 1 NUMBER 22 0 0 0 + ** 0 4 TRANS_NO 0 NUMBER 22 0 0 0 + ** + ** 1 0 0 NUMBER 22 7 2 10 + ** 1 1 ACCOUNT 0 NUMBER 22 0 0 0 + ** 1 2 PERSON 0 RECORD 0 0 0 0 + ** 1 2 PERSON_ID 1 NUMBER 22 4 0 10 + ** 1 2 PERSON_NM 1 VARCHAR2 10 0 0 0 + ** 1 3 AMOUNTS 0 TABLE 0 0 0 0 + ** 1 3 1 NUMBER 22 0 0 0 + ** 1 4 TRANS_DATE 0 NUMBER 22 0 0 0 + ** + ** + ** OCIDPR Argument Descriptions - + ** + ** ldadef - pointer to ldadef + ** object_name - object name, synonyms are also accepted and will + ** be translate, currently only procedure and function + ** names are accepted, also NLS names are accepted. + ** Currently, the accepted format of a name is + ** [[part1.]part2.]part3[@dblink] (required) + ** object_length - object name length (required) + ** reserved1 - reserved for future use + ** reserved1_length - reserved for future use + ** reserved2 - reserved for future use + ** reserved2_length - reserved for future use + ** overload - array indicating overloaded procedure # (returned) + ** position - array of argument positions, position 0 is a + ** function return argument (returned) + ** level - array of argument type levels, used to describe + ** sub-datatypes of data structures like records + ** and arrays (returned) + ** argument_name - array of argument names, only returns first + ** 30 characters of argument names, note storage + ** for 30 characters is allocated by client (returned) + ** argument_length - array of argument name lengths (returned) + ** datatype - array of oracle datatypes (returned) + ** default_supplied - array indicating parameter has default (returned) + ** 0 = no default, 1 = default supplied + ** in_out - array indicating if argument is IN or OUT (returned + ** 0 = IN param, 1 = OUT param, 2 = IN/OUT param + ** length - array of argument lengths (returned) + ** precision - array of precisions (if number type)(returned) + ** scale - array of scales (if number type)(returned) + ** radix - array of radix (if number type)(returned) + ** spare - array of spares. + ** total_elements - size of arrays supplied by client (required), + ** total number of elements filled (returned) + */ + +/*************************************/ +/* DEFINING */ +/*************************************/ +sword ocidfi( struct csrdef *cursor, sword pos, ub1 *buf, sword bufl, + sword ftype, sb2 *rc, sword scale ); +sword ocidfn( struct csrdef *cursor, sword pos, ub1 *buf, sword bufl, + sword ftype, sword scale, sb2 *indp, oratext *fmt, sword fmtl, + sword fmtt, ub2 *rl, ub2 *rc ); +sword ocidfnps( struct csrdef *cursor, ub1 opcode, sword pos, ub1 *buf, + sb4 bufl, sword ftype, sword scale, + sb2 *indp, oratext *fmt, sb4 fmtl, + sword fmtt, ub2 *rl, ub2 *rc, + sb4 pv_skip, sb4 ind_skip, sb4 len_skip, + sb4 rc_skip ); + + + /* Define a user data buffer using upidfn + ** cursor - pointer to csrdef + ** pos - position of a field or exp in the select list of a query + ** bfa/bfl - address and length of client-supplied storage + to receive data + ** ftype - user datatype + ** scale - number of fractional digits for cobol packed decimals + ** indp - place to store the length of the returned value. If returned + ** value is: + ** negative, the field fetched was NULL + ** zero , the field fetched was same length or shorter than + ** the buffer provided + ** positive, the field fetched was truncated + ** fmt - format string + ** fmtl - length of format string, if -1 strlent(fmt) used + ** rl - place to store column length after each fetch + ** rc - place to store column error code after each fetch + ** fmtt - fomat type + */ + +/********************************/ +/* PIECE INFORMATION GET/SET */ +/********************************/ +sword ocigetpi( struct csrdef *cursor, ub1 *piecep, + void **ctxpp, ub4 *iterp, ub4 *indexp ); +sword ocisetpi( struct csrdef *cursor, ub1 piece, + void *bufp, ub4 *lenp ); + + +/********************************/ +/* EXECUTE */ +/********************************/ +sword ociexe( struct csrdef *cursor ); +sword ociexn( struct csrdef *cursor, sword iters, sword roff ); +sword ociefn( struct csrdef *cursor, ub4 nrows, sword can, sword exact ); + /* + ** ociexe - execute a cursor + ** ociexn - execute a cursosr N times + ** cursor - pointer to a csrdef + ** iters - number of times to execute cursor + ** roff - offset within the bind variable array at which to begin + ** operations. + */ + + +/*********************************/ +/* FETCHING */ +/*********************************/ +sword ocifet( struct csrdef *cursor ); +sword ocifen( struct csrdef *cursor, sword nrows ); + /* ocifet - fetch the next row + ** ocifen - fetch n rows + ** cursor - pointer to csrdef + ** nrows - number of rows to be fetched + */ + +sword ocilng( struct csrdef *cursor, sword posit, ub1 *bfa, sb4 bfl, + sword dty, ub4 *rln, sb4 off ); + +/*********************************/ +/* CONVERSION */ +/*********************************/ +sword ocic32( struct csrdef *cursor ); + /* + ** Convert selected version 3 return codes to the equivalent + ** version 2 code. + ** csrdef->csrrc is set to the converted code + ** csrdef->csrft is set to v2 oracle statment type + ** csrdef->csrrpc is set to the rows processed count + ** csrdef->csrpeo is set to error postion + ** + ** cursor - pointer to csrdef + */ + + +sword ocir32( struct csrdef *cursor, sword retcode ); + /* + ** Convert selected version 3 return codes to the equivalent version 2 + ** code. + ** + ** cursor - pointer to csrdef + ** retcode - place to store the return code + */ + + +void ociscn( sword **arglst, char *mask_addr, sword **newlst ); + /* + ** Convert call-by-ref to call-by-value: + ** takes an arg list and a mask address, determines which args need + ** conversion to a value, and creates a new list begging at the address + ** of newlst. + ** + ** arglst - list of arguments + ** mast_addr _ mask address determines args needing conversion + ** newlst - new list of args + */ + +sword ocistf ( sword typ, sword bufl, sword rdig, oratext *fmt, + struct csrdef *cursor, sword *err ); +/* Convert a packed decimal buffer length (bytes) and scale to a format +** string of the form mm.+/-nn, where mm is the number of packed +** decimal digits, and nn is the scaling factor. A positive scale name +** nn digits to the rights of the decimal; a negative scale means nn zeros +** should be supplied to the left of the decimal. +** bufl - length of the packed decimal buffer +** rdig - number of fractional digits +** fmt - pointer to a string holding the conversion format +** cursor - pointer to csrdef +** err - pointer to word storing error code +*/ + + +/******************************************/ +/* Non-blocking operations */ +/******************************************/ +sword ocinbs( ldadef *lda ); /* set a connection to non-blocking */ +sword ocinbt( ldadef *lda ); /* test if connection is non-blocking */ +sword ocinbc( ldadef *lda ); /* clear a connection to blocking */ +sword ocinlo( ldadef *lda, struct hstdef *hst, oratext *conn, + sword connl, oratext *uid, sword uidl, + oratext *psw, sword pswl, sword audit ); + /* logon in non-blocking fashion */ +/* ocinlo allows an application to logon in non-blocking fashion. +** lda - pointer to ldadef +** hst - pointer to a 256 byte area, must be cleared to zero before call +** conn - the database link (if specified @LINK in uid will be ignored) +** connl - length of conn; if -1 strlen(conn) is used +** uid - user id [USER[/PASSWORD][@LINK]] +** uidl - length of uid, if -1 strlen(uid) is used +** psw - password string; ignored if specified in uid +** pswl - length of psw, if -1 strlen(psw) is used +** audit - is not supported; the only permissible value is 0 +*/ + +/***************************************************/ +/* Procedure Declaration for Pro*C */ +/***************************************************/ +/* Note: The following routines are used in Pro*C and have the + same interface as their couterpart in OCI. + Althought the interface follows for more details please refer + to the above routines */ + +/******************************************/ +/* initialization/logon/logof */ +/******************************************/ +sword ocipin( ub4 mode ); + +sword ologin( ldadef *lda, sb2 areacount ); +sword ologon( ldadef *lda, sb2 areacount ); + +/*****************************************/ +/* Open/Close/Parse Cursor */ +/*****************************************/ + +/* +** ocisqd - oci delayed parse (Should be used only with deferred upi/oci) +** FUNCTION: Call upidpr to delay the parse of the sql statement till the +** time that a call needs to be made to the kernel (execution or +** describe time ) +** RETURNS: Oracle return code. +*/ +sword ocisq7( struct csrdef *cursor, oratext * /* sqlstm */, sb4 sqllen, + sword defflg, ub4 sqlt ); + +/*****************************************/ +/* Bind */ +/*****************************************/ +sword obind( struct csrdef *cursor, oratext *sqlvar, sword sqlvl, + ub1 *progv, sword progvl, sword ftype, sword scale, + oratext *fmt, sword fmtl, sword fmtt ); +sword obindn( struct csrdef *cursor, ub2 sqlvn, ub1 *progv, sword progvl, + sword ftype, sword scale, oratext *fmt, sword fmtl, + sword fmtt ); + +/**********************************************/ +/* Define */ +/**********************************************/ +sword odfinn( struct csrdef *cursor, sword pos, ub1 *buf, sword bufl, + sword ftype, sb2 *rc, sword scale ); + +/**********************************************/ +/* Describe */ +/**********************************************/ +sword odsrbn( struct csrdef *cursor, sword pos, sb2 *dbsize, sb2 *dtype, + sb2 *fsize ); + + +/******************************************/ +/* Non-blocking operations */ +/******************************************/ +sword onblon( ldadef *lda, struct hstdef *hst, oratext *conn, + sword connl, oratext *uid, sword uidl, + oratext *psw, sword pswl, sword audit ); + /* logon in non-blocking fashion */ +sword ocignfd( ldadef *lda, void *nfdp ); /* get native fd */ + +ub2 ocigft_getFcnType( ub2 oertyp ); /* get sql function code */ + +#endif diff --git a/libodbc/include/ora_linux/ocidem.h b/libodbc/include/ora_linux/ocidem.h new file mode 100644 index 0000000000..a6d0eaf378 --- /dev/null +++ b/libodbc/include/ora_linux/ocidem.h @@ -0,0 +1,113 @@ +/* + * + */ + +/* Copyright (c) 1991, 2005, Oracle. All rights reserved. */ +/* Copyright (c) 1991, 2005, Oracle. All rights reserved. */ +/* + NAME + ocidem.h - OCI demo header + MODIFIED (MM/DD/YY) + dmukhin 06/29/05 - ANSI prototypes; miscellaneous cleanup + whe 04/07/99 - bug#810071 + whe 03/19/99 - lrg 32079 etc.: putting static back for oci_func_tab + nmacnaug 02/02/99 - static declarations should not be in header files + mygopala 09/22/97 - Fix for bug 550351 + surman 03/14/97 - Merge 413362 to 8.0.3 + surman 11/08/96 - 413362: Add SS_64BIT_SERVER macro + emendez 04/07/94 - merge changes from branch 1.6.710.1 + emendez 02/02/94 - Fix for bug 157576 + jnlee 01/05/93 - include oratypes.h once, make oci_func_tab static + rkooi2 10/26/92 - More portability mods + rkooi2 10/22/92 - Change text back to char to avoid casts + rkooi2 10/20/92 - Changes to make it portable + sjain 03/16/92 - Creation +*/ + +/* + * ocidem.h + * + * Declares additional functions and data structures + * used in the OCI C sample programs. + */ + + +#ifndef ORATYPES +#include +#endif /* ORATYPES */ + +#ifndef OCIDFN +#include +#endif /* OCIDFN */ + +#ifndef OCIDEM +#define OCIDEM + + +/* internal/external datatype codes */ +#define VARCHAR2_TYPE 1 +#define NUMBER_TYPE 2 +#define INT_TYPE 3 +#define FLOAT_TYPE 4 +#define STRING_TYPE 5 +#define ROWID_TYPE 11 +#define DATE_TYPE 12 + +/* ORACLE error codes used in demonstration programs */ +#define VAR_NOT_IN_LIST 1007 +#ifndef NO_DATA_FOUND +# define NO_DATA_FOUND 1403 +#endif +#define NULL_VALUE_RETURNED 1405 + +/* some SQL and OCI function codes */ +#define FT_INSERT 3 +#define FT_SELECT 4 +#define FT_UPDATE 5 +#define FT_DELETE 9 + +#define FC_OOPEN 14 + +/* + * OCI function code labels, + * corresponding to the fc numbers + * in the cursor data area. + */ +static const text *oci_func_tab[] = {(text *) "not used", +/* 1-2 */ (text *) "not used", (text *) "OSQL", +/* 3-4 */ (text *) "not used", (text *) "OEXEC, OEXN", +/* 5-6 */ (text *) "not used", (text *) "OBIND", +/* 7-8 */ (text *) "not used", (text *) "ODEFIN", +/* 9-10 */ (text *) "not used", (text *) "ODSRBN", +/* 11-12 */ (text *) "not used", (text *) "OFETCH, OFEN", +/* 13-14 */ (text *) "not used", (text *) "OOPEN", +/* 15-16 */ (text *) "not used", (text *) "OCLOSE", +/* 17-18 */ (text *) "not used", (text *) "not used", +/* 19-20 */ (text *) "not used", (text *) "not used", +/* 21-22 */ (text *) "not used", (text *) "ODSC", +/* 23-24 */ (text *) "not used", (text *) "ONAME", +/* 25-26 */ (text *) "not used", (text *) "OSQL3", +/* 27-28 */ (text *) "not used", (text *) "OBNDRV", +/* 29-30 */ (text *) "not used", (text *) "OBNDRN", +/* 31-32 */ (text *) "not used", (text *) "not used", +/* 33-34 */ (text *) "not used", (text *) "OOPT", +/* 35-36 */ (text *) "not used", (text *) "not used", +/* 37-38 */ (text *) "not used", (text *) "not used", +/* 39-40 */ (text *) "not used", (text *) "not used", +/* 41-42 */ (text *) "not used", (text *) "not used", +/* 43-44 */ (text *) "not used", (text *) "not used", +/* 45-46 */ (text *) "not used", (text *) "not used", +/* 47-48 */ (text *) "not used", (text *) "not used", +/* 49-50 */ (text *) "not used", (text *) "not used", +/* 51-52 */ (text *) "not used", (text *) "OCAN", +/* 53-54 */ (text *) "not used", (text *) "OPARSE", +/* 55-56 */ (text *) "not used", (text *) "OEXFET", +/* 57-58 */ (text *) "not used", (text *) "OFLNG", +/* 59-60 */ (text *) "not used", (text *) "ODESCR", +/* 61-62 */ (text *) "not used", (text *) "OBNDRA", +/* 63-64 */ (text *) "OBINDPS", (text *) "ODEFINPS", +/* 65-66 */ (text *) "OGETPI", (text *) "OSETPI" +}; + +#endif /* OCIDEM */ + diff --git a/libodbc/include/ora_linux/ocidfn.h b/libodbc/include/ora_linux/ocidfn.h new file mode 100644 index 0000000000..7a3ac2de3b --- /dev/null +++ b/libodbc/include/ora_linux/ocidfn.h @@ -0,0 +1,249 @@ +/* Copyright (c) 1991, 2005, Oracle. All rights reserved. */ +/* Copyright (c) 1991, 2005, Oracle. All rights reserved. */ +/* + NAME + ocidfn.h - OCI Definations + NOTES + Shipped to users. + MODIFIED (MM/DD/YY) + mbastawa 09/16/05 - dbhygiene + dmukhin 06/29/05 - ANSI prototypes; miscellaneous cleanup + srseshad 11/25/02 - change binary float/double codes + srseshad 11/14/02 - Add SQLT_IBFLOAT, SQLT_IBDOUBLE + mxyang 09/17/02 - grabtrans 'mmorsi_obj_float' + srseshad 09/06/02 - Add binary float/double + aahluwal 06/04/02 - bug 2360115 + kmuthukk 05/02/00 - add SQLT_PNTY + amangal 07/30/99 - Merge into 8.1.6 : Bug 879031 + tnbui 07/28/99 - Remove SQLT_TIMESTAMP_ITZ + tnbui 07/21/99 - SQLT_TIMESTAMP_LTZ + tnbui 06/16/99 - TIMESTAMP WITH IMPLICIT TIME ZONE + whe 04/07/99 - bug#810075 + whe 03/19/99 - lrg 32079 etc.: move HDA def from ocidem.h to ocidfn. + skmishra 05/10/98 - + vyanaman 04/16/98 - update sql92 datatypes + khnguyen 01/16/98 - + khnguyen 12/23/97 - SQLT* for datetimes and intervals + tanguyen 08/19/97 - + dchatter 03/18/97 - porting exception 390897 + dchatter 05/02/97 - merge porting exception + dalpern 12/04/96 - SQLCS_LIT_NULL added + cxcheng 11/14/96 - add SQLT_BFILE/SQLT_CFILE to fix compile prob + cxcheng 11/12/96 - add SQLT_NCO for named collection + lchidamb 10/17/96 - add SQLT_VST and SQLT_ODT + sgollapu 10/14/96 - Mutual exclusion of ocidfn and sqldef + sgollapu 10/07/96 - OCI Simplification + aroy 09/09/96 - add SQLCS* definitions + slari 08/07/96 - add SQLT_RDD, rowid descriptor + slari 06/12/96 - remove SQLT_TTBL + dchatter 04/21/96 - prepare for merge into main + slari 08/24/95 - b299432, define CDA_SIZE + zwalcott 02/28/96 - add SQLT_BFILEE and SQLT_CFILEE. + lchidamb 02/22/96 - make dtys consistent with dtydef.h + lchidamb 02/16/96 - add SQLT_BFILEE and SQLT_CFILEE + lchidamb 01/30/96 - rename new datatypes for v8 + lchidamb 09/06/95 - add new datatypes + slari 05/11/95 - add OCI_EV_DEF and OCI_EV_TSF + dchatter 04/06/95 - add ifdef flags around OCI_flags + dchatter 03/08/95 - piece values + dchatter 03/06/95 - merge changes from branch 1.2.720.3 + jfbrown 02/17/95 - merge changes from branch 1.2.720.2 + dchatter 02/08/95 - olog call modes + jfbrown 02/03/95 - remove non-printable characters + lchidamb 12/06/94 - merge changes from branch 1.2.720.1 + lchidamb 10/04/94 - added field chk to cda_head, cda_def + dchatter 07/05/94 - SQLT_CUR added + rkooi2 11/27/92 - Changing e* datatypes to s* + rkooi2 10/26/92 - More portability mods + rkooi2 10/22/92 - Added #ifndef ORATYPES ... + rkooi2 10/18/92 - Changes to make it portable. + sjain 03/16/92 - Creation +*/ + +/* + * ocidfn.h + * + * Common header file for OCI C sample programs. + * This header declares the cursor and logon data area structure. + * The types used are defined in . + * + */ + +#ifndef OCIDFN +#define OCIDFN + +#include + +/* The cda_head struct is strictly PRIVATE. It is used + internally only. Do not use this struct in OCI programs. */ + +struct cda_head { + sb2 v2_rc; + ub2 ft; + ub4 rpc; + ub2 peo; + ub1 fc; + ub1 rcs1; + ub2 rc; + ub1 wrn; + ub1 rcs2; + sword rcs3; + struct { + struct { + ub4 rcs4; + ub2 rcs5; + ub1 rcs6; + } rd; + ub4 rcs7; + ub2 rcs8; + } rid; + sword ose; + ub1 chk; + void *rcsp; +}; + +/* +** Size of HDA area: +** 512 for 64 bit arquitectures +** 256 for 32 bit arquitectures +*/ + +#if defined(SS_64BIT_SERVER) || defined(__64BIT__) +# define HDA_SIZE 512 +#else +# define HDA_SIZE 256 +#endif + +#if defined(SS_64BIT_SERVER) || defined(__64BIT__) +#define CDA_SIZE 88 +#else +# define CDA_SIZE 64 +#endif + +/* the real CDA, padded to CDA_SIZE bytes in size */ +struct cda_def { + sb2 v2_rc; /* V2 return code */ + ub2 ft; /* SQL function type */ + ub4 rpc; /* rows processed count */ + ub2 peo; /* parse error offset */ + ub1 fc; /* OCI function code */ + ub1 rcs1; /* filler area */ + ub2 rc; /* V7 return code */ + ub1 wrn; /* warning flags */ + ub1 rcs2; /* reserved */ + sword rcs3; /* reserved */ + struct { /* rowid structure */ + struct { + ub4 rcs4; + ub2 rcs5; + ub1 rcs6; + } rd; + ub4 rcs7; + ub2 rcs8; + } rid; + sword ose; /* OSD dependent error */ + ub1 chk; + void *rcsp; /* pointer to reserved area */ + ub1 rcs9[CDA_SIZE - sizeof (struct cda_head)]; /* filler */ +}; + +typedef struct cda_def Cda_Def; + +/* the logon data area (LDA) + is the same shape as the CDA */ +typedef struct cda_def Lda_Def; + +/* OCI Environment Modes for opinit call */ +#define OCI_EV_DEF 0 /* default single-threaded environment */ +#define OCI_EV_TSF 1 /* thread-safe environment */ + +/* OCI Logon Modes for olog call */ +#define OCI_LM_DEF 0 /* default login */ +#define OCI_LM_NBL 1 /* non-blocking logon */ + +/* + * since sqllib uses both ocidef and ocidfn the following defines + * need to be guarded + */ +#ifndef OCI_FLAGS +#define OCI_FLAGS + +/* OCI_*_PIECE defines the piece types that are returned or set +*/ +#define OCI_ONE_PIECE 0 /* there or this is the only piece */ +#define OCI_FIRST_PIECE 1 /* the first of many pieces */ +#define OCI_NEXT_PIECE 2 /* the next of many pieces */ +#define OCI_LAST_PIECE 3 /* the last piece of this column */ +#endif + +#ifndef SQLDEF + +/* input data types */ +#define SQLT_CHR 1 /* (ORANET TYPE) character string */ +#define SQLT_NUM 2 /* (ORANET TYPE) oracle numeric */ +#define SQLT_INT 3 /* (ORANET TYPE) integer */ +#define SQLT_FLT 4 /* (ORANET TYPE) Floating point number */ +#define SQLT_STR 5 /* zero terminated string */ +#define SQLT_VNU 6 /* NUM with preceding length byte */ +#define SQLT_PDN 7 /* (ORANET TYPE) Packed Decimal Numeric */ +#define SQLT_LNG 8 /* long */ +#define SQLT_VCS 9 /* Variable character string */ +#define SQLT_NON 10 /* Null/empty PCC Descriptor entry */ +#define SQLT_RID 11 /* rowid */ +#define SQLT_DAT 12 /* date in oracle format */ +#define SQLT_VBI 15 /* binary in VCS format */ +#define SQLT_BFLOAT 21 /* Native Binary float*/ +#define SQLT_BDOUBLE 22 /* NAtive binary double */ +#define SQLT_BIN 23 /* binary data(DTYBIN) */ +#define SQLT_LBI 24 /* long binary */ +#define SQLT_UIN 68 /* unsigned integer */ +#define SQLT_SLS 91 /* Display sign leading separate */ +#define SQLT_LVC 94 /* Longer longs (char) */ +#define SQLT_LVB 95 /* Longer long binary */ +#define SQLT_AFC 96 /* Ansi fixed char */ +#define SQLT_AVC 97 /* Ansi Var char */ +#define SQLT_IBFLOAT 100 /* binary float canonical */ +#define SQLT_IBDOUBLE 101 /* binary double canonical */ +#define SQLT_CUR 102 /* cursor type */ +#define SQLT_RDD 104 /* rowid descriptor */ +#define SQLT_LAB 105 /* label type */ +#define SQLT_OSL 106 /* oslabel type */ + +#define SQLT_NTY 108 /* named object type */ +#define SQLT_REF 110 /* ref type */ +#define SQLT_CLOB 112 /* character lob */ +#define SQLT_BLOB 113 /* binary lob */ +#define SQLT_BFILEE 114 /* binary file lob */ +#define SQLT_CFILEE 115 /* character file lob */ +#define SQLT_RSET 116 /* result set type */ +#define SQLT_NCO 122 /* named collection type (varray or nested table) */ +#define SQLT_VST 155 /* OCIString type */ +#define SQLT_ODT 156 /* OCIDate type */ + +/* datetimes and intervals */ +#define SQLT_DATE 184 /* ANSI Date */ +#define SQLT_TIME 185 /* TIME */ +#define SQLT_TIME_TZ 186 /* TIME WITH TIME ZONE */ +#define SQLT_TIMESTAMP 187 /* TIMESTAMP */ +#define SQLT_TIMESTAMP_TZ 188 /* TIMESTAMP WITH TIME ZONE */ +#define SQLT_INTERVAL_YM 189 /* INTERVAL YEAR TO MONTH */ +#define SQLT_INTERVAL_DS 190 /* INTERVAL DAY TO SECOND */ +#define SQLT_TIMESTAMP_LTZ 232 /* TIMESTAMP WITH LOCAL TZ */ + +#define SQLT_PNTY 241 /* pl/sql representation of named types */ + +/* cxcheng: this has been added for backward compatibility - + it needs to be here because ocidfn.h can get included ahead of sqldef.h */ +#define SQLT_FILE SQLT_BFILEE /* binary file lob */ +#define SQLT_CFILE SQLT_CFILEE +#define SQLT_BFILE SQLT_BFILEE + +/* CHAR/NCHAR/VARCHAR2/NVARCHAR2/CLOB/NCLOB char set "form" information */ +#define SQLCS_IMPLICIT 1 /* for CHAR, VARCHAR2, CLOB w/o a specified set */ +#define SQLCS_NCHAR 2 /* for NCHAR, NCHAR VARYING, NCLOB */ +#define SQLCS_EXPLICIT 3 /* for CHAR, etc, with "CHARACTER SET ..." syntax */ +#define SQLCS_FLEXIBLE 4 /* for PL/SQL "flexible" parameters */ +#define SQLCS_LIT_NULL 5 /* for typecheck of NULL and empty_clob() lits */ + +#endif /* SQLDEF */ +#endif /* OCIDFN */ diff --git a/libodbc/include/ora_linux/ociextp.h b/libodbc/include/ora_linux/ociextp.h new file mode 100644 index 0000000000..cab02dc9f5 --- /dev/null +++ b/libodbc/include/ora_linux/ociextp.h @@ -0,0 +1,282 @@ +/* + * + */ + +/* Copyright (c) 1996, 2005, Oracle. All rights reserved. */ + +/* + NAME + ociextp.h - Interface Definitions for PL/SQL External Procedures + + DESCRIPTION + This header file contains C language callable interface from + PL/SQL External Procedures. + + PUBLIC FUNCTION(S) + OCIExtProcAllocCallMemory - Allocate Call memory + OCIExtProcRaiseExcp - Raise Exception + OCIExtProcRaiseExcpWithMsg - Raise Exception with message + OCIExtProcGetEnv - Get OCI Environment + + PRIVATE FUNCTION(S) + + + EXAMPLES + + NOTES + + + MODIFIED (MM/DD/YY) + dmukhin 06/29/05 - ANSI prototypes; miscellaneous cleanup + srseshad 03/12/03 - convert oci public api to ansi + rdecker 01/10/02 - change 32k to MAX_OEN for error numbers + sagrawal 07/20/01 - Statement Handle to safe cal outs + abrumm 04/19/01 - move include of oci.h after defines/typedef + rdecker 02/22/01 - lint fix + bpalaval 02/08/01 - Change text to oratext. + sagrawal 06/16/00 - ref cursor in callouts + whe 09/01/99 - 976457:check __cplusplus for C++ code + asethi 04/15/99 - Created (by moving ociextp.h from /vobs/plsql/public) + rhari 03/25/97 - Use ifndef + rhari 12/18/96 - Include oratypes.h + rhari 12/11/96 - #416977, Flip values of return codes + rhari 12/02/96 - Define Return Code Macros + rhari 11/18/96 - Error number is int + rhari 10/30/96 - Fix OCIExtProcRaiseExcpWithMsg + rhari 10/30/96 - Get rid of warnings + rhari 10/04/96 - Fix OCIExtProcRaiseExcpWithMsg + rhari 09/23/96 - Creation + +*/ + + +#ifndef OCIEXTP_ORACLE +# define OCIEXTP_ORACLE + +# ifndef ORATYPES +# include +# endif + + +/*--------------------------------------------------------------------------- + PUBLIC TYPES AND CONSTANTS + ---------------------------------------------------------------------------*/ + + +/* ----------------------------- Return Codes ----------------------------- */ +/* Success and Error return codes for certain external procedure interface + * functions. If a particular interface function returns OCIEXTPROC_SUCCESS + * or OCIEXTPROC_ERROR, then applications must use these macros to check + * for return values. + * + * OCIEXTPROC_SUCCESS -- External Procedure Success Return Code + * OCIEXTPROC_ERROR -- External Procedure Failure Return Code + */ +#define OCIEXTPROC_SUCCESS 0 +#define OCIEXTPROC_ERROR 1 + + +/* --------------------------- With-Context Type --------------------------- */ +/* + * The C callable interface to PL/SQL External Procedures require the + * With-Context parameter to be passed. The type of this structure is + * OCIExtProcContext is is opaque to the user. + * + * The user can declare the With-Context parameter in the application as + * + * OCIExtProcContext *with_context; + */ +typedef struct OCIExtProcContext OCIExtProcContext; + +/* NOTE: OCIExtProcContext must be visible prior to including */ + +# ifndef OCI_ORACLE +# include +# endif + + +/* ----------------------- OCIExtProcAllocCallMemory ----------------------- */ +/* OCIExtProcAllocCallMemory + * Allocate N bytes of memory for the duration of the External Procedure. + * + * Memory thus allocated will be freed by PL/SQL upon return from the + * External Procedure. You must not use any kind of 'free' function on + * memory allocated by OCIExtProcAllocCallMemory. + * Use this function to allocate memory for function returns. + * + * PARAMETERS + * Input : + * with_context - The with_context pointer that is passed to the C + * External Procedure. + * Type of with_context : OCIExtProcContext * + * amount - The number of bytes to allocate. + * Type of amount : size_t + * + * Output : + * Nothing + * + * Return : + * An untyped (opaque) Pointer to the allocated memory. + * + * Errors : + * A 0 return value should be treated as an error + * + * EXAMPLE + * text *ptr = (text *)OCIExtProcAllocCallMemory(wctx, 1024) + * + */ +#define OCIExtProcAllocCallMemory(with_context, amount) \ +ociepacm(with_context, (size_t)amount) + + + + +/* -------------------------- OCIExtProcRaiseExcp -------------------------- */ +/* OCIExtProcRaiseExcp + * Raise an Exception to PL/SQL. + * + * Calling this function signalls an exception back to PL/SQL. After a + * successful return from this function, the External Procedure must start + * its exit handling and return back to PL/SQL. Once an exception is + * signalled to PL/SQL, INOUT and OUT arguments, if any, are not processed + * at all. + * + * PARAMETERS + * Input : + * with_context - The with_context pointer that is passed to the C + * External Procedure. + * Type of with_context : OCIExtProcContext * + * errnum - Oracle Error number to signal to PL/SQL. errnum + * must be a positive number and in the range 1 to MAX_OEN + * Type of errnum : int + * Output : + * Nothing + * + * Return : + * OCIEXTPROC_SUCCESS - If the call was successful. + * OCIEXTPROC_ERROR - If the call failed. + * + */ +#define OCIExtProcRaiseExcp(with_context, errnum) \ +ocieperr(with_context, (int)errnum) + + + + + +/* ---------------------- OCIExtProcRaiseExcpWithMsg ---------------------- */ +/* OCIExtProcRaiseExcpWithMsg + * Raise an exception to PL/SQL. In addition, substitute the + * following error message string within the standard Oracle error + * message string. See note for OCIExtProcRaiseExcp + * + * PARAMETERS + * Input : + * with_context - The with_context pointer that is passed to the C + * External Procedure. + * Type of with_context : OCIExtProcContext * + * errnum - Oracle Error number to signal to PL/SQL. errnum + * must be a positive number and in the range 1 to MAX_OEN + * Type of errnum : int + * errmsg - The error message associated with the errnum. + * Type of errmsg : char * + * len - The length of the error message. 0 if errmsg is + * null terminated string. + * Type of len : size_t + * Output : + * Nothing + * + * Return : + * OCIEXTPROC_SUCCESS - If the call was successful. + * OCIEXTPROC_ERROR - If the call failed. + * + */ +#define OCIExtProcRaiseExcpWithMsg(with_context, errnum, errmsg, msglen) \ +ociepmsg(with_context, (int)errnum, errmsg, (size_t)msglen) + + + +/* --------------------------- OCIExtProcGetEnv --------------------------- */ +/* OCIExtProcGetEnv + * Get OCI Environment + * + * PARAMETERS + * Input : + * with_context - The with_context pointer that is passed to the C + * External Procedure. + * + * Output : + * envh - The OCI Environment handle. + * svch - The OCI Service handle. + * errh - The OCI Error handle. + * + * Return : + * OCI_SUCCESS - Successful completion of the function. + * OCI_ERROR - Error. + * + */ +#define OCIExtProcGetEnv(with_context, envh, svch, errh) \ +ociepgoe(with_context, envh, svch, errh) + + + +/* ------------------------ OCIInitializeStatementHandle ------------------- */ +/* OCIreateStatementHandle + * Initialize Statement Handle + * + * PARAMETERS + * Input : + * wctx - The + * cursorno - The cursor number for which we need to initialize + * the statement handle + * svch - The OCI Service handle. + * + * Output : + * stmthp - The OCI Statement handle. + * errh - The OCI Error handle. + * + * Return : + * OCI_SUCCESS - Successful completion of the function. + * OCI_ERROR - Error. + * + */ +#define OCIInitializeStatementHandle(wctx, cursorno, svch, stmthp, errh) \ +ociepish(wctx, cursor, svch, stmthp, errh) + + + + +/*--------------------------------------------------------------------------- + PRIVATE TYPES AND CONSTANTS + ---------------------------------------------------------------------------*/ + + +/*--------------------------------------------------------------------------- + PUBLIC FUNCTIONS + ---------------------------------------------------------------------------*/ + + +/*--------------------------------------------------------------------------- + PRIVATE FUNCTIONS + ---------------------------------------------------------------------------*/ + + + +void *ociepacm(OCIExtProcContext *with_context, size_t amount); + + + +size_t ocieperr(OCIExtProcContext *with_context, int error_number); + + + +size_t ociepmsg(OCIExtProcContext *with_context, int error_number, + oratext *error_message, size_t len ); + + + +sword ociepgoe(OCIExtProcContext *with_context, OCIEnv **envh, + OCISvcCtx **svch, OCIError **errh); + + +#endif /* OCIEXTP_ORACLE */ diff --git a/libodbc/include/ora_linux/ocikpr.h b/libodbc/include/ora_linux/ocikpr.h new file mode 100644 index 0000000000..465960d992 --- /dev/null +++ b/libodbc/include/ora_linux/ocikpr.h @@ -0,0 +1,165 @@ +/* Copyright (c) 1991, 2005, Oracle. All rights reserved. */ +/* + NAME + ocikpr.h - header of K & R compilers + MODIFIED (MM/DD/YY) + mbastawa 09/16/05 - dbhygiene + porangas 12/04/00 - Forward merge bug#974710 to 9i + sgollapu 05/19/98 - Change text to OraText + dchatter 04/21/96 - + dchatter 11/10/95 - add ognfd() - get native fd + lchidamb 04/06/95 - drop maxdsz from obindps/odefinps + slari 04/07/95 - add opinit + dchatter 03/08/95 - osetpi and ogetpi + lchidamb 12/09/94 - add obindps() and odefinps() + dchatter 03/06/95 - merge changes from branch 1.1.720.2 + dchatter 11/14/94 - merge changes from branch 1.1.720.1 + dchatter 02/08/95 - olog call; drop onblon + dchatter 10/31/94 - new functions for non-blocking oci + rkooi2 11/27/92 - Changing datatypes (in comments) and return types + rkooi2 10/26/92 - More portability mods + rkooi2 10/18/92 - Changed to agree with oci.c + sjain 03/16/92 - Creation +*/ + +/* + * Declare the OCI functions. + * Prototype information is commented out. + * Use this header for non-ANSI C compilers. + * Note that you will need to include ocidfn.h in the .c files + * to get the definition for cda_def. + */ + +#ifndef OCIKPR +#define OCIKPR + +#include + +/* + * Oci BIND (Piecewise or with Skips) + */ +sword obindps( struct cda_def *cursor, ub1 opcode, OraText *sqlvar, + sb4 sqlvl, ub1 *pvctx, sb4 progvl, + sword ftype, sword scale, + sb2 *indp, ub2 *alen, ub2 *arcode, + sb4 pv_skip, sb4 ind_skip, sb4 alen_skip, sb4 rc_skip, + ub4 maxsiz, ub4 *cursiz, + OraText *fmt, sb4 fmtl, sword fmtt ); +sword obreak( struct cda_def *lda ); +sword ocan ( struct cda_def *cursor ); +sword oclose( struct cda_def *cursor ); +sword ocof ( struct cda_def *lda ); +sword ocom ( struct cda_def *lda ); +sword ocon ( struct cda_def *lda ); + + +/* + * Oci DEFINe (Piecewise or with Skips) + */ +sword odefinps( struct cda_def *cursor, ub1 opcode, sword pos,ub1 *bufctx, + sb4 bufl, sword ftype, sword scale, + sb2 *indp, OraText *fmt, sb4 fmtl, sword fmtt, + ub2 *rlen, ub2 *rcode, + sb4 pv_skip, sb4 ind_skip, sb4 alen_skip, sb4 rc_skip ); +sword odescr( struct cda_def *cursor, sword pos, sb4 *dbsize, + sb2 *dbtype, sb1 *cbuf, sb4 *cbufl, sb4 *dsize, + sb2 *prec, sb2 *scale, sb2 *nullok ); +sword odessp( struct cda_def *cursor, OraText *objnam, size_t onlen, + ub1 *rsv1, size_t rsv1ln, ub1 *rsv2, size_t rsv2ln, + ub2 *ovrld, ub2 *pos, ub2 *level, OraText **argnam, + ub2 *arnlen, ub2 *dtype, ub1 *defsup, ub1* mode, + ub4 *dtsiz, sb2 *prec, sb2 *scale, ub1 *radix, + ub4 *spare, ub4 *arrsiz ); +sword oerhms( struct cda_def *lda, sb2 rcode, OraText *buf, + sword bufsiz ); +sword oermsg( sb2 rcode, OraText *buf ); +sword oexec ( struct cda_def *cursor ); +sword oexfet( struct cda_def *cursor, ub4 nrows, + sword cancel, sword exact ); +sword oexn ( struct cda_def *cursor, sword iters, sword rowoff ); +sword ofen ( struct cda_def *cursor, sword nrows ); +sword ofetch( struct cda_def *cursor ); +sword oflng ( struct cda_def *cursor, sword pos, ub1 *buf, + sb4 bufl, sword dtype, ub4 *retl, sb4 offset ); +sword ogetpi( struct cda_def *cursor, ub1 *piecep, void **ctxpp, + ub4 *iterp, ub4 *indexp ); +sword opinit( ub4 mode ); +sword olog ( struct cda_def *lda, ub1 *hst, + OraText *uid, sword uidl, + OraText *psw, sword pswl, + OraText *conn, sword connl, + ub4 mode ); +sword ologof( struct cda_def *lda ); +sword oopen ( struct cda_def *cursor, struct cda_def *lda, + OraText *dbn, sword dbnl, sword arsize, + OraText *uid, sword uidl ); +sword oopt ( struct cda_def *cursor, sword rbopt, sword waitopt ); +sword oparse( struct cda_def *cursor, OraText *sqlstm, sb4 sqllen, + sword defflg, ub4 lngflg ); +sword orol ( struct cda_def *lda ); +sword osetpi( struct cda_def *cursor, ub1 piece, void *bufp, + ub4 *lenp ); +void sqlld2 ( struct cda_def *lda, OraText *cname, sb4 *cnlen ); +void sqllda ( struct cda_def *lda ); + +/* non-blocking functions */ +sword onbset( struct cda_def *lda ); +sword onbtst( struct cda_def *lda ); +sword onbclr( struct cda_def *lda ); +sword ognfd ( struct cda_def *lda, void *fdp ); + + + +/* + * OBSOLETE FUNCTIONS + */ + +/* + * OBSOLETE BIND CALLS-- use obindps() + */ +sword obndra( struct cda_def *cursor, OraText *sqlvar, sword sqlvl, + ub1 *progv, sword progvl, sword ftype, sword scale, + sb2 *indp, ub2 *alen, ub2 *arcode, ub4 maxsiz, + ub4 *cursiz, OraText *fmt, sword fmtl, sword fmtt ); +sword obndrn( struct cda_def *cursor, sword sqlvn, ub1 *progv, + sword progvl, sword ftype, sword scale, sb2 *indp, + OraText *fmt, sword fmtl, sword fmtt ); +sword obndrv( struct cda_def *cursor, OraText *sqlvar, sword sqlvl, + ub1 *progv, sword progvl, sword ftype, sword scale, + sb2 *indp, OraText *fmt, sword fmtl, sword fmtt ); + +/* + * OBSOLETE DEFINE CALLS-- use odefinps() + */ +sword odefin( struct cda_def *cursor, sword pos, ub1 *buf, + sword bufl, sword ftype, sword scale, sb2 *indp, + OraText *fmt, sword fmtl, sword fmtt, ub2 *rlen, + ub2 *rcode ); + + +/* older calls ; preferred equivalent calls above */ +sword odsc ( struct cda_def *cursor, sword pos, sb2 *dbsize, + sb2 *fsize, sb2 *rcode, sb2 *dtype, sb1 *buf, + sb2 *bufl, sb2 *dsize ); +sword oname ( struct cda_def *cursor, sword pos, sb1 *tbuf, + sb2 *tbufl, sb1 *buf, sb2 *bufl ); +sword olon ( struct cda_def *lda, OraText *uid, sword uidl, + OraText *pswd, sword pswdl, sword audit ); +sword orlon ( struct cda_def *lda, ub1 *hda, OraText *uid, + sword uidl, OraText *pswd, sword pswdl, sword audit ); +sword osql3 ( struct cda_def *cda, OraText *sqlstm, sword sqllen ); + + + + + + + +#endif /* OCIKPR */ + + + + + + + diff --git a/libodbc/include/ora_linux/ocixmldb.h b/libodbc/include/ora_linux/ocixmldb.h new file mode 100644 index 0000000000..3f02085e36 --- /dev/null +++ b/libodbc/include/ora_linux/ocixmldb.h @@ -0,0 +1,135 @@ +/* Copyright (c) 2003, Oracle Corporation. All rights reserved. */ + +/* + NAME + ocixmldb.h - XDB public functions + + DESCRIPTION + This file contains XDB specific public functions required for DOM C-API. + + RELATED DOCUMENTS + + + EXPORT FUNCTION(S) + struct xmlctx *OCIXmlDbInitXmlCtx(OCIEnv *, OCISvcCtx *, OCIError *, + ocixmldbparam *params, int num_params); + + void OCIXmlDbFreeXmlCtx(struct xmlctx *xctx); + + + ------------------------------------------------------------------------ + EXAMPLES + + NOTES + + MODIFIED (MM/DD/YY) + ataracha 12/11/03 - remove redundant definitions + ataracha 05/28/03 - change names + ataracha 02/18/03 - add oratypes, remove XMLERR_* + imacky 02/01/03 - remove xml.h; xdbs fix + ataracha 01/24/03 - use "struct xmlctx" instead of xmlctx + imacky 01/28/03 - fix XMLERR defs + ataracha 01/21/03 - ataracha_uni_capi_cleanup + ataracha 01/09/03 - Creation + +*/ + +#ifndef ORATYPES +#include +#endif + +#ifndef OCI_ORACLE +# include +#endif + +#ifndef OCIXMLDB_ORACLE +# define OCIXMLDB_ORACLE + + +/*--------------------------------------------------------------------------- + PUBLIC TYPES AND CONSTANTS + ---------------------------------------------------------------------------*/ + +#ifndef XMLCTX_DEFINED +# define XMLCTX_DEFINED +/* DATATYPE xmlctx - XML top-level context +*/ +struct xmlctx; typedef struct xmlctx xmlctx; +#endif + +typedef enum +{ + XCTXINIT_OCIDUR = 1, + XCTXINIT_ERRHDL = 2 +} ocixmldbpname; + +typedef struct ocixmldbparam +{ + ocixmldbpname name_ocixmldbparam; + void *value_ocixmldbparam; +} ocixmldbparam; + +#define NUM_OCIXMLDBPARAMS 2 + +/*--------------------------------------------------------------------------- + PRIVATE TYPES AND CONSTANTS + ---------------------------------------------------------------------------*/ + + +/*--------------------------------------------------------------------------- + EXPORT FUNCTIONS + ---------------------------------------------------------------------------*/ +/***************************************************************************** + DESCRIPTION + +-----------------------------OCIXmlDbInitXmlCtx--------------------------------- +Name +OCIXmlDbInitXmlCtx +Purpose +To get a xmlctx structure initialized with error-handler and XDB callbacks. +Syntax +struct xmlctx *OCIXmlDbInitXmlCtx (OCIEnv *envhp, + OCISvcCtx *svchp, + OCIError *err, + params_ocixmldb *params, + int num_params); +Parameters +envhp (IN) - The OCI environment handle +svchp (IN) - The OCI service handle +errhp (IN) - The OCI error handle +params (IN)- This contains the following optional parameters : + (a) OCIDuration dur (IN - The OCI Duration (Default: OCI_DURATION_SESSION) + (b) void (*err_handler) (sword, (const oratext *) (IN) - + Pointer to the error handling function (Default: null) +num_params (IN) - Number of parameters to be read from parameter params. + If the value of num_params exceeds the size of array + "params", unexpected behavior will result. + +Returns +A pointer to xmlctx structure, with xdb context, error handler and callbacks +populated with appropriate values. This is later used for all API calls. NULL +if no database connection available. + +-----------------------------OCIXmlDbFreeXmlCtx---------------------------- +Name +OCIXmlDbFreeXmlCtx +Pupose +To free any allocations done during OCIXmlDbInitXmlCtx. +Syntax +void OCIXmlDbFreeXmlCtx (struct xmlctx *xctx) +Parameters +xctx (IN) - The xmlctx to terminate +Returns +- +******************************************************************************/ + +struct xmlctx *OCIXmlDbInitXmlCtx(OCIEnv *, OCISvcCtx *, OCIError *, + ocixmldbparam *, int); + +void OCIXmlDbFreeXmlCtx(struct xmlctx *xctx); +/*--------------------------------------------------------------------------- + INTERNAL FUNCTIONS + ---------------------------------------------------------------------------*/ + + +#endif /* OCIXMLDB_ORACLE */ diff --git a/libodbc/include/ora_linux/odci.h b/libodbc/include/ora_linux/odci.h new file mode 100644 index 0000000000..cd4bbd6f9b --- /dev/null +++ b/libodbc/include/ora_linux/odci.h @@ -0,0 +1,796 @@ +/* + * + */ + +/* Copyright (c) 1998, 2006, Oracle. All rights reserved. */ + +/* + NAME + odci.h - Oracle Data Cartridge Interface definitions + + DESCRIPTION + This file contains Oracle Data Cartridge Interface definitions. These + include the ODCI Types and Constants. + + RELATED DOCUMENTS + + INSPECTION STATUS + Inspection date: + Inspection status: + Estimated increasing cost defects per page: + Rule sets: + + ACCEPTANCE REVIEW STATUS + Review date: + Review status: + Reviewers: + + PUBLIC FUNCTION(S) + None. + + PRIVATE FUNCTION(S) + None. + + EXAMPLES + + NOTES + - The constants defined here are replica of the constants defined + in ODCIConst Package defined as part of catodci.sql. If you change + these do make the similar change in catodci.sql. + + MODIFIED (MM/DD/YY) + yhu 06/02/06 - add callproperty for statistics + yhu 05/22/06 - add ODCI_NODATA to speed rebuild empty index or ind. + part. + srirkris 05/09/06 - change ODCIOrderByInfo_ind + srirkris 02/06/06 - add definitions for CDI query. + spsundar 02/17/06 - add fields/types for system managed domain idx + yhu 02/08/06 - add RenameCol Na d RenameTopADT + yhu 03/11/05 - add flags for rename column and rename table + spsundar 11/28/05 - add fields/types for composite domain idx + yhu 12/06/05 - mapping table for local text indexes + dmukhin 06/29/05 - ANSI prototypes; miscellaneous cleanup + ayoaz 04/21/03 - add CursorNum to ODCIEnv + abrumm 12/30/02 - Bug #2223225: add define for + ODCI_ARG_DESC_LIST_MAXSIZE + ayoaz 10/14/02 - Add Cardinality to ODCIArgDesc + ayoaz 09/11/02 - add ODCIQueryInfo to ODCIIndexCtx + yhu 09/19/02 - add ODCI_DEBUGGING_ON for ODCIEnv.EnvFlags + hsbedi 10/10/02 - add object number into ODCIExtTableInfo + ayoaz 08/30/02 - add ODCITable2 types + tchorma 07/29/02 - Add ODCIFuncCallInfo type for WITH COLUMN CONTEXT + hsbedi 06/29/02 - External table populate + yhu 07/20/01 - add parallel degree in ODCIIndexInfo. + abrumm 02/20/01 - ODCIExtTableInfo: add AccessParmBlob attribute + abrumm 01/18/01 - ODCIExtTableInfo: add default directory + spsundar 08/24/00 - Update attrbiute positions + abrumm 08/04/00 - external tables changes: ODCIExtTableInfo, constants + tchorma 09/11/00 - Add return code ODCI_FATAL + tchorma 08/08/00 - Add Update Block References Option for Alter Index + ayoaz 08/01/00 - Add ODCI_AGGREGATE_REUSE_CTX + spsundar 06/19/00 - add ODCIEnv type + abrumm 06/27/00 - add defines for ODCIExtTable flags + abrumm 06/04/00 - external tables: ODCIExtTableInfo change; add ODCIEnv + ddas 04/28/00 - extensible optimizer enhancements for 8.2 + yhu 06/05/00 - add a bit in IndexInfoFlags for trans. tblspc + yhu 04/10/00 - add ODCIPartInfo & remove ODCIIndexPartList + abrumm 03/29/00 - external table support + spsundar 02/14/00 - update odci definitions for 8.2 + nagarwal 03/07/99 - bug# 838308 - set estimate_stats=1 + rmurthy 11/09/98 - add blocking flag + ddas 10/31/98 - add ODCI_QUERY_SORT_ASC and ODCI_QUERY_SORT_DESC + ddas 05/26/98 - fix ODCIPredInfo flag bits + rmurthy 06/03/98 - add macro for RegularCall + spsundar 05/08/98 - add constants related to ODCIIndexAlter options + rmurthy 04/30/98 - remove include s.h + rmurthy 04/20/98 - name fixes + rmurthy 04/13/98 - add C mappings for odci types + alsrivas 04/10/98 - adding defines for ODCI_INDEX1 + jsriniva 04/04/98 - Creation + +*/ + +#ifndef OCI_ORACLE +# include +#endif +#ifndef ODCI_ORACLE +# define ODCI_ORACLE + +/*---------------------------------------------------------------------------*/ +/* SHORT NAMES SUPPORT SECTION */ +/*---------------------------------------------------------------------------*/ + +#ifdef SLSHORTNAME + +/* The following are short names that are only supported on IBM mainframes + * with the SLSHORTNAME defined. + * With this all subsequent long names will actually be substituted with + * the short names here + */ + +#define ODCIColInfo_ref odcicir +#define ODCIColInfoList odcicil +#define ODCIColInfoList2 odcicil2 +#define ODCIIndexInfo_ref odciiir +#define ODCIPredInfo_ref odcipir +#define ODCIRidList odcirl +#define ODCIIndexCtx_ref odciicr +#define ODCIObject_ref odcior +#define ODCIObjectList odciol +#define ODCIQueryInfo_ref odciqir +#define ODCIFuncInfo_ref odcifir +#define ODCICost_ref odcicr +#define ODCIArgDesc_ref odciadr +#define ODCIArgDescList odciadl +#define ODCIStatsOptions_ref odcisor +#define ODCIColInfo odcici +#define ODCIColInfo_ind odcicii +#define ODCIIndexInfo odciii +#define ODCIIndexInfo_ind odciiii +#define ODCIPredInfo odcipi +#define ODCIPredInfo_ind odcipii +#define ODCIIndexCtx odciic +#define ODCIIndexCtx_ind odciici +#define ODCIObject odcio +#define ODCIObject_ind odcioi +#define ODCIQueryInfo odciqi +#define ODCIQueryInfo_ind odciqii +#define ODCIFuncInfo odcifi +#define ODCIFuncInfo_infd odcifii +#define ODCICost odcic +#define ODCICost_ind odcici +#define ODCIArgDesc odciad +#define ODCIArgDesc_ind odciadi +#define ODCIStatsOptions odciso +#define ODCIStatsOptions_ind odcisoi +#define ODCIPartInfo odcipti +#define ODCIPartInfo_ind odciptii +#define ODCIPartInfo_ref odciptir +#define ODCIExtTableInfo odcixt +#define ODCIExtTableInfo_ind odcixti +#define ODCIExtTableInfo_ref odcixtr +#define ODCIExtTableQCInfo odcixq +#define ODCIExtTableQCInfo_ind odcixqi +#define ODCIExtTableQCInfo_ref odcixqr +#define ODCIFuncCallInfo odcifc +#define ODCIFuncCall_ind odcifci +#define ODCIFuncCall_ref odcifcr +#define ODCIColValList odcicvl +#define ODCIColArrayList odcical +#define ODCIFilterInfoList odciflil +#define ODCIOrderByInfoList odciobil +#define ODCIFilterInfo_ref odciflir +#define ODCIOrderByInfo_ref odciobir +#define ODCICompQueryInfo_ref odcicqir +#define ODCIFilterInfo odcifli +#define ODCIOrderByInfo odciobi +#define ODCICompQueryInfo odcicqi +#define ODCIFilterInfo_ind odciflii +#define ODCIOrderByInfo_ind odciobii +#define ODCICompQueryInfo_ind odcicqii + +#endif /* SLSHORTNAME */ + +/*--------------------------------------------------------------------------- + PUBLIC TYPES AND CONSTANTS + ---------------------------------------------------------------------------*/ + +/* Constants for Return Status */ +#define ODCI_SUCCESS 0 +#define ODCI_ERROR 1 +#define ODCI_WARNING 2 +#define ODCI_ERROR_CONTINUE 3 +#define ODCI_FATAL 4 + +/* Constants for ODCIPredInfo.Flags */ +#define ODCI_PRED_EXACT_MATCH 0x0001 +#define ODCI_PRED_PREFIX_MATCH 0x0002 +#define ODCI_PRED_INCLUDE_START 0x0004 +#define ODCI_PRED_INCLUDE_STOP 0x0008 +#define ODCI_PRED_OBJECT_FUNC 0x0010 +#define ODCI_PRED_OBJECT_PKG 0x0020 +#define ODCI_PRED_OBJECT_TYPE 0x0040 +#define ODCI_PRED_MULTI_TABLE 0x0080 +#define ODCI_PRED_NOT_EQUAL 0x0100 + +/* Constants for QueryInfo.Flags */ +#define ODCI_QUERY_FIRST_ROWS 0x01 +#define ODCI_QUERY_ALL_ROWS 0x02 +#define ODCI_QUERY_SORT_ASC 0x04 +#define ODCI_QUERY_SORT_DESC 0x08 +#define ODCI_QUERY_BLOCKING 0x10 + +/* Constants for ScnFlg(Func /w Index Context) */ +#define ODCI_CLEANUP_CALL 1 +#define ODCI_REGULAR_CALL 2 + +/* Constants for ODCIFuncInfo.Flags */ +#define ODCI_OBJECT_FUNC 0x01 +#define ODCI_OBJECT_PKG 0x02 +#define ODCI_OBJECT_TYPE 0x04 + +/* Constants for ODCIArgDesc.ArgType */ +#define ODCI_ARG_OTHER 1 +#define ODCI_ARG_COL 2 /* column */ +#define ODCI_ARG_LIT 3 /* literal */ +#define ODCI_ARG_ATTR 4 /* object attribute */ +#define ODCI_ARG_NULL 5 +#define ODCI_ARG_CURSOR 6 + +/* Maximum size of ODCIArgDescList array */ +#define ODCI_ARG_DESC_LIST_MAXSIZE 32767 + +/* Constants for ODCIStatsOptions.Options */ +#define ODCI_PERCENT_OPTION 1 +#define ODCI_ROW_OPTION 2 + +/* Constants for ODCIStatsOptions.Flags */ +#define ODCI_ESTIMATE_STATS 0x01 +#define ODCI_COMPUTE_STATS 0x02 +#define ODCI_VALIDATE 0x04 + +/* Constants for ODCIIndexAlter parameter alter_option */ +#define ODCI_ALTIDX_NONE 0 +#define ODCI_ALTIDX_RENAME 1 +#define ODCI_ALTIDX_REBUILD 2 +#define ODCI_ALTIDX_REBUILD_ONL 3 +#define ODCI_ALTIDX_MODIFY_COL 4 +#define ODCI_ALTIDX_UPDATE_BLOCK_REFS 5 +#define ODCI_ALTIDX_RENAME_COL 6 +#define ODCI_ALTIDX_RENAME_TAB 7 +#define ODCI_ALTIDX_MIGRATE 8 + +/* Constants for ODCIIndexInfo.IndexInfoFlags */ +#define ODCI_INDEX_LOCAL 0x0001 +#define ODCI_INDEX_RANGE_PARTN 0x0002 +#define ODCI_INDEX_HASH_PARTN 0x0004 +#define ODCI_INDEX_ONLINE 0x0008 +#define ODCI_INDEX_PARALLEL 0x0010 +#define ODCI_INDEX_UNUSABLE 0x0020 +#define ODCI_INDEX_ONIOT 0x0040 +#define ODCI_INDEX_TRANS_TBLSPC 0x0080 +#define ODCI_INDEX_FUNCTION_IDX 0x0100 + +/* Constants for ODCIIndexInfo.IndexParaDegree */ +#define ODCI_INDEX_DEFAULT_DEGREE 32767 + +/* Constants for ODCIEnv.EnvFlags */ +#define ODCI_DEBUGGING_ON 0x01 +#define ODCI_NODATA 0x02 + +/* Constants for ODCIEnv.CallProperty */ +#define ODCI_CALL_NONE 0 +#define ODCI_CALL_FIRST 1 +#define ODCI_CALL_INTERMEDIATE 2 +#define ODCI_CALL_FINAL 3 +#define ODCI_CALL_REBUILD_INDEX 4 +#define ODCI_CALL_REBUILD_PMO 5 +#define ODCI_CALL_STATSGLOBAL 6 +#define ODCI_CALL_STATSGLOBALANDPARTITION 7 +#define ODCI_CALL_STATSPARTITION 8 + +/* Constants for ODCIExtTableInfo.OpCode */ +#define ODCI_EXTTABLE_INFO_OPCODE_FETCH 1 +#define ODCI_EXTTABLE_INFO_OPCODE_POPULATE 2 + +/* Constants (bit definitions) for ODCIExtTableInfo.Flag */ + /* sampling type: row or block */ +#define ODCI_EXTTABLE_INFO_FLAG_SAMPLE 0x00000001 +#define ODCI_EXTTABLE_INFO_FLAG_SAMPLE_BLOCK 0x00000002 + /* AccessParmClob, AccessParmBlob discriminator */ +#define ODCI_EXTTABLE_INFO_FLAG_ACCESS_PARM_CLOB 0x00000004 +#define ODCI_EXTTABLE_INFO_FLAG_ACCESS_PARM_BLOB 0x00000008 + +/* Constants for ODCIExtTableInfo.IntraSourceConcurrency */ +#define ODCI_TRUE 1 +#define ODCI_FALSE 0 + +/* Constants (bit definitions) for ODCIExtTable{Open,Fetch,Populate,Close} + * Flag argument. + */ +#define ODCI_EXTTABLE_OPEN_FLAGS_QC 0x00000001 /* caller is Query Coord */ +#define ODCI_EXTTABLE_OPEN_FLAGS_SHADOW 0x00000002 /* caller is shadow proc */ +#define ODCI_EXTTABLE_OPEN_FLAGS_SLAVE 0x00000004 /* caller is slave proc */ + +#define ODCI_EXTTABLE_FETCH_FLAGS_EOS 0x00000001 /* end-of-stream on fetch */ + +/* Constants for Flags argument to ODCIAggregateTerminate */ +#define ODCI_AGGREGATE_REUSE_CTX 1 + +/* Constants for ODCIColInfo.Flags */ +#define ODCI_COMP_FILTERBY_COL 0x0001 +#define ODCI_COMP_ORDERBY_COL 0x0002 +#define ODCI_COMP_ORDERDSC_COL 0x0004 +#define ODCI_COMP_UPDATED_COL 0x0008 +#define ODCI_COMP_RENAMED_COL 0x0010 +#define ODCI_COMP_RENAMED_TOPADT 0x0020 + +/* Constants for ODCIOrderByInfo.ExprType */ +#define ODCI_COLUMN_EXPR 1 +#define ODCI_ANCOP_EXPR 2 + +/* Constants for ODCIOrderByInfo.SortOrder */ +#define ODCI_SORT_ASC 1 +#define ODCI_SORT_DESC 2 +#define ODCI_NULLS_FIRST 4 + +/* Constants for ODCIPartInfo.PartOp */ +#define ODCI_ADD_PARTITION 1 +#define ODCI_DROP_PARTITION 2 + +/*--------------------------------------------------------------------------- + ODCI TYPES + ---------------------------------------------------------------------------*/ +/* + * These are C mappings for the OTS types defined in catodci.sql + */ + +typedef OCIRef ODCIColInfo_ref; +typedef OCIArray ODCIColInfoList; +typedef OCIArray ODCIColInfoList2; +typedef OCIRef ODCIIndexInfo_ref; +typedef OCIRef ODCIPredInfo_ref; +typedef OCIArray ODCIRidList; +typedef OCIRef ODCIIndexCtx_ref; +typedef OCIRef ODCIObject_ref; +typedef OCIArray ODCIObjectList; +typedef OCIRef ODCIQueryInfo_ref; +typedef OCIRef ODCIFuncInfo_ref; +typedef OCIRef ODCICost_ref; +typedef OCIRef ODCIArgDesc_ref; +typedef OCIArray ODCIArgDescList; +typedef OCIRef ODCIStatsOptions_ref; +typedef OCIRef ODCIPartInfo_ref; +typedef OCIRef ODCIEnv_ref; +typedef OCIRef ODCIExtTableInfo_ref; /* external table support */ +typedef OCIArray ODCIGranuleList; /* external table support */ +typedef OCIRef ODCIExtTableQCInfo_ref; /* external table support */ +typedef OCIRef ODCIFuncCallInfo_ref; +typedef OCIArray ODCINumberList; +typedef OCIArray ODCIPartInfoList; +typedef OCIArray ODCIColValList; +typedef OCIArray ODCIColArrayList; +typedef OCIArray ODCIFilterInfoList; +typedef OCIArray ODCIOrderByInfoList; +typedef OCIRef ODCIFilterInfo_ref; +typedef OCIRef ODCIOrderByInfo_ref; +typedef OCIRef ODCICompQueryInfo_ref; + +struct ODCIColInfo +{ + OCIString* TableSchema; + OCIString* TableName; + OCIString* ColName; + OCIString* ColTypName; + OCIString* ColTypSchema; + OCIString* TablePartition; + OCINumber ColFlags; + OCINumber ColOrderPos; + OCINumber TablePartitionIden; + OCINumber TablePartitionTotal; +}; +typedef struct ODCIColInfo ODCIColInfo; + +struct ODCIColInfo_ind +{ + OCIInd atomic; + OCIInd TableSchema; + OCIInd TableName; + OCIInd ColName; + OCIInd ColTypName; + OCIInd ColTypSchema; + OCIInd TablePartition; + OCIInd ColFlags; + OCIInd ColOrderPos; + OCIInd TablePartitionIden; + OCIInd TablePartitionTotal; +}; +typedef struct ODCIColInfo_ind ODCIColInfo_ind; + +struct ODCIFuncCallInfo +{ + struct ODCIColInfo ColInfo; +}; + +struct ODCIFuncCallInfo_ind +{ + struct ODCIColInfo_ind ColInfo; +}; + +struct ODCIIndexInfo +{ + OCIString* IndexSchema; + OCIString* IndexName; + ODCIColInfoList* IndexCols; + OCIString* IndexPartition; + OCINumber IndexInfoFlags; + OCINumber IndexParaDegree; + OCINumber IndexPartitionIden; + OCINumber IndexPartitionTotal; +}; +typedef struct ODCIIndexInfo ODCIIndexInfo; + +struct ODCIIndexInfo_ind +{ + OCIInd atomic; + OCIInd IndexSchema; + OCIInd IndexName; + OCIInd IndexCols; + OCIInd IndexPartition; + OCIInd IndexInfoFlags; + OCIInd IndexParaDegree; + OCIInd IndexPartitionIden; + OCIInd IndexPartitionTotal; +}; +typedef struct ODCIIndexInfo_ind ODCIIndexInfo_ind; + +struct ODCIPredInfo +{ + OCIString* ObjectSchema; + OCIString* ObjectName; + OCIString* MethodName; + OCINumber Flags; +}; +typedef struct ODCIPredInfo ODCIPredInfo; + +struct ODCIPredInfo_ind +{ + OCIInd atomic; + OCIInd ObjectSchema; + OCIInd ObjectName; + OCIInd MethodName; + OCIInd Flags; +}; +typedef struct ODCIPredInfo_ind ODCIPredInfo_ind; + +struct ODCIFilterInfo +{ + ODCIColInfo ColInfo; + OCINumber Flags; + OCIAnyData *strt; + OCIAnyData *stop; +}; +typedef struct ODCIFilterInfo ODCIFilterInfo; + +struct ODCIFilterInfo_ind +{ + OCIInd atomic; + ODCIColInfo_ind ColInfo; + OCIInd Flags; + OCIInd strt; + OCIInd stop; +}; +typedef struct ODCIFilterInfo_ind ODCIFilterInfo_ind; + + +struct ODCIOrderByInfo +{ + OCINumber ExprType; + OCIString *ObjectSchema; + OCIString *TableName; + OCIString *ExprName; + OCINumber SortOrder; +}; +typedef struct ODCIOrderByInfo ODCIOrderByInfo; + +struct ODCIOrderByInfo_ind +{ + OCIInd atomic; + OCIInd ExprType; + OCIInd ObjectSchema; + OCIInd TableName; + OCIInd ExprName; + OCIInd SortOrder; +}; +typedef struct ODCIOrderByInfo_ind ODCIOrderByInfo_ind; + + +struct ODCICompQueryInfo +{ + ODCIFilterInfoList *PredInfo; + ODCIOrderByInfoList *ObyInfo; +}; +typedef struct ODCICompQueryInfo ODCICompQueryInfo; + +struct ODCICompQueryInfo_ind +{ + OCIInd atomic; + OCIInd PredInfo; + OCIInd ObyInfo; +}; +typedef struct ODCICompQueryInfo_ind ODCICompQueryInfo_ind; + + +struct ODCIObject +{ + OCIString* ObjectSchema; + OCIString* ObjectName; +}; +typedef struct ODCIObject ODCIObject; + +struct ODCIObject_ind +{ + OCIInd atomic; + OCIInd ObjectSchema; + OCIInd ObjectName; +}; +typedef struct ODCIObject_ind ODCIObject_ind; + +struct ODCIQueryInfo +{ + OCINumber Flags; + ODCIObjectList* AncOps; + ODCICompQueryInfo CompInfo; +}; +typedef struct ODCIQueryInfo ODCIQueryInfo; + + +struct ODCIQueryInfo_ind +{ + OCIInd atomic; + OCIInd Flags; + OCIInd AncOps; + ODCICompQueryInfo_ind CompInfo; +}; +typedef struct ODCIQueryInfo_ind ODCIQueryInfo_ind; + +struct ODCIIndexCtx +{ + struct ODCIIndexInfo IndexInfo; + OCIString* Rid; + struct ODCIQueryInfo QueryInfo; +}; +typedef struct ODCIIndexCtx ODCIIndexCtx; + +struct ODCIIndexCtx_ind +{ + OCIInd atomic; + struct ODCIIndexInfo_ind IndexInfo; + OCIInd Rid; + struct ODCIQueryInfo_ind QueryInfo; +}; +typedef struct ODCIIndexCtx_ind ODCIIndexCtx_ind; + +struct ODCIFuncInfo +{ + OCIString* ObjectSchema; + OCIString* ObjectName; + OCIString* MethodName; + OCINumber Flags; +}; +typedef struct ODCIFuncInfo ODCIFuncInfo; + +struct ODCIFuncInfo_ind +{ + OCIInd atomic; + OCIInd ObjectSchema; + OCIInd ObjectName; + OCIInd MethodName; + OCIInd Flags; +}; +typedef struct ODCIFuncInfo_ind ODCIFuncInfo_ind; + +struct ODCICost +{ + OCINumber CPUcost; + OCINumber IOcost; + OCINumber NetworkCost; + OCIString* IndexCostInfo; +}; +typedef struct ODCICost ODCICost; + +struct ODCICost_ind +{ + OCIInd atomic; + OCIInd CPUcost; + OCIInd IOcost; + OCIInd NetworkCost; + OCIInd IndexCostInfo; +}; +typedef struct ODCICost_ind ODCICost_ind; + +struct ODCIArgDesc +{ + OCINumber ArgType; + OCIString* TableName; + OCIString* TableSchema; + OCIString* ColName; + OCIString* TablePartitionLower; + OCIString* TablePartitionUpper; + OCINumber Cardinality; +}; +typedef struct ODCIArgDesc ODCIArgDesc; + +struct ODCIArgDesc_ind +{ + OCIInd atomic; + OCIInd ArgType; + OCIInd TableName; + OCIInd TableSchema; + OCIInd ColName; + OCIInd TablePartitionLower; + OCIInd TablePartitionUpper; + OCIInd Cardinality; +}; +typedef struct ODCIArgDesc_ind ODCIArgDesc_ind; + +struct ODCIStatsOptions +{ + OCINumber Sample; + OCINumber Options; + OCINumber Flags; +}; +typedef struct ODCIStatsOptions ODCIStatsOptions; + +struct ODCIStatsOptions_ind +{ + OCIInd atomic; + OCIInd Sample; + OCIInd Options; + OCIInd Flags; +}; +typedef struct ODCIStatsOptions_ind ODCIStatsOptions_ind; + +struct ODCIEnv +{ + OCINumber EnvFlags; + OCINumber CallProperty; + OCINumber DebugLevel; + OCINumber CursorNum; +}; +typedef struct ODCIEnv ODCIEnv; + +struct ODCIEnv_ind +{ + OCIInd _atomic; + OCIInd EnvFlags; + OCIInd CallProperty; + OCIInd DebugLevel; + OCIInd CursorNum; +}; +typedef struct ODCIEnv_ind ODCIEnv_ind; + +struct ODCIPartInfo +{ + OCIString* TablePartition; + OCIString* IndexPartition; + OCINumber IndexPartitionIden; + OCINumber PartOp; +}; +typedef struct ODCIPartInfo ODCIPartInfo; + +struct ODCIPartInfo_ind +{ + OCIInd atomic; + OCIInd TablePartition; + OCIInd IndexPartition; + OCIInd IndexPartitionIden; + OCIInd PartOp; +}; +typedef struct ODCIPartInfo_ind ODCIPartInfo_ind; + +/*---------- External Tables ----------*/ +struct ODCIExtTableInfo +{ + OCIString* TableSchema; + OCIString* TableName; + ODCIColInfoList* RefCols; + OCIClobLocator* AccessParmClob; + OCIBlobLocator* AccessParmBlob; + ODCIArgDescList* Locations; + ODCIArgDescList* Directories; + OCIString* DefaultDirectory; + OCIString* DriverType; + OCINumber OpCode; + OCINumber AgentNum; + OCINumber GranuleSize; + OCINumber Flag; + OCINumber SamplePercent; + OCINumber MaxDoP; + OCIRaw* SharedBuf; + OCIString* MTableName; + OCIString* MTableSchema; + OCINumber TableObjNo; +}; +typedef struct ODCIExtTableInfo ODCIExtTableInfo; + +struct ODCIExtTableInfo_ind +{ + OCIInd _atomic; + OCIInd TableSchema; + OCIInd TableName; + OCIInd RefCols; + OCIInd AccessParmClob; + OCIInd AccessParmBlob; + OCIInd Locations; + OCIInd Directories; + OCIInd DefaultDirectory; + OCIInd DriverType; + OCIInd OpCode; + OCIInd AgentNum; + OCIInd GranuleSize; + OCIInd Flag; + OCIInd SamplePercent; + OCIInd MaxDoP; + OCIInd SharedBuf; + OCIInd MTableName; + OCIInd MTableSchema; + OCIInd TableObjNo; +}; +typedef struct ODCIExtTableInfo_ind ODCIExtTableInfo_ind; + +struct ODCIExtTableQCInfo +{ + OCINumber NumGranules; + OCINumber NumLocations; + ODCIGranuleList* GranuleInfo; + OCINumber IntraSourceConcurrency; + OCINumber MaxDoP; + OCIRaw* SharedBuf; +}; +typedef struct ODCIExtTableQCInfo ODCIExtTableQCInfo; + +struct ODCIExtTableQCInfo_ind +{ + OCIInd _atomic; + OCIInd NumGranules; + OCIInd NumLocations; + OCIInd GranuleInfo; + OCIInd IntraSourceConcurrency; + OCIInd MaxDoP; + OCIInd SharedBuf; +}; +typedef struct ODCIExtTableQCInfo_ind ODCIExtTableQCInfo_ind; + +/*********************************************************/ +/* Table Function Info types (used by ODCITablePrepare) */ +/*********************************************************/ + +struct ODCITabFuncInfo +{ + ODCINumberList* Attrs; + OCIType* RetType; +}; +typedef struct ODCITabFuncInfo ODCITabFuncInfo; + +struct ODCITabFuncInfo_ind +{ + OCIInd _atomic; + OCIInd Attrs; + OCIInd RetType; +}; +typedef struct ODCITabFuncInfo_ind ODCITabFuncInfo_ind; + +/*********************************************************************/ +/* Table Function Statistics types (used by ODCIStatsTableFunction) */ +/*********************************************************************/ + +struct ODCITabFuncStats +{ + OCINumber num_rows; +}; +typedef struct ODCITabFuncStats ODCITabFuncStats; + +struct ODCITabFuncStats_ind +{ + OCIInd _atomic; + OCIInd num_rows; +}; +typedef struct ODCITabFuncStats_ind ODCITabFuncStats_ind; + +/*--------------------------------------------------------------------------- + PRIVATE TYPES AND CONSTANTS + ---------------------------------------------------------------------------*/ + + +/*--------------------------------------------------------------------------- + PUBLIC FUNCTIONS + ---------------------------------------------------------------------------*/ + + +/*--------------------------------------------------------------------------- + PRIVATE FUNCTIONS + ---------------------------------------------------------------------------*/ + + +#endif /* ODCI_ORACLE */ diff --git a/libodbc/include/ora_linux/oratypes.h b/libodbc/include/ora_linux/oratypes.h new file mode 100644 index 0000000000..0faa306ea9 --- /dev/null +++ b/libodbc/include/ora_linux/oratypes.h @@ -0,0 +1,285 @@ +/* $RCSfile: oratypes.h,v $ $Date: 20-jul-00.13:44:19 + ---------------------------------------------------------------------- + Copyright (c) 1982, 2003, Oracle. All rights reserved. + ---------------------------------------------------------------------- */ + +#ifndef ORATYPES +# define ORATYPES +# define SX_ORACLE +# define SX3_ORACLE + +#ifndef ORASTDDEF +# include +# define ORASTDDEF +#endif + +#ifndef ORALIMITS +# include +# define ORALIMITS +#endif + +#ifndef TRUE +# define TRUE 1 +# define FALSE 0 +#endif + +/* --- Signed/Unsigned one-byte scalar (sb1/ub1) --- */ + +#ifndef lint + typedef unsigned char ub1; + typedef signed char sb1; + typedef char eb1; +#else +# define ub1 unsigned char +# define sb1 signed char +# define eb1 char +#endif + +#define UB1MAXVAL ((ub1)UCHAR_MAX) +#define UB1MINVAL ((ub1) 0) +#define SB1MAXVAL ((sb1)SCHAR_MAX) +#define SB1MINVAL ((sb1)SCHAR_MIN) + +#define MINUB1MAXVAL ((ub1) 255) +#define MAXUB1MINVAL ((ub1) 0) +#define MINSB1MAXVAL ((sb1) 127) +#define MAXSB1MINVAL ((sb1) -127) + +#define EB1MAXVAL ((eb1)SCHAR_MAX) +#define EB1MINVAL ((eb1) 0) + +#define MINEB1MAXVAL ((eb1) 127) +#define MAXEB1MINVAL ((eb1) 0) + +#define UB1BITS CHAR_BIT +#define UB1MASK ((1 << ((uword)CHAR_BIT)) - 1) + +/* backwards compatibility */ + +#ifndef lint + typedef sb1 b1; +#else +# define b1 sb1 +#endif + +#define B1MAXVAL SB1MAXVAL +#define B1MINVAL SB1MINVAL + +/* --- Signed/Unsigned two-byte scalar (sb2/ub2) --- */ + +#ifndef lint + typedef unsigned short ub2; + typedef signed short sb2; + typedef short eb2; +#else +# define ub2 unsigned short +# define sb2 signed short +# define eb2 short +#endif + +#define UB2MAXVAL ((ub2)USHRT_MAX) +#define UB2MINVAL ((ub2) 0) +#define SB2MAXVAL ((sb2) SHRT_MAX) +#define SB2MINVAL ((sb2) SHRT_MIN) + +#define MINUB2MAXVAL ((ub2) 65535) +#define MAXUB2MINVAL ((ub2) 0) +#define MINSB2MAXVAL ((sb2) 32767) +#define MAXSB2MINVAL ((sb2)-32767) + +#define EB2MAXVAL ((eb2) SHRT_MAX) +#define EB2MINVAL ((eb2) 0) + +#define MINEB2MAXVAL ((eb2) 32767) +#define MAXEB2MINVAL ((eb2) 0) + +/* backwards compatibility */ + +#ifndef lint + typedef sb2 b2; +#else +# define b2 sb2 +#endif + +#define B2MAXVAL SB2MAXVAL +#define B2MINVAL SB2MINVAL + +/* --- Signed/Unsigned four-byte scalar (sb4/ub4) --- */ + +#ifndef lint + typedef unsigned int ub4; + typedef signed int sb4; + typedef int eb4; +#else +# define ub4 unsigned int +# define sb4 signed int +# define eb4 int +#endif + +#define UB4MAXVAL ((ub4)UINT_MAX) +#define UB4MINVAL ((ub4) 0) +#define SB4MAXVAL ((sb4) INT_MAX) +#define SB4MINVAL ((sb4) INT_MIN) + +#define MINUB4MAXVAL ((ub4) 4294967295) +#define MAXUB4MINVAL ((ub4) 0) +#define MINSB4MAXVAL ((sb4) 2147483647) +#define MAXSB4MINVAL ((sb4)-2147483647) + +#define EB4MAXVAL ((eb4) INT_MAX) +#define EB4MINVAL ((eb4) 0) + +#define MINEB4MAXVAL ((eb4) 2147483647) +#define MAXEB4MINVAL ((eb4) 0) + +/* --- Signed/Unsigned eight-byte scalar (orasb8/oraub8) --- */ + +#define ORAXB8_DEFINED +#ifdef _LP64 + typedef unsigned long oraub8; + typedef signed long orasb8; +#else + typedef unsigned long long oraub8; + typedef signed long long orasb8; +#endif /* _LP64 */ + +typedef oraub8 ub8; +typedef orasb8 sb8; + +# define ORAUB8MINVAL ((oraub8)0) +# define ORAUB8MAXVAL ((oraub8)18446744073709551615) +# define ORASB8MINVAL ((orasb8)-9223372036854775808) +# define ORASB8MAXVAL ((orasb8) 9223372036854775807) + +# define MAXORAUB8MINVAL ((oraub8)0) +# define MINORAUB8MAXVAL ((oraub8)18446744073709551615) +# define MAXORASB8MINVAL ((orasb8)-9223372036854775807) +# define MINORASB8MAXVAL ((orasb8) 9223372036854775807) + +/* backwards compatibility */ + +#ifndef lint + typedef sb4 b4; +#else +# define b4 sb4 +#endif + +#define B4MAXVAL SB4MAXVAL +#define B4MINVAL SB4MINVAL + +/* --- Character pointer --- */ + +#ifdef lint +# define oratext unsigned char +#else + typedef unsigned char oratext; +#endif + +#if !defined(LUSEMFC) +# ifdef lint +# define text unsigned char +# define OraText oratext +# else + typedef oratext text; + typedef oratext OraText; +# endif +#endif + +#if !defined(MOTIF) && !defined(LISPL) && !defined(__cplusplus) && \ + !defined(LUSEMFC) + typedef OraText *string; +#endif + +#ifndef lint + typedef unsigned short utext; +#else +# define utext unsigned short +#endif + +/* --- Boolean --- */ + +#ifndef boolean +# ifndef lint + typedef int boolean; +# else +# define boolean int +# endif +#endif + +/* --- Other data types --- */ + +#ifndef lint + typedef int eword; + typedef unsigned int uword; + typedef signed int sword; +#else +# define eword int +# define uword unsigned int +# define sword signed int +#endif + +#define EWORDMAXVAL ((eword) INT_MAX) +#define EWORDMINVAL ((eword) 0) + +#define UWORDMAXVAL ((uword)UINT_MAX) +#define UWORDMINVAL ((uword) 0) + +#define SWORDMAXVAL ((sword) INT_MAX) +#define SWORDMINVAL ((sword) INT_MIN) + +#define MINEWORDMAXVAL ((eword) 2147483647) +#define MAXEWORDMINVAL ((eword) 0) + +#define MINUWORDMAXVAL ((uword) 4294967295) +#define MAXUWORDMINVAL ((uword) 0) + +#define MINSWORDMAXVAL ((sword) 2147483647) +#define MAXSWORDMINVAL ((sword) -2147483647) + +#ifndef lint + typedef unsigned long ubig_ora; + typedef signed long sbig_ora; +#else +# define ubig_ora unsigned long +# define sbig_ora signed long +#endif + +#define UBIG_ORAMAXVAL ((ubig_ora)ULONG_MAX) +#define UBIG_ORAMINVAL ((ubig_ora) 0) + +#define SBIG_ORAMAXVAL ((sbig_ora) LONG_MAX) +#define SBIG_ORAMINVAL ((sbig_ora) LONG_MIN) + +#define MINUBIG_ORAMAXVAL ((ubig_ora) 4294967295) +#define MAXUBIG_ORAMINVAL ((ubig_ora) 0) + +#define MINSBIG_ORAMAXVAL ((sbig_ora) 2147483647) +#define MAXSBIG_ORAMINVAL ((sbig_ora)-2147483647) + +#define UBIGORABITS (UB1BITS * sizeof(ubig_ora)) + +/* --- Const --- */ + +#undef CONST +#define CONST const + +/* --- Misc --- */ + +#define dvoid void + +typedef void (*lgenfp_t)( void ); + +#ifndef ORASYS_TYPES +# include +# define ORASYS_TYPES +#endif + +#ifndef SIZE_TMAXVAL +# define SIZE_TMAXVAL UBIG_ORAMAXVAL +#endif + +#ifndef MINSIZE_TMAXVAL +# define MINSIZE_TMAXVAL (size_t)4294967295 +#endif + +#endif /* ORATYPES */ diff --git a/libodbc/include/ora_linux/ori.h b/libodbc/include/ora_linux/ori.h new file mode 100644 index 0000000000..d291f150e1 --- /dev/null +++ b/libodbc/include/ora_linux/ori.h @@ -0,0 +1,2095 @@ +/* Copyright (c) 1994, 2006, Oracle. All rights reserved. */ + +/* + NAME + ORI - OCI navigational interface + + DESCRIPTION + + This section is intended to give a brief introduction to the navigational + interfaces. Readers can refer to the documents listed in the section + 'RELATED DOCUMENTS' for more information. + + PURPOSE + The Oracle Call Interface (OCI) supports navigational access of objects. + In the navigational paradigm, data is represented as a graph of objects + connected by references. Objects in the graph are reached by following + the references. + + OBJECT ENVIRONMENT + + The object environment is initialized when the OCI environment handle is + initialized with the object option. An object environment contains a + heap which buffers type instances in memory. The object environment also + contains an object cache which keeps track of the objects in the object + environment. Readers can refer to the "Functional Specification for + Programmatic Interface" for more information about the object + environment. + + INSTANCE, OBJECT AND VALUE + + An OTS instance is an occurence of a type specified by the Oracle Type + System (OTS). This section describes how an OTS instance can be + represented in OCI. In OCI, an OTS instance can be classified based on + the type, the lifetime and referencability (see the figure below): + + 1) A persistent object is an instance of an object type. A persistent + object resides in a row of a table in the server and can exist longer + than the duration of a session (connection). Persistent objects can be + identified by object references which contain the object identifiers. + A persistent object is obtained by pinning its object reference. + + 2) A transient object is an instance of an object type. A transient + object cannot exist longer than the duration of a session, and it is + used to contain temporary computing results. Transient objects can + also be identified by references which contain transient object + identifiers. + + 3) A value is an instance of an user-defined type (object type or + collection type) or any built-in OTS type. Unlike objects, values of + object types are identified by memory pointers, rather than by + references. + + A value can be standalone or embbeded. A standalone value is usually + obtained by issuing a select statement. OCI also allows the client + program to select a row of object table into a value by issuing a SQL + statement. Thus, a referenceable object (in the database) can be + represented as a value (which cannot be identified by a reference). + A standalone value can also be an out-of-line attribute in an object + (e.g varchar, raw) or an out-of-line element in a collection (e.g. + varchar, raw, object). + + An embedded value is phyiscally included in a containing instance. + An embedded value can be an in-line attribute in an object (e.g. + number, nested object) or an in-line element in a collection. + + All values are considered to be transient by OCI, e.g. OCI does not + support automatic flushing a value to the database, and the client has + to explicitly execute a SQL statement to store a value into the + database. For embedded values, they are flushed when their containing + instance are flushed. + + + OTS instance + | | + v v + object value (type) + | | + v v + persistent transient (lifetime) + + + persistent obj transient obj value + --------------------------------------------------------------- + | | | | object type, | + | type | object type | object type | built-in, | + | | | | collection | + --------------------------------------------------------------- + | maximum | until object | session | session | + | lifetime | is deleted | | | + --------------------------------------------------------------- + | referencable | yes | yes | no | + --------------------------------------------------------------- + | embeddable | no | no | yes | + --------------------------------------------------------------- + + REFERENCEABLE OBJECT, STANDALONE OBJECT, EMBEDDED OBJECT + + In the reminding of this include file, the following term will be used: + 1) The term 'object' can be generally referred to a persistent object, + a transient object, a standalone value of object type, or an embedded + value of object type. + 2) The term 'referenceable object' refers to a persistent object or a + transient object. + 3) The term 'standalone object' refers to a persistent object, a + transient object or a standalone value of object type. + 4) The term 'embedded object' referes to a embbeded value of object + type. + + META ATTRIBUTES + + There is a set of meta-attributes that are defined for standalone + objects. A meta-attribute can be transient or persistent. A + transient meta-attribute is applicable to an instance only when it is + in memory. A persistent meta-attribute can be applicable to an instance + that is in the disk. + + The set of user visible meta-attributes for persistent objects are: + 1) existent (persistent) : Does the object exist? + 2) nullness (persistent) : Null information of the instance + 3) locked (persistent) : Is the object locked? + 4) pinned (transient) : Is the object being accessed by the client? + 5) dirty (transient) : Has the object been modified? + 6) allocation duration (transient) : see below + 7) pin duration (transient) : see below + + The set of user visible meta-attributes for transient objects are: + 1) existent (transient) : Does the object exist? + 2) nullness (transient) : Null information of the instance + 3) pinned (transient) : Is the object being accessed by the client? + 4) dirty (transient) : Has the object been modified? + 4) allocation duration (transient) : see below + 5) pin duration (transient) : see below + + The set of user visible meta-attributes for standalone values of object + type or collections are: + 1) allocation duration (transient) : see below + 2) nullness (transient) : Null information of the instance + (of an object type) + + NULLNESS OF AN INSTANCE + + Each standalone object is associated with a null structure which keeps + the null information about the object. A null indicates the absence of + data. The null structure itself contains null indicators that represent: + 1) atomic nullness : a null value that pertains to the whole object + 2) null status of the individual attribute in the object + + The layout of a null structure in memory resembles that of the object, + except that the null structure has additional indicators to represent + the atomic nullness for each object. + + An non-existent object is different than an object that is atomically + null. A atomically null object is an existing object that has no data. + + MEMORY LAYOUT OF AN OBJECT + + A standalone object in memory is composed of a top level memory chunk, + a null structure and optionally, a number of secondary memory chunks. + For a DEPARTMENT object type, + + OBJECT TYPE department + { + dep_name varchar2(20), + budget number, + manager person, /o person is an object type o/ + employees collection of person + } + + Each instance of DEPARTMENT will has a top level memory chunk which + contains the top level attributes such as dep_name, budget, manager and + employees. The attributes dep_name and employees are themselves pointers + to the additional memory (the secondary memory chunks). The secondary + memory is for the out-of-line attribute (e.g. varray). + + CONSISTENCY MODEL + + Each pin operation behaves like a distinct SQL select. Thus, the object + cache does not guarantee consistency for a graph of objects. In order to + retrieve a consistent graph of objects, the user has to explicitly start + a serializable transaction or a read-only transaction. + + DURATION + In OCI, a duration is used to specify + + 1) the length of memory allocation of an instance + When each instance is allocated, it is associate with an allocation + duration. The memory occupied by the object is freed automatically + at the end of its allocation duration. The allocation duration of an + instance cannot be changed. + + 2) the length of pinning of an object + When each object is pinned, the client has to give a pin duration + which specify the length of time that the object is intended to be + used. It is an user error to specify a pin duration longer than an + allocation duration of the object. An object is completely unpinned + at the end of its pin duration (see OCIObjectUnpin()). + + An OCI program can use the allocation duration and the pin duration to + automatically free the memory of the instances: + 1) Transient objects and values are freed at the end of the allocation + duration. + 2) Persistent objects ARE freed at the end of the allocation duration. + Persistent objects CAN be freed at the end of the pin duration when + the objects are completely unpinned. The persistent objects are said + to be aged out. See OCIObjectUnpin() for more details. + + There are 3 predefined duration: session, transaction, call. The time + spans of these durations are defined based on the programming model + presented by OCI. The call duration is mapped to the transaction + duration in the client-side environment. See oro.h for the macros defined + for these 3 durations. + + A pin duration can be promoted. For example, if an object is pinned with + duration 1, and the object is later pinned with duration 2, the pin + routine will try to find a duration that is longer or equal to the + length of both duration 1 and duration 2. The pin duration of the object + is set to the that duration. The object is automatically unpinned only + after both duration 1 and duration 2 are terminated. + + RELATED DOCUMENTS + "Functional Specification for Oracle Object RDBMS" + "Functional Specification for Programmatic Interfaces" + "Functional Specification for the Oracle Type System (OTS)" + + INSPECTION STATUS + Inspection date: + Inspection status: + Estimated increasing cost defects per page: + Rule sets: + + ACCEPTANCE REVIEW STATUS + Review date: + Review status: + Reviewers: + + PUBLIC FUNCTIONS + OCIObjectNew - OCI new a standalone instance + OCIObjectPin - OCI pin an object by reference + OCIObjectUnpin - OCI unpin a referenceable object + OCIObjectPinCountReset - OCI reset the pin count of a referenceable object + OCIObjectLock - OCI lock a persistent object + OCIObjectLockNoWait - OCI lock a persistent object + OCIObjectMarkUpdate - OCI mark a referenceable object as updated + OCIObjectUnmark - OCI unmark a dirtied referenceable object + OCIObjectUnmarkByRef - OCI unmark a dirtied object by reference + OCIObjectFree - OCI free a standalone instance + OCIObjectMarkDelete - OCI mark a referenceable object as deleted + OCIObjectMarkDeleteByRef - OCI mark a referenceable object as deleted by + giving a reference + OCIObjectFlush - OCI flush a persistent object + OCIObjectRefresh - OCI refresh a persistent object + OCIObjectCopy - OCI CoPy one object to another + OCIObjectGetTypeRef - OCI get the Type Reference of a standalone object + OCIObjectGetObjectRef - OCI get the Object's Reference + OCIObjectGetInd - OCI get Null Structure of an standalone object + OCIObjectExists - OCI get the existence of a referenceable object + OCIObjectGetProperty - get object property + OCIObjectIsLocked - OCI get the lock status of a referenceable object + OCIObjectIsDirty - OCI get the dirty status of a referenceable object + OCIObjectPinTable - OCI get Table object + OCIObjectArrayPin - OCI pin array of objects + OCIObjectGetPrimayKeyTypeRef - OCI get the Ref for the primary key OID's + type + OCIObjectMakeObjectRef - OCI Create a pk or sys generated REF + + OCIObjectGetNewOID - OCI Create a new Object ID + + OCICacheFlush - OCI flsuh the modified persistent objects in the cache + OCICacheRefresh - OCI refresh persistent objects in the cache + OCICacheUnpin - OCI unpin referenceable objects in the cache + OCICacheFree - OCI free all instances in the environment + OCICacheUnmark - OCI unmark all dirty referenceable objects in the cache + + PRIVATE FUNCTIONS + None + + EXAMPLES + + The following types will be used in the examples in this section: + + OBJECT TYPE professor + ( + varchar2 name; + number department; + number num_of_students; + ); + + OBJECT TYPE course + ( + varchar2 name; + number grade; + ); + + OBJECT TYPE student + ( + vstring name; + number department; + ref advisor; /o advisor is a professor o/ + collection courses; + ); + + EXAMPLE 1 + + Here is a set of examples to illustrate the usages of some of the + orio and oric functions. + + OCIenv *env; /o OCI environment handle o/ + OCIError *err; /o OCI error handle o/ + OCISvcCtx *svc; /o OCI service handle o/ + + void *stu_tbl; /o pointer to the student table o/ + OCIType *stu_tdo; /o student type tdo o/ + + OCIRef *stu2_ref; /o object reference to student object o/ + student *stu1; /o pointer to the student object o/ + student *stu2; /o pointer to the student object o/ + professor *pro; /o pointer to the professor object o/ + + /o Initialize the OCI environment handle, error handle and service + handle and login to the database o/ + ... + + /o CREATE A PERSISTENT OBJECT o/ + + /o get the table object of student o/ + if (OCIObjectPinTable(env, err, svc, "ORACLEU", sizeof("ORACLEU"), + "STUDENT_TABLE", sizeof("STUDENT_TABLE"), (OCIRef *)0, + OCI_DURATION_NULL, &stu_tbl) != OCI_SUCCESS) + /o error handling code o/ + + /o get type object of student o/ + if (OCITypeByName(env, err, svc, "ORACLEU", sizeof("ORACLEU"), + "STUDENT", sizeof("STUDENT"), OCI_DURATION_NULL, OCI_TYPEGET_HEADER, + &stu_tdo) != OCI_SUCCESS) + /o error handling code o/ + + /o create a persistent object 'mark' (of type student) o/ + if (OCIObjectNew(env, err, svc, OCI_TYPECODE_ADT, stu_tdo, stu_tbl, + OCI_DURATION_TRANS, (ub1)FALSE, (void **)&stu1) != OCI_SUCCESS) + /o error handling code o/ + + /o RETRIEVE OBJECTS IN PERSISTENT STORES o/ + + /o Use OCI to retrieve a reference to student object 'joe'. + o The retrieved reference is bound to the variable stu2_ref. + o/ + + /o pin/retrieve the student "joe" by reference o/ + if (OCIObjectPin(env, err, &stu2_ref, (OCIComplexObject *)0, OCI_PIN_ANY, + OCI_DURATION_TRANS, OCI_LOCK_X, &stu2) != OCI_SUCCESS) + /o error handling code o/ + + /o pin/retrieve the advisor of student "joe" by reference o/ + if (OCIObjectPin(env, err, &stu2->advisor, (OCIComplexObject *)0, + OCI_PIN_ANY, OCI_DURATION_TRANS, OCI_LOCK_X, &pro) != OCI_SUCCESS) + /o error handling code o/ + + /o MODIFY OBJECTS o/ + + /o initialize the newly created object "mark" o/ + DISCARD OCIStringAssignText(env, err, "mark", sizeof("mark"), + &stu1->name); + department = 522; + DISCARD OCINumberFromInt(err, &department, sizeof(department), + OCI_NUMBER_UNSIGNED, &stu1->department); + + /o assign advisor to student "mark" o/ + DISCARD OCIRefAssign(env, err, &stu2->advisor, &stu1->advisor); + + /o update student "joe". o/ + department = 533; + DISCARD OCINumberFromInt(err, &department, sizeof(department), + OCI_NUMBER_UNSIGNED, &stu2->department); + DISCARD OCIObjectMarkUpdate(env, err, stu2); + + /o UNPIN OBJECTS AFTER FINSIHED PROCESSING THEM o/ + + /o unpin the student object "mark" o/ + if (OCIObjectUnpin(env, err, stu1) != OCI_SUCCESS) + /o error handling code o/ + + /o unpin the student object "joe" o/ + if (OCIObjectUnpin(env, err, stu2) != OCI_SUCCESS) + /o error handling code o/ + + /o unpin the professor object o/ + if (OCIObjectUnpin(env, err, pro) != OCI_SUCCESS) + /o error handling code o/ + + /o unpin the type object o/ + if (OCIObjectUnpin(env, err, stu_tdo) != OCI_SUCCESS) + /o error handling code o/ + + /o unpin the table object o/ + if (OCIObjectUnpin(env, err, stu_tbl) != OCI_SUCCESS) + /o error handling code o/ + + /o FLUSH MODIFIED OBJECTS BACK TO PERSISTENT STORE o/ + + if (OCICacheFlush(env, err, svc, (void *)0, ((OCIRef*)(*)())0, + (OCIRef *)0) != OCI_SUCCESS) + /o error handling code o/ + + /o commit transaction o/ + + END OF EXAMPLE 1 + + NOTES + This file has been subsetted to contain only the routines that will + be in the first release. + + MODIFIED + dmukhin 06/29/05 - ANSI prototypes; miscellaneous cleanup + srseshad 03/12/03 - convert oci public api to ansi + aahluwal 06/03/02 - bug 2360115 + bpalaval 02/09/01 - Change text to oratext. + rkasamse 06/21/00 - add ociobjectgetnewoid + rkasamse 05/24/00 - add OCIObjectSetData + whe 09/01/99 - 976457:check __cplusplus for C++ code + smuralid 10/29/98 - add comments for OCIObjectMakeObjectRef + mkrishna 08/19/98 - change OCIGetPkTypeRef to OCIObjectGetPrimaryKeyTypeR + mkrishna 08/10/98 - add OCIObjectMakeObjectRef & OCIObjectGetPkTypeRef + rkasamse 06/22/98 - add comments for OCIDurationBegin(End) + pmitra 04/01/98 - OCIObjectLockNoWait added + pmitra 11/05/97 - [573769] OCIObjectArrayPin pos parameter cannot be NU + cxcheng 07/29/97 - fix compile for short names + skrishna 07/14/97 - add OCIObjectGetProperty + skrishna 04/30/97 - OCIObjectFlushRefresh: remove duplicate declaration + skrishna 04/24/97 - flag unsupported functions + sthakur 03/20/97 - modify flag argument to OCIObjectFree + skrishna 03/18/97 - fix ifdef for supporting ansi and k&r proto-types + cxcheng 02/19/97 - remove short names support + cxcheng 02/06/97 - take out short name support except with SLSHORTNAME + sthakur 12/20/96 - fix a typepo in OCIOBjectArrayPin + jboonleu 11/07/96 - modify comments + cxcheng 10/28/96 - more beautification changes + jboonleu 10/24/96 - add flag to OCIObjectFree + jboonleu 10/22/96 - change interface of OCICacheFlush + cxcheng 10/18/96 - rename OCIObjectPinArray to OCIObjectArrayPin + cxcheng 10/14/96 - more renaming of types + jboonleu 10/09/96 - add new interfaces + cxcheng 10/09/96 - more lint fixes + cxcheng 10/08/96 - more lint fixes + jboonleu 09/27/96 - fix lint errors + jboonleu 10/07/96 - beautify ori.h after conversion to long names + cxcheng 10/04/96 - replace short names with long names + sthakur 08/20/96 - add COR context to OCIObjectPin + mluong 07/17/96 - add back orioglk, oriogdr, oriogiv, and oriocur. + jboonleu 07/17/96 - rename refresh option to conherency option + jboonleu 07/16/96 - change comment for cache consistency + jwijaya 07/03/96 - add ANSI prototypes + jboonleu 06/12/96 - update comment + jboonleu 05/08/96 - change description of OCIDurationGetParent + jboonleu 05/01/96 - add OROOCOSFN + skrishna 04/08/96 - change ori*() to take OCIEnv* and OCIError* instead + of oroenv* + jboonleu 01/04/96 - interface change + jboonleu 10/24/95 - support of variable ref + jboonleu 02/15/95 - new interface + sthakur 01/05/95 - pass username to origrgc + skotsovo 12/07/94 - update example + jwijaya 11/15/94 - rename ORONSPTAB to ORONSPEXT + jwijaya 10/06/94 - add namespace to oriopnm() + jwijaya 10/02/94 - connection handle -> connection number + jboonleu 08/16/94 - fix lint errors + jboonleu 07/20/94 - change interface of OCICacheFlush + tanguyen 07/18/94 - add oriocpe, change OCIObjectCopy to oriocps + tcheng 07/15/94 - add init param maximum_sga_heap_size + tcheng 07/13/94 - change origini to get param string + jboonleu 07/05/94 - change sccs string from sccid to a comment + jboonleu 07/01/94 - Add examples to ORIO* and ORIC* functions + tanguyen 06/30/94 - Fix the ORI_ORACLE ifdef + skotsovo 06/27/94 - include all public functions in public functions + list at top of header file + tcheng 06/27/94 - modify comments according to new template + tanguyen 06/24/94 - fix comments for OCIObjectCopy + tcheng 06/24/94 - fix comments in origrgc() + tanguyen 06/21/94 - fix comments and format + tcheng 06/20/94 - commenting origini/trm/err/rgc/urg() functions + tanguyen 06/16/94 - fix descriptions of ref operations + tanguyen 06/16/94 - clarifies refs comparison + tanguyen 05/12/94 - adds more interfaces (OCIObjectMarkUpdate) + jwijaya 05/10/94 - fix examples, add origurg, change origcon to origrgc + tanguyen 05/03/94 - remove unnecessary 'type' argument from + 'OCIObjectCopy' + tanguyen 03/08/94 - clarifies comments + jwijaya 02/16/94 - more questions + jwijaya 02/11/94 - more comments + jwijaya 02/10/94 - identify optional arguments + jwijaya 02/07/94 - Creation +*/ + + +#ifndef ORATYPES +#include +#endif +#ifndef ORO_ORACLE +#include +#endif +#ifndef OCI_ORACLE +#include +#endif +#ifndef ORT_ORACLE +#include +#endif + +#ifndef ORI_ORACLE +#define ORI_ORACLE + +/*---------------------------------------------------------------------------*/ +/* SHORT NAMES SUPPORT SECTION */ +/*---------------------------------------------------------------------------*/ + +#ifdef SLSHORTNAME + +/* the following are short names that are only supported on IBM mainframes + with the SLSHORTNAME defined. + With this all subsequent long names will actually be substituted with + the short names here */ + +#define OCIDurationBegin origbgu +#define OCIDurationEnd origedu +#define OCIDurationGetParent origpdr +#define OCICacheFlushRefresh oricfrh +#define OCICacheUnpin oricunp +#define OCICacheFree oricfre +#define OCICacheUnmark oricumk +#define OCICacheGetObjects oricgpr +#define OCICacheRegister oricscb +#define OCIObjectUnpin oriounp +#define OCIObjectPinCountReset orioupz +#define OCIObjectLock oriolck +#define OCIObjectLockNoWait oriolnw +#define OCIObjectMarkUpdate orioupd +#define OCIObjectUnmark orioumk +#define OCIObjectUnmarkByRef orioumr +#define OCIObjectAlwaysLatest oriomkl +#define OCIObjectNotAlwaysLatest oriouml +#define OCIObjectMarkDeleteByRef oriordl +#define OCIObjectMarkDelete oriopdl +#define OCIObjectFlush oriofls +#define OCIObjectFlushRefresh oriofrh +#define OCIObjectCopy oriocpy +#define OCIObjectGetTypeRef oriogtr +#define OCIObjectGetObjectRef oriogor +#define OCIObjectGetInd oriogns +#define OCIObjectExists oriogex +#define OCIObjectGetProperty oriogpr +#define OCIObjectRefresh oriorfs +#define OCIObjectPinTable oriogtb +#define OCIObjectGetPrimaryKeyTypeRef oriogpf +#define OCIObjectMakeObjectRef oriomrf + +#define OCIObjectNew orionew +#define OCIObjectPin oriopin +#define OCIObjectFree oriofre +#define OCIObjectArrayPin orioapn +#define OCIObjectIsDirty oriodrt +#define OCIObjectIsDirtied oriodrd +#define OCIObjectIsLoaded orioldd +#define OCICacheFlush oricfls +#define OCICacheRefresh oricrfs + +#endif /* SLSHORTNAME */ + +/*---------------------------------------------------------------------------*/ +/* PUBLIC TYPES AND CONSTANTS */ +/*---------------------------------------------------------------------------*/ + +/* Also see oro.h. */ + +/*---------------------------------------------------------------------------*/ +/* PUBLIC FUNCTIONS */ +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ +/* OBJECT/INSTANCE OPERATIONS */ +/*---------------------------------------------------------------------------*/ + +/*--------------------------- OCIObjectNew ----------------------------------*/ +sword OCIObjectNew( OCIEnv *env, OCIError *err, const OCISvcCtx *svc, + OCITypeCode typecode, OCIType *tdo, void *table, + OCIDuration duration, boolean value, + void **instance ); +/* + NAME: OCIObjectNew - OCI new (create) a standalone instance + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + svc (IN) - OCI service handle. + typecode (IN) - the typecode of the type of the instance. + tdo (IN, optional) - pointer to the type descriptor object. The + TDO describes the type of the instance that is to be + created. Refer to OCITypeByName() for obtaining a TDO. + The TDO is required for creating a named type (e.g. an + object or a collection). + table (IN, optional) - pointer to a table object which specifies a + table in the server. This parameter can be set to NULL + if no table is given. See the description below to find + out how the table object and the TDO are used together + to determine the kind of instances (persistent, + transient, value) to be created. Also see + OCIObjectPinTable() for retrieving a table object. + duration (IN) - this is an overloaded parameter. The use of this + parameter is based on the kind of the instance that is + to be created. + a) persistent object. This parameter specifies the + pin duration. + b) transient object. This parameter specififes the + allocation duration and pin duration. + c) value. This parameter specifies the allocation + duration. + value (IN) - specifies whether the created object is a value. + If TRUE, then a value is created. Otherwise, a + referenceable object is created. If the instance is + not an object, then this parameter is ignored. + instance (OUT) - address of the newly created instance + + REQUIRES: + - a valid OCI environment handle must be given. + DESCRIPTION: + This function creates a new instance of the type specified by the + typecode or the TDO. Based on the parameters 'typecode' (or 'tdo'), + 'value' and 'table', different kinds of instances can be created: + + The parameter 'table' is not NULL? + + yes no + ---------------------------------------------------------------- + | object type (value=TRUE) | value | value | + ---------------------------------------------------------------- + | object type (value=FALSE) | persistent obj | transient obj | + type ---------------------------------------------------------------- + | built-in type | value | value | + ---------------------------------------------------------------- + | collection type | value | value | + ---------------------------------------------------------------- + + This function allocates the top level memory chunk of an OTS instance. + The attributes in the top level memory are initialized (e.g. an + attribute of varchar2 is initialized to a vstring of 0 length). + + If the instance is an object, the object is marked existed but is + atomically null. + + FOR PERSISTENT OBJECTS: + The object is marked dirty and existed. The allocation duration for + the object is session. The object is pinned and the pin duration is + specified by the given parameter 'duration'. + + FOR TRANSIENT OBJECTS: + The object is pinned. The allocation duration and the pin duration are + specified by the given parameter 'duration'. + + FOR VALUES: + The allocation duration is specified by the given parameter 'duration'. + + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/*--------------------------- OCIObjectPin ----------------------------------*/ +sword OCIObjectPin( OCIEnv *env, OCIError *err, OCIRef *object_ref, + OCIComplexObject *corhdl, OCIPinOpt pin_option, + OCIDuration pin_duration, + OCILockOpt lock_option, void **object ); +/* + NAME: OCIObjectPin - OCI pin a referenceable object + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns + OCI_ERROR. The error recorded in 'err' can be + retrieved by calling OCIErrorGet(). + object_ref (IN) - the reference to the object. + corhdl (IN) - handle for complex object retrieval. + pin_option (IN) - See description below. + pin_duration (IN) - The duration of which the object is being accesed + by a client. The object is implicitly unpinned at + the end of the pin duration. + If OCI_DURATION_NULL is passed, there is no pin + promotion if the object is already loaded into + the cache. If the object is not yet loaded, then + the pin duration is set to OCI_DURATION_DEFAULT. + lock_option (IN) - lock option (e.g., exclusive). If a lock option + is specified, the object is locked in the server. + See 'oro.h' for description about lock option. + object (OUT) - the pointer to the pinned object. + + REQUIRES: + - a valid OCI environment handle must be given. + DESCRIPTION: + + This function pins a referenceable object instance given the object + reference. The process of pinning serves three purposes: + + 1) locate an object given its reference. This is done by the object + cache which keeps track of the objects in the object heap. + + 2) notify the object cache that an object is being in use. An object + can be pinned many times. A pinned object will remain in memory + until it is completely unpinned (see OCIObjectUnpin()). + + 3) notify the object cache that a persistent object is being in use + such that the persistent object cannot be aged out. Since a + persistent object can be loaded from the server whenever is needed, + the memory utilization can be increased if a completely unpinned + persistent object can be freed (aged out), even before the + allocation duration is expired. + + Also see OCIObjectUnpin() for more information about unpinning. + + FOR PERSISTENT OBJECTS: + + When pinning a persistent object, if it is not in the cache, the object + will be fetched from the persistent store. The allocation duration of + the object is session. If the object is already in the cache, it is + returned to the client. The object will be locked in the server if a + lock option is specified. + + This function will return an error for a non-existent object. + + A pin option is used to specify the copy of the object that is to be + retrieved: + + 1) If option is OCI_PIN_ANY (pin any), if the object is already + in the environment heap, return this object. Otherwise, the object + is retrieved from the database. This option is useful when the + client knows that he has the exclusive access to the data in a + session. + + 2) If option is OCI_PIN_LATEST (pin latest), if the object is + not cached, it is retrieved from the database. If the object is + cached, it is refreshed with the latest version. See + OCIObjectRefresh() for more information about refreshing. + + 3) If option is OCI_PIN_RECENT (pin recent), if the object is loaded + into the cache in the current transaction, the object is returned. + If the object is not loaded in the current transaction, the object + is refreshed from the server. + + FOR TRANSIENT OBJECTS: + + This function will return an error if the transient object has already + been freed. This function does not return an error if an exclusive + lock is specified in the lock option. + + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/*------------------------------ OCIObjectUnpin -----------------------------*/ +sword OCIObjectUnpin( OCIEnv *env, OCIError *err, void *object ); +/* + NAME: OCIObjectUnpin - OCI unpin a referenceable object + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by + calling OCIErrorGet(). + object (IN) - pointer to an object + REQUIRES: + - a valid OCI environment handle must be given. + - The specified object must be pinned. + DESCRIPTION: + This function unpins an object. An object is completely unpinned when + 1) the object was unpinned N times after it has been pinned N times + (by calling OCIObjectPin()). + 2) it is the end of the pin duration + 3) the function OCIObjectPinCountReset() is called + + There is a pin count associated with each object which is incremented + whenever an object is pinned. When the pin count of the object is zero, + the object is said to be completely unpinned. An unpinned object can + be freed without error. + + FOR PERSISTENT OBJECTS: + When a persistent object is completely unpinned, it becomes a candidate + for aging. The memory of an object is freed when it is aged out. Aging + is used to maximize the utilization of memory. An dirty object cannot + be aged out unless it is flushed. + + FOR TRANSIENT OBJECTS: + The pin count of the object is decremented. A transient can be freed + only at the end of its allocation duration or when it is explicitly + deleted by calling OCIObjectFree(). + + FOR VALUE: + This function will return an error for value. + + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/*---------------------------- OCIObjectPinCountReset -----------------------*/ +sword OCIObjectPinCountReset( OCIEnv *env, OCIError *err, void *object ); +/* + NAME: OCIObjectPinCountReset - OCI resets the pin count of a referenceable + object + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by + calling OCIErrorGet(). + object (IN) - pointer to an object + REQUIRES: + - a valid OCI environment handle must be given. + - The specified object must be pinned. + DESCRIPTION: + This function completely unpins an object. When an object is + completely unpinned, it can be freed without error. + + FOR PERSISTENT OBJECTS: + When a persistent object is completely unpinned, it becomes a candidate + for aging. The memory of an object is freed when it is aged out. Aging + is used to maximize the utilization of memory. An dirty object cannot + be aged out unless it is flushed. + + FOR TRANSIENT OBJECTS: + The pin count of the object is decremented. A transient can be freed + only at the end of its allocation duration or when it is explicitly + freed by calling OCIObjectFree(). + + FOR VALUE: + This function will return an error for value. + + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/*--------------------------- OCIObjectLock ---------------------------------*/ +sword OCIObjectLock( OCIEnv *env, OCIError *err, void *object ); +/* + NAME: OCIObjectLock - OCI lock a persistent object + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by + calling OCIErrorGet(). + object (IN) - pointer to the persistent object + REQUIRES: + - a valid OCI environment handle must be given. + - The specified object must be pinned. + DESCRIPTION: + This function locks a persistent object at the server. Unlike + OCIObjectLockNoWait() this function waits if another user currently + holds a lock on the desired object. This function + returns an error if: + 1) the object is non-existent. + + This function will return an error for transient objects and values. + The lock of an object is released at the end of a transaction. + + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. +*/ + +/*------------------------ OCIObjectLockNoWait ------------------------------*/ +sword OCIObjectLockNoWait( OCIEnv *env, OCIError *err, void *object ); +/* + NAME: OCIObjectLockNoWait - OCI lock a persistent object, do not wait for + the lock, return error if lock not available + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by + calling OCIErrorGet(). + object (IN) - pointer to the persistent object + REQUIRES: + - a valid OCI environment handle must be given. + - The specified object must be pinned. + DESCRIPTION: + This function locks a persistent object at the server. Unlike + OCIObjectLock() this function will not wait if another user holds + the lock on the desired object. This function returns an error if: + 1) the object is non-existent. + 2) the object is currently locked by another user in which + case this function returns with an error. + + This function will return an error for transient objects and values. + The lock of an object is released at the end of a transaction. + + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. +*/ + +/*--------------------------- OCIObjectMarkUpdate ---------------------------*/ +sword OCIObjectMarkUpdate( OCIEnv *env, OCIError *err, void *object ); +/* + NAME: OCIObjectMarkUpdate - OCI marks an object as updated + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by + calling OCIErrorGet(). + object (IN) - pointer to the persistent object + REQUIRES: + - a valid OCI environment handle must be given. + - The specified object must be pinned. + DESCRIPTION: + FOR PERSISTENT OBJECTS: + This function marks the specified persistent object as updated. The + persistent objects will be written to the server when the object cache + is flushed. The object is not locked or flushed by this function. It + is an error to update a deleted object. + + After an object is marked updated and flushed, this function must be + called again to mark the object as updated if it has been dirtied + after it is being flushed. + + FOR TRANSIENT OBJECTS: + This function marks the specified transient object as updated. The + transient objects will NOT be written to the server. It is an error + to update a deleted object. + + FOR VALUES: + It is an no-op for values. + + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/*----------------------------- OCIObjectUnmark -----------------------------*/ +sword OCIObjectUnmark( OCIEnv *env, OCIError *err, void *object ); +/* + NAME: OCIObjectUnmark - OCI unmarks an object + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by + calling OCIErrorGet(). + object (IN) - pointer to the persistent object + REQUIRES: + - a valid OCI environment handle must be given. + - The specified object must be pinned. + DESCRIPTION: + FOR PERSISTENT OBJECTS AND TRANSIENT OBJECTS: + This function unmarks the specified persistent object as dirty. Changes + that are made to the object will not be written to the server. If the + object is marked locked, it remains marked locked. The changes that + have already made to the object will not be undone implicitly. + + FOR VALUES: + It is an no-op for values. + + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/*----------------------------- OCIObjectUnmarkByRef ------------------------*/ +sword OCIObjectUnmarkByRef( OCIEnv *env, OCIError *err, OCIRef *ref ); +/* + NAME: OCIObjectUnmarkByRef - OCI unmarks an object by Ref + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by + calling OCIErrorGet(). + ref (IN) - reference of the object + REQUIRES: + - a valid OCI environment handle must be given. + - The specified object must be pinned. + DESCRIPTION: + FOR PERSISTENT OBJECTS AND TRANSIENT OBJECTS: + This function unmarks the specified persistent object as dirty. Changes + that are made to the object will not be written to the server. If the + object is marked locked, it remains marked locked. The changes that + have already made to the object will not be undone implicitly. + + FOR VALUES: + It is an no-op for values. + + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/*--------------------------- OCIObjectFree ---------------------------------*/ +sword OCIObjectFree( OCIEnv *env, OCIError *err, void *instance, + ub2 flags ); +/* + NAME: OCIObjectFree - OCI free (and unpin) an standalone instance + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns + OCI_ERROR. The error recorded in 'err' can be + retrieved by calling OCIErrorGet(). + instance (IN) - pointer to a standalone instance. + flags (IN) - If OCI_OBJECT_FREE_FORCE is set, free the object + even if it is pinned or dirty. + If OCI_OBJECT_FREE_NONULL is set, the null + structure will not be freed. + REQUIRES: + - a valid OCI environment handle must be given. + - The instance to be freed must be standalone. + - If the instance is a referenceable object, the object must be pinned. + DESCRIPTION: + This function deallocates all the memory allocated for an OTS instance, + including the null structure. + + FOR PERSISTENT OBJECTS: + This function will return an error if the client is attempting to free + a dirty persistent object that has not been flushed. The client should + either flush the persistent object or set the parameter 'flag' to + OCI_OBJECT_FREE_FORCE. + + This function will call OCIObjectUnpin() once to check if the object + can be completely unpin. If it succeeds, the rest of the function will + proceed to free the object. If it fails, then an error is returned + unless the parameter 'flag' is set to OCI_OBJECT_FREE_FORCE. + + Freeing a persistent object in memory will not change the persistent + state of that object at the server. For example, the object will + remain locked after the object is freed. + + FOR TRANSIENT OBJECTS: + + This function will call OCIObjectUnpin() once to check if the object + can be completely unpin. If it succeeds, the rest of the function will + proceed to free the object. If it fails, then an error is returned + unless the parameter 'flag' is set to OCI_OBJECT_FREE_FORCE. + + FOR VALUES: + The memory of the object is freed immediately. + + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. +*/ + +/*----------------------- OCIObjectMarkDeleteByRef --------------------------*/ +sword OCIObjectMarkDeleteByRef( OCIEnv *env, OCIError *err, + OCIRef *object_ref); +/* + NAME: OCIObjectMarkDeleteByRef - OCI "delete" (and unpin) an object given + a reference + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns + OCI_ERROR. The error recorded in 'err' can be + retrieved by calling OCIErrorGet(). + object_ref (IN) - ref of the object to be deleted + + REQUIRES: + - a valid OCI environment handle must be given. + DESCRIPTION: + This function marks the object designated by 'object_ref' as deleted. + + FOR PERSISTENT OBJECTS: + If the object is not loaded, then a temporary object is created and is + marked deleted. Otherwise, the object is marked deleted. + + The object is deleted in the server when the object is flushed. + + FOR TRANSIENT OBJECTS: + The object is marked deleted. The object is not freed until it is + unpinned. + + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/*--------------------------- OCIObjectMarkDelete ---------------------------*/ +sword OCIObjectMarkDelete( OCIEnv *env, OCIError *err, void *instance ); +/* + NAME: OCIObjectMarkDelete - OCI "delete" an instance given a Pointer + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns + OCI_ERROR. The error recorded in 'err' can be + retrieved by calling OCIErrorGet(). + instance (IN) - pointer to the instance + REQUIRES: + - a valid OCI environment handle must be given. + - The instance must be standalone. + - If the instance is a referenceable object, then it must be pinned. + DESCRIPTION: + + FOR PERSISTENT OBJECTS: + The object is marked deleted. The memory of the object is not freed. + The object is deleted in the server when the object is flushed. + + FOR TRANSIENT OBJECTS: + The object is marked deleted. The memory of the object is not freed. + + FOR VALUES: + This function frees a value immediately. + + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/*---------------------------- OCIObjectFlush -------------------------------*/ +sword OCIObjectFlush( OCIEnv *env, OCIError *err, void *object ); +/* + NAME: OCIObjectFlush - OCI flush a persistent object + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns + OCI_ERROR. The error recorded in 'err' can be + retrieved by calling OCIErrorGet(). + object (IN) - pointer to the persistent object + REQUIRES: + - a valid OCI environment handle must be given. + - The specified object must be pinned. + DESCRIPTION: + This function flushes a modified persistent object to the server. + An exclusive lock is obtained implicitly for the object when flushed. + + When the object is written to the server, triggers may be fired. + Objects can be modified by the triggers at the server. To keep the + objects in the object cache being coherent with the database, the + clients can free or refresh the objects in the cache. + + This function will return an error for transient objects and values. + + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/*------------------------ OCIObjectRefresh ---------------------------------*/ +sword OCIObjectRefresh( OCIEnv *env, OCIError *err, void *object ); +/* + NAME: OCIObjectRefresh - OCI refresh a persistent object + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns + OCI_ERROR. The error recorded in 'err' can be + retrieved by calling OCIErrorGet(). + object (IN) - pointer to the persistent object + REQUIRES: + - a valid OCI environment handle must be given. + - The specified object must be pinned. + DESCRIPTION: + This function refreshes an unmarked object with data retrieved from the + latest snapshot in the server. An object should be refreshed when the + objects in the cache are inconsistent with the objects at + the server: + 1) When an object is flushed to the server, triggers can be fired to + modify more objects in the server. The same objects (modified by + the triggers) in the object cache become obsolete. + 2) When the user issues a SQL or executes a PL/SQL procedure to modify + any object in the server, the same object in the cache becomes + obsolete. + + The object that is refreshed will be 'replaced-in-place'. When an + object is 'replaced-in-place', the top level memory of the object will + be reused so that new data can be loaded into the same memory address. + The top level memory of the null structre is also reused. Unlike the + top level memory chunk, the secondary memory chunks may be resized and + reallocated. The client should be careful when holding onto a pointer + to the secondary memory chunk (e.g. assigning the address of a + secondary memory to a local variable), since this pointer can become + invalid after the object is refreshed. + + The object state will be modified as followed after being refreshed: + - existent : set to appropriate value + - pinned : unchanged + - allocation duration : unchanged + - pin duration : unchanged + + This function is an no-op for transient objects or values. + + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/*---------------------------- OCIObjectCopy --------------------------------*/ +sword OCIObjectCopy( OCIEnv *env, OCIError *err, const OCISvcCtx *svc, + void *source, void *null_source, + void *target, void *null_target, OCIType *tdo, + OCIDuration duration, ub1 option ); +/* + NAME: OCIObjectCopy - OCI copy one instance to another + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns + OCI_ERROR. The error recorded in 'err' can be + retrieved by calling OCIErrorGet(). + svc (IN) - OCI service context handle + source (IN) - pointer to the source instance + null_source (IN) - pointer to the null structure of the source + target (IN) - pointer to the target instance + null_target (IN) - pointer to the null structure of the target + tdo (IN) - the TDO for both source and target + duration (IN) - allocation duration of the target memory + option (IN) - specify the copy option: + OROOCOSFN - Set Reference to Null. All references + in the source will not be copied to the target. The + references in the target are set to null. + REQUIRES: + - a valid OCI environment handle must be given. + - If source or target is referenceable, it must be pinned. + - The target or the containing instance of the target must be already + be instantiated (e.g. created by OCIObjectNew()). + - The source and target instances must be of the same type. If the + source and target are located in a different databases, then the + same type must exist in both databases. + DESCRIPTION: + This function copies the contents of the 'source' instance to the + 'target' instance. This function performs a deep-copy such that the + data that is copied/duplicated include: + a) all the top level attributes (see the exceptions below) + b) all the secondary memory (of the source) that is reachable from the + top level attributes. + c) the null structure of the instance + + Memory is allocated with the specified allocation duration. + + Certain data items are not copied: + a) If the option OCI_OBJECTCOPY_NOREF is specified, then all references + in the source are not copied. Instead, the references in the target + are set to null. + b) If the attribute is a LOB, then it is set to null. + + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/*---------------------------- OCIObjectGetTypeRef --------------------------*/ +sword OCIObjectGetTypeRef( OCIEnv *env, OCIError *err, void *instance, + OCIRef *type_ref ); +/* + NAME: OCIObjectGetTypeRef - get the type reference of a standalone object + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns + OCI_ERROR. The error recorded in 'err' can be + retrieved by calling OCIErrorGet(). + instance (IN) - pointer to an standalone instance + type_ref (OUT) - reference to the type of the object. The reference + must already be allocated. + REQUIRES: + - a valid OCI environment handle must be given. + - The instance must be standalone. + - If the object is referenceable, the specified object must be pinned. + - The reference must already be allocated. + DESCRIPTION: + This function returns a reference to the TDO of a standalone instance. + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/*--------------------------- OCIObjectGetObjectRef -------------------------*/ +sword OCIObjectGetObjectRef( OCIEnv *env, OCIError *err, void *object, + OCIRef *object_ref ); +/* + NAME: OCIObjectGetObjectRef - OCI get the object reference of an + referenceable object + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns + OCI_ERROR. The error recorded in 'err' can be + retrieved by calling OCIErrorGet(). + object (IN) - pointer to a persistent object + object_ref (OUT) - reference of the given object. The reference must + already be allocated. + REQUIRES: + - a valid OCI environment handle must be given. + - The specified object must be pinned. + - The reference must already be allocated. + DESCRIPTION: + This function returns a reference to the given object. It returns an + error for values. + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/*--------------------------- OCIObjectMakeObjectRef -----------------------*/ +sword OCIObjectMakeObjectRef( OCIEnv *env, OCIError *err, + const OCISvcCtx *svc, void * table, + void **values, ub4 array_len, + OCIRef *object_ref ); +/* + NAME: OCIObjectMakeObjectRef - OCI Create an object reference to a + referenceable object. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns + OCI_ERROR. The error recorded in 'err' can be + retrieved by calling OCIErrorGet(). + svc (IN) - the service context + table (IN) - A pointer to the table object (must be pinned) + attrlist (IN) - A list of values (OCI type values) from which + the ref is to be created. + attrcnt (IN) - The length of the attrlist array. + object_ref (OUT) - reference of the given object. The reference must + already be allocated. + REQUIRES: + - a valid OCI environment handle must be given. + - The specified table object must be pinned. + - The reference must already be allocated. + DESCRIPTION: + This function creates a reference given the values that make up the + reference and also a pointer to the table object. + Based on the table's OID property, whether it is a pk based OID or + a system generated OID, the function creates a sys-generated REF or + a pk based REF. + In case of system generated REFs pass in a OCIRaw which is 16 bytes + long contatining the sys generated OID. + In case of PK refs pass in the OCI equivalent for numbers, chars etc.. + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/*--------------------------- OCIObjectGetPrimaryKeyTypeRef --------------- */ +sword OCIObjectGetPrimaryKeyTypeRef( OCIEnv *env, OCIError *err, + const OCISvcCtx *svc, void *table, + OCIRef *type_ref ); +/* + NAME: OCIObjectGetPrimaryKeyTypeRef - OCI get the REF to the pk OID type + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns + OCI_ERROR. The error recorded in 'err' can be + retrieved by calling OCIErrorGet(). + svc (IN) - the service context + table (IN) - pointer to the table object + type_ref (OUT) - reference of the pk type. The reference must + already be allocated. + REQUIRES: + - a valid OCI environment handle must be given. + - The specified table object must be pinned. + - The reference must already be allocated. + DESCRIPTION: + This function returns a reference to the pk type. It returns an + error for values. If the table is not a Pk oid table/view, then + it returns error. + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/*-------------------------- OCIObjectGetInd --------------------------------*/ +sword OCIObjectGetInd( OCIEnv *env, OCIError *err, void *instance, + void **null_struct ); +/* + NAME: OCIObjectGetInd - OCI get the null structure of a standalone object + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns + OCI_ERROR. The error recorded in 'err' can be + retrieved by calling OCIErrorGet(). + instance (IN) - pointer to the instance + null_struct (OUT) - null structure + REQUIRES: + - a valid OCI environment handle must be given. + - The object must be standalone. + - If the object is referenceable, the specified object must be pinned. + DESCRIPTION: + This function returns the null structure of an instance. This function + will allocate the top level memory of the null structure if it is not + already allocated. If an null structure cannot be allocated for the + instance, then an error is returned. This function only works for + ADT or row type instance. + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/*------------------------- OCIObjectExists --------------------------------*/ +sword OCIObjectExists(OCIEnv *env, OCIError *err, void *ins, boolean *exist); +/* + NAME: OCIObjectExist - OCI checks if the object exists + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns + OCI_ERROR. The error recorded in 'err' can be + retrieved by calling OCIErrorGet(). + ins (IN) - pointer to an instance + exist (OUT) - return TRUE if the object exists + REQUIRES: + - a valid OCI environment handle must be given. + - The object must be standalone. + - if object is a referenceable, it must be pinned. + DESCRIPTION: + This function returns the existence of an instance. If the instance + is a value, this function always returns TRUE. + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/*------------------------- OCIObjectGetProperty ---------------------------*/ +sword OCIObjectGetProperty(OCIEnv *envh, OCIError *errh, const void *obj, + OCIObjectPropId propertyId, + void *property, ub4 *size ); +/* + NAME: OCIObjectGetProperty - OCIObject Get Property of given object + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns + OCI_ERROR. The error recorded in 'err' can be + retrieved by calling OCIErrorGet(). + obj (IN) - object whose property is returned + propertyId (IN) - id which identifies the desired property + property (OUT) - buffer into which the desired property is + copied + size (IN/OUT) - on input specifies the size of the property buffer + passed by caller, on output will contain the + size in bytes of the property returned. + This parameter is required for string type + properties only (e.g OCI_OBJECTPROP_SCHEMA, + OCI_OBJECTPROP_TABLE). For non-string + properties this parameter is ignored since + the size is fixed. + DESCRIPTION: + This function returns the specified property of the object. + The desired property is identified by 'propertyId'. The property + value is copied into 'property' and for string typed properties + the string size is returned via 'size'. + + Objects are classified as persistent, transient and value + depending upon the lifetime and referenceability of the object. + Some of the properties are applicable only to persistent + objects and some others only apply to persistent and + transient objects. An error is returned if the user tries to + get a property which in not applicable to the given object. + To avoid such an error, the user should first check whether + the object is persistent or transient or value + (OCI_OBJECTPROP_LIFETIME property) and then appropriately + query for other properties. + + The different property ids and the corresponding type of + 'property' argument is given below. + + OCI_OBJECTPROP_LIFETIME + This identifies whether the given object is a persistent + object (OCI_OBJECT_PERSISTENT) or a + transient object (OCI_OBJECT_TRANSIENT) or a + value instance (OCI_OBJECT_VALUE). + 'property' argument must be a pointer to a variable of + type OCIObjectLifetime. + + OCI_OBJECTPROP_SCHEMA + This returns the schema name of the table in which the + object exists. An error is returned if the given object + points to a transient instance or a value. If the input + buffer is not big enough to hold the schema name an error + is returned, the error message will communicate the + required size. Upon success, the size of the returned + schema name in bytes is returned via 'size'. + 'property' argument must be an array of type text and 'size' + should be set to size of array in bytes by the caller. + + OCI_OBJECTPROP_TABLE + This returns the table name in which the object exists. An + error is returned if the given object points to a + transient instance or a value. If the input buffer is not + big enough to hold the table name an error is returned, + the error message will communicate the required size. Upon + success, the size of the returned table name in bytes is + returned via 'size'. 'property' argument must be an array + of type text and 'size' should be set to size of array in + bytes by the caller. + + OCI_OBJECTPROP_PIN_DURATION + This returns the pin duration of the object. + An error is returned if the given object points to a value + instance. Valid pin durations are: OCI_DURATION_SESSION and + OCI_DURATION_TRANS. + 'property' argument must be a pointer to a variable of type + OCIDuration. + + OCI_OBJECTPROP_ALLOC_DURATION + This returns the allocation duration of the object. + Valid allocation durations are: OCI_DURATION_SESSION and + OCI_DURATION_TRANS. + 'property' argument must be a pointer to a variable of type + OCIDuration. + + OCI_OBJECTPROP_LOCK + This returns the lock status of the + object. The possible lock status is enumerated by OCILockOpt. + An error is returned if the given object points to a transient + or value instance. + 'property' argument must be a pointer to a variable of + type OCILockOpt. + Note, the lock status of an object can also be retrieved by + calling OCIObjectIsLocked(). + + OCI_OBJECTPROP_MARKSTATUS + This returns the status flag which indicates whether the + object is a new object, updated object and/or deleted object. + The following macros can be used to test the mark status + flag: + + OCI_OBJECT_IS_UPDATED(flag) + OCI_OBJECT_IS_DELETED(flag) + OCI_OBJECT_IS_NEW(flag) + OCI_OBJECT_IS_DIRTY(flag) + + An object is dirty if it is a new object or marked deleted or + marked updated. + An error is returned if the given object points to a transient + or value instance. 'property' argument must be of type + OCIObjectMarkStatus. + + OCI_OBJECTPROP_VIEW + This identifies whether the specified object is a view object + or not. If property value returned is TRUE, it indicates the + object is a view otherwise it is not. + 'property' argument must be of type boolean. + + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. Possible errors are TBD + */ + +/*---------------------------- OCIObjectIsLocked --------------------------*/ +sword OCIObjectIsLocked( OCIEnv *env, OCIError *err, void *ins, + boolean *lock); +/* + NAME: OCIObjectIsLocked - OCI get the lock status of a standalone object + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns + OCI_ERROR. The error recorded in 'err' can be + retrieved by calling OCIErrorGet(). + ins (IN) - pointer to an instance + lock (OUT) - return value for the lock status. + REQUIRES: + - a valid OCI environment handle must be given. + - The instance must be standalone. + - If the object is referenceable, the specified object must be pinned. + DESCRIPTION: + This function returns the lock status of an instance. If the instance + is a value, this function always returns FALSE. + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/*------------------------- OCIObjectIsDirty ------------------------------*/ +sword OCIObjectIsDirty( OCIEnv *env, OCIError *err, void *ins, + boolean *dirty); +/* + NAME: OCIObjectIsDirty - OCI get the dirty status of a standalone object + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns + OCI_ERROR. The error recorded in 'err' can be + retrieved by calling OCIErrorGet(). + ins (IN) - pointer to an instance + dirty (OUT) - return value for the dirty status. + REQUIRES: + - a valid OCI environment handle must be given. + - The instance must be standalone. + - if instance is an object, the instance must be pinned. + DESCRIPTION: + This function returns the dirty status of an instance. If the instance + is a value, this function always returns FALSE. + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/*--------------------------- OCIObjectPinTable -----------------------------*/ +sword OCIObjectPinTable( OCIEnv *env, OCIError *err, const OCISvcCtx *svc, + const oratext *schema_name, + ub4 s_n_length, const oratext *object_name, ub4 o_n_length, + const OCIRef *scope_obj_ref, OCIDuration pin_duration, + void ** object ); +/* + NAME: OCIObjectPinTable - OCI get table object + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns + OCI_ERROR. The error recorded in 'err' can be + retrieved by calling OCIErrorGet(). + svc (IN) - OCI service context handle + schema_name (IN, optional) - schema name of the table + s_n_length (IN, optional) - length of the schema name + object_name (IN) - name of the table + o_n_length (IN) - length of the table name + scope_obj_ref (IN, optional) - reference of the scoping object + pin_duration (IN) - pin duration. See description in OCIObjectPin(). + object (OUT) - the pinned table object + REQUIRES: + - a valid OCI environment handle must be given. + DESCRIPTION: + This function pin a table object with the specified pin duration. + The client can unpin the object by calling OCIObjectUnpin(). See + OCIObjectPin() and OCIObjectUnpin() for more information about pinning + and unpinning. + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/*------------------------- OCIObjectArrayPin -------------------------------*/ +sword OCIObjectArrayPin(OCIEnv *env, OCIError *err, OCIRef **ref_array, + ub4 array_size, OCIComplexObject **cor_array, + ub4 cor_array_size, OCIPinOpt pin_option, + OCIDuration pin_duration, OCILockOpt lock, + void **obj_array, ub4 *pos ); +/* + NAME: OCIObjectArrayPin - ORIO array pin + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns + OCI_ERROR. The error recorded in 'err' can be + retrieved by calling OCIErrorGet(). + ref_array (IN) - array of references to be pinned + array_size (IN) - number of elements in the array of references + pin_option (IN) - pin option. See OCIObjectPin(). + pin_duration (IN) - pin duration. See OCIObjectPin(). + lock_option (IN) - lock option. See OCIObjectPin(). + obj_array (OUT) - If this argument is not NULL, the pinned objects + will be returned in the array. The user must + allocate this array with element type being + 'void *'. The size of this array is identical to + 'array'. + pos (OUT) - If there is an error, this argument will contain + the element that is causing the error. Note that + this argument is set to 1 for the first element in + the ref_array. + REQUIRE: + - a valid OCI environment handle must be given. + - If 'obj_array' is not NULL, then it must already be allocated and + the size of 'obj_array' is 'array_size'. + DESCRIPTION: + This function pin an array of references. All the pinned objects are + retrieved from the database in one network roundtrip. If the user + specifies an output array ('obj_array'), then the address of the + pinned objects will be assigned to the elements in the array. See + OCIObjectPin() for more information about pinning. + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/*---------------------------------------------------------------------------*/ +/* HEAP/CACHE OPERATIONS */ +/*---------------------------------------------------------------------------*/ + +/*--------------------------- OCICacheFlush ---------------------------------*/ +sword OCICacheFlush( OCIEnv *env, OCIError *err, const OCISvcCtx *svc, + void *context, OCIRef *(*get)(void *context, ub1 *last), + OCIRef **ref ); +/* + NAME: OCICacheFlush - OCI flush persistent objects + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns + OCI_ERROR. The error recorded in 'err' can be + retrieved by calling OCIErrorGet(). + svc (IN) [optional] - OCI service context. If null pointer is + specified, then the dirty objects in all connections + will be flushed. + context (IN) [optional] - specifies an user context that is an + argument to the client callback function 'get'. This + parameter is set to NULL if there is no user context. + get (IN) [optional] - an client-defined function which acts an + iterator to retrieve a batch of dirty objects that need + to be flushed. If the function is not NULL, this function + will be called to get a reference of a dirty object. + This is repeated until a null reference is returned by + the client function or the parameter 'last' is set to + TRUE. The parameter 'context' is passed to get() + for each invocation of the client function. This + parameter should be NULL if user callback is not given. + If the object that is returned by the client function is + not a dirtied persistent object, the object is ignored. + All the objects that are returned from the client + function must be from newed or pinned the same service + context, otherwise, an error is signalled. Note that the + returned objects are flushed in the order in which they + are marked dirty. + ref (OUT) [optional] - if there is an error in flushing the + objects, (*ref) will point to the object that + is causing the error. If 'ref' is NULL, then the object + will not be returned. If '*ref' is NULL, then a + reference will be allocated and set to point to the + object. If '*ref' is not NULL, then the reference of + the object is copied into the given space. If the + error is not caused by any of the dirtied object, + the given ref is initalized to be a NULL reference + (OCIRefIsNull(*ref) is TRUE). + REQUIRES: + - a valid OCI environment handle must be given. + DESCRIPTION: + This function flushes the modified persistent objects from the + environment heap to the server. The objects are flushed in the order + that they are marked updated or deleted. + + See OCIObjectFlush() for more information about flushing. + + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/*--------------------------- OCICacheRefresh -------------------------------*/ +sword OCICacheRefresh(OCIEnv *env, OCIError *err, const OCISvcCtx *svc, + OCIRefreshOpt option, void *context, + OCIRef *(*get)(void *context), OCIRef **ref); +/* + NAME: OCICacheRefresh - OCI ReFreSh persistent objects + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns + OCI_ERROR. The error recorded in 'err' can be + retrieved by calling OCIErrorGet(). + svc (IN) [optional] - OCI service context. If null pointer is + specified, then the persistent objects in all connections + will be refreshed. + option (IN) [optional] - if OCI_REFRESH_LOAD is specified, all + objects that is loaded within the transaction are + refreshed. If the option is OCI_REFERSH_LOAD and the + parameter 'get' is not NULL, this function will ignore + the parameter. + context (IN) [optional] - specifies an user context that is an + argument to the client callback function 'get'. This + parameter is set to NULL if there is no user context. + get (IN) [optional] - an client-defined function which acts an + iterator to retrieve a batch of objects that need to be + refreshed. If the function is not NULL, this function + will be called to get a reference of an object. If + the reference is not NULL, then the object will be + refreshed. These steps are repeated until a null + reference is returned by this function. The parameter + 'context' is passed to get() for each invocation of the + client function. This parameter should be NULL if user + callback is not given. + ref (OUT) [optional] - if there is an error in refreshing the + objects, (*ref) will point to the object that + is causing the error. If 'ref' is NULL, then the object + will not be returned. If '*ref' is NULL, then a + reference will be allocated and set to point to the + object. If '*ref' is not NULL, then the reference of + the object is copied into the given space. If the + error is not caused by any of the object, + the given ref is initalized to be a NULL reference + (OCIRefIsNull(*ref) is TRUE). + REQUIRES: + - a valid OCI environment handle must be given. + DESCRIPTION: + This function refreshes all pinned persistent objects. All unpinned + persistent objects are freed. See OCIObjectRefresh() for more + information about refreshing. + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/*---------------------------- OCICacheUnpin --------------------------------*/ +sword OCICacheUnpin( OCIEnv *env, OCIError *err, const OCISvcCtx *svc ); +/* + NAME: OCICacheUnpin - OCI UNPin objects + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns + OCI_ERROR. The error recorded in 'err' can be + retrieved by calling OCIErrorGet(). + svc (IN) [optional] - OCI service context. If null pointer is + specified, then the objects in all connections + will be unpinned. + REQUIRES: + - a valid OCI environment handle must be given. + DESCRIPTION: + If a connection is specified, this function completely unpins the + persistent objects in that connection. Otherwise, all persistent + objects in the heap are completely unpinned. All transient objects in + the heap are also completely unpinned. See OCIObjectUnpin() for more + information about unpinning. + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/*----------------------------- OCICacheFree --------------------------------*/ +sword OCICacheFree( OCIEnv *env, OCIError *err, const OCISvcCtx *svc ); +/* + NAME: OCICacheFree - OCI FREe instances + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns + OCI_ERROR. The error recorded in 'err' can be + retrieved by calling OCIErrorGet(). + svc (IN) [optional] - OCI service context. If null pointer is + specified, then the objects in all connections + will be freed. + REQUIRES: + - a valid OCI environment handle must be given. + DESCRIPTION: + If a connection is specified, this function frees the persistent + objects, transient objects and values allocated for that connection. + Otherwise, all persistent objects, transient objects and values in the + heap are freed. Objects are freed regardless of their pin count. See + OCIObjectFree() for more information about freeing an instance. + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. +*/ + +/*---------------------------- OCICacheUnmark -------------------------------*/ +sword OCICacheUnmark( OCIEnv *env, OCIError *err, const OCISvcCtx *svc ); +/* + NAME: OCICacheUnmark - OCI Unmark all dirty objects + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns + OCI_ERROR. The error recorded in 'err' can be + retrieved by calling OCIErrorGet(). + svc (IN) [optional] - OCI service context. If null pointer is + specified, then the objects in all connections + will be unmarked. + REQUIRES: + - a valid OCI environment handle must be given. + DESCRIPTION: + If a connection is specified, this function unmarks all dirty objects + in that connection. Otherwise, all dirty objects in the cache are + unmarked. See OCIObjectUnmark() for more information about unmarking + an object. + RETURNS: + if environment handle or error handle is null, return + OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + + +sword OCIDurationBegin( OCIEnv *env, OCIError *err, const OCISvcCtx *svc, + OCIDuration parent, OCIDuration *dur ); +/* + NAME: OCIDurationBegin - OCI DURATION BEGIN + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + This should be passed NULL, when cartridge services + are to be used. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + svc (IN/OUT) - OCI service handle. + parent (IN) - parent for the duration to be started. + dur (OUT) - newly created user duration + REQUIRES: + - a valid OCI environment handle must be given for non-cartridge + services. + - For cartridge services, NULL should be given for environment handle + - A valid service handle must be given in all cases. + DESCRIPTION: + This function starts a new user duration. A user can have multiple + active user durations simultaneously. The user durations do not have + to be nested. + + The object subsystem predefines 3 durations : + 1) session - memory allocated with session duration comes from + the UGA heap (OCI_DURATION_SESSION). A session + duration terminates at the end of the user session. + 2) transaction - memory allocated with transaction duration comes + from the UGA heap (OCI_DURATION_TRANS). A trans- + action duration terminates at the end of the user + transaction. + 3) call - memory allocated with call duration comes from PGA + heap (OCI_DURATION_CALL). A call duration terminates + at the end of the user call. + + Each user duration has a parent duration. A parent duration can be a + predefined duration or another user duration. The relationship between + a user duration and its parent duration (child duration) are: + + 1) An user duration is nested within the parent duration. When its + parent duration terminates, the user duration will also terminate. + 2) The memory allocated with an user duration comes from the heap of + its parent duration. For example, if the parent duration of an + user duration is call, then the memory allocated with the user + duration will also come from the PGA heap. + + This function can be used as both part of cartridge services as well + as without cartridge services. + The difference in the function in the case of cartridge and + non-cartridge services is: + In case of cartridge services, as descibed above a new user + duration is created as a child of the "parent" duration. + But when used for non-cartridge purposes, when a pre-defined + duration is passed in as parent, it is mapped to the cache duration + for that connection (which is created if not already present) and + the new user duration will be child of the cache duration. + + RETURNS: + if environment handle and service handle is null or if error + handle is null return OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + + +sword OCIDurationEnd( OCIEnv *env, OCIError *err, const OCISvcCtx *svc, + OCIDuration duration ); +/* + NAME: OCIDurationEnd - OCI DURATION END + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + This should be passed NULL, when cartridge services + are to be used. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + svc (IN/OUT) - OCI service handle. + dur (OUT) - a previously created user duration using + OCIDurationBegin() + REQUIRES: + - a valid OCI environment handle must be given for non-cartridge + services. + - For cartridge services, NULL should be given for environment handle + - A valid service handle must be given in all cases. + DESCRIPTION: + This function terminates a user duration. All memory allocated for + this duration is freed. + + This function can be used as both part of cartridge services as well + as without cartridge services. In both cased, the heap duration + is freed and all the allocated memory for that duration is freed. + The difference in the function in the case of cartridge and + non-cartridge services is: + In case of non-cartridge services, if the duration is pre- + defined, the associated cache duration (see OCIDurationBegin()) + is also terminated and the following is done. + 1) The child durations are terminated. + 2) All objects pinned for this duration are unpinned. + 3) All instances allocated for this duration are freed. + + In case of cartridge services, only the heap duration is + freed. All the context entries allocated for that duration are + freed from the context hash table.. + + RETURNS: + if environment handle and service handle is null or if error + handle is null return OCI_INVALID_HANDLE. + if operation suceeds, return OCI_SUCCESS. + if operation fails, return OCI_ERROR. + */ + +/****************************************************************************** +** DO NOT USE THE FUNCTIONS BELOW! ** +** UNSUPPORTED INTERFACE ** +** WILL BE REMOVED/CHANGED IN A FUTURE RELEASE ** +******************************************************************************/ + +sword OCIDurationGetParent( OCIEnv *env, OCIError *err, + OCIDuration duration, OCIDuration *parent ); + +sword OCIObjectAlwaysLatest( OCIEnv *env, OCIError *err, void *object ); + +sword OCIObjectNotAlwaysLatest( OCIEnv *env, OCIError *err, + void *object ); + +sword OCIObjectFlushRefresh( OCIEnv *env, OCIError *err, void *object); + +sword OCIObjectIsLoaded( OCIEnv *env, OCIError *err, void *ins, + boolean *load); + +sword OCIObjectIsDirtied( OCIEnv *env, OCIError *err, void *ins, + boolean *dirty); + +sword OCICacheGetObjects( OCIEnv *env, OCIError *err, + const OCISvcCtx *svc, + OCIObjectProperty property, + void *client_context, + void (*client_callback)( + void *client_context, + void *object )); + +sword OCICacheRegister( OCIEnv *env, OCIError *err, + OCIObjectEvent event, + void *client_context, + void (*client_callback)( + void *client_context, + OCIObjectEvent event, + void *object)); + +sword OCICacheFlushRefresh( OCIEnv *env, OCIError *err, + const OCISvcCtx *svc, void *context, + OCIRef *(*get)(void *context, ub1 *last), + OCIRef **ref ); + +sword OCIObjectSetData(OCIEnv *env, OCIError *err, void *obj_hdr, + void *data); + +sword OCIObjectGetNewOID(OCIEnv *env, OCIError *err, OCISvcCtx *svc, + ub1 *oid); + + +#endif /* ORI_ORACLE */ diff --git a/libodbc/include/ora_linux/orid.h b/libodbc/include/ora_linux/orid.h new file mode 100644 index 0000000000..c1c664292a --- /dev/null +++ b/libodbc/include/ora_linux/orid.h @@ -0,0 +1,373 @@ +/* Copyright (c) 1994, 2006, Oracle. All rights reserved. */ + +/* + Author: Tin Nguyen + Date: 02/07/94 + Source documents: "Functional Specification for C Object Interface, Object + Management Subsystem", "Oracle C Coding Standards + version 2.2", and the header file template + Rule sets: the generic and .h file rule sets + Quality status: not exited + Identification tag: [ one or more letters to identify the .h file ] + Revision code: [ date of the last revision of the .h file ] + + Note to the user of this header file: + + Anything in this header file that is marked private is not supported and + must not be used. Private sections are included in the header file to + improve internal maintenance. + + NAME + + ORID - Oracle Object Interface for Dynamic Data Access + + DESCRIPTION + + This file contains declarations for C object interface functions including + the dynamic object data access operations that allow callers to dynamically + access and manipulate objects; these operations include getting and setting + attributes of an object. These dynamic object operations are for accessing + and manipulation objects whose types are not known at compile-time. + + RELATED DOCUMENTS + + Functional Specification for C Object Interface / Object Management System + + PUBLIC FUNCTIONS + + OCIObjectSetAttr - ORID SET attribute value + OCIObjectGetAttr - ORID GET attribute value + + PRIVATE FUNCTIONS + + None + + EXAMPLES + + EXAMPLE 1 + + /o + o This example illustrates how an interative program can use the dynamic + o attribute access to display and modify attributes of an ADT instance. + o The interactive program does not know the type of the object at + o compile time. + o/ + + void display(adt_ref, object, null_struct, names, names_count, + names_length, indexes, indexes_count) + { + /o Pin the ADT o/ + if (OCIObjectPin(env, &adt_ref, OROOPOCUR, OROOPDTRA, OROOLMNON, &adt) + != OROSTASUC) + /o error handling code o/ + + /o + o Call the type manager to obtain all the attributes in the object. + o Display the content of each attribute in the ADT instance. If the + o attribute is an array, display each element of the array. If the + o attribute is an ADT instance, recursively call this routine to + o display the embedded ADT instance. + o/ + numAttrs = OCITypeAttrs(env, adt); + for (i= 1; i <= numAttrs; i++) + { + /o get attribute descriptor o/ + if (ortgabp(env, adt, i, &ado_ref, &ado) != OROSTASUC) + /o error handling code o/ + + /o get attribute name o/ + names[names_count] = OCITypeElemName(env, ado, + &names_length[names_count]); + + /o dynamically get the attr o/ + if (OCIObjectGetAttr(env, object, null_struct, 0, adt_ref, names, + names_length, names_count+1, indexes, indexes_count, 0, + &null, &null_info, &attr) != OROSTASUC) + /o error handling code o/ + + /o check if attribute is null o/ + if (null) continue; + + /o get typecode of attribute o/ + typecode = OCITypeElemTypeCode(env, ado); + + /o if attribute is a varray, display each element in varray o/ + if (typecode == OCI_TYPECODE_VARRAY) + { + /o get the reference to the type of the element of the array o/ + if (OCITypeElemParameterizedTyper(env, ado, &attr_type_ref) + != OROSTASUC) + /o error handling code o/ + + /o get the size of array o/ + if (orlasiz(env, &attr_type_ref, (orlva *)attr, + &numElm) != OROSTASUC) + /o error handling code o/ + + /o get the typecode of the element of the array o/ + if (ortty2r(env, attr_type_ref, &typecode) != OROSTASUC) + /o error handling code o/ + + /o iterate the array o/ + for (j=0; j < numElm; j++) + { + /o get an element in the array o/ + if (OCIObjectGetAttr(env, attr, null_info, j+1, attr_type_ref, + names, names_length, 0, indexes, 0, 0, &null, &null_info, + &element) != OROSTASUC) + /o error handling code o/ + + /o check if element is null o/ + if (null) continue; + + /o if attr is an ADT instance, recursively call this routine o/ + if (typecode == OCI_TYPECODE_ADT || typecode == + OCI_TYPECODE_UNNAMEDADT) + { + /o display the element as an adt o/ + display(attr_type_ref, element, null_info, names, lengths, + 0, indexes, 0); + } + + /o if attribute is scalar, print the value to the screen o/ + else output_to_screen(element, typecode); + } + } + + /o if attribute is an ADT instance, recursively call this routine o/ + else if (typecode == OCI_TYPECODE_ADT || typecode == + OCI_TYPECODE_UNNAMEDADT) + { + /o get the type ref of the attribute o/ + if (ortgarf(env, ado, &attr_type_ref) != OROSTASUC) + /o error handling code o/ + + display(attr_type_ref, attr, null_info, 0, names, 0, names_length, + indexes, 0); + } + + /o if attribute is scalar, print the value to the screen o/ + else output_to_screen(attr, typecode); + } + } + + /o ******** main routine *********** o/ + .... + + /o + o Allocate the arrays for storing the path expression + o/ + + /o get the tdo of type 'long' o/ + if (orttypget(&env, con, "SYS", sizeof("SYS"), "SINT32", sizeof("SINT32"), + OROOPDSES, &long_ref, &long_tdo) != OROSTASUC) + /o error handling code o/ + + /o get the tdo of type 'varchar' o/ + if (orttypget(&env, con, "SYS", sizeof("SYS"), "SQL_VARCHAR2", + sizeof("SQL_VARCHAR2"), OROOPDSES, &vchar_ref, &vchar_tdo) + != OROSTASUC) + /o error handling code o/ + + /o allocate the varrays for the path expression o/ + if (orlalloc(env, &vchar_ref, MAX_ARR_SIZE, &attr_names) != OROSTASUC) + /o error handling code o/ + + if (orlalloc(env, &long_ref, MAX_ARR_SIZE, &attr_name_lengths) + != OROSTASUC) + /o error handling code o/ + + if (orlalloc(env, &long_ref, MAX_ARR_SIZE, &attr_name_indexes) + != OROSTASUC) + /o error handling code o/ + + /o + o Get an ADT instance. The ref to the ADT instance can be obtained + o by through ORI or OSCI. + o/ + if (OCIObjectPin(env, &obj_ref, OROOPOCUR, OROOPDTRA, OROOLMUPD, &object) + != OROSTASUC) + /o error handling code o/ + + /o get the null structure of the ADT instance o/ + if (OCIObjectGetInd(gp, object, &null_struct) != OROSTASUC) + /o error handling code o/ + + /o + o Get the type of the ADT instance + o/ + + /o find out the type of the ADT instance o/ + if (oriogto(env, object, &adt_ref) != OROSTASUC) + /o error handling code o/ + + /o display the object o/ + display(adt_ref, object, null_struct, attr_names, 0, attr_names_lengths, + attr_names_indexes, 0); + + /o After the object is displayed, the program waits for the user to + o respond. The user modifies the values of an attribute and the + o program generates a path expression for the attribute and calls + o OCIObjectSetAttr() to set the value. + o/ + + if (OCIObjectSetAttr(env, object, null_struct, adt_ref, + (text **)attr_names, (ub4 *)attr_name_lengths, + attr_names_count, (ub4 *)attr_array_indexes, + attr_array_indexes_count, + (void *)0, FALSE, (void *)value) != OROSTASUC) + /o error handling code o/ + + END OF EXAMPLE 1 + + NOTES + + This file has been subsetted to contain only the routines that will + be in the first release. + + MODIFIED + dmukhin 06/29/05 - ANSI prototypes; miscellaneous cleanup + srseshad 03/12/03 - convert oci public api to ansi + aahluwal 06/03/02 - bug 2360115 + bpalaval 02/09/01 - Change text to oratext. + whe 09/01/99 - 976457:check __cplusplus for C++ code + sthakur 09/18/97 - collection indexing not supported + cxcheng 08/05/97 - fix compile with short names + skrishna 03/18/97 - fix ifdef for supporting ansi and k&r proto-types + cxcheng 02/06/97 - take out short name support except with SLSHORTNAME + cxcheng 10/17/96 - final renaming of functions + jboonleu 10/07/96 - beautify with OCI long names + cxcheng 10/07/96 - change short names to long names for readability + jboonleu 09/27/96 - fix lint + jwijaya 07/03/96 - add ANSI prototypes + jboonleu 04/13/95 - new interface + jwijaya 10/11/94 - fix the sccs header and add namespace + tanguyen 08/22/94 - fix example + tanguyen 08/09/94 - remove Sccsid declaration + tanguyen 07/20/94 - fix OCIObjectSetAttr and OCIObjectGetAttr to + use position descriptor + tanguyen 07/18/94 - change 'object' type to become ptr to object + tanguyen 06/30/94 - Fix the ORID_ORACLE ifdef + tanguyen 06/27/94 - update to template format + skotsovo 05/12/94 - replace ado with attribute position + jweisz 05/11/94 - test new checkin facility + jwijaya 05/05/94 - orienv/ref/typ -> oroenv/ref/typ + jwijaya 02/07/94 - Creation + +*/ + +#ifndef ORATYPES +#include +#endif +#ifndef ORO_ORACLE +#include +#endif +#ifndef OCI_ORACLE +#include +#endif + +#ifndef ORID_ORACLE +#define ORID_ORACLE + +#ifdef SLSHORTNAME + +#define OCIObjectSetAttr oridset +#define OCIObjectGetAttr oridget + +#endif /* SLSHORTNAME */ + +/*---------------------------------------------------------------------------*/ +/* PUBLIC FUNCTIONS */ +/*---------------------------------------------------------------------------*/ + +/*-------------------------- OCIObjectSetAttr ----------------------------*/ +sword OCIObjectSetAttr( OCIEnv *env, OCIError *err, void *instance, + void *null_struct, struct OCIType *tdo, + const oratext **names, const ub4 *lengths, + const ub4 name_count, const ub4 *indexes, + const ub4 index_count, const OCIInd null_status, + const void *attr_null_struct, const void *attr_value ); +/* + NAME: OCIObjectSetAttr - ORID SET value + PARAMETERS: + env (IN) - OCI environment handle initialized in object mode + err (IN) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + instance (IN) - pointer to an ADT instance + null_struct (IN) - the null structure of the ADT instance or array + tdo (IN) - pointer to the TDO + names (IN) - array of attribute names. This is used to specify + the names of the attributes in the path expression. + lengths (IN) - array of lengths of attribute names. + name_count (IN) - number of element in the array 'names'. + indexes (IN) [OPTIONAL] - currently NOT SUPPORTED, pass (ub4 *)0. + index_count (IN) [OPTIONAL] - currently NOT SUPPORTED, pass (ub4)0. + attr_null_status (IN) - the null status of the attribute if the type of + attribute is primitive. + attr_null_struct (IN) - the null structure of an ADT or collection + attribute. + attr_value (IN) - pointer to the attribute value. + REQUIRES: + DESCRIPTION: + This function set the attribute of the given object with the given + value. The position of the attribute is specified as a path + expression which is an array of names and an array of indexes. + RETURNS: + one of OROSTA* + EXAMPLES: + For path expression stanford.cs.stu[5].addr, the arrays will look like + names = {"stanford", "cs", "stu", "addr"} + lengths = {8, 2, 3, 4} + indexes = {5} + + Also see the above example. + */ + +/*-------------------------- OCIObjectGetAttr ----------------------------*/ +sword OCIObjectGetAttr( OCIEnv *env, OCIError *err, void *instance, + void *null_struct, struct OCIType *tdo, + const oratext **names, const ub4 *lengths, + const ub4 name_count, const ub4 *indexes, + const ub4 index_count, OCIInd *attr_null_status, + void **attr_null_struct, void **attr_value, + struct OCIType **attr_tdo ); +/* + NAME: OCIObjectGetAttr - ORID GET value + PARAMETERS: + env (IN) - OCI environment handle initialized in object mode + err (IN) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + instance (IN) - pointer to an ADT instance + null_struct (IN) - the null structure of the ADT instance or array + tdo (IN) - pointer to the TDO + names (IN) - array of attribute names. This is used to specify + the names of the attributes in the path expression. + lengths (IN) - array of lengths of attribute names. + name_count (IN) - number of element in the array 'names'. + indexes (IN) [OPTIONAL] - currently NOT SUPPORTED, pass (ub4 *)0. + index_count (IN) [OPTIONAL] - currently NOT SUPPORTED, pass (ub4)0. + attr_null_status (OUT) - the null status of the attribute if the type + of attribute is primitive. + attr_null_struct (OUT) - the null structure of an ADT or collection + attribute. + attr_value (OUT) - pointer to the attribute value. + attr_tdo (OUT) - pointer to the TDO of the attribute. + REQUIRES: + - a valid OCI environment handle must be given. + DESCRIPTION: + This function gets a value from an ADT instance or from an array. + If the parameter 'instance' points to an ADT instance, then the path + expression specifies the location of the attribute in the ADT. + It is assumed that the object is pinned and that the value returned + is valid until the object is unpinned. + RETURNS: + one of OROSTA* + EXAMPLES: + See example in OCIObjectSetAttr(). Also see the above example. + */ + +#endif /* ORID_ORACLE */ diff --git a/libodbc/include/ora_linux/orl.h b/libodbc/include/ora_linux/orl.h new file mode 100644 index 0000000000..61b0267eb6 --- /dev/null +++ b/libodbc/include/ora_linux/orl.h @@ -0,0 +1,3633 @@ +/* Copyright (c) 1993, 2006, Oracle. All rights reserved. */ + +/* + Author: Srinath Krishnaswamy + Date: 11/24/93 + Source documents: "Functional Specification for C Language Mapping of + OTS Types, Object Management Subsystem", "Oracle C + Coding Standards version 2.2", and the header file + template + Rule sets: the generic and .h file rule sets + Quality status: not exited + Identification tag: [ one or more letters to identify the .h file ] + Revision code: 11/24/93 + + NAME + + ORL - ORacle's external C Language interface to primitive OTS types + + DESCRIPTION + + This header file contains C langauge interface to the OTS primitive + types. The interface includes C mapping of OTS primitive types and + the prototype of the pre-defined operations on the primitive types. + + *********************************************************************** + *** NOTE: The OCI functions for objects requires the *** + *** application to be running in OBJECT mode. That is, during *** + *** process initialization OCIInitialize(), the mode *** + *** specified should be OBJECT mode. *** + ** OCIInitialize(OCI_OBJECT, ..); *** + *********************************************************************** + + RELATED DOCUMENTS + + [1] Krishnaswamy, Srinath and Nguyen, Tin A., "Functional Specification + for C Language Mapping of OTS Types, Object Management Subsystem", + March 1994. + [2] Nguyen, Tin A., "The Open Type System", Oracle Corporation, + February 1994. + [3] Klein, Jonathan D., "Large Field Management", Oracle Corporation, + October 1993. + + PUBLIC FUNCTIONS + + OCI - OCI functions to manipulate Oracle Number, float and decimal + ARITHMETIC + OCINumberInc - OCINumber INCrement (optimized) + OCINumberDec - OCINumber DECrement (optimized) + OCINumberAdd - OCINumber ADD numbers + OCINumberSub - OCINumber SUBtract numbers + OCINumberMul - OCINumber MULtiply numbers + OCINumberDiv - OCINumber DIVide numbers + OCINumberMod - OCINumber MODulo division + OCINumberIntPower - OCINumber integer PoWeR + OCINumberShift - OCINumber decimal ShiFT number + OCINumberNeg - OCINumber NEGate number + OCINumberAbs - OCINumber ABSolute value + OCINumberCeil - OCINumber CEiling of number + OCINumberFloor - OCINumber FLooR of number + OCINumberSqrt - OCINumber SQuare Root of number + OCINumberSign - OCINumber get SIGN of number + NATIVE TYPE CONVERSION + OCINumberToInt - OCINumber convert number TO machine-format Integer + OCINumberFromInt - OCINumber convert machine-format Integer TO Number + OCINumberToReal - OCINumber convert number TO machine-format Real + OCINumberToRealArray - OCINumber convert array of numbers TO + machine-format Real + OCINumberFromReal - OCINumber convert machine-format Real TO Number + TEXT STRING CONVERSION + OCINumberToText - OCINumber convert number TO String + OCINumberFromText - OCINumber convert String TO Number + COMPARISON + OCINumberCmp - OCINumber CoMPare numbers + OCINumberIsZero - OCINumber comparison with ZERo + OCINumberIsInt - OCINumber Is an Integer + ASSIGNMENT + OCINumberAssign - OCINumber ASsiGn number + OCINumberSetZero - OCINumber Set number to Zero value + OCINumberSetPi - OCINumber Set number to Pi + ROUNDING + OCINumberTrunc - OCINumber TRUncate an Oracle number + OCINumberRound - OCINumber ROUnd number + OCINumberPrec - OCINumber round to Precision digits + TRANSCENDENTAL + OCINumberSin - OCINumber SINe + OCINumberArcSin - OCINumber Arc SINe + OCINumberHypSin - OCINumber SiNe Hyperbolic + OCINumberCos - OCINumber COSine + OCINumberArcCos - OCINumber Arc COSine + OCINumberHypCos - OCINumber CoSine Hyperbolic + OCINumberTan - OCINumber TANgent + OCINumberArcTan - OCINumber Arc TANgent + OCINumberArcTan2 - OCINumber Arc TaNgent 2 + OCINumberHypTan - OCINumber TaNgent Hyperbolic + OCINumberPower - OCINumber arbitrary Base EXponentiation + OCINumberExp - OCINumber EXPonentiation to base e + OCINumberLn - OCINumber Logarithm Natural + OCINumberLog - OCINumber LOGarithm to arbitrary base + + OCIDate - OCI functions to manipulate OCI Date + OCIDateToExternal - OCIDate convert date to external form + OCIDateFromExternal - OCIDate convert external form of date into OCIDate + OCIDateAssign - OCIDate Assignment + OCIDateToText - OCIDate convert date TO String + OCIDateFromText - OCIDate convert String TO Date + OCIDateZoneToZone - OCIDate convert date from one time + Zone TO another Zone + OCIDateCompare - OCIDate CoMPare dates + OCIDateAddMonths - OCIDate ADd or subtract Months + OCIDateAddDays - OCIDate ADd or subtract Days + OCIDateLastDay - OCIDate get date of LaST day of month + OCIDateDaysBetween - OCIDate get number of days BeTWeen two dates + OCIDateNextDay - OCIDate get date of Next DaY + OCIDateCheck - OCIDate CHecK if the given date is valid + OCIDateSysDate - OCIDate get current SYStem date and time + + OCIString - OCI String functions to manipulate Variable-length string + OCIStringAssign - OCIString Assign string to string + OCIStringAssignText - OCIString Assign Text string to string + OCIStringResize - OCIString ReSiZe string + OCIStringSize - OCIString get String Size + OCIStringPtr - OCIString get String PoinTeR + OCIStringAllocSize - OCIString get Allocated SiZe + + OCIRaw - OCI Raw functions to manipulate variable-length raW + OCIRawAssignRaw - OCIRaw Assign Raw (of type OCIRaw*) to raw + (of type OCIRaw*) + OCIRawResize - OCIRaw Resize raw + OCIRawSize - OCIRaw get Raw Size + OCIRawPtr - OCIRaw get Raw data Pointer + OCIRawAllocSize - OCIRaw get Allocated Size + + OCIColl - OCI Collection generic functions. These functions can be + used to manipulate both variable-length array (varray) and + nested table. + OCICollSize - OCIColl return current SIZe of the given collection + (in number of elements) + OCICollMax - OCIColl return the MAXimum number of elements in the + collection (i.e. upper-bound) + OCICollGetElem - OCIColl GET pointer to the element at the given + position + OCICollAssignElem - OCIColl assign to element at given index + OCICollAssign - OCIColl ASsiGn collection; perform deep-copy of source + collection to target collection + OCICollAppend - OCIColl aPPend the given element to the end of the + collection + OCICollTrim - OCIColl trim (delete) the given number of elements + from the end of the collection + OCICollIsLocator - OCIColl indicates whether a collection is locator + based or not. + OCIIterCreate - OCIColl Create an ITerator to scan the collection + elements + OCIIterDelete - OCIColl Delete ITerator + OCIIterInit - OCIColl Initialize ITerator to scan the given collection + OCIIterGetCurrent - OCIColl Iterator based, get CURrent + collection element + OCIIterNext - OCIColl Iterator based, get NeXT collection element + OCIIterPrev - OCIColl Iterator based, get PReVious collection element + + OCITable - OCI functions to manipulate nested Table. The OCIColl*() and + OCITable*() functions can be used to manipulate nested table + OCITableDelete(i) - OCITable if element(i) exists then the element is + marked as deleted else the function returns false. So + delete's create "holes". + OCITableExists(i) - OCITable return true iff an element at + position i EXIsts + OCITableFirst - OCITable return the smallest value of i for which + exists(i) is true. + OCITableLast - OCITable return the largest value of i for which + exists(i) is true. + OCITableNext(i) - OCITable return pointer to the smallest position j, + greater than i, such that OCITableExists(j) is true + OCITablePrev(i) - OCITable return pointer to the largest position j, + less than i, such that OCITableExists(j) is true + OCITableSize - OCITable return current SIZe of the given nested table not + including deleted elements + + OCIRef - OCI functions to manipulate object Reference + OCIRefClear - OCIRef CLeaR or nullify a ref + OCIRefAssign - OCIRef ASsiGn a ref to another + OCIRefIsEqual - OCIRef compare two refs for EQUality + OCIRefIsNull - OCIRef test if a ref is NULl + OCIRefFromHex - OCIRef convert a Hexadecimal string TO a Ref + OCIRefToHex - OCIRef convert a ref to a Hexadecimal string + OCIRefHexSize - OCIRef get size of buffer in bytes to store hexadecimal + string + + OBSOLETE: to be replaced by functions from oci.h: + + ORLL - ORL functions to manipulate lob Locators + orllasg - ORLL AsiGn one locator to another + orllequ - ORLL compare two locators for EQUality + orlliini - ORLL Is the locator INItialized? + orllgsz - ORLL Get locator SiZe + orllgcid - ORLL Get Character set ID + + NOTE: The following are specific to FILE lobs: + + orllsnm - ORLL Set directory alias and file NaMe in the locator + orllgnm - ORLL Get directory alias and file NaMe from the locator + + EXAMPLES + + Examples are given in the description of each function where + relevant. + + NOTES + + This file has been subsetted to contain ONLY the routines that will + be in the first release. + + QUESTIONS + + MODIFIED + bkhaladk 08/01/05 - add defn for OCIBinXmlReposCtx + dmukhin 06/29/05 - ANSI prototypes; miscellaneous cleanup + srseshad 03/12/03 - convert oci public api to ansi + rpingte 11/21/02 - Add OCICollGetElemArray and OCINumberToRealArray + aahluwal 06/03/02 - bug 2360115 + gayyappa 02/01/02 - fix 2210776 : change Dom to DOM + whe 09/25/01 - add OCIXMLType & OCIDomDocument opaque types + bpalaval 02/09/01 - Change text to oratext. + rkasamse 09/20/99 - lint changes + whe 09/01/99 - 976457:check __cplusplus for C++ code + hsbedi 08/11/99 - Add macro + rxgovind 10/14/98 - make non exposed calls (OCIRowType etc) private + rxgovind 06/09/98 - update OCIRowTypeCreate + nmantrav 05/11/98 - add OCIRowTypeGetCount + rxgovind 03/29/98 - add OCIRowType and OCIRowData interfaces + jwijaya 05/06/98 - add OCICollIsLocator + rxgovind 03/18/98 - opaque types: move to kolo.h + etucker 02/02/98 - add comments for Dec and Inc + etucker 01/29/98 - Finish core5 integration + rxgovind 11/11/97 - opaque types + etucker 10/28/97 - add ORLN functions for SDK + cxcheng 07/28/97 - remove OCILobLocator #define + skmishra 05/13/97 - stdcc compatibility changes + skrishna 04/25/97 - rename OCINumber*(): Exp Power TanHyp Zero Init + TanToArc Sqr Truncate and Compare + skotsovo 03/31/97 - remove OCILobLocatorSize + skrishna 03/25/97 - remove orld2i and orldi2d + skrishna 03/18/97 - fix ifdef for supporting ansi and k&r proto-types + cxcheng 02/06/97 - take out short name support except with SLSHORTNAME + skrishna 01/06/97 - update OCITableSize() comments + skrishna 12/27/96 - fix OCIDateGet/OCIDateSet + skrishna 12/12/96 - update OCICollGelElem comments + skrishna 11/07/96 - OCICollGetElem: interface change + skrishna 11/05/96 - add OCIDate Get/Set and OCIDateAssign + cxcheng 10/31/96 - change OCINumberTanHyp to OCINumberHypTan + cxcheng 10/30/96 - #define orll short names to long names + dchatter 10/26/96 - fix some OCI file long names + cxcheng 10/24/96 - remove unnecessary comment in front + cxcheng 10/14/96 - disable long name mapping for LOB functions + skrishna 10/13/96 - continue beautification + skotsovo 10/16/96 - update ocilob names + cxcheng 10/09/96 - add structure members in #define for date/time + cxcheng 10/09/96 - more lint fixes + skrishna 10/09/96 - continue beautification + cxcheng 10/09/96 - more fixes + skrishna 10/09/96 - change fixed-char rep. to orlvstr* + jwijaya 10/08/96 - continue beautification + jwijaya 10/07/96 - beautify + cxcheng 10/07/96 - more changes + cxcheng 10/04/96 - replace short names with long names + skrishna 10/01/96 - orlcsiz, orltsiz: change prototype to take errhdl + skrishna 09/23/96 - fix lint errors + skotsovo 09/23/96 - remove orllmkcur(). + jwijaya 09/17/96 - comments on null ref + skrishna 09/19/96 - change orlraw format + skotsovo 09/19/96 - add orlliini and remove orllnul + skrishna 08/14/96 - orlvstr: change format to ub4 followed by text + jboonleu 08/06/96 - update comment + skotsovo 08/08/96 - revert to locators instead of descriptors as input t + jboonleu 07/23/96 - remove orlrcur + skrishna 07/06/96 - add orltsiz + skrishna 07/05/96 - add orld2i and orldi2d + jwijaya 07/03/96 - add ANSI prototypes + skrishna 06/27/96 - document default string format in orlds2d & orld2s + skrishna 06/25/96 - change max date value + skrishna 06/18/96 - modify orld2s() comments + skotsovo 06/13/96 - orll functions take lob descriptors instead of locat + rxgovind 06/05/96 - change prototype of orlrcur to take ocienvh + skrishna 05/30/96 - support collection trimming + skrishna 05/30/96 - remove orlralo/fre and orllalo/fre instead use + orionew/fre + skrishna 05/28/96 - add orlt*() and modify orla*() + skotsovo 05/23/96 - add orlbl typedefs for pro*c + jboonleu 05/14/96 - add orlrcur + rxgovind 05/08/96 - changes for 3gl callbacks + skotsovo 05/01/96 - in orllasg, no need to alloc orlbl* + skrishna 04/21/96 - merge changes from 960418 object branch into big + skrishna 04/17/96 - rename orlrcpy to orlrasg + skrishna 04/12/96 - add orlr2h and orlrh2r functions + skotsovo 04/15/96 - add fnt to make the lob locator current + skrishna 04/08/96 - change orl*() to take ocienvh* and ocierrh* instead + of oroenv* + skotsovo 03/22/96 - add locator functions + skotsovo 03/22/96 - add locator functions + skrishna 02/27/96 - remove mlslabel interface + skotsovo 02/20/96 - remove orlbty and use dty type instead. + skotsovo 02/14/96 - add text file lobs. + skrishna 01/31/96 - update comments of orln2r, orldchk, orlds2d & orld2s + skrishna 01/31/96 - change orld2s() and orln2s() to return string length + skrishna 01/21/96 - remove old raw interface + skrishna 12/14/95 - add raw interface + skotsovo 01/03/96 - change LOB offsets and lengths from ub4 to ubig_ora + to support 64 bit machines. + skotsovo 10/30/95 - add orlblsiz() to get lob locator size + skrishna 10/24/95 - move ref functions from ori and update the ref + functions to support variable-length ref + cxcheng 10/20/95 - add more comments on number versions + cxcheng 10/13/95 - add more number functions + cxcheng 08/29/95 - Support for segmented varrays + cxcheng 08/18/95 - modifiy orlmls structure + skrishna 06/06/95 - rename orln, orld, orlvs and orlva to orlnum, + orldat, orlvstr and orlvary respectively + skrishna 11/15/94 - remove orlnget() function + skrishna 09/20/94 - modify orldbtw() to return number of days only + skrishna 08/24/94 - change format string length type from ub4 to ub1 + skrishna 07/19/94 - Rename orln2c & orlnc2n to orln2s & orlns2n + skrishna 06/29/94 - Add blob interface; add examples + skrishna 06/23/94 - Update comments and format + skrishna 05/19/94 - update varray append comments + skrishna 05/05/94 - Subsetting + skrishna 11/24/93 - Creation +*/ + +#ifndef ORATYPES +#include +#endif + +#ifndef ORO_ORACLE +#include +#endif + +#ifndef ORT_ORACLE +#include +#endif + +#ifndef OCI_ORACLE +#include +#endif + +#ifndef ORL_ORACLE +#define ORL_ORACLE + +/*---------------------------------------------------------------------------*/ +/* SHORT NAMES SUPPORT SECTION */ +/*---------------------------------------------------------------------------*/ + +#ifdef SLSHORTNAME + +/* the following are short names that are only supported on IBM mainframes + with the SLSHORTNAME defined. + With this all subsequent long names will actually be substituted with + the short names here */ + +#define OCIArray orlvary +#define OCIColl orlcol +#define OCICollAppend orlcapp +#define OCICollAssign orlcasg +#define OCICollAssignElem orlcase +#define OCICollGetElem orlcget +#define OCICollGetElemArray orlcgeta +#define OCICollMax orlcmax +#define OCICollSize orlcsiz +#define OCICollTrim orlctrm +#define OCICollIsLocator orlcilc +#define OCIDate orldat +#define OCIDateAddDays orldadd +#define OCIDateAddMonths orldadm +#define OCIDateCheck orldchk +#define OCIDateCompare orldcmp +#define OCIDateDD day_orldat +#define OCIDateDaysBetween orldbtw +#define OCIDateFromText orlds2d +#define OCIDateLastDay orldlst +#define OCIDateMM mon_orldat +#define OCIDateNextDay orldndy +#define OCIDateSysDate orldsys +#define OCIDateTime time_orldat +#define OCIDateYYYY gye_orldat +#define OCIDateZoneToZone orldz2z +#define OCIIter orlcitr +#define OCIIterCreate orlccit +#define OCIIterDelete orlcdit +#define OCIIterGetCurrent orlcicur +#define OCIIterInit orlciit +#define OCIIterNext orlcinxt +#define OCIIterPrev orlciprv +#define OCINumber orlnum +#define OCINumberAbs orlnabs +#define OCINumberAdd orlnadd +#define OCINumberArcCos orlnacos +#define OCINumberArcSin orlnasin +#define OCINumberArcTan orlnatan +#define OCINumberAssign orlnasg +#define OCINumberCeil orlncel +#define OCINumberCos orlncos +#define OCINumberDiv orlndiv +#define OCINumberPower orlnbex +#define OCINumberFloor orlnflr +#define OCINumberFromInt orlni2n +#define OCINumberFromReal orlnr2n +#define OCINumberFromText orlns2n +#define OCINumberHypCos orlncsh +#define OCINumberHypSin orlnsnh +#define OCINumberSetZero orlnini +#define OCINumberSetPi orlnspi +#define OCINumberInc orlninc +#define OCINumberDec orlndec +#define OCINumberIntPower orlnpwr +#define OCINumberLn orlnln +#define OCINumberLog orlnlog +#define OCINumberMod orlnmod +#define OCINumberMul orlnmul +#define OCINumberNeg orlnneg +#define OCINumberPart orlnpart +#define OCINumberExp orlnexp +#define OCINumberRound orlnrou +#define OCINumberPrec orlnpre +#define OCINumberShift orlnsft +#define OCINumberSign orlnsgn +#define OCINumberSin orlnsin +#define OCINumberSqrt orlnsqr +#define OCINumberSub orlnsub +#define OCINumberTan orlntan +#define OCINumberHypTan orlntnh +#define OCINumberArcTan2 orlnatn2 +#define OCINumberToInt orln2i +#define OCINumberToReal orln2r +#define OCINumberToRealArray orln2ra +#define OCINumberToText orln2s +#define OCINumberTrunc orlntru +#define OCINumberCmp orlncmp +#define OCINumberIsZero orlnzer +#define OCINumberIsInt orlnint +#define OCIRaw orlraw +#define OCIRawAllocSize orlwasz +#define OCIRawAssignBytes orlwabr +#define OCIRawAssignRaw orlwarr +#define OCIRawPtr orlwgrp +#define OCIRawResize orlwrsz +#define OCIRawSize orlwgsz +#define OCIRefAssign orlrasg +#define OCIRefClear orlrclr +#define OCIRefFromHex orlrh2r +#define OCIRefHexSize orlrhsz +#define OCIRefIsEqual orlrequ +#define OCIRefIsNull orlrnul +#define OCIRefToHex orlr2h +#define OCIString orlvstr +#define OCIStringAllocSize orlvasz +#define OCIStringAssign orlvass +#define OCIStringAssignText orlvats +#define OCIStringPtr orlvgsp +#define OCIStringResize orlvrsz +#define OCIStringSize orlvgsz +#define OCITable orltbl +#define OCITableDelete orltdel +#define OCITableExists orltexi +#define OCITableFirst orltfst +#define OCITableLast orltlst +#define OCITableNext orltnxt +#define OCITablePrev orltprv +#define OCITableSize orltsiz +#define OCITime orldtm +#define OCITimeHH orldtmhh +#define OCITimeMI orldtmmm +#define OCITimeSS orldtmss +#define OCI_LOBMODE_READONLY ORLBMORO +#define OCI_LOBMODE_READWRITE ORLBMORW + +#endif /* SLSHORTNAME */ + +/*****************************************************************************/ +/* NUMBER/FLOAT/DECIMAL TYPE */ +/*****************************************************************************/ + +#define OCI_NUMBER_SIZE 22 +struct OCINumber +{ + ub1 OCINumberPart[OCI_NUMBER_SIZE]; +}; +typedef struct OCINumber OCINumber; + +/* + * OCINumber - OCI Number mapping in c + * + * The OTS types: NUMBER, NUMERIC, INT, SHORTINT, REAL, DOUBLE PRECISION, + * FLOAT and DECIMAL are represented by OCINumber. + * The contents of OCINumber is opaque to clients. + * + * For binding variables of type OCINumber in OCI calls (OCIBindByName(), + * OCIBindByPos(), and OCIDefineByPos()) use the type code SQLT_VNU. + */ + +/* + EXAMPLE + + The following example shows how to manipulate an attribute of type + oracle number. + + struct person + { + OCINumber sal; + }; + typedef struct person person; + + OCIError *err; + person* joe; + person* tom; + person* debbie; + OCINumber *joesal; + OCINumber *tomsal; + OCINumber *debsal; + sword status; + int inum; + double dnum; + OCINumber ornum; + char buffer[21]; + ub4 buflen; + sword result; + + /o See oci.h for an example of how to initialize OCIError. + o For this example, assume the OCIEnv and OCIError has been + o initialized. + o/ + + /o Pin joe, tom and debbie person objects in the object cache. See ori.h + o for an example on pinning objects. For this example, assume that + o joe, tom and debbie are pointing to pinned objects. + o/ + joesal = &joe->sal; + tomsal = &tom->sal; + debsal = &debbie->sal; + + /o initialize joe's salary to be $12,000 o/ + inum = 12000; + status = OCINumberFromInt(err, &inum, sizeof(inum), OCI_NUMBER_SIGNED, + joesal); + if (status != OCI_SUCCESS) + /o goto to handle error from OCINumberFromInt o/; + + /o initialize tom's salary to be same as joe o/ + OCINumberAssign(err, joesal, tomsal); + + /o initialize debbie's salary to be 20% more than joe's o/ + dnum = 1.2; + status = OCINumberFromReal(err, &dnum, sizeof(double), &ornum); + if (status != OCI_SUCCESS) + /o goto to handle error from OCINumberFromReal o/; + status = OCINumberMul(err, joesal, &ornum, debsal); + if (status != OCI_SUCCESS) /o goto to handle error from OCINumberMul o/; + + /o give tom a 50% raise o/ + dnum = 1.5; + status = OCINumberFromReal(err, &dnum, sizeof(double), &ornum); + if (status != OCI_SUCCESS) + /o goto to handle error from OCINumberFromReal o/; + status = OCINumberMul(err, tomsal, &ornum, tomsal); + if (status != OCI_SUCCESS) /o goto to handle error from OCINumberMul o/; + + /o double joe's salary o/ + status = OCINumberAdd(err, joesal, joesal, joesal); + if (status != OCI_SUCCESS) /o goto to handle error from OCINumberAdd o/; + + /o get joe's salary in integer o/ + status = OCINumberToInt(err, joesal, sizeof(inum), OCI_NUMBER_SIGNED, + &inum); + if (status != OCI_SUCCESS)/o goto to handle error from OCINumberToInt o/; + /o inum is set to 24000 o/ + + /o get debbie's salary in double o/ + status = OCINumberToReal(err, debsal, sizeof(dnum), &dnum); + if (status != OCI_SUCCESS)/o goto to handle error from OCINumberToReal o/; + /o dnum is set to 14400 o/ + + /o print tom's salary as DEM0001`8000.00 o/ + buflen = sizeof(buffer); + status = OCINumberToText(err, tomsal, "C0999G9999D99", 13, + "NLS_NUMERIC_CHARACTERS='.`' NLS_ISO_CURRENCY='Germany'", 54, + &buflen, buffer); + if (status != OCI_SUCCESS)/o goto to handle error from OCINumberToText o/; + printf("tom's salary = %s\n", buffer); + + /o compare joe and tom's salary o/ + status = OCINumberCmp(err, joesal, tomsal, &result); + if (status != OCI_SUCCESS) /o goto to handle error from OCINumberCmp o/; + /o result is positive o/ + + /o read debbie's new salary from string o/ + status = OCINumberFromText(err, "48`000.00", 9, "99G999D99", 9, + "NLS_NUMERIC_CHARACTERS='.`'", 27, debsal); + if (status != OCI_SUCCESS) + /o goto to handle error from OCINumberFromText o/; + /o debbie's salary is now 48000.00 o/ + +*/ + +/*----------------------------- OCINumberInc --------------------------------*/ + +sword OCINumberInc( OCIError *err, OCINumber *number ); +/* + NAME: OCINumberInc - OCINumber INCrement numbers + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN/OUT) a positive Oracle number to be incremented + DESCRIPTION: + Increment Oracle number in place. It is assumed that the input is + an integer between 0 and 100^21-2. If the is input too large, it will + be treated as 0 - the result will be an Oracle number 1. If the input + is not a positive integer, the result will be unpredictable. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + */ + +/*----------------------------- OCINumberDec --------------------------------*/ + +sword OCINumberDec( OCIError *err, OCINumber *number ); +/* + NAME: OCINumberDec - OCINumber DECrement numbers + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN/OUT) - a positive Oracle number to be decremented + DESCRIPTION: + Decrement Oracle number in place. It is assumed that the input is an + integer between 1 and 100^21-2. If the input is too large, it will be + treated as 1 - the result will be an Oracle number 0. If the input is + not a positive integer, the result will be unpredictable. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + */ + +/*-------------------------- OCINumberSetZero -------------------------------*/ + +void OCINumberSetZero( OCIError *err, OCINumber *num ); +/* + NAME: OCINumberSetZero - OCINumber Set number to Zero value + PARAMETERS: + err (IN/OUT) - pointer to OCI error handle + num (OUT) - set to zero value + DESCRIPTION: + Initialize the given number to value 0. + */ + +/*--------------------------- OCINumberSetPi --------------------------------*/ + +void OCINumberSetPi( OCIError *err, OCINumber *num ); +/* + NAME: OCINumberSetPi - OCINumber Set number to Pi + err (IN/OUT) - pointer to OCI error handle + num (OUT) - set to zero value + DESCRIPTION: + Initialize the given number to value Pi. + */ + +/*----------------------------- OCINumberAdd --------------------------------*/ + +sword OCINumberAdd( OCIError *err, const OCINumber *number1, + const OCINumber *number2, OCINumber *result ); +/* + NAME: OCINumberAdd - OCINumber ADD numbers + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number1, number2 (IN) - numbers to be added + result (OUT) - result of adding 'number1' with 'number2' + DESCRIPTION: + Add 'number1' with 'number2' and return result in 'result'. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + */ + +/*----------------------------- OCINumberSub --------------------------------*/ + +sword OCINumberSub( OCIError *err, const OCINumber *number1, + const OCINumber *number2, OCINumber *result ); +/* + NAME: OCINumberSub - OCINumber SUBtract numbers + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number1, number2 (IN) - 'number2' subtracted from 'number1' + result (OUT) - subtraction result + DESCRIPTION: + Subtract 'number2' from 'number1' and return result in 'result'. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + */ + +/*----------------------------- OCINumberMul --------------------------------*/ + +sword OCINumberMul( OCIError *err, const OCINumber *number1, + const OCINumber *number2, OCINumber *result ); +/* + NAME: OCINumberMul - OCINumber MULtiply numbers + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number1, number2 (IN) - numbers to be multiplied + result (OUT) - multiplication result + DESCRIPTION: + Multiply 'number1' with 'number2' and return result in 'result'. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + */ + +/*----------------------------- OCINumberDiv --------------------------------*/ + +sword OCINumberDiv( OCIError *err, const OCINumber *number1, + const OCINumber *number2, OCINumber *result ); +/* + NAME: OCINumberDiv - OCINumber DIVide numbers + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number1 (IN) - pointer to the numerator + number2 (IN) - pointer to the denominator + result (OUT) - division result + DESCRIPTION: + Divide 'number1' by 'number2' and return result in 'result'. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + underflow errorr + overflow errorr + divide by zero errorr + */ + +/*----------------------------- OCINumberMod --------------------------------*/ + +sword OCINumberMod( OCIError *err, const OCINumber *number1, + const OCINumber *number2, OCINumber *result ); +/* + NAME: OCINumberMod - OCINumber MODulous + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number1 (IN) - pointer to the numerator + number2 (IN) - pointer to the denominator + result (OUT) - remainder of the result + DESCRIPTION: + Finds the remainder of the division of two Oracle numbers. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + divide by zero errorr + */ + +/*------------------------ OCINumberIntPower --------------------------------*/ + +sword OCINumberIntPower( OCIError *err, const OCINumber *base, + const sword exp, OCINumber *result ); +/* + NAME: OCINumberIntPower - OCINumber takes an arbitary base to an arbitary + integer PoWeR + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + base (IN) - base of the exponentiation + exp (IN) - exponent to which the base is to be raised + result (OUT) - output of exponentiation + DESCRIPTION: + Takes an arbitary base to an arbitary integer power. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + */ + +/*-------------------------- OCINumberShift ---------------------------------*/ + +sword OCINumberShift( OCIError *err, const OCINumber *number, + const sword nDig, OCINumber *result ); +/* + NAME: OCINumberShift - OCINumber multiplies by a power of 10. + + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - Oracle Number to be shifted. + nDig (IN) - number of decimal places to shift. + result (OUT) - shift result. + DESCRIPTION: + Multiplies number by 10^NDig and sets product to the result. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + */ + +/*----------------------------- OCINumberNeg --------------------------------*/ + +sword OCINumberNeg( OCIError *err, const OCINumber *number, + OCINumber *result ); +/* + NAME: OCINumberNeg - OCINumber NEGate number + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - number to be negated + result (OUT) - will contain negated value of 'number' + DESCRIPTION: + Negates an Oracle number. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + */ + +/*------------------------- OCINumberToText ---------------------------------*/ + +sword OCINumberToText( OCIError *err, const OCINumber *number, + const oratext *fmt, ub4 fmt_length, + const oratext *nls_params, ub4 nls_p_length, + ub4 *buf_size, oratext *buf ); +/* + NAME: OCINumberToText - OCINumber convert number TO String + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - Oracle number to be converted + fmt (IN) - conversion format + fmt_length (IN) - length of the 'fmt' parameter + nls_params (IN) - nls format specification, if null string + i.e. (oratext *)0, then the default parameters for the + session is used + nls_p_length (IN) - length of the 'nls_params' parameter + buf_size (IN/OUT) - size of the buffer must be passed as input by + the caller, this function will return the length of the + resulting string in bytes via this parameter. The length + does not include the terminating null ('\0'). + buf (OUT) - buffer into which the converted string is placed. The + resulting string is null terminated. + DESCRIPTION: + Converts the given number to a character string + according to the specified format. Refer to "TO_NUMBER" conversion + function described in "Oracle SQL Language Reference Manual" for a + description of format and NLS parameters. + The converted number string is stored in the buffer 'buf', up to + a max of '*buf_size' bytes. Length of the resulting string is + returned via 'buf_size'. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + 'number' or 'buf' is null + buffer too small + invalid format + invalid nls format + number to text translation for the given format causes overflow + */ + +/*-------------------------- OCINumberFromText ------------------------------*/ + +sword OCINumberFromText( OCIError *err, const oratext *str, + ub4 str_length, const oratext *fmt, ub4 fmt_length, + const oratext *nls_params, ub4 nls_p_length, + OCINumber *number ); +/* + NAME: OCINumberFromText - OCINumber convert String TO Number + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + str (IN) - input string to be converted to Oracle number + str_length (IN) - size of the input string + fmt (IN) - conversion format + fmt_length (IN) - length of the 'fmt' parameter + nls_params (IN) - nls format specification, if null string + i.e. (oratext *)0, then the default parameters for the + session is used + nls_p_length (IN) - length of the 'nls_params' parameter + number (OUT) - given string converted to number + DESCRIPTION: + Converts the given string to a number + according to the specified format. Refer to "TO_NUMBER" conversion + function described in "Oracle SQL Language Reference Manual" for a + description of format and NLS parameters. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + 'number' or 'str' is null + 'str_length' is 0 + invalid format + invalid nls format + invalid input string + */ + +/*-------------------------- OCINumberToInt ---------------------------------*/ + +#define OCI_NUMBER_UNSIGNED 0 /* Unsigned type -- ubX */ +#define OCI_NUMBER_SIGNED 2 /* Signed type -- sbX */ + +sword OCINumberToInt( OCIError *err, const OCINumber *number, + uword rsl_length, uword rsl_flag, void *rsl ); +/* + NAME: OCINumberToInt - OCINumber convert number TO Integer + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - number to be converted + rsl_length (IN) - size of the desired result + rsl_s_flag (IN) - flag denoting the desired sign of the output; valid + values are OCI_NUMBER_UNSIGNED, OCI_NUMBER_SIGNED + rsl (OUT) - pointer to space for the result + DESCRIPTION: + Native type conversion function. + Converts the given Oracle number into an xbx (e.g. ub2, ub4, sb2 etc.) + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + 'number' or 'rsl' is null + integer value of 'number' is too big -- overflow + integer value of 'number' is too small -- underflow + invalid sign flag value ('rsl_s_flag') + */ + +/*--------------------------- OCINumberFromInt ------------------------------*/ + +sword OCINumberFromInt( OCIError *err, const void *inum, uword inum_length, + uword inum_s_flag, OCINumber *number ); +/* + NAME: OCINumberFromInt - OCINumber convert Integer TO Number + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + inum (IN) - pointer to the integer to be converted + inum_length (IN) - size of the integer + inum_s_flag (IN) - flag that designates the sign of the integer; valid + values are OCI_NUMBER_UNSIGNED, OCI_NUMBER_SIGNED + number (OUT) - given integer converted to Oracle number + DESCRIPTION: + Native type conversion function. Converts any Oracle standard + machine-native integer type (xbx) to an Oracle number. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + 'number' or 'inum' is null + integer too BIG -- the number is too large to fit into an Oracle + number + invalid sign flag value ('inum_s_flag') + */ + +/*------------------------- OCINumberToReal ---------------------------------*/ + +sword OCINumberToReal( OCIError *err, const OCINumber *number, + uword rsl_length, void *rsl ); +/* + NAME: OCINumberToReal - OCINumber convert number TO Real + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - number to be converted + rsl_length (IN) - is the size of the desired result, + sizeof( float | double | long double) + rsl (OUT) - pointer to space for storing the result + DESCRIPTION: + Native type conversion function. Converts an Oracle number into a + machine-native real type. This function only converts numbers up to + LDBL_DIG, DBL_DIG, or FLT_DIG digits of precision and removes + trailing zeroes. The above constants are defined in float.h + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + 'number' or 'rsl' is null + 'rsl_length' is 0 + */ + +/*------------------------- OCINumberToRealArray ----------------------------*/ + +sword OCINumberToRealArray( OCIError *err, const OCINumber **number, + uword elems, uword rsl_length, void *rsl ); +/* + NAME: OCINumberToRealArray - OCINumber convert array of numbers TO Real + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - Pointer to array of number to be converted + elems (IN) - Upper bound of number array + rsl_length (IN) - is the size of the desired result, + sizeof( float | double | long double) + rsl (OUT) - pointer to array of space for storing the result + DESCRIPTION: + Native type conversion function. Converts an Oracle number into a + machine-native real type. This function only converts numbers up to + LDBL_DIG, DBL_DIG, or FLT_DIG digits of precision and removes + trailing zeroes. The above constants are defined in float.h + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + 'number' or 'rsl' is null + 'rsl_length' is 0 + */ + +/*-------------------------- OCINumberFromReal ------------------------------*/ + +sword OCINumberFromReal( OCIError *err, const void *rnum, + uword rnum_length, OCINumber *number ); +/* + NAME: OCINumberFromReal - OCINumber convert Real TO Number + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + rnum (IN) - pointer to the floating point number to be converted + rnum_length (IN) - size of the desired result, i.e. + sizeof({float | double | long double}) + number (OUT) - given float converted to Oracle number + DESCRIPTION: + Native type conversion function. Converts a machine-native floating + point type to an Oracle number. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + 'number' or 'rnum' is null + 'rnum_length' is 0 + */ + +/*----------------------------- OCINumberCmp --------------------------------*/ + +sword OCINumberCmp( OCIError *err, const OCINumber *number1, + const OCINumber *number2, sword *result ); +/* + NAME: OCINumberCmp - OCINumber CoMPare numbers + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number1, number2 (IN) - numbers to be compared + result (OUT) - 0 if equal, negative if number1 < number2, + positive if number1 > number2 + DESCRIPTION: + The function OCINumberCmp compares two numbers. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + 'number1' or 'number2' or 'result' is null + */ + +/*---------------------------- OCINumberSign --------------------------------*/ + +sword OCINumberSign( OCIError *err, const OCINumber *number, + sword *result ); +/* + NAME: OCINumberSign - OCINumber obtains SiGN of an Oracle number + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - number whose sign is returned + result (OUT) - 0 if number == 0, -1 if number < 0, + 1 if number > 0 + DESCRIPTION: + Obtains sign of an Oracle number + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + 'number' or 'result' is null + */ + +/*---------------------------- OCINumberIsZero ------------------------------*/ + +sword OCINumberIsZero( OCIError *err, const OCINumber *number, + boolean *result ); +/* + NAME: OCINumberIsZero - OCINumber comparison with ZERo + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - numbers to be compared + result (OUT) - set to TRUE if equal to zero else FALSE + DESCRIPTION: + Test if the given number is equal to zero. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + 'number' or 'result' is null + */ + +/*---------------------------- OCINumberIsInt -------------------------------*/ + +sword OCINumberIsInt( OCIError *err, const OCINumber *number, + boolean *result ); +/* + NAME: OCINumberIsInt - OCINumber Is Integer value. + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - number to be tested + result (OUT) - set to TRUE if integer value else FALSE + DESCRIPTION: + Test if the given number is an integer value. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + 'number' or 'result' is null + */ + +/*-------------------------- OCINumberAssign --------------------------------*/ + +sword OCINumberAssign( OCIError *err, const OCINumber *from, + OCINumber *to ); +/* + NAME: OCINumberAssign - OCINumber ASsiGn number + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + from (IN) - number to be assigned + to (OUT) - number copied into + DESCRIPTION: + Assign number 'from' to 'to'. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + 'from' or 'to' is null + */ + +/*----------------------------- OCINumberAbs --------------------------------*/ + +sword OCINumberAbs( OCIError *err, const OCINumber *number, + OCINumber *result ); +/* + NAME: OCINumberAbs - OCINumber compute ABSolute value + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - input number + result (OUT) - output which will contain the absolue value of the + input number + DESCRIPTION: + Computes the absolute value of an Oracle number. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + */ + +/*---------------------------- OCINumberCeil --------------------------------*/ + +sword OCINumberCeil( OCIError *err, const OCINumber *number, + OCINumber *result ); +/* + NAME: OCINumberCeil - OCINumber compute the CEiL value of an Oracle number + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - input number + result (OUT) - output which will contain the ceil value of the + input number + DESCRIPTION: + Computes the ceil value of an Oracle number. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + */ + +/*--------------------------- OCINumberFloor --------------------------------*/ + +sword OCINumberFloor( OCIError *err, const OCINumber *number, + OCINumber *result ); +/* + NAME: OCINumberFloor - OCINumber compute the FLooR value of an Oracle number + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - input number + result (OUT) - output which will contain the floor value of the + input number + DESCRIPTION: + Computes the floor value of an Oracle number. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + */ + +/*----------------------------- OCINumberSqrt -------------------------------*/ + +sword OCINumberSqrt( OCIError *err, const OCINumber *number, + OCINumber *result ); +/* + NAME: OCINumberSqrt - OCINumber compute the SQuare Root of an Oracle number + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - input number + result (OUT) - output which will contain the square root of the + input number + DESCRIPTION: + Computes the square root of an Oracle number. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + 'number' is negative + */ + +/*--------------------------- OCINumberTrunc --------------------------------*/ + +sword OCINumberTrunc( OCIError *err, const OCINumber *number, + sword decplace, OCINumber *result ); +/* + NAME: OCINumberTrunc - OCINumber TRUncate an Oracle number at a + specified decimal place + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - input number + decplace (IN) - number of decimal digits to the right of the + decimal point to truncate at. Negative values are allowed. + result (OUT) - output of truncation + DESCRIPTION: + Truncate an Oracle number at a specified decimal place + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + */ + +/*----------------------------- OCINumberPower ------------------------------*/ + +sword OCINumberPower( OCIError *err, const OCINumber *base, + const OCINumber *number, OCINumber *result ); +/* + NAME: OCINumberPower - OCINumber takes an arbitary Base to an + arbitary Power + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + base (IN) - base of the exponentiation + number (IN) - exponent to which the base is to be raised + result (OUT) - output of exponentiation + DESCRIPTION: + Takes an arbitary base to an arbitary power. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + */ + +/*--------------------------- OCINumberRound --------------------------------*/ + +sword OCINumberRound( OCIError *err, const OCINumber *number, + sword decplace, OCINumber *result ); +/* + NAME: OCINumberRound - OCINumber ROUnds an Oracle number to a specified + decimal place + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - round this number and return result in 'result' + decplace (IN) - number of decimal digits to the right of the + decimal point to round to. Negative values are allowed. + result (OUT) - output of rounding + DESCRIPTION: + Rounds an Oracle number to a specified decimal place + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + */ + +/*--------------------------- OCINumberPrec ---------------------------------*/ + +sword OCINumberPrec( OCIError *err, const OCINumber *number, + sword nDigs, OCINumber *result ); +/* + NAME: OCINumberPrec - Rounds an Oracle number to a specified number of + decimal digits. + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - number for which to set precision. + nDig (IN) - number of decimal digits desired in the result. + result (OUT) - result. + DESCRIPTION: + Performs a floating point round with respect to the number + of digits. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + */ + +/*----------------------------- OCINumberSin --------------------------------*/ + +sword OCINumberSin( OCIError *err, const OCINumber *number, + OCINumber *result ); +/* + NAME: OCINumberSin - OCINumber takes the SINe of an Oracle number + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - argument of the sine in radians + result (OUT) - result of the sine + DESCRIPTION: + Takes the sine in radians of an Oracle number. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + */ + +/*-------------------------- OCINumberArcSin --------------------------------*/ + +sword OCINumberArcSin( OCIError *err, const OCINumber *number, + OCINumber *result ); +/* + NAME: OCINumberArcSin - OCINumber takes the Arc SINe of an Oracle number + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - argument of the arc sine + result (OUT) - result of the arc sine in radians + DESCRIPTION: + Takes the arc sine in radians of an Oracle number. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + 'number' is < -1 or 'number' is > 1. + */ + +/*-------------------------- OCINumberHypSin --------------------------------*/ + +sword OCINumberHypSin( OCIError *err, const OCINumber *number, + OCINumber *result ); +/* + NAME: OCINumberHypSin - OCINumber takes the SiNe Hyperbolic of an + Oracle number + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - argument of the sine hyperbolic + result (OUT) - result of the sine hyperbolic + DESCRIPTION: + Takes the hyperbolic sine of an Oracle number. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + NOTES: + An Oracle number overflow causes an unpredictable result value. + */ + +/*----------------------------- OCINumberCos --------------------------------*/ + +sword OCINumberCos( OCIError *err, const OCINumber *number, + OCINumber *result ); +/* + NAME: OCINumberCos - OCINumber takes the COSine of an Oracle number + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - argument of the cosine in radians + result (OUT) - result of the cosine + DESCRIPTION: + Takes the cosine in radians of an Oracle number. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + */ + +/*-------------------------- OCINumberArcCos --------------------------------*/ + +sword OCINumberArcCos( OCIError *err, const OCINumber *number, + OCINumber *result ); +/* + NAME: OCINumberArcCos - OCINumber takes the Arc COSine of an Oracle number + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - argument of the arc cosine + result (OUT) - result of the arc cosine in radians + DESCRIPTION: + Takes the arc cosine in radians of an Oracle number. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + 'number' is < -1 or 'number' is > 1. + */ + +/*-------------------------- OCINumberHypCos --------------------------------*/ + +sword OCINumberHypCos( OCIError *err, const OCINumber *number, + OCINumber *result ); +/* + NAME: OCINumberHypCos - OCINumber takes the CoSine Hyperbolic of an + Oracle number + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - argument of the cosine hyperbolic + result (OUT) - result of the cosine hyperbolic + DESCRIPTION: + Takes the hyperbolic cosine of an Oracle number. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + NOTES: + An Oracle number overflow causes an unpredictable result value. + */ + +/*----------------------------- OCINumberTan --------------------------------*/ + +sword OCINumberTan( OCIError *err, const OCINumber *number, + OCINumber *result ); +/* + NAME: OCINumberTan - OCINumber takes the TANgent of an Oracle number + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - argument of the tangent in radians + result (OUT) - result of the tangent + DESCRIPTION: + Takes the tangent in radians of an Oracle number. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + */ + +/*-------------------------- OCINumberArcTan --------------------------------*/ + +sword OCINumberArcTan( OCIError *err, const OCINumber *number, + OCINumber *result ); +/* + NAME: OCINumberArcTan - OCINumber takes the Arc TANgent of an Oracle number + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - argument of the arc tangent + result (OUT) - result of the arc tangent in radians + DESCRIPTION: + Takes the arc tangent in radians of an Oracle number. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + */ + +/*------------------------ OCINumberArcTan2 ---------------------------------*/ + +sword OCINumberArcTan2( OCIError *err, const OCINumber *number1, + const OCINumber *number2, OCINumber *result ); +/* + NAME: OCINumberArcTan2 - OCINumber takes the ATan2 of 2 Oracle numbers + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number1 (IN) - first argument of atan2(y,x) function which + corresponds to 'y' parameter in the function + number2 (IN) - second argument of atan2(y,x) function which + corresponds to 'x' parameter in the function + result (OUT) - result of the atan2() in radians + DESCRIPTION: + Takes the atan2(number1, number2). + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + 'number2' is 0 + */ + +/*----------------------------- OCINumberHypTan -----------------------------*/ + +sword OCINumberHypTan( OCIError *err, const OCINumber *number, + OCINumber *result ); +/* + NAME: OCINumberHypTan - OCINumber takes the TaNgent Hyperbolic of an Oracle + number + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - argument of the tangent hyperbolic + result (OUT) - result of the tangent hyperbolic + DESCRIPTION: + Takes the hyperbolic tangent of an Oracle number. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + NOTES: + An Oracle number overflow causes an unpredictable result value. + */ + +/*--------------------------- OCINumberExp ----------------------------------*/ + +sword OCINumberExp( OCIError *err, const OCINumber *number, + OCINumber *result ); +/* + NAME: OCINumberExp - OCINumber EXPonential + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - e raised to this Oracle number power + result (OUT) - output of exponentiation + DESCRIPTION: + Raises e to the specified Oracle number power + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + */ + +/*----------------------------- OCINumberLn ---------------------------------*/ + +sword OCINumberLn( OCIError *err, const OCINumber *number, + OCINumber *result ); +/* + NAME: OCINumberLn - OCINumber Logarithm Natural + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + number (IN) - logarithm of this number is computed + result (OUT) - logarithm result + DESCRIPTION: + Takes the logarithm of the given Oracle number with respect + to the given base. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + 'number' is <= 0 + */ + +/*----------------------------- OCINumberLog --------------------------------*/ + +sword OCINumberLog( OCIError *err, const OCINumber *base, + const OCINumber *number, OCINumber *result ); +/* + NAME: OCINumberLog - OCINumber LOGarithm any base + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + base (IN) - base of the logarithm + number (IN) - opearnd + result (OUT) - logarithm result + DESCRIPTION: + Takes the logarithm with the specified base of an Oracle number. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + any of the number arguments is null + 'number' is <= 0 + 'base' is <= 0 + */ + +/*****************************************************************************/ +/* ORACLE DATE TYPE */ +/*****************************************************************************/ + +struct OCITime +{ + ub1 OCITimeHH; /* hours; range is 0 <= hours <=23 */ + ub1 OCITimeMI; /* minutes; range is 0 <= minutes <= 59 */ + ub1 OCITimeSS; /* seconds; range is 0 <= seconds <= 59 */ +}; +typedef struct OCITime OCITime; + +/* + * OCITime - OCI TiMe portion of date + * + * This structure should be treated as an opaque structure as the format + * of this structure may change. Use OCIDateGetTime/OCIDateSetTime + * to manipulate time portion of OCIDate. + */ + +struct OCIDate +{ + sb2 OCIDateYYYY; /* gregorian year; range is -4712 <= year <= 9999 */ + ub1 OCIDateMM; /* month; range is 1 <= month < 12 */ + ub1 OCIDateDD; /* day; range is 1 <= day <= 31 */ + OCITime OCIDateTime; /* time */ +}; +typedef struct OCIDate OCIDate; + +/* + * OCIDate - OCI oracle Date representation in C + * + * OCIDate represents the C mapping of Oracle date. + * + * This structure should be treated as an opaque structure as the format + * of this structure may change. Use OCIDateGetDate/OCIDateSetDate + * to access/initialize OCIDate. + * + * For binding variables of type OCIDate in OCI calls (OCIBindByName(), + * OCIBindByPos(), and OCIDefineByPos()) use the type code SQLT_ODT. + */ + +/* + EXAMPLE + + The following example shows how to manipulate an attribute of type + oracle date. + + #define FMT "Month dd, YYYY, HH:MI A.M." + #define LANG "American" + + struct person + { + OCIDate start_date; + }; + typedef struct person person; + + OCIError *err; + person *joe; + sword status; /o error status o/ + + /o See oci.h for an example of how to initialize OCIError. + o For this example, assume the OCIEnv and OCIError has been + o initialized. + o/ + + /o Pin joe person object in the object cache. See ori.h + o for an example on pinning objects. For this example, assume that + o joe is pointing to the pinned object. + o/ + + /o set the start date of joe o/ + OCIDateSetTime(&joe->start_date, 8, 0, 0); + OCIDateSetDate(&joe->start_date, 1990, 10, 5); + + /o check if the date is valid o/ + uword invalid; + if (OCIDateCheck(err, &joe->start_date, &invalid) != OCI_SUCCESS) + /o error handling code o/ + if (invalid) + /o error handling code o/ + + /o convert date for display purposes o/ + char str[100]; + ub4 strlen = sizeof(str); + if (OCIDateToText(err, &joe->start_date, FMT, sizeof(FMT)-1, LANG, + sizeof(LANG)-1, &strlen, str) != OCI_SUCCESS) + /o error handling code o/ + + */ + +/*--------------------------- OCIDateGetTime --------------------------------*/ +/* void OCIDateGetTime(/o_ const OCIDate *date, ub1 *hour, ub1 *min, + ub1 *sec _o/); */ +#define OCIDateGetTime(date, hour, min, sec) \ + { \ + *hour = (date)->OCIDateTime.OCITimeHH; \ + *min = (date)->OCIDateTime.OCITimeMI; \ + *sec = (date)->OCIDateTime.OCITimeSS; \ + } +/* + NAME: OCIDateGetTime - OCIDate Get Time portion of date + PARAMETERS: + date (IN) - Oracle date whose time data is retrieved + hour (OUT) - hour value returned + min (OUT) - minute value returned + sec (OUT) - second value returned + DESCRIPTION: + Return time inforamtion stored in the given date. The time + information returned is: hour, minute and seconds. + RETURNS: + NONE + */ + +/*--------------------------- OCIDateGetDate --------------------------------*/ +/* void OCIDateGetDate(/o_ const OCIDate *date, sb2 *year, ub1 *month, + ub1 *day _o/); */ +#define OCIDateGetDate(date, year, month, day) \ + { \ + *year = (date)->OCIDateYYYY; \ + *month = (date)->OCIDateMM; \ + *day = (date)->OCIDateDD; \ + } +/* + NAME: OCIDateGetDate - OCIDate Get Date (year, month, day) portion of date + PARAMETERS: + date (IN) - Oracle date whose year, month, day data is retrieved + year (OUT) - year value returned + month (OUT) - month value returned + day (OUT) - day value returned + DESCRIPTION: + Return year, month, day inforamtion stored in the given date. + RETURNS: + NONE + */ + +/*--------------------------- OCIDateSetTime --------------------------------*/ +/* void OCIDateSetTime(/o_ OCIDate *date, ub1 hour, ub1 min, + ub1 sec _o/); */ +#define OCIDateSetTime(date, hour, min, sec) \ + { \ + (date)->OCIDateTime.OCITimeHH = hour; \ + (date)->OCIDateTime.OCITimeMI = min; \ + (date)->OCIDateTime.OCITimeSS = sec; \ + } +/* + NAME: OCIDateSetTime - OCIDate Set Time portion of date + PARAMETERS: + date (OUT) - Oracle date whose time data is set + hour (IN) - hour value to be set + min (IN) - minute value to be set + sec (IN) - second value to be set + DESCRIPTION: + Set the date with the given time inforamtion. + RETURNS: + NONE + */ + +/*--------------------------- OCIDateSetDate --------------------------------*/ +/* void OCIDateSetDate(/o_ OCIDate *date, sb2 year, ub1 month, ub1 day _o/); */ +#define OCIDateSetDate(date, year, month, day) \ + { \ + (date)->OCIDateYYYY = year; \ + (date)->OCIDateMM = month; \ + (date)->OCIDateDD = day; \ + } +/* + NAME: OCIDateSetDate - OCIDate Set Date (year, month, day) portion of date + PARAMETERS: + date (IN) - Oracle date whose year, month, day data is set + year (OUT) - year value to be set + month (OUT) - month value to be set + day (OUT) - day value to be set + DESCRIPTION: + Set the date with the given year, month, day inforamtion. + RETURNS: + NONE + */ + +/*--------------------------- OCIDateAssign ---------------------------------*/ + +sword OCIDateAssign( OCIError *err, const OCIDate *from, + OCIDate *to ); +/* + NAME: OCIDateAssign - OCIDate Assignment + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + from (IN) - date to be assigned + to (OUT) - lhs of assignment + DESCRIPTION: + Performs date assignment. + RETURNS: + OCI_SUCCESS + */ + +/*--------------------------- OCIDateToText ---------------------------------*/ + +sword OCIDateToText( OCIError *err, const OCIDate *date, + const oratext *fmt, ub1 fmt_length, + const oratext *lang_name, ub4 lang_length, + ub4 *buf_size, oratext *buf ); +/* + NAME: OCIDateToText - OCIDate convert date TO String + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + date (IN) - Oracle date to be converted + fmt (IN) - conversion format, if null string pointer (oratext*)0, then + the date is converted to a character string in the + date format "DD-MON-YY". + fmt_length (IN) - length of the 'fmt' parameter + lang_name (IN) - specifies the language in which the names and + abbreviations of months and days are returned; + default language of session is used if 'lang_name' + is null i.e. (oratext *)0 + lang_length (IN) - length of the 'nls_params' parameter + buf_size (IN/OUT) - size of the buffer; size of the resulting string + is returned via this parameter + buf (OUT) - buffer into which the converted string is placed + DESCRIPTION: + Converts the given date to a string according to the specified format. + Refer to "TO_DATE" conversion function described in + "Oracle SQL Language Reference Manual" for a description of format + and NLS arguments. The converted null-terminated date string is + stored in the buffer 'buf'. + + An error is reported upon overflow, e.g. trying to convert a number + of value 10 using format '9' causes an overflow. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + buffer too small + invalid format + unknown language + overflow error + */ + +/*---------------------------- OCIDateFromText ------------------------------*/ + +sword OCIDateFromText( OCIError *err, const oratext *date_str, + ub4 d_str_length, const oratext *fmt, ub1 fmt_length, + const oratext *lang_name, ub4 lang_length, + OCIDate *date ); +/* + NAME: OCIDateFromText - OCIDate convert String TO Date + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + date_str (IN) - input string to be converted to Oracle date + d_str_length (IN) - size of the input string, if the length is -1 + then 'date_str' is treated as a null terminated string + fmt (IN) - conversion format; if 'fmt' is a null pointer, then + the string is expected to be in 'DD-MON-YY' format. + fmt_length (IN) - length of the 'fmt' parameter + lang_name (IN) - language in which the names and abbreviations of + days and months are specified, if null i.e. (oratext *)0, + the default language of session is used, + lang_length (IN) - length of the 'lang_name' parameter + date (OUT) - given string converted to date + DESCRIPTION: + Converts the given string to Oracle date + according to the specified format. Refer to "TO_DATE" conversion + function described in "Oracle SQL Language Reference Manual" for a + description of format. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + invalid format + unknown language + invalid input string + + */ + +/*----------------------------- OCIDateCompare ------------------------------*/ + +sword OCIDateCompare( OCIError *err, const OCIDate *date1, + const OCIDate *date2, sword *result ); +/* + NAME: OCIDateCompare - OCIDate CoMPare dates + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + date1, date2 (IN) - dates to be compared + result (OUT) - comparison result, 0 if equal, -1 if date1 < date2, + 1 if date1 > date2 + DESCRIPTION: + The function OCIDateCompare compares two dates. It returns -1 if date1 + is smaller than date2, 0 if they are equal, and 1 if date1 is greater + than date2. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + invalid date + + */ + +/*------------------------- OCIDateAddMonths --------------------------------*/ + +sword OCIDateAddMonths( OCIError *err, const OCIDate *date, sb4 num_months, + OCIDate *result ); +/* + NAME: OCIDateAddMonths - OCIDate ADd or subtract Months + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + date (IN) - 'num_months' added or subtracted from 'date' + num_months (IN) - number of months to be added or subtracted + (a negative value will be subtracted) + result (IN/OUT) - result of adding or subtracting to 'date' + DESCRIPTION: + The function OCIDateAddDays adds or subtracts num_months from the + date 'date'. + If the input 'date' is the last day of a month, then + appropriate adjustments are made to ensure that the output date is + also the last day of the month. For example, Feb. 28 + 1 month = + March 31, and November 30 - 3 months = August 31. Otherwise the + 'result' date has the same day component as 'date'. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + invalid date + + */ + +/*--------------------------- OCIDateAddDays --------------------------------*/ + +sword OCIDateAddDays( OCIError *err, const OCIDate *date, sb4 num_days, + OCIDate *result ); +/* + NAME: OCIDateAddDays - OCIDate ADd or subtract Days + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + date (IN) - 'num_days' added or subtracted from 'date' + num_days (IN) - number of days to be added or subtracted + (a negative value will be subtracted) + result (IN/OUT) - result of adding or subtracting to 'date' + DESCRIPTION: + The function OCIDateAddDays adds or subtracts num_days from the + date 'date'. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + invalid date + + */ + +/*--------------------------- OCIDateLastDay --------------------------------*/ + +sword OCIDateLastDay( OCIError *err, const OCIDate *date, + OCIDate *last_day ); +/* + NAME: OCIDateLastDay - OCIDate get date of the LaST day of the month + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + date (IN) - input date + last_day (OUT) - last day of the month in date 'date' + DESCRIPTION: + The function OCIDateLastDay returns the date of the last day of the + month in date 'date'. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + invalid date + + */ + +/*----------------------- OCIDateDaysBetween --------------------------------*/ + +sword OCIDateDaysBetween( OCIError *err, const OCIDate *date1, + const OCIDate *date2, sb4 *num_days ); +/* + NAME: OCIDateDaysBetween - OCIDate get number of days BeTWeen two dates + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + date1, date2 (IN) - input dates + num_days (OUT) - number of days between date1 and date2 + DESCRIPTION: + The function OCIDateDaysBetween returns the number of days between + date1 and date2. The time is ignored in this computation. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + invalid date + + */ + +/*------------------------ OCIDateZoneToZone --------------------------------*/ + +sword OCIDateZoneToZone( OCIError *err, const OCIDate *date1, + const oratext *zon1, + ub4 zon1_length, const oratext *zon2, + ub4 zon2_length, OCIDate *date2 ); +/* + NAME: OCIDateZoneToZone - OCIDate convert date from one Zone TO another Zone + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + date1 (IN) - date to be converted + zon1 (IN) - zone of input date + zon1_length (IN) - length in bytes of string 'zon1' + zon2 (IN) - zone to be converted to + zon2_length (IN) - length in bytes of string 'zon2' + date2 (OUT) - converted date (in 'zon2') + DESCRIPTION: + Converts date from one time zone to another. Given date 'date1' + in time zone 'zon1' returns date 'date2' in time zone 'zon2'. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + invlid date + invald input time zone + invald output time zone + + */ + +/*--------------------------- OCIDateNextDay --------------------------------*/ + +sword OCIDateNextDay( OCIError *err, const OCIDate *date, + const oratext *day_p, ub4 day_length, + OCIDate *next_day ); +/* + NAME: OCIDateNextDay - OCIDate get date of Next DaY + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + date (IN) - returned date should be later than this date + day (IN) - first day of week named by this is returned + day_length (IN) - length in bytes of string 'day' + next_day (OUT) - first day of the week named by 'day' later than 'date' + DESCRIPTION: + Returns the date of the first day of the + week named by 'day' that is later than date 'date'. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + invalid date + invalid day + + */ + +/*----------------------------- OCIDateCheck --------------------------------*/ + +/* Listing of error bits used by OCIDateCheck() */ +#define OCI_DATE_INVALID_DAY 0x1 /* Bad DAy */ +#define OCI_DATE_DAY_BELOW_VALID 0x2 /* Bad DAy Low/high bit (1=low)*/ +#define OCI_DATE_INVALID_MONTH 0x4 /* Bad MOnth */ +#define OCI_DATE_MONTH_BELOW_VALID 0x8 /* Bad MOnth Low/high bit (1=low)*/ +#define OCI_DATE_INVALID_YEAR 0x10 /* Bad YeaR */ +#define OCI_DATE_YEAR_BELOW_VALID 0x20 /* Bad YeaR Low/high bit (1=low)*/ +#define OCI_DATE_INVALID_HOUR 0x40 /* Bad HouR */ +#define OCI_DATE_HOUR_BELOW_VALID 0x80 /* Bad HouR Low/high bit (1=low)*/ +#define OCI_DATE_INVALID_MINUTE 0x100 /* Bad MiNute */ +#define OCI_DATE_MINUTE_BELOW_VALID 0x200 + /* Bad MiNute Low/high bit (1=low)*/ +#define OCI_DATE_INVALID_SECOND 0x400 /* Bad SeCond */ +#define OCI_DATE_SECOND_BELOW_VALID 0x800 + /* bad second Low/high bit (1=low)*/ +#define OCI_DATE_DAY_MISSING_FROM_1582 0x1000 + /* Day is one of those "missing" from 1582 */ +#define OCI_DATE_YEAR_ZERO 0x2000 /* Year may not equal zero */ +#define OCI_DATE_INVALID_FORMAT 0x8000 /* Bad date format input */ + +sword OCIDateCheck( OCIError *err, const OCIDate *date, uword *valid ); +/* + NAME: OCIDateCheck - OCIDate CHecK if the given date is valid + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + date (IN) - date to be checked + valid (OUT) - returns zero for a valid date, otherwise + the ORed combination of all error bits specified below: + + Macro name Bit number Error + ---------- ---------- ----- + OCI_DATE_INVALID_DAY 0x1 Bad day + OCI_DATE_DAY_BELOW_VALID 0x2 Bad DAy Low/high bit (1=low) + OCI_DATE_INVALID_MONTH 0x4 Bad MOnth + OCI_DATE_MONTH_BELOW_VALID 0x8 Bad MOnth Low/high bit (1=low) + OCI_DATE_INVALID_YEAR 0x10 Bad YeaR + OCI_DATE_YEAR_BELOW_VALID 0x20 Bad YeaR Low/high bit (1=low) + OCI_DATE_INVALID_HOUR 0x40 Bad HouR + OCI_DATE_HOUR_BELOW_VALID 0x80 Bad HouR Low/high bit (1=low) + OCI_DATE_INVALID_MINUTE 0x100 Bad MiNute + OCI_DATE_MINUTE_BELOW_VALID 0x200 Bad MiNute Low/high bit (1=low) + OCI_DATE_INVALID_SECOND 0x400 Bad SeCond + OCI_DATE_SECOND_BELOW_VALID 0x800 bad second Low/high bit (1=low) + OCI_DATE_DAY_MISSING_FROM_1582 0x1000 Day is one of those "missing" + from 1582 + OCI_DATE_YEAR_ZERO 0x2000 Year may not equal zero + OCI_DATE_INVALID_FORMAT 0x8000 Bad date format input + + So, for example, if the date passed in was 2/0/1990 25:61:10 in + (month/day/year hours:minutes:seconds format), the erroor returned + would be OCI_DATE_INVALID_DAY | OCI_DATE_DAY_BELOW_VALID | + OCI_DATE_INVALID_HOUR | OCI_DATE_INVALID_MINUTE + + DESCRIPTION: + Check if the given date is valid. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + 'date' and 'valid' pointers are NULL pointers + */ + +/*--------------------------- OCIDateSysDate --------------------------------*/ + +sword OCIDateSysDate( OCIError *err, OCIDate *sys_date ); +/* + NAME: OCIDateSysDate - OCIDate get current SYStem date and time + PARAMETERS: + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + sys_date (OUT) - current system date and time + DESCRIPTION: + Returns the current system date and time. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'err' is NULL. + OCI_ERROR if + + */ + +/*****************************************************************************/ +/* FIXED-LENGTH STRING - CHAR (N) */ +/*****************************************************************************/ + +/* + * An ADT attribute declared as "x CHAR(n)" is mapped to "OCIString *x;". + * The representation of OCIString * is shown below. + */ + +/*****************************************************************************/ +/* VARIABLE-LENGTH STRING */ +/*****************************************************************************/ + +/* + * The variable-length string is represented in C as a pointer to OCIString + * structure. The OCIString structure is opaque to the user. Functions are + * provided to allow the user to manipulate a variable-length string. + * + * A variable-length string can be declared as: + * + * OCIString *vstr; + * + * For binding variables of type OCIString* in OCI calls (OCIBindByName(), + * OCIBindByPos() and OCIDefineByPos()) use the external type code SQLT_VST. + */ +typedef struct OCIString OCIString; + +/*-------------------------- OCIStringAssign --------------------------------*/ + +sword OCIStringAssign( OCIEnv *env, OCIError *err, const OCIString *rhs, + OCIString **lhs ); +/* + NAME: OCIStringAssign - OCIString Assign String to String + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + rhs (IN) - RHS of the assignment, the type of rhs is also OCIString + lhs (IN/OUT) - LHS of the assignment + DESCRIPTION: + Assign 'rhs' string to 'lhs' string. The 'lhs' string may be + resized depending upon the size of the 'rhs'. The assigned string is + null-terminated. The 'length' field will not include the extra byte + needed for null termination. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + out of space error + */ + +/*---------------------- OCIStringAssignText --------------------------------*/ + +sword OCIStringAssignText( OCIEnv *env, OCIError *err, const oratext *rhs, + ub4 rhs_len, OCIString **lhs ); +/* + NAME: OCIStringAssignText - OCIString Assign Text string to String + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + rhs (IN) - RHS of the assignment, the type of rhs is a text string + rhs_len (IN) - length of the 'rhs' string + lhs (IN/OUT) - LHS of the assignment + DESCRIPTION: + Assign 'rhs' string to 'lhs' string. The 'lhs' string may be + resized depending upon the size of the 'rhs'. The assigned string is + null-terminated. The 'length' field will not include the extra byte + needed for null termination. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + out of space error + */ + +/*-------------------------- OCIStringResize --------------------------------*/ + +sword OCIStringResize( OCIEnv *env, OCIError *err, ub4 new_size, + OCIString **str ); +/* + NAME: OCIStringResize - OCIString ReSiZe string memory + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + new_size (IN) - new memory size of the string in bytes + str (IN/OUT) - allocated memory for the string is freed from the + OOCI heap + DESCRIPTION: + This function resizes the memory of the given variable-length string in + the object cache. The contents of the string are NOT preserved. + This function may allocate the string in a new memory region in + which case the original memory occupied by the given string will + be freed. If the input string is null (str == NULL), then this + function will allocate memory for the string. + + If the new_size is 0, then this function frees the memory occupied + by 'str' and a null pointer value is returned. + + NOTE: The caller must compute 'new_size' taking into account space + for the null character ('\0'). + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + out of space error + */ + +/*---------------------------- OCIStringSize --------------------------------*/ + +ub4 OCIStringSize( OCIEnv *env, const OCIString *vs ); +/* + NAME: OCIStringSize - OCIString Get String siZe + PARAMETERS: + env(IN) - pointer to OCI environment handle + vs (IN) - string whose size is returned + DESCRIPTION: + Return the size of the given string. + RETURNS: + size of the string in bytes is returned + */ + +/*----------------------------- OCIStringPtr --------------------------------*/ + +oratext *OCIStringPtr( OCIEnv *env, const OCIString *vs ); +/* + NAME: OCIStringPtr - OCIString Get String Pointer + PARAMETERS: + env(IN) - pointer to OCI environment handle + vs (IN) - pointer to the text of this string is returned + DESCRIPTION: + Return the pointer to the text of the given string. + RETURNS: + pointer to the text of the string is returned + */ + +/*----------------------- OCIStringAllocSize --------------------------------*/ + +sword OCIStringAllocSize( OCIEnv *env, OCIError *err, const OCIString *vs, + ub4 *allocsize ); +/* + NAME: OCIStringAllocSize - OCIString get Allocated SiZe of string memory + in bytes + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + vs (IN) - string whose allocated size in bytes is returned + allocsize (OUT) - allocated size of string memory in bytes is returned + DESCRIPTION: + Return the allocated size of the string memory in bytes. The + allocated size is >= actual string size. + REQUIRES: + vs is a non-null pointer + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR on error + */ + +/*****************************************************************************/ +/* VARIABLE-LENGTH RAW */ +/*****************************************************************************/ + +/* + * The variable-length raw is represented in C as a pointer to OCIRaw + * structure. The OCIRaw structure is opaque to the user. Functions are + * provided to allow the user to manipulate a variable-length raw. + * + * A variable-length raw can be declared as: + * + * OCIRaw *raw; + * + * For binding variables of type OCIRaw* in OCI calls (OCIBindByName(), + * OCIBindByPos() and OCIDefineByPos()) use the external type code SQLT_LVB. + */ +typedef struct OCIRaw OCIRaw; + +/*-------------------------- OCIRawAssignRaw --------------------------------*/ + +sword OCIRawAssignRaw( OCIEnv *env, OCIError *err, const OCIRaw *rhs, + OCIRaw **lhs ); +/* + NAME: OCIRawAssignRaw - OCIRaw Assign Raw (of type OCIRaw*) to + Raw (of type OCIRaw*) + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + rhs (IN) - RHS of the assignment, the type of rhs is also OCIRaw + lhs (IN/OUT) - LHS of the assignment + DESCRIPTION: + Assign 'rhs' raw to 'lhs' raw. The 'lhs' raw may be + resized depending upon the size of the 'rhs'. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + out of space error + */ + +/*------------------------ OCIRawAssignBytes --------------------------------*/ + +sword OCIRawAssignBytes( OCIEnv *env, OCIError *err, const ub1 *rhs, + ub4 rhs_len, OCIRaw **lhs ); +/* + NAME: OCIRawAssignBytes - OCIRaw Assign raw Bytes (of type ub1*) to Raw + (of type OCIRaw*) + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + rhs (IN) - RHS of the assignment, the type of rhs is ub1 * + rhs_len (IN) - length of the 'rhs' raw + lhs (IN/OUT) - LHS of the assignment + DESCRIPTION: + Assign 'rhs' raw to 'lhs' raw. The 'lhs' raw may be + resized depending upon the size of the 'rhs'. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + out of space error + */ + +/*---------------------------- OCIRawResize ---------------------------------*/ + +sword OCIRawResize( OCIEnv *env, OCIError *err, ub4 new_size, + OCIRaw **raw ); +/* + NAME: OCIRawResize - OCIRaw ReSiZe memory of variable-length raw + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + new_size (IN) - new size of the raw data in bytes + raw (IN) - variable-length raw pointer; the raw is + resized to 'new_size' + DESCRIPTION: + This function resizes the memory of the given variable-length raw in + the object cache. + The previous contents of the raw are NOT preserved. + This function may allocate the raw in a new memory region in + which case the original memory occupied by the given raw will + be freed. If the input raw is null (raw == NULL), then this + function will allocate memory for the raw data. + + If the new_size is 0, then this function frees the memory occupied + by 'raw' and a null pointer value is returned. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + out of space error + */ + +/*------------------------------- OCIRawSize --------------------------------*/ + +ub4 OCIRawSize( OCIEnv * env, const OCIRaw *raw ); +/* + NAME: OCIRawSize - OCIRaw Get Raw siZe + PARAMETERS: + env (IN) - pointer to OCI environment handle + raw (INT) - raw whose size is returned + DESCRIPTION: + Return the size of the given raw. + RETURNS: + size of the raw in bytes is returned + */ + +/*--------------------------------- OCIRawPtr -------------------------------*/ +ub1 *OCIRawPtr( OCIEnv * env, const OCIRaw *raw ); +/* + NAME: OCIRawPtr - OCIRaw Get Raw data Pointer + PARAMETERS: + env (IN) - pointer to OCI environment handle + raw (IN) - pointer to the data of this raw is returned + DESCRIPTION: + Return the pointer to the data of the given raw. + RETURNS: + pointer to the data of the raw is returned + */ + +/*------------------------------ OCIRawAllocSize ----------------------------*/ + +sword OCIRawAllocSize( OCIEnv *env, OCIError *err, const OCIRaw *raw, + ub4 *allocsize ); +/* + NAME: OCIRawAllocSize - OCIRaw get Allocated SiZe of raw memory in bytes + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + raw (IN) - raw whose allocated size in bytes is returned + allocsize (OUT) - allocated size of raw memory in bytes is returned + DESCRIPTION: + Return the allocated size of the raw memory in bytes. The + allocated size is >= actual raw size. + REQUIRES: + raw is a non-null pointer + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR upon error + */ + +/*****************************************************************************/ +/* OBJECT REFERENCE OPERATIONS */ +/*****************************************************************************/ + +/* + * See the definition of OCIRef in oro.h. + * + * For binding variables of type OCIRef* in OCI calls (OCIBindByName(), + * OCIBindByPos() and OCIDefineByPos()) use the code SQLT_REF. + * + */ + +/*---------------------------- OCIRefClear ----------------------------------*/ +void OCIRefClear( OCIEnv *env, OCIRef *ref ); +/* + NAME: OCIRefClear - OCIRef CLeaR or nullify a ref + PARAMETERS: + env (IN) - pointer to OCI environment handle + ref (IN/OUT) - ref to clear + DESCRIPTION: + Clear or nullify the given ref. A ref is considered to be a null ref + if it does not contain a valid OID (and thus doesn't point to an + object). Logically, a null ref is a dangling ref. + + Note that a null ref is still a valid SQL value and is not SQL-ly null. + It can be used as a valid non-null constant ref value for NOT NULL + column or attribute of a row in a table. + + If a null pointer value is passed as a ref, + then this function is a no-op. + */ + +/*--------------------------- OCIRefAssign ----------------------------------*/ +sword OCIRefAssign( OCIEnv *env, OCIError *err, const OCIRef *source, + OCIRef **target ); +/* + NAME: OCIRefAssign - OCIRef CoPY a ref to another + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + source (IN) - ref to copy from + target (IN/OUT) - ref to copy to + DESCRIPTION: + Copy 'source' ref to 'target' ref; both then reference the same + object. If the target ref pointer is null (i.e. *target == NULL) + then the copy function will allocate memory for the target ref + in OOCI heap prior to the copy. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + 1) out of memory + */ + +/*-------------------------- OCIRefIsEqual ----------------------------------*/ +boolean OCIRefIsEqual( OCIEnv *env, const OCIRef *x, const OCIRef *y ); +/* + NAME: OCIRefIsEqual - OCIRef compare two refs for EQUality + PARAMETERS: + env (IN) - pointer to OCI environment handle + x (IN) - ref to compare + y (IN) - ref to compare + DESCRIPTION: + Compare the given refs for equality. + Two refs are equal if and only if: + - they are both referencing the same persistent object, or + - they are both referencing the same transient object. + + NOTE THAT TWO NULL REFS ARE CONSIDERED NOT EQUAL BY THIS FUNCTION. + RETURNS: + TRUE if the two refs are equal + FALSE if the two refs are not equal, or X is NULL, or Y is NULL + */ + +/*--------------------------- OCIRefIsNull ----------------------------------*/ +boolean OCIRefIsNull( OCIEnv *env, const OCIRef *ref ); +/* + NAME: OCIRefIsNull - OCIRef test if a ref is NULl + PARAMETERS: + env (IN) - pointer to OCI environment handle + ref (IN) - ref to test for null + DESCRIPTION: + Return TRUE if the given ref is null; otherwise, return FALSE. + A ref is null if and only if: + - it is supposed to be referencing a persistent object, but + its OID is null, or + - it is supposed to be referencing a transient object, but it is + currently not pointing to an object. + A ref is a dangling ref if the object that it points to does not + exist. + RETURNS: + TRUE if the given ref is NULL + FALSE if the given ref is not NULL + */ + +/*-------------------------- OCIRefHexSize ----------------------------------*/ +ub4 OCIRefHexSize( OCIEnv *env, const OCIRef *ref ); +/* + NAME: OCIRefHexSize - OCIRef Hexadecimal buffer SiZe in bytes + PARAMETERS: + env (IN) - pointer to OCI environment handle + ref (IN) - ref whose size in hexadecimal representation in bytes is + returned + DESCRIPTION: + Return the size of the buffer in bytes required for the hexadecimal + representation of the ref. A buffer of at-least this size must be + passed to ref-to-hex (OCIRefToHex) conversion function. + RETURNS: + size of hexadecimal representation of ref + */ + +/*-------------------------- OCIRefFromHex ---------------------------------*/ +sword OCIRefFromHex( OCIEnv *env, OCIError *err, const OCISvcCtx *svc, + const oratext *hex, ub4 length, OCIRef **ref ); +/* + NAME: + OCIRefFromHex - OCIRef convert a Hexadecimal string TO a Ref + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by + calling OCIErrorGet(). + svc (IN) - OCI service context handle; if the resulting ref is + initialized with this service context + hex (IN) - hexadecimal string (that was produced by 'OCIRefToHex()" + previously) to be convert into a ref + length (IN) - length of the hexadecimal string + ref (IN/OUT) - ref is initialized with the given value ('hex'). + If *ref is null, then space for the ref is allocated in the + object cache, otherwise the memory occupied by the given ref + is re-used. + DESCRIPTION: + Convert the given hexadecimal string into a ref. This function + ensures that the resulting ref is well formed. It does NOT ensure + that the object pointed to by the resulting ref exists or not. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + */ + +/*--------------------------- OCIRefToHex -----------------------------------*/ +sword OCIRefToHex( OCIEnv *env, OCIError *err, const OCIRef *ref, + oratext *hex, ub4 *hex_length ); +/* + NAME: + OCIRefToHex - OCIRef convert ref to a Hexadecimal string + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by + calling OCIErrorGet(). + ref (IN) - ref to be converted into a hexadecimal string; if the + ref is a null ref (i.e. OCIRefIsNull(ref) == TRUE) then + a zero hex_length value is returned + hex (OUT) - buffer that is large enough to contain the resulting + hexadecimal string; the contents of the string is opaque + to the caller + hex_length (IN/OUT) - on input specifies the size of the 'hex' buffer, + on output specifies the actual size of the hexadecimal + string being returned in 'hex' + DESCRIPTION: + Convert the given ref into a hexadecimal string, and return the length + of the string. The resulting string is opaque to the caller. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + the given buffer is not big enough to hold the resulting string + */ + + +/*****************************************************************************/ +/* COLLECTION FUNCTIONS */ +/*****************************************************************************/ + +/* + The generic collection is represented by the type 'OCIColl'. The following + operations OCIColl*() are provided on a generic collection: + - get current size of collection + - get upper bound of collection + - get pointer to an element given its index + - set element at given index (assign element) + - append an element + - trim the given number of elements from the end of the collection + - collection assignment + + The following iterator based scanning functions are also provided on a + generic collection. These functions make use of an iterator which is + defined to be of type OCIIter. + + - create an iterator for scanning collection + - destroy iterator + - reset iterator to the beginning of collection + - get pointer to current element pointed by iterator + - get pointer to next element + - get pointer to previous element + + The collections variable-length array (varray) and nested table + are sub-types of generic collection. This means that the OCIColl*() + functions can also be used to manipulate varray and nested table. + + The varray is represented by OCIArray type and nested table by OCITable. + Besides OCIColl*() functions no additional functions are provided for + manipulating varrays. The OCIColl*() functions are a complete set of + functions to manipulate varrays. + + Besides OCIColl*() functions, the following functions OCITable*() can be + used to manipulate nested table. The OCITable*() functions operate on + nested tables only and should not be used on a varray. + + - delete an element at index i. Note that the position + ordinals of the remaining elements of the table is not changed by the + delete operation. So delete creates "holes" in the table. + - check if an element exists at the given index i + - return the smallest value of i for which exists(i) is true + - return the largest value of i for which exists(i) is true + - return pointer to the smallest position j, greater than i, such that + OCITableExists(j) is true + - return pointer to the largest position j, less than i, such that + OCITableExists(j) is true + + For binding variables of type OCIColl* or OCITable* in OCI calls + (OCIBindByName(), OCIBindByPos() and OCIDefineByPos()) use the external + type code SQLT_NTY. + */ + +/* OCIColl - generic collection type */ +typedef struct OCIColl OCIColl; + +/* OCIArray - varray collection type */ +typedef OCIColl OCIArray; + +/* OCITable - nested table collection type */ +typedef OCIColl OCITable; + +/* OCIIter - collection iterator */ +typedef struct OCIIter OCIIter; + +/*----------------------------- OCICollSize ---------------------------------*/ + +sword OCICollSize( OCIEnv *env, OCIError *err, const OCIColl *coll, + sb4 *size ); +/* + NAME: OCICollSize - OCIColl return current SIZe of the given collection + PARAMETERS: + env(IN) - pointer to OCI environment handle + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + coll (IN) - collection whose number of elements is returned + size (OUT) - current number of elements in the collection + DESCRIPTION: + Returns the current number of elements in the given collection. + + For collections of type nested table wherein 'delete element' + operation is allowed, the count returned by OCICollSize() will + NOT be decremented upon deleting elements. For example: + + OCICollSize(...); + // assume 'size' returned is equal to 5 + OCITableDelete(...); // delete one element + OCICollSize(...); + // 'size' returned will still be 5 + + To get the count minus the deleted elements use OCITableSize(). + Continuing the above example, + + OCITableSize(...) + // 'size' returned will be equal to 4 + + Note, a trim operation (OCICollTrim) will decrement the count + by the number of trimmed elements. Continuing the above example, + + OCICollTrim(..,1..); // trim one element + OCICollSize(...); + // 'size' returned will be equal to 4 + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + error during loading of collection into object cache + any of the input parameters is null + */ + +/*------------------------------ OCICollMax ---------------------------------*/ + +sb4 OCICollMax( OCIEnv *env, const OCIColl *coll ); +/* + NAME: OCICollMax - OCIColl return MAXimum size (upper-bound) of the + given collection (in number of elements) + PARAMETERS: + env(IN) - pointer to OCI environment handle + coll (IN) - collection whose upper-bound in number of elements + is returned + DESCRIPTION: + Returns the max number of elements that the given collection can hold. + A value 0 indicates that the collection has no upper-bound. + REQUIRES: + coll must point to a valid collection descriptor + RETURNS: + upper-bound of the given collection + */ + +/*-------------------------- OCICollGetElem ---------------------------------*/ + +sword OCICollGetElem( OCIEnv *env, OCIError *err, const OCIColl *coll, + sb4 index, boolean *exists, void **elem, + void **elemind ); +/* + NAME: OCICollGetElem - OCIColl GET pointer to the element at the given index + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + coll (IN) - pointer to the element in this collection is returned + index (IN) - index of the element whose pointer is returned + exists (OUT) - set to FALSE if element at the specified index does + not exist else TRUE + elem (OUT) - address of the desired element is returned + elemind (OUT) [optional] - address of the null indicator information + is returned; if (elemind == NULL) then the null indicator + information will NOT be returned + DESCRIPTION: + Get the address of the element at the given position. Optionally + this function also returns the address of the element's null indicator + information. + + The following table describes for each collection element type + what the corresponding element pointer type is. The element pointer + is returned via the 'elem' parameter of OCICollGetElem(). + + Element Type *elem is set to + ----------------------- --------------- + Oracle Number (OCINumber) OCINumber* + Date (OCIDate) OCIDate* + Variable-length string (OCIString*) OCIString** + Variable-length raw (OCIRaw*) OCIRaw** + object reference (OCIRef*) OCIRef** + lob locator (OCILobLocator*) OCILobLocator** + object type (e.g. person) person* + + The element pointer returned by OCICollGetElem() is in a form + such that it can not only be used to access the + element data but also is in a form that can be used as the target + (i.e left-hand-side) of an assignment statement. + + For example, assume the user is iterating over the elements of + a collection whose element type is object reference (OCIRef*). A call + to OCICollGetElem() returns pointer to a reference handle + (i.e. OCIRef**). After getting, the pointer to the collection + element, the user may wish to modify it by assigning a new reference. + This can be accomplished via the ref assignment function shown below: + + sword OCIRefAssign( OCIEnv *env, OCIError *err, const OCIRef *source, + OCIRef **target ); + + Note that the 'target' parameter of OCIRefAssign() is of type + 'OCIRef**'. Hence OCICollGetElem() returns 'OCIRef**'. + If '*target == NULL' a new ref will be allocated by OCIRefAssign() + and returned via the 'target' parameter. + + Similarly, if the collection element was of type string (OCIString*), + OCICollGetElem() returns pointer to string handle + (i.e. OCIString**). If a new string is assigned, via + OCIStringAssign() or OCIStringAssignText() the type of the target + must be 'OCIString **'. + + If the collection element is of type Oracle number, OCICollGetElem() + returns OCINumber*. The prototype of OCINumberAssign() is shown below: + + sword OCINumberAssign(OCIError *err, const OCINumber *from, + OCINumber *to); + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + any of the input parameters is null + */ + +/*------------------------- OCICollGetElemArray -----------------------------*/ + +sword OCICollGetElemArray( OCIEnv *env, OCIError *err, const OCIColl *coll, + sb4 index, boolean *exists, void **elem, + void **elemind, uword *nelems); +/* + NAME: OCICollGetElemArray - OCIColl GET pointers to elements from given index + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + coll (IN) - pointers to the elements in this collection is returned + index (IN) - starting index of the element + exists (OUT) - set to FALSE if element at the specified index does + not exist else TRUE + elem (OUT) - address of the desired elements is returned + elemind (OUT) [optional] - address of the null indicators information + is returned; if (elemind == NULL) then the null indicator + information will NOT be returned + nelems(IN/OUT) - Upper bound of elem and/or elemind array + DESCRIPTION: + Get the address of the elements from the given position. Optionally + this function also returns the address of the element's null indicator + information. + + The following table describes for each collection element type + what the corresponding element pointer type is. The element pointer + is returned via the 'elem' parameter of OCICollGetElem(). + + Element Type *elem is set to + ----------------------- --------------- + Oracle Number (OCINumber) OCINumber* + Date (OCIDate) OCIDate* + Variable-length string (OCIString*) OCIString** + Variable-length raw (OCIRaw*) OCIRaw** + object reference (OCIRef*) OCIRef** + lob locator (OCILobLocator*) OCILobLocator** + object type (e.g. person) person* + + The element pointer returned by OCICollGetElem() is in a form + such that it can not only be used to access the + element data but also is in a form that can be used as the target + (i.e left-hand-side) of an assignment statement. + + For example, assume the user is iterating over the elements of + a collection whose element type is object reference (OCIRef*). A call + to OCICollGetElem() returns pointer to a reference handle + (i.e. OCIRef**). After getting, the pointer to the collection + element, the user may wish to modify it by assigning a new reference. + This can be accomplished via the ref assignment function shown below: + + sword OCIRefAssign( OCIEnv *env, OCIError *err, const OCIRef *source, + OCIRef **target ); + + Note that the 'target' parameter of OCIRefAssign() is of type + 'OCIRef**'. Hence OCICollGetElem() returns 'OCIRef**'. + If '*target == NULL' a new ref will be allocated by OCIRefAssign() + and returned via the 'target' parameter. + + Similarly, if the collection element was of type string (OCIString*), + OCICollGetElem() returns pointer to string handle + (i.e. OCIString**). If a new string is assigned, via + OCIStringAssign() or OCIStringAssignText() the type of the target + must be 'OCIString **'. + + If the collection element is of type Oracle number, OCICollGetElem() + returns OCINumber*. The prototype of OCINumberAssign() is shown below: + + sword OCINumberAssign(OCIError *err, const OCINumber *from, + OCINumber *to); + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + any of the input parameters is null + */ + +/*----------------------- OCICollAssignElem ---------------------------------*/ + +sword OCICollAssignElem( OCIEnv *env, OCIError *err, sb4 index, + const void *elem, + const void *elemind, OCIColl *coll ); +/* + NAME: OCICollAssignElem - OCIColl ASsign Element + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + index (IN) - index of the element whose is assigned to + elem (IN) - element which is assigned from (source element) + elemind (IN) [optional] - pointer to the element's null indicator + information; if (elemind == NULL) then the null indicator + information of the assigned element will be set to non-null. + coll (IN/OUT) - collection to be updated + DESCRIPTION: + Assign the given element value 'elem' to the element at coll[index]. + If the collection is of type nested table, the element at the given + index may not exist (i.e. may have been deleted). In this case, the + given element is inserted at index 'index'. + Otherwise, the element at index 'index' is updated with the value + of 'elem'. + + Note that the given element is deep-copied and + 'elem' is strictly an input parameter. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + any of the input parameters is null + out of memory error + given index is out of bounds of the given collection + */ + +/*--------------------------- OCICollAssign ---------------------------------*/ + +sword OCICollAssign( OCIEnv *env, OCIError *err, const OCIColl *rhs, + OCIColl *lhs ); +/* + NAME: OCICollAssign - OCIColl ASsiGn collection + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + rhs (IN) - collection to be assigned from + lhs (OUT) - collection to be assigned to + DESCRIPTION: + Assign 'rhs' to 'lhs'. The 'lhs' collection may be decreased or + increased depending upon the size of 'rhs'. If the 'lhs' contains + any elements then the elements will be deleted prior to the + assignment. This function performs a deep-copy. The memory for the + elements comes from the object cache. + + An error is returned if the element types of the lhs and rhs + collections do not match. Also, an error is returned if the + upper-bound of the lhs collection is less than the current number of + elements in the rhs collection. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + any of the input parameters is null + out of memory error + type mis-match of lhs and rhs collections + upper-bound of lhs collection is less than the current number of + elements in the rhs collection + */ + +/*--------------------------- OCICollAppend ---------------------------------*/ + +sword OCICollAppend( OCIEnv *env, OCIError *err, const void *elem, + const void *elemind, OCIColl *coll ); +/* + NAME: OCICollAppend - OCIColl APPend collection + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + elem (IN) - pointer to the element which is appended to the end + of the given collection + elemind (IN) [optional] - pointer to the element's null indicator + information; if (elemind == NULL) then the null indicator + information of the appended element will be set to non-null. + coll (IN/OUT) - updated collection + DESCRIPTION: + Append the given element to the end of the given collection. + Appending an element is equivalent to: + - increasing the size of the collection by 1 element + - updating (deep-copying) the last element's data with the given + element's data + + Note that the pointer to the given element 'elem' will not be saved + by this function. So 'elem' is strictly an input parameter. + An error is returned if the current size of the collection + is equal to the max size (upper-bound) of the collection prior to + appending the element. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + any of the input parameters is null + out of memory error + current size of collection == max size of the collection + */ + +/*----------------------------- OCICollTrim ---------------------------------*/ + +sword OCICollTrim( OCIEnv *env, OCIError *err, sb4 trim_num, + OCIColl *coll ); +/* + NAME: OCICollTrim - OCIColl Trim elements from the end of the collection + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + trim_num (IN) - number of elements to trim + coll (IN/OUT) - 'trim_num' of elements are removed (freed) from the + end of the collection + DESCRIPTION: + Trim the collection by the given number of elements. The elements are + removed from the end of the collection. + + An error is returned if the 'trim_num' is greater than the current + size of the collection. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + any of the input parameters is null + 'trim_num' is greater than the current size of the collection. + */ + +/*--------------------------- OCICollIsLocator ------------------------------*/ + +sword OCICollIsLocator(OCIEnv *env, OCIError *err, const OCIColl *coll, + boolean *result ); +/* +Name: OCICollIsLocator - OCIColl indicates whether a collection is locator + based or not. +Parameters: + env(IN) - pointer to OCI environment handle + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + coll (IN) - collection item. + result (OUT) - TRUE if the collection item is a locator, FALSE + otherwise +Description: + Returns TRUE in the result OUT parameter if the collection item is a + locator, otherwise returns FALSE. +Returns: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. +*/ + +/*---------------------------- OCIIterCreate --------------------------------*/ + +sword OCIIterCreate( OCIEnv *env, OCIError *err, const OCIColl *coll, + OCIIter **itr ); +/* + NAME: OCIIterCreate - OCIColl Create an ITerator to scan the collection + elements + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + coll (IN) - collection which will be scanned; the different + collection types are varray and nested table + itr (OUT) - address to the allocated collection iterator is + returned by this function + DESCRIPTION: + Create an iterator to scan the elements of the collection. The + iterator is created in the object cache. The iterator is initialized + to point to the beginning of the collection. + + If the next function (OCIIterNext) is called immediately + after creating the iterator then the first element of the collection + is returned. + If the previous function (OCIIterPrev) is called immediately after + creating the iterator then "at beginning of collection" error is + returned. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + any of the input parameters is null + out of memory error + */ + +/*----------------------------- OCIIterDelete ------------------------------*/ + +sword OCIIterDelete( OCIEnv *env, OCIError *err, OCIIter **itr ); +/* + NAME: OCIIterDelete - OCIColl Delete ITerator + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + itr (IN/OUT) - the allocated collection iterator is destroyed and + the 'itr' is set to NULL prior to returning + DESCRIPTION: + Delete the iterator which was previously created by a call to + OCIIterCreate. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + any of the input parameters is null + to be discovered + */ + +/*----------------------------- OCIIterInit ---------------------------------*/ + +sword OCIIterInit( OCIEnv *env, OCIError *err, const OCIColl *coll, + OCIIter *itr ); +/* + NAME: OCIIterInit - OCIColl Initialize ITerator to scan the given + collection + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + coll (IN) - collection which will be scanned; the different + collection types are varray and nested table + itr (IN/OUT) - pointer to an allocated collection iterator + DESCRIPTION: + Initializes the given iterator to point to the beginning of the + given collection. This function can be used to: + + a. reset an iterator to point back to the beginning of the collection + b. reuse an allocated iterator to scan a different collection + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + any of the input parameters is null + */ + +/*------------------------ OCIIterGetCurrent --------------------------------*/ + +sword OCIIterGetCurrent( OCIEnv *env, OCIError *err, const OCIIter *itr, + void **elem, void **elemind ); +/* + NAME: OCIIterGetCurrent - OCIColl Iterator based, get CURrent collection + element + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + itr (IN) - iterator which points to the current element + elem (OUT) - address of the element pointed by the iterator is returned + elemind (OUT) [optional] - address of the element's null indicator + information is returned; if (elemind == NULL) then the null + indicator information will NOT be returned + DESCRIPTION: + Returns pointer to the current element and its corresponding null + information. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + any of the input parameters is null + */ + +/*------------------------------ OCIIterNext --------------------------------*/ + +sword OCIIterNext( OCIEnv *env, OCIError *err, OCIIter *itr, + void **elem, void **elemind, boolean *eoc ); +/* + NAME: OCIIterNext - OCIColl Iterator based, get NeXT collection element + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + itr (IN/OUT) - iterator is updated to point to the next element + elem (OUT) - after updating the iterator to point to the next element, + address of the element is returned + elemind (OUT) [optional] - address of the element's null indicator + information is returned; if (elemind == NULL) then the null + indicator information will NOT be returned + eoc (OUT) - TRUE if iterator is at End Of Collection (i.e. next + element does not exist) else FALSE + DESCRIPTION: + Returns pointer to the next element and its corresponding null + information. The iterator is updated to point to the next element. + + If the iterator is pointing to the last element of the collection + prior to executing this function, then calling this function will + set eoc flag to TRUE. The iterator will be left unchanged in this + situation. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + any of the input parameters is null + */ + +/*------------------------------ OCIIterPrev --------------------------------*/ + +sword OCIIterPrev( OCIEnv *env, OCIError *err, OCIIter *itr, + void **elem, void **elemind, boolean *boc ); +/* + NAME: OCIIterPrev - OCIColl Iterator based, get PReVious collection element + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + itr (IN/OUT) - iterator is updated to point to the previous + element + elem (OUT) - after updating the iterator to point to the previous + element, address of the element is returned + elemind (OUT) [optional] - address of the element's null indicator + information is returned; if (elemind == NULL) then the null + indicator information will NOT be returned + boc (OUT) - TRUE if iterator is at Beginning Of Collection (i.e. + previous element does not exist) else FALSE. + DESCRIPTION: + Returns pointer to the previous element and its corresponding null + information. The iterator is updated to point to the previous element. + + If the iterator is pointing to the first element of the collection + prior to executing this function, then calling this function will + set 'boc' to TRUE. The iterator will be left unchanged in this + situation. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + any of the input parameters is null + */ + +/*****************************************************************************/ +/* FUNCTIONS WHICH OPERATE ONLY ON NESTED TABLE OCITable*() */ +/*****************************************************************************/ + +/*---------------------------- OCITableSize ---------------------------------*/ + +sword OCITableSize( OCIEnv *env, OCIError *err, const OCITable *tbl, + sb4 *size); +/* + NAME: OCITableSize - OCITable return current SIZe of the given + nested table (not including deleted elements) + PARAMETERS: + env(IN) - pointer to OCI environment handle + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + tbl (IN) - nested table whose number of elements is returned + size (OUT) - current number of elements in the nested table. The count + does not include deleted elements. + DESCRIPTION: + Returns the count of elements in the given nested table. + + The count returned by OCITableSize() will be decremented upon + deleting elements from the nested table. So, this count DOES NOT + includes any "holes" created by deleting elements. + For example: + + OCITableSize(...); + // assume 'size' returned is equal to 5 + OCITableDelete(...); // delete one element + OCITableSize(...); + // 'size' returned will be equal to 4 + + To get the count plus the count of deleted elements use + OCICollSize(). Continuing the above example, + + OCICollSize(...) + // 'size' returned will still be equal to 5 + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + error during loading of nested table into object cache + any of the input parameters is null + */ + +/*---------------------- OCITableExists ---------------------------------*/ + +sword OCITableExists( OCIEnv *env, OCIError *err, const OCITable *tbl, + sb4 index, boolean *exists ); +/* + NAME: OCITableExists - OCITable test whether element at the given index + EXIsts + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + tbl (IN) - table in which the given index is checked + index (IN) - index of the element which is checked for existence + exists (OUT) - set to TRUE if element at given 'index' exists + else set to FALSE + DESCRIPTION: + Test whether an element exists at the given 'index'. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + any of the input parameters is null + */ + +/*--------------------------- OCITableDelete -------------------------------*/ + +sword OCITableDelete( OCIEnv *env, OCIError *err, sb4 index, + OCITable *tbl ); +/* + NAME: OCITableDelete - OCITable DELete element at the specified index + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + index (IN) - index of the element which must be deleted + tbl (IN) - table whose element is deleted + DESCRIPTION: + Delete the element at the given 'index'. Note that the position + ordinals of the remaining elements of the table is not changed by the + delete operation. So delete creates "holes" in the table. + + An error is returned if the element at the specified 'index' has + been previously deleted. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + any of the input parameters is null + given index is not valid + */ + +/*--------------------------- OCITableFirst ---------------------------------*/ + +sword OCITableFirst( OCIEnv *env, OCIError *err, const OCITable *tbl, + sb4 *index ); +/* + NAME: OCITableFirst - OCITable return FirST index of table + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + tbl (IN) - table which is scanned + index (OUT) - first index of the element which exists in the given + table is returned + DESCRIPTION: + Return the first index of the element which exists in the given + table. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + table is empty + */ + +/*---------------------------- OCITableLast ---------------------------------*/ + +sword OCITableLast( OCIEnv *env, OCIError *err, const OCITable *tbl, + sb4 *index ); +/* + NAME: OCITableFirst - OCITable return LaST index of table + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + tbl (IN) - table which is scanned + index (OUT) - last index of the element which exists in the given + table is returned + DESCRIPTION: + Return the last index of the element which exists in the given + table. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + table is empty + */ + +/*---------------------------- OCITableNext ---------------------------------*/ + +sword OCITableNext( OCIEnv *env, OCIError *err, sb4 index, + const OCITable *tbl, sb4 *next_index, + boolean *exists ); +/* + NAME: OCITableNext - OCITable return NeXT available index of table + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + index (IN) - starting at 'index' the index of the next element + which exists is returned + tbl (IN) - table which is scanned + next_index (OUT) - index of the next element which exists + is returned + exists (OUT) - FALSE if no next index available else TRUE + DESCRIPTION: + Return the smallest position j, greater than 'index', such that + exists(j) is TRUE. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + no next index available + */ + +/*---------------------------- OCITablePrev ---------------------------------*/ + +sword OCITablePrev( OCIEnv *env, OCIError *err, sb4 index, + const OCITable *tbl, sb4 *prev_index, + boolean *exists ); +/* + NAME: OCITablePrev - OCITable return PReVious available index of table + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode. + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + index (IN) - starting at 'index' the index of the previous element + which exists is returned + tbl (IN) - table which is scanned + prev_index (OUT) - index of the previous element which exists + is returned + exists (OUT) - FALSE if no next index available else TRUE + DESCRIPTION: + Return the largest position j, less than 'index', such that + exists(j) is TRUE. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is NULL. + OCI_ERROR if + no previous index available + */ + +/*------------------------ OCINumberToLnx -----------------------------------*/ +/* void OCINumberToLnx(/o_ OCINumber *num _o/); */ + +#define OCINumberToLnx(num) ((lnxnum_t *)num) + +/* + NAME: OCINumberToLnx + PARAMETERS: + num (IN) - OCINumber to convert ; + DESCRIPTION: + Converts OCINumber to its internal lnx format + This is not to be used in Public interfaces , but + has been provided due to special requirements from + SQLPLUS development group as they require to call + Core funtions directly . +*/ + +/* OCI representation of XMLType */ +typedef struct OCIXMLType OCIXMLType; + +/* OCI representation of OCIDomDocument */ +typedef struct OCIDOMDocument OCIDOMDocument; + +/* OCI representation for the Binary XML repository context */ +typedef struct OCIBinXmlReposCtx OCIBinXmlReposCtx; + +#endif /* ORL_ORACLE */ diff --git a/libodbc/include/ora_linux/oro.h b/libodbc/include/ora_linux/oro.h new file mode 100644 index 0000000000..bf1e8f85fb --- /dev/null +++ b/libodbc/include/ora_linux/oro.h @@ -0,0 +1,883 @@ +/* Copyright (c) 1994, 2003, Oracle Corporation. All rights reserved. */ + +/* + NAME + OCI - Oracle Object Interface for External/Internal/Kernel Clients + + DESCRIPTION + This header file contains Oracle object interface definitions which + can be included by external user applications, tools, as well as + the kernel. It defines types and constants that are common to all + object interface which is being defined in several other header files + (e.g., ori.h, ort.h, and orl.h). + + RELATED DOCUMENTS + TBD + + INSPECTION STATUS [[ deletable if no inspection ]] + Inspection date: [[ date of the last logging meeting ]] + Inspection status: [[ exited, not exited, or N/A if exit is not a goal ]] + Estimated increasing cost defects per page: + Rule sets: [[ rule sets inspected against or planned to be + inspected against ]] + + ACCEPTANCE REVIEW STATUS [[ deletable if no approval review ]] + Review date: [[ date of the meeting where issues were logged and the + approval status was decided ]] + Review status: [[ current status: accepted, conditionally accepted, + major revision required, rejected ]] + Reviewers: [[ names of the members on the review team ]] + + PUBLIC FUNCTIONS + + EXAMPLES + Examples are given in the description of each function or macro where + relevant. + + MODIFIED + mnanal 06/09/03 - backout of fix 2836388 + mnanal 05/14/03 - bug-2836388 + srseshad 11/27/02 - Change OCI_TYPECODE_BFLOAT/BDOUBLE codes + rxgovind 10/09/02 - add OCI_TYPECODE_UROWID + mxyang 09/17/02 - grabtrans 'mmorsi_obj_float' + srseshad 09/11/02 - + srseshad 09/01/02 - + aahluwal 06/03/02 - bug 2360115 + celsbern 10/19/01 - merge LOG to MAIN + rxgovind 10/16/01 - update typecodes + rxgovind 09/19/01 - add typecodes + rkasamse 08/15/01 - add OCI_DURATION_USER_CALLBACK + jchai 09/24/01 - add type code for PLS_INTEGER + porangas 08/22/01 - Fix bug#1776434 + schatter 04/09/01 - merge 1456235: define OCI_DURATION_INVALID + rdani 10/12/00 - 1449943 NOCOPY and PIPELINE + ciyer 05/26/00 - short names for abstract, overriding + rkasamse 05/25/00 - OCCI enhancements + smuralid 05/11/00 - OCITypeMethodFlags - add NOT INSTANTIABLE, OVERRIDING + rxgovind 05/09/00 - add OCI_TYPECODE_NONE + tnbui 07/28/99 - Remove OCI_TYPECODE_TIMESTAMP_ITZ + tnbui 07/21/99 - TS LOCAL TZ + thoang 06/21/99 - Add OCI_TYPECODE_TIMESTAMP_ITZ + thoang 03/04/99 - Add datetime datatypes + rkasamse 10/20/98 - add OCI_ATTR_CACHE_ARRAYFLUSH + rkasamse 10/29/98 - add OCI_DURATION_CALLOUT + rkasamse 04/28/98 - OCI_OBJECT_DETECTCHANGE -> OCI_ATTR_OBJECT_DETECTCHAN + rkasamse 04/28/98 - OCI_OBJECT_NEWNOTNULL -> OCI_ATTR_OBJECT_NEWNOTNULL + rkasamse 04/23/98 - add OCI_OBJECT_DETECTCHANGE + rkasamse 04/03/98 - add OCI_OBJECT_NEWNOTNULL + pmitra 04/01/98 - OCI_LOCK_X_NOWAIT added + rxgovind 02/18/98 - add OCI_TYPECODE_OPAQUE + rkasamse 02/13/98 - Add OCI_DURATION_PROCESS + cxcheng 07/28/97 - fix compile with SLSHORTNAME + skrishna 07/14/97 - add OCIObjectGetProperty + cxcheng 04/30/97 - make OCITypeParamMode values consistent with PL/SQL + skrishna 04/28/97 - undocument OCIObjectProperty & OCIObjectEvent + cxcheng 03/29/97 - remove all remaining short names + sthakur 03/20/97 - add casts to constants + cxcheng 02/21/97 - temporarily put SLSHORTNAME for PL/SQL + cxcheng 02/06/97 - take out short name support except with SLSHORTNAME + lchidamb 01/20/97 - update OCIRef comments + sgollapu 11/19/96 - Add OCI type codes for BOOL,REC,and TAB + cxcheng 11/19/96 - more typecode changes + cxcheng 11/13/96 - add #include for ocidfn.h + cxcheng 11/13/96 - add OCI_TYPECODE_ADT for compatibility + cxcheng 11/12/96 - add SQLT_NCO for named collection + cxcheng 11/11/96 - more changes to typecodes + cxcheng 11/07/96 - #define OCI_TYPECODE_MLSLABEL to SQLT_LAB + cxcheng 11/06/96 - fix #define omission for OROTCNAT + cxcheng 10/30/96 - move OCI_TYPECODE_* to ocidfn.h as SQLT_* + cxcheng 10/28/96 - more beautification changes + jboonleu 10/29/96 - add flags for freeing object + dchatter 10/26/96 - delete redef of OCISvcCtx, OCIError, OCIEnv + cxcheng 10/15/96 - more changes + cxcheng 10/14/96 - more final fixes to constants + mluong 10/11/96 - + mluong 10/11/96 - KOCON and KONSP are in lowercase + mluong 10/11/96 - add some define per Calvin + cxcheng 10/09/96 - add #define for OROOCOSFN to OCI_COPY_NOREF + jboonleu 10/08/96 - change OROOCOSFN to OCICopyFlag + jboonleu 10/07/96 - use new OCI names for cache options + cxcheng 10/07/96 - add OROTCS02 for KOTTCBRI and OROTCS03 as spare + cxcheng 10/07/96 - more lint fixes + cxcheng 10/02/96 - move oronsp to ko.h as konsp + cxcheng 10/01/96 - add long names for readability + cxcheng 10/01/96 - remove orotty and orotal + rjenkins 09/28/96 - 2k char 4k varchar2 + jboonleu 09/27/96 - add macro used only in beta2 + cxcheng 09/27/96 - move oroenv to oroenv.h + cxcheng 09/24/96 - remove unnecessary orotyp + cxcheng 09/25/96 - add typecode OROTCS01 as placeholder for lob pointer + cxcheng 09/20/96 - add TDO load option orotgo + jboonleu 09/18/96 - add OROOPOREC + jboonleu 09/10/96 - add OROOPODFL + jweisz 08/27/96 - add SQL internal typecode OROTCS00 + cxcheng 08/02/96 - add PLSQL internal typecodes OROTCP.. + cxcheng 08/01/96 - add OROTCFAR to fill up space left by OROTCCAR + jboonleu 07/16/96 - new pin option + cxcheng 06/18/96 - add casts to OROTNOPRE and OROTNOSCL + cxcheng 05/29/96 - change OROTCNPT back to OROTCDOM + vkrishna 05/27/96 - add OROTCCAR + cxcheng 05/17/96 - replace OROTCFAR with OROTCCAR + cxcheng 05/08/96 - change orotmf from ub1 to ub2 + cxcheng 05/07/96 - fix public defines for method types + cxcheng 04/30/96 - change OROTCDOM to OROTCNPT + cxcheng 04/15/96 - remove obsolete OROTTYICT + jboonleu 04/12/96 - add new pin option + sthakur 04/12/96 - add indicator type and indicator status + cxcheng 04/10/96 - add function parameter codes for ORT/KOT + cxcheng 04/03/96 - replace OROTCFAR as OROTCCAR + jwijaya 03/29/96 - add OROTTCCAR + jwijaya 03/27/96 - better comments for orotc + cxcheng 02/23/96 - add typecodes for SMALLINT and VARCHAR2 + skrishna 02/22/96 - add oroind - null indicator type + cxcheng 02/21/96 - change lob character codes to OROTCCLB, OROTCBLB... + jboonleu 02/06/96 - new value for predefined duration + cxcheng 01/12/96 - add OROTCCLO, OROTCBLO, OROTCFIL to orotc + cxcheng 12/05/95 - add OROTCDOM and OROTCAAT to orotc + skotsovo 10/30/95 - reserve space for internal 'oid' type + jwijaya 10/20/95 - support variable-length ref + cxcheng 10/03/95 - add OROTMFOR for ordering function to orotmf + cxcheng 10/03/95 - Adding the ordering function type to orotmf + jboonleu 09/28/95 - set OROODTPRE + jboonleu 09/25/95 - add oroodt + skotsovo 03/10/95 - update to only include release 1 + jboonleu 02/15/95 - add OROOPOREC, remove orocro, oroolo + skotsovo 01/30/95 - add default max lengths for varrays and vstrings + skotsovo 01/24/95 - categorize sint32, double, and real as number types + (with precision and scale) instead of scalar types. + skotsovo 12/20/94 - add release 1 types + skotsovo 12/12/94 - update according to new ots doc + skotsovo 12/01/94 - add default precision and scale + jwijaya 11/15/94 - rename ORONSPTAB to ORONSPEXT + jwijaya 10/25/94 - tint + jwijaya 10/06/94 - add namespace + jwijaya 10/02/94 - connection handle -> connection number + skotsovo 09/12/94 - keep 0 as uninitialized value for ORT consts + skotsovo 08/24/94 - fix orotec + skotsovo 08/17/94 - modify type code names + skotsovo 08/12/94 - fix 141 lint errors + skotsovo 07/25/94 - modify categorization of complex types (orotc) + skotsovo 07/07/94 - change typecode enum values & add decimal type + skotsovo 07/01/94 - change order of typecodes + jwijaya 06/15/94 - review + jboonleu 06/13/94 - add comments for the object cache options + jwijaya 06/13/94 - adhere to the header file template + skotsovo 06/09/94 - make ots scalar type names consistent with the ots + document + jwijaya 06/07/94 - include oratypes.h instead of s.h + skotsovo 05/24/94 - change typecodes + jwijaya 05/23/94 - fix comments of ororef + skotsovo 05/19/94 - remove type composition + skotsovo 05/09/94 - modified orotc according to new OTS document + jwijaya 05/03/94 - oroid and ororef + jwijaya 01/26/94 - Creation +*/ + + +#ifndef ORATYPES +#include +#endif + +#ifndef OCIDFN_ORACLE +#include +#endif + +#ifndef ORO_ORACLE +#define ORO_ORACLE + +/*---------------------------------------------------------------------------*/ +/* SHORT NAMES SUPPORT SECTION */ +/*---------------------------------------------------------------------------*/ + +#ifdef SLSHORTNAME + +/* the following are short names that are only supported on IBM mainframes + with the SLSHORTNAME defined. + With this all subsequent long names will actually be substituted with + the short names here */ + +#define OCIDuration oroodt +#define OCIInd oroind +#define OCILockOpt oroolm +#define OCIMarkOpt oroomo +#define OCIObjectEvent orocev +#define OCIObjectProperty oroopr +#define OCIPinOpt oroopo +#define OCIRef ororef +#define OCIRefreshOpt orooro +#define OCITypeCode orotc +#define OCITypeEncap orotec +#define OCITypeGetOpt orotgo +#define OCITypeMethodFlag orotmf +#define OCITypeParamMode orotpm +#define OCIObjectPropId oroopi +#define OCIObjectLifetime oroolft +#define OCIObjectMarkstatus oroomst +#define OCI_LOCK_NONE OROOLMNUL +#define OCI_LOCK_X OROOLMX +#define OCI_LOCK_X_NOWAIT OROOLMXNW +#define OCI_MARK_DEFAULT OROOMODFL +#define OCI_MARK_NONE OROOMONON +#define OCI_MARK_UPDATE OROOMOUPD +#define OCI_OBJECTEVENT_AFTER_FLUSH OROCEVAFL +#define OCI_OBJECTEVENT_AFTER_REFRESH OROCEVARF +#define OCI_OBJECTEVENT_BEFORE_FLUSH OROCEVBFL +#define OCI_OBJECTEVENT_BEFORE_REFRESH OROCEVBRF +#define OCI_OBJECTEVENT_WHEN_LOCK OROCEVWLK +#define OCI_OBJECTEVENT_WHEN_MARK_DELETED OROCEVWDL +#define OCI_OBJECTEVENT_WHEN_MARK_UPDATED OROCEVWUP +#define OCI_OBJECTEVENT_WHEN_UNMARK OROCEVWUM +#define OCI_OBJECTPROP_DIRTIED OROOPRDRT +#define OCI_OBJECTPROP_LOADED OROOPRLOD +#define OCI_OBJECTPROP_LOCKED OROOPRLCK +#define OCI_PIN_ANY OROOPOANY +#define OCI_PIN_DEFAULT OROOPODFL +#define OCI_PIN_LATEST OROOPOLST +#define OCI_PIN_RECENT OROOPOREC +#define OCI_REFRESH_LOADED OROOROLOD +#define OCI_TYPEENCAP_PRIVATE OROTECPVT +#define OCI_TYPEENCAP_PUBLIC OROTECPUB +#define OCI_TYPEGET_ALL OROTGOALL +#define OCI_TYPEGET_HEADER OROTGOHDR +#define OCI_TYPEMETHOD_CONSTANT OROTMCON +#define OCI_TYPEMETHOD_CONSTRUCTOR OROTMCSTR +#define OCI_TYPEMETHOD_DESTRUCTOR OROTMDSTR +#define OCI_TYPEMETHOD_INLINE OROTMINL +#define OCI_TYPEMETHOD_MAP OROTMMAP +#define OCI_TYPEMETHOD_OPERATOR OROTMOP +#define OCI_TYPEMETHOD_ORDER OROTMOR +#define OCI_TYPEMETHOD_RNDS OROTMRDS +#define OCI_TYPEMETHOD_RNPS OROTMRPS +#define OCI_TYPEMETHOD_SELFISH OROTMSLF +#define OCI_TYPEMETHOD_VIRTUAL OROTMVRT +#define OCI_TYPEMETHOD_WNDS OROTMWDS +#define OCI_TYPEMETHOD_WNPS OROTMWPS +#define OCI_TYPEMETHOD_ABSTRACT OROTMABSTRACT +#define OCI_TYPEMETHOD_OVERRIDING OROTMOVERRIDING +#define OCI_TYPEMETHOD_PIPELINED OROTMPIPELINED +#define OCI_TYPEPARAM_BYREF OROTPMREF +#define OCI_TYPEPARAM_IN OROTPMIN +#define OCI_TYPEPARAM_INOUT OROTPMIO +#define OCI_TYPEPARAM_OUT OROTPMOUT +#define OCI_TYPEPARAM_OUTNCPY OROTPMOUTNCPY +#define OCI_TYPEPARAM_INOUTNCPY OROTPMIONCPY + +#endif /* SLSHORTNAME */ + + +/*---------------------------------------------------------------------------*/ +/* PUBLIC TYPES, CONSTANTS AND MACROS */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* GENERAL OBJECT TYPES, CONSTANTS, MACROS */ +/*---------------------------------------------------------------------------*/ + +/*------------------------- OBJECT REFERENCE (REF) --------------------------*/ + +typedef struct OCIRef OCIRef; +/* + * OCIRef - OCI object REFerence + * + * In the Oracle object runtime environment, an object is identified by an + * object reference (ref) which contains the object identifier plus other + * runtime information. The contents of a ref is opaque to clients. Use + * OCIObjectNew() to construct a ref. + */ + + +/*--------------------------- OBJECT INDICATOR ------------------------------*/ + +typedef sb2 OCIInd; +/* + * OCIInd -- a variable of this type contains (null) indicator information + */ + +#define OCI_IND_NOTNULL (OCIInd)0 /* not NULL */ +#define OCI_IND_NULL (OCIInd)(-1) /* NULL */ +#define OCI_IND_BADNULL (OCIInd)(-2) /* BAD NULL */ +#define OCI_IND_NOTNULLABLE (OCIInd)(-3) /* not NULLable */ + +/*---------------------------------------------------------------------------*/ +/* OBJECT CACHE */ +/*---------------------------------------------------------------------------*/ + +/* To enable object change detection mode, set this to TRUE */ +#define OCI_ATTR_OBJECT_DETECTCHANGE 0x00000020 + +/* To enable object creation with non-NULL attributes by default, set the + following to TRUE. + By default, object is created with NULL attributes +*/ +#define OCI_ATTR_OBJECT_NEWNOTNULL 0x00000010 + +/* To enable sorting of the objects that belong to the same table + before being flushed through OCICacheFlush. + Please note that by enabling this object cache will not be flushing + the objects in the same order they were dirtied */ +#define OCI_ATTR_CACHE_ARRAYFLUSH 0x00000040 + +/*--------------------------- OBJECT PIN OPTION -----------------------------*/ + +enum OCIPinOpt +{ + /* 0 = uninitialized */ + OCI_PIN_DEFAULT = 1, /* default pin option */ + OCI_PIN_ANY = 3, /* pin any copy of the object */ + OCI_PIN_RECENT = 4, /* pin recent copy of the object */ + OCI_PIN_LATEST = 5 /* pin latest copy of the object */ +}; +typedef enum OCIPinOpt OCIPinOpt; + +/* + * OCIPinOpt - OCI object Pin Option + * + * In the Oracle object runtime environment, the program has the option to + * specify which copy of the object to pin. + * + * OCI_PINOPT_DEFAULT pins an object using the default pin option. The default + * pin option can be set as an attribute of the OCI environment handle + * (OCI_ATTR_PINTOPTION). The value of the default pin option can be + * OCI_PINOPT_ANY, OCI_PINOPT_RECENT, or OCI_PIN_LATEST. The default option + * is initialized to OCI_PINOPT_ANY. + * + * OCI_PIN_ANY pins any copy of the object. The object is pinned + * using the following criteria: + * If the object copy is not loaded, load it from the persistent store. + * Otherwise, the loaded object copy is returned to the program. + * + * OCI_PIN_RECENT pins the latest copy of an object. The object is + * pinned using the following criteria: + * If the object is not loaded, load the object from the persistent store + * from the latest version. + * If the object is not loaded in the current transaction and it is not + * dirtied, the object is refreshed from the latest version. + * Otherwise, the loaded object copy is returned to the program. + * + * OCI_PINOPT_LATEST pins the latest copy of an object. The object copy is + * pinned using the following criteria: + * If the object copy is not loaded, load it from the persistent store. + * If the object copy is loaded and dirtied, it is returned to the program. + * Otherwise, the loaded object copy is refreshed from the persistent store. + */ + + + +/*--------------------------- OBJECT LOCK OPTION ----------------------------*/ + +enum OCILockOpt +{ + /* 0 = uninitialized */ + OCI_LOCK_NONE = 1, /* null (same as no lock) */ + OCI_LOCK_X = 2, /* exclusive lock */ + OCI_LOCK_X_NOWAIT = 3 /* exclusive lock, do not wait */ +}; +typedef enum OCILockOpt OCILockOpt; +/* + * OCILockOpt - OCI object LOCK Option + * + * This option is used to specify the locking preferences when an object is + * loaded from the server. + */ + + +/*------------------------- OBJECT MODIFYING OPTION -------------------------*/ + +enum OCIMarkOpt +{ + /* 0 = uninitialized */ + OCI_MARK_DEFAULT = 1, /* default (the same as OCI_MARK_NONE) */ + OCI_MARK_NONE = OCI_MARK_DEFAULT, /* object has not been modified */ + OCI_MARK_UPDATE /* object is to be updated */ +}; +typedef enum OCIMarkOpt OCIMarkOpt; +/* + * OCIMarkOpt - OCI object Mark option + * + * When the object is marked updated, the client has to specify how the + * object is intended to be changed. + */ + +/*-------------------------- OBJECT Duration --------------------------------*/ + +typedef ub2 OCIDuration; + +#define OCI_DURATION_INVALID 0xFFFF /* Invalid duration */ +#define OCI_DURATION_BEGIN (OCIDuration)10 + /* beginning sequence of duration */ +#define OCI_DURATION_NULL (OCIDuration)(OCI_DURATION_BEGIN-1) + /* null duration */ +#define OCI_DURATION_DEFAULT (OCIDuration)(OCI_DURATION_BEGIN-2) /* default */ +#define OCI_DURATION_USER_CALLBACK (OCIDuration)(OCI_DURATION_BEGIN-3) +#define OCI_DURATION_NEXT (OCIDuration)(OCI_DURATION_BEGIN-4) + /* next special duration */ +#define OCI_DURATION_SESSION (OCIDuration)(OCI_DURATION_BEGIN) + /* the end of user session */ +#define OCI_DURATION_TRANS (OCIDuration)(OCI_DURATION_BEGIN+1) + /* the end of user transaction */ +/****************************************************************************** +** DO NOT USE OCI_DURATION_CALL. IT IS UNSUPPORTED ** +** WILL BE REMOVED/CHANGED IN A FUTURE RELEASE ** +******************************************************************************/ +#define OCI_DURATION_CALL (OCIDuration)(OCI_DURATION_BEGIN+2) + /* the end of user client/server call */ +#define OCI_DURATION_STATEMENT (OCIDuration)(OCI_DURATION_BEGIN+3) + +/* This is to be used only during callouts. It is similar to that +of OCI_DURATION_CALL, but lasts only for the duration of a callout. +Its heap is from PGA */ +#define OCI_DURATION_CALLOUT (OCIDuration)(OCI_DURATION_BEGIN+4) + +#define OCI_DURATION_LAST OCI_DURATION_CALLOUT + /* last of predefined durations */ + +/* This is not being treated as other predefined durations such as + SESSION, CALL etc, because this would not have an entry in the duration + table and its functionality is primitive such that only allocate, free, + resize memory are allowed, but one cannot create subduration out of this +*/ +#define OCI_DURATION_PROCESS (OCIDuration)(OCI_DURATION_BEGIN-5) + +/* + * OCIDuration - OCI object duration + * + * A client can specify the duration of which an object is pinned (pin + * duration) and the duration of which the object is in memory (allocation + * duration). If the objects are still pinned at the end of the pin duration, + * the object cache manager will automatically unpin the objects for the + * client. If the objects still exist at the end of the allocation duration, + * the object cache manager will automatically free the objects for the client. + * + * Objects that are pinned with the option OCI_DURATION_TRANS will get unpinned + * automatically at the end of the current transaction. + * + * Objects that are pinned with the option OCI_DURATION_SESSION will get + * unpinned automatically at the end of the current session (connection). + * + * The option OCI_DURATION_NULL is used when the client does not want to set + * the pin duration. If the object is already loaded into the cache, then the + * pin duration will remain the same. If the object is not yet loaded, the + * pin duration of the object will be set to OCI_DURATION_DEFAULT. + */ + +/*----------------------------- OBJECT PROPERTY -----------------------------*/ + +/****************************************************************************** +** DO NOT USE OCIObjectProperty. IT IS UNSUPPORTED ** +** WILL BE REMOVED/CHANGED IN A FUTURE RELEASE ** +******************************************************************************/ +enum OCIObjectProperty +{ + /* 0 = uninitialized */ + OCI_OBJECTPROP_DIRTIED = 1, /* dirty objects */ + OCI_OBJECTPROP_LOADED, /* objects loaded in the transaction */ + OCI_OBJECTPROP_LOCKED /* locked objects */ +}; +typedef enum OCIObjectProperty OCIObjectProperty; +/* + * OCIObjectProperty -- OCI Object Property + * This specifies the properties of objects in the object cache. + */ + +/*------------------------- CACHE REFRESH OPTION ---------------------------*/ + +enum OCIRefreshOpt +{ + /* 0 = uninitialized */ + OCI_REFRESH_LOADED = 1 /* refresh objects loaded in the transaction */ +}; +typedef enum OCIRefreshOpt OCIRefreshOpt; +/* + * OCIRefreshOpt - OCI cache Refresh Option + * This option is used to specify the set of objects to be refreshed. + * + * OCI_REFRESH_LOAD refreshes the objects that are loaded in the current + * transaction. + */ + +/*-------------------------------- OBJECT EVENT -----------------------------*/ + +/****************************************************************************** +** DO NOT USE OCIObjectEvent. IT IS UNSUPPORTED ** +** WILL BE REMOVED/CHANGED IN A FUTURE RELEASE ** +******************************************************************************/ +enum OCIObjectEvent +{ + /* 0 = uninitialized */ + OCI_OBJECTEVENT_BEFORE_FLUSH = 1, /* before flushing the cache */ + OCI_OBJECTEVENT_AFTER_FLUSH, /* after flushing the cache */ + OCI_OBJECTEVENT_BEFORE_REFRESH, /* before refreshing the cache */ + OCI_OBJECTEVENT_AFTER_REFRESH, /* after refreshing the cache */ + OCI_OBJECTEVENT_WHEN_MARK_UPDATED, /* when an object is marked updated */ + OCI_OBJECTEVENT_WHEN_MARK_DELETED, /* when an object is marked deleted */ + OCI_OBJECTEVENT_WHEN_UNMARK, /* when an object is being unmarked */ + OCI_OBJECTEVENT_WHEN_LOCK /* when an object is being locked */ +}; +typedef enum OCIObjectEvent OCIObjectEvent; +/* + * OCIObjectEvent -- OCI Object Event + * This specifies the kind of event that is supported by the object + * cache. The program can register a callback that is invoked when the + * specified event occurs. + */ + +/*----------------------------- OBJECT COPY OPTION --------------------------*/ +#define OCI_OBJECTCOPY_NOREF (ub1)0x01 +/* + * OCIObjectCopyFlag - Object copy flag + * + * If OCI_OBJECTCOPY_NOREF is specified when copying an instance, the + * reference and lob will not be copied to the target instance. + */ + +/*----------------------------- OBJECT FREE OPTION --------------------------*/ +#define OCI_OBJECTFREE_FORCE (ub2)0x0001 +#define OCI_OBJECTFREE_NONULL (ub2)0x0002 +#define OCI_OBJECTFREE_HEADER (ub2)0x0004 +/* + * OCIObjectFreeFlag - Object free flag + * + * If OCI_OBJECTCOPY_FORCE is specified when freeing an instance, the instance + * is freed regardless it is pinned or diritied. + * If OCI_OBJECTCOPY_NONULL is specified when freeing an instance, the null + * structure is not freed. + */ + +/*----------------------- OBJECT PROPERTY ID -------------------------------*/ + +typedef ub1 OCIObjectPropId; +#define OCI_OBJECTPROP_LIFETIME 1 /* persistent or transient or value */ +#define OCI_OBJECTPROP_SCHEMA 2 /* schema name of table containing object */ +#define OCI_OBJECTPROP_TABLE 3 /* table name of table containing object */ +#define OCI_OBJECTPROP_PIN_DURATION 4 /* pin duartion of object */ +#define OCI_OBJECTPROP_ALLOC_DURATION 5 /* alloc duartion of object */ +#define OCI_OBJECTPROP_LOCK 6 /* lock status of object */ +#define OCI_OBJECTPROP_MARKSTATUS 7 /* mark status of object */ +#define OCI_OBJECTPROP_VIEW 8 /* is object a view object or not? */ + +/* + * OCIObjectPropId - OCI Object Property Id + * Identifies the different properties of objects. + */ + +/*----------------------- OBJECT LIFETIME ----------------------------------*/ + +enum OCIObjectLifetime +{ + /* 0 = uninitialized */ + OCI_OBJECT_PERSISTENT = 1, /* persistent object */ + OCI_OBJECT_TRANSIENT, /* transient object */ + OCI_OBJECT_VALUE /* value object */ +}; +typedef enum OCIObjectLifetime OCIObjectLifetime; +/* + * OCIObjectLifetime - OCI Object Lifetime + * Classifies objects depending upon the lifetime and referenceability + * of the object. + */ + +/*----------------------- OBJECT MARK STATUS -------------------------------*/ + +typedef uword OCIObjectMarkStatus; +#define OCI_OBJECT_NEW 0x0001 /* new object */ +#define OCI_OBJECT_DELETED 0x0002 /* object marked deleted */ +#define OCI_OBJECT_UPDATED 0x0004 /* object marked updated */ +/* + * OCIObjectMarkStatus - OCI Object Mark Status + * Status of the object - new or updated or deleted + */ + +/* macros to test the object mark status */ +#define OCI_OBJECT_IS_UPDATED(flag) bit((flag), OCI_OBJECT_UPDATED) +#define OCI_OBJECT_IS_DELETED(flag) bit((flag), OCI_OBJECT_DELETED) +#define OCI_OBJECT_IS_NEW(flag) bit((flag), OCI_OBJECT_NEW) +#define OCI_OBJECT_IS_DIRTY(flag) \ + bit((flag), OCI_OBJECT_UPDATED|OCI_OBJECT_NEW|OCI_OBJECT_DELETED) + +/*---------------------------------------------------------------------------*/ +/* TYPE MANAGER */ +/*---------------------------------------------------------------------------*/ + +/*------------------------------ TYPE CODE ----------------------------------*/ + +/* + * Type manager typecodes + * + * These are typecodes designed to be used with the type manager; + * they also include longer, more readable versions of existing SQLT names. + * Those types that are directly related to existing SQLT types are #define'd + * to their SQLT equivalents. + * + * The type manager typecodes are designed to be useable for all OCI calls. + * They are in the range from 192 to 320 for typecodes, so as not to conflict + * with existing OCI SQLT typecodes (see ocidfn.h). + */ + +#define OCI_TYPECODE_REF SQLT_REF /* SQL/OTS OBJECT REFERENCE */ +#define OCI_TYPECODE_DATE SQLT_DAT /* SQL DATE OTS DATE */ +#define OCI_TYPECODE_SIGNED8 27 /* SQL SIGNED INTEGER(8) OTS SINT8 */ +#define OCI_TYPECODE_SIGNED16 28 /* SQL SIGNED INTEGER(16) OTS SINT16 */ +#define OCI_TYPECODE_SIGNED32 29 /* SQL SIGNED INTEGER(32) OTS SINT32 */ +#define OCI_TYPECODE_REAL 21 /* SQL REAL OTS SQL_REAL */ +#define OCI_TYPECODE_DOUBLE 22 /* SQL DOUBLE PRECISION OTS SQL_DOUBLE */ +#define OCI_TYPECODE_BFLOAT SQLT_IBFLOAT /* Binary float */ +#define OCI_TYPECODE_BDOUBLE SQLT_IBDOUBLE /* Binary double */ +#define OCI_TYPECODE_FLOAT SQLT_FLT /* SQL FLOAT(P) OTS FLOAT(P) */ +#define OCI_TYPECODE_NUMBER SQLT_NUM/* SQL NUMBER(P S) OTS NUMBER(P S) */ +#define OCI_TYPECODE_DECIMAL SQLT_PDN + /* SQL DECIMAL(P S) OTS DECIMAL(P S) */ +#define OCI_TYPECODE_UNSIGNED8 SQLT_BIN + /* SQL UNSIGNED INTEGER(8) OTS UINT8 */ +#define OCI_TYPECODE_UNSIGNED16 25 /* SQL UNSIGNED INTEGER(16) OTS UINT16 */ +#define OCI_TYPECODE_UNSIGNED32 26 /* SQL UNSIGNED INTEGER(32) OTS UINT32 */ +#define OCI_TYPECODE_OCTET 245 /* SQL ??? OTS OCTET */ +#define OCI_TYPECODE_SMALLINT 246 /* SQL SMALLINT OTS SMALLINT */ +#define OCI_TYPECODE_INTEGER SQLT_INT /* SQL INTEGER OTS INTEGER */ +#define OCI_TYPECODE_RAW SQLT_LVB /* SQL RAW(N) OTS RAW(N) */ +#define OCI_TYPECODE_PTR 32 /* SQL POINTER OTS POINTER */ +#define OCI_TYPECODE_VARCHAR2 SQLT_VCS + /* SQL VARCHAR2(N) OTS SQL_VARCHAR2(N) */ +#define OCI_TYPECODE_CHAR SQLT_AFC /* SQL CHAR(N) OTS SQL_CHAR(N) */ +#define OCI_TYPECODE_VARCHAR SQLT_CHR + /* SQL VARCHAR(N) OTS SQL_VARCHAR(N) */ +#define OCI_TYPECODE_MLSLABEL SQLT_LAB /* OTS MLSLABEL */ +#define OCI_TYPECODE_VARRAY 247 /* SQL VARRAY OTS PAGED VARRAY */ +#define OCI_TYPECODE_TABLE 248 /* SQL TABLE OTS MULTISET */ +#define OCI_TYPECODE_OBJECT SQLT_NTY /* SQL/OTS NAMED OBJECT TYPE */ +#define OCI_TYPECODE_OPAQUE 58 /* SQL/OTS Opaque Types */ +#define OCI_TYPECODE_NAMEDCOLLECTION SQLT_NCO + /* SQL/OTS NAMED COLLECTION TYPE */ +#define OCI_TYPECODE_BLOB SQLT_BLOB /* SQL/OTS BINARY LARGE OBJECT */ +#define OCI_TYPECODE_BFILE SQLT_BFILE /* SQL/OTS BINARY FILE OBJECT */ +#define OCI_TYPECODE_CLOB SQLT_CLOB /* SQL/OTS CHARACTER LARGE OBJECT */ +#define OCI_TYPECODE_CFILE SQLT_CFILE /* SQL/OTS CHARACTER FILE OBJECT */ + +/* the following are ANSI datetime datatypes added in 8.1 */ +#define OCI_TYPECODE_TIME SQLT_TIME /* SQL/OTS TIME */ +#define OCI_TYPECODE_TIME_TZ SQLT_TIME_TZ /* SQL/OTS TIME_TZ */ +#define OCI_TYPECODE_TIMESTAMP SQLT_TIMESTAMP /* SQL/OTS TIMESTAMP */ +#define OCI_TYPECODE_TIMESTAMP_TZ SQLT_TIMESTAMP_TZ /* SQL/OTS TIMESTAMP_TZ */ + +#define OCI_TYPECODE_TIMESTAMP_LTZ SQLT_TIMESTAMP_LTZ /* TIMESTAMP_LTZ */ + +#define OCI_TYPECODE_INTERVAL_YM SQLT_INTERVAL_YM /* SQL/OTS INTRVL YR-MON */ +#define OCI_TYPECODE_INTERVAL_DS SQLT_INTERVAL_DS /* SQL/OTS INTRVL DAY-SEC */ +#define OCI_TYPECODE_UROWID SQLT_RDD /* Urowid type */ + + +#define OCI_TYPECODE_OTMFIRST 228 /* first Open Type Manager typecode */ +#define OCI_TYPECODE_OTMLAST 320 /* last OTM typecode */ +#define OCI_TYPECODE_SYSFIRST 228 /* first OTM system type (internal) */ +#define OCI_TYPECODE_SYSLAST 235 /* last OTM system type (internal) */ +#define OCI_TYPECODE_PLS_INTEGER 266 /* type code for PLS_INTEGER */ + +/* the following are PL/SQL-only internal. They should not be used */ +#define OCI_TYPECODE_ITABLE SQLT_TAB /* PLSQL indexed table */ +#define OCI_TYPECODE_RECORD SQLT_REC /* PLSQL record */ +#define OCI_TYPECODE_BOOLEAN SQLT_BOL /* PLSQL boolean */ + +/* NOTE : The following NCHAR related codes are just short forms for saying + OCI_TYPECODE_VARCHAR2 with a charset form of SQLCS_NCHAR. These codes are + intended for use in the OCIAnyData API only and nowhere else. */ +#define OCI_TYPECODE_NCHAR 286 +#define OCI_TYPECODE_NVARCHAR2 287 +#define OCI_TYPECODE_NCLOB 288 + + +/* To indicate absence of typecode being specified */ +#define OCI_TYPECODE_NONE 0 +/* To indicate error has to be taken from error handle - reserved for + sqlplus use */ +#define OCI_TYPECODE_ERRHP 283 + +/* The OCITypeCode type is interchangeable with the existing SQLT type + which is a ub2 */ +typedef ub2 OCITypeCode; + + +/*----------------------- GET OPTIONS FOR TDO ------------------------------*/ + +enum OCITypeGetOpt +{ + OCI_TYPEGET_HEADER, + /* load only the header portion of the TDO when getting type */ + OCI_TYPEGET_ALL /* load all attribute and method descriptors as well */ +}; +typedef enum OCITypeGetOpt OCITypeGetOpt; + +/* + * OCITypeGetOpt + * + * This is the flag passed to OCIGetTypeArray() to indicate how the TDO is + * going to be loaded into the object cache. + * OCI_TYPEGET_HEADER implies that only the header portion is to be loaded + * initially, with the rest loaded in on a 'lazy' basis. Only the header is + * needed for PL/SQL and OCI operations. OCI_TYPEGET_ALL implies that ALL + * the attributes and methods belonging to a TDO will be loaded into the + * object cache in one round trip. Hence it will take much longer to execute, + * but will ensure that no more loading needs to be done when pinning ADOs + * etc. This is only needed if your code needs to examine and manipulate + * attribute and method information. + * + * The default is OCI_TYPEGET_HEADER. + */ + + +/*------------------------ TYPE ENCAPSULTATION LEVEL ------------------------*/ + +enum OCITypeEncap +{ + /* 0 = uninitialized */ + OCI_TYPEENCAP_PRIVATE, /* private: only internally visible */ + OCI_TYPEENCAP_PUBLIC /* public: visible to both internally and externally */ +}; +typedef enum OCITypeEncap OCITypeEncap; +/* + * OCITypeEncap - OCI Encapsulation Level + */ + + +/*---------------------------- TYPE METHOD FLAGS ----------------------------*/ + +enum OCITypeMethodFlag +{ + OCI_TYPEMETHOD_INLINE = 0x0001, /* inline */ + OCI_TYPEMETHOD_CONSTANT = 0x0002, /* constant */ + OCI_TYPEMETHOD_VIRTUAL = 0x0004, /* virtual */ + OCI_TYPEMETHOD_CONSTRUCTOR = 0x0008, /* constructor */ + OCI_TYPEMETHOD_DESTRUCTOR = 0x0010, /* destructor */ + OCI_TYPEMETHOD_OPERATOR = 0x0020, /* operator */ + OCI_TYPEMETHOD_SELFISH = 0x0040, /* selfish method (generic otherwise) */ + + OCI_TYPEMETHOD_MAP = 0x0080, /* map (relative ordering) */ + OCI_TYPEMETHOD_ORDER = 0x0100, /* order (relative ordering) */ + /* OCI_TYPEMETHOD_MAP and OCI_TYPEMETHOD_ORDER are mutually exclusive */ + + OCI_TYPEMETHOD_RNDS= 0x0200, /* Read no Data State (default) */ + OCI_TYPEMETHOD_WNDS= 0x0400, /* Write no Data State */ + OCI_TYPEMETHOD_RNPS= 0x0800, /* Read no Process State */ + OCI_TYPEMETHOD_WNPS= 0x1000, /* Write no Process State */ + OCI_TYPEMETHOD_ABSTRACT = 0x2000, /* abstract (not instantiable) method */ + OCI_TYPEMETHOD_OVERRIDING = 0x4000, /* overriding method */ + OCI_TYPEMETHOD_PIPELINED = 0x8000 /* method is pipelined */ +}; +typedef enum OCITypeMethodFlag OCITypeMethodFlag; + +/* macros to test the type method flags */ +#define OCI_METHOD_IS_INLINE(flag) bit((flag), OCI_TYPEMETHOD_INLINE) +#define OCI_METHOD_IS_CONSTANT(flag) bit((flag), OCI_TYPEMETHOD_CONSTANT) +#define OCI_METHOD_IS_VIRTUAL(flag) bit((flag), OCI_TYPEMETHOD_VIRTUAL) +#define OCI_METHOD_IS_CONSTRUCTOR(flag) bit((flag), OCI_TYPEMETHOD_CONSTRUCTOR) +#define OCI_METHOD_IS_DESTRUCTOR(flag) bit((flag), OCI_TYPEMETHOD_DESTRUCTOR) +#define OCI_METHOD_IS_OPERATOR(flag) bit((flag), OCI_TYPEMETHOD_OPERATOR) +#define OCI_METHOD_IS_SELFISH(flag) bit((flag), OCI_TYPEMETHOD_SELFISH) +#define OCI_METHOD_IS_MAP(flag) bit((flag), OCI_TYPEMETHOD_MAP) +#define OCI_METHOD_IS_ORDER(flag) bit((flag), OCI_TYPEMETHOD_ORDER) +#define OCI_METHOD_IS_RNDS(flag) bit((flag), OCI_TYPEMETHOD_RNDS) +#define OCI_METHOD_IS_WNDS(flag) bit((flag), OCI_TYPEMETHOD_WNDS) +#define OCI_METHOD_IS_RNPS(flag) bit((flag), OCI_TYPEMETHOD_RNPS) +#define OCI_METHOD_IS_WNPS(flag) bit((flag), OCI_TYPEMETHOD_WNPS) +#define OCI_METHOD_IS_ABSTRACT(flag) bit((flag), OCI_TYPEMETHOD_ABSTRACT) +#define OCI_METHOD_IS_OVERRIDING(flag) bit((flag), OCI_TYPEMETHOD_OVERRIDING) +#define OCI_METHOD_IS_PIPELINED(flag) bit((flag), OCI_TYPEMETHOD_PIPELINED) + +#define OCI_TYPEMETHOD_IS_INLINE(flag) bit((flag), OCI_TYPEMETHOD_INLINE) +#define OCI_TYPEMETHOD_IS_CONSTANT(flag) bit((flag), OCI_TYPEMETHOD_CONSTANT) +#define OCI_TYPEMETHOD_IS_VIRTUAL(flag) bit((flag), OCI_TYPEMETHOD_VIRTUAL) +#define OCI_TYPEMETHOD_IS_CONSTRUCTOR(flag) \ + bit((flag), OCI_TYPEMETHOD_CONSTRUCTOR) +#define OCI_TYPEMETHOD_IS_DESTRUCTOR(flag) \ + bit((flag), OCI_TYPEMETHOD_DESTRUCTOR) +#define OCI_TYPEMETHOD_IS_OPERATOR(flag) bit((flag), OCI_TYPEMETHOD_OPERATOR) +#define OCI_TYPEMETHOD_IS_SELFISH(flag) bit((flag), OCI_TYPEMETHOD_SELFISH) +#define OCI_TYPEMETHOD_IS_MAP(flag) bit((flag), OCI_TYPEMETHOD_MAP) +#define OCI_TYPEMETHOD_IS_ORDER(flag) bit((flag), OCI_TYPEMETHOD_ORDER) +#define OCI_TYPEMETHOD_IS_RNDS(flag) bit((flag), OCI_TYPEMETHOD_RNDS) +#define OCI_TYPEMETHOD_IS_WNDS(flag) bit((flag), OCI_TYPEMETHOD_WNDS) +#define OCI_TYPEMETHOD_IS_RNPS(flag) bit((flag), OCI_TYPEMETHOD_RNPS) +#define OCI_TYPEMETHOD_IS_WNPS(flag) bit((flag), OCI_TYPEMETHOD_WNPS) +#define OCI_TYPEMETHOD_IS_ABSTRACT(flag) bit((flag), OCI_TYPEMETHOD_ABSTRACT) +#define OCI_TYPEMETHOD_IS_OVERRIDING(flag) \ + bit((flag), OCI_TYPEMETHOD_OVERRIDING) +#define OCI_TYPEMETHOD_IS_PIPELINED(flag) bit((flag), OCI_TYPEMETHOD_PIPELINED) + +/* macros to set the type method flags */ +#define OCI_TYPEMETHOD_SET_INLINE(flag) bis((flag), OCI_TYPEMETHOD_INLINE) +#define OCI_TYPEMETHOD_SET_CONSTANT(flag) bis((flag), OCI_TYPEMETHOD_CONSTANT) +#define OCI_TYPEMETHOD_SET_VIRTUAL(flag) bis((flag), OCI_TYPEMETHOD_VIRTUAL) +#define OCI_TYPEMETHOD_SET_CONSTRUCTOR(flag) \ + bis((flag), OCI_TYPEMETHOD_CONSTRUCTOR) +#define OCI_TYPEMETHOD_SET_DESTRUCTOR(flag) \ + bis((flag), OCI_TYPEMETHOD_DESTRUCTOR) +#define OCI_TYPEMETHOD_SET_OPERATOR(flag) bis((flag), OCI_TYPEMETHOD_OPERATOR) +#define OCI_TYPEMETHOD_SET_SELFISH(flag) bis((flag), OCI_TYPEMETHOD_SELFISH) +#define OCI_TYPEMETHOD_SET_MAP(flag) bis((flag), OCI_TYPEMETHOD_MAP) +#define OCI_TYPEMETHOD_SET_ORDER(flag) bis((flag), OCI_TYPEMETHOD_ORDER) +#define OCI_TYPEMETHOD_SET_RNDS(flag) bis((flag), OCI_TYPEMETHOD_RNDS) +#define OCI_TYPEMETHOD_SET_WNDS(flag) bis((flag), OCI_TYPEMETHOD_WNDS) +#define OCI_TYPEMETHOD_SET_RNPS(flag) bis((flag), OCI_TYPEMETHOD_RNPS) +#define OCI_TYPEMETHOD_SET_WNPS(flag) bis((flag), OCI_TYPEMETHOD_WNPS) + +/* macros to clear the type method flags */ +#define OCI_TYPEMETHOD_CLEAR_INLINE(flag) bic((flag), OCI_TYPEMETHOD_INLINE) +#define OCI_TYPEMETHOD_CLEAR_CONSTANT(flag) \ + bic((flag), OCI_TYPEMETHOD_CONSTANT) +#define OCI_TYPEMETHOD_CLEAR_VIRTUAL(flag) bic((flag), OCI_TYPEMETHOD_VIRTUAL) +#define OCI_TYPEMETHOD_CLEAR_CONSTRUCTOR(flag) \ + bic((flag), OCI_TYPEMETHOD_CONSTRUCTOR) +#define OCI_TYPEMETHOD_CLEAR_DESTRUCTOR(flag) \ + bic((flag), OCI_TYPEMETHOD_DESTRUCTOR) +#define OCI_TYPEMETHOD_CLEAR_OPERATOR(flag) \ + bic((flag), OCI_TYPEMETHOD_OPERATOR) +#define OCI_TYPEMETHOD_CLEAR_SELFISH(flag) bic((flag), OCI_TYPEMETHOD_SELFISH) +#define OCI_TYPEMETHOD_CLEAR_MAP(flag) bic((flag), OCI_TYPEMETHOD_MAP) +#define OCI_TYPEMETHOD_CLEAR_ORDER(flag) bic((flag), OCI_TYPEMETHOD_ORDER) +#define OCI_TYPEMETHOD_CLEAR_RNDS(flag) bic((flag), OCI_TYPEMETHOD_RNDS) +#define OCI_TYPEMETHOD_CLEAR_WNDS(flag) bic((flag), OCI_TYPEMETHOD_WNDS) +#define OCI_TYPEMETHOD_CLEAR_RNPS(flag) bic((flag), OCI_TYPEMETHOD_RNPS) +#define OCI_TYPEMETHOD_CLEAR_WNPS(flag) bic((flag), OCI_TYPEMETHOD_WNPS) + +/*--------------------------- TYPE PARAMETER MODE ---------------------------*/ + +enum OCITypeParamMode +{ + /* PL/SQL starts this from 0 */ + OCI_TYPEPARAM_IN = 0, /* in */ + OCI_TYPEPARAM_OUT, /* out */ + OCI_TYPEPARAM_INOUT, /* in-out */ + OCI_TYPEPARAM_BYREF, /* call by reference (implicitly in-out) */ + OCI_TYPEPARAM_OUTNCPY, /* OUT with NOCOPY modifier */ + OCI_TYPEPARAM_INOUTNCPY /* IN OUT with NOCOPY modifier */ +}; +typedef enum OCITypeParamMode OCITypeParamMode; + + +/*-------------------------------- DEFAULTS ---------------------------------*/ + +/* default binary and decimal precision and scale */ + +#define OCI_NUMBER_DEFAULTPREC ((ub1)0) /* no precision specified */ +#define OCI_NUMBER_DEFAULTSCALE ((sb1)MAXSB1MINVAL) + /* no binary/decimal scale specified */ + +/* default maximum length for varrays and vstrings (used in sql.bsq) */ + +#define OCI_VARRAY_MAXSIZE 4000 + /* default maximum number of elements for a varray */ +#define OCI_STRING_MAXLEN 4000 /* default maximum length of a vstring */ + +/*---------------------------------------------------------------------------*/ +/* This set of macro is used only in beta2. They should be removed as soon as + * PLSQL has made the changes of not using these macros. + */ + +/* Special duration for allocating memory only. No instance can be allocated + * given these durations. + */ +#define OCICoherency OCIRefreshOpt +#define OCI_COHERENCY_NONE (OCIRefreshOpt)2 +#define OCI_COHERENCY_NULL (OCIRefreshOpt)4 +#define OCI_COHERENCY_ALWAYS (OCIRefreshOpt)5 + +#endif /* ORO_ORACLE */ + diff --git a/libodbc/include/ora_linux/ort.h b/libodbc/include/ora_linux/ort.h new file mode 100644 index 0000000000..36b283dbb5 --- /dev/null +++ b/libodbc/include/ora_linux/ort.h @@ -0,0 +1,2594 @@ +/* @(#)ort.h 1.44 95/07/07 */ + +/* Copyright (c) 1994, 2005, Oracle. All rights reserved. */ + +/* + NAME + + ORT - ORacle's external open Type interface to the open type manager (OTM) + + DESCRIPTION + + The open type manager interface includes dynamic type operations to + create, delete, update, and access types. See the "Functional + Specification for Oracle Object Call Interface (Objects Project), + Version 1.0" for a user level description of the OTM. For a more + detailed description, see the "Component Document for the Open Type + Manager, Version 1.0". + + NOTE: MOST Of the functions in this header file are being desupported. + Please use the OCIDescribeAny interface as described in oci.h + instead. + The OCIType, OCITypeElem, OCITypeMethod abstract types continue + to be supported. The only two functions that remain to be documented + are OCITypeArrayByName and OCITypeArrayByRef. + All obsolete types/functions are marked accordingly below. + + RELATED DOCUMENTS + + For the functional specification for the OTM, see: + [1] Kotsovolos, Susan, "Functional Specification for Oracle Object + Call Interface (Objects Project), Version 1.0", Oracle + Corporation, February 1995. + For the internal design of the OTM, see the following: + [2] Kotsovolos, Susan, "Component Document for the Open Type Manager", + Oracle Corporation, November 1994. + [3] Kotsovolos, Susan, "Design for The Open Type Manager, Oracle + Object Management Subsystem Version 1.0", Oracle Corporation, + March 1994. + [4] Kotsovolos, Susan and Tin A. Nguyen, "The Open Type Manager", + Oracle Corporation, March 1994. + [5] Kotsovolos, Susan and Tin A. Nguyen, "Schema Evolution", + Oracle Corporation, March 1994. + For a description of the types the OTM must support, see: + [6] Nguyen, Tin A., "The Open Type System", Oracle Corporation, + February 1994. + + INSPECTION STATUS + + Inspection date: + Inspection status: + Estimated increasing cost defects per page: + Rule sets: + + ACCEPTANCE REVIEW STATUS + + Review date: + Review status: + Reviewers: + + + **** ALL OBSOLETE FUNCTIONS/TYPES ARE MARKED ACCORDINGLY *** + + EXPORT FUNCTIONS + + None + + PUBLIC DATA STRUCTURES + + OCIType - type descriptor in the object cache + OCITypeElem - type element descriptor in the object cache + (used for attributes and paramters) + OCITypeCode - Open Type System type code. + OCITypeMethod - method descriptor in the object cache + OCITypeParamMode - parameter modes (ie. IN, IN-OUT etc) + + PUBLIC FUNCTIONS + + ITERATOR (for OCITypeAttrNext and OCITypeMethodNext) + + OCITypeIterNew - ** OBSOLETE ** Create new instance of an iteraton. + OCITypeIterSet - ** OBSOLETE ** Initialize iterator. + OCITypeIterFree - ** OBSOLETE ** Free instance of iterator. + + TYPE GET + + OCITypeByName - ** OBSOLETE ** Get a type by name. + OCITypeArrayByName - Get an array of types by their names. + OCITypeByRef - ** OBSOLETE ** Get a type by its CREF. + OCITypeArrayByRef - Get an array of types by their CREFs. + + TYPE ACCESSORS + + OCITypeName - ** OBSOLETE ** OCI Get a type's name. + OCITypeSchema - ** OBSOLETE ** OCI Get a type's schema name. + OCITypeTypeCode - ** OBSOLETE ** OCI Get a type's type code. + OCITypeVersion - ** OBSOLETE ** OCI Get a Type's user-readable Version. + OCITypeAttrs - ** OBSOLETE ** OCI Get a Type's Number of Attributes. + OCITypeMethods - ** OBSOLETE ** OCI Get a Type's Number of Methods. + + TYPE ELEMENT ACCESSORS (they represent attributes/parameters/results) + + OCITypeElemName - ** OBSOLETE ** Get a type element's (only for + attributes) name. + OCITypeElemType - ** OBSOLETE ** Get a type element's type + descriptor. + OCITypeElemTypeCode - ** OBSOLETE ** Get a type element's typecode. + OCITypeElemParameterizedType - ** OBSOLETE ** Get a type element's + parameterized type's type descriptor. + OCITypeElemNumPrec - ** OBSOLETE ** Get a number's precision. + OCITypeElemNumScale - ** OBSOLETE ** Get a decimal or oracle Number's + Scale + OCITypeElemCharSetID - ** OBSOLETE ** Get a fixed or variable length + string's character set ID. + OCITypeElemCharSetForm - ** OBSOLETE ** Get a fixed or variable length + string's character set form (how + character set information has + been specified). + OCITypeElemLength - ** OBSOLETE ** Get a raw, fixed or variable + length string's length. + OCITypeElemParamMode - ** OBSOLETE ** Get element's parameter's mode + (only valid for parameter). + OCITypeElemDefaultValue - ** OBSOLETE ** Get element's Default Value. + + ATTRIBUTE ACCESSORS + + OCITypeAttrByName - ** OBSOLETE ** Get an Attribute by Name. + OCITypeAttrNext - ** OBSOLETE ** Get an Attribute by Iteration. + + COLLECTION ACCESSORS + + OCITypeCollTypeCode - ** OBSOLETE ** Get a named collection's typecode. + OCITypeCollElem - ** OBSOLETE ** Get a named collection's element's + type element information. + OCITypeCollSize - ** OBSOLETE ** Get a named collection's size in + number of elements. + + METHOD ACCESSORS + + OCITypeMethodOverload - ** OBSOLETE ** Get number of overloaded methods + with the given method name. + (no direct equivalent for + OCIDescribe interface) + OCITypeMethodByName - ** OBSOLETE ** Get one or more methods by name. + OCITypeMethodNext - ** OBSOLETE ** Iterate to the next method to + retrieve. + OCITypeMethodName - ** OBSOLETE ** Get method's name. + OCITypeMethodEncap - ** OBSOLETE ** Get method's encapsulation level. + OCITypeMethodFlags - ** OBSOLETE ** et method's flags. + OCITypeMethodMap - ** OBSOLETE ** Get type's map function. + OCITypeMethodOrder - ** OBSOLETE ** Get type's order function. + OCITypeMethodParams - ** OBSOLETE ** Get a method's number of + parameters. + + RESULT ACCESSORS + + OCITypeResult - ** OBSOLETE ** OCI Get a method's Result. + + See also ATTRIBUTE/PARAMETER/RESULT TYPE ACCESSORS. + + PARAMETER ACCESSORS + + OCITypeParamByPos - ** OBSOLETE ** Get a Parameter in a method By + Position. + OCITypeParamByName - ** OBSOLETE ** Get a Parameter in a method By Name. + OCITypeParamPos - ** OBSOLETE ** Get a Parameter's PoSition in a + method. + + CALL GRAPHS: + + Only type accessors are supported for 8.0. + ** OBSOLETE ** please use OCIDescribe interface + + TYPE ACCESSOR EXAMPLE + + CREATE TYPE CAR + ( + name vstring, + age number, + number car_age; /o Oracle number o/ + weight car_weight; /o abstract type o/ + + PUBLIC: + + /o methods o/ + car(orlvs a_name, number an_age, WEIGHT a_weight); + ~car(); + inline number get_age() const; + + /o relative ordering (map) functions o/ + number car_map + ); + + /o the following code accesses the type created above o/ + + ub1 meth_flags; + ub4 i, j; + ub4 text_len, position; + ub4 count; + ub4 length; + OCITypeCode typecode; + OCIRef *attr_ref; + OCIRef *param_ref; + OCIType *tdo, new_tdo, final_tdo; + OCITypeElem *elem; + OCITypeIter *iterator_ort; + oratext (*names)[]; + ub4 lengths[]; + ub4 *positions; + oratext *name; + oratext name_buffer[M_IDEN]; + + /o initialize the references o/ + DISCARD orlrini(env, err, (dvoid *)&attr_ref); + DISCARD orlrini(env, err, (dvoid *)¶m_ref); + + /o ----------------- GET INFORMATION ABOUT A TYPE ----------------- o/ + + /o start a transaction o/ + + /o Pin the type until the end of the transaction. Pinning the type is + o required before using any type accessors. + o/ + if (OCITypeByName(env, err, svc, (oratext *)0, 0, "CAR", strlen("CAR"), + OCI_DURATION_TRANS, &car_ref, &car_tdo) != OCI_SUCCESS) + /o error o/ ; + + /o get the type's name o/ + if (!memcmp(OCITypeName(env, err, car_tdo, &text_len), "person", + text_len)) + /o do something o/ ; + + /o get the type's schema name o/ + if (!memcmp(OCITypeSchema(env, err, car_tdo, &text_len), "john", + text_len)) + /o do something o/ ; + + /o get the type code of the type o/ + if (OCITypeTypeCode(env, err, car_tdo) == OCI_TYPECODE_ADT) + /o do something o/ ; + + /o get the type version o/ + if (!memcmp(OCITypeVersion(env, err, car_tdo, &text_len), "1", text_len)) + /o do something o/ ; + + /o ------- GET FLATTENED POSITION OF AN ATTRIBUTES IN A TYPE ------- o/ + + names = malloc(sizeof(oratext *) * 2); + names[0] = malloc(strlen("car_weight")); + names[1] = malloc(strlen("ounces")); + memcpy(names[0], "car_weight", strlen("car_weight")); + memcpy(names[1], "ounces", strlen("ounces")); + + lengths = malloc(sizeof(ub4) * 2); + lengths[0] = strlen("car_weight"); + lengths[1] = strlen("ounces"); + + /o ---------- GET IMMEDIATE ATTRIBUTES IN A TYPE ---------- o/ + + /o loop through all attributes in the type with iterator o/ + if (OCITypeIterNew(env, err, car_tdo, &iterator_ort) != OCI_SUCCESS) + /o do something o/ + + while (OCITypeAttrNext(env, err, iterator_ort, &ado) != OCI_NO_DATA) + { + /o get the attribute's name o/ + if (!memcmp(OCITypeElemName(env, err, ado, &text_len), + "tiger", text_len)) + /o do something o/ ; + + /o get the attribute's type descriptor o/ + if (OCITypeElemType(env, err, ado, &tdo) != OCI_SUCCESS) + /o error o/ ; + + /o get the attribute's type code o/ + typecode = OCITypeElemTypeCode(env, err, ado); + + switch (typecode) + { + /o scalar types o/ + case OCI_TYPECODE_DATE: /o date o/ + case OCI_TYPECODE_SIGNED8: /o byte o/ + case OCI_TYPECODE_SIGNED16: /o short o/ + case OCI_TYPECODE_UNSIGNED8: /o unsigned byte o/ + case OCI_TYPECODE_UNSIGNED16: /o unsigned short o/ + case OCI_TYPECODE_OCTET: /o octet o/ + case OCI_TYPECODE_TABLE: /o nested table o/ + case OCI_TYPECODE_CLOB: /o character lob o/ + case OCI_TYPECODE_BLOB: /o binary lob o/ + case OCI_TYPECODE_CFILE: /o character file object o/ + case OCI_TYPECODE_BFILE: /o binary file object o/ + + /o do something o/ + break; + + /o number types o/ + case OCI_TYPECODE_NUMBER: /o oracle number o/ + case OCI_TYPECODE_DECIMAL: /o decimal o/ + { + /o get the scale of the number o/ + if (OCITypeElemNumScale(env, err, ado) == 3) + /o do something o/ ; + } + /o fall through to get the precision o/ + + case OCI_TYPECODE_FLOAT: /o float o/ + case OCI_TYPECODE_SIGNED32: /o long o/ + case OCI_TYPECODE_UNSIGNED32: /o unsigned long o/ + case OCI_TYPECODE_REAL: /o real o/ + case OCI_TYPECODE_DOUBLE: /o double o/ + { + /o get the precision of the number o/ + if (OCITypeElemNumPrec(env, err, ado) == 2) + /o do something o/ ; + } + break; + + /o string types o/ + case OCI_TYPECODE_CHAR: /o fixed length string o/ + case OCI_TYPECODE_VARCHAR2: /o variable length string o/ + case OCI_TYPECODE_RAW: /o raw o/ + { + /o get the length of the fixed or variable length string o/ + if (OCITypeElemLength(env, err, ado) < 100) + /o do something o/ + } + break; + + /o parameterized types o/ + case OCI_TYPECODE_REF: /o reference o/ + case OCI_TYPECODE_PTR: /o pointer o/ + { + /o get the type stored in the parameterized type o/ + if (OCITypeElemParameterizedType(env, err, ado, &tdo) + != OCI_SUCCESS) + /o error o/ ; + + /o do something o/ + if (OCI_TYPEELEM_IS_REF(OCITypeElemFlags(env, err, ado)))... + } + break; + + /o domain type o/ + case OCI_TYPECODE_NAMEDCOLLECTION: + switch (OCITypeCollTypeCode(env, err, tdo)) + { + case OCI_TYPECODE_VARRAY: /o variable array o/ + ub4 num_elems; + OCIType *element_type; + + /o get the number of elements in the farray or the maximum number + o of elements in the varray. + o/ + OCITypeCollSize(env, err, tdo, &num_elems); + + /o get the type of the array o/ + OCITypeElemType(env, err, tdo, &element_type); + } + break; + + case OCI_TYPECODE_TABLE: /o multiset o/ + { + OCIType *table_type; + + /o get the type of the multiset o/ + OCITypeElemType(env, err, tdo, &table_type); + + /o do something o/ + } + } + + /o abstract type o/ + case OCI_TYPECODE_ADT: /o abstract data type o/ + { + /o get the adt information o/ + if (OCITypeElemType(env, err, ado, &tdo) != OCI_SUCCESS) + /o error o/ ; + + /o do something o/ + } + break; + + default: + DISCARD printf("Error: invalid type code\n"); + + } /o end of typecode switch o/ + + } /o end of loop through all attributes in a type o/ + + + /o ------------ GET THE IMMEDIATE METHODS OF A TYPE ------------ o/ + + /o loop through all methods in the type by reusing iterator o/ + if (OCITypeIterSet(env, err, car_tdo, iterator_ort) != OCI_SUCCESS) + /o do something o/ + + while (OCITypeMethodNext(env, err, iterator_ort) != OCI_NO_DATA) + { + /o get the method's name o/ + if (!memcmp(OCITypeMethodName(env, err, mdo, &text_len), "car", + text_len)) + /o do something o/ ; + + /o get the method's encapsulation o/ + if (OCITypeMethodEncap(env, err, mdo) == OCI_TYPEENCAP_PUBLIC) + /o do something o/ ; + + /o get the method's flags o/ + meth_flags = OCITypeMethodFlags(env, err, mdo); + if (meth_flags & OCI_TYPEMETHOD_VIRTUAL) + /o do something o/ ; + + + /o ------------ GET THE PARAMETERS IN A METHOD ------------ o/ + + /o loop through all parameters in the method o/ + count = OCITypeMethodParams(env, err, mdo); + for (j = 1; j <= count; j++) + { + /o get the parameter information by position o/ + if (OCITypeParamByPos(env, err, mdo, i, &elem) != OCI_SUCCESS) + /o error o/ ; + + /o get the parameter's name o/ + if (!memcmp(OCITypeElemName(env, err, elem, &text_len), "an_age", + text_len)) + /o do something o/ ; + + /o get the parameter's mode o/ + if (OCITypeElemMode(env, err, elem) == OCI_PARAM_OUT) + /o do something o/ ; + + /o get the parameter's required flag o/ + if (ortgprq(env, err, elem)) + /o do something o/ ; + } + } + + /o get a method by name o/ + if (OCITypeMethodByName(env, err, car_tdo, "car_constructor", + strlen("car_constructor"), NULLP(OCIRef), &mdo) + != OCI_SUCCESS) + /o error o/ ; + + /o get a parameter in a method by name o/ + if (OCITypeParamByName(env, err, mdo, "an_age", strlen("an_age"), &elem) + != OCI_SUCCESS) + /o error o/ ; + + /o get a parameter's typecode o/ + typecode = OCITypeElemTypeCode(env, err, elem); + + /o get a parameter's type object o/ + if (OCITypeElemType(env, err, elem, &tdo)) != OCI_SUCCESS) + /o error o/ ; + + /o get a parameter's position in a method o/ + if (ortgpps(env, err, mdo, "an_age", strlen("an_age"), + &position, NULLP(OCIRef), NULLP(OCITypeElem)) != OCI_SUCCESS) + /o error o/ ; + + /o ------------ GET THE METHOD's RESULT ------------ o/ + + /o get a method by name o/ + if (OCITypeMethodByName(env, err, car_tdo, "get_age", strlen("get_age"), + &mdo) != OCI_SUCCESS) + /o error o/ ; + + /o get the typecode of the method's result o/ + typecode = OCITypeElemTypeCode(env, err, mdo); + + + /o ----------------- END ---------------- o/ + + /o free the references implicitly allocated o/ + DISCARD orlrfre(env, err, (dvoid *)&attr_ref); + DISCARD orlrfre(env, err, (dvoid *)¶m_ref); + + NOTES + + MODIFIED + dmukhin 06/29/05 - ANSI prototypes; miscellaneous cleanup + srseshad 03/12/03 - convert oci public api to ansi + aahluwal 06/03/02 - bug 2360115 + skabraha 04/16/02 - fix compiler warnings + rkasamse 03/02/01 - do not use iterator : keyword in MSVB + bpalaval 02/09/01 - Change text to oratext. + rxgovind 01/31/00 - add OCIType interfaces for transient types + whe 09/01/99 - 976457:check __cplusplus for C++ code + cxcheng 05/06/97 - make OCI_TYPE?? test macros return either 1 or 0 + cxcheng 04/22/97 - add comment on desupporting OCIType functions + skrishna 03/18/97 - fix ifdef for supporting ansi and k&r proto-types + cxcheng 02/26/97 - fix lint problem with oro names + cxcheng 02/06/97 - take out short name support except with SLSHORTNAME + cxcheng 01/15/97 - change prototype of OCITypeElemParameterizedType() + cxcheng 01/03/97 - replace bit in OCI_TYPEPARAM_IS_REQUIRED with bitwis + cxcheng 12/31/96 - replace OCI_PARAM_IS_REQUIRED with OCI_TYPEPARAM_IS_ + cxcheng 12/09/96 - add prototype for OCITypeElemExtTypeCode and OCIType + cxcheng 11/25/96 - add schema name parameter to OCITypeVTInsert() + cxcheng 11/20/96 - fix prototype for OCITypeByName() + cxcheng 11/11/96 - fix prototype for OCITypeByName() + cxcheng 11/05/96 - remove OCITypeElemExtTypeCode and OCITypeCollExtType + dchatter 10/28/96 - change ortgatyp to be OCITypeArrayByName + cxcheng 10/25/96 - fix problem with ortgatyp at end + cxcheng 10/22/96 - add OCITypeByRef and OCITypeArrayByRef + cxcheng 10/20/96 - remove ortgtyp() from #define section at end + cxcheng 10/18/96 - rename OCITypeGetArray to OCITypeArrayByName + cxcheng 10/17/96 - final change to prototype for OCI_TYPEPARAM_IS_REQUI + cxcheng 10/15/96 - rename OCIEncapLevel and OCIMethodFlag + cxcheng 10/14/96 - change prototype of OCITypeResult + mluong 10/11/96 - fix compile error + jwijaya 10/10/96 - fix bug on OCI_PARAM_IS_REQUIRED + cxcheng 10/09/96 - more lint and link fixes + cxcheng 10/08/96 - more lint fixes + cxcheng 10/07/96 - more changes + cxcheng 10/04/96 - replace short names with long names + cxcheng 10/01/96 - change to long names for readability + cxcheng 09/27/96 - rename ortgatyp() to ortgtya() for lint + cxcheng 09/20/96 - add ortgatyp() for array get type + cxcheng 09/18/96 - add array pin and iterator functions + cxcheng 08/09/96 - add version table calls + cxcheng 07/22/96 - add OCITypeElemType() to top + jwijaya 07/03/96 - add ANSI prototypes + cxcheng 06/28/96 - add OCITypeElemCharSetForm() + cxcheng 06/26/96 - fix comment on OCITypeParamByPos()/ortgpps() + cxcheng 06/18/96 - fix comments on OCITypeResult() + cxcheng 06/17/96 - improve comments + skrishna 06/03/96 - change OCITypeCollElem() prototype + vkrishna 05/29/96 - replace OROTCFAR with OROTCCAR + cxcheng 05/28/96 - fix comments, remove non-beta1 functions + cxcheng 05/02/96 - fix prototype bugs + cxcheng 04/29/96 - rename OCITypeElemm() to ortanct() + cxcheng 04/26/96 - add ortgrbp and ortftyi, + fix comments and examples + cxcheng 04/22/96 - big merge to main branch + cxcheng 04/17/96 - fix syntax + cxcheng 04/08/96 - change prototype to ortaty() + skrishna 04/08/96 - change ort*() to take OCIEnv* and OCIError* instead + of oroenv* + cxcheng 03/28/96 - add ortslob(), change ortsstr() prototype + cxcheng 03/13/96 - change alter type interface + cxcheng 03/11/96 - ORT interface changes + cxcheng 02/27/96 - correct comments + jboonleu 02/09/96 - rename oroopd to OCIDuration + cxcheng 01/19/96 - change ORTCTYVAL to ORTCTYEMB for embedded ADT + cxcheng 02/14/96 - add more comments + jboonleu 02/09/96 - rename oroopd to OCIDuration + cxcheng 02/07/96 - fix comments and examples + cxcheng 01/19/96 - new ORT interface without korfc's + cxcheng 01/08/96 - consolidate collection functions + cxcheng 12/14/95 - remove obsolete ortgcol() and ortrelease() + jweisz 12/12/95 - merge screwup: ortdth twice + cxcheng 12/05/95 - change multiset interface for new standard + skotsovo 12/01/95 - merge from /vobs/rdbms/public/ort.h@@/main/ + st_rdbms_big_dev/st_rdbms_obj/ + st_rdbms_jwijaya_variable_ref + cxcheng 11/13/95 - add ortaty()/orteaty() + cxcheng 11/13/95 - add new collection type accessors + skotsovo 10/30/95 - add 'oid' type b/c extent type uses it. + skotsovo 10/24/95 - update according to new variable length ref + cxcheng 10/05/95 - add null support, change prototypes to calls + cxcheng 10/03/95 - add OCITypeMethodOrder() to get ORDER method + cxcheng 09/28/95 - add OCITypeElemm() for collection types support + skotsovo 06/05/95 - add adt_type parameter to ortsab() + skotsovo 05/10/95 - ifdef'd out ortgafp() + skotsovo 03/07/95 - update interface to only include release 1 + skotsovo 02/22/95 - add multiset accessors + skotsovo 02/09/95 - update according to new ots doc + skotsovo 01/31/95 - add rest of release 1 types + skotsovo 01/24/95 - categorize sint32, double, and real as number types + (with precision and scale) instead of scalar types. + skotsovo 01/12/95 - remove dependency from ortdty interface + skotsovo 01/03/95 - remove orotyp accessors + skotsovo 12/12/94 - update comments + skotsovo 12/05/94 - change OCITypeElemParameterizedTyper interface + skotsovo 10/26/94 - add type version table + skotsovo 10/17/94 - fix ortgafp() comments + skotsovo 10/14/94 - modify ortgafp() parameters + skotsovo 10/14/94 - add examples + skotsovo 10/13/94 - add a few new routines + jwijaya 10/07/94 - add namespace to pin by name + jwijaya 10/02/94 - connection handle -> connection number + skotsovo 09/13/94 - modify example to use updated oririni interface + skotsovo 08/25/94 - change scale to sb1 from sb2 + skotsovo 07/28/94 - add ortbeg() and ortend() + skotsovo 07/14/94 - add decimal type & call graph + skotsovo 06/28/94 - subset by removing miscellaneous functions + skotsovo 06/28/94 - consistently put comments before typedefs + skotsovo 06/27/94 - modify according to new header file template, add + more examples, and change ortcty() to return a + reference to the type + skotsovo 06/24/94 - add functions to get type information from orotyp + skotsovo 06/20/94 - finish modifying according to header template + skotsovo 06/09/94 - modify according to header file template + skotsovo 06/08/94 - replace s.h with oratypes.h + skotsovo 05/24/94 - modify comments & update example + skotsovo 05/23/94 - modify fnt names for create, alter and drop type + skotsovo 05/18/94 - remove ortdme() -- delete a method + skotsovo 05/17/94 - add tdo parameter to all type modifiers + skotsovo 05/11/94 - return text* instead of including it in arglist + skotsovo 11/16/93 - creation + +*/ + +#ifndef ORATYPES +#include +#endif +#ifndef ORO_ORACLE +#include +#endif +#ifndef OCI_ORACLE +#include +#endif + +#ifndef ORT_ORACLE +#define ORT_ORACLE + +/*---------------------------------------------------------------------------*/ +/* SHORT NAMES SUPPORT SECTION */ +/*---------------------------------------------------------------------------*/ + +#ifdef SLSHORTNAME + +/* the following are short names that are only supported on IBM mainframes + with the SLSHORTNAME defined. + With this all subsequent long names will actually be substituted with + the short names here */ + +#define OCITypeArrayByName ortgatyp +#define OCITypeAttrByName ortgabn +#define OCITypeAttrNext ortgabi +#define OCITypeAttrs ortgtna +#define OCITypeByRef ortgtbrf +#define OCITypeCollElem ortgcel +#define OCITypeCollExtTypeCode ortgcsqt +#define OCITypeCollSize ortgcne +#define OCITypeCollTypeCode ortgdttc +#define OCITypeElem ortado +#define OCITypeElemCharSetForm ortgscform +#define OCITypeElemCharSetID ortgscid +#define OCITypeElemDefaultValue ortgpdv +#define OCITypeElemExtTypeCode ortgasqt +#define OCITypeElemLength ortgsl +#define OCITypeElemName ortganm +#define OCITypeElemNumPrec ortgnp +#define OCITypeElemNumScale ortgns +#define OCITypeElemParamMode ortgpmo +#define OCITypeElemParameterizedType ortgpa +#define OCITypeElemType ortgaty +#define OCITypeElemTypeCode ortgatc +#define OCITypeIter ortitr +#define OCITypeIterFree ortifre +#define OCITypeIterNew ortinew +#define OCITypeIterSet ortiset +#define OCITypeMethod ortmdo +#define OCITypeMethodByName ortgmbn +#define OCITypeMethodEncap ortgmen +#define OCITypeMethodFlags ortgmfl +#define OCITypeMethodMap ortgmmap +#define OCITypeMethodName ortgmnm +#define OCITypeMethodNext ortgmbi +#define OCITypeMethodOrder ortgmor +#define OCITypeMethodOverload ortgmno +#define OCITypeMethodParams ortgmnp +#define OCITypeMethods ortgtnm +#define OCITypeName ortgtme +#define OCITypeParamByName ortgpbn +#define OCITypeParamPos ortgpps +#define OCITypeSchema ortgtsch +#define OCITypeTypeCode ortgttc +#define OCITypeVTInit ortvini +#define OCITypeVTInsert ortvins +#define OCITypeVTSelect ortvsel +#define OCITypeVersion ortgtvn + +#endif /* SLSHORTNAME */ + + +/*============================*/ +/* PUBLIC TYPES AND CONSTANTS */ +/*============================*/ + +/*----------------------------- TYPE DESCRIPTION ----------------------------*/ + +/* + * OCIType - OCI Type Description Object + * + * The contents of an 'OCIType' is private/opaque to clients. Clients just + * need to declare and pass 'OCIType' pointers in to the type manage + * functions. + * The pointer points to the type in the object cache. Thus, clients don't + * need to allocate space for this type and must NEVER free the pointer to the + * 'OCIType'. + */ + +typedef struct OCIType OCIType; + +/*------------------------- TYPE ELEMENT DESCRIPTION ------------------------*/ + + +/* + * OCITypeElem - OCI Type Element object + * + * The contents of an 'OCITypeElem' is private/opaque to clients. Clients just + * need to declare and pass 'OCITypeElem' pointers in to the type manager + * functions. + * + * 'OCITypeElem' objects contains type element information such as the numeric + * precision for example, for number objects, and the number of elements for + * arrays. + * They ARE used to describe type attributes, collection elements, + * method parameters, and method results. Hence they are pass in or returned + * by attribute, collection, and method parameter/result accessors. + */ + +typedef struct OCITypeElem OCITypeElem; + + +/*--------------------------- METHOD DESCRIPTION ---------------------------*/ + + +/* + * OCITypeMethod - OCI Method Description object + * + * The contents of an 'OCITypeMethod' is private/opaque to clients. Clients + * just need to declare and pass 'OCITypeMethod' pointers in to the type + * manager functions. + * The pointer points to the method in the object cache. Thus, clients don't + * need to allocate space for this type and must NEVER free the pointer to + * the 'OCITypeMethod'. + */ + +typedef struct OCITypeMethod OCITypeMethod; + + +/*--------------------------- TYPE ACCESS ITERATOR --------------------------*/ + +/* + * OCITypeIter- OCI Type Iterator + * + * The contents of an 'orti' is private/opaque to clients. Clients just + * need to declare and pass 'orti' pointers in to the type manager functions. + * The iterator is used to retreive MDO's and ADO's that belong to the TDO + * one at a time. It needs to be allocated by the 'OCITypeIterNew()' function + * call and deallocated with the 'OCITypeIterFree()' function call. + */ + +typedef struct OCITypeIter OCITypeIter; + + +/*==================*/ +/* PUBLIC FUNCTIONS */ +/*==================*/ + +/*--------------------------------------------------------------------------*/ +/* ITERATOR */ +/*--------------------------------------------------------------------------*/ + +/*-----------------------_- OCITypeIterNew ---------------------------------*/ + +/* ** OBSOLETE ** */ +sword OCITypeIterNew( OCIEnv *env, OCIError *err, OCIType *tdo, + OCITypeIter **iterator_ort ); + +/* + NAME: OCITypeIterNew - OCI Iterator NEW + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + tdo (IN) - pointer to the pinned type in the object cache to + initialize the iterator with + iterator_ort (OUT) - pointer to the pointer to the new iterator created + DESCRIPTION: + Create a new instance of a method/attribute iterator and initalize + it's values. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is null. + OCI_ERROR if + 1) any of the required parameters is null. + 2) error while allocating space for the iterator. +*/ + +/*------------------------ OCITypeIterSet ---------------------------------*/ + +/* ** OBSOLETE ** */ +sword OCITypeIterSet( OCIEnv *env, OCIError *err, OCIType *tdo, + OCITypeIter *iterator_ort ); + +/* + NAME: OCITypeIterSet - OCI Iterator SET + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + tdo (IN) - pointer to the pinned type in the object cache to + initialize the iterator with + iterator_ort (IN/OUT) - pointer to the iterator to set + DESCRIPTION: + Initializes the iterator. This is used to reset the state of the + iterator. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is null. + OCI_ERROR if + 1) any of the required parameters is null. +*/ + +/*------------------------ OCITypeIterFree ---------------------------------*/ + +/* ** OBSOLETE ** */ +sword OCITypeIterFree( OCIEnv *env, OCIError *err, OCITypeIter + *iterator_ort ); + +/* + NAME: OCITypeIterFree - OCI Iterator FREe + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + iterator_ort (IN/OUT) - pointer to the iterator to free + DESCRIPTION: + Free space allocated for the iterator. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is null. + OCI_ERROR if + 1) any of the required parameters is null. + 2) error while freeing the iterator, probably bad iterator pointer. +*/ + + +/*--------------------------------------------------------------------------*/ +/* TYPE GET */ +/*--------------------------------------------------------------------------*/ + +/* ** OBSOLETE ** */ +sword OCITypeByName( OCIEnv *env, OCIError *err, const OCISvcCtx *svc, + const oratext *schema_name, ub4 s_length, + const oratext *type_name, ub4 t_length, + const oratext *version_name, ub4 v_length, + OCIDuration pin_duration, OCITypeGetOpt get_option, + OCIType **tdo ); +/* + NAME: OCITypeByName - OCI Get the most current version of an existing TYPe + by name. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + svc (IN) - OCI service handle + schema_name (IN, optional) - name of schema associated with the + type. By default, the user's schema name is used. + s_length (IN) - length of the 'schema_name' parameter + type_name (IN) - name of the type to get + t_length (IN) - length of the 'type_name' parameter + version_name (IN, optional) - user readable version of the type. + Pass (oratext *)0 for the most current version. + v_length (IN) - length of version_name in bytes. Should be 0 if + the most current version is to be retrieved. + pin_duration (IN) - pin duration (e.g. until the end of current + transaction). See 'oro.h' for a description of + each option. + get_option (IN) - options for loading the types. It can be one of two + values: + OCI_TYPEGET_HEADER for only the header to be loaded, or + OCI_TYPEGET_ALL for the TDO and all ADO and MDOs to be + loaded. + tdo (OUT) - pointer to the pinned type in the object cache + DESCRIPTION: + Get a pointer to a version of the existing type associated + with schema/type name. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is null. + OCI_ERROR if + 1) any of the required parameters is null. + 2) the adt type associated with schema/type name does not exist. + NOTE: + Schema and type names are CASE-SENSITIVE. If they have been created + via SQL, you need to use uppercase names. +*/ + +sword OCITypeArrayByName( OCIEnv *env, OCIError *err, const OCISvcCtx *svc, + ub4 array_len, + const oratext *schema_name[], ub4 s_length[], + const oratext *type_name[], ub4 t_length[], + const oratext *version_name[], ub4 v_length[], + OCIDuration pin_duration, + OCITypeGetOpt get_option, OCIType **tdo ); + +/* + NAME: OCITypeArrayByName - OCI Get array of TYPes by name. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + svc (IN) - OCI service handle + array_len (IN) - number of schema_name/type_name/version_name entries to + be retrieved. + schema_name (IN, optional) - array of schema names associated with the + types to be retrieved. The array must have array_len + elements if specified. + If 0 is supplied, the default schema is assumed, otherwise + it MUST have array_len number of elements. + 0 can be supplied for one or more of the entries to indicate + that the default schema is desired for those entries. + s_length (IN) - array of schema_name lengths with each entry + corresponding to the length of the corresponding schema_name + entry in the schema_name array in bytes. + The array must either have array_len number of elements or + it MUST be 0 if schema_name is not specified. + type_name (IN) - array of the names of the types to retrieve. This + MUST have array_len number of elements. + t_length (IN) - array of the lengths of type names in the type_name + array in bytes. + version_name (IN) - array of the version names of the types to retrieve + corresponding. This can be 0 to indicate retrieval of the + most current versions, or it MUST have array_len number of + elements. + If 0 is supplied, the most current version is assumed, + otherwise it MUST have array_len number of elements. + 0 can be supplied for one or more of the entries to indicate + that the current version is desired for those entries. + v_length (IN) - array of the lengths of version names in the + version_name array in bytes. + pin_duration (IN) - pin duration (e.g. until the end of current + transaction) for the types retreieve. See 'oro.h' for a + description of each option. + get_option (IN) - options for loading the types. It can be one of two + values: + OCI_TYPEGET_HEADER for only the header to be loaded, or + OCI_TYPEGET_ALL for the TDO and all ADO and MDOs to be + loaded. + tdo (OUT) - output array for the pointers to each pinned type in the + object cache. It must have space for array_len pointers. + Use OCIObjectGetObjectRef() to obtain the CREF to each + pinned type descriptor. + DESCRIPTION: + Get pointers to the existing types associated with the schema/type name + array. This is similar to OCITypeByName() except that all the TDO's are + retreived via a single network roundtrip. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is null. + OCI_ERROR if + 1) any of the required parameters is null. + 2) one or more adt types associated with a schema/type name entry + does not exist. +*/ + +sword OCITypeByRef( OCIEnv *env, OCIError *err, + const OCIRef *type_ref, OCIDuration pin_duration, + OCITypeGetOpt get_option, OCIType **tdo ); + +/* + NAME: OCITypeArrayByRef - OCI Get array of TYPes by REF. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + type_ref (IN) - OCIRef * pointing to the particular version of + the type descriptor object to obtain. + The array must have array_len elements if specified. + pin_duration (IN) - pin duration (e.g. until the end of current + transaction) for the type to retreieve. See 'oro.h' for a + description of each option. + get_option (IN) - options for loading the type. It can be one of two + values: + OCI_TYPEGET_HEADER for only the header to be loaded, or + OCI_TYPEGET_ALL for the TDO and all ADO and MDOs to be + loaded. + tdo (OUT) - pointer to the pinned type in the object cache + DESCRIPTION: + Get pointers to the + with the schema/type name array. This is similar to OCITypeByName() + except that all the TDO's are retreived via a single network roundtrip. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is null. + OCI_ERROR if + 1) any of the required parameters is null. + 2) one or more adt types associated with a schema/type name entry + does not exist. +*/ + +sword OCITypeArrayByRef( OCIEnv *env, OCIError *err, + ub4 array_len, const OCIRef **type_ref, + OCIDuration pin_duration, + OCITypeGetOpt get_option, OCIType **tdo ); + +/* + NAME: OCITypeArrayByRef - OCI Get array of TYPes by REF. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + array_len (IN) - number of schema_name/type_name/version_name entries to + be retrieved. + type_ref (IN) - array of OCIRef * pointing to the particular version of + the type descriptor object to obtain. + The array must have array_len elements if specified. + pin_duration (IN) - pin duration (e.g. until the end of current + transaction) for the types retreieve. See 'oro.h' for a + description of each option. + get_option (IN) - options for loading the types. It can be one of two + values: + OCI_TYPEGET_HEADER for only the header to be loaded, or + OCI_TYPEGET_ALL for the TDO and all ADO and MDOs to be + loaded. + tdo (OUT) - output array for the pointers to each pinned type in the + object cache. It must have space for array_len pointers. + Use OCIObjectGetObjectRef() to obtain the CREF to each + pinned type descriptor. + DESCRIPTION: + Get pointers to the + with the schema/type name array. This is similar to OCITypeByName() + except that all the TDO's are retreived via a single network roundtrip. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is null. + OCI_ERROR if + 1) any of the required parameters is null. + 2) one or more adt types associated with a schema/type name entry + does not exist. +*/ + + +/*--------------------------------------------------------------------------*/ +/* TYPE ACCESSORS */ +/*--------------------------------------------------------------------------*/ + +/*---------------------------- OCITypeName ---------------------------------*/ + +/* ** OBSOLETE ** */ +oratext* OCITypeName( OCIEnv *env, OCIError *err, const OCIType *tdo, + ub4 *n_length ); +/* + NAME: OCITypeName - ORT Get a Type's naME. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + tdo (IN) - pointer to to the type descriptor in the object cache + n_length (OUT) - length (in bytes) of the returned type name. The + caller must allocate space for the ub4 before calling this + routine. + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) All input parameters must not be NULL and must be valid. + 3) 'n_length' must point to an allocated ub4. + DESCRIPTION: + Get the name of the type. + RETURNS: + the name of the type + NOTES: + The type descriptor, 'tdo', must be unpinned when the accessed + information is no longer needed. + */ + +/*------------------------ OCITypeSchema ---------------------------------*/ + +/* ** OBSOLETE ** */ +oratext* OCITypeSchema( OCIEnv *env, OCIError *err, const OCIType *tdo, + ub4 *n_length ); +/* + NAME: OCITypeSchema - ORT Get a Type's SCHema name. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + tdo (IN) - pointer to to the type descriptor in the object cache + n_length (OUT) - length (in bytes) of the returned schema name. The + caller must allocate space for the ub4 before calling this + routine. + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) All input parameters must not be NULL and must be valid. + 3) 'n_length' must point to an allocated ub4. + DESCRIPTION: + Get the schema name of the type. + RETURNS: + the schema name of the type + NOTES: + The type descriptor, 'tdo', must be unpinned when the accessed + information is no longer needed. + */ + +/*------------------------ OCITypeTypeCode ---------------------------------*/ + +/* ** OBSOLETE ** */ +OCITypeCode OCITypeTypeCode( OCIEnv *env, OCIError *err, + const OCIType *tdo ); +/* + NAME: OCITypeTypeCode - OCI Get a Type's Type Code. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + tdo (IN) - pointer to to the type descriptor in the object cache + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) All input parameters must not be NULL and must be valid. + DESCRIPTION: + Get the type code of the type. + RETURNS: + The type code of the type. + NOTES: + The type descriptor, 'tdo', must be unpinned when the accessed + information is no longer needed. + */ + +/*----------------------- OCITypeCollTypeCode -------------------------------*/ + +/* ** OBSOLETE ** */ +OCITypeCode OCITypeCollTypeCode( OCIEnv *env, OCIError *err, + const OCIType *tdo ); +/* + NAME: OCITypeCollTypeCode - OCI Get a Domain Type's Type Code. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + tdo (IN) - pointer to to the type descriptor in the object cache + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) All input parameters must not be NULL and must be valid. + 3) 'tdo' MUST point to a named collection type. + DESCRIPTION: + Get the type code of the named collection type. For V8.0, named + collection types can only be variable length arrays and nested tables. + RETURNS: + OCI_TYPECODE_VARRAY for variable length array, and + OCI_TYPECODE_TABLE for nested tables. + NOTES: + The type descriptor, 'tdo', should be unpinned when the accessed + information is no longer needed. + */ + +/*------------------------- OCITypeVersion ---------------------------------*/ + +/* ** OBSOLETE ** */ +oratext* OCITypeVersion( OCIEnv *env, OCIError *err, const OCIType *tdo, + ub4 *v_length ); +/* + NAME: OCITypeVersion - OCI Get a Type's user-readable VersioN. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + tdo (IN) - pointer to to the type descriptor in the object cache + v_length (OUT) - length (in bytes) of the returned user-readable + version. The caller must allocate space for the ub4 before + calling this routine. + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) All input parameters must not be NULL and must be valid. + 3) 'v_length' must point to an allocated ub4. + DESCRIPTION: + Get the user-readable version of the type. + RETURNS: + The user-readable version of the type + NOTES: + The type descriptor, 'tdo', must be unpinned when the accessed + information is no longer needed. + */ + +/*--------------------------- OCITypeAttrs ---------------------------------*/ + +/* ** OBSOLETE ** */ +ub4 OCITypeAttrs( OCIEnv *env, OCIError *err, const OCIType *tdo ); +/* + NAME: OCITypeAttrs - OCI Get a Type's Number of Attributes. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + tdo (IN) - pointer to to the type descriptor in the object cache + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) All input parameters must not be NULL and must be valid. + DESCRIPTION: + Get the number of attributes in the type. + RETURNS: + The number of attributes in the type. 0 for ALL non-ADTs. + NOTES: + The type descriptor, 'tdo', must be unpinned when the accessed + information is no longer needed. + */ + +/*------------------------- OCITypeMethods ---------------------------------*/ + +/* ** OBSOLETE ** */ +ub4 OCITypeMethods( OCIEnv *env, OCIError *err, const OCIType *tdo ); +/* + NAME: OCITypeMethods - OCI Get a Type's Number of Methods. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + tdo (IN) - pointer to to the type descriptor in the object cache + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) All input parameters must not be NULL and must be valid. + DESCRIPTION: + Get the number of methods in a type. + RETURNS: + The number of methods in the type + NOTES: + The type descriptor, 'tdo', must be unpinned when the accessed + information is no longer needed. + */ + + +/*--------------------------------------------------------------------------*/ +/* TYPE ELEMENT INFORMATION ACCESSORS */ +/*--------------------------------------------------------------------------*/ + +/*------------------------ OCITypeElemName ---------------------------------*/ + +/* ** OBSOLETE ** */ +oratext* OCITypeElemName( OCIEnv *env, OCIError *err, + const OCITypeElem *elem, ub4 *n_length ); +/* + NAME: OCITypeElemName - OCI Get an Attribute's NaMe. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + elem (IN) - pointer to the type element descriptor in the object cache + n_length (OUT) - length (in bytes) of the returned attribute name. + The caller must allocate space for the ub4 before calling this + routine. + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) All input parameters must not be NULL and must be valid. + 3) 'n_length' must point to an allocated ub4. + DESCRIPTION: + Get the name of the attribute. + RETURNS: + the name of the attribute and the length in n_length + NOTES: + The type must be unpinned when the accessed information is no + longer needed. + */ + +/*------------------------ OCITypeElemTypeCode ------------------------------*/ + +/* ** OBSOLETE ** */ +OCITypeCode OCITypeElemTypeCode( OCIEnv *env, OCIError *err, + const OCITypeElem *elem ); +/* + NAME: OCITypeElemTypeCode - OCI Get an Attribute's TypeCode. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + elem (IN) - pointer to the type element descriptor in the object cache + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) All input parameters must not be NULL and must be valid. + DESCRIPTION: + Get the typecode of an attribute's type. + RETURNS: + the typecode of the attribute's type. If this is a scalar type, the + typecode sufficiently describes the scalar type and no further calls + need to be made. Valid scalar types include: OCI_TYPECODE_SIGNED8, + OCI_TYPECODE_UNSIGNED8, OCI_TYPECODE_SIGNED16, OCI_TYPECODE_UNSIGNED16, + OCI_TYPECODE_SIGNED32, OCI_TYPECODE_UNSIGNED32, OCI_TYPECODE_REAL, + OCI_TYPECODE_DOUBLE, OCI_TYPECODE_DATE, + OCI_TYPECODE_MLSLABEL, OROTCOID, OCI_TYPECODE_OCTET, or OROTCLOB. + This function converts the CREF (stored in the attribute) into a + typecode. + NOTES: + The type must be unpinned when the accessed information is no + longer needed. + */ + +/*------------------------ OCITypeElemType ---------------------------------*/ + +/* ** OBSOLETE ** */ +sword OCITypeElemType( OCIEnv *env, OCIError *err, const OCITypeElem *elem, + OCIType **elem_tdo ); +/* + PARAMETERS + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + elem (IN) - pointer to the type element descriptor in the object cache + elem_tdo (OUT) - If the function completes successfully, 'elem_tdo' + points to the type descriptor (in the object cache) of the type of + the element. + + REQUIRES + 1) All type accessors require that the type be pinned before calling + any accessor. This can be done by calling 'OCITypeByName()'. + 2) if 'elem' is not null, it must point to a valid type element descriptor + in the object cache. + + DESCRIPTION + Get the type tdo of the type of this element. + RETURNS + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is null. + OCI_ERROR if + 1) any of the parameters is null. + + NOTES + The type must be unpinned when the accessed information is no + longer needed. This can be done by calling 'OCIObjectUnpin()'. + */ + +/*------------------------- OCITypeElemFlags -------------------------------*/ + +/* ** OBSOLETE ** */ +ub4 OCITypeElemFlags( OCIEnv *env, OCIError *err, + const OCITypeElem *elem ); +/* + NAME: OCITypeElemFlags - OCI Get a Elem's FLags + (inline, constant, virtual, constructor, + destructor). + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + elem (IN) - pointer to the type element descriptor in the object cache + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) All input parameters must not be NULL and must be valid. + DESCRIPTION: + Get the flags of a type element (attribute, parameter). + RETURNS: + The flags of the type element. + NOTES: + The flag bits are not externally documented. Use only the macros + in the last section (ie. OCI_TYPEPARAM_IS_REQUIRED, and + OCI_TYPEELEM_IS_REF) to test for them only. The type must be unpinned + when the accessed information is no longer needed. + */ + +/*------------------------ OCITypeElemNumPrec ------------------------------*/ + +/* ** OBSOLETE ** */ +ub1 OCITypeElemNumPrec( OCIEnv *env, OCIError *err, + const OCITypeElem *elem ); +/* + NAME: OCITypeElemNumPrec - Get a Number's Precision. This includes float, + decimal, real, double, and oracle number. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + elem (IN) - pointer to the type element descriptor in the object cache + REQUIRES: + All input parameters must not be NULL and must be valid. + DESCRIPTION: + Get the precision of a float, decimal, long, unsigned long, real, + double, or Oracle number type. + RETURNS: + the precision of the float, decimal, long, unsigned long, real, double, + or Oracle number + */ + +/*------------------------- OCITypeElemNumScale -----------------------------*/ + +/* ** OBSOLETE ** */ +sb1 OCITypeElemNumScale( OCIEnv *env, OCIError *err, + const OCITypeElem *elem ); +/* + NAME: OCITypeElemNumScale - Get a decimal or oracle Number's Scale + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + elem (IN) - pointer to the type element descriptor in the object cache + REQUIRES: + All input parameters must not be NULL and must be valid. + DESCRIPTION: + Get the scale of a decimal, or Oracle number type. + RETURNS: + the scale of the decimal, or Oracle number + */ + +/*------------------------ OCITypeElemLength -------------------------------*/ + +/* ** OBSOLETE ** */ +ub4 OCITypeElemLength( OCIEnv *env, OCIError *err, + const OCITypeElem *elem ); +/* + NAME: OCITypeElemLength - Get a raw, fixed or variable length String's + length in bytes. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + elem (IN) - pointer to the type element descriptor in the object cache + REQUIRES: + All input parameters must not be NULL and must be valid. + DESCRIPTION: + Get the length of a raw, fixed or variable length string type. + RETURNS: + length of the raw, fixed or variable length string + */ + +/*----------------------- OCITypeElemCharSetID -----------------------------*/ + +/* ** OBSOLETE ** */ +ub2 OCITypeElemCharSetID( OCIEnv *env, OCIError *err, + const OCITypeElem *elem ); +/* + NAME: OCITypeElemCharSetID - Get a fixed or variable length String's + character set ID + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + elem (IN) - pointer to the type element descriptor in the object cache + REQUIRES: + All input parameters must not be NULL and must be valid. + DESCRIPTION: + Get the character set ID of a fixed or variable length string type. + RETURNS: + character set ID of the fixed or variable length string + */ + +/*---------------------- OCITypeElemCharSetForm ----------------------------*/ + +/* ** OBSOLETE ** */ +ub2 OCITypeElemCharSetForm( OCIEnv *env, OCIError *err, + const OCITypeElem *elem ); +/* + NAME: OCITypeElemCharSetForm - Get a fixed or variable length String's + character set specification form. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + elem (IN) - pointer to the attribute information in the object cache + REQUIRES: + All input parameters must not be NULL and must be valid. + DESCRIPTION: + Get the character form of a fixed or variable length string type. + The character form is an enumerated value that can be one of the + 4 values below: + SQLCS_IMPLICIT for CHAR, VARCHAR2, CLOB w/o a specified set + SQLCS_NCHAR for NCHAR, NCHAR VARYING, NCLOB + SQLCS_EXPLICIT for CHAR, etc, with "CHARACTER SET ..." syntax + SQLCS_FLEXIBLE for PL/SQL "flexible" parameters + RETURNS: + character form of the fixed or variable string + */ + +/*--------------------- OCITypeElemParameterizedType ------------------------*/ + +/* ** OBSOLETE ** */ +sword OCITypeElemParameterizedType( OCIEnv *env, OCIError *err, + const OCITypeElem *elem, + OCIType **type_stored ); +/* + NAME: OCITypeElemParameterizedType + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + elem (IN) - pointer to the type element descriptor in the object cache + type_stored (OUT) - If the function completes successfully, + and the parameterized type is complex, 'type_stored' is NULL. + Otherwise, 'type_stored' points to the type descriptor (in the + object cache) of the type that is stored in the parameterized + type. The caller must allocate space for the OCIType* + before calling this routine and must not write into the space. + REQUIRES: + All input parameters must be valid. + DESCRIPTION: + Get a descriptor to the parameter type of a parameterized type. + Parameterized types are types of the form: + REF T + VARRAY (n) OF T + etc, where T is the parameter in the parameterized type. + Additionally is_ref is set if the parameter is a PTR or REF. + For example, it is set for REF T or VARRAY(n) OF REF T. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is null. + OCI_ERROR if + 1) any of the parameters is null. + 2) 'type_stored' is not NULL but points to NULL data. + NOTES: + Complex parameterized types will be in a future release (once + typedefs are supported. When setting the parameterized type + information, the user must typedef the contents if it's a + complex parameterized type. Ex. for varray>, use + 'typedef varray varcar' and then use varray. + */ + +/*----------------------- OCITypeElemExtTypeCode ----------------------------*/ + +/* ** OBSOLETE ** */ +OCITypeCode OCITypeElemExtTypeCode( OCIEnv *env, OCIError *err, + const OCITypeElem *elem ); +/* + NAME: OCITypeElemExtTypeCode - OCI Get an element's SQLT constant. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + elem (IN) - pointer to the type element descriptor in the object cache + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) All input parameters must not be NULL and must be valid. + DESCRIPTION: + Get the internal Oracle typecode associated with an attribute's type. + This is the actual typecode for the attribute when it gets mapped + to a column in the Oracle database. + RETURNS: + The Oracle typecode associated with the attribute's type. + NOTES: + The type must be unpinned when the accessed information is no + longer needed. + */ + +/*--------------------------------------------------------------------------*/ +/* ATTRIBUTE ACCESSORS */ +/*--------------------------------------------------------------------------*/ + +/*------------------------ OCITypeAttrByName -------------------------------*/ + +/* ** OBSOLETE ** */ +sword OCITypeAttrByName( OCIEnv *env, OCIError *err, const OCIType *tdo, + const oratext *name, ub4 n_length, + OCITypeElem **elem ); +/* + NAME: OCITypeAttrByName - OCI Get an Attribute By Name. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + tdo (IN) - pointer to to the type descriptor in the object cache + name (IN) - the attribute's name + n_length (IN) - length (in bytes) of the 'name' parameter + elem (OUT) - If this function completes successfully, 'elem' points to + the selected type element descriptor pertaining to the + attributein the object cache. + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) if 'tdo' is not null, it must point to a valid type descriptor + in the object cache. + DESCRIPTION: + Get an attribute given its name. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is null. + OCI_ERROR if + 1) any of the required parameters is null. + 2) the type does not contain an attribute with the input 'name'. + 3) 'name' is NULL. + NOTES: + The type descriptor, 'tdo', must be unpinned when the accessed + information is no longer needed. + Schema and type names are CASE-SENSITIVE. If they have been created + via SQL, you need to use uppercase names. + */ + +/*------------------------ OCITypeAttrNext ---------------------------------*/ + +/* ** OBSOLETE ** */ +sword OCITypeAttrNext( OCIEnv *env, OCIError *err, + OCITypeIter *iterator_ort, OCITypeElem **elem ); + +/* + NAME: OCITypeAttrNext - OCI Get an Attribute By Iteration. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + iterator_ort (IN/OUT) - iterator for retrieving the next attribute; + see OCITypeIterNew() to initialize iterator. + elem (OUT) - If this function completes successfully, 'elem' points to + the selected type element descriptor pertaining to the + attributein the object cache. + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) if 'tdo' is not null, it must point to a valid type descriptor + in the object cache. + DESCRIPTION: + Iterate to the next attribute to retrieve. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_NO_DATA if there are no more attributes to iterate on; use + OCITypeIterSet() to reset the iterator if necessary. + OCI_INVALID_HANDLE if 'env' or 'err' is null. + OCI_ERROR if + 1) any of the required parameters is null. + NOTES: + The type must be unpinned when the accessed information is no + longer needed. + */ + +/*--------------------------------------------------------------------------*/ +/* COLLECTION ACCESSORS */ +/*--------------------------------------------------------------------------*/ + +/*------------------------ OCITypeCollElem ---------------------------------*/ + +/* ** OBSOLETE ** */ +sword OCITypeCollElem( OCIEnv *env, OCIError *err, const OCIType *tdo, + OCITypeElem **element ); +/* + NAME: OCITypeCollElem + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + tdo (IN) - pointer to the type descriptor in the object cache + element (IN/OUT) - If the function completes successfully, this + points to the descriptor for the collection's element. + It is stored in the same format as an ADT attribute's + descriptor. + If *element is NULL, OCITypeCollElem() implicitly allocates a + new instance of OCITypeElem in the object cache. This instance + will be + automatically freed at the end of the session, and does not have + to be freed explicitly. + If *element is not NULL, OCITypeCollElem() assumes that it + points to a valid OCITypeElem descriptor and will copy the + results into it. + REQUIRES: + All input parameters must be valid. + DESCRIPTION: + Get a pointer to the descriptor (OCITypeElem) of the element of an + array or the rowtype of a nested table. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is null. + OCI_ERROR if + 1) any of the parameters is null. + 2) the type TDO does not point to a valid collection's type. + NOTES: + Complex parameterized types will be in a future release (once + typedefs are supported. When setting the parameterized type + information, the user must typedef the contents if it's a + complex parameterized type. Ex. for varray>, use + 'typedef varray varcar' and then use varray. + */ + +/*------------------------ OCITypeCollSize ---------------------------------*/ + +/* ** OBSOLETE ** */ +sword OCITypeCollSize( OCIEnv *env, OCIError *err, const OCIType *tdo, + ub4 *num_elems ); +/* + NAME: OCITypeCollSize - OCI Get a Collection's Number of Elements. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + tdo (IN) - pointer to the type descriptor in the object cache + num_elems (OUT) - number of elements in collection + REQUIRES: + All input parameters must be valid. tdo points to an array type + defined as a domain. + DESCRIPTION: + Get the number of elements stored in a fixed array or the maximum + number of elements in a variable array. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is null. + OCI_ERROR if + 1) any of the parameters is null. + 2) 'tdo' does not point to a domain with a collection type. + NOTES: + Complex parameterized types will be in a future release (once + typedefs are supported. When setting the parameterized type + information, the user must typedef the contents if it's a + complex parameterized type. Ex. for varray>, use + 'typedef varray varcar' and then use varray. + */ + +/*------------------------ OCITypeCollExtTypeCode ---------------------------*/ + +/* ** OBSOLETE ** */ +sword OCITypeCollExtTypeCode( OCIEnv *env, OCIError *err, + const OCIType *tdo, OCITypeCode *sqt_code ); +/* + NAME: ortcsqt - OCI Get a Collection element's DTY constant. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + tdo (IN) - pointer to the type descriptor in the object cache + sqt_code (OUT) - SQLT code of type element. + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) All input parameters must not be NULL and must be valid. + DESCRIPTION: + Get the SQLT constant associated with an domain's element type. + The SQLT codes are defined in and are needed for OCI/OOCI + use. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is null. + OCI_ERROR if + 1) any of the parameters is null. + 2) 'tdo' does not point to a domain with a collection type. + NOTES: + The type must be unpinned when the accessed information is no + longer needed. + */ + + +/*--------------------------------------------------------------------------*/ +/* METHOD ACCESSORS */ +/*--------------------------------------------------------------------------*/ + +/*------------------------- OCITypeMethodOverload --------------------------*/ + +/* ** OBSOLETE ** */ +ub4 OCITypeMethodOverload( OCIEnv *env, OCIError *err, const OCIType *tdo, + const oratext *method_name, ub4 m_length ); +/* + NAME: OCITypeMethodOverload - OCI Get type's Number of Overloaded names + for the given method name. + PARAMETERS: + gp (IN/OUT) - pga environment handle. Any errors are recorded here. + tdo (IN) - pointer to to the type descriptor in the object cache + method_name (IN) - the method's name + m_length (IN) - length (in bytes) of the 'method_name' parameter + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) if 'tdo' is not null, it must point to a valid type descriptor + in the object cache. + DESCRIPTION: + Overloading of methods implies that more than one method may have the + same method name. This routine returns the number of methods that + have the given method name. If there are no methods with the input + method name, 'num_methods' is 0. The caller uses this information when + allocating space for the array of mdo and/or position pointers before + calling 'OCITypeMethodByName()' or 'ortgmps()'. + RETURNS: + The number of methods with the given name. 0 if none contains the + name. + NOTES: + Schema and type names are CASE-SENSITIVE. If they have been created + via SQL, you need to use uppercase names. + */ + +/*------------------------ OCITypeMethodByName ------------------------------*/ + +/* ** OBSOLETE ** */ +sword OCITypeMethodByName( OCIEnv *env, OCIError *err, const OCIType *tdo, + const oratext *method_name, ub4 m_length, + OCITypeMethod **mdos ); +/* + NAME: OCITypeMethodByName - OCI Get one or more Methods with Name. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + tdo (IN) - pointer to to the type descriptor in the object cache + method_name (IN) - the methods' name + m_length (IN) - length (in bytes) of the 'name' parameter + mdos (OUT) - If this function completes successfully, 'mdos' points to + the selected methods in the object cache. The caller must + allocate space for the array of OCITypeMethod pointers before + calling this routine and must not write into the space. + The number of OCITypeMethod pointers that will be returned can + be obtained by calling 'OCITypeMethodOverload()'. + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) if 'tdo' is not null, it must point to a valid type descriptor + in the object cache. + DESCRIPTION: + Get one or more methods given the name. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is null. + OCI_ERROR if + 1) any of the required parameters is null. + 2) No methods in type has name 'name'. + 3) 'mdos' is not NULL but points to NULL data. + NOTES: + The type must be unpinned when the accessed information is no + longer needed. + Schema and type names are CASE-SENSITIVE. If they have been created + via SQL, you need to use uppercase names. + */ + +/*------------------------ OCITypeMethodNext --------------------------------*/ + +/* ** OBSOLETE ** */ +sword OCITypeMethodNext( OCIEnv *env, OCIError *err, + OCITypeIter *iterator_ort, + OCITypeMethod **mdo ); + +/* + NAME: OCITypeMethodNext - OCI Get a Method By Iteration. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + iterator_ort (IN/OUT) - iterator for retrieving the next method; + see OCITypeIterNew() to set iterator. + mdo (OUT) - If this function completes successfully, 'mdo' points to + the selected method descriptor in the object cache. Positions + start at 1. The caller must allocate space for the + OCITypeMethod* before calling this routine and must not write + nto the space. + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) if 'tdo' is not null, it must point to a valid type descriptor + in the object cache. + DESCRIPTION: + Iterate to the next method to retrieve. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_NO_DATA if there are no more attributes to iterate on; use + OCITypeIterSet() to reset the iterator if necessary. + OCI_INVALID_HANDLE if 'env' or 'err' is null. + OCI_ERROR if + 1) any of the required parameters is null. + 2) 'mdo' is not NULL but points to NULL data. + NOTES: + The type must be unpinned when the accessed information is no + longer needed. + */ + +/*------------------------ OCITypeMethodName --------------------------------*/ + +/* ** OBSOLETE ** */ +oratext *OCITypeMethodName( OCIEnv *env, OCIError *err, + const OCITypeMethod *mdo, ub4 *n_length ); +/* + NAME: OCITypeMethodName - OCI Get a Method's NaMe. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + mdo (IN) - pointer to the method descriptor in the object cache + n_length (OUT) - length (in bytes) of the 'name' parameter. The caller + must allocate space for the ub4 before calling this routine. + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) All input parameters must not be NULL and must be valid. + DESCRIPTION: + Get the (non-unique) real name of the method. + RETURNS: + the non-unique name of the method or NULL if there is an error. + NOTES: + The type must be unpinned when the accessed information is no + longer needed. + */ + +/*------------------------ OCITypeMethodEncap -------------------------------*/ + +/* ** OBSOLETE ** */ +OCITypeEncap OCITypeMethodEncap( OCIEnv *env, OCIError *err, + const OCITypeMethod *mdo ); +/* + NAME: OCITypeMethodEncap - Get a Method's ENcapsulation (private/public). + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + mdo (IN) - pointer to the method descriptor in the object cache + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) All input parameters must not be NULL and must be valid. + DESCRIPTION: + Get the encapsulation (private, or public) of a method. + RETURNS: + the encapsulation (private, or public) of the method + NOTES: + The type must be unpinned when the accessed information is no + longer needed. + */ + +/*------------------------ OCITypeMethodFlags -------------------------------*/ + +/* ** OBSOLETE ** */ +OCITypeMethodFlag OCITypeMethodFlags( OCIEnv *env, OCIError *err, + const OCITypeMethod *mdo ); +/* + NAME: OCITypeMethodFlags - OCI Get a Method's FLags + (inline, constant, virtual, constructor, + destructor). + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + mdo (IN) - pointer to the method descriptor in the object cache + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) All input parameters must not be NULL and must be valid. + DESCRIPTION: + Get the flags (inline, constant, virutal, constructor, destructor) of + a method. + RETURNS: + the flags (inline, constant, virutal, constructor, destructor) of + the method + NOTES: + The type must be unpinned when the accessed information is no + longer needed. + */ + +/*------------------------ OCITypeMethodMap ---------------------------------*/ + +/* ** OBSOLETE ** */ +sword OCITypeMethodMap( OCIEnv *env, OCIError *err, const OCIType *tdo, + OCITypeMethod **mdo ); +/* + NAME: OCITypeMethodMap - OCI Get the Method's MAP function. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + tdo (IN) - pointer to to the type descriptor in the object cache + mdo (OUT) - If this function completes successfully, and there is a + map function for this type, 'mdo' points to the selected method + descriptor in the object cache. Otherwise, 'mdo' is null. + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) All required input parameters must not be NULL and must be valid. + DESCRIPTION: + A type may have only one map function. 'OCITypeMethodMap()' finds + this function, if it exists, and returns a reference and a pointer to + the method descriptor in the object cache. If the type does not have a + map (relative ordering) function, then 'mdo_ref' and 'mdo' are set + to null and an error is returned. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is null. + OCI_ERROR if + the type does not contain a map function. + NOTES: + The type must be unpinned when the accessed information is no + longer needed. + */ + +/*------------------------ OCITypeMethodOrder -------------------------------*/ + +/* ** OBSOLETE ** */ +sword OCITypeMethodOrder( OCIEnv *env, OCIError *err, const OCIType *tdo, + OCITypeMethod **mdo ); +/* + NAME: OCITypeMethodOrder - OCI Get the Method's ORder function. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + tdo (IN) - pointer to to the type descriptor in the object cache + mdo (OUT) - If this function completes successfully, and there is a + map function for this type, 'mdo' points to the selected method + descriptor in the object cache. Otherwise, 'mdo' is null. + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) All required input parameters must not be NULL and must be valid. + DESCRIPTION: + A type may have only one ORder or MAP function. 'OCITypeMethodOrder()' + finds this function, if it exists, and returns a ref and a pointer + to the method descriptor in the object cache. If the type does not + have a map (relative ordering) function, then 'mdo_ref' and 'mdo' are + set to null and an error is returned. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is null. + OCI_ERROR if + the type does not contain a map function. + NOTES: + The type must be unpinned when the accessed information is no + longer needed. + */ + +/*------------------------ OCITypeMethodParams ------------------------------*/ + +/* ** OBSOLETE ** */ +ub4 OCITypeMethodParams( OCIEnv *env, OCIError *err, + const OCITypeMethod *mdo ); +/* + NAME: OCITypeMethodParams - OCI Get a Method's Number of Parameters. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + mdo (IN) - pointer to the method descriptor in the object cache + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) All input parameters must not be NULL and must be valid. + DESCRIPTION: + Get the number of parameters in a method. + RETURNS: + the number of parameters in the method + NOTES: + The type must be unpinned when the accessed information is no + longer needed. + */ + + +/*--------------------------------------------------------------------------*/ +/* RESULT ACCESSORS */ +/*--------------------------------------------------------------------------*/ + +/*-------------------------- OCITypeResult ---------------------------------*/ + +/* ** OBSOLETE ** */ +sword OCITypeResult( OCIEnv *env, OCIError *err, const OCITypeMethod *mdo, + OCITypeElem **elem ); +/* + NAME: OCITypeResult - OCI Get a method's result type descriptor. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + mdo (IN) - pointer to the method descriptor in the object cache + elem (OUT) - If this function completes successfully, 'rdo' points to + the selected result (parameter) descriptor in the object cache. + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) 'elem' MUST be the address of an OCITypeElem pointer. + DESCRIPTION: + Get the result of a method. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is null. + OCI_ERROR if + 1) any of the required parameters is null. + 2) method returns no results. + NOTES: + The method must be unpinned when the accessed information is no + longer needed. + */ + + +/*--------------------------------------------------------------------------*/ +/* PARAMETER ACCESSORS */ +/*--------------------------------------------------------------------------*/ + +/*------------------------ OCITypeParamByPos -------------------------------*/ + +/* ** OBSOLETE ** */ +sword OCITypeParamByPos( OCIEnv *env, OCIError *err, + const OCITypeMethod *mdo, ub4 position, + OCITypeElem **elem ); +/* + NAME: OCITypeParamByPos - OCI Get a Parameter in a method By Position. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + mdo (IN) - pointer to the method descriptor in the object cache + position (IN) - the parameter's position. Positions start at 1. + elem (OUT) - If this function completes successfully, 'elem' points to + the selected parameter descriptor in the object cache. + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + DESCRIPTION: + Get a parameter given its position in the method. Positions start + at 1. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is null. + OCI_ERROR if + 1) any of the required parameters is null. + 2) 'position' is not >= 1 and <= the number of parameters in the + method. + NOTES: + The type must be unpinned when the accessed information is no + longer needed. + */ + +/*------------------------ OCITypeParamByName -------------------------------*/ + +/* ** OBSOLETE ** */ +sword OCITypeParamByName( OCIEnv *env, OCIError *err, + const OCITypeMethod *mdo, + const oratext *name, ub4 n_length, + OCITypeElem **elem ); +/* + NAME: OCITypeParamByName - OCI Get a Parameter in a method By Name. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + mdo (IN) - pointer to the method descriptor in the object cache + name (IN) - the parameter's name + n_length (IN) - length (in bytes) of the 'name' parameter + elem (OUT) - If this function completes successfully, 'elem' points to + the selected parameter descriptor in the object cache. + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) if 'mdo' is not null, it must point to a valid method descriptor + in the object cache. + DESCRIPTION: + Get a parameter given its name. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is null. + OCI_ERROR if + 1) any of the required parameters is null. + 2) the method does not contain a parameter with the input 'name'. + NOTES: + The type must be unpinned when the accessed information is no + longer needed. + */ + +/*------------------------ OCITypeParamPos ---------------------------------*/ + +/* ** OBSOLETE ** */ +sword OCITypeParamPos( OCIEnv *env, OCIError *err, + const OCITypeMethod *mdo, + const oratext *name, ub4 n_length, ub4 *position, + OCITypeElem **elem ); +/* + NAME: OCITypeParamPos - OCI Get a parameter's position in a method + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + mdo (IN) - pointer to the method descriptor in the object cache + name (IN) - the parameter's name + n_length (IN) - length (in bytes) of the 'name' parameter + position (OUT) - If this function completes successfully, 'position' + points to the position of the parameter in the method starting + at position 1. position MUST point to space for a ub4. + elem (OUT) - If this function completes successfully, and + the input 'elem' is not NULL, 'elem' points to the selected + parameter descriptor in the object cache. + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) if 'mdo' is not null, it must point to a valid method descriptor + in the object cache. + DESCRIPTION: + Get the position of a parameter in a method. Positions start at 1. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is null. + OCI_ERROR if + 1) any of the parameters is null. + 2) the method does not contain a parameter with the input 'name'. + NOTES: + The type must be unpinned when the accessed information is no + longer needed. + */ + +/*------------------------ OCITypeParamElemMode -----------------------------*/ + +/* ** OBSOLETE ** */ +OCITypeParamMode OCITypeElemParamMode( OCIEnv *env, OCIError *err, + const OCITypeElem *elem ); +/* + NAME: OCITypeElemParamMode - OCI Get a parameter's mode + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + elem (IN) - pointer to the parameter descriptor in the object cache + (represented by an OCITypeElem) + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) All input parameters must not be NULL and must be valid. + DESCRIPTION: + Get the mode (in, out, or in/out) of the parameter. + RETURNS: + the mode (in, out, or in/out) of the parameter + NOTES: + The type must be unpinned when the accessed information is no + longer needed. + */ + +/*------------------------- OCITypeElemDefaultValue -------------------------*/ + +/* ** OBSOLETE ** */ +oratext* OCITypeElemDefaultValue( OCIEnv *env, OCIError *err, + const OCITypeElem *elem, + ub4 *d_v_length ); +/* + NAME: OCITypeElemDefaultValue - OCI Get the element's Default Value. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + elem (IN) - pointer to the parameter descriptor in the object cache + (represented by an OCITypeElem) + d_v_length (OUT) - length (in bytes) of the returned default value. + The caller must allocate space for the ub4 before calling this + routine. + REQUIRES: + 1) All type accessors require that the type be pinned before calling + any accessor. + 2) All input parameters must not be NULL and must be valid. + DESCRIPTION: + Get the default value in text form (PL/SQL) of an element. For V8.0, + this only makes sense for a method parameter. + RETURNS: + The default value (text) of the parameter. + NOTES: + The type must be unpinned when the accessed information is no + longer needed. + */ + + +/*--------------------------------------------------------------------------*/ +/* TYPE VERSION TABLE */ +/*--------------------------------------------------------------------------*/ + +/* For V8.0, the type version table is meant to be an internal data structure + only for Oracle clients for type version maintanence purposes. A more + general version of the API may be made public in subsequent releases. */ + + +/*--------------------------- OCITypeVTInit --------------------------------*/ + +/* ** OBSOLETE ** */ +sword OCITypeVTInit( OCIEnv *env, OCIError *err ); +/* + NAME: OCITypeVTInit - OCI type Version table INItialize + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + REQUIRES: + none + DESCRIPTION: + Allocate space for and initialize the type version table and the type + version table's index. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is null. + OCI_ERROR if internal errors occurrs during initialization. + */ + +/*--------------------------- OCITypeVTInsert -------------------------------*/ + +/* ** OBSOLETE ** */ +sword OCITypeVTInsert( OCIEnv *env, OCIError *err, + const oratext *schema_name, ub4 s_n_length, + const oratext *type_name, ub4 t_n_length, + const oratext *user_version, ub4 u_v_length ); +/* + NAME: OCITypeVTInsert - OCI type Version table INSert entry. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + schema_name (IN, optional) - name of schema associated with the + type. By default, the user's schema name is used. + s_n_length (IN) - length of the 'schema_name' parameter + type_name (IN) - type name to insert + t_n_length (IN) - length (in bytes) of the 'type_name' parameter + user_version (IN) - user readable version of the type + u_v_length (IN) - length (in bytes) of the 'user_version' parameter + REQUIRES: + none + DESCRIPTION: + Insert an entry into the type version table and the type version + table's index. The entry's type name and user readable version + fields are updated with the input values. All other fields are + initialized to null. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is null. + OCI_ERROR if + 1) any of the parameters is invalid. + 2) an entry for 'type_name' has already been registered in the + type version table. + */ + +/*------------------------------ OCITypeVTSelect ----------------------------*/ + +/* OCITypeVTSelect - OCI type VERSion table SELECT entry */ +/* ** OBSOLETE ** */ +sword OCITypeVTSelect( OCIEnv *env, OCIError *err, + const oratext *schema_name, ub4 s_n_length, + const oratext *type_name, ub4 t_n_length, + oratext **user_version, ub4 *u_v_length, + ub2 *version ); +/* + NAME: OCITypeVTSelect - OCI type Version table SELect entry. + PARAMETERS: + env (IN/OUT) - OCI environment handle initialized in object mode + err (IN/OUT) - error handle. If there is an error, it is + recorded in 'err' and this function returns OCI_ERROR. + The error recorded in 'err' can be retrieved by calling + OCIErrorGet(). + schema_name (IN, optional) - name of schema associated with the + type. By default, the user's schema name is used. + s_n_length (IN) - length of the 'schema_name' parameter + type_name (IN) - type name to select + t_n_length (IN) - length (in bytes) of the 'type_name' parameter + user_version (OUT, optional) - pointer to user readable version of the + type + u_v_length (OUT, optional) - length (in bytes) of the 'user_version' + parameter + version (OUT, optional) - internal type version + REQUIRES: + All input parameters must not be NULL and must be valid. + DESCRIPTION: + Select an entry in the type version table by name. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_INVALID_HANDLE if 'env' or 'err' is null. + OCI_ERROR if + 1) any of the parameters is invalid. + 2) an entry with 'type_name' does not exist. + */ + +/* Compatibility function - following function prototype retained for + compatibility only */ +sword ortgcty( OCIEnv *env, OCIError *err, OCIType *coll_tdo, + OCIType **collelem_tdo ); + +/*---------------------------------------------------------------------------*/ +/* Transient Type Construction functions */ +/*---------------------------------------------------------------------------*/ + +sword OCITypeBeginCreate(OCISvcCtx *svchp, OCIError *errhp, OCITypeCode tc, + OCIDuration dur, OCIType **type); +/* + NAME: OCITypeBeginCreate - OCI Type Begin Creation of a transient type. + REMARKS + Begins the construction process for a transient type. The type will be + anonymous (no name). To create a persistent named type, the CREATE TYPE + statement should be used from SQL. Transient types have no identity. + They are pure values. + PARAMETERS: + svchp (IN) - The OCI Service Context. + errhp (IN/OUT) - The OCI error handle. If there is an error, it is + recorded in errhp and this function returns + OCI_ERROR. Diagnostic information can be obtained by + calling OCIErrorGet(). + tc - The TypeCode for the type. The Typecode could + correspond to a User Defined Type or a Built-in type. + Currently, the permissible values for User Defined + Types are OCI_TYPECODE_OBJECT for an Object Type + (structured), OCI_TYPECODE_VARRAY for a VARRAY + collection type or OCI_TYPECODE_TABLE for a nested + table collection type. For Object types, + OCITypeAddAttr() needs to be called to add each of + the attribute types. For Collection types, + OCITypeSetCollection() needs to be called. + Subsequently, OCITypeEndCreate() needs to be called + to finish the creation process. + The permissible values for Built-in type codes are + specified in the user manual. Additional information + on built-ins if any (like precision, scale for + numbers, character set info for VARCHAR2s etc.) must + be set with a subsequent call to OCITypeSetBuiltin(). + Subsequently OCITypeEndCreate() needs to be called + to finish the creation process. + dur - The allocation duration for the Type. Could be a + predefined or a user defined duration. + type(OUT) - The OCIType (Type Descriptor) that is being + constructed. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_ERROR on error. +*/ + + +sword OCITypeSetCollection(OCISvcCtx *svchp, OCIError *errhp, OCIType *type, + OCIParam *collelem_info, ub4 coll_count); +/* + NAME: OCITypeSetCollection - OCI Type Set Collection information + REMARKS : + Set Collection type information. This call can be called only if the + OCIType has been constructed with a collection typecode. + PARAMETERS: + svchp (IN) - The OCI Service Context. + errhp (IN/OUT) - The OCI error handle. If there is an error, it is + recorded in errhp and this function returns + OCI_ERROR. Diagnostic information can be obtained by + calling OCIErrorGet(). + type(IN OUT) - The OCIType (Type Descriptor) that is being + constructed. + collelem_info - collelem_info provides information on the collection + element. It is obtained by allocating an OCIParam + (parameter handle) and setting type information in + the OCIParam using OCIAttrSet() calls. + coll_count - The count of elements in the collection. Pass 0 for + a nested table (unbounded). + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_ERROR on error. +*/ + +sword OCITypeSetBuiltin(OCISvcCtx *svchp, OCIError *errhp, OCIType *type, + OCIParam *builtin_info); +/* + NAME: OCITypeSetBuiltin - OCI Type Set Builtin information. + REMARKS: + Set Built-in type information. This call can be called only if the + OCIType has been constructed with a built-in typecode + (OCI_TYPECODE_NUMBER etc.). + PARAMETERS: + svchp (IN) - The OCI Service Context. + errhp (IN/OUT) - The OCI error handle. If there is an error, it is + recorded in errhp and this function returns + OCI_ERROR. Diagnostic information can be obtained by + calling OCIErrorGet(). + type(IN OUT) - The OCIType (Type Descriptor) that is being + constructed. + builtin_info - builtin_info provides information on the built-in + (like precision, scale, charater set etc.). It is + obtained by allocating an OCIParam (parameter handle) + and setting type information in the OCIParam using + OCIAttrSet() calls. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_ERROR on error. +*/ + +sword OCITypeAddAttr(OCISvcCtx *svchp, OCIError *errhp, OCIType *type, + const oratext *a_name, ub4 a_length, + OCIParam *attr_info); +/* + NAME: OCITypeAddAttr - OCI Type Add Attribute to an Object Type. + REMARKS: + Adds an attribute to an Object type (that was constructed earlier with + typecode OCI_TYPECODE_OBJECT). + PARAMETERS: + svchp (IN) - The OCI Service Context + errhp (IN/OUT) - The OCI error handle. If there is an error, it is + recorded in errhp and this function returns + OCI_ERROR. Diagnostic information can be obtained by + calling OCIErrorGet(). + type (IN/OUT) - The Type description that is being constructed. + a_name(IN) - Optional. gives the name of the attribute. + a_length - Optional. gives length of attribute name. + attr_info - Information on the attribute. It is obtained by + allocating an OCIParam (parameter handle) and setting + type information in the OCIParam using OCIAttrSet() + calls. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_ERROR on error. +*/ + +sword OCITypeEndCreate(OCISvcCtx *svchp, OCIError *errhp, OCIType *type); +/* + NAME: OCITypeEndCreate - OCI Type End Creation + REMARKS: + Finishes construction of a type description.Subsequently, only access + will be allowed. + PARAMETERS: + svchp (IN) - The OCI Service Context + errhp (IN/OUT) - The OCI error handle. If there is an error, it is + recorded in errhp and this function returns + OCI_ERROR. Diagnostic information can be obtained by + calling OCIErrorGet(). + type (IN/OUT) - The Type description that is being constructed. + RETURNS: + OCI_SUCCESS if the function completes successfully. + OCI_ERROR on error. +*/ + +/*=========================*/ +/* PUBLIC MACROS AND FLAGS */ +/*=========================*/ + +/*--------------------------------------------------------------------------*/ +/* TYPE ELEMENT FLAGS */ +/*--------------------------------------------------------------------------*/ + +#define OCI_TYPEELEM_REF 0x8000 /* element is a REF */ +#define OCI_TYPEPARAM_REQUIRED 0x0800 /* parameter is required */ + +/* macros to test flags */ +#define OCI_TYPEELEM_IS_REF(elem_flag) \ + (((elem_flag) & OCI_TYPEELEM_REF)!=0) +#define OCI_TYPEPARAM_IS_REQUIRED(param_flag) \ + (((param_flag) & OCI_TYPEPARAM_REQUIRED)!=0) + + +#endif /* ORT_ORACLE */ + diff --git a/libodbc/include/ora_linux/xa.h b/libodbc/include/ora_linux/xa.h new file mode 100644 index 0000000000..eb637e1c9b --- /dev/null +++ b/libodbc/include/ora_linux/xa.h @@ -0,0 +1,200 @@ +/* Copyright (c) 1992, 2006, Oracle. All rights reserved. */ + +/* + NAME + xa.h - + DESCRIPTION + + PUBLIC FUNCTION(S) + + PRIVATE FUNCTION(S) + + RETURNS + + NOTES + + + This is the public XA .h file + + MODIFIED (MM/DD/YY) + yohu 08/27/06 - XA/RAC project changes: XAER_AFFINITY + dmukhin 06/29/05 - ANSI prototypes; miscellaneous cleanup + whe 09/01/99 - 976457:check __cplusplus for C++ code + ntang 10/20/98 - Remove TMCACHE & TMFORCL + abhide 08/04/97 - implement xaoforcl + abhide 07/23/97 - XA OTS project changes + schandra 02/20/96 - lint + abhide 04/07/94 - merge changes from branch 1.1.710.1 + abhide 02/14/94 - Creation + abhide 02/10/94 - Creation + abhide 02/10/94 - Creation +*/ +/* + * xa.h header + * Typed in from X/Open doc of March 13, 1990 + * Updated to Parsippany II draft, March, 1991 + * Updated to Co Review draft, 19 Sep 1991 + */ + +#ifndef XA_H +#define XA_H + + +/* + * Transaction branch identification: XID and NULLXID: + */ + + +#define XIDDATASIZE 128 /* size in bytes */ +#define MAXGTRIDSIZE 64 /* maximum size in bytes of gtrid */ +#define MAXBQUALSIZE 64 /* maximum size in bytes of bqual */ +struct xid_t { + long formatID; /* format identifier */ + long gtrid_length; /* value from 1 through 64 */ + long bqual_length; /* value from 1 through 64 */ + char data[XIDDATASIZE]; +}; +typedef struct xid_t XID; + +/* + * A value of -1 in formatID means that the XID is null. + */ +/* + * Declarations of routines by which RMs call TMs: + */ + +int ax_reg(int, XID *, long); +int ax_unreg(int, long); +/* + * XA Switch Data Structure + */ +#define RMNAMESZ 32 /* length of resource manager name, */ + /* including the null terminator */ +#define MAXINFOSIZE 256 /* maximum size in bytes of xa_info strings, */ + /* including the null terminator */ +struct xa_switch_t { + char name[RMNAMESZ]; /* name of resource manager */ + long flags; /* resource manager specific options */ + long version; /* must be 0 */ + + int (*xa_open_entry)(char *, int, long); /*xa_open function pointer*/ + int (*xa_close_entry)(char *, int, long); /*xa_close function pointer*/ + int (*xa_start_entry)(XID *, int, long); /*xa_start function pointer*/ + int (*xa_end_entry)(XID *, int, long); /*xa_end function pointer*/ + int (*xa_rollback_entry)(XID *, int, long); + /*xa_rollback function pointer*/ + int (*xa_prepare_entry)(XID *, int, long); /*xa_prepare function pointer*/ + int (*xa_commit_entry)(XID *, int, long); /*xa_commit function pointer*/ + int (*xa_recover_entry)(XID *, long, int, long); + /*xa_recover function pointer*/ + int (*xa_forget_entry)(XID *, int, long); /*xa_forget function pointer*/ + int (*xa_complete_entry)(int *, int *, int, long); +}; + +/* + * Flag definition for the RM switch + */ +#define TMNOFLAGS 0x00000000L /* no resource manager features + selected */ +#define TMREGISTER 0x00000001L /* resource manager dynamically + registers */ +#define TMNOMIGRATE 0x00000002L /* resource manager does not support + association migration */ +#define TMUSEASYNC 0x00000004L /* resource manager supports + asynchronous operations */ +/* + * Flag definitions for xa_ and ax_ routines + */ +/* Use TMNOFLAGS, defined above, when not specifying other flags */ +#define TMASYNC 0x80000000L /* perform routine asynchronously */ +#define TMONEPHASE 0x40000000L /* caller is using one-phase commit + optimisation */ +#define TMFAIL 0x20000000L /* dissociates caller and marks + transaction branch rollback-only */ +#define TMNOWAIT 0x10000000L /* return if blocking condition + exists */ +#define TMRESUME 0x08000000L /* caller is resuming association + with suspended transaction branch */ +#define TMSUCCESS 0x04000000L /* dissociate caller from transaction + branch */ +#define TMSUSPEND 0x02000000L /* caller is suspending, not ending, + association */ +#define TMSTARTRSCAN 0x01000000L /* start a recovery scan */ +#define TMENDRSCAN 0x00800000L /* end a recovery scan */ +#define TMMULTIPLE 0x00400000L /* wait for any asynchronous + operation */ +#define TMJOIN 0x00200000L /* caller is joining existing + transaction branch */ +#define TMMIGRATE 0x00100000L /* caller intends to perform + migration */ + +/* + * ax_() return codes (transaction manager reports to resource manager) + */ +#define TM_JOIN 2 /* caller is joining existing transaction + branch */ +#define TM_RESUME 1 /* caller is resuming association with + suspended transaction branch */ +#define TM_OK 0 /* normal execution */ +#define TMER_TMERR -1 /* an error occurred in the transaction + manager */ +#define TMER_INVAL -2 /* invalid arguments were given */ +#define TMER_PROTO -3 /* routine invoked in an improper context */ + +/* + * xa_() return codes (resource manager reports to transaction manager) + */ +#define XA_RBBASE 100 /* The inclusive lower bound of the + rollback codes */ +#define XA_RBROLLBACK XA_RBBASE /* The rollback was caused by an + unspecified reason */ +#define XA_RBCOMMFAIL XA_RBBASE+1 /* The rollback was caused by a + communication failure */ +#define XA_RBDEADLOCK XA_RBBASE+2 /* A deadlock was detected */ +#define XA_RBINTEGRITY XA_RBBASE+3 /* A condition that violates the + integrity of the resources was + detected */ +#define XA_RBOTHER XA_RBBASE+4 /* The resource manager rolled back the + transaction for a reason not on this + list */ +#define XA_RBPROTO XA_RBBASE+5 /* A protocal error occurred in the + resource manager */ +#define XA_RBTIMEOUT XA_RBBASE+6 /* A transaction branch took too long*/ +#define XA_RBTRANSIENT XA_RBBASE+7 /* May retry the transaction branch */ +#define XA_RBEND XA_RBTRANSIENT /* The inclusive upper bound of the + rollback codes */ + +#define XA_NOMIGRATE 9 /* resumption must occur where + suspension occurred */ +#define XA_HEURHAZ 8 /* the transaction branch may have been + heuristically completed */ +#define XA_HEURCOM 7 /* the transaction branch has been + heuristically comitted */ +#define XA_HEURRB 6 /* the transaction branch has been + heuristically rolled back */ +#define XA_HEURMIX 5 /* the transaction branch has been + heuristically committed and rolled + back */ +#define XA_RETRY 4 /* routine returned with no effect + and may be re-issued */ +#define XA_RDONLY 3 /* the transaction was read-only + and has been committed */ +#define XA_OK 0 /* normal execution */ +#define XAER_ASYNC -2 /* asynchronous operation already + outstanding */ +#define XAER_RMERR -3 /* a resource manager error occurred + in the transaction branch */ +#define XAER_NOTA -4 /* the XID is not valid */ +#define XAER_INVAL -5 /* invalid arguments were given */ +#define XAER_PROTO -6 /* routine invoked in an improper + context */ +#define XAER_RMFAIL -7 /* resource manager unavailable */ +#define XAER_DUPID -8 /* the XID already exists */ +#define XAER_OUTSIDE -9 /* resource manager doing work */ + /* outside global transaction */ + +#define XAER_AFFINITY -10 /* XA on RAC: resumption must occur on + RAC instance where the transaction + branch was created */ + +#endif /* ifndef XA_H */ diff --git a/libodbc/include/pgAPI.h b/libodbc/include/pgAPI.h new file mode 100644 index 0000000000..c367f5a45f --- /dev/null +++ b/libodbc/include/pgAPI.h @@ -0,0 +1,287 @@ +// pgAPI.h +// +////////////////////////////////////////////////////////////////////// + +#if !defined(__PGAPI_H__) +#define __PGAPI_H__ + +#include "SQLAPI.h" + +// API header(s) +#include +#include + +extern void AddPostgreSQLSupport(const SAConnection *pCon); +extern void ReleasePostgreSQLSupport(); + +typedef PGconn* (*PQconnectStart_t)(const char *conninfo); +typedef PostgresPollingStatusType (*PQconnectPoll_t)(PGconn *conn); +typedef PGconn* (*PQconnectdb_t)(const char *conninfo); +typedef PGconn* (*PQsetdbLogin_t)(const char *pghost, const char *pgport, const char *pgoptions, const char *pgtty, + const char *dbName, + const char *login, const char *pwd); +typedef void (*PQfinish_t)(PGconn *conn); +typedef PQconninfoOption* (*PQconndefaults_t)(void); +typedef void (*PQconninfoFree_t)(PQconninfoOption *connOptions); +typedef int (*PQresetStart_t)(PGconn *conn); +typedef PostgresPollingStatusType (*PQresetPoll_t)(PGconn *conn); +typedef void (*PQreset_t)(PGconn *conn); +typedef int (*PQrequestCancel_t)(PGconn *conn); +typedef PGcancel* (*PQgetCancel_t)(PGconn *conn); +typedef void (*PQfreeCancel_t)(PGcancel *cancel); +typedef int (*PQcancel_t)(PGcancel *cancel, char *errbuf, int errbufsize); +typedef int (*PQserverVersion_t)(const PGconn *conn); +typedef char* (*PQdb_t)(const PGconn *conn); +typedef char* (*PQuser_t)(const PGconn *conn); +typedef char* (*PQpass_t)(const PGconn *conn); +typedef char* (*PQhost_t)(const PGconn *conn); +typedef char* (*PQport_t)(const PGconn *conn); +typedef char* (*PQtty_t)(const PGconn *conn); +typedef char* (*PQoptions_t)(const PGconn *conn); +typedef ConnStatusType (*PQstatus_t)(const PGconn *conn); +typedef char* (*PQerrorMessage_t)(const PGconn *conn); +typedef int (*PQsocket_t)(const PGconn *conn); +typedef int (*PQbackendPID_t)(const PGconn *conn); +typedef int (*PQclientEncoding_t)(const PGconn *conn); +typedef int (*PQsetClientEncoding_t)(PGconn *conn, const char *encoding); +#ifdef USE_SSL +typedef SSL* (*PQgetssl_t)(PGconn *conn); +#endif +typedef void (*PQtrace_t)(PGconn *conn, FILE *debug_port); +typedef void (*PQuntrace_t)(PGconn *conn); +typedef PQnoticeProcessor (*PQsetNoticeProcessor_t)(PGconn *conn, PQnoticeProcessor proc, void *arg); +typedef PGresult* (*PQexec_t)(PGconn *conn, const char *query); +typedef PGnotify* (*PQnotifies_t)(PGconn *conn); +typedef int (*PQsendQuery_t)(PGconn *conn, const char *query); +typedef PGresult* (*PQgetResult_t)(PGconn *conn); +typedef int (*PQisBusy_t)(PGconn *conn); +typedef int (*PQconsumeInput_t)(PGconn *conn); +typedef int (*PQgetline_t)(PGconn *conn, char *string, int length); +typedef int (*PQputline_t)(PGconn *conn, const char *string); +typedef int (*PQgetlineAsync_t)(PGconn *conn, char *buffer, int bufsize); +typedef int (*PQputnbytes_t)(PGconn *conn, const char *buffer, int nbytes); +typedef int (*PQendcopy_t)(PGconn *conn); +typedef int (*PQsetnonblocking_t)(PGconn *conn, int arg); +typedef int (*PQisnonblocking_t)(const PGconn *conn); +typedef int (*PQflush_t)(PGconn *conn); +typedef PGresult* (*PQfn_t)(PGconn *conn, int fnid, + int *result_buf, + int *result_len, + int result_is_int, + const PQArgBlock *args, + int nargs); +typedef ExecStatusType (*PQresultStatus_t)(const PGresult *res); +typedef char* (*PQresStatus_t)(ExecStatusType status); +typedef char* (*PQresultErrorMessage_t)(const PGresult *res); +typedef int (*PQntuples_t)(const PGresult *res); +typedef int (*PQnfields_t)(const PGresult *res); +typedef int (*PQbinaryTuples_t)(const PGresult *res); +typedef char* (*PQfname_t)(const PGresult *res, int field_num); +typedef int (*PQfnumber_t)(const PGresult *res, const char *field_name); +typedef int (*PQfformat_t)(const PGresult *res, int field_num); +typedef Oid (*PQftype_t)(const PGresult *res, int field_num); +typedef int (*PQfsize_t)(const PGresult *res, int field_num); +typedef int (*PQfmod_t)(const PGresult *res, int field_num); +typedef char* (*PQcmdStatus_t)(PGresult *res); +typedef char* (*PQoidStatus_t)(const PGresult *res); /* old and ugly */ +typedef Oid (*PQoidValue_t)(const PGresult *res); /* new and improved */ +typedef char* (*PQcmdTuples_t)(PGresult *res); +typedef char* (*PQgetvalue_t)(const PGresult *res, int tup_num, int field_num); +typedef int (*PQgetlength_t)(const PGresult *res, int tup_num, int field_num); +typedef int (*PQgetisnull_t)(const PGresult *res, int tup_num, int field_num); +typedef void (*PQclear_t)(PGresult *res); +typedef PGresult* (*PQmakeEmptyPGresult_t)(PGconn *conn, ExecStatusType status); +typedef void (*PQprint_t)(FILE *fout, /* output stream */ + const PGresult *res, + const PQprintOpt *ps); /* option structure */ +typedef void (*PQdisplayTuples_t)(const PGresult *res, + FILE *fp, /* where to send the + * output */ + int fillAlign, /* pad the fields with + * spaces */ + const char *fieldSep, /* field separator */ + int printHeader, /* display headers? */ + int quiet); +typedef void (*PQprintTuples_t)(const PGresult *res, + FILE *fout, /* output stream */ + int printAttName, /* print attribute names */ + int terseOutput, /* delimiter bars */ + int width); /* width of column, if + * 0, use variable width */ +typedef int (*lo_open_t)(PGconn *conn, Oid lobjId, int mode); +typedef int (*lo_close_t)(PGconn *conn, int fd); +typedef int (*lo_read_t)(PGconn *conn, int fd, char *buf, size_t len); +typedef int (*lo_write_t)(PGconn *conn, int fd, char *buf, size_t len); +typedef int (*lo_lseek_t)(PGconn *conn, int fd, int offset, int whence); +typedef Oid (*lo_creat_t)(PGconn *conn, int mode); +typedef int (*lo_tell_t)(PGconn *conn, int fd); +typedef int (*lo_unlink_t)(PGconn *conn, Oid lobjId); +typedef Oid (*lo_import_t)(PGconn *conn, const char *filename); +typedef int (*lo_export_t)(PGconn *conn, Oid lobjId, const char *filename); +typedef int (*PQmblen_t)(const unsigned char *s, int encoding); +typedef int (*PQenv2encoding_t)(void); + +// new +typedef PGVerbosity (*PQsetErrorVerbosity_t)(PGconn *conn, PGVerbosity verbosity); +typedef char* (*PQresultErrorField_t)(const PGresult *res, int fieldcode); + +// escape +typedef size_t (*PQescapeStringConn_t)(PGconn *conn, + char *to, const char *from, size_t length, + int *error); +typedef unsigned char* (*PQescapeByteaConn_t)(PGconn *conn, + const unsigned char *from, size_t from_length, + size_t *to_length); +typedef unsigned char* (*PQunescapeBytea_t)(const unsigned char *strtext, + size_t *retbuflen); + +/* These forms are deprecated! */ +typedef size_t (*PQescapeString_t)(char *to, const char *from, size_t length); +typedef char* (*PQescapeBytea_t)(const unsigned char *from, size_t from_length, + size_t *to_length); + +typedef void (*PQfreemem_t)(void *ptr); + +typedef int (*PQputCopyData_t)(PGconn *conn, const char *buffer, int nbytes); +typedef int (*PQputCopyEnd_t)(PGconn *conn, const char *errormsg); +typedef int (*PQgetCopyData_t)(PGconn *conn, char **buffer, int async); + +typedef PGPing (*PQping_t)(const char *conninfo); +typedef PGPing (*PQpingParams_t)(const char **keywords, + const char **values, int expand_dbname); + + +// API declarations +class SQLAPI_API pgAPI : public saAPI +{ +public: + pgAPI(); + + PQconnectStart_t PQconnectStart; + PQconnectPoll_t PQconnectPoll; + PQconnectdb_t PQconnectdb; + PQsetdbLogin_t PQsetdbLogin; + PQfinish_t PQfinish; + PQconndefaults_t PQconndefaults; + PQconninfoFree_t PQconninfoFree; + PQresetStart_t PQresetStart; + PQresetPoll_t PQresetPoll; + PQreset_t PQreset; + PQrequestCancel_t PQrequestCancel; + PQgetCancel_t PQgetCancel; + PQfreeCancel_t PQfreeCancel; + PQcancel_t PQcancel; + PQserverVersion_t PQserverVersion; + PQdb_t PQdb; + PQuser_t PQuser; + PQpass_t PQpass; + PQhost_t PQhost; + PQport_t PQport; + PQtty_t PQtty; + PQoptions_t PQoptions; + PQstatus_t PQstatus; + PQerrorMessage_t PQerrorMessage; + PQsocket_t PQsocket; + PQbackendPID_t PQbackendPID; + PQclientEncoding_t PQclientEncoding; + PQsetClientEncoding_t PQsetClientEncoding; +#ifdef USE_SSL + PQgetssl_t PQgetssl; +#endif + PQtrace_t PQtrace; + PQuntrace_t PQuntrace; + PQsetNoticeProcessor_t PQsetNoticeProcessor; + PQexec_t PQexec; + PQnotifies_t PQnotifies; + PQsendQuery_t PQsendQuery; + PQgetResult_t PQgetResult; + PQisBusy_t PQisBusy; + PQconsumeInput_t PQconsumeInput; + PQgetline_t PQgetline; + PQputline_t PQputline; + PQgetlineAsync_t PQgetlineAsync; + PQputnbytes_t PQputnbytes; + PQendcopy_t PQendcopy; + PQsetnonblocking_t PQsetnonblocking; + PQisnonblocking_t PQisnonblocking; + PQflush_t PQflush; + PQfn_t PQfn; + PQresultStatus_t PQresultStatus; + PQresStatus_t PQresStatus; + PQresultErrorMessage_t PQresultErrorMessage; + PQntuples_t PQntuples; + PQnfields_t PQnfields; + PQbinaryTuples_t PQbinaryTuples; + PQfname_t PQfname; + PQfnumber_t PQfnumber; + PQfformat_t PQfformat; + PQftype_t PQftype; + PQfsize_t PQfsize; + PQfmod_t PQfmod; + PQcmdStatus_t PQcmdStatus; + PQoidStatus_t PQoidStatus; + PQoidValue_t PQoidValue; + PQcmdTuples_t PQcmdTuples; + PQgetvalue_t PQgetvalue; + PQgetlength_t PQgetlength; + PQgetisnull_t PQgetisnull; + PQclear_t PQclear; + PQmakeEmptyPGresult_t PQmakeEmptyPGresult; + PQprint_t PQprint; + PQdisplayTuples_t PQdisplayTuples; + PQprintTuples_t PQprintTuples; + lo_open_t lo_open; + lo_close_t lo_close; + lo_read_t lo_read; + lo_write_t lo_write; + lo_lseek_t lo_lseek; + lo_creat_t lo_creat; + lo_tell_t lo_tell; + lo_unlink_t lo_unlink; + lo_import_t lo_import; + lo_export_t lo_export; + PQmblen_t PQmblen; + PQenv2encoding_t PQenv2encoding; + + // new 3.7.12 + PQsetErrorVerbosity_t PQsetErrorVerbosity; + PQresultErrorField_t PQresultErrorField; + + // escape + PQescapeStringConn_t PQescapeStringConn; + PQescapeByteaConn_t PQescapeByteaConn; + PQunescapeBytea_t PQunescapeBytea; + + // These forms are deprecated! + PQescapeString_t PQescapeString; + PQescapeBytea_t PQescapeBytea; + + PQfreemem_t PQfreemem; + + PQputCopyData_t PQputCopyData; + PQputCopyEnd_t PQputCopyEnd; + PQgetCopyData_t PQgetCopyData; + + PQping_t PQping; + PQpingParams_t PQpingParams; +}; + +class SQLAPI_API pgConnectionHandles : public saConnectionHandles +{ +public: + pgConnectionHandles(); + + PGconn *conn; // PostgreSQL connection struct +}; + +class SQLAPI_API pgCommandHandles : public saCommandHandles +{ +public: + pgCommandHandles(); + + PGresult *res; // PostgreSQL result struct +}; + +extern pgAPI g_pgAPI; + +#endif // !defined(__PGAPI_H__) diff --git a/libodbc/include/pgsql/libpq-fe.h b/libodbc/include/pgsql/libpq-fe.h new file mode 100644 index 0000000000..4ff464011a --- /dev/null +++ b/libodbc/include/pgsql/libpq-fe.h @@ -0,0 +1,576 @@ +/*------------------------------------------------------------------------- + * + * libpq-fe.h + * This file contains definitions for structures and + * externs for functions used by frontend postgres applications. + * + * Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/interfaces/libpq/libpq-fe.h + * + *------------------------------------------------------------------------- + */ + +#ifndef LIBPQ_FE_H +#define LIBPQ_FE_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include + +/* + * postgres_ext.h defines the backend's externally visible types, + * such as Oid. + */ +#include "postgres_ext.h" + +/* + * Option flags for PQcopyResult + */ +#define PG_COPYRES_ATTRS 0x01 +#define PG_COPYRES_TUPLES 0x02 /* Implies PG_COPYRES_ATTRS */ +#define PG_COPYRES_EVENTS 0x04 +#define PG_COPYRES_NOTICEHOOKS 0x08 + +/* Application-visible enum types */ + +typedef enum +{ + /* + * Although it is okay to add to this list, values which become unused + * should never be removed, nor should constants be redefined - that would + * break compatibility with existing code. + */ + CONNECTION_OK, + CONNECTION_BAD, + /* Non-blocking mode only below here */ + + /* + * The existence of these should never be relied upon - they should only + * be used for user feedback or similar purposes. + */ + CONNECTION_STARTED, /* Waiting for connection to be made. */ + CONNECTION_MADE, /* Connection OK; waiting to send. */ + CONNECTION_AWAITING_RESPONSE, /* Waiting for a response from the + * postmaster. */ + CONNECTION_AUTH_OK, /* Received authentication; waiting for + * backend startup. */ + CONNECTION_SETENV, /* Negotiating environment. */ + CONNECTION_SSL_STARTUP, /* Negotiating SSL. */ + CONNECTION_NEEDED /* Internal state: connect() needed */ +} ConnStatusType; + +typedef enum +{ + PGRES_POLLING_FAILED = 0, + PGRES_POLLING_READING, /* These two indicate that one may */ + PGRES_POLLING_WRITING, /* use select before polling again. */ + PGRES_POLLING_OK, + PGRES_POLLING_ACTIVE /* unused; keep for awhile for backwards + * compatibility */ +} PostgresPollingStatusType; + +typedef enum +{ + PGRES_EMPTY_QUERY = 0, /* empty query string was executed */ + PGRES_COMMAND_OK, /* a query command that doesn't return + * anything was executed properly by the + * backend */ + PGRES_TUPLES_OK, /* a query command that returns tuples was + * executed properly by the backend, PGresult + * contains the result tuples */ + PGRES_COPY_OUT, /* Copy Out data transfer in progress */ + PGRES_COPY_IN, /* Copy In data transfer in progress */ + PGRES_BAD_RESPONSE, /* an unexpected response was recv'd from the + * backend */ + PGRES_NONFATAL_ERROR, /* notice or warning message */ + PGRES_FATAL_ERROR, /* query failed */ + PGRES_COPY_BOTH /* Copy In/Out data transfer in progress */ +} ExecStatusType; + +typedef enum +{ + PQTRANS_IDLE, /* connection idle */ + PQTRANS_ACTIVE, /* command in progress */ + PQTRANS_INTRANS, /* idle, within transaction block */ + PQTRANS_INERROR, /* idle, within failed transaction */ + PQTRANS_UNKNOWN /* cannot determine status */ +} PGTransactionStatusType; + +typedef enum +{ + PQERRORS_TERSE, /* single-line error messages */ + PQERRORS_DEFAULT, /* recommended style */ + PQERRORS_VERBOSE /* all the facts, ma'am */ +} PGVerbosity; + +typedef enum +{ + PQPING_OK, /* server is accepting connections */ + PQPING_REJECT, /* server is alive but rejecting connections */ + PQPING_NO_RESPONSE, /* could not establish connection */ + PQPING_NO_ATTEMPT /* connection not attempted (bad params) */ +} PGPing; + +/* PGconn encapsulates a connection to the backend. + * The contents of this struct are not supposed to be known to applications. + */ +typedef struct pg_conn PGconn; + +/* PGresult encapsulates the result of a query (or more precisely, of a single + * SQL command --- a query string given to PQsendQuery can contain multiple + * commands and thus return multiple PGresult objects). + * The contents of this struct are not supposed to be known to applications. + */ +typedef struct pg_result PGresult; + +/* PGcancel encapsulates the information needed to cancel a running + * query on an existing connection. + * The contents of this struct are not supposed to be known to applications. + */ +typedef struct pg_cancel PGcancel; + +/* PGnotify represents the occurrence of a NOTIFY message. + * Ideally this would be an opaque typedef, but it's so simple that it's + * unlikely to change. + * NOTE: in Postgres 6.4 and later, the be_pid is the notifying backend's, + * whereas in earlier versions it was always your own backend's PID. + */ +typedef struct pgNotify +{ + char *relname; /* notification condition name */ + int be_pid; /* process ID of notifying server process */ + char *extra; /* notification parameter */ + /* Fields below here are private to libpq; apps should not use 'em */ + struct pgNotify *next; /* list link */ +} PGnotify; + +/* Function types for notice-handling callbacks */ +typedef void (*PQnoticeReceiver) (void *arg, const PGresult *res); +typedef void (*PQnoticeProcessor) (void *arg, const char *message); + +/* Print options for PQprint() */ +typedef char pqbool; + +typedef struct _PQprintOpt +{ + pqbool header; /* print output field headings and row count */ + pqbool align; /* fill align the fields */ + pqbool standard; /* old brain dead format */ + pqbool html3; /* output html tables */ + pqbool expanded; /* expand tables */ + pqbool pager; /* use pager for output if needed */ + char *fieldSep; /* field separator */ + char *tableOpt; /* insert to HTML */ + char *caption; /* HTML
*/ + char **fieldName; /* null terminated array of replacement field + * names */ +} PQprintOpt; + +/* ---------------- + * Structure for the conninfo parameter definitions returned by PQconndefaults + * or PQconninfoParse. + * + * All fields except "val" point at static strings which must not be altered. + * "val" is either NULL or a malloc'd current-value string. PQconninfoFree() + * will release both the val strings and the PQconninfoOption array itself. + * ---------------- + */ +typedef struct _PQconninfoOption +{ + char *keyword; /* The keyword of the option */ + char *envvar; /* Fallback environment variable name */ + char *compiled; /* Fallback compiled in default value */ + char *val; /* Option's current value, or NULL */ + char *label; /* Label for field in connect dialog */ + char *dispchar; /* Indicates how to display this field in a + * connect dialog. Values are: "" Display + * entered value as is "*" Password field - + * hide value "D" Debug option - don't show + * by default */ + int dispsize; /* Field size in characters for dialog */ +} PQconninfoOption; + +/* ---------------- + * PQArgBlock -- structure for PQfn() arguments + * ---------------- + */ +typedef struct +{ + int len; + int isint; + union + { + int *ptr; /* can't use void (dec compiler barfs) */ + int integer; + } u; +} PQArgBlock; + +/* ---------------- + * PGresAttDesc -- Data about a single attribute (column) of a query result + * ---------------- + */ +typedef struct pgresAttDesc +{ + char *name; /* column name */ + Oid tableid; /* source table, if known */ + int columnid; /* source column, if known */ + int format; /* format code for value (text/binary) */ + Oid typid; /* type id */ + int typlen; /* type size */ + int atttypmod; /* type-specific modifier info */ +} PGresAttDesc; + +/* ---------------- + * Exported functions of libpq + * ---------------- + */ + +/* === in fe-connect.c === */ + +/* make a new client connection to the backend */ +/* Asynchronous (non-blocking) */ +extern PGconn *PQconnectStart(const char *conninfo); +extern PGconn *PQconnectStartParams(const char **keywords, + const char **values, int expand_dbname); +extern PostgresPollingStatusType PQconnectPoll(PGconn *conn); + +/* Synchronous (blocking) */ +extern PGconn *PQconnectdb(const char *conninfo); +extern PGconn *PQconnectdbParams(const char **keywords, + const char **values, int expand_dbname); +extern PGconn *PQsetdbLogin(const char *pghost, const char *pgport, + const char *pgoptions, const char *pgtty, + const char *dbName, + const char *login, const char *pwd); + +#define PQsetdb(M_PGHOST,M_PGPORT,M_PGOPT,M_PGTTY,M_DBNAME) \ + PQsetdbLogin(M_PGHOST, M_PGPORT, M_PGOPT, M_PGTTY, M_DBNAME, NULL, NULL) + +/* close the current connection and free the PGconn data structure */ +extern void PQfinish(PGconn *conn); + +/* get info about connection options known to PQconnectdb */ +extern PQconninfoOption *PQconndefaults(void); + +/* parse connection options in same way as PQconnectdb */ +extern PQconninfoOption *PQconninfoParse(const char *conninfo, char **errmsg); + +/* free the data structure returned by PQconndefaults() or PQconninfoParse() */ +extern void PQconninfoFree(PQconninfoOption *connOptions); + +/* + * close the current connection and restablish a new one with the same + * parameters + */ +/* Asynchronous (non-blocking) */ +extern int PQresetStart(PGconn *conn); +extern PostgresPollingStatusType PQresetPoll(PGconn *conn); + +/* Synchronous (blocking) */ +extern void PQreset(PGconn *conn); + +/* request a cancel structure */ +extern PGcancel *PQgetCancel(PGconn *conn); + +/* free a cancel structure */ +extern void PQfreeCancel(PGcancel *cancel); + +/* issue a cancel request */ +extern int PQcancel(PGcancel *cancel, char *errbuf, int errbufsize); + +/* backwards compatible version of PQcancel; not thread-safe */ +extern int PQrequestCancel(PGconn *conn); + +/* Accessor functions for PGconn objects */ +extern char *PQdb(const PGconn *conn); +extern char *PQuser(const PGconn *conn); +extern char *PQpass(const PGconn *conn); +extern char *PQhost(const PGconn *conn); +extern char *PQport(const PGconn *conn); +extern char *PQtty(const PGconn *conn); +extern char *PQoptions(const PGconn *conn); +extern ConnStatusType PQstatus(const PGconn *conn); +extern PGTransactionStatusType PQtransactionStatus(const PGconn *conn); +extern const char *PQparameterStatus(const PGconn *conn, + const char *paramName); +extern int PQprotocolVersion(const PGconn *conn); +extern int PQserverVersion(const PGconn *conn); +extern char *PQerrorMessage(const PGconn *conn); +extern int PQsocket(const PGconn *conn); +extern int PQbackendPID(const PGconn *conn); +extern int PQconnectionNeedsPassword(const PGconn *conn); +extern int PQconnectionUsedPassword(const PGconn *conn); +extern int PQclientEncoding(const PGconn *conn); +extern int PQsetClientEncoding(PGconn *conn, const char *encoding); + +/* Get the OpenSSL structure associated with a connection. Returns NULL for + * unencrypted connections or if any other TLS library is in use. */ +extern void *PQgetssl(PGconn *conn); + +/* Tell libpq whether it needs to initialize OpenSSL */ +extern void PQinitSSL(int do_init); + +/* More detailed way to tell libpq whether it needs to initialize OpenSSL */ +extern void PQinitOpenSSL(int do_ssl, int do_crypto); + +/* Set verbosity for PQerrorMessage and PQresultErrorMessage */ +extern PGVerbosity PQsetErrorVerbosity(PGconn *conn, PGVerbosity verbosity); + +/* Enable/disable tracing */ +extern void PQtrace(PGconn *conn, FILE *debug_port); +extern void PQuntrace(PGconn *conn); + +/* Override default notice handling routines */ +extern PQnoticeReceiver PQsetNoticeReceiver(PGconn *conn, + PQnoticeReceiver proc, + void *arg); +extern PQnoticeProcessor PQsetNoticeProcessor(PGconn *conn, + PQnoticeProcessor proc, + void *arg); + +/* + * Used to set callback that prevents concurrent access to + * non-thread safe functions that libpq needs. + * The default implementation uses a libpq internal mutex. + * Only required for multithreaded apps that use kerberos + * both within their app and for postgresql connections. + */ +typedef void (*pgthreadlock_t) (int acquire); + +extern pgthreadlock_t PQregisterThreadLock(pgthreadlock_t newhandler); + +/* === in fe-exec.c === */ + +/* Simple synchronous query */ +extern PGresult *PQexec(PGconn *conn, const char *query); +extern PGresult *PQexecParams(PGconn *conn, + const char *command, + int nParams, + const Oid *paramTypes, + const char *const * paramValues, + const int *paramLengths, + const int *paramFormats, + int resultFormat); +extern PGresult *PQprepare(PGconn *conn, const char *stmtName, + const char *query, int nParams, + const Oid *paramTypes); +extern PGresult *PQexecPrepared(PGconn *conn, + const char *stmtName, + int nParams, + const char *const * paramValues, + const int *paramLengths, + const int *paramFormats, + int resultFormat); + +/* Interface for multiple-result or asynchronous queries */ +extern int PQsendQuery(PGconn *conn, const char *query); +extern int PQsendQueryParams(PGconn *conn, + const char *command, + int nParams, + const Oid *paramTypes, + const char *const * paramValues, + const int *paramLengths, + const int *paramFormats, + int resultFormat); +extern int PQsendPrepare(PGconn *conn, const char *stmtName, + const char *query, int nParams, + const Oid *paramTypes); +extern int PQsendQueryPrepared(PGconn *conn, + const char *stmtName, + int nParams, + const char *const * paramValues, + const int *paramLengths, + const int *paramFormats, + int resultFormat); +extern PGresult *PQgetResult(PGconn *conn); + +/* Routines for managing an asynchronous query */ +extern int PQisBusy(PGconn *conn); +extern int PQconsumeInput(PGconn *conn); + +/* LISTEN/NOTIFY support */ +extern PGnotify *PQnotifies(PGconn *conn); + +/* Routines for copy in/out */ +extern int PQputCopyData(PGconn *conn, const char *buffer, int nbytes); +extern int PQputCopyEnd(PGconn *conn, const char *errormsg); +extern int PQgetCopyData(PGconn *conn, char **buffer, int async); + +/* Deprecated routines for copy in/out */ +extern int PQgetline(PGconn *conn, char *string, int length); +extern int PQputline(PGconn *conn, const char *string); +extern int PQgetlineAsync(PGconn *conn, char *buffer, int bufsize); +extern int PQputnbytes(PGconn *conn, const char *buffer, int nbytes); +extern int PQendcopy(PGconn *conn); + +/* Set blocking/nonblocking connection to the backend */ +extern int PQsetnonblocking(PGconn *conn, int arg); +extern int PQisnonblocking(const PGconn *conn); +extern int PQisthreadsafe(void); +extern PGPing PQping(const char *conninfo); +extern PGPing PQpingParams(const char **keywords, + const char **values, int expand_dbname); + +/* Force the write buffer to be written (or at least try) */ +extern int PQflush(PGconn *conn); + +/* + * "Fast path" interface --- not really recommended for application + * use + */ +extern PGresult *PQfn(PGconn *conn, + int fnid, + int *result_buf, + int *result_len, + int result_is_int, + const PQArgBlock *args, + int nargs); + +/* Accessor functions for PGresult objects */ +extern ExecStatusType PQresultStatus(const PGresult *res); +extern char *PQresStatus(ExecStatusType status); +extern char *PQresultErrorMessage(const PGresult *res); +extern char *PQresultErrorField(const PGresult *res, int fieldcode); +extern int PQntuples(const PGresult *res); +extern int PQnfields(const PGresult *res); +extern int PQbinaryTuples(const PGresult *res); +extern char *PQfname(const PGresult *res, int field_num); +extern int PQfnumber(const PGresult *res, const char *field_name); +extern Oid PQftable(const PGresult *res, int field_num); +extern int PQftablecol(const PGresult *res, int field_num); +extern int PQfformat(const PGresult *res, int field_num); +extern Oid PQftype(const PGresult *res, int field_num); +extern int PQfsize(const PGresult *res, int field_num); +extern int PQfmod(const PGresult *res, int field_num); +extern char *PQcmdStatus(PGresult *res); +extern char *PQoidStatus(const PGresult *res); /* old and ugly */ +extern Oid PQoidValue(const PGresult *res); /* new and improved */ +extern char *PQcmdTuples(PGresult *res); +extern char *PQgetvalue(const PGresult *res, int tup_num, int field_num); +extern int PQgetlength(const PGresult *res, int tup_num, int field_num); +extern int PQgetisnull(const PGresult *res, int tup_num, int field_num); +extern int PQnparams(const PGresult *res); +extern Oid PQparamtype(const PGresult *res, int param_num); + +/* Describe prepared statements and portals */ +extern PGresult *PQdescribePrepared(PGconn *conn, const char *stmt); +extern PGresult *PQdescribePortal(PGconn *conn, const char *portal); +extern int PQsendDescribePrepared(PGconn *conn, const char *stmt); +extern int PQsendDescribePortal(PGconn *conn, const char *portal); + +/* Delete a PGresult */ +extern void PQclear(PGresult *res); + +/* For freeing other alloc'd results, such as PGnotify structs */ +extern void PQfreemem(void *ptr); + +/* Exists for backward compatibility. bjm 2003-03-24 */ +#define PQfreeNotify(ptr) PQfreemem(ptr) + +/* Error when no password was given. */ +/* Note: depending on this is deprecated; use PQconnectionNeedsPassword(). */ +#define PQnoPasswordSupplied "fe_sendauth: no password supplied\n" + +/* Create and manipulate PGresults */ +extern PGresult *PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status); +extern PGresult *PQcopyResult(const PGresult *src, int flags); +extern int PQsetResultAttrs(PGresult *res, int numAttributes, PGresAttDesc *attDescs); +extern void *PQresultAlloc(PGresult *res, size_t nBytes); +extern int PQsetvalue(PGresult *res, int tup_num, int field_num, char *value, int len); + +/* Quoting strings before inclusion in queries. */ +extern size_t PQescapeStringConn(PGconn *conn, + char *to, const char *from, size_t length, + int *error); +extern char *PQescapeLiteral(PGconn *conn, const char *str, size_t len); +extern char *PQescapeIdentifier(PGconn *conn, const char *str, size_t len); +extern unsigned char *PQescapeByteaConn(PGconn *conn, + const unsigned char *from, size_t from_length, + size_t *to_length); +extern unsigned char *PQunescapeBytea(const unsigned char *strtext, + size_t *retbuflen); + +/* These forms are deprecated! */ +extern size_t PQescapeString(char *to, const char *from, size_t length); +extern unsigned char *PQescapeBytea(const unsigned char *from, size_t from_length, + size_t *to_length); + + + +/* === in fe-print.c === */ + +extern void +PQprint(FILE *fout, /* output stream */ + const PGresult *res, + const PQprintOpt *ps); /* option structure */ + +/* + * really old printing routines + */ +extern void +PQdisplayTuples(const PGresult *res, + FILE *fp, /* where to send the output */ + int fillAlign, /* pad the fields with spaces */ + const char *fieldSep, /* field separator */ + int printHeader, /* display headers? */ + int quiet); + +extern void +PQprintTuples(const PGresult *res, + FILE *fout, /* output stream */ + int printAttName, /* print attribute names */ + int terseOutput, /* delimiter bars */ + int width); /* width of column, if 0, use variable width */ + + +/* === in fe-lobj.c === */ + +/* Large-object access routines */ +extern int lo_open(PGconn *conn, Oid lobjId, int mode); +extern int lo_close(PGconn *conn, int fd); +extern int lo_read(PGconn *conn, int fd, char *buf, size_t len); +extern int lo_write(PGconn *conn, int fd, const char *buf, size_t len); +extern int lo_lseek(PGconn *conn, int fd, int offset, int whence); +extern Oid lo_creat(PGconn *conn, int mode); +extern Oid lo_create(PGconn *conn, Oid lobjId); +extern int lo_tell(PGconn *conn, int fd); +extern int lo_truncate(PGconn *conn, int fd, size_t len); +extern int lo_unlink(PGconn *conn, Oid lobjId); +extern Oid lo_import(PGconn *conn, const char *filename); +extern Oid lo_import_with_oid(PGconn *conn, const char *filename, Oid lobjId); +extern int lo_export(PGconn *conn, Oid lobjId, const char *filename); + +/* === in fe-misc.c === */ + +/* Get the version of the libpq library in use */ +extern int PQlibVersion(void); + +/* Determine length of multibyte encoded char at *s */ +extern int PQmblen(const char *s, int encoding); + +/* Determine display length of multibyte encoded char at *s */ +extern int PQdsplen(const char *s, int encoding); + +/* Get encoding id from environment variable PGCLIENTENCODING */ +extern int PQenv2encoding(void); + +/* === in fe-auth.c === */ + +extern char *PQencryptPassword(const char *passwd, const char *user); + +/* === in encnames.c === */ + +extern int pg_char_to_encoding(const char *name); +extern const char *pg_encoding_to_char(int encoding); +extern int pg_valid_server_encoding_id(int encoding); + +#ifdef __cplusplus +} +#endif + +#endif /* LIBPQ_FE_H */ diff --git a/libodbc/include/pgsql/libpq-fs.h b/libodbc/include/pgsql/libpq-fs.h new file mode 100644 index 0000000000..f07ab91b76 --- /dev/null +++ b/libodbc/include/pgsql/libpq-fs.h @@ -0,0 +1,24 @@ +/*------------------------------------------------------------------------- + * + * libpq-fs.h + * definitions for using Inversion file system routines (ie, large objects) + * + * + * Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/libpq/libpq-fs.h + * + *------------------------------------------------------------------------- + */ +#ifndef LIBPQ_FS_H +#define LIBPQ_FS_H + +/* + * Read/write mode flags for inversion (large object) calls + */ + +#define INV_WRITE 0x00020000 +#define INV_READ 0x00040000 + +#endif /* LIBPQ_FS_H */ diff --git a/libodbc/include/pgsql/postgres_ext.h b/libodbc/include/pgsql/postgres_ext.h new file mode 100644 index 0000000000..d53a3aed98 --- /dev/null +++ b/libodbc/include/pgsql/postgres_ext.h @@ -0,0 +1,59 @@ +/*------------------------------------------------------------------------- + * + * postgres_ext.h + * + * This file contains declarations of things that are visible everywhere + * in PostgreSQL *and* are visible to clients of frontend interface libraries. + * For example, the Oid type is part of the API of libpq and other libraries. + * + * Declarations which are specific to a particular interface should + * go in the header file for that interface (such as libpq-fe.h). This + * file is only for fundamental Postgres declarations. + * + * User-written C functions don't count as "external to Postgres." + * Those function much as local modifications to the backend itself, and + * use header files that are otherwise internal to Postgres to interface + * with the backend. + * + * src/include/postgres_ext.h + * + *------------------------------------------------------------------------- + */ + +#ifndef POSTGRES_EXT_H +#define POSTGRES_EXT_H + +/* + * Object ID is a fundamental type in Postgres. + */ +typedef unsigned int Oid; + +#ifdef __cplusplus +#define InvalidOid (Oid(0)) +#else +#define InvalidOid ((Oid) 0) +#endif + +#define OID_MAX UINT_MAX +/* you will need to include to use the above #define */ + + +/* + * Identifiers of error message fields. Kept here to keep common + * between frontend and backend, and also to export them to libpq + * applications. + */ +#define PG_DIAG_SEVERITY 'S' +#define PG_DIAG_SQLSTATE 'C' +#define PG_DIAG_MESSAGE_PRIMARY 'M' +#define PG_DIAG_MESSAGE_DETAIL 'D' +#define PG_DIAG_MESSAGE_HINT 'H' +#define PG_DIAG_STATEMENT_POSITION 'P' +#define PG_DIAG_INTERNAL_POSITION 'p' +#define PG_DIAG_INTERNAL_QUERY 'q' +#define PG_DIAG_CONTEXT 'W' +#define PG_DIAG_SOURCE_FILE 'F' +#define PG_DIAG_SOURCE_LINE 'L' +#define PG_DIAG_SOURCE_FUNCTION 'R' + +#endif diff --git a/libodbc/include/samisc.h b/libodbc/include/samisc.h new file mode 100644 index 0000000000..f2937e7523 --- /dev/null +++ b/libodbc/include/samisc.h @@ -0,0 +1,144 @@ +// samisc.h +// +////////////////////////////////////////////////////////////////////// + +#if !defined(__SAMISC_H__) +#define __SAMISC_H__ + +#define sa_min(x, y) ((x) < (y)? (x) : (y)) +#define sa_max(x, y) ((x) > (y)? (x) : (y)) + +#if defined(SA_UNICODE) +#define sa_strcpy(x, y) wcscpy(x, y) +#define sa_strlen(x) wcslen(x) +#define sa_strstr(x, y) wcsstr(x, y) +#define sa_strchr(x, y) wcschr(x, y) +#define sa_isspace(x) iswspace(x) +#define sa_isdigit(x) iswdigit(x) +#define sa_isalpha(x) iswalpha(x) +#define sa_strcmp(x, y) wcscmp(x, y) +#define sa_strncmp(x, y, z) wcsncmp(x, y, z) +#define sa_tolower(x) towlower(x) +#define sa_toupper(x) towupper(x) +#define sa_strcoll(x, y) wcscoll(x, y) +#define sa_strpbrk(x, y) wcspbrk(x, y) +#define sa_strrchr(x, y) wcsrchr(x, y) +#define sa_strtol(x, y, z) wcstol(x, y, z) +#define sa_strtoul(x, y, z) wcstoul(x, y, z) +#define sa_strtod(x, y) wcstod(x, y) +#define sa_toi(x) (int)wcstol(x, NULL, 10) +#define sa_tol(x) wcstol(x, NULL, 10) +#define sa_sscanf swscanf +#define sa_printf wprintf +#define sa_scanf wscanf +#define sa_getchar getwchar +#ifdef SQLAPI_WINDOWS +#define sa_snprintf _snwprintf +#define sa_vsnprintf(x, y, z, j) _vsnwprintf(x, y, z, j) +#define sa_stricmp(x, y) _wcsicmp(x, y) +#else +#define sa_vsnprintf(x, y, z, j) vswprintf(x, y, z, j) +#define sa_snprintf swprintf +#define sa_stricmp(x, y) wcscasecmp(x, y) +#endif // ! SQLAPI_WINDOWS +#define sa_csinc(x) (++(x)) +#define sa_clen(x) (1) +#else +#define sa_strcpy(x, y) strcpy(x, y) +#define sa_strlen(x) strlen(x) +#define sa_strstr(x, y) strstr(x, y) +#define sa_strchr(x, y) strchr(x, y) +#define sa_isspace(x) isspace((unsigned char)x) +#define sa_isdigit(x) isdigit((unsigned char)x) +#define sa_isalpha(x) isalpha((unsigned char)x) +#define sa_strcmp(x, y) strcmp(x, y) +#define sa_strncmp(x, y, z) strncmp(x, y, z) +#define sa_tolower(x) tolower((unsigned char)x) +#define sa_toupper(x) toupper((unsigned char)x) +#define sa_strcoll(x, y) strcoll(x, y) +#define sa_strpbrk(x, y) strpbrk(x, y) +#define sa_strrchr(x, y) strrchr(x, y) +#define sa_strtol(x, y, z) strtol(x, y, z) +#define sa_strtoul(x, y, z) strtoul(x, y, z) +#define sa_strtod(x, y) strtod(x, y) +#define sa_toi(x) atoi(x) +#define sa_tol(x) atol(x) +#define sa_sscanf sscanf +#define sa_printf printf +#define sa_scanf scanf +#define sa_getchar getchar +#ifdef SQLAPI_WINDOWS +#if defined(__BORLANDC__) && (__BORLANDC__ <= 0x0520) +#define sa_vsnprintf(x, y, z, j) vsprintf(x, z, j) +#else +#define sa_vsnprintf(x, y, z, j) _vsnprintf(x, y, z, j) +#endif +#define sa_snprintf _snprintf +#define sa_stricmp(x, y) _stricmp(x, y) +#else +#define sa_vsnprintf(x, y, z, j) vsnprintf(x, y, z, j) +#define sa_snprintf snprintf +#define sa_stricmp(x, y) strcasecmp(x, y) +#endif // ! SQLAPI_WINDOWS +#define sa_csinc(x) (++(x)) +#define sa_clen(x) (1) +#endif + +#ifdef SQLAPI_WINDOWS +#ifdef __BORLANDC__ +#define _strnicmp strnicmp +#define _stricmp stricmp +#endif +#elif SQLAPI_SCOOSR5 +#define _strnicmp strnicmp +#define _stricmp stricmp +#else +#define _strnicmp strncasecmp +#define _stricmp strcasecmp +#endif // defined(SQLAPI_WINDOWS) + +#ifdef SQLAPI_WINDOWS +#include +#else +#if defined(SA_USE_PTHREAD) +#include +#endif // defined(SA_USE_PTHREAD) +#endif + +class SQLAPI_API SAMutex +{ +#ifdef SQLAPI_WINDOWS +#ifdef SA_USE_MUTEXT_LOCK + HANDLE m_hMutex; +#else + CRITICAL_SECTION m_hCriticalSection; +#endif +#endif // defined(SQLAPI_WINDOWS) + +#if defined(SA_USE_PTHREAD) + pthread_mutex_t m_mutex; // mutex + // we need additional machinery + // to allow portable recursion + int m_locks; // number of times owner locked mutex + pthread_t m_owner_thread; //owner of mutex + pthread_mutex_t m_helper_mutex; // structure access lock +#endif // defined(SA_USE_PTHREAD) + +public: + SAMutex(); + virtual ~SAMutex(); + + void Wait(); + void Release(); +}; + +class SQLAPI_API SACriticalSectionScope +{ + SAMutex *m_pSAMutex; + +public: + SACriticalSectionScope(SAMutex *pSAMutex); + virtual ~SACriticalSectionScope(); +}; + +#endif // !defined(__SAMISC_H__) diff --git a/libodbc/include/sbAPI.h b/libodbc/include/sbAPI.h new file mode 100644 index 0000000000..d884911996 --- /dev/null +++ b/libodbc/include/sbAPI.h @@ -0,0 +1,514 @@ +// sbAPI.h +// +////////////////////////////////////////////////////////////////////// + +#if !defined(__SB7API_H__) +#define __SB7API_H__ + +#include "SQLAPI.h" + +// API header(s) +#define SQL_32BITTARG 1 +#include + +extern long g_nSBDLLVersionLoaded; + +extern void AddSB6Support(const SAConnection * pCon); +extern void ReleaseSB6Support(); +extern bool CanBeLoadedSB7(const SAConnection * pCon); +extern void AddSB7Support(const SAConnection * pCon); +extern void ReleaseSB7Support(); + +typedef byte2 (SBSTDCALL *sqlarf_t)(SQLTCUR cur , SQLTFNP fnp , + SQLTFNL fnl , SQLTCHO cho ); +typedef byte2 (SBSTDCALL *sqlbbr_t)(SQLTCUR cur , SQLTXER PTR errnum , + SQLTDAP errbuf , SQLTDAL PTR buflen , + SQLTBIR PTR errrow , SQLTRBF PTR rbf , + SQLTBIR errseq ); +typedef byte2 (SBSTDCALL *sqlbdb_t)(SQLTSVH shandle , SQLTDAP dbname , + SQLTDAL dbnamel , SQLTFNP bkpdir , + SQLTFNL bkpdirl , SQLTBOO local , + SQLTBOO over ); +typedef byte2 (SBSTDCALL *sqlbef_t)(SQLTCUR cur ); +typedef byte2 (SBSTDCALL *sqlber_t)(SQLTCUR cur , SQLTRCD PTR rcd , + SQLTBIR PTR errrow , SQLTRBF PTR rbf , + SQLTBIR errseq ); +typedef byte2 (SBSTDCALL *sqlbkp_t)(SQLTCUR cur , SQLTBOO defalt , + SQLTBOO overwrt , SQLTFNP bkfname , + SQLTFNL bkfnlen ); +typedef byte2 (SBSTDCALL *sqlbld_t)(SQLTCUR cur , SQLTBNP bnp , + SQLTBNL bnl ); +typedef byte2 (SBSTDCALL *sqlblf_t)(SQLTSVH shandle , SQLTDAP dbname , + SQLTDAL dbnamel , SQLTFNP bkpdir , + SQLTFNL bkpdirl , SQLTBOO local , + SQLTBOO over ); +typedef byte2 (SBSTDCALL *sqlblk_t)(SQLTCUR cur , SQLTFLG blkflg ); +typedef byte2 (SBSTDCALL *sqlbln_t)(SQLTCUR cur , SQLTBNN bnn ); +typedef byte2 (SBSTDCALL *sqlbna_t)(SQLTCUR cur , SQLTBNP bnp , + SQLTBNL bnl , SQLTDAP dap , + SQLTDAL dal , SQLTSCA sca , + SQLTPDT pdt , SQLTNUL nli ); +typedef byte2 (SBSTDCALL *sqlbnd_t)(SQLTCUR cur , SQLTBNP bnp , + SQLTBNL bnl , SQLTDAP dap , + SQLTDAL dal , SQLTSCA sca , + SQLTPDT pdt ); +typedef byte2 (SBSTDCALL *sqlbnn_t)(SQLTCUR cur , SQLTBNN bnn , + SQLTDAP dap , SQLTDAL dal , + SQLTSCA sca , SQLTPDT pdt ); +typedef byte2 (SBSTDCALL *sqlbnu_t)(SQLTCUR cur , SQLTBNN bnn , + SQLTDAP dap , SQLTDAL dal , + SQLTSCA sca , SQLTPDT pdt , + SQLTNUL nli ); +typedef byte2 (SBSTDCALL *sqlbss_t)(SQLTSVH shandle , SQLTDAP dbname , + SQLTDAL dbnamel , SQLTFNP bkpdir , + SQLTFNL bkpdirl , SQLTBOO local , + SQLTBOO over ); +typedef byte2 (SBSTDCALL *sqlcan_t)(SQLTCUR cur ); +typedef byte2 (SBSTDCALL *sqlcbv_t)(SQLTCUR cur ); +typedef byte2 (SBSTDCALL *sqlcdr_t)(SQLTSVH shandle, SQLTCUR cur ); +typedef byte2 (SBSTDCALL *sqlcex_t)(SQLTCUR cur , SQLTDAP dap , + SQLTDAL dal ); +typedef byte2 (SBSTDCALL *sqlclf_t)(SQLTSVH cur , SQLTDAP logfile , + SQLTFMD startflag); +typedef byte2 (SBSTDCALL *sqlcmt_t)(SQLTCUR cur ); +typedef byte2 (SBSTDCALL *sqlcnc_t)(SQLTCUR PTR curp , SQLTDAP dbnamp , + SQLTDAL dbnaml ); +typedef byte2 (SBSTDCALL *sqlcnr_t)(SQLTCUR PTR curp , SQLTDAP dbnamp , + SQLTDAL dbnaml ); +typedef byte2 (SBSTDCALL *sqlcom_t)(SQLTCUR cur , SQLTDAP cmdp , + SQLTDAL cmdl ); +typedef byte2 (SBSTDCALL *sqlcon_t)(SQLTCUR PTR curp , SQLTDAP dbnamp , + SQLTDAL dbnaml , SQLTWSI cursiz , + SQLTNPG pages , SQLTRCF recovr , + SQLTDAL outsize , SQLTDAL insize ); +typedef byte2 (SBSTDCALL *sqlcpy_t)(SQLTCUR fcur , SQLTDAP selp , + SQLTDAL sell , SQLTCUR tcur , + SQLTDAP isrtp , SQLTDAL isrtl ); +typedef byte2 (SBSTDCALL *sqlcre_t)(SQLTSVH shandle , SQLTDAP dbnamp , + SQLTDAL dbnaml ); +typedef byte2 (SBSTDCALL *sqlcrf_t)(SQLTSVH shandle , SQLTDAP dbname , + SQLTDAL dbnamel ); +typedef byte2 (SBSTDCALL *sqlcrs_t)(SQLTCUR cur , SQLTDAP rsp , + SQLTDAL rsl ); +typedef byte2 (SBSTDCALL *sqlcsv_t)(SQLTSVH PTR shandlep, SQLTDAP serverid, + SQLTDAP password); +typedef byte2 (SBSTDCALL *sqlcty_t)(SQLTCUR cur , SQLTCTY PTR cty ); +typedef byte2 (SBSTDCALL *sqldbn_t)(SQLTDAP serverid, SQLTDAP buffer , + SQLTDAL length ); +typedef byte2 (SBSTDCALL *sqlded_t)(SQLTSVH shandle , SQLTDAP dbnamp , + SQLTDAL dbnaml ); +typedef byte2 (SBSTDCALL *sqldel_t)(SQLTSVH shandle , SQLTDAP dbnamp , + SQLTDAL dbnaml ); +typedef byte2 (SBSTDCALL *sqldes_t)(SQLTCUR cur , SQLTSLC slc , + SQLTDDT PTR ddt , SQLTDDL PTR ddl , + SQLTCHP chp , SQLTCHL PTR chlp , + SQLTPRE PTR prep , SQLTSCA PTR scap ); +typedef byte2 (SBSTDCALL *sqldid_t)(SQLTDAP dbname , SQLTDAL dbnamel ); +typedef byte2 (SBSTDCALL *sqldii_t)(SQLTCUR cur , SQLTSLC ivn , + SQLTDAP inp , SQLTCHL* inlp ); +typedef byte2 (SBSTDCALL *sqldin_t)(SQLTDAP dbnamp , SQLTDAL dbnaml ); +typedef byte2 (SBSTDCALL *sqldir_t)(SQLTSVN srvno , SQLTDAP buffer , + SQLTDAL length ); +typedef byte2 (SBSTDCALL *sqldis_t)(SQLTCUR cur ); +typedef byte2 (SBSTDCALL *sqldon_t)(void); +typedef byte2 (SBSTDCALL *sqldox_t)(SQLTSVH shandle , SQLTDAP dirnamep, + SQLTFAT fattr ); +typedef byte2 (SBSTDCALL *sqldrc_t)(SQLTSVH cur ); +typedef byte2 (SBSTDCALL *sqldro_t)(SQLTSVH shandle , SQLTDAP dirname ); +typedef byte2 (SBSTDCALL *sqldrr_t)(SQLTSVH shandle , SQLTDAP filename); +typedef byte2 (SBSTDCALL *sqldrs_t)(SQLTCUR cur , SQLTDAP rsp , + SQLTDAL rsl ); +typedef byte2 (SBSTDCALL *sqldsc_t)(SQLTCUR cur , SQLTSLC slc , + SQLTDDT PTR edt , SQLTDDL PTR edl , + SQLTCHP chp , SQLTCHL PTR chlp , + SQLTPRE PTR prep , SQLTSCA PTR scap ); +typedef byte2 (SBSTDCALL *sqldst_t)(SQLTCUR cur , SQLTDAP cnp , + SQLTDAL cnl ); +typedef byte2 (SBSTDCALL *sqldsv_t)(SQLTSVH shandle ); +typedef byte2 (SBSTDCALL *sqlebk_t)(SQLTCUR cur ); +typedef byte2 (SBSTDCALL *sqlefb_t)(SQLTCUR cur ); +typedef byte2 (SBSTDCALL *sqlelo_t)(SQLTCUR cur ); +typedef byte2 (SBSTDCALL *sqlenr_t)(SQLTSVH shandle , SQLTDAP dbname , + SQLTDAL dbnamel ); +typedef byte2 (SBSTDCALL *sqlepo_t)(SQLTCUR cur , SQLTEPO PTR epo ); +typedef byte2 (SBSTDCALL *sqlerf_t)(SQLTCUR cur ); +typedef byte2 (SBSTDCALL *sqlerr_t)(SQLTRCD error , SQLTDAP msg ); +typedef byte2 (SBSTDCALL *sqlers_t)(SQLTCUR cur ); +typedef byte2 (SBSTDCALL *sqletx_t)(SQLTRCD error , SQLTPTY msgtyp , + SQLTDAP bfp , SQLTDAL bfl , + SQLTDAL PTR txtlen ); +typedef byte2 (SBSTDCALL *sqlexe_t)(SQLTCUR cur ); +typedef byte2 (SBSTDCALL *sqlexp_t)(SQLTCUR cur , SQLTDAP buffer , + SQLTDAL length ); +typedef byte2 (SBSTDCALL *sqlfbk_t)(SQLTCUR cur ); +typedef byte2 (SBSTDCALL *sqlfer_t)(SQLTRCD error , SQLTDAP msg ); +typedef byte2 (SBSTDCALL *sqlfet_t)(SQLTCUR cur ); +typedef byte2 (SBSTDCALL *sqlfgt_t)(SQLTSVH cur , SQLTDAP srvfile , + SQLTDAP lclfile ); +typedef byte2 (SBSTDCALL *sqlfpt_t)(SQLTSVH cur , SQLTDAP srvfile , + SQLTDAP lclfile ); +typedef byte2 (SBSTDCALL *sqlfqn_t)(SQLTCUR cur , SQLTFLD field , + SQLTDAP nameptr , SQLTDAL PTR namelen ); +typedef byte2 (SBSTDCALL *sqlgbi_t)(SQLTCUR cur , SQLTCUR PTR pcur , + SQLTPNM PTR ppnm ); +typedef byte2 (SBSTDCALL *sqlgdi_t)(SQLTCUR cur , SQLTPGD gdi ); +typedef byte2 (SBSTDCALL *sqlget_t)(SQLTCUR cur , SQLTPTY parm , + SQLTDAP p , SQLTDAL PTR l ); +typedef byte2 (SBSTDCALL *sqlgfi_t)(SQLTCUR cur , SQLTSLC slc , + SQLTCDL PTR cvl , SQLTFSC PTR fsc ); +typedef byte2 (SBSTDCALL *sqlgls_t)(SQLTCUR cur , SQLTSLC slc , + SQLTLSI PTR size ); +typedef byte2 (SBSTDCALL *sqlgnl_t)(SQLTSVH shandle , SQLTDAP dbname , + SQLTDAL dbnamel , SQLTLNG PTR lognum ); +typedef byte2 (SBSTDCALL *sqlgnr_t)(SQLTCUR cur , SQLTDAP tbnam , + SQLTDAL tbnaml , SQLTROW PTR rows ); +typedef byte2 (SBSTDCALL *sqlgsi_t)(SQLTSVH shandle , SQLTFLG infoflags, + SQLTDAP buffer , SQLTDAL buflen , + SQLTDAL PTR rbuflen ); +typedef byte2 (SBSTDCALL *sqlidb_t)(SQLTCUR cur ); +typedef byte2 (SBSTDCALL *sqlims_t)(SQLTCUR cur , SQLTDAL insize ); +typedef byte2 (SBSTDCALL *sqlind_t)(SQLTSVH shandle , SQLTDAP dbnamp , + SQLTDAL dbnaml ); +typedef byte2 (SBSTDCALL *sqlini_t)(SQLTPFP callback); +typedef byte2 (SBSTDCALL *sqlins_t)(SQLTSVN srvno , SQLTDAP dbnamp , + SQLTDAL dbnaml , SQLTFLG createflag, + SQLTFLG overwrite); +typedef byte2 (SBSTDCALL *sqllab_t)(SQLTCUR cur , SQLTSLC slc , + SQLTCHP lbp , SQLTCHL PTR lblp ); +typedef byte2 (SBSTDCALL *sqlldp_t)(SQLTCUR cur , SQLTDAP cmdp , + SQLTDAL cmdl ); +typedef byte2 (SBSTDCALL *sqllsk_t)(SQLTCUR cur , SQLTSLC slc , + SQLTLSI pos ); +typedef byte2 (SBSTDCALL *sqlmcl_t)(SQLTSVH shandle , SQLTFLH fd ); +typedef byte2 (SBSTDCALL *sqlmdl_t)(SQLTSVH shandle , SQLTDAP filename); +typedef byte2 (SBSTDCALL *sqlmop_t)(SQLTSVH shandle , SQLTFLH PTR fdp , + SQLTDAP filename, SQLTFMD openmode); +typedef byte2 (SBSTDCALL *sqlmrd_t)(SQLTSVH shandle , SQLTFLH fd , + SQLTDAP buffer , SQLTDAL len , + SQLTDAL PTR rlen ); +typedef byte2 (SBSTDCALL *sqlmsk_t)(SQLTSVH shandle , SQLTFLH fd , + SQLTLNG offset , SQLTWNC whence , + SQLTLNG PTR roffset ); +typedef byte2 (SBSTDCALL *sqlmwr_t)(SQLTSVH shandle , SQLTFLH fd , + SQLTDAP buffer , SQLTDAL len , + SQLTDAL PTR rlen ); +typedef byte2 (SBSTDCALL *sqlnbv_t)(SQLTCUR cur , SQLTNBV PTR nbv ); +typedef byte2 (SBSTDCALL *sqlnii_t)(SQLTCUR cur , SQLTNSI PTR nii ); +typedef byte2 (SBSTDCALL *sqlnrr_t)(SQLTCUR cur , SQLTROW PTR rcountp ); +typedef byte2 (SBSTDCALL *sqlnsi_t)(SQLTCUR cur , SQLTNSI PTR nsi ); +typedef byte2 (SBSTDCALL *sqloms_t)(SQLTCUR cur , SQLTDAL outsize ); +typedef byte2 (SBSTDCALL *sqlprs_t)(SQLTCUR cur , SQLTROW row ); +typedef byte2 (SBSTDCALL *sqlrbf_t)(SQLTCUR cur , SQLTRBF PTR rbf ); +typedef byte2 (SBSTDCALL *sqlrbk_t)(SQLTCUR cur ); +typedef byte2 (SBSTDCALL *sqlrcd_t)(SQLTCUR cur , SQLTRCD PTR rcd ); +typedef byte2 (SBSTDCALL *sqlrdb_t)(SQLTSVH shandle , SQLTDAP dbname , + SQLTDAL dbnamel , SQLTFNP bkpdir , + SQLTFNL bkpdirl , SQLTBOO local , + SQLTBOO over ); +typedef byte2 (SBSTDCALL *sqlrdc_t)(SQLTCUR cur , SQLTDAP bufp , + SQLTDAL bufl , SQLTDAL PTR readl ); +typedef byte2 (SBSTDCALL *sqlrel_t)(SQLTCUR cur ); +typedef byte2 (SBSTDCALL *sqlres_t)(SQLTCUR PTR curptr , SQLTFNP bkfname , + SQLTFNL bkfnlen , SQLTSVN bkfserv , + SQLTBOO overwrt , SQLTDAP dbname , + SQLTDAL dbnlen , SQLTSVN dbserv ); +typedef byte2 (SBSTDCALL *sqlret_t)(SQLTCUR cur , SQLTDAP cnp , + SQLTDAL cnl ); +typedef byte2 (SBSTDCALL *sqlrlf_t)(SQLTSVH shandle , SQLTDAP dbname , + SQLTDAL dbnamel , SQLTFNP bkpdir , + SQLTFNL bkpdirl , SQLTBOO local , + SQLTBOO over ); +typedef byte2 (SBSTDCALL *sqlrlo_t)(SQLTCUR cur , SQLTSLC slc , + SQLTDAP bufp , SQLTDAL bufl , + SQLTDAL PTR readl ); +typedef byte2 (SBSTDCALL *sqlrof_t)(SQLTSVH shandle , SQLTDAP dbname , + SQLTDAL dbnamel , SQLTRFM mode , + SQLTDAP datetime, SQLTDAL datetimel); +typedef byte2 (SBSTDCALL *sqlrow_t)(SQLTCUR cur , SQLTROW PTR row ); +typedef byte2 (SBSTDCALL *sqlrrd_t)(SQLTCUR cur ); +typedef byte2 (SBSTDCALL *sqlrrs_t)(SQLTCUR cur , SQLTDAP rsp , + SQLTDAL rsl ); +typedef byte2 (SBSTDCALL *sqlrsi_t)(SQLTSVH shandle ); +typedef byte2 (SBSTDCALL *sqlrss_t)(SQLTSVH shandle , SQLTDAP dbname , + SQLTDAL dbnamel , SQLTFNP bkpdir , + SQLTFNL bkpdirl , SQLTBOO local , + SQLTBOO over ); +typedef byte2 (SBSTDCALL *sqlsab_t)(SQLTSVH shandle , SQLTPNM pnum ); +typedef byte2 (SBSTDCALL *sqlsap_t)(SQLTSVN srvno , SQLTDAP password, + SQLTPNM pnum ); +typedef byte2 (SBSTDCALL *sqlscl_t)(SQLTCUR cur , SQLTDAP namp , + SQLTDAL naml ); +typedef byte2 (SBSTDCALL *sqlscn_t)(SQLTCUR cur , SQLTDAP namp , + SQLTDAL naml ); +typedef byte2 (SBSTDCALL *sqlscp_t)(SQLTNPG pages ); +typedef byte2 (SBSTDCALL *sqlsdn_t)(SQLTDAP dbnamp , SQLTDAL dbnaml ); +typedef byte2 (SBSTDCALL *sqlsds_t)(SQLTSVH shandle, SQLTFLG shutdownflg); +typedef byte2 (SBSTDCALL *sqlsdx_t)(SQLTSVH shandle, SQLTDAP dbnamp, + SQLTDAL dbnaml , SQLTFLG shutdownflg); +typedef byte2 (SBSTDCALL *sqlset_t)(SQLTCUR cur , SQLTPTY parm , + SQLTDAP p , SQLTDAL l ); +typedef byte2 (SBSTDCALL *sqlsil_t)(SQLTCUR cur , SQLTILV isolation); +typedef byte2 (SBSTDCALL *sqlslp_t)(SQLTCUR cur , SQLTNPG lpt , + SQLTNPG lpm ); +typedef byte2 (SBSTDCALL *sqlspr_t)(SQLTCUR cur ); +typedef byte2 (SBSTDCALL *sqlsrf_t)(SQLTCUR cur , SQLTDAP fnp , + SQLTDAL fnl ); +typedef byte2 (SBSTDCALL *sqlsrs_t)(SQLTCUR cur ); +typedef byte2 (SBSTDCALL *sqlssb_t)(SQLTCUR cur , SQLTSLC slc , + SQLTPDT pdt , SQLTDAP pbp , + SQLTPDL pdl , SQLTSCA sca , + SQLTCDL PTR pcv , SQLTFSC PTR pfc ); +typedef byte2 (SBSTDCALL *sqlsss_t)(SQLTCUR cur , SQLTDAL size ); +typedef byte2 (SBSTDCALL *sqlsta_t)(SQLTCUR cur , SQLTSTC PTR svr , + SQLTSTC PTR svw , SQLTSTC PTR spr , + SQLTSTC PTR spw ); +typedef byte2 (SBSTDCALL *sqlstm_t)(SQLTSVH shandle ); +typedef byte2 (SBSTDCALL *sqlsto_t)(SQLTCUR cur , SQLTDAP cnp , + SQLTDAL cnl , SQLTDAP ctp , + SQLTDAL ctl ); +typedef byte2 (SBSTDCALL *sqlstr_t)(SQLTCUR cur ); +typedef byte2 (SBSTDCALL *sqlsxt_t)(SQLTSVN srvno , SQLTDAP password); +typedef byte2 (SBSTDCALL *sqlsys_t)(SQLTCUR cur , SQLTSYS PTR sys ); +typedef byte2 (SBSTDCALL *sqltec_t)(SQLTRCD rcd , SQLTRCD PTR np ); +typedef byte2 (SBSTDCALL *sqltem_t)(SQLTCUR cur , SQLTXER PTR xer , + SQLTPTY msgtyp , SQLTDAP bfp , + SQLTDAL bfl , SQLTDAL PTR txtlen ); +typedef byte2 (SBSTDCALL *sqltio_t)(SQLTCUR cur , SQLTTIV _timeout); +typedef byte2 (SBSTDCALL *sqlunl_t)(SQLTCUR cur , SQLTDAP cmdp , + SQLTDAL cmdl ); +typedef byte2 (SBSTDCALL *sqlurs_t)(SQLTCUR cur ); +typedef byte2 (SBSTDCALL *sqlwdc_t)(SQLTCUR cur , SQLTDAP bufp , + SQLTDAL bufl ); +typedef byte2 (SBSTDCALL *sqlwlo_t)(SQLTCUR cur , SQLTDAP bufp , + SQLTDAL bufl ); +typedef byte2 (SBSTDCALL *sqlxad_t)(SQLTNMP op , SQLTNMP np1 , + SQLTNML nl1 , SQLTNMP np2 , + SQLTNML nl2 ); +typedef byte2 (SBSTDCALL *sqlxcn_t)(SQLTNMP op , SQLTDAP ip , + SQLTDAL il ); +typedef byte2 (SBSTDCALL *sqlxda_t)(SQLTNMP op , SQLTNMP dp , + SQLTNML dl , SQLTDAY days ); +typedef byte2 (SBSTDCALL *sqlxdp_t)(SQLTDAP op , SQLTDAL ol , + SQLTNMP ip , SQLTNML il , + SQLTDAP pp , SQLTDAL pl ); +typedef byte2 (SBSTDCALL *sqlxdv_t)(SQLTNMP op , SQLTNMP np1 , + SQLTNML nl1 , SQLTNMP np2 , + SQLTNML nl2 ); +typedef byte2 (SBSTDCALL *sqlxer_t)(SQLTCUR cur , SQLTXER PTR errnum, + SQLTDAP errbuf , SQLTDAL PTR buflen ); +typedef byte2 (SBSTDCALL *sqlxml_t)(SQLTNMP op , SQLTNMP np1 , + SQLTNML nl1 , SQLTNMP np2 , + SQLTNML nl2 ); +typedef byte2 (SBSTDCALL *sqlxnp_t)(SQLTDAP outp , SQLTDAL outl , + SQLTNMP isnp , SQLTNML isnl , + SQLTDAP picp , SQLTDAL picl ); +typedef byte2 (SBSTDCALL *sqlxpd_t)(SQLTNMP op , SQLTNML PTR olp , + SQLTDAP ip , SQLTDAP pp , + SQLTDAL pl ); +typedef byte2 (SBSTDCALL *sqlxsb_t)(SQLTNMP op , SQLTNMP np1 , + SQLTNML nl1 , SQLTNMP np2 , + SQLTNML nl2 ); + +// version 7 specific +typedef byte2 (SBSTDCALL *sqlcch_t)(SQLTCON PTR hConp , SQLTDAP dbnamp , + SQLTDAL dbnaml , SQLTMOD fType ); +typedef byte2 (SBSTDCALL *sqldch_t)(SQLTCON hCon ); +typedef byte2 (SBSTDCALL *sqlopc_t)(SQLTCUR PTR curp , SQLTCON hCon , + SQLTMOD fType ); + +// API declarations +class SQLAPI_API sb6API : public saAPI +{ +public: + sb6API(); + + sqlarf_t sqlarf; + sqlbbr_t sqlbbr; + sqlbdb_t sqlbdb; + sqlbef_t sqlbef; + sqlber_t sqlber; + sqlbkp_t sqlbkp; + sqlbld_t sqlbld; + sqlblf_t sqlblf; + sqlblk_t sqlblk; + sqlbln_t sqlbln; + sqlbna_t sqlbna; + sqlbnd_t sqlbnd; + sqlbnn_t sqlbnn; + sqlbnu_t sqlbnu; + sqlbss_t sqlbss; + sqlcan_t sqlcan; + sqlcbv_t sqlcbv; + sqlcdr_t sqlcdr; + sqlcex_t sqlcex; + sqlclf_t sqlclf; + sqlcmt_t sqlcmt; + sqlcnc_t sqlcnc; + sqlcnr_t sqlcnr; + sqlcom_t sqlcom; + sqlcon_t sqlcon; + sqlcpy_t sqlcpy; + sqlcre_t sqlcre; + sqlcrf_t sqlcrf; + sqlcrs_t sqlcrs; + sqlcsv_t sqlcsv; + sqlcty_t sqlcty; + sqldbn_t sqldbn; + sqlded_t sqlded; + sqldel_t sqldel; + sqldes_t sqldes; + sqldid_t sqldid; + sqldii_t sqldii; + sqldin_t sqldin; + sqldir_t sqldir; + sqldis_t sqldis; + sqldon_t sqldon; + sqldox_t sqldox; + sqldrc_t sqldrc; + sqldro_t sqldro; + sqldrr_t sqldrr; + sqldrs_t sqldrs; + sqldsc_t sqldsc; + sqldst_t sqldst; + sqldsv_t sqldsv; + sqlebk_t sqlebk; + sqlefb_t sqlefb; + sqlelo_t sqlelo; + sqlenr_t sqlenr; + sqlepo_t sqlepo; + sqlerf_t sqlerf; + sqlerr_t sqlerr; + sqlers_t sqlers; + sqletx_t sqletx; + sqlexe_t sqlexe; + sqlexp_t sqlexp; + sqlfbk_t sqlfbk; + sqlfer_t sqlfer; + sqlfet_t sqlfet; + sqlfgt_t sqlfgt; + sqlfpt_t sqlfpt; + sqlfqn_t sqlfqn; + sqlgbi_t sqlgbi; + sqlgdi_t sqlgdi; + sqlget_t sqlget; + sqlgfi_t sqlgfi; + sqlgls_t sqlgls; + sqlgnl_t sqlgnl; + sqlgnr_t sqlgnr; + sqlgsi_t sqlgsi; + sqlidb_t sqlidb; + sqlims_t sqlims; + sqlind_t sqlind; + sqlini_t sqlini; + sqlins_t sqlins; + sqllab_t sqllab; + sqlldp_t sqlldp; + sqllsk_t sqllsk; + sqlmcl_t sqlmcl; + sqlmdl_t sqlmdl; + sqlmop_t sqlmop; + sqlmrd_t sqlmrd; + sqlmsk_t sqlmsk; + sqlmwr_t sqlmwr; + sqlnbv_t sqlnbv; + sqlnii_t sqlnii; + sqlnrr_t sqlnrr; + sqlnsi_t sqlnsi; + sqloms_t sqloms; + sqlprs_t sqlprs; + sqlrbf_t sqlrbf; + sqlrbk_t sqlrbk; + sqlrcd_t sqlrcd; + sqlrdb_t sqlrdb; + sqlrdc_t sqlrdc; + sqlrel_t sqlrel; + sqlres_t sqlres; + sqlret_t sqlret; + sqlrlf_t sqlrlf; + sqlrlo_t sqlrlo; + sqlrof_t sqlrof; + sqlrow_t sqlrow; + sqlrrd_t sqlrrd; + sqlrrs_t sqlrrs; + sqlrsi_t sqlrsi; + sqlrss_t sqlrss; + sqlsab_t sqlsab; + sqlsap_t sqlsap; + sqlscl_t sqlscl; + sqlscn_t sqlscn; + sqlscp_t sqlscp; + sqlsdn_t sqlsdn; + sqlsds_t sqlsds; + sqlsdx_t sqlsdx; + sqlset_t sqlset; + sqlsil_t sqlsil; + sqlslp_t sqlslp; + sqlspr_t sqlspr; + sqlsrf_t sqlsrf; + sqlsrs_t sqlsrs; + sqlssb_t sqlssb; + sqlsss_t sqlsss; + sqlsta_t sqlsta; + sqlstm_t sqlstm; + sqlsto_t sqlsto; + sqlstr_t sqlstr; + sqlsxt_t sqlsxt; + sqlsys_t sqlsys; + sqltec_t sqltec; + sqltem_t sqltem; + sqltio_t sqltio; + sqlunl_t sqlunl; + sqlurs_t sqlurs; + sqlwdc_t sqlwdc; + sqlwlo_t sqlwlo; + sqlxad_t sqlxad; + sqlxcn_t sqlxcn; + sqlxda_t sqlxda; + sqlxdp_t sqlxdp; + sqlxdv_t sqlxdv; + sqlxer_t sqlxer; + sqlxml_t sqlxml; + sqlxnp_t sqlxnp; + sqlxpd_t sqlxpd; + sqlxsb_t sqlxsb; +}; + +// version 7 specific +class SQLAPI_API sb7API : public sb6API +{ +public: + sb7API(); + + sqlcch_t sqlcch; + sqldch_t sqldch; + sqlopc_t sqlopc; +}; + +class SQLAPI_API sb6ConnectionHandles : public saConnectionHandles +{ +public: + sb6ConnectionHandles(); + + SQLTCUR m_cur; // SQLBase cursor number +}; + +class SQLAPI_API sb7ConnectionHandles : public sb6ConnectionHandles +{ +public: + sb7ConnectionHandles(); + + SQLTCON m_hCon; +}; + +class SQLAPI_API sbCommandHandles : public saCommandHandles +{ +public: + sbCommandHandles(); + + SQLTCUR m_cur; +}; + +extern sb7API g_sb7API; +extern sb6API &g_sb6API; + +#endif // !defined(__SB7API_H__) diff --git a/libodbc/include/sl3API.h b/libodbc/include/sl3API.h new file mode 100644 index 0000000000..980af69e89 --- /dev/null +++ b/libodbc/include/sl3API.h @@ -0,0 +1,252 @@ +////////////////////////////////////////////////////////////////////// +// slAPI.h +////////////////////////////////////////////////////////////////////// + +#if !defined(__SLAPI_H__) +#define __SLAPI_H__ + +#include +#include + +extern void AddSQLite3Support(const SAConnection * pCon); +extern void ReleaseSQLite3Support(); + +typedef int (*sqlite3_open_t)(const void *filename, sqlite3 **ppDb); +typedef const char * (*sqlite3_libversion_t)(void); +typedef int (*sqlite3_libversion_number_t)(void); +typedef int (*sqlite3_threadsafe_t)(void); +typedef int (*sqlite3_close_t)(sqlite3 *); +typedef int (*sqlite3_extended_result_codes_t)(sqlite3*, int onoff); +typedef sqlite3_int64 (*sqlite3_last_insert_rowid_t)(sqlite3*); +typedef int (*sqlite3_changes_t)(sqlite3*); +typedef int (*sqlite3_total_changes_t)(sqlite3*); +typedef void (*sqlite3_interrupt_t)(sqlite3*); +typedef int (*sqlite3_complete_t)(const char *sql); +typedef int (*sqlite3_complete16_t)(const void *sql); +typedef int (*sqlite3_busy_handler_t)(sqlite3*, int(*)(void*,int), void*); +typedef int (*sqlite3_busy_timeout_t)(sqlite3*, int ms); +typedef void (*sqlite3_free_table_t)(char **result); +typedef char *(*sqlite3_mprintf_t)(const char*,...); +typedef char *(*sqlite3_vmprintf_t)(const char*, va_list); +typedef char *(*sqlite3_snprintf_t)(int,char*,const char*, ...); +typedef void *(*sqlite3_malloc_t)(int); +typedef void *(*sqlite3_realloc_t)(void*, int); +typedef void (*sqlite3_free_t)(void*); +typedef sqlite3_int64 (*sqlite3_memory_used_t)(void); +typedef sqlite3_int64 (*sqlite3_memory_highwater_t)(int resetFlag); +typedef void *(*sqlite3_trace_t)(sqlite3*, void(*xTrace)(void*,const char*), void*); +typedef void (*sqlite3_progress_handler_t)(sqlite3*, int, int(*)(void*), void*); +typedef int (*sqlite3_errcode_t)(sqlite3 *db); +typedef const void *(*sqlite3_errmsg_t)(sqlite3*); +typedef int (*sqlite3_bind_blob_t)(sqlite3_stmt*, int, const void*, int n, void(*)(void*)); +typedef int (*sqlite3_bind_double_t)(sqlite3_stmt*, int, double); +typedef int (*sqlite3_bind_int_t)(sqlite3_stmt*, int, int); +typedef int (*sqlite3_bind_int64_t)(sqlite3_stmt*, int, sqlite3_int64); +typedef int (*sqlite3_bind_null_t)(sqlite3_stmt*, int); +typedef int (*sqlite3_bind_text_t)(sqlite3_stmt*, int, const void*, int n, void(*)(void*)); +typedef int (*sqlite3_bind_value_t)(sqlite3_stmt*, int, const sqlite3_value*); +typedef int (*sqlite3_bind_zeroblob_t)(sqlite3_stmt*, int, int n); +typedef int (*sqlite3_bind_parameter_count_t)(sqlite3_stmt*); +typedef const char *(*sqlite3_bind_parameter_name_t)(sqlite3_stmt*, int); +typedef int (*sqlite3_bind_parameter_index_t)(sqlite3_stmt*, const char *zName); +typedef int (*sqlite3_clear_bindings_t)(sqlite3_stmt*); +typedef int (*sqlite3_column_count_t)(sqlite3_stmt *pStmt); +typedef const void *(*sqlite3_column_name_t)(sqlite3_stmt*, int N); +typedef const char *(*sqlite3_column_database_name_t)(sqlite3_stmt*,int); +typedef const void *(*sqlite3_column_database_name16_t)(sqlite3_stmt*,int); +typedef const char *(*sqlite3_column_table_name_t)(sqlite3_stmt*,int); +typedef const void *(*sqlite3_column_table_name16_t)(sqlite3_stmt*,int); +typedef const char *(*sqlite3_column_origin_name_t)(sqlite3_stmt*,int); +typedef const void *(*sqlite3_column_origin_name16_t)(sqlite3_stmt*,int); +typedef const void *(*sqlite3_column_decltype_t)(sqlite3_stmt *, int); +typedef int (*sqlite3_step_t)(sqlite3_stmt*); +typedef int (*sqlite3_data_count_t)(sqlite3_stmt *pStmt); +typedef const void *(*sqlite3_column_blob_t)(sqlite3_stmt*, int iCol); +typedef int (*sqlite3_column_bytes_t)(sqlite3_stmt*, int iCol); +typedef double (*sqlite3_column_double_t)(sqlite3_stmt*, int iCol); +typedef int (*sqlite3_column_int_t)(sqlite3_stmt*, int iCol); +typedef sqlite3_int64 (*sqlite3_column_int64_t)(sqlite3_stmt*, int iCol); +typedef const void *(*sqlite3_column_text_t)(sqlite3_stmt*, int iCol); +typedef int (*sqlite3_column_type_t)(sqlite3_stmt*, int iCol); +typedef sqlite3_value *(*sqlite3_column_value_t)(sqlite3_stmt*, int iCol); +typedef int (*sqlite3_finalize_t)(sqlite3_stmt *pStmt); +typedef int (*sqlite3_reset_t)(sqlite3_stmt *pStmt); +typedef int (*sqlite3_aggregate_count_t)(sqlite3_context*); +typedef int (*sqlite3_expired_t)(sqlite3_stmt*); +typedef int (*sqlite3_transfer_bindings_t)(sqlite3_stmt*, sqlite3_stmt*); +typedef int (*sqlite3_global_recover_t)(void); +typedef void (*sqlite3_thread_cleanup_t)(void); +typedef const void *(*sqlite3_value_blob_t)(sqlite3_value*); +typedef int (*sqlite3_value_bytes_t)(sqlite3_value*); +typedef int (*sqlite3_value_bytes16_t)(sqlite3_value*); +typedef double (*sqlite3_value_double_t)(sqlite3_value*); +typedef int (*sqlite3_value_int_t)(sqlite3_value*); +typedef sqlite3_int64 (*sqlite3_value_int64_t)(sqlite3_value*); +typedef const unsigned char *(*sqlite3_value_text_t)(sqlite3_value*); +typedef const void *(*sqlite3_value_text16_t)(sqlite3_value*); +typedef const void *(*sqlite3_value_text16le_t)(sqlite3_value*); +typedef const void *(*sqlite3_value_text16be_t)(sqlite3_value*); +typedef int (*sqlite3_value_type_t)(sqlite3_value*); +typedef int (*sqlite3_value_numeric_type_t)(sqlite3_value*); +typedef void *(*sqlite3_aggregate_context_t)(sqlite3_context*, int nBytes); +typedef void *(*sqlite3_user_data_t)(sqlite3_context*); +typedef void *(*sqlite3_get_auxdata_t)(sqlite3_context*, int); +typedef void (*sqlite3_set_auxdata_t)(sqlite3_context*, int, void*, void (*)(void*)); +typedef void (*sqlite3_result_blob_t)(sqlite3_context*, const void*, int, void(*)(void*)); +typedef void (*sqlite3_result_double_t)(sqlite3_context*, double); +typedef void (*sqlite3_result_error_t)(sqlite3_context*, const char*, int); +typedef void (*sqlite3_result_error16_t)(sqlite3_context*, const void*, int); +typedef void (*sqlite3_result_error_toobig_t)(sqlite3_context*); +typedef void (*sqlite3_result_error_nomem_t)(sqlite3_context*); +typedef void (*sqlite3_result_int_t)(sqlite3_context*, int); +typedef void (*sqlite3_result_int64_t)(sqlite3_context*, sqlite3_int64); +typedef void (*sqlite3_result_null_t)(sqlite3_context*); +typedef void (*sqlite3_result_text_t)(sqlite3_context*, const char*, int, void(*)(void*)); +typedef void (*sqlite3_result_text16_t)(sqlite3_context*, const void*, int, void(*)(void*)); +typedef void (*sqlite3_result_text16le_t)(sqlite3_context*, const void*, int,void(*)(void*)); +typedef void (*sqlite3_result_text16be_t)(sqlite3_context*, const void*, int,void(*)(void*)); +typedef void (*sqlite3_result_value_t)(sqlite3_context*, sqlite3_value*); +typedef void (*sqlite3_result_zeroblob_t)(sqlite3_context*, int n); +typedef int (*sqlite3_sleep_t)(int); +typedef int (*sqlite3_get_autocommit_t)(sqlite3*); +typedef sqlite3 *(*sqlite3_db_handle_t)(sqlite3_stmt*); +typedef void *(*sqlite3_commit_hook_t)(sqlite3*, int(*)(void*), void*); +typedef void *(*sqlite3_rollback_hook_t)(sqlite3*, void(*)(void *), void*); +typedef int (*sqlite3_enable_shared_cache_t)(int); +typedef int (*sqlite3_release_memory_t)(int); +typedef void (*sqlite3_soft_heap_limit_t)(int); +typedef int (*sqlite3_enable_load_extension_t)(sqlite3 *db, int onoff); +typedef int (*sqlite3_auto_extension_t)(void *xEntryPoint); +typedef void (*sqlite3_reset_auto_extension_t)(void); +typedef int (*sqlite3_declare_vtab_t)(sqlite3*, const char *zCreateTable); +typedef int (*sqlite3_overload_function_t)(sqlite3*, const char *zFuncName, int nArg); +typedef int (*sqlite3_blob_close_t)(sqlite3_blob *); +typedef int (*sqlite3_blob_bytes_t)(sqlite3_blob *); +typedef int (*sqlite3_blob_read_t)(sqlite3_blob *, void *z, int n, int iOffset); +typedef int (*sqlite3_blob_write_t)(sqlite3_blob *, const void *z, int n, int iOffset); +typedef sqlite3_vfs *(*sqlite3_vfs_find_t)(const char *zVfsName); +typedef int (*sqlite3_vfs_register_t)(sqlite3_vfs*, int makeDflt); +typedef int (*sqlite3_vfs_unregister_t)(sqlite3_vfs*); +typedef sqlite3_mutex *(*sqlite3_mutex_alloc_t)(int); +typedef void (*sqlite3_mutex_free_t)(sqlite3_mutex*); +typedef void (*sqlite3_mutex_enter_t)(sqlite3_mutex*); +typedef int (*sqlite3_mutex_try_t)(sqlite3_mutex*); +typedef void (*sqlite3_mutex_leave_t)(sqlite3_mutex*); +typedef int (*sqlite3_mutex_held_t)(sqlite3_mutex*); +typedef int (*sqlite3_mutex_notheld_t)(sqlite3_mutex*); +typedef int (*sqlite3_file_control_t)(sqlite3*, const char *zDbName, int op, void*); +typedef int (*sqlite3_exec_t)( + sqlite3*, /* An open database */ + const char *sql, /* SQL to be evaluted */ + int (*callback)(void*,int,char**,char**), /* Callback function */ + void *, /* 1st argument to callback */ + char **errmsg /* Error msg written here */ +); +typedef int (*sqlite3_prepare_t)( + sqlite3 *db, /* Database handle */ + const void *zSql, /* SQL statement, UTF-16 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const void **pzTail /* OUT: Pointer to unused portion of zSql */ +); +typedef int (*sqlite3_open_v2_t)(const char *filename, sqlite3 **ppDb, int flags, const char *zVfs); + +typedef sqlite3_backup *(*sqlite3_backup_init_t)( + sqlite3 *pDest, /* Destination database handle */ + const char *zDestName, /* Destination database name */ + sqlite3 *pSource, /* Source database handle */ + const char *zSourceName /* Source database name */ +); +typedef int (*sqlite3_backup_step_t)(sqlite3_backup *p, int nPage); +typedef int (*sqlite3_backup_finish_t)(sqlite3_backup *p); +typedef int (*sqlite3_backup_remaining_t)(sqlite3_backup *p); +typedef int (*sqlite3_backup_pagecount_t)(sqlite3_backup *p); + + +typedef int (*sqlite3_table_column_metadata_t)( + sqlite3 *db, /* Connection handle */ + const char *zDbName, /* Database name or NULL */ + const char *zTableName, /* Table name */ + const char *zColumnName, /* Column name */ + char const **pzDataType, /* OUTPUT: Declared data type */ + char const **pzCollSeq, /* OUTPUT: Collation sequence name */ + int *pNotNull, /* OUTPUT: True if NOT NULL constraint exists */ + int *pPrimaryKey, /* OUTPUT: True if column part of PK */ + int *pAutoinc /* OUTPUT: True if column is auto-increment */ +); + +// API declarations +class SQLAPI_API sl3API : public saAPI +{ +public: + sl3API(); + + sqlite3_open_t sqlite3_open; + sqlite3_libversion_t sqlite3_libversion; + sqlite3_libversion_number_t sqlite3_libversion_number; + sqlite3_errcode_t sqlite3_errcode; + sqlite3_errmsg_t sqlite3_errmsg; + sqlite3_close_t sqlite3_close; + sqlite3_exec_t sqlite3_exec; + sqlite3_prepare_t sqlite3_prepare; + sqlite3_bind_parameter_index_t sqlite3_bind_parameter_index; + sqlite3_column_count_t sqlite3_column_count; + sqlite3_column_name_t sqlite3_column_name; + sqlite3_column_type_t sqlite3_column_type; + sqlite3_column_bytes_t sqlite3_column_bytes; + sqlite3_step_t sqlite3_step; + sqlite3_db_handle_t sqlite3_db_handle; + sqlite3_reset_t sqlite3_reset; + sqlite3_clear_bindings_t sqlite3_clear_bindings; + sqlite3_finalize_t sqlite3_finalize; + sqlite3_interrupt_t sqlite3_interrupt; + sqlite3_changes_t sqlite3_changes; + sqlite3_column_int64_t sqlite3_column_int64; + sqlite3_column_double_t sqlite3_column_double; + sqlite3_column_blob_t sqlite3_column_blob; + sqlite3_column_text_t sqlite3_column_text; + sqlite3_bind_blob_t sqlite3_bind_blob; + sqlite3_bind_double_t sqlite3_bind_double; + sqlite3_bind_int_t sqlite3_bind_int; + sqlite3_bind_int64_t sqlite3_bind_int64; + sqlite3_bind_null_t sqlite3_bind_null; + sqlite3_bind_text_t sqlite3_bind_text; + + sqlite3_busy_handler_t sqlite3_busy_handler; + sqlite3_busy_timeout_t sqlite3_busy_timeout; + sqlite3_threadsafe_t sqlite3_threadsafe; + sqlite3_last_insert_rowid_t sqlite3_last_insert_rowid; + + sqlite3_column_decltype_t sqlite3_column_decltype; + + sqlite3_open_v2_t sqlite3_open_v2; + + sqlite3_backup_init_t sqlite3_backup_init; + sqlite3_backup_step_t sqlite3_backup_step; + sqlite3_backup_finish_t sqlite3_backup_finish; + sqlite3_backup_remaining_t sqlite3_backup_remaining; + sqlite3_backup_pagecount_t sqlite3_backup_pagecount; + + sqlite3_table_column_metadata_t sqlite3_table_column_metadata; + + sqlite3_column_value_t sqlite3_column_value; + sqlite3_value_type_t sqlite3_value_type; +}; + +class SQLAPI_API sl3ConnectionHandles : public saConnectionHandles +{ +public: + sl3ConnectionHandles(); + sqlite3 *pDb; +}; + +class SQLAPI_API sl3CommandHandles : public saCommandHandles +{ +public: + sl3CommandHandles(); + sqlite3_stmt *pStmt; +}; + +extern sl3API g_sl3API; + +#endif //__SLAPI_H__ diff --git a/libodbc/include/sqlbase/sql.h b/libodbc/include/sqlbase/sql.h new file mode 100644 index 0000000000..9096e403c4 --- /dev/null +++ b/libodbc/include/sqlbase/sql.h @@ -0,0 +1,1834 @@ +/* COPYRIGHT (C) GUPTA TECHNOLOGIES, LLC 1984-2004 */ +/* +INTERFACE TO + SQL +*/ +/* +REVISION HISTORY + 12/04/91 GTI release 5.0.0 + 12/08/91 GTI release 5.0.1 + 04/01/92 GTI release 5.0.2 + 08/28/92 GTI release 5.1.0 + 11/02/92 GTI release 5.1.1 + 02/12/93 GTI release 5.1.2 + 04/02/93 GTI release 5.2.0 + 05/03/93 GTI release 5.2.0 + 06/15/93 GTI release (null) + 06/15/93 GTI release 5.2.A + 06/30/93 GTI release 5.1.3 + 08/04/93 GTI release 5.1.4 + 01/19/94 GTI release 5.2.C + 03/22/94 GTI release 5.2.0 + 04/18/93 GTI release 6.0.A + 01/14/94 GTI release 6.0.B + 05/11/94 GTI release 6.0.C + 09/27/94 GTI release 6.0.0 + 04/12/95 GTI release 6.0.1 + 08/02/95 GTI release 6.1.0 + 11/14/96 GTI release 6.5.0 + 10/20/97 GTI release 7.0.0 + 10/23/98 GTI release 7.5.0 + 11/10/00 GTI release 7.6.0 + 08/22/01 RWS release 8.0.0 + 10/22/02 GTI release 8.1.0 + 12/20/02 GTI release 8.5.0 + 01/18/05 RWS release 9.0.1 +DESCRIPTION + This file contains structure definitions and defined constants used to + interface with SQLBASE. For a more complete definition see "SQLBASE: C + Programmer's Guide". +*/ + +#ifndef SQL +#define SQL + +#ifdef __cplusplus +extern "C" { /* Assume C declarations for C++ */ +#endif /* __cplusplus */ + +#ifndef SBSTDCALL +#ifdef __GNUC__ + #define SBSTDCALL /* stdcall */ +#else + #define SBSTDCALL __stdcall +#endif +#endif + +/* VERSION NUMBER */ +#define SQLVERS 90001 /* version number */ +#define SQLAPIV 00102 /* API version number since 3.6 */ +/* DEFINED CONSTANTS */ + +/*------------------------------------------------------------------------- + For 32-bit target systems, such as NetWare 386, Windows/NT, and OS/2 2.x, + redefine some 16-bit-oriented constructs, such as far, near, pascal, etc. + These redefinitions assume the compiler being used supports the flat + memory model. + ------------------------------------------------------------------------- */ + +# undef far +# undef near +# undef pascal +# undef cdecl + +# define far +# define near +# define pascal +# define cdecl +# ifndef CDECL +# define CDECL __cdecl +# endif +# define PTR * + +/* FETCH RETURN CODES */ +#define FETRTRU 1 /* data truncated */ +#define FETRSIN 2 /* signed number fetched */ +#define FETRDNN 3 /* data is not numeric */ +#define FETRNOF 4 /* numeric overflow */ +#define FETRDTN 5 /* data type not supported */ +#define FETRDND 6 /* data is not in date format */ +#define FETRNUL 7 /* data is null */ +/* DATABASE DATA TYPES */ +#define SQLDCHR 1 /* character data type */ +#define SQLDNUM 2 /* numeric data type */ +#define SQLDDAT 3 /* date-time data type */ +#define SQLDLON 4 /* long data type */ +#define SQLDDTE 5 /* date (only) data type */ +#define SQLDTIM 6 /* time (only) data type */ +#define SQLDHDL 7 /* sql handle data type */ +#define SQLDBOO 8 /* boolean data type */ +#define SQLDDTM 8 /* maximum data type */ +/* PROGRAM DATA TYPES */ +#define SQLPBUF 1 /* buffer */ +#define SQLPSTR 2 /* string (zero terminated) */ +#define SQLPUCH 3 /* unsigned char */ +#define SQLPSCH 4 /* char */ +#define SQLPUIN 5 /* unsigned int */ +#define SQLPSIN 6 /* int */ +#define SQLPULO 7 /* unsigned long */ +#define SQLPSLO 8 /* long */ +#define SQLPFLT 9 /* float */ +#define SQLPDOU 10 /* double */ +#define SQLPNUM 11 /* SQLBASE internal numeric format */ +#define SQLPDAT 12 /* SQLBASE internal datetime format */ +#define SQLPUPD 13 /* unsigned packed decimal */ +#define SQLPSPD 14 /* signed packed decimal */ +#define SQLPDTE 15 /* date only format */ +#define SQLPTIM 16 /* time only format */ +#define SQLPUSH 17 /* unsigned short */ +#define SQLPSSH 18 /* short */ +#define SQLPNST 19 /* numeric string */ +#define SQLPNBU 20 /* numeric buffer */ +#define SQLPEBC 21 /* EBCDIC buffer format */ +#define SQLPLON 22 /* long text string */ +#define SQLPLBI 23 /* long binary buffer */ +#define SQLPLVR 24 /* char\long varchar > 254 */ +#define SQLPULL 25 /* unsigned long long */ +#define SQLPSLL 26 /* long long */ +#define SQLPDTM 26 /* data type maximum */ +/* EXTERNAL DATA TYPES */ +#define SQLEINT 1 /* INTEGER */ +#define SQLESMA 2 /* SMALLINT */ +#define SQLEFLO 3 /* FLOAT */ +#define SQLECHR 4 /* CHAR */ +#define SQLEVAR 5 /* VARCHAR */ +#define SQLELON 6 /* LONGVAR */ +#define SQLEDEC 7 /* DECIMAL */ +#define SQLEDAT 8 /* DATE */ +#define SQLETIM 9 /* TIME */ +#define SQLETMS 10 /* TIMESTAMP */ +#define SQLEMON 11 /* MONEY */ +#define SQLEDOU 12 /* DOUBLE */ +#define SQLEGPH 13 /* GRAPHIC */ +#define SQLEVGP 14 /* VAR GRAPHIC */ +#define SQLELGP 15 /* LONG VAR GRAPHIC */ +#define SQLEBIN 16 /* BINARY */ +#define SQLEVBI 17 /* VAR BINARY */ +#define SQLELBI 18 /* LONG BINARY */ +#define SQLEBOO 19 /* BOOLEAN */ +#define SQLELCH 20 /* CHAR > 254 */ +#define SQLELVR 21 /* VARCHAR > 254 */ + +/* SET and GET PARAMETER TYPES */ +/* Global parameters + ------------------ */ +#define SQLPDDB 1 /* default database name */ +#define SQLPDUS 2 /* default user name */ +#define SQLPDPW 3 /* default password */ +#define SQLPGBC 4 /* global cursor value */ +#define SQLPLRD 5 /* local result set directory */ +#define SQLPDBM 6 /* db mode - see below */ +#define SQLPDBD 7 /* dbdir */ +#define SQLPCPG 8 /* code page information */ +#define SQLPNIE 9 /* null indicator error */ +#define SQLPCPT 10 /* connect pass thru to backend */ +#define SQLPTPD 11 /* temp dir */ +#define SQLPDTR 12 /* distributed transaction mode */ +#define SQLPPSW 15 /* server password */ +#define SQLPOOJ 16 /* oracle outer join */ +#define SQLPNPF 17 /* net prefix */ +#define SQLPNLG 18 /* net log */ +#define SQLPNCT 19 /* net check type */ +#define SQLPNCK 20 /* net check */ +#define SQLPLCK 22 /* locks */ +#define SQLPINT 25 /* interrupt */ +#define SQLPERF 27 /* error file */ +#define SQLPDIO 28 /* direct I/O */ +#define SQLPSWR 29 /* default write */ +#define SQLPCTY 31 /* country */ +#define SQLPCSD 32 /* commit server daemon */ +#define SQLPCSR 33 /* commit server */ +#define SQLPCCK 36 /* client check */ +#define SQLPCTS 37 /* characterset */ +#define SQLPCGR 38 /* cache group */ +#define SQLPAIO 39 /* asyncio */ +#define SQLPANL 40 /* apply net log */ +#define SQLPGRS 41 /* get reentracy state */ +#define SQLPSTF 42 /* set SQLTrace flags */ +#define SQLPCLG 43 /* set commit-order logging */ + +/* Server specific parameters + -------------------------- */ + +#define SQLPHEP 1001 /* HEAP size for TSR executables */ +#define SQLPCAC 1002 /* CACHE size in Kbytes */ +#define SQLPBRN 1003 /* brand of database */ +#define SQLPVER 1004 /* release version (ex. "4.0.J") */ +#define SQLPPRF 1005 /* server profiling */ +#define SQLPPDB 1006 /* partitioned database */ +#define SQLPGCM 1007 /* group commit count */ +#define SQLPGCD 1008 /* group commit delay ticks */ +#define SQLPDLK 1009 /* number of deadlocks */ +#define SQLPCTL 1010 /* command time limit */ +#define SQLPAPT 1011 /* process timer activated */ +#define SQLPOSR 1012 /* OS sample rate */ +#define SQLPAWS 1013 /* OS Averaging window size */ +#define SQLPWKL 1014 /* Work Limit */ +#define SQLPWKA 1015 /* Work Space allocation */ +#define SQLPUSR 1016 /* Number of users */ +#define SQLPTMO 1017 /* time out */ +#define SQLPTSS 1018 /* thread stack size */ +#define SQLPTHM 1019 /* thread mode */ +#define SQLPSTC 1020 /* sortcache size in kilobytes */ +#define SQLPSIL 1021 /* silent mode */ +#define SQLPSPF 1022 /* server prefix */ +#define SQLPSVN 1024 /* server name */ +#define SQLPROM 1025 /* read-only mode (0 or 1) */ +#define SQLPSTA 1026 /* enable stats gathering */ +#define SQLPCSV 1027 /* commit server */ +#define SQLPTTP 1028 /* trace for 2PC */ +#define SQLPAJS 1029 /* ANSI join syntax */ +#define SQLPSDIR 1030 /* server module directory */ +#define SQLPSINI 1031 /* server ini file full path name */ +#define SQLPBLD 1032 /* server build number */ + +/* Database specific parameters + ---------------------------- */ + +#define SQLPDBN 2001 /* database name */ +#define SQLPDDR 2002 /* database directory */ +#define SQLPLDR 2003 /* log directory */ +#define SQLPLFS 2004 /* log file size in Kbytes */ +#define SQLPCTI 2005 /* checkpoint time interval in mins */ +#define SQLPLBM 2006 /* log backup mode? (0 or 1) */ +#define SQLPPLF 2007 /* Pre-allocate log files? (0 or 1) */ +#define SQLPTSL 2008 /* transaction span limit */ +#define SQLPROT 2009 /* read-only transactions (0, 1, 2) */ +#define SQLPHFS 2010 /* history file size in Kbytes */ +#define SQLPREC 2011 /* recovery */ +#define SQLPEXE 2012 /* name of executable */ +#define SQLPNLB 2013 /* next log to backup */ +#define SQLPROD 2014 /* read-only database (0 or 1) */ +#define SQLPEXS 2015 /* database file extension size */ +#define SQLPPAR 2016 /* partitioned database (0 or 1) */ +#define SQLPNDB 2017 /* NEWDB */ +#define SQLPLGF 2018 /* log file offset */ +#define SQLPDTL 2019 /* command timelimit */ +#define SQLPSMN 2020 /* show main db */ +#define SQLPCVC 2021 /* catalog version counter */ +#define SQLPDBS 2022 /* database block size */ +#define SQLPUED 2023 /* update external dictionary */ +#define SQLPCINI 2024 /* client ini file full path name */ + +/* Cursor specific parameters + -------------------------- */ + +#define SQLPISO 3001 /* isolation level (SQLILRR etc..) */ +#define SQLPWTO 3002 /* lock wait timeout in seconds */ +#define SQLPPCX 3003 /* preserve context (0 or 1) */ +#define SQLPFRS 3004 /* front end result sets */ +#define SQLPLDV 3005 /* load version (ex. "3.6.22") */ +#define SQLPAUT 3006 /* autocommit */ +#define SQLPRTO 3007 /* rollback trans on lock timeout */ +#define SQLPSCR 3008 /* scroll mode (0 or 1) */ +#define SQLPRES 3009 /* restriction mode (0 or 1) */ +#define SQLPFT 3010 /* fetch through */ +#define SQLPNPB 3011 /* no pre-build in RL mode */ +#define SQLPPWD 3012 /* current password */ +#define SQLPDB2 3013 /* DB2 compatibility mode */ +#define SQLPREF 3014 /* referential integrity checking */ +#define SQLPBLK 3015 /* bulk-execute mode */ +#define SQLPOBL 3016 /* optimized bulk-execute mode */ +#define SQLPLFF 3017 /* LONG data allowed in FERS */ +#define SQLPDIS 3018 /* When to return Describe info */ +#define SQLPCMP 3019 /* Compress messages sent to server */ +#define SQLPCHS 3020 /* chained cmd has SELECT (0 or 1) */ +#define SQLPOPL 3021 /* optimizer level */ +#define SQLPRID 3022 /* ROWID */ +#define SQLPEMT 3023 /* Error Message Tokens */ +#define SQLPCLN 3024 /* client name */ +#define SQLPLSS 3025 /* last compiled SQL statement */ +#define SQLPEXP 3026 /* explain query plan */ +#define SQLPCXP 3027 /* cost of execution plan */ +#define SQLPOCL 3028 /* optimizercostlevel */ +#define SQLPTST 3029 /* distributed transaction status */ +#define SQLP2PP 3030 /* 2-phase protocol (SQL2STD, etc.) */ +/* defined for Load/Unload parsed parameters - cursor specific */ +#define SQLPCLI 3031 /* ON CLIENT option */ +#define SQLPFNM 3032 /* load/unload file name */ +#define SQLPOVR 3033 /* file OVERWRITE flag */ +#define SQLPTFN 3034 /* A Temporary file name */ +#define SQLPTRC 3035 /* Trace stored procedures */ +#define SQLPTRF 3036 /* Tracefile for stored procedures */ +#define SQLPCTF 3037 /* control file flag */ + +#define SQLPMID 3038 /* mail id */ +#define SQLPAID 3039 /* adapter id */ +#define SQLPNID 3040 /* network id */ +#define SQLPUID 3041 /* user application id */ +#define SQLPCIS 3042 /* client identification strings */ +#define SQLPIMB 3043 /* input message buffer size */ +#define SQLPOMB 3044 /* output message buffer size */ +#define SQLPWFC 3045 /* which fetchable command */ +#define SQLPRFE 3046 /* Return on First Error-bulk insert */ +#define SQLPCUN 3047 /* Current cursor user name */ +#define SQLPOFF 3048 /* Optimize First Fetch */ +#define SQLPUSC 3049 /* Use Specified Cursor for ref */ +#define SQLPPDG 3050 /* Plan Debug */ + +/* Application Specific ie. applicable to all cursors that + belong to the same application (3700 - 3799) */ + +#define SQLPCCB 3700 /* Connect Closure Behaviour */ +#define SQLPTTV 3701 /* Thread Timeout Value */ + +/* Static attributes + -------------------------- */ + +#define SQLPFAT 4000 /* first attribute */ +#define SQLPBRS 4001 /* back end result sets */ +#define SQLPMUL 4002 /* multi-user */ +#define SQLPDMO 4003 /* demonstration version */ +#define SQLPLOC 4004 /* local version of database */ +#define SQLPFPT 4005 /* 1st participant */ +#define SQLPLAT 4006 /* last attribute */ +#define SQLPCAP 4007 /* API capability level */ +#define SQLPSCL 4008 /* server capability level */ +#define SQLPRUN 4009 /* runtime version */ + +/* Server specific parameters + ---------------------------- */ + +#define SQLPPLV 5001 /* print level */ +#define SQLPALG 5002 /* activity log */ +#define SQLPTMS 5003 /* time stamp */ +#define SQLPPTH 5004 /* path name seperator */ +#define SQLPTMZ 5005 /* time zone */ +#define SQLPTCO 5006 /* time colon only */ + +/* SQL Server & Router/Gateway specific parameters + ------------------------------ */ +#define SQLPESTR 5101 /* get server error # and string */ +#define SQLPMSTR 5102 /* get server msg# and string */ +#define SQLPMAPC 5103 /* MapGTICursors */ +#define SQLPUPRE 5104 /* get user prefix */ +#define SQLPORID 5105 /* Oracle RowID */ +#define SQLPERRM 5106 /* error mapping */ +#define SQLPRTS 5107 /* SQL Server - Return Status */ +#define SQLPSAUT 5108 /* SQL Server - Autocommit */ +#define SQLPROW 5109 /* SQL Server - Command Type */ +#define SQLPEHC 5110 /* SQL Server - Enhanced Cursors */ +#define SQLPGFS 5111 /* SQL Server - Get Fetch Status */ +#define SQLPLBUF 5112 /* Longbuffer setting */ +#define SQLPDPH 5113 /* SQL Server - DBProcess handle */ +#define SQLPCKE 5114 /* SQL Server - CHECK EXISTS */ +#define SQLPWTX 5115 /* SQL Server - DBWRITETEXT */ +#define SQLPYLD 5116 /* SQL Server - YieldOnServerCall */ +#define SQLPOBN 5117 /* ODBC Router - backend brand */ +#define SQLPOBV 5118 /* ODBC Router - backend version */ +#define SQLPODN 5119 /* ODBC Router - driver name */ +#define SQLPODV 5120 /* ODBC Router - driver version */ +#define SQLPOCV 5121 /* ODBC Router - ODBC version */ +#define SQLPRSYS 5122 /* DRDA - EXEC SQL CONNECT TO remote system name */ +#define SQLPLAB 5123 /* DB2 - return label information if exists */ +#define SQLPCID 5124 /* DB2 - Set Current SQLID default */ +#define SQLPNUMST 5125 /* AS/400 Number of Statements */ +#define SQLPBNDRW 5126 /* Oracle- bind SQLPBUF as RAW */ +#define SQLPNLS 5127 /* Informix - NLS database */ + +#define SQLPFRW 5200 /* fetchrow */ +#define SQLPBRW 5201 /* buffrow */ + +/* Sybase System 10 parameters (reserved 5220 - 5250) + ------------------------------------------------------------ */ + +#define SQLPNESTR 5220 /* SYB - get next error from client */ +#define SQLPNMSTR 5221 /* SYB - get next error from server */ +#define SQLPCESTR 5222 /* SYB - get client message count */ +#define SQLPCMSTR 5223 /* SYB - get server message count */ +#define SQLPTXT 5224 /* SYB - allow bind for text, image */ +#define SQLPEMC 5225 /* SYB - enable multiple connections */ + +/* ODBC specific parameters - Refer to ODBC spec for definition + ------------------------------------------------------------ */ + +#define SQLP_ACTIVE_CONNECTIONS 5500 +#define SQLP_ACTIVE_STATEMENTS 5501 +#define SQLP_DATA_SOURCE_NAME 5502 +#define SQLP_DRIVER_HDBC 5503 +#define SQLP_DRIVER_HENV 5504 +#define SQLP_DRIVER_HSTMT 5505 +#define SQLP_DRIVER_NAME 5506 +#define SQLP_DRIVER_VER 5507 +#define SQLP_FETCH_DIRECTION 5508 +#define SQLP_ODBC_API_CONFORMANCE 5509 +#define SQLP_ODBC_VER 5510 +#define SQLP_ROW_UPDATES 5511 +#define SQLP_ODBC_SAG_CLI_CONFORMANCE 5512 +#define SQLP_SERVER_NAME 5513 +#define SQLP_SEARCH_PATTERN_ESCAPE 5514 +#define SQLP_ODBC_SQL_CONFORMANCE 5515 +#define SQLP_DATABASE_NAME 5516 +#define SQLP_DBMS_NAME 5517 +#define SQLP_DBMS_VER 5518 +#define SQLP_ACCESSIBLE_TABLES 5519 +#define SQLP_ACCESSIBLE_PROCEDURES 5520 +#define SQLP_PROCEDURES 5521 +#define SQLP_CONCAT_NULL_BEHAVIOUR 5522 +#define SQLP_CURSOR_COMMIT_BEHAVIOUR 5523 +#define SQLP_CURSOR_ROLLBACK_BEHAVIOUR 5524 +#define SQLP_DATA_SOURCE_READ_ONLY 5525 +#define SQLP_DEFAULT_TXN_ISOLATION 5526 +#define SQLP_EXPRESSIONS_IN_ORDERBY 5527 +#define SQLP_IDENTIFIER_CASE 5528 +#define SQLP_IDENTIFIER_QUOTE_CHAR 5529 +#define SQLP_MAX_COLUMN_NAME_LEN 5530 +#define SQLP_MAX_CURSOR_NAME_LEN 5531 +#define SQLP_MAX_OWNER_NAME_LEN 5532 +#define SQLP_MAX_PROCEDURE_NAME_LEN 5533 +#define SQLP_MAX_QUALIFIER_NAME_LEN 5534 +#define SQLP_MAX_TABLE_NAME_LEN 5535 +#define SQLP_MULT_RESULT_SETS 5536 +#define SQLP_MULTIPLE_ACTIVE_TXN 5537 +#define SQLP_OUTER_JOINS 5538 +#define SQLP_OWNER_TERM 5539 +#define SQLP_PROCEDURE_TERM 5540 +#define SQLP_QUALIFIER_NAME_SEPARATOR 5541 +#define SQLP_QUALIFIER_TERM 5542 +#define SQLP_SCROLL_CONCURRENCY 5543 +#define SQLP_SCROLL_OPTIONS 5544 +#define SQLP_TABLE_TERM 5545 +#define SQLP_TXN_CAPABLE 5546 +#define SQLP_USER_NAME 5547 +#define SQLP_CONVERT_FUNCTIONS 5548 +#define SQLP_NUMERIC_FUNCTIONS 5549 +#define SQLP_STRING_FUNCTIONS 5550 +#define SQLP_SYSTEM_FUNCTIONS 5551 +#define SQLP_TIMEDATE_FUNCTIONS 5552 +#define SQLP_CONVERT_BIGINT 5553 +#define SQLP_CONVERT_BINARY 5554 +#define SQLP_CONVERT_BIT 5555 +#define SQLP_CONVERT_CHAR 5556 +#define SQLP_CONVERT_DATE 5557 +#define SQLP_CONVERT_DECIMAL 5558 +#define SQLP_CONVERT_DOUBLE 5559 +#define SQLP_CONVERT_FLOAT 5560 +#define SQLP_CONVERT_INTEGER 5561 +#define SQLP_CONVERT_LONGVARCHAR 5562 +#define SQLP_CONVERT_NUMERIC 5563 +#define SQLP_CONVERT_REAL 5564 +#define SQLP_CONVERT_SMALLINT 5565 +#define SQLP_CONVERT_TIME 5566 +#define SQLP_CONVERT_TIMESTAMP 5567 +#define SQLP_CONVERT_TINYINT 5568 +#define SQLP_CONVERT_VARBINARY 5569 +#define SQLP_CONVERT_VARCHAR 5570 +#define SQLP_CONVERT_LONGVARBINARY 5571 +#define SQLP_TXN_ISOLATION_OPTION 5572 +#define SQLP_ODBC_SQL_OPT_IEF 5573 + +/*** ODBC SDK 1.0 Additions ***/ +#define SQLP_CORRELATION_NAME 5574 +#define SQLP_NON_NULLABLE_COLUMNS 5575 + +/*** ODBC SDK 2.0 Additions ***/ +#define SQLP_DRIVER_HLIB 5576 +#define SQLP_DRIVER_ODBC_VER 5577 +#define SQLP_LOCK_TYPES 5578 +#define SQLP_POS_OPERATIONS 5579 +#define SQLP_POSITIONED_STATEMENTS 5580 +#define SQLP_GETDATA_EXTENSIONS 5581 +#define SQLP_BOOKMARK_PERSISTENCE 5582 +#define SQLP_STATIC_SENSITIVITY 5583 +#define SQLP_FILE_USAGE 5584 +#define SQLP_NULL_COLLATION 5585 +#define SQLP_ALTER_TABLE 5586 +#define SQLP_COLUMN_ALIAS 5587 +#define SQLP_GROUP_BY 5588 +#define SQLP_KEYWORDS 5589 +#define SQLP_ORDER_BY_COLUMNS_IN_SELECT 5590 +#define SQLP_OWNER_USAGE 5591 +#define SQLP_QUALIFIER_USAGE 5592 +#define SQLP_QUOTED_IDENTIFIER_CASE 5593 +#define SQLP_SPECIAL_CHARACTERS 5594 +#define SQLP_SUBQUERIES 5595 +#define SQLP_UNION 5596 +#define SQLP_MAX_COLUMNS_IN_GROUP_BY 5597 +#define SQLP_MAX_COLUMNS_IN_INDEX 5598 +#define SQLP_MAX_COLUMNS_IN_ORDER_BY 5599 +#define SQLP_MAX_COLUMNS_IN_SELECT 5600 +#define SQLP_MAX_COLUMNS_IN_TABLE 5601 +#define SQLP_MAX_INDEX_SIZE 5602 +#define SQLP_MAX_ROW_SIZE_INCLUDES_LONG 5603 +#define SQLP_MAX_ROW_SIZE 5604 +#define SQLP_MAX_STATEMENT_LEN 5605 +#define SQLP_MAX_TABLES_IN_SELECT 5606 +#define SQLP_MAX_USER_NAME_LEN 5607 +#define SQLP_MAX_CHAR_LITERAL_LEN 5608 +#define SQLP_TIMEDATE_ADD_INTERVALS 5609 +#define SQLP_TIMEDATE_DIFF_INTERVALS 5610 +#define SQLP_NEED_LONG_DATA_LEN 5611 +#define SQLP_MAX_BINARY_LITERAL_LEN 5612 +#define SQLP_LIKE_ESCAPE_CLAUSE 5613 +#define SQLP_QUALIFIER_LOCATION 5614 + +#define SQLP_GET_TYPE_INFO 5699 + + +/* The following parmeters in the range 6000 - 7000 are reserved for + SQLBase INTERNAL use. +*/ + +#define SQLP000 6000 /* for internal use only */ +#define SQLP999 6999 /* for internal use only */ +#define SQLPITP 0x4000 /* INTERNAL USE ONLY */ +#define SQLPITC 0x8000 /* INTERNAL USE ONLY */ + +/* end of SET and GET PARAMETER TYPES */ + + +/* defines for ON, OFF, DEFAULT parameter values */ + +#define SQLVOFF 0 /* parameter should be OFF */ +#define SQLVON 1 /* parameter should be ON */ +#define SQLVDFL 2 /* parameter should default */ + +/* defines for SQLPDBM (db mode) */ + +#define SQLMDBL 1 /* DB Local */ +#define SQLMRTR 2 /* DB Router */ +#define SQLMCOM 3 /* DB Combo */ + +/* defines for database brands */ + +#define SQLBSQB 1 /* SQLBASE */ +#define SQLBDB2 2 /* DB2 */ +#define SQLBDBM 3 /* IBM OS/2 Database Manager */ +#define SQLBORA 4 /* Oracle */ +#define SQLBIGW 5 /* Informix */ +#define SQLBNTW 6 /* Netware SQL */ +#define SQLBAS4 7 /* IBM AS/400 SQL/400 */ +#define SQLBSYB 8 /* Sybase SQL Server */ +#define SQLBDBC 9 /* Teradata DBC Machines */ +#define SQLBALB 10 /* HP Allbase */ +#define SQLBRDB 11 /* DEC's RDB */ +#define SQLBTDM 12 /* Tandem's Nonstop SQL */ +#define SQLBSDS 13 /* IBM SQL/DS */ +#define SQLBSES 14 /* SNI SESAM */ +#define SQLBING 15 /* Ingres */ +#define SQLBSQL 16 /* SQL Access */ +#define SQLBDBA 17 /* DBase */ +#define SQLBDB4 18 /* SNI DDB4 */ +#define SQLBFUJ 19 /* Fujitsu RDBII */ +#define SQLBSUP 20 /* Cincom SUPRA */ +#define SQLB204 21 /* CCA Model 204 */ +#define SQLBDAL 22 /* Apple DAL interface */ +#define SQLBSHR 23 /* Teradata ShareBase */ +#define SQLBIOL 24 /* Informix On-Line */ +#define SQLBEDA 25 /* EDA/SQL */ +#define SQLBUDS 26 /* SNI UDS */ +#define SQLBMIM 27 /* Nocom Mimer */ +#define SQLBOR7 28 /* Oracle version 7 */ +#define SQLBIOS 29 /* Ingres OpenSQL */ +#define SQLBIOD 30 /* Ingres OpenSQL with date support */ +#define SQLBODB 31 /* ODBC Router */ +#define SQLBS10 32 /* SYBASE System 10 */ +#define SQLBSE6 33 /* Informix SE version 6 */ +#define SQLBOL6 34 /* Informix On-Line version 6 */ +#define SQLBNSE 35 /* Informix SE NLS version 6 */ +#define SQLBNOL 36 /* Informix On-Line NLS version 6 */ +#define SQLBSE7 37 /* Informix SE version 7 */ +#define SQLBOL7 38 /* Informix On-Line version 7 */ +#define SQLBETA 39 /* Entire Access, ADABAS */ +#define SQLBI12 40 /* Ingres CA-OpenIngres 1.2 */ +#define SQLBAPP 99 /* SQLHost App Services */ + +/* SIZES */ +#define SQLSNUM 12 /* numeric program buffer size */ +#define SQLSDAT 12 /* date-time program buffer size */ +#define SQLSCDA 26 /* character date-time size */ +#define SQLSDTE SQLSDAT /* date (only) program buffer size */ +#define SQLSCDE 10 /* character date (only) size */ +#define SQLSRID 40 /* size of ROWID */ +#define SQLSTIM SQLSDAT /* time (only) program buffer size */ +#define SQLSCTI 15 /* character time (only) size */ +#define SQLSFEM 100L /* file extension size (multi-user) */ +#define SQLSFES 20L /* file extension size (single-user) */ +#define SQLSTEX 5L /* table extent size */ + + +/* Two-phase Commit Protocols */ + +typedef int SQLT2PP; /* type: 2-phase commit protocol */ + +#define SQL2MIN SQL2STD /* minimum protocol value */ + +#define SQL2STD ((SQLT2PP) 1) /* standard 2pc protocol */ +#define SQL2PRA ((SQLT2PP) 2) /* presumed-abort 2pc protocol */ +#define SQL2PRC ((SQLT2PP) 3) /* presumed-commit 2pc protocol */ +#define SQL2DEF SQL2STD /* default is standard */ + +#define SQL2MAX SQL2PRC /* maximum protocol value */ + +/* Two-phase Commit Votes */ + +typedef int SQLT2PV; /* type: 2-phase commit vote */ + +#define SQLVMIN SQLVCMT /* minimum vote value */ + +#define SQLVCMT ((SQLT2PV) 1) /* Vote Commit */ +#define SQLVRBK ((SQLT2PV) 2) /* Vote Rollback */ +#define SQLVRO ((SQLT2PV) 3) /* Vote ReadOnly */ + +#define SQLVMAX SQLVRO /* maximum vote value */ + +/* defines for distributed transaction status */ + +typedef int SQLTTST; /* distributed transaction state */ + +#define SQLSCMT ((SQLTTST) 1) /* transaction state = COMMITted */ +#define SQLSRBK ((SQLTTST) 2) /* transaction state = ROLLBACKed */ +#define SQLSUNK ((SQLTTST) 3) /* transaction state = UNKNOWN */ + + +/* NULL POINTER */ +#define SQLNPTR (ubyte1 PTR)0 /* null pointer */ +/* RESULT COMMAND TYPES */ +#define SQLTSEL 1 /* select */ +#define SQLTINS 2 /* insert */ +#define SQLTCTB 3 /* create table */ +#define SQLTUPD 4 /* update */ +#define SQLTDEL 5 /* delete */ +#define SQLTCIN 6 /* create index */ +#define SQLTDIN 7 /* drop index */ +#define SQLTDTB 8 /* drop table */ +#define SQLTCMT 9 /* commit */ +#define SQLTRBK 10 /* rollback */ +#define SQLTACO 11 /* add column */ +#define SQLTDCO 12 /* drop column */ +#define SQLTRTB 13 /* rename table */ +#define SQLTRCO 14 /* rename column */ +#define SQLTMCO 15 /* modify column */ +#define SQLTGRP 16 /* grant privilege on table */ +#define SQLTGRD 17 /* grant dba */ +#define SQLTGRC 18 /* grant connect */ +#define SQLTGRR 19 /* grant resource */ +#define SQLTREP 20 /* revoke privilege on table */ +#define SQLTRED 21 /* revoke dba */ +#define SQLTREC 22 /* revoke connect */ +#define SQLTRER 23 /* revoke resource */ +#define SQLTCOM 24 /* comment on */ +#define SQLTWAI 25 /* wait */ +#define SQLTPOS 26 /* post */ +#define SQLTCSY 27 /* create synonym */ +#define SQLTDSY 28 /* drop synonym */ +#define SQLTCVW 29 /* create view */ +#define SQLTDVW 30 /* drop view */ +#define SQLTRCT 31 /* row count */ +#define SQLTAPW 32 /* alter password */ +#define SQLTLAB 33 /* label on */ +#define SQLTCHN 34 /* chained command */ +#define SQLTRPT 35 /* repair table */ +#define SQLTSVP 36 /* savepoint */ +#define SQLTRBS 37 /* rollback to savepoint */ +#define SQLTUDS 38 /* update statistics */ +#define SQLTCDB 39 /* check database */ +#define SQLTFRN 40 /* foreign DBMS commands */ +#define SQLTAPK 41 /* add primary key */ +#define SQLTAFK 42 /* add foreign key */ +#define SQLTDPK 43 /* drop primary key */ +#define SQLTDFK 44 /* drop foreign key */ +/* SERVER COMMAND TYPES */ +#define SQLTCDA 45 /* create dbarea */ +#define SQLTADA 46 /* alter dbarea */ +#define SQLTDDA 47 /* delete dbarea */ +#define SQLTCSG 48 /* create stogroup */ +#define SQLTASG 49 /* alter stogroup */ +#define SQLTDSG 50 /* delete stogroup */ +#define SQLTCRD 51 /* create database */ +#define SQLTADB 52 /* alter database */ +#define SQLTDDB 53 /* delete database */ +#define SQLTSDS 54 /* set default stogroup */ +#define SQLTIND 55 /* install database */ +#define SQLTDED 56 /* de-install database */ +/* END OF SERVER COMMAND TYPES */ + +#define SQLTARU 57 /* add RI user error */ +#define SQLTDRU 58 /* drop RI user error */ +#define SQLTMRU 59 /* modify RI user error */ +#define SQLTSCL 60 /* set client */ +#define SQLTCKT 61 /* check table */ +#define SQLTCKI 62 /* check index */ +#define SQLTOPL 63 /* PL/SQL Stored Procedure */ +#define SQLTBGT 64 /* BEGIN TRANSACTION */ +#define SQLTPRT 65 /* PREPARE TRANSACTION */ +#define SQLTCXN 66 /* COMMIT TRANSACTION */ +#define SQLTRXN 67 /* ROLLBACK TRANSACTION */ +#define SQLTENT 68 /* END TRANSACTION */ + +/* COMMIT SERVER COMMAND TYPES */ +#define SQLTCBT 69 /* begin transaction */ +#define SQLTCCT 70 /* commit transaction */ +#define SQLTCET 71 /* end transaction */ +#define SQLTCPT 72 /* prepare transaction */ +#define SQLTCRT 73 /* rollback transaction */ +#define SQLTCST 74 /* status transaction */ +#define SQLTCRX 75 /* reduce transaction */ +#define SQLTCSD 76 /* start daemon */ +#define SQLTCTD 77 /* stop daemon */ +#define SQLTCRA 78 /* resolve all transactions */ +#define SQLTCRO 79 /* resolve one transaction */ +#define SQLTCOT 80 /* orphan a transaction */ +#define SQLTCFL 81 /* CREATE FAILURE */ +#define SQLTDFL 82 /* DELETE FAILURE */ +#define SQLTSTN 83 /* SET TRACETWOPC ON */ +#define SQLTSTF 84 /* SET TRACETWOPC OFF */ +#define SQLTUNL 85 /* Unload command */ +#define SQLTLDP 86 /* load command */ +#define SQLTPRO 87 /* stored procedure */ +#define SQLTGEP 88 /* grant execute privilege */ +#define SQLTREE 89 /* revoke execute privilege */ +#define SQLTTGC 90 /* create trigger */ +#define SQLTTGD 91 /* drop trigger */ +#define SQLTVNC 92 /* create event */ +#define SQLTVND 93 /* drop event */ +#define SQLTSTR 94 /* start audit */ +#define SQLTAUD 95 /* audit message */ +#define SQLTSTP 96 /* stop audit */ +#define SQLTACM 97 /* Alter CoMmand */ +#define SQLTXDL 98 /* lock database */ +#define SQLTXDU 99 /* unlock database */ +#define SQLTCEF 100 /* create external function */ +#define SQLTDEF 101 /* drop external function */ +#define SQLTDBT 102 /* DBATTRIBUTE */ +#define SQLTATG 103 /* ALTER TRIGGER */ +#define SQLTAEF 104 /* alter external function */ +#define SQLTADS 105 /* alter database security */ +#define SQLTAEK 106 /* alter exportkey */ +#define SQLTASP 107 /* alter server */ + +/* DEFAULTS */ +#define SQLDCGP 30 /* CACHEGROUP, cache page allocation group */ +#define SQLDCRT 5 /* CONNECTRETRY, seconds for connect timeout */ +#define SQLDCPT 10 /* CONNECTPAUSETICKS, ticks for pausing */ +#define SQLDDGH 10000l /* HEAP, DBGATEWY heap size */ +#define SQLDDLH 145000l /* HEAP, DBLOCAL heap size */ +#define SQLDDRH 20000l /* HEAP, DBROUTER heap size */ +#define SQLDNTN 71 /* INTERRUPT, interrupt number */ +#define SQLDNBS 30000 /* NETBUFFER, size DBXROUTR network buffer */ +#define SQLDRET 3 /* RETRY, number of connect retries */ +#define SQLDSVS 0X8000 /* STACKSIZE, DBSERVER stack */ +#define SQLDSMS 0X8000 /* STACKSIZE, DBSIM stack */ +#define SQLDSRS 7000 /* STACKSIZE, DBSIM w/router stack */ +#define SQLDTMZ 0l /* TIMEZONE */ +#define SQLDSVU 128 /* USERS, DBSERVER users */ +#define SQLDSMU 3 /* USERS, DBSIM users */ +#define SQLDCLI 1024000L /* checkpoint log interval in bytes */ +#define SQLDCTI 1 /* checkpt time interval in minutes */ +#define SQLDWSA 1000 /* cursor work space allocation */ +#define SQLDPRE 5 /* decimal precision */ +#define SQLDSCA 0 /* decimal scale */ +#define SQLDIML 2000 /* input message buffer length */ +#define SQLDPRI 10 /* integer precision */ +#define SQLDSUL 6 /* length of system user name */ +#define SQLDLBS 20480 /* log buffer size in bytes */ +#define SQLDLFS 1024000L /* log file size in bytes */ +#define SQLDSLS 15 /* maximum # of large server stacks */ +#define SQLDHFS 1000 /* maximum history file size */ +#define SQLDLPM 20000 /* maximum number of rollback log pages */ +#define SQLDNES 100 /* normal file extension size */ +#define SQLDOML 1000 /* output message buffer length */ +#define SQLDPES 1024 /* partitioned file extension size */ +#define SQLDPUB "PUBLIC" /* public user name */ +#define SQLDLPT 16000 /* rollback log page threshold */ +#define SQLDPRS 5 /* smallint precision */ +#define SQLDRTO 5 /* default response time out */ +#define SQLDSUN "SYSADM" /* system default username */ +#define SQLDESC "$$" /* connect escape sequence */ +#define SQLDSUN "SYSADM" /* system default username */ +#define SQLDNTG 16 /* number of triggers allowed per event/time/scope */ + /* Maximum triggers for an event is * 4 */ + +/* MAXIMUM SIZES */ +#define SQLMSBNL 18 /* short bind name length */ +#define SQLMBNL 36 /* bind name length */ +#define SQLMLBNL 64 /* long bind name length */ +#define SQLMBSL 32000 /* max length Backend string literal */ +#define SQLMCG1 32767 /* cache group pages */ +#define SQLMCKF 16 /* concatenated key fields */ +#define SQLMCLL 255 /* clientlimit */ +#define SQLMCLN 12 /* maximum client name size */ +#define SQLMCLP 128 /* commmand line parameter length */ +#define SQLMCMT 106 /* max command types */ +#define SQLMCNM SQLMBNL /* max referential constraint name */ +#define SQLMCOH 255 /* column heading string */ +#define SQLMCST 400 /* max connect string length */ +#define SQLMDBA 10 /* number of databases accessed */ +#define SQLMDFN 25 /* database file name */ +#define SQLMPSS 25 /* process status string */ +#define SQLMDMO 750 /* maximum DB size for demos (Kbytes) */ +#define SQLMSDNM 8 /* database name CAM_1..4_VERSION */ +#define SQLMDNM 16 /* database name */ +#define SQLMDVL 254 /* data value length */ +#define SQLMERR 255 /* error message length */ +#define SQLMETX 3000 /* error text length */ +/* ------------------------------------------------------------------------- * + * We are reverting back to the previous value of 128 for SQLMFNL because it * + * is resulting in unnecessary complications in the cdm, aic size etc. * + * ------------------------------------------------------------------------- */ +#define SQLMFNL 128 /* filename length */ + +/* ------------------------------------------------------------------------- * + * Note : We are defining a new constant called SQLRFNL which is used to * + * create a filename of restricted length (128) instead of SQLMFNL. It is * + * required because the areas table created by main.ini uses a pathname of * + * 128 bytes * + * ------------------------------------------------------------------------- */ +#define SQLRFNL 128 +#define SQLMFQN 3 /* number of fields in fully qualified column name */ +#define SQLMFRD 40 /* maximum size of foreign result set directory */ +#define SQLMGCM 32767 /* maximum group commit count */ +#define SQLMICO 255 /* installed cache page owners */ +#define SQLMICU 255 /* installed cursors */ +#define SQLMIDB 255 /* installed databases */ +#define SQLMILK 32767 /* installed locks */ +#define SQLMINL 2000 /* input length */ +#define SQLMIPG 1000000 /* installed pages */ +#define SQLMIPR 800 /* installed processes */ +#define SQLMITR 800 /* installed transactions */ +#define SQLMJTB 17 /* joined tables */ +#define SQLMTAC 17*16 /* tables each tab can have subsel */ +#define SQLMLID 32 /* long identifiers */ +#define SQLMNBF 60000 /* network buffer size */ +#define SQLMNCO 254 /* number of columns per row */ +#define SQLMUCO 253 /* number of user columns available */ +#define SQLMNPF 3 /* NETPREFIX size */ +#define SQLMOUL 1000 /* output length */ +#define SQLMPAL 255 /* max path string length */ +#define SQLMSVP 1024 /* max serverpath (inside ini client section) string length */ +#define SQLMPFS 21 /* max platform string length */ +#define SQLMPKL 254 /* max primary key length */ +#define SQLMPRE 15 /* maximum decimal precision */ +#define SQLMPTL 4 /* maximum print level */ +#define SQLMPWD 128 /* maximum password length */ +#define SQLMCTL 43200 /* max query timelimit (12 hours) */ +#define SQLMRBB 8192 /* maximum rollback log buffer */ +#define SQLMRCB 20480 /* maximum recovery log buffer */ +#define SQLMRET 1000 /* retry count */ +#define SQLMRFH 4 /* maximum # remote file handles */ +#define SQLMROB 8192 /* max size of restore output buffer */ +#define SQLMSES 16 /* number of sessions */ +#define SQLMSID 8 /* short identifiers */ +#define SQLMSLI 255 /* max number of select list exprs. */ +#define SQLMSNM 8 /* server name */ +#define SQLMSRL 32 /* max length of SQL reserved word */ +#define SQLMSVN 199 /* maximum server names */ +#define SQLMTFS 10 /* maximum temporary file size */ +#define SQLMTMO 200 /* maximum timeout */ +#define SQLMTSS 256 /* text string space size */ +#define SQLMUSR 128 /* maximum username length */ +#define SQLMVER 8 /* max version string (nn.nn.nn) */ +#define SQLMXER 255 /* Extended error message length */ +#define SQLMXFS 2147483648UL /* max file size in bytes */ +#define SQLMXLF 2097152 /* max log file size in KB */ +#define SQLMTHM 2 /* maximum thread mode value */ +#define SQLMPKL 254 /* max primary key length */ +#define SQLMGTI 250 /* max global transaction-id length */ +#define SQLMAUF 32 /* max concurrent audit files */ +#define SQLMPNM 8 /* max protocol name length */ +#define SQLMOSR 255 /* max OS sample rate */ +#define SQLMAWS 255 /* max OS Averaging window size */ +#define SQLMMID 32 /* max length identificatin strings */ + +/* MINIMUMS */ +#define SQLMCG0 1 /* cache group pages */ +#define SQLMEXS 1024 /* partitioned file extension size */ +#define SQLMLFE 100000L /* minimum log file extension size */ +#define SQLMLFS 100000L /* minimum log file size */ +#define SQLMPAG 15 /* minimum pages (cache) */ +#define SQLMITM 1 /* minimum thread mode value */ + +/* typedefs */ +#if defined(WIN32) || defined(SYSFWNT) + #ifndef SQLFI64 + #define SQLFI64 + typedef __int64 b8; /* 64-bits signed */ + typedef unsigned __int64 ub8; /* 64-bits unsigned */ + #endif + +#else + #ifndef SQLFI64 + #define SQLFI64 + typedef struct { + unsigned long LoPart; + unsigned long HiPart; + } ub8; + typedef struct { + unsigned long LoPart; + long HiPart; + } b8; + #endif + +#endif + +typedef unsigned char ubyte1; +typedef unsigned short ubyte2; +typedef unsigned long ubyte4; +typedef ub8 ubyte8; +typedef ubyte1 byte1; +typedef short byte2; +typedef long byte4; +typedef b8 byte8; +typedef unsigned char PTR ubyte1p; +typedef int (SBSTDCALL *SQLTPFP)(void); + +typedef ubyte1 SQLTARC; /* remote connection architecture */ +typedef ubyte1 SQLTBNL; /* bind name length */ +typedef ubyte1 SQLTBNN; /* bind number */ +typedef ubyte1p SQLTBNP; /* bind name pointer */ +typedef byte2 SQLTNUL; /* null indicator */ +typedef ubyte1 SQLTBOO; /* boolean data type */ +typedef ubyte1 SQLTCDL; /* column data length */ +typedef ubyte1 SQLTCHL; /* column header length */ +typedef ubyte1 SQLTCHO; /* check option */ +typedef ubyte1p SQLTCHP; /* column header pointer */ +typedef ubyte2 SQLTCLL; /* column data length(long) */ +typedef ubyte1 SQLTCTY; /* command type */ +typedef ubyte2 SQLTCUR; /* cursor number */ +typedef ubyte2 SQLTDAL; /* data length */ +typedef ubyte1p SQLTDAP; /* data pointer */ +typedef byte2 SQLTDAY; /* number of days */ +typedef ubyte1 SQLTDDL; /* database data length */ +typedef ubyte1 SQLTDDT; /* database data type */ +typedef ubyte2 SQLTDEDL; /* database extended data length */ +typedef ubyte2 SQLTDPT; /* database parameter type */ +typedef ubyte4 SQLTDPV; /* database parameter value */ +typedef ubyte2 SQLTEPO; /* error position */ +typedef ubyte2 SQLTFAT; /* file attribute */ +typedef ubyte2 SQLTFLD; /* SELECT statement field number */ +typedef byte2 SQLTFLG; /* flag field */ +typedef ubyte4 SQLTFLH; /* file handle */ +typedef byte2 SQLTFMD; /* file mode */ +typedef ubyte2 SQLTFNL; /* file name length */ +typedef ubyte1p SQLTFNP; /* file name pointer */ +typedef ubyte1 SQLTFSC; /* fetch status code */ +typedef ubyte1p SQLTILV; /* isolation level string */ +typedef ubyte1 SQLTLBL; /* label information length */ +typedef ubyte1p SQLTLBP; /* label infromation pointer */ +typedef byte8 SQLTLLI; /* long long integer */ +typedef byte4 SQLTLNG; /* long size */ +typedef ubyte4 SQLTLSI; /* long size */ +typedef ubyte2 SQLTMSZ; /* message size */ +typedef ubyte1 SQLTNBV; /* number of bind variables */ +typedef ubyte2 SQLTNCU; /* number of cursors */ +typedef ubyte1 SQLTNML; /* number length */ +typedef ubyte1p SQLTNMP; /* number pointer */ +typedef ubyte2 SQLTNPG; /* number of pages */ +typedef ubyte4 SQLTLNPG; /* number of pages */ +typedef ubyte1 SQLTNSI; /* number of select items */ +typedef ubyte1 SQLTPCX; /* preserve context flag */ +typedef ubyte1 SQLTPDL; /* program data length */ +typedef ubyte1 SQLTPDT; /* program data type */ +typedef ubyte4 SQLTPGN; /* page number */ +typedef ubyte2 SQLTPNM; /* process number */ +typedef ubyte1 SQLTPRE; /* precision */ +typedef ubyte2 SQLTPTY; /* set/get parameter type */ +typedef ubyte1 SQLTRBF; /* roll back flag */ +typedef byte2 SQLTRCD; /* return codes */ +typedef ubyte1 SQLTRCF; /* recovery flag */ +typedef ubyte2 SQLTRFM; /* rollforward mode */ +typedef byte4 SQLTROW; /* number of rows */ +typedef ubyte1 SQLTSCA; /* scale */ +typedef ubyte1 SQLTSLC; /* select list column */ +typedef ubyte2 SQLTSTC; /* statistics counter */ +typedef ubyte2 SQLTSVH; /* server handle */ +typedef ubyte2 SQLTSVN; /* server number */ +typedef byte2 SQLTTIV; /* wait timeout value */ +typedef byte2 SQLTWNC; /* whence */ +typedef ubyte2 SQLTWSI; /* work size */ +typedef ubyte2 SQLTBIR; /* bulk insert error row number */ +typedef ubyte1p SQLTDIS; /* Describe info indicator */ +typedef byte4 SQLTXER; /* extended error # */ +typedef ubyte4 SQLTPID; /* client process id */ +typedef ubyte4 SQLTMOD; /* mode flag */ +typedef ubyte4 SQLTCON; /* connection handle */ + +/* defines for isolation level string */ +#define SQLILRR "RR" /* Repeatable Read isolation */ +#define SQLILCS "CS" /* Cursor Stability isolation */ +#define SQLILRO "RO" /* Read-Only isolation */ +#define SQLILRL "RL" /* Release Locks isolation */ +/* defines for isolation level flags*/ +#define SQLFIRR 0x01 /* Repeatable Read isolation flag */ +#define SQLFICS 0x02 /* Cursor Stability isolation flag */ +#define SQLFIRO 0x04 /* Read-Only isolation flag */ +#define SQLFIRL 0x08 /* Release Locks isolation flag */ +/* defines for SQLROF rollforward mode parameter */ +#define SQLMEOL 1 /* rollforward to end of log */ +#define SQLMEOB 2 /* rollforward to end of backup */ +#define SQLMTIM 3 /* rollforward to specified time */ +/* defines for when to collect Describe information */ +#define SQLDELY 0 /* get Describe info after sqlcom */ +#define SQLDDLD 1 /* get Describe info after sqlexe */ +#define SQLDNVR 2 /* never get any Describe info */ +/* defines for SQLETX() and SQLTEM(): error text type parameters */ +#define SQLXMSG 1 /* retrieve error message text */ +#define SQLXREA 2 /* retrieve error message reason */ +#define SQLXREM 4 /* retrieve error message remedy */ + +/* defines for extended directory open function */ +#define SQLANRM 0x00 /* normal - no restrictions */ +#define SQLARDO 0x01 /* read only */ +#define SQLAHDN 0x02 /* hidden file */ +#define SQLASYS 0x04 /* system file */ +#define SQLAVOL 0x08 /* volume label */ +#define SQLADIR 0x10 /* directory */ +#define SQLAARC 0x20 /* archive bit */ +#define SQLAFDL 0x100 /* files and directories */ +#define SQLAFIL 0x200 /* files only */ + +/* defines for state of cursor */ +#define SQLCIDL 0 /* idle cursor */ +#define SQLCECM 1 /* executing compile */ +#define SQLCCCM 2 /* completed compile */ +#define SQLCEXE 3 /* executing command */ +#define SQLCCXE 4 /* completed command */ +#define SQLCEFT 5 /* executing fetch */ +#define SQLCCFT 6 /* completed fetch */ +/* SYSTEM DEFINED TYPEDEF'S -- FOR SYSTEM USE ONLY */ + +typedef ubyte2 SQLTMSL; /* message length */ +typedef byte1 far* SQLTMSP; /* message pointer */ + +/* +DESCRIPTION + This structure is used to receive system information from the + backend. Structure elements must be arranged so that the structure + layout is the same in packed or padded compilation modes. For + now, this means longs in the front, ints in the middle, and chars at + the end of the structure. +*/ + +struct sysdefx + { + SQLTPGN syslpt; /* log page threshold */ + SQLTPGN syslpm; /* log page maximum */ + ubyte4 syshep; /* heap size */ + SQLTNPG sysncp; /* number of cache pages */ + SQLTTIV systiv; /* wait timeout value in seconds */ + ubyte1 sysiso[3]; /* isolation level */ + ubyte1 sysjou; /* journal */ + ubyte1 syslog; /* log */ + ubyte1 sysrec; /* recovery */ + ubyte1 systyp; /* system type */ + }; +typedef struct sysdefx sysdef; +typedef struct sysdefx SQLTSYS; +#define SYSSIZ sizeof(sysdef) + +/* +DESCRIPTION: + This structure is used as a parameter to the SQLGDI function. After a + a compile, all relevant information for a given Select column can be + obtained in this structure. + Note: + Please note that, originally, gdichb was the first element of the + gdidefx structure. It has been moved further down because a column + heading can be greater than 31 bytes. A bug was reported complaining + that the column heading was not being returned correctly since the + maximum length of a column heading is 46. This can now be returned + since the size of the buffer (gdichb) has been changed to 47. + Also, the length field (gdichl) has also been moved down to go with + the column heading buffer (gdichb). + The original gdichb and gdichl fields have been renamed to gdifl1 and + gdifl2. +*/ +struct gdidefx + { + ubyte1 gdifl1[31]; /* filler reserved for future use */ + ubyte1 gdifl2; /* filler reserved for future use */ + ubyte1 gdilbb[31]; /* label buffer */ + SQLTLBL gdilbl; /* label info length */ + SQLTSLC gdicol; /* select column number */ + SQLTDDT gdiddt; /* database data type */ + SQLTDEDL gdiddl; /* database extended data length */ + SQLTDDT gdiedt; /* external data type */ + SQLTDEDL gdiedl; /* external extended data length */ + SQLTPRE gdipre; /* decimal precision */ + SQLTSCA gdisca; /* decimal scale */ + byte2 gdinul; /* null indicator */ + ubyte1 gdichb[47]; /* column heading buffer */ + SQLTCHL gdichl; /* column heading length */ + byte1 gdifil[2]; /* for future use */ + }; +typedef struct gdidefx gdidef; +typedef struct gdidefx SQLTGDI; +typedef struct gdidefx* SQLTPGD; +#define GDISIZ sizeof(gdidef) + +/* +DESCRIPTION + This structure is used when passing binary data to and from external + functions. Since binary data can contains nulls as part of the data + we cannot look for a string terminator. Hence this structure is used + to provide a pointer to the binary data and the length of the data. +*/ + +struct binaryx + { + long binary_len; + char* binary_ptr; + }; + +#ifndef _INC_FSTREAM +typedef struct binaryx binary; +#endif +typedef struct binaryx BINARY; +typedef struct binaryx *lpbinary; +typedef struct binaryx *LPBINARY; + +#define BINARYSIZ sizeof(BINARY) + +#define BINARY_GET_LENGTH(x) (x.binary_len) +#define BINARY_GET_BUFFER(x) (x.binary_ptr) + +#define BINARY_SET_LENGTH(x,y) (x.binary_len=y) +#define BINARY_SET_BUFFER(x,y) (x.binary_ptr=y) + +/* + The following datatypes are analogous to the SqlWindows datatypes + NUMBER and DATETIME. They are used to pass the Sqlbase internal number + and datatime datatypes to external functions +*/ + +struct datetimex + { + char datetime_len; + char datetime_value[12]; + }; + +typedef struct datetimex datetime; + +#define DATETIMESIZ sizeof(datetime) + +#define DATETIME_IS_NULL(x) (x.datetime_len == 0) +#define DATETIME_SET_NULL(x) (x.datetime_len = 0) + +struct numberx + { + char number_len; + char number_value[12]; + }; + +typedef struct numberx number; + +#define NUMBERSIZ sizeof(number) + +#define NUMBER_IS_NULL(x) (x.number_len == 0) +#define NUMBER_SET_NULL(x) (x.number_len = 0) + + +/* system types */ +#define SYSTSGL 1 /* single user */ +#define SYSTMUL 2 /* multi-user */ +#define SYSTDB2 3 /* DB2 */ +#define SYSTDMO 4 /* demo */ +#define SYSTGWY 5 /* SQLNetwork Gateway */ +#define SYSTRTR 6 /* SQLNetwork Router */ +#define SYSTSHAS 7 /* SQLNetwork SQLHost App Services */ + +/*------------------------------------------------------------------------- + SQL API calling convention: + + For 32-bit systems, the calling convention used depends on the + target platform: + + - For NetWare and Windows/NT, the __stdcall calling convention is used. + If __stdcall is not supported by your compiler, then you will need + to define it to be something equivalent to __stdcall. + ------------------------------------------------------------------------- */ + +# define SQLTAPI byte2 SBSTDCALL /* Use __stdcall */ + +#ifndef SQL_PROTO +#ifndef NLINT_ARGS /* argument checking enabled */ + +/* SQL FUNCTION PROTOTYPES */ + +SQLTAPI sqlarf(SQLTCUR cur , SQLTFNP fnp , + SQLTFNL fnl , SQLTCHO cho ); +SQLTAPI sqlbbr(SQLTCUR cur , SQLTXER PTR errnum , + SQLTDAP errbuf , SQLTDAL PTR buflen , + SQLTBIR PTR errrow , SQLTRBF PTR rbf , + SQLTBIR errseq ); +SQLTAPI sqlbdb(SQLTSVH shandle , SQLTDAP dbname , + SQLTDAL dbnamel , SQLTFNP bkpdir , + SQLTFNL bkpdirl , SQLTBOO local , + SQLTBOO over ); +SQLTAPI sqlbef(SQLTCUR cur ); +SQLTAPI sqlber(SQLTCUR cur , SQLTRCD PTR rcd , + SQLTBIR PTR errrow , SQLTRBF PTR rbf , + SQLTBIR errseq ); +SQLTAPI sqlbkp(SQLTCUR cur , SQLTBOO defalt , + SQLTBOO overwrt , SQLTFNP bkfname , + SQLTFNL bkfnlen ); +SQLTAPI sqlbld(SQLTCUR cur , SQLTBNP bnp , + SQLTBNL bnl ); +SQLTAPI sqlblf(SQLTSVH shandle , SQLTDAP dbname , + SQLTDAL dbnamel , SQLTFNP bkpdir , + SQLTFNL bkpdirl , SQLTBOO local , + SQLTBOO over ); +SQLTAPI sqlblk(SQLTCUR cur , SQLTFLG blkflg ); +SQLTAPI sqlbln(SQLTCUR cur , SQLTBNN bnn ); +SQLTAPI sqlbna(SQLTCUR cur , SQLTBNP bnp , + SQLTBNL bnl , SQLTDAP dap , + SQLTDAL dal , SQLTSCA sca , + SQLTPDT pdt , SQLTNUL nli ); +SQLTAPI sqlbnd(SQLTCUR cur , SQLTBNP bnp , + SQLTBNL bnl , SQLTDAP dap , + SQLTDAL dal , SQLTSCA sca , + SQLTPDT pdt ); +SQLTAPI sqlbnn(SQLTCUR cur , SQLTBNN bnn , + SQLTDAP dap , SQLTDAL dal , + SQLTSCA sca , SQLTPDT pdt ); +SQLTAPI sqlbnu(SQLTCUR cur , SQLTBNN bnn , + SQLTDAP dap , SQLTDAL dal , + SQLTSCA sca , SQLTPDT pdt , + SQLTNUL nli ); +SQLTAPI sqlbss(SQLTSVH shandle , SQLTDAP dbname , + SQLTDAL dbnamel , SQLTFNP bkpdir , + SQLTFNL bkpdirl , SQLTBOO local , + SQLTBOO over ); +SQLTAPI sqlcan(SQLTCUR cur ); +SQLTAPI sqlcbv(SQLTCUR cur ); +SQLTAPI sqlcch(SQLTCON PTR hConp , SQLTDAP dbnamp , + SQLTDAL dbnaml , SQLTMOD fType ); +SQLTAPI sqlcdr(SQLTSVH shandle, SQLTCUR cur ); +SQLTAPI sqlcex(SQLTCUR cur , SQLTDAP dap , + SQLTDAL dal ); +SQLTAPI sqlclf(SQLTSVH cur , SQLTDAP logfile , + SQLTFMD startflag); +SQLTAPI sqlcmt(SQLTCUR cur ); +SQLTAPI sqlcnc(SQLTCUR PTR curp , SQLTDAP dbnamp , + SQLTDAL dbnaml ); +SQLTAPI sqlcnr(SQLTCUR PTR curp , SQLTDAP dbnamp , + SQLTDAL dbnaml ); +SQLTAPI sqlcom(SQLTCUR cur , SQLTDAP cmdp , + SQLTDAL cmdl ); +SQLTAPI sqlcon(SQLTCUR PTR curp , SQLTDAP dbnamp , + SQLTDAL dbnaml , SQLTWSI cursiz , + SQLTNPG pages , SQLTRCF recovr , + SQLTDAL outsize , SQLTDAL insize ); +SQLTAPI sqlcpy(SQLTCUR fcur , SQLTDAP selp , + SQLTDAL sell , SQLTCUR tcur , + SQLTDAP isrtp , SQLTDAL isrtl ); +SQLTAPI sqlcre(SQLTSVH shandle , SQLTDAP dbnamp , + SQLTDAL dbnaml ); +SQLTAPI sqlcrf(SQLTSVH shandle , SQLTDAP dbname , + SQLTDAL dbnamel ); +SQLTAPI sqlcrs(SQLTCUR cur , SQLTDAP rsp , + SQLTDAL rsl ); +SQLTAPI sqlcsv(SQLTSVH PTR shandlep, SQLTDAP serverid, + SQLTDAP password); +SQLTAPI sqlcty(SQLTCUR cur , SQLTCTY PTR cty ); +SQLTAPI sqldbn(SQLTDAP serverid, SQLTDAP buffer , + SQLTDAL length ); +SQLTAPI sqldch(SQLTCON hCon ); +SQLTAPI sqlded(SQLTSVH shandle , SQLTDAP dbnamp , + SQLTDAL dbnaml ); +SQLTAPI sqldel(SQLTSVH shandle , SQLTDAP dbnamp , + SQLTDAL dbnaml ); +SQLTAPI sqldes(SQLTCUR cur , SQLTSLC slc , + SQLTDDT PTR ddt , SQLTDDL PTR ddl , + SQLTCHP chp , SQLTCHL PTR chlp , + SQLTPRE PTR prep , SQLTSCA PTR scap ); +SQLTAPI sqldid(SQLTDAP dbname , SQLTDAL dbnamel ); +SQLTAPI sqldii(SQLTCUR cur , SQLTSLC ivn , + SQLTDAP inp , SQLTCHL* inlp ); +SQLTAPI sqldin(SQLTDAP dbnamp , SQLTDAL dbnaml ); +SQLTAPI sqldir(SQLTSVN srvno , SQLTDAP buffer , + SQLTDAL length ); +SQLTAPI sqldis(SQLTCUR cur ); +SQLTAPI sqldon(void); +SQLTAPI sqldox(SQLTSVH shandle , SQLTDAP dirnamep, + SQLTFAT fattr ); +SQLTAPI sqldrc(SQLTSVH cur ); +SQLTAPI sqldro(SQLTSVH shandle , SQLTDAP dirname ); +SQLTAPI sqldrr(SQLTSVH shandle , SQLTDAP filename); +SQLTAPI sqldrs(SQLTCUR cur , SQLTDAP rsp , + SQLTDAL rsl ); +SQLTAPI sqldsc(SQLTCUR cur , SQLTSLC slc , + SQLTDDT PTR edt , SQLTDDL PTR edl , + SQLTCHP chp , SQLTCHL PTR chlp , + SQLTPRE PTR prep , SQLTSCA PTR scap ); +SQLTAPI sqldst(SQLTCUR cur , SQLTDAP cnp , + SQLTDAL cnl ); +SQLTAPI sqldsv(SQLTSVH shandle ); +SQLTAPI sqlebk(SQLTCUR cur ); +SQLTAPI sqlefb(SQLTCUR cur ); +SQLTAPI sqlelo(SQLTCUR cur ); +SQLTAPI sqlenl(SQLTCON hCon , SQLTDAP p1, SQLTDAL l1, + SQLTDAP p2 , SQLTDAL* l2_p ); +SQLTAPI sqlenr(SQLTSVH shandle , SQLTDAP dbname , + SQLTDAL dbnamel ); +SQLTAPI sqlepo(SQLTCUR cur , SQLTEPO PTR epo ); +SQLTAPI sqlerf(SQLTCUR cur ); +SQLTAPI sqlerr(SQLTRCD error , SQLTDAP msg ); +SQLTAPI sqlers(SQLTCUR cur ); +SQLTAPI sqletx(SQLTRCD error , SQLTPTY msgtyp , + SQLTDAP bfp , SQLTDAL bfl , + SQLTDAL PTR txtlen ); +SQLTAPI sqlexe(SQLTCUR cur ); +SQLTAPI sqlexp(SQLTCUR cur , SQLTDAP buffer , + SQLTDAL length ); +SQLTAPI sqlfbk(SQLTCUR cur ); +SQLTAPI sqlfer(SQLTRCD error , SQLTDAP msg ); +SQLTAPI sqlfet(SQLTCUR cur ); +SQLTAPI sqlfgt(SQLTSVH cur , SQLTDAP srvfile , + SQLTDAP lclfile ); +SQLTAPI sqlfpt(SQLTSVH cur , SQLTDAP srvfile , + SQLTDAP lclfile ); +SQLTAPI sqlfqn(SQLTCUR cur , SQLTFLD field , + SQLTDAP nameptr , SQLTDAL PTR namelen ); +SQLTAPI sqlgbi(SQLTCUR cur , SQLTCUR PTR pcur , + SQLTPNM PTR ppnm ); +SQLTAPI sqlgdi(SQLTCUR cur , SQLTPGD gdi ); +SQLTAPI sqlget(SQLTCUR cur , SQLTPTY parm , + SQLTDAP p , SQLTDAL PTR l ); +SQLTAPI sqlgfi(SQLTCUR cur , SQLTSLC slc , + SQLTCDL PTR cvl , SQLTFSC PTR fsc ); +SQLTAPI sqlgls(SQLTCUR cur , SQLTSLC slc , + SQLTLSI PTR size ); +SQLTAPI sqlgnl(SQLTSVH shandle , SQLTDAP dbname , + SQLTDAL dbnamel , SQLTLNG PTR lognum ); +SQLTAPI sqlgnr(SQLTCUR cur , SQLTDAP tbnam , + SQLTDAL tbnaml , SQLTROW PTR rows ); +SQLTAPI sqlgsi(SQLTSVH shandle , SQLTFLG infoflags, + SQLTDAP buffer , SQLTDAL buflen , + SQLTDAL PTR rbuflen ); +SQLTAPI sqlgwo(SQLTCON hCon , SQLTDAP p , + SQLTDAL PTR l ); +SQLTAPI sqlidb(SQLTCUR cur ); +SQLTAPI sqlims(SQLTCUR cur , SQLTDAL insize ); +SQLTAPI sqlind(SQLTSVH shandle , SQLTDAP dbnamp , + SQLTDAL dbnaml ); +SQLTAPI sqlini(SQLTPFP callback); +SQLTAPI sqliniEx(SQLTDAP iniPath, SQLTDAL l); +SQLTAPI sqlins(SQLTSVN srvno , SQLTDAP dbnamp , + SQLTDAL dbnaml , SQLTFLG createflag, + SQLTFLG overwrite); +SQLTAPI sqliqx(SQLTCON hCon, SQLTDAP p, + SQLTDAL l, SQLTBOO PTR b ); +SQLTAPI sqllab(SQLTCUR cur , SQLTSLC slc , + SQLTCHP lbp , SQLTCHL PTR lblp ); +SQLTAPI sqlldp(SQLTCUR cur , SQLTDAP cmdp , + SQLTDAL cmdl ); +SQLTAPI sqllsk(SQLTCUR cur , SQLTSLC slc , + SQLTLSI pos ); +SQLTAPI sqlmcl(SQLTSVH shandle , SQLTFLH fd ); +SQLTAPI sqlmdl(SQLTSVH shandle , SQLTDAP filename); +SQLTAPI sqlmls(SQLTSVH shandle , SQLTFLH fd , + SQLTLLI offset , SQLTWNC whence , + SQLTLLI PTR roffset ); +SQLTAPI sqlmop(SQLTSVH shandle , SQLTFLH PTR fdp , + SQLTDAP filename, SQLTFMD openmode); +SQLTAPI sqlmrd(SQLTSVH shandle , SQLTFLH fd , + SQLTDAP buffer , SQLTDAL len , + SQLTDAL PTR rlen ); +SQLTAPI sqlmsk(SQLTSVH shandle , SQLTFLH fd , + SQLTLNG offset , SQLTWNC whence , + SQLTLNG PTR roffset ); +SQLTAPI sqlmwr(SQLTSVH shandle , SQLTFLH fd , + SQLTDAP buffer , SQLTDAL len , + SQLTDAL PTR rlen ); +SQLTAPI sqlnbv(SQLTCUR cur , SQLTNBV PTR nbv ); +SQLTAPI sqlnii(SQLTCUR cur , SQLTNSI PTR nii ); +SQLTAPI sqlnrr(SQLTCUR cur , SQLTROW PTR rcountp ); +SQLTAPI sqlnsi(SQLTCUR cur , SQLTNSI PTR nsi ); +SQLTAPI sqloms(SQLTCUR cur , SQLTDAL outsize ); +SQLTAPI sqlopc(SQLTCUR PTR curp , SQLTCON hCon , + SQLTMOD fType ); +SQLTAPI sqlprs(SQLTCUR cur , SQLTROW row ); +SQLTAPI sqlrbf(SQLTCUR cur , SQLTRBF PTR rbf ); +SQLTAPI sqlrbk(SQLTCUR cur ); +SQLTAPI sqlrcd(SQLTCUR cur , SQLTRCD PTR rcd ); +SQLTAPI sqlrdb(SQLTSVH shandle , SQLTDAP dbname , + SQLTDAL dbnamel , SQLTFNP bkpdir , + SQLTFNL bkpdirl , SQLTBOO local , + SQLTBOO over ); +SQLTAPI sqlrdc(SQLTCUR cur , SQLTDAP bufp , + SQLTDAL bufl , SQLTDAL PTR readl ); +SQLTAPI sqlrel(SQLTCUR cur ); +SQLTAPI sqlres(SQLTCUR PTR curptr , SQLTFNP bkfname , + SQLTFNL bkfnlen , SQLTSVN bkfserv , + SQLTBOO overwrt , SQLTDAP dbname , + SQLTDAL dbnlen , SQLTSVN dbserv ); +SQLTAPI sqlret(SQLTCUR cur , SQLTDAP cnp , + SQLTDAL cnl ); +SQLTAPI sqlrlf(SQLTSVH shandle , SQLTDAP dbname , + SQLTDAL dbnamel , SQLTFNP bkpdir , + SQLTFNL bkpdirl , SQLTBOO local , + SQLTBOO over ); +SQLTAPI sqlrlo(SQLTCUR cur , SQLTSLC slc , + SQLTDAP bufp , SQLTDAL bufl , + SQLTDAL PTR readl ); +SQLTAPI sqlrof(SQLTSVH shandle , SQLTDAP dbname , + SQLTDAL dbnamel , SQLTRFM mode , + SQLTDAP datetime, SQLTDAL datetimel); +SQLTAPI sqlrow(SQLTCUR cur , SQLTROW PTR row ); +SQLTAPI sqlrrd(SQLTCUR cur ); +SQLTAPI sqlrrs(SQLTCUR cur , SQLTDAP rsp , + SQLTDAL rsl ); +SQLTAPI sqlrsi(SQLTSVH shandle ); +SQLTAPI sqlrss(SQLTSVH shandle , SQLTDAP dbname , + SQLTDAL dbnamel , SQLTFNP bkpdir , + SQLTFNL bkpdirl , SQLTBOO local , + SQLTBOO over ); +SQLTAPI sqlsab(SQLTSVH shandle , SQLTPNM pnum ); +SQLTAPI sqlsap(SQLTSVN srvno , SQLTDAP password, + SQLTPNM pnum ); +SQLTAPI sqlscl(SQLTCUR cur , SQLTDAP namp , + SQLTDAL naml ); +SQLTAPI sqlscn(SQLTCUR cur , SQLTDAP namp , + SQLTDAL naml ); +SQLTAPI sqlscp(SQLTNPG pages ); +SQLTAPI sqlsdn(SQLTDAP dbnamp , SQLTDAL dbnaml ); +SQLTAPI sqlsds(SQLTSVH shandle, SQLTFLG shutdownflg); +SQLTAPI sqlsdx(SQLTSVH shandle, SQLTDAP dbnamp, + SQLTDAL dbnaml , SQLTFLG shutdownflg); +SQLTAPI sqlset(SQLTCUR cur , SQLTPTY parm , + SQLTDAP p , SQLTDAL l ); +SQLTAPI sqlsil(SQLTCUR cur , SQLTILV isolation); +SQLTAPI sqlslp(SQLTCUR cur , SQLTNPG lpt , + SQLTNPG lpm ); +SQLTAPI sqlspr(SQLTCUR cur ); +SQLTAPI sqlsrf(SQLTCUR cur , SQLTDAP fnp , + SQLTDAL fnl ); +SQLTAPI sqlsrs(SQLTCUR cur ); +SQLTAPI sqlssb(SQLTCUR cur , SQLTSLC slc , + SQLTPDT pdt , SQLTDAP pbp , + SQLTPDL pdl , SQLTSCA sca , + SQLTCDL PTR pcv , SQLTFSC PTR pfc ); +SQLTAPI sqlsss(SQLTCUR cur , SQLTDAL size ); +SQLTAPI sqlsta(SQLTCUR cur , SQLTSTC PTR svr , + SQLTSTC PTR svw , SQLTSTC PTR spr , + SQLTSTC PTR spw ); +SQLTAPI sqlstm(SQLTSVH shandle ); +SQLTAPI sqlsto(SQLTCUR cur , SQLTDAP cnp , + SQLTDAL cnl , SQLTDAP ctp , + SQLTDAL ctl ); +SQLTAPI sqlstr(SQLTCUR cur ); +SQLTAPI sqlsxt(SQLTSVN srvno , SQLTDAP password); +SQLTAPI sqlsys(SQLTCUR cur , SQLTSYS PTR sys ); +SQLTAPI sqltec(SQLTRCD rcd , SQLTRCD PTR np ); +SQLTAPI sqltem(SQLTCUR cur , SQLTXER PTR xer , + SQLTPTY msgtyp , SQLTDAP bfp , + SQLTDAL bfl , SQLTDAL PTR txtlen ); +SQLTAPI sqltio(SQLTCUR cur , SQLTTIV _timeout); +SQLTAPI sqlunl(SQLTCUR cur , SQLTDAP cmdp , + SQLTDAL cmdl ); +SQLTAPI sqlurs(SQLTCUR cur ); +SQLTAPI sqlwdc(SQLTCUR cur , SQLTDAP bufp , + SQLTDAL bufl ); +SQLTAPI sqlwlo(SQLTCUR cur , SQLTDAP bufp , + SQLTDAL bufl ); +SQLTAPI sqlxad(SQLTNMP op , SQLTNMP np1 , + SQLTNML nl1 , SQLTNMP np2 , + SQLTNML nl2 ); +SQLTAPI sqlxcn(SQLTNMP op , SQLTDAP ip , + SQLTDAL il ); +SQLTAPI sqlxda(SQLTNMP op , SQLTNMP dp , + SQLTNML dl , SQLTDAY days ); +SQLTAPI sqlxdp(SQLTDAP op , SQLTDAL ol , + SQLTNMP ip , SQLTNML il , + SQLTDAP pp , SQLTDAL pl ); +SQLTAPI sqlxdv(SQLTNMP op , SQLTNMP np1 , + SQLTNML nl1 , SQLTNMP np2 , + SQLTNML nl2 ); +SQLTAPI sqlxer(SQLTCUR cur , SQLTXER PTR errnum, + SQLTDAP errbuf , SQLTDAL PTR buflen ); +SQLTAPI sqlxml(SQLTNMP op , SQLTNMP np1 , + SQLTNML nl1 , SQLTNMP np2 , + SQLTNML nl2 ); +SQLTAPI sqlxnp(SQLTDAP outp , SQLTDAL outl , + SQLTNMP isnp , SQLTNML isnl , + SQLTDAP picp , SQLTDAL picl ); +SQLTAPI sqlxpd(SQLTNMP op , SQLTNML PTR olp , + SQLTDAP ip , SQLTDAP pp , + SQLTDAL pl ); +SQLTAPI sqlxsb(SQLTNMP op , SQLTNMP np1 , + SQLTNML nl1 , SQLTNMP np2 , + SQLTNML nl2 ); + +#else + +SQLTAPI sqlarf(); +SQLTAPI sqlbbr(); +SQLTAPI sqlbdb(); +SQLTAPI sqlbef(); +SQLTAPI sqlber(); +SQLTAPI sqlbkp(); +SQLTAPI sqlbld(); +SQLTAPI sqlblf(); +SQLTAPI sqlblk(); +SQLTAPI sqlbln(); +SQLTAPI sqlbna(); +SQLTAPI sqlbnd(); +SQLTAPI sqlbnn(); +SQLTAPI sqlbnu(); +SQLTAPI sqlbss(); +SQLTAPI sqlcan(); +SQLTAPI sqlcbv(); +SQLTAPI sqlcch(); +SQLTAPI sqlcdr(); +SQLTAPI sqlcex(); +SQLTAPI sqlclf(); +SQLTAPI sqlcmt(); +SQLTAPI sqlcnc(); +SQLTAPI sqlcnr(); +SQLTAPI sqlcom(); +SQLTAPI sqlcon(); +SQLTAPI sqlcpy(); +SQLTAPI sqlcre(); +SQLTAPI sqlcrf(); +SQLTAPI sqlcrs(); +SQLTAPI sqlcsv(); +SQLTAPI sqlcty(); +SQLTAPI sqldbn(); +SQLTAPI sqldch(); +SQLTAPI sqlded(); +SQLTAPI sqldel(); +SQLTAPI sqldes(); +SQLTAPI sqldid(); +SQLTAPI sqldii(); +SQLTAPI sqldin(); +SQLTAPI sqldir(); +SQLTAPI sqldis(); +SQLTAPI sqldon(); +SQLTAPI sqldox(); +SQLTAPI sqldrc(); +SQLTAPI sqldro(); +SQLTAPI sqldrr(); +SQLTAPI sqldrs(); +SQLTAPI sqldsc(); +SQLTAPI sqldst(); +SQLTAPI sqldsv(); +SQLTAPI sqlebk(); +SQLTAPI sqlefb(); +SQLTAPI sqlelo(); +SQLTAPI sqlenr(); +SQLTAPI sqlepo(); +SQLTAPI sqlerf(); +SQLTAPI sqlerr(); +SQLTAPI sqlers(); +SQLTAPI sqletx(); +SQLTAPI sqlexe(); +SQLTAPI sqlexp(); +SQLTAPI sqlfbk(); +SQLTAPI sqlfer(); +SQLTAPI sqlfet(); +SQLTAPI sqlfgt(); +SQLTAPI sqlfpt(); +SQLTAPI sqlfqn(); +SQLTAPI sqlgbi(); +SQLTAPI sqlgdi(); +SQLTAPI sqlget(); +SQLTAPI sqlgfi(); +SQLTAPI sqlgls(); +SQLTAPI sqlgnl(); +SQLTAPI sqlgnr(); +SQLTAPI sqlgsi(); +SQLTAPI sqlgwo(); +SQLTAPI sqlidb(); +SQLTAPI sqlims(); +SQLTAPI sqlind(); +SQLTAPI sqlini(); +SQLTAPI sqliniEx(); +SQLTAPI sqlins(); +SQLTAPI sqliqx(); +SQLTAPI sqllab(); +SQLTAPI sqlldp(); +SQLTAPI sqllsk(); +SQLTAPI sqlmcl(); +SQLTAPI sqlmdl(); +SQLTAPI sqlmls(); +SQLTAPI sqlmop(); +SQLTAPI sqlmrd(); +SQLTAPI sqlmsk(); +SQLTAPI sqlmwr(); +SQLTAPI sqlnbv(); +SQLTAPI sqlnii(); +SQLTAPI sqlnrr(); +SQLTAPI sqlnsi(); +SQLTAPI sqloms(); +SQLTAPI sqlopc(); +SQLTAPI sqlprs(); +SQLTAPI sqlrbf(); +SQLTAPI sqlrbk(); +SQLTAPI sqlrcd(); +SQLTAPI sqlrdb(); +SQLTAPI sqlrdc(); +SQLTAPI sqlrel(); +SQLTAPI sqlres(); +SQLTAPI sqlret(); +SQLTAPI sqlrlf(); +SQLTAPI sqlrlo(); +SQLTAPI sqlrof(); +SQLTAPI sqlrow(); +SQLTAPI sqlrrd(); +SQLTAPI sqlrrs(); +SQLTAPI sqlrsi(); +SQLTAPI sqlrss(); +SQLTAPI sqlsab(); +SQLTAPI sqlsap(); +SQLTAPI sqlscl(); +SQLTAPI sqlscn(); +SQLTAPI sqlscp(); +SQLTAPI sqlsdn(); +SQLTAPI sqlsds(); +SQLTAPI sqlsdx(); +SQLTAPI sqlset(); +SQLTAPI sqlsil(); +SQLTAPI sqlslp(); +SQLTAPI sqlspr(); +SQLTAPI sqlsrf(); +SQLTAPI sqlsrs(); +SQLTAPI sqlssb(); +SQLTAPI sqlsss(); +SQLTAPI sqlsta(); +SQLTAPI sqlstm(); +SQLTAPI sqlsto(); +SQLTAPI sqlstr(); +SQLTAPI sqlsxt(); +SQLTAPI sqlsys(); +SQLTAPI sqltec(); +SQLTAPI sqltem(); +SQLTAPI sqltio(); +SQLTAPI sqlunl(); +SQLTAPI sqlurs(); +SQLTAPI sqlwdc(); +SQLTAPI sqlwlo(); +SQLTAPI sqlxad(); +SQLTAPI sqlxcn(); +SQLTAPI sqlxda(); +SQLTAPI sqlxdp(); +SQLTAPI sqlxdv(); +SQLTAPI sqlxer(); +SQLTAPI sqlxml(); +SQLTAPI sqlxnp(); +SQLTAPI sqlxpd(); +SQLTAPI sqlxsb(); + +#endif +#endif + +#define SQLF000 0 /* not a function */ +#define SQLFINI 1 /* SQL INItialize applications use of the database */ +#define SQLFDON 2 /* SQL DONe using database */ +#define SQLFCON 3 /* SQL CONnect to a cursor/database */ +#define SQLFDIS 4 /* SQL DISconnect from a cursor/database */ +#define SQLFCOM 5 /* SQL COMpile a SQL command */ +#define SQLFEXE 6 /* SQL EXEcute an SQL command */ +#define SQLFCEX 7 /* SQL Compile and EXecute a SQL command */ +#define SQLFCMT 8 /* SQL CoMmiT a transaction to the database */ +#define SQLFDES 9 /* SQL DEScribe the items of a select statement */ +#define SQLFGFI 10 /* SQL Get Fetch Information */ +#define SQLFFBK 11 /* SQL FETch previous row from SELECT */ +#define SQLFFET 12 /* SQL FETch next row from SELECT */ +#define SQLFEFB 13 /* SQL Enable Fetch Backwards */ +#define SQLFPRS 14 /* SQL Position in Result Set */ +#define SQLFURS 15 /* SQL Undo Result Set */ +#define SQLFNBV 16 /* SQL get Number of Bind Variables */ +#define SQLFBND 17 /* SQL BiNd Data variables. This function is supercede */ +#define SQLFBNN 18 /* SQL BiNd Numerics */ +#define SQLFBLN 19 /* SQL Bind Long Number */ +#define SQLFBLD 20 /* SQL Bind Long Data variables */ +#define SQLFSRS 21 /* SQL Start Restriction Set processing */ +#define SQLFRRS 22 /* SQL Restart Restriction Set processing */ +#define SQLFCRS 23 /* SQL Close Restriction Set */ +#define SQLFDRS 24 /* SQL Drop Restriction Set */ +#define SQLFARF 25 /* SQL Apply Roll Forward journal */ +#define SQLFERF 26 /* SQL End RollForward recovery (no longer supported) */ +#define SQLFSRF 27 /* SQL Start Roll Forward journal */ +#define SQLFSTO 28 /* SQL STOre a compiled SQL command */ +#define SQLFRET 29 /* SQL RETrieve a compiled SQL command */ +#define SQLFDST 30 /* SQL Drop a STored command */ +#define SQLFCTY 31 /* SQL get Command TYpe */ +#define SQLFEPO 32 /* SQL get Error POsition */ +#define SQLFGNR 33 /* SQL Get Number of Rows */ +#define SQLFNSI 34 /* SQL get Number of Select Items */ +#define SQLFRBF 35 /* SQL get Roll Back Flag */ +#define SQLFRCD 36 /* SQL get Return CoDe */ +#define SQLFROW 37 /* SQL get number of ROWs */ +#define SQLFSCN 38 /* SQL Set Cursor Name */ +#define SQLFSIL 39 /* SQL Set Isolation Level */ +#define SQLFSLP 40 /* SQL Set Log Parameters */ +#define SQLFSSB 41 /* SQL Set Select Buffer */ +#define SQLFSSS 42 /* SQL Set SortSpace */ +#define SQLFRLO 43 /* SQL Read LOng */ +#define SQLFWLO 44 /* SQL Write LOng */ +#define SQLFLSK 45 /* SQL Long SeeK */ +#define SQLFGLS 46 /* SQL Get Long Size */ +#define SQLFELO 47 /* SQL End Long Operation */ +#define SQLFRBK 48 /* SQL RollBacK a transaction from the database */ +#define SQLFERR 49 /* SQL get ERRor message */ +#define SQLFCPY 50 /* SQL CoPY */ +#define SQLFIDB 51 /* SQL Initialize DataBase */ +#define SQLFSYS 52 /* SQL SYSTEM */ +#define SQLFSTA 53 /* SQL STAtistics */ +#define SQLFR02 54 /* SQL RESERVED */ +#define SQLFXAD 55 /* SQL eXtra ADd */ +#define SQLFXCN 56 /* SQL eXtra Character to NUmber */ +#define SQLFXDA 57 /* SQL eXtra Date Add */ +#define SQLFXDP 58 /* SQL eXtra convert SQLBASE Date to Picture */ +#define SQLFXDV 59 /* SQL eXtra DiVide */ +#define SQLFXML 60 /* SQL eXtra MuLtiply */ +#define SQLFXNP 61 /* SQL eXtra convert SQLBASE Numeric to Picture */ +#define SQLFXPD 62 /* SQL eXtra convert Picture to SQLBASE Date. */ +#define SQLFXSB 63 /* SQL eXtra SuBtract */ +#define SQLFINS 64 /* SQL INStall database (no longer supported) */ +#define SQLFDIN 65 /* SQL DeINstall database (no longer supported) */ +#define SQLFDIR 66 /* SQL DIRectory of databases */ +#define SQLFTIO 67 /* SQL TImeOut */ +#define SQLFFQN 68 /* SQL get Fully Qualified column Name */ +#define SQLFEXP 69 /* SQL EXexcution Plan */ +#define SQLFFER 70 /* SQL Full ERror message */ +#define SQLFBKP 71 /* SQL BacKuP */ +#define SQLFRDC 72 /* SQL Read Database Chunk */ +#define SQLFEBK 73 /* SQL End network online BacKup */ +#define SQLFRES 74 /* SQL REStore from backup */ +#define SQLFWDC 75 /* SQL Write Database Chunk */ +#define SQLFRRD 76 /* SQL Recover Restored Database */ +#define SQLFERS 77 /* SQL End network ReStore */ +#define SQLFNRR 78 /* SQL Number of Rows in Result set */ +#define SQLFSTR 79 /* SQL STart Restriction mode */ +#define SQLFSPR 80 /* SQL StoP Restriction mode */ +#define SQLFCNC 81 /* SQL CoNneCt: the sequel. */ +#define SQLFCNR 82 /* SQL Connect with No Recovery */ +#define SQLFOMS 83 /* SQL set Output Message Size */ +#define SQLFIMS 84 /* SQL set Input Message Size */ +#define SQLFSCP 85 /* SQL Set Cache Pages */ +#define SQLFDSC 86 /* SQL DeSCribe item of SELECT with external type */ +#define SQLFLAB 87 /* SQL get LABel information */ +#define SQLFCBV 88 /* SQL Clear Bind Variables */ +#define SQLFGET 89 /* SQL GET database parameter */ +#define SQLFSET 90 /* SQL SET database parameter */ +#define SQLFTEC 91 /* SQL Translate Error Code */ +#define SQLFBDB 92 /* SQL Backup DataBase */ +#define SQLFBEF 93 /* SQL Bulk Execute Flush */ +#define SQLFBER 94 /* SQL get Bulk Execute Returned code */ +#define SQLFBLF 95 /* SQL Backup Log Files */ +#define SQLFBLK 96 /* SQL set BuLK insert mode */ +#define SQLFBSS 97 /* SQL Backup SnapShot */ +#define SQLFCAN 98 /* SQL CaNceL command */ +#define SQLFCLF 99 /* SQL Change server activity LogFile */ +#define SQLFCRE 100 /* SQL CREate database */ +#define SQLFCRF 101 /* SQL Continue RollForward recovery */ +#define SQLFCSV 102 /* SQL Connect to SerVer */ +#define SQLFDBN 103 /* SQL Directory By Name */ +#define SQLFDED 104 /* SQL DeINstall database */ +#define SQLFDEL 105 /* SQL DELete database */ +#define SQLFDID 106 /* SQL DeInstall database and Delete database files */ +#define SQLFDRC 107 /* SQL DiRectory Close */ +#define SQLFDRO 108 /* SQL DiRectory Open */ +#define SQLFDRR 109 /* SQL DiRectory Read */ +#define SQLFDSV 110 /* SQL Disconnect from SerVer */ +#define SQLFENR 111 /* SQL ENd Rollforward recovery */ +#define SQLFFGT 112 /* SQL File GeT */ +#define SQLFFPT 113 /* SQL File Put */ +#define SQLFGNL 114 /* SQL Get Next Log for rollforward */ +#define SQLFGSI 115 /* SQL Get Server Information */ +#define SQLFIND 116 /* SQL INstall Database */ +#define SQLFMCL 117 /* SQL reMote CLose server file */ +#define SQLFMDL 118 /* SQL reMote DeLete file or directory on remote server */ +#define SQLFMOP 119 /* SQL reMote OPen file on server */ +#define SQLFMRD 120 /* SQL reMote ReaD from file on server */ +#define SQLFMSK 121 /* SQL reMote SeeK into file on server */ +#define SQLFMWR 122 /* SQL reMote WRite to file on server */ +#define SQLFRDB 123 /* SQL Restore DataBase */ +#define SQLFREL 124 /* SQL RELease log */ +#define SQLFRLF 125 /* SQL Restore Log Files */ +#define SQLFROF 126 /* SQL ROllForward recovery */ +#define SQLFRSS 127 /* SQL Restore SnapShot */ +#define SQLFSAB 128 /* SQL Server ABort process */ +#define SQLFSAP 129 /* SQL Server Abort Process */ +#define SQLFSDN 130 /* SQL ShutDowN database */ +#define SQLFSTM 131 /* SQL Server TerMinate */ +#define SQLFBBR 132 /* SQL get Bulk Execute Backend error # and message */ +#define SQLFBNA 133 /* SQL BiNd Data variables by name */ +#define SQLFBNU 134 /* SQL BiNd Numerical bind variable */ +#define SQLFGDI 135 /* SQL Get Descriptor info for a given Select column. */ +#define SQLFSXT 136 /* SQL Server eXiT (no longer supported) */ +#define SQLFXER 137 /* SQL get backend (Extended) error number and Message */ +#define SQLFETX 138 /* SQL get Error message TeXt */ +#define SQLFTEM 139 /* SQL get Tokenized Error Message */ +#define SQLFSCL 140 /* SQL Set CLient name */ +#define SQLFLDP 141 /* SQL LoaD oPeration */ +#define SQLFUNL 142 /* SQL UNLoad command */ +#define SQLFGBI 143 /* SQL Get Backend cursor Information */ +#define SQLFNII 144 /* SQL get Number of Into variable Information */ +#define SQLFDII 145 /* SQL Describe Into variable Information */ +#define SQLFSDS 146 /* SQL Shutdown/enable server */ +#define SQLFSDX 147 /* SQL Shutdown/enable Database Extended */ +#define SQLFCDR 148 /* SQL Cancel Database Request */ +#define SQLFDOX 149 /* SQL Directory Open Extended */ +#define SQLFRSI 150 /* SQL Reset Statistical Information */ +#define SQLFCCH 151 /* SQL Create Connection Handle */ +#define SQLFOPC 152 /* SQL OPen Cursor */ +#define SQLFDCH 153 /* SQL Destroy Connection Handle */ +#define SQLFENL 154 /* SQL MTS Enlist */ +#define SQLFGWO 155 /* SQL MTS Get Whereabouts Object */ +#define SQLFMLS 156 /* SQL reMote Long SeeK into file on server */ +#define SQLFIQX 157 /* SQL MTS Query a transaction's status */ + +#define SQLFMINAPI SQLFINI /* changes these when API entry */ +#define SQLFMAXAPI SQLFGWO /* points change */ + +/* + * The following default value macros are obsolete and are not used by + * the SQLBase code anymore. + */ +#if 0 +#define SQLDNPG 500 /* CACHE, number of cache pages */ +#define SQLDNSCPG 500 /* SORTCACHE, num of sortcache pages */ +#define SQLMISCPG 1000000 /* installed sort cache pages */ +#define SQLMSCPAG 0 /* minimum sort cache pages */ +#define SQLMSRS 3000 /* minimum sort space */ +#endif + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* !SQL */ diff --git a/libodbc/include/sqlite/sqlite3.h b/libodbc/include/sqlite/sqlite3.h new file mode 100644 index 0000000000..212e118045 --- /dev/null +++ b/libodbc/include/sqlite/sqlite3.h @@ -0,0 +1,5734 @@ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This header file defines the interface that the SQLite library +** presents to client programs. If a C-function, structure, datatype, +** or constant definition does not appear in this file, then it is +** not a published API of SQLite, is subject to change without +** notice, and should not be referenced by programs that use SQLite. +** +** Some of the definitions that are in this file are marked as +** "experimental". Experimental interfaces are normally new +** features recently added to SQLite. We do not anticipate changes +** to experimental interfaces but reserve the right to make minor changes +** if experience from use "in the wild" suggest such changes are prudent. +** +** The official C-language API documentation for SQLite is derived +** from comments in this file. This file is the authoritative source +** on how SQLite interfaces are suppose to operate. +** +** The name of this file under configuration management is "sqlite.h.in". +** The makefile makes some minor changes to this file (such as inserting +** the version number) and changes its name to "sqlite3.h" as +** part of the build process. +*/ +#ifndef _SQLITE3_H_ +#define _SQLITE3_H_ +#include /* Needed for the definition of va_list */ + +/* +** Make sure we can call this stuff from C++. +*/ +#ifdef __cplusplus +extern "C" { +#endif + + +/* +** Add the ability to override 'extern' +*/ +#ifndef SQLITE_EXTERN +# define SQLITE_EXTERN extern +#endif + +#ifndef SQLITE_API +# define SQLITE_API +#endif + + +/* +** These no-op macros are used in front of interfaces to mark those +** interfaces as either deprecated or experimental. New applications +** should not use deprecated interfaces - they are support for backwards +** compatibility only. Application writers should be aware that +** experimental interfaces are subject to change in point releases. +** +** These macros used to resolve to various kinds of compiler magic that +** would generate warning messages when they were used. But that +** compiler magic ended up generating such a flurry of bug reports +** that we have taken it all out and gone back to using simple +** noop macros. +*/ +#define SQLITE_DEPRECATED +#define SQLITE_EXPERIMENTAL + +/* +** Ensure these symbols were not defined by some previous header file. +*/ +#ifdef SQLITE_VERSION +# undef SQLITE_VERSION +#endif +#ifdef SQLITE_VERSION_NUMBER +# undef SQLITE_VERSION_NUMBER +#endif + +/* +** CAPI3REF: Compile-Time Library Version Numbers +** +** ^(The [SQLITE_VERSION] C preprocessor macro in the sqlite3.h header +** evaluates to a string literal that is the SQLite version in the +** format "X.Y.Z" where X is the major version number (always 3 for +** SQLite3) and Y is the minor version number and Z is the release number.)^ +** ^(The [SQLITE_VERSION_NUMBER] C preprocessor macro resolves to an integer +** with the value (X*1000000 + Y*1000 + Z) where X, Y, and Z are the same +** numbers used in [SQLITE_VERSION].)^ +** The SQLITE_VERSION_NUMBER for any given release of SQLite will also +** be larger than the release from which it is derived. Either Y will +** be held constant and Z will be incremented or else Y will be incremented +** and Z will be reset to zero. +** +** Since version 3.6.18, SQLite source code has been stored in the +** Fossil configuration management +** system. ^The SQLITE_SOURCE_ID macro evalutes to +** a string which identifies a particular check-in of SQLite +** within its configuration management system. ^The SQLITE_SOURCE_ID +** string contains the date and time of the check-in (UTC) and an SHA1 +** hash of the entire source tree. +** +** See also: [sqlite3_libversion()], +** [sqlite3_libversion_number()], [sqlite3_sourceid()], +** [sqlite_version()] and [sqlite_source_id()]. +*/ +#define SQLITE_VERSION "3.6.23.1" +#define SQLITE_VERSION_NUMBER 3006023 +#define SQLITE_SOURCE_ID "2010-03-26 22:28:06 b078b588d617e07886ad156e9f54ade6d823568e" + +/* +** CAPI3REF: Run-Time Library Version Numbers +** KEYWORDS: sqlite3_version, sqlite3_sourceid +** +** These interfaces provide the same information as the [SQLITE_VERSION], +** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros +** but are associated with the library instead of the header file. ^(Cautious +** programmers might include assert() statements in their application to +** verify that values returned by these interfaces match the macros in +** the header, and thus insure that the application is +** compiled with matching library and header files. +** +**
+** assert( sqlite3_libversion_number()==SQLITE_VERSION_NUMBER );
+** assert( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)==0 );
+** assert( strcmp(sqlite3_libversion(),SQLITE_VERSION)==0 );
+** 
)^ +** +** ^The sqlite3_version[] string constant contains the text of [SQLITE_VERSION] +** macro. ^The sqlite3_libversion() function returns a pointer to the +** to the sqlite3_version[] string constant. The sqlite3_libversion() +** function is provided for use in DLLs since DLL users usually do not have +** direct access to string constants within the DLL. ^The +** sqlite3_libversion_number() function returns an integer equal to +** [SQLITE_VERSION_NUMBER]. ^The sqlite3_sourceid() function returns +** a pointer to a string constant whose value is the same as the +** [SQLITE_SOURCE_ID] C preprocessor macro. +** +** See also: [sqlite_version()] and [sqlite_source_id()]. +*/ +SQLITE_API SQLITE_EXTERN const char sqlite3_version[]; +SQLITE_API const char *sqlite3_libversion(void); +SQLITE_API const char *sqlite3_sourceid(void); +SQLITE_API int sqlite3_libversion_number(void); + +#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS +/* +** CAPI3REF: Run-Time Library Compilation Options Diagnostics +** +** ^The sqlite3_compileoption_used() function returns 0 or 1 +** indicating whether the specified option was defined at +** compile time. ^The SQLITE_ prefix may be omitted from the +** option name passed to sqlite3_compileoption_used(). +** +** ^The sqlite3_compileoption_get() function allows interating +** over the list of options that were defined at compile time by +** returning the N-th compile time option string. ^If N is out of range, +** sqlite3_compileoption_get() returns a NULL pointer. ^The SQLITE_ +** prefix is omitted from any strings returned by +** sqlite3_compileoption_get(). +** +** ^Support for the diagnostic functions sqlite3_compileoption_used() +** and sqlite3_compileoption_get() may be omitted by specifing the +** [SQLITE_OMIT_COMPILEOPTION_DIAGS] option at compile time. +** +** See also: SQL functions [sqlite_compileoption_used()] and +** [sqlite_compileoption_get()] and the [compile_options pragma]. +*/ +SQLITE_API int sqlite3_compileoption_used(const char *zOptName); +SQLITE_API const char *sqlite3_compileoption_get(int N); +#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */ + +/* +** CAPI3REF: Test To See If The Library Is Threadsafe +** +** ^The sqlite3_threadsafe() function returns zero if and only if +** SQLite was compiled mutexing code omitted due to the +** [SQLITE_THREADSAFE] compile-time option being set to 0. +** +** SQLite can be compiled with or without mutexes. When +** the [SQLITE_THREADSAFE] C preprocessor macro is 1 or 2, mutexes +** are enabled and SQLite is threadsafe. When the +** [SQLITE_THREADSAFE] macro is 0, +** the mutexes are omitted. Without the mutexes, it is not safe +** to use SQLite concurrently from more than one thread. +** +** Enabling mutexes incurs a measurable performance penalty. +** So if speed is of utmost importance, it makes sense to disable +** the mutexes. But for maximum safety, mutexes should be enabled. +** ^The default behavior is for mutexes to be enabled. +** +** This interface can be used by an application to make sure that the +** version of SQLite that it is linking against was compiled with +** the desired setting of the [SQLITE_THREADSAFE] macro. +** +** This interface only reports on the compile-time mutex setting +** of the [SQLITE_THREADSAFE] flag. If SQLite is compiled with +** SQLITE_THREADSAFE=1 or =2 then mutexes are enabled by default but +** can be fully or partially disabled using a call to [sqlite3_config()] +** with the verbs [SQLITE_CONFIG_SINGLETHREAD], [SQLITE_CONFIG_MULTITHREAD], +** or [SQLITE_CONFIG_MUTEX]. ^(The return value of the +** sqlite3_threadsafe() function shows only the compile-time setting of +** thread safety, not any run-time changes to that setting made by +** sqlite3_config(). In other words, the return value from sqlite3_threadsafe() +** is unchanged by calls to sqlite3_config().)^ +** +** See the [threading mode] documentation for additional information. +*/ +SQLITE_API int sqlite3_threadsafe(void); + +/* +** CAPI3REF: Database Connection Handle +** KEYWORDS: {database connection} {database connections} +** +** Each open SQLite database is represented by a pointer to an instance of +** the opaque structure named "sqlite3". It is useful to think of an sqlite3 +** pointer as an object. The [sqlite3_open()], [sqlite3_open16()], and +** [sqlite3_open_v2()] interfaces are its constructors, and [sqlite3_close()] +** is its destructor. There are many other interfaces (such as +** [sqlite3_prepare_v2()], [sqlite3_create_function()], and +** [sqlite3_busy_timeout()] to name but three) that are methods on an +** sqlite3 object. +*/ +typedef struct sqlite3 sqlite3; + +/* +** CAPI3REF: 64-Bit Integer Types +** KEYWORDS: sqlite_int64 sqlite_uint64 +** +** Because there is no cross-platform way to specify 64-bit integer types +** SQLite includes typedefs for 64-bit signed and unsigned integers. +** +** The sqlite3_int64 and sqlite3_uint64 are the preferred type definitions. +** The sqlite_int64 and sqlite_uint64 types are supported for backwards +** compatibility only. +** +** ^The sqlite3_int64 and sqlite_int64 types can store integer values +** between -9223372036854775808 and +9223372036854775807 inclusive. ^The +** sqlite3_uint64 and sqlite_uint64 types can store integer values +** between 0 and +18446744073709551615 inclusive. +*/ +#ifdef SQLITE_INT64_TYPE + typedef SQLITE_INT64_TYPE sqlite_int64; + typedef unsigned SQLITE_INT64_TYPE sqlite_uint64; +#elif defined(_MSC_VER) || defined(__BORLANDC__) + typedef __int64 sqlite_int64; + typedef unsigned __int64 sqlite_uint64; +#else + typedef long long int sqlite_int64; + typedef unsigned long long int sqlite_uint64; +#endif +typedef sqlite_int64 sqlite3_int64; +typedef sqlite_uint64 sqlite3_uint64; + +/* +** If compiling for a processor that lacks floating point support, +** substitute integer for floating-point. +*/ +#ifdef SQLITE_OMIT_FLOATING_POINT +# define double sqlite3_int64 +#endif + +/* +** CAPI3REF: Closing A Database Connection +** +** ^The sqlite3_close() routine is the destructor for the [sqlite3] object. +** ^Calls to sqlite3_close() return SQLITE_OK if the [sqlite3] object is +** successfullly destroyed and all associated resources are deallocated. +** +** Applications must [sqlite3_finalize | finalize] all [prepared statements] +** and [sqlite3_blob_close | close] all [BLOB handles] associated with +** the [sqlite3] object prior to attempting to close the object. ^If +** sqlite3_close() is called on a [database connection] that still has +** outstanding [prepared statements] or [BLOB handles], then it returns +** SQLITE_BUSY. +** +** ^If [sqlite3_close()] is invoked while a transaction is open, +** the transaction is automatically rolled back. +** +** The C parameter to [sqlite3_close(C)] must be either a NULL +** pointer or an [sqlite3] object pointer obtained +** from [sqlite3_open()], [sqlite3_open16()], or +** [sqlite3_open_v2()], and not previously closed. +** ^Calling sqlite3_close() with a NULL pointer argument is a +** harmless no-op. +*/ +SQLITE_API int sqlite3_close(sqlite3 *); + +/* +** The type for a callback function. +** This is legacy and deprecated. It is included for historical +** compatibility and is not documented. +*/ +typedef int (*sqlite3_callback)(void*,int,char**, char**); + +/* +** CAPI3REF: One-Step Query Execution Interface +** +** The sqlite3_exec() interface is a convenience wrapper around +** [sqlite3_prepare_v2()], [sqlite3_step()], and [sqlite3_finalize()], +** that allows an application to run multiple statements of SQL +** without having to use a lot of C code. +** +** ^The sqlite3_exec() interface runs zero or more UTF-8 encoded, +** semicolon-separate SQL statements passed into its 2nd argument, +** in the context of the [database connection] passed in as its 1st +** argument. ^If the callback function of the 3rd argument to +** sqlite3_exec() is not NULL, then it is invoked for each result row +** coming out of the evaluated SQL statements. ^The 4th argument to +** to sqlite3_exec() is relayed through to the 1st argument of each +** callback invocation. ^If the callback pointer to sqlite3_exec() +** is NULL, then no callback is ever invoked and result rows are +** ignored. +** +** ^If an error occurs while evaluating the SQL statements passed into +** sqlite3_exec(), then execution of the current statement stops and +** subsequent statements are skipped. ^If the 5th parameter to sqlite3_exec() +** is not NULL then any error message is written into memory obtained +** from [sqlite3_malloc()] and passed back through the 5th parameter. +** To avoid memory leaks, the application should invoke [sqlite3_free()] +** on error message strings returned through the 5th parameter of +** of sqlite3_exec() after the error message string is no longer needed. +** ^If the 5th parameter to sqlite3_exec() is not NULL and no errors +** occur, then sqlite3_exec() sets the pointer in its 5th parameter to +** NULL before returning. +** +** ^If an sqlite3_exec() callback returns non-zero, the sqlite3_exec() +** routine returns SQLITE_ABORT without invoking the callback again and +** without running any subsequent SQL statements. +** +** ^The 2nd argument to the sqlite3_exec() callback function is the +** number of columns in the result. ^The 3rd argument to the sqlite3_exec() +** callback is an array of pointers to strings obtained as if from +** [sqlite3_column_text()], one for each column. ^If an element of a +** result row is NULL then the corresponding string pointer for the +** sqlite3_exec() callback is a NULL pointer. ^The 4th argument to the +** sqlite3_exec() callback is an array of pointers to strings where each +** entry represents the name of corresponding result column as obtained +** from [sqlite3_column_name()]. +** +** ^If the 2nd parameter to sqlite3_exec() is a NULL pointer, a pointer +** to an empty string, or a pointer that contains only whitespace and/or +** SQL comments, then no SQL statements are evaluated and the database +** is not changed. +** +** Restrictions: +** +**
    +**
  • The application must insure that the 1st parameter to sqlite3_exec() +** is a valid and open [database connection]. +**
  • The application must not close [database connection] specified by +** the 1st parameter to sqlite3_exec() while sqlite3_exec() is running. +**
  • The application must not modify the SQL statement text passed into +** the 2nd parameter of sqlite3_exec() while sqlite3_exec() is running. +**
+*/ +SQLITE_API int sqlite3_exec( + sqlite3*, /* An open database */ + const char *sql, /* SQL to be evaluated */ + int (*callback)(void*,int,char**,char**), /* Callback function */ + void *, /* 1st argument to callback */ + char **errmsg /* Error msg written here */ +); + +/* +** CAPI3REF: Result Codes +** KEYWORDS: SQLITE_OK {error code} {error codes} +** KEYWORDS: {result code} {result codes} +** +** Many SQLite functions return an integer result code from the set shown +** here in order to indicates success or failure. +** +** New error codes may be added in future versions of SQLite. +** +** See also: [SQLITE_IOERR_READ | extended result codes] +*/ +#define SQLITE_OK 0 /* Successful result */ +/* beginning-of-error-codes */ +#define SQLITE_ERROR 1 /* SQL error or missing database */ +#define SQLITE_INTERNAL 2 /* Internal logic error in SQLite */ +#define SQLITE_PERM 3 /* Access permission denied */ +#define SQLITE_ABORT 4 /* Callback routine requested an abort */ +#define SQLITE_BUSY 5 /* The database file is locked */ +#define SQLITE_LOCKED 6 /* A table in the database is locked */ +#define SQLITE_NOMEM 7 /* A malloc() failed */ +#define SQLITE_READONLY 8 /* Attempt to write a readonly database */ +#define SQLITE_INTERRUPT 9 /* Operation terminated by sqlite3_interrupt()*/ +#define SQLITE_IOERR 10 /* Some kind of disk I/O error occurred */ +#define SQLITE_CORRUPT 11 /* The database disk image is malformed */ +#define SQLITE_NOTFOUND 12 /* NOT USED. Table or record not found */ +#define SQLITE_FULL 13 /* Insertion failed because database is full */ +#define SQLITE_CANTOPEN 14 /* Unable to open the database file */ +#define SQLITE_PROTOCOL 15 /* NOT USED. Database lock protocol error */ +#define SQLITE_EMPTY 16 /* Database is empty */ +#define SQLITE_SCHEMA 17 /* The database schema changed */ +#define SQLITE_TOOBIG 18 /* String or BLOB exceeds size limit */ +#define SQLITE_CONSTRAINT 19 /* Abort due to constraint violation */ +#define SQLITE_MISMATCH 20 /* Data type mismatch */ +#define SQLITE_MISUSE 21 /* Library used incorrectly */ +#define SQLITE_NOLFS 22 /* Uses OS features not supported on host */ +#define SQLITE_AUTH 23 /* Authorization denied */ +#define SQLITE_FORMAT 24 /* Auxiliary database format error */ +#define SQLITE_RANGE 25 /* 2nd parameter to sqlite3_bind out of range */ +#define SQLITE_NOTADB 26 /* File opened that is not a database file */ +#define SQLITE_ROW 100 /* sqlite3_step() has another row ready */ +#define SQLITE_DONE 101 /* sqlite3_step() has finished executing */ +/* end-of-error-codes */ + +/* +** CAPI3REF: Extended Result Codes +** KEYWORDS: {extended error code} {extended error codes} +** KEYWORDS: {extended result code} {extended result codes} +** +** In its default configuration, SQLite API routines return one of 26 integer +** [SQLITE_OK | result codes]. However, experience has shown that many of +** these result codes are too coarse-grained. They do not provide as +** much information about problems as programmers might like. In an effort to +** address this, newer versions of SQLite (version 3.3.8 and later) include +** support for additional result codes that provide more detailed information +** about errors. The extended result codes are enabled or disabled +** on a per database connection basis using the +** [sqlite3_extended_result_codes()] API. +** +** Some of the available extended result codes are listed here. +** One may expect the number of extended result codes will be expand +** over time. Software that uses extended result codes should expect +** to see new result codes in future releases of SQLite. +** +** The SQLITE_OK result code will never be extended. It will always +** be exactly zero. +*/ +#define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8)) +#define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8)) +#define SQLITE_IOERR_WRITE (SQLITE_IOERR | (3<<8)) +#define SQLITE_IOERR_FSYNC (SQLITE_IOERR | (4<<8)) +#define SQLITE_IOERR_DIR_FSYNC (SQLITE_IOERR | (5<<8)) +#define SQLITE_IOERR_TRUNCATE (SQLITE_IOERR | (6<<8)) +#define SQLITE_IOERR_FSTAT (SQLITE_IOERR | (7<<8)) +#define SQLITE_IOERR_UNLOCK (SQLITE_IOERR | (8<<8)) +#define SQLITE_IOERR_RDLOCK (SQLITE_IOERR | (9<<8)) +#define SQLITE_IOERR_DELETE (SQLITE_IOERR | (10<<8)) +#define SQLITE_IOERR_BLOCKED (SQLITE_IOERR | (11<<8)) +#define SQLITE_IOERR_NOMEM (SQLITE_IOERR | (12<<8)) +#define SQLITE_IOERR_ACCESS (SQLITE_IOERR | (13<<8)) +#define SQLITE_IOERR_CHECKRESERVEDLOCK (SQLITE_IOERR | (14<<8)) +#define SQLITE_IOERR_LOCK (SQLITE_IOERR | (15<<8)) +#define SQLITE_IOERR_CLOSE (SQLITE_IOERR | (16<<8)) +#define SQLITE_IOERR_DIR_CLOSE (SQLITE_IOERR | (17<<8)) +#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8) ) + +/* +** CAPI3REF: Flags For File Open Operations +** +** These bit values are intended for use in the +** 3rd parameter to the [sqlite3_open_v2()] interface and +** in the 4th parameter to the xOpen method of the +** [sqlite3_vfs] object. +*/ +#define SQLITE_OPEN_READONLY 0x00000001 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_READWRITE 0x00000002 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_CREATE 0x00000004 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_DELETEONCLOSE 0x00000008 /* VFS only */ +#define SQLITE_OPEN_EXCLUSIVE 0x00000010 /* VFS only */ +#define SQLITE_OPEN_AUTOPROXY 0x00000020 /* VFS only */ +#define SQLITE_OPEN_MAIN_DB 0x00000100 /* VFS only */ +#define SQLITE_OPEN_TEMP_DB 0x00000200 /* VFS only */ +#define SQLITE_OPEN_TRANSIENT_DB 0x00000400 /* VFS only */ +#define SQLITE_OPEN_MAIN_JOURNAL 0x00000800 /* VFS only */ +#define SQLITE_OPEN_TEMP_JOURNAL 0x00001000 /* VFS only */ +#define SQLITE_OPEN_SUBJOURNAL 0x00002000 /* VFS only */ +#define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 /* VFS only */ +#define SQLITE_OPEN_NOMUTEX 0x00008000 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_FULLMUTEX 0x00010000 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_SHAREDCACHE 0x00020000 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_PRIVATECACHE 0x00040000 /* Ok for sqlite3_open_v2() */ + +/* +** CAPI3REF: Device Characteristics +** +** The xDeviceCapabilities method of the [sqlite3_io_methods] +** object returns an integer which is a vector of the these +** bit values expressing I/O characteristics of the mass storage +** device that holds the file that the [sqlite3_io_methods] +** refers to. +** +** The SQLITE_IOCAP_ATOMIC property means that all writes of +** any size are atomic. The SQLITE_IOCAP_ATOMICnnn values +** mean that writes of blocks that are nnn bytes in size and +** are aligned to an address which is an integer multiple of +** nnn are atomic. The SQLITE_IOCAP_SAFE_APPEND value means +** that when data is appended to a file, the data is appended +** first then the size of the file is extended, never the other +** way around. The SQLITE_IOCAP_SEQUENTIAL property means that +** information is written to disk in the same order as calls +** to xWrite(). +*/ +#define SQLITE_IOCAP_ATOMIC 0x00000001 +#define SQLITE_IOCAP_ATOMIC512 0x00000002 +#define SQLITE_IOCAP_ATOMIC1K 0x00000004 +#define SQLITE_IOCAP_ATOMIC2K 0x00000008 +#define SQLITE_IOCAP_ATOMIC4K 0x00000010 +#define SQLITE_IOCAP_ATOMIC8K 0x00000020 +#define SQLITE_IOCAP_ATOMIC16K 0x00000040 +#define SQLITE_IOCAP_ATOMIC32K 0x00000080 +#define SQLITE_IOCAP_ATOMIC64K 0x00000100 +#define SQLITE_IOCAP_SAFE_APPEND 0x00000200 +#define SQLITE_IOCAP_SEQUENTIAL 0x00000400 + +/* +** CAPI3REF: File Locking Levels +** +** SQLite uses one of these integer values as the second +** argument to calls it makes to the xLock() and xUnlock() methods +** of an [sqlite3_io_methods] object. +*/ +#define SQLITE_LOCK_NONE 0 +#define SQLITE_LOCK_SHARED 1 +#define SQLITE_LOCK_RESERVED 2 +#define SQLITE_LOCK_PENDING 3 +#define SQLITE_LOCK_EXCLUSIVE 4 + +/* +** CAPI3REF: Synchronization Type Flags +** +** When SQLite invokes the xSync() method of an +** [sqlite3_io_methods] object it uses a combination of +** these integer values as the second argument. +** +** When the SQLITE_SYNC_DATAONLY flag is used, it means that the +** sync operation only needs to flush data to mass storage. Inode +** information need not be flushed. If the lower four bits of the flag +** equal SQLITE_SYNC_NORMAL, that means to use normal fsync() semantics. +** If the lower four bits equal SQLITE_SYNC_FULL, that means +** to use Mac OS X style fullsync instead of fsync(). +*/ +#define SQLITE_SYNC_NORMAL 0x00002 +#define SQLITE_SYNC_FULL 0x00003 +#define SQLITE_SYNC_DATAONLY 0x00010 + +/* +** CAPI3REF: OS Interface Open File Handle +** +** An [sqlite3_file] object represents an open file in the +** [sqlite3_vfs | OS interface layer]. Individual OS interface +** implementations will +** want to subclass this object by appending additional fields +** for their own use. The pMethods entry is a pointer to an +** [sqlite3_io_methods] object that defines methods for performing +** I/O operations on the open file. +*/ +typedef struct sqlite3_file sqlite3_file; +struct sqlite3_file { + const struct sqlite3_io_methods *pMethods; /* Methods for an open file */ +}; + +/* +** CAPI3REF: OS Interface File Virtual Methods Object +** +** Every file opened by the [sqlite3_vfs] xOpen method populates an +** [sqlite3_file] object (or, more commonly, a subclass of the +** [sqlite3_file] object) with a pointer to an instance of this object. +** This object defines the methods used to perform various operations +** against the open file represented by the [sqlite3_file] object. +** +** If the xOpen method sets the sqlite3_file.pMethods element +** to a non-NULL pointer, then the sqlite3_io_methods.xClose method +** may be invoked even if the xOpen reported that it failed. The +** only way to prevent a call to xClose following a failed xOpen +** is for the xOpen to set the sqlite3_file.pMethods element to NULL. +** +** The flags argument to xSync may be one of [SQLITE_SYNC_NORMAL] or +** [SQLITE_SYNC_FULL]. The first choice is the normal fsync(). +** The second choice is a Mac OS X style fullsync. The [SQLITE_SYNC_DATAONLY] +** flag may be ORed in to indicate that only the data of the file +** and not its inode needs to be synced. +** +** The integer values to xLock() and xUnlock() are one of +**
    +**
  • [SQLITE_LOCK_NONE], +**
  • [SQLITE_LOCK_SHARED], +**
  • [SQLITE_LOCK_RESERVED], +**
  • [SQLITE_LOCK_PENDING], or +**
  • [SQLITE_LOCK_EXCLUSIVE]. +**
+** xLock() increases the lock. xUnlock() decreases the lock. +** The xCheckReservedLock() method checks whether any database connection, +** either in this process or in some other process, is holding a RESERVED, +** PENDING, or EXCLUSIVE lock on the file. It returns true +** if such a lock exists and false otherwise. +** +** The xFileControl() method is a generic interface that allows custom +** VFS implementations to directly control an open file using the +** [sqlite3_file_control()] interface. The second "op" argument is an +** integer opcode. The third argument is a generic pointer intended to +** point to a structure that may contain arguments or space in which to +** write return values. Potential uses for xFileControl() might be +** functions to enable blocking locks with timeouts, to change the +** locking strategy (for example to use dot-file locks), to inquire +** about the status of a lock, or to break stale locks. The SQLite +** core reserves all opcodes less than 100 for its own use. +** A [SQLITE_FCNTL_LOCKSTATE | list of opcodes] less than 100 is available. +** Applications that define a custom xFileControl method should use opcodes +** greater than 100 to avoid conflicts. +** +** The xSectorSize() method returns the sector size of the +** device that underlies the file. The sector size is the +** minimum write that can be performed without disturbing +** other bytes in the file. The xDeviceCharacteristics() +** method returns a bit vector describing behaviors of the +** underlying device: +** +**
    +**
  • [SQLITE_IOCAP_ATOMIC] +**
  • [SQLITE_IOCAP_ATOMIC512] +**
  • [SQLITE_IOCAP_ATOMIC1K] +**
  • [SQLITE_IOCAP_ATOMIC2K] +**
  • [SQLITE_IOCAP_ATOMIC4K] +**
  • [SQLITE_IOCAP_ATOMIC8K] +**
  • [SQLITE_IOCAP_ATOMIC16K] +**
  • [SQLITE_IOCAP_ATOMIC32K] +**
  • [SQLITE_IOCAP_ATOMIC64K] +**
  • [SQLITE_IOCAP_SAFE_APPEND] +**
  • [SQLITE_IOCAP_SEQUENTIAL] +**
+** +** The SQLITE_IOCAP_ATOMIC property means that all writes of +** any size are atomic. The SQLITE_IOCAP_ATOMICnnn values +** mean that writes of blocks that are nnn bytes in size and +** are aligned to an address which is an integer multiple of +** nnn are atomic. The SQLITE_IOCAP_SAFE_APPEND value means +** that when data is appended to a file, the data is appended +** first then the size of the file is extended, never the other +** way around. The SQLITE_IOCAP_SEQUENTIAL property means that +** information is written to disk in the same order as calls +** to xWrite(). +** +** If xRead() returns SQLITE_IOERR_SHORT_READ it must also fill +** in the unread portions of the buffer with zeros. A VFS that +** fails to zero-fill short reads might seem to work. However, +** failure to zero-fill short reads will eventually lead to +** database corruption. +*/ +typedef struct sqlite3_io_methods sqlite3_io_methods; +struct sqlite3_io_methods { + int iVersion; + int (*xClose)(sqlite3_file*); + int (*xRead)(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); + int (*xWrite)(sqlite3_file*, const void*, int iAmt, sqlite3_int64 iOfst); + int (*xTruncate)(sqlite3_file*, sqlite3_int64 size); + int (*xSync)(sqlite3_file*, int flags); + int (*xFileSize)(sqlite3_file*, sqlite3_int64 *pSize); + int (*xLock)(sqlite3_file*, int); + int (*xUnlock)(sqlite3_file*, int); + int (*xCheckReservedLock)(sqlite3_file*, int *pResOut); + int (*xFileControl)(sqlite3_file*, int op, void *pArg); + int (*xSectorSize)(sqlite3_file*); + int (*xDeviceCharacteristics)(sqlite3_file*); + /* Additional methods may be added in future releases */ +}; + +/* +** CAPI3REF: Standard File Control Opcodes +** +** These integer constants are opcodes for the xFileControl method +** of the [sqlite3_io_methods] object and for the [sqlite3_file_control()] +** interface. +** +** The [SQLITE_FCNTL_LOCKSTATE] opcode is used for debugging. This +** opcode causes the xFileControl method to write the current state of +** the lock (one of [SQLITE_LOCK_NONE], [SQLITE_LOCK_SHARED], +** [SQLITE_LOCK_RESERVED], [SQLITE_LOCK_PENDING], or [SQLITE_LOCK_EXCLUSIVE]) +** into an integer that the pArg argument points to. This capability +** is used during testing and only needs to be supported when SQLITE_TEST +** is defined. +*/ +#define SQLITE_FCNTL_LOCKSTATE 1 +#define SQLITE_GET_LOCKPROXYFILE 2 +#define SQLITE_SET_LOCKPROXYFILE 3 +#define SQLITE_LAST_ERRNO 4 + +/* +** CAPI3REF: Mutex Handle +** +** The mutex module within SQLite defines [sqlite3_mutex] to be an +** abstract type for a mutex object. The SQLite core never looks +** at the internal representation of an [sqlite3_mutex]. It only +** deals with pointers to the [sqlite3_mutex] object. +** +** Mutexes are created using [sqlite3_mutex_alloc()]. +*/ +typedef struct sqlite3_mutex sqlite3_mutex; + +/* +** CAPI3REF: OS Interface Object +** +** An instance of the sqlite3_vfs object defines the interface between +** the SQLite core and the underlying operating system. The "vfs" +** in the name of the object stands for "virtual file system". +** +** The value of the iVersion field is initially 1 but may be larger in +** future versions of SQLite. Additional fields may be appended to this +** object when the iVersion value is increased. Note that the structure +** of the sqlite3_vfs object changes in the transaction between +** SQLite version 3.5.9 and 3.6.0 and yet the iVersion field was not +** modified. +** +** The szOsFile field is the size of the subclassed [sqlite3_file] +** structure used by this VFS. mxPathname is the maximum length of +** a pathname in this VFS. +** +** Registered sqlite3_vfs objects are kept on a linked list formed by +** the pNext pointer. The [sqlite3_vfs_register()] +** and [sqlite3_vfs_unregister()] interfaces manage this list +** in a thread-safe way. The [sqlite3_vfs_find()] interface +** searches the list. Neither the application code nor the VFS +** implementation should use the pNext pointer. +** +** The pNext field is the only field in the sqlite3_vfs +** structure that SQLite will ever modify. SQLite will only access +** or modify this field while holding a particular static mutex. +** The application should never modify anything within the sqlite3_vfs +** object once the object has been registered. +** +** The zName field holds the name of the VFS module. The name must +** be unique across all VFS modules. +** +** SQLite will guarantee that the zFilename parameter to xOpen +** is either a NULL pointer or string obtained +** from xFullPathname(). SQLite further guarantees that +** the string will be valid and unchanged until xClose() is +** called. Because of the previous sentence, +** the [sqlite3_file] can safely store a pointer to the +** filename if it needs to remember the filename for some reason. +** If the zFilename parameter is xOpen is a NULL pointer then xOpen +** must invent its own temporary name for the file. Whenever the +** xFilename parameter is NULL it will also be the case that the +** flags parameter will include [SQLITE_OPEN_DELETEONCLOSE]. +** +** The flags argument to xOpen() includes all bits set in +** the flags argument to [sqlite3_open_v2()]. Or if [sqlite3_open()] +** or [sqlite3_open16()] is used, then flags includes at least +** [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]. +** If xOpen() opens a file read-only then it sets *pOutFlags to +** include [SQLITE_OPEN_READONLY]. Other bits in *pOutFlags may be set. +** +** SQLite will also add one of the following flags to the xOpen() +** call, depending on the object being opened: +** +**
    +**
  • [SQLITE_OPEN_MAIN_DB] +**
  • [SQLITE_OPEN_MAIN_JOURNAL] +**
  • [SQLITE_OPEN_TEMP_DB] +**
  • [SQLITE_OPEN_TEMP_JOURNAL] +**
  • [SQLITE_OPEN_TRANSIENT_DB] +**
  • [SQLITE_OPEN_SUBJOURNAL] +**
  • [SQLITE_OPEN_MASTER_JOURNAL] +**
+** +** The file I/O implementation can use the object type flags to +** change the way it deals with files. For example, an application +** that does not care about crash recovery or rollback might make +** the open of a journal file a no-op. Writes to this journal would +** also be no-ops, and any attempt to read the journal would return +** SQLITE_IOERR. Or the implementation might recognize that a database +** file will be doing page-aligned sector reads and writes in a random +** order and set up its I/O subsystem accordingly. +** +** SQLite might also add one of the following flags to the xOpen method: +** +**
    +**
  • [SQLITE_OPEN_DELETEONCLOSE] +**
  • [SQLITE_OPEN_EXCLUSIVE] +**
+** +** The [SQLITE_OPEN_DELETEONCLOSE] flag means the file should be +** deleted when it is closed. The [SQLITE_OPEN_DELETEONCLOSE] +** will be set for TEMP databases, journals and for subjournals. +** +** The [SQLITE_OPEN_EXCLUSIVE] flag is always used in conjunction +** with the [SQLITE_OPEN_CREATE] flag, which are both directly +** analogous to the O_EXCL and O_CREAT flags of the POSIX open() +** API. The SQLITE_OPEN_EXCLUSIVE flag, when paired with the +** SQLITE_OPEN_CREATE, is used to indicate that file should always +** be created, and that it is an error if it already exists. +** It is not used to indicate the file should be opened +** for exclusive access. +** +** At least szOsFile bytes of memory are allocated by SQLite +** to hold the [sqlite3_file] structure passed as the third +** argument to xOpen. The xOpen method does not have to +** allocate the structure; it should just fill it in. Note that +** the xOpen method must set the sqlite3_file.pMethods to either +** a valid [sqlite3_io_methods] object or to NULL. xOpen must do +** this even if the open fails. SQLite expects that the sqlite3_file.pMethods +** element will be valid after xOpen returns regardless of the success +** or failure of the xOpen call. +** +** The flags argument to xAccess() may be [SQLITE_ACCESS_EXISTS] +** to test for the existence of a file, or [SQLITE_ACCESS_READWRITE] to +** test whether a file is readable and writable, or [SQLITE_ACCESS_READ] +** to test whether a file is at least readable. The file can be a +** directory. +** +** SQLite will always allocate at least mxPathname+1 bytes for the +** output buffer xFullPathname. The exact size of the output buffer +** is also passed as a parameter to both methods. If the output buffer +** is not large enough, [SQLITE_CANTOPEN] should be returned. Since this is +** handled as a fatal error by SQLite, vfs implementations should endeavor +** to prevent this by setting mxPathname to a sufficiently large value. +** +** The xRandomness(), xSleep(), and xCurrentTime() interfaces +** are not strictly a part of the filesystem, but they are +** included in the VFS structure for completeness. +** The xRandomness() function attempts to return nBytes bytes +** of good-quality randomness into zOut. The return value is +** the actual number of bytes of randomness obtained. +** The xSleep() method causes the calling thread to sleep for at +** least the number of microseconds given. The xCurrentTime() +** method returns a Julian Day Number for the current date and time. +** +*/ +typedef struct sqlite3_vfs sqlite3_vfs; +struct sqlite3_vfs { + int iVersion; /* Structure version number */ + int szOsFile; /* Size of subclassed sqlite3_file */ + int mxPathname; /* Maximum file pathname length */ + sqlite3_vfs *pNext; /* Next registered VFS */ + const char *zName; /* Name of this virtual file system */ + void *pAppData; /* Pointer to application-specific data */ + int (*xOpen)(sqlite3_vfs*, const char *zName, sqlite3_file*, + int flags, int *pOutFlags); + int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir); + int (*xAccess)(sqlite3_vfs*, const char *zName, int flags, int *pResOut); + int (*xFullPathname)(sqlite3_vfs*, const char *zName, int nOut, char *zOut); + void *(*xDlOpen)(sqlite3_vfs*, const char *zFilename); + void (*xDlError)(sqlite3_vfs*, int nByte, char *zErrMsg); + void (*(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol))(void); + void (*xDlClose)(sqlite3_vfs*, void*); + int (*xRandomness)(sqlite3_vfs*, int nByte, char *zOut); + int (*xSleep)(sqlite3_vfs*, int microseconds); + int (*xCurrentTime)(sqlite3_vfs*, double*); + int (*xGetLastError)(sqlite3_vfs*, int, char *); + /* New fields may be appended in figure versions. The iVersion + ** value will increment whenever this happens. */ +}; + +/* +** CAPI3REF: Flags for the xAccess VFS method +** +** These integer constants can be used as the third parameter to +** the xAccess method of an [sqlite3_vfs] object. They determine +** what kind of permissions the xAccess method is looking for. +** With SQLITE_ACCESS_EXISTS, the xAccess method +** simply checks whether the file exists. +** With SQLITE_ACCESS_READWRITE, the xAccess method +** checks whether the file is both readable and writable. +** With SQLITE_ACCESS_READ, the xAccess method +** checks whether the file is readable. +*/ +#define SQLITE_ACCESS_EXISTS 0 +#define SQLITE_ACCESS_READWRITE 1 +#define SQLITE_ACCESS_READ 2 + +/* +** CAPI3REF: Initialize The SQLite Library +** +** ^The sqlite3_initialize() routine initializes the +** SQLite library. ^The sqlite3_shutdown() routine +** deallocates any resources that were allocated by sqlite3_initialize(). +** These routines are designed to aid in process initialization and +** shutdown on embedded systems. Workstation applications using +** SQLite normally do not need to invoke either of these routines. +** +** A call to sqlite3_initialize() is an "effective" call if it is +** the first time sqlite3_initialize() is invoked during the lifetime of +** the process, or if it is the first time sqlite3_initialize() is invoked +** following a call to sqlite3_shutdown(). ^(Only an effective call +** of sqlite3_initialize() does any initialization. All other calls +** are harmless no-ops.)^ +** +** A call to sqlite3_shutdown() is an "effective" call if it is the first +** call to sqlite3_shutdown() since the last sqlite3_initialize(). ^(Only +** an effective call to sqlite3_shutdown() does any deinitialization. +** All other valid calls to sqlite3_shutdown() are harmless no-ops.)^ +** +** The sqlite3_initialize() interface is threadsafe, but sqlite3_shutdown() +** is not. The sqlite3_shutdown() interface must only be called from a +** single thread. All open [database connections] must be closed and all +** other SQLite resources must be deallocated prior to invoking +** sqlite3_shutdown(). +** +** Among other things, ^sqlite3_initialize() will invoke +** sqlite3_os_init(). Similarly, ^sqlite3_shutdown() +** will invoke sqlite3_os_end(). +** +** ^The sqlite3_initialize() routine returns [SQLITE_OK] on success. +** ^If for some reason, sqlite3_initialize() is unable to initialize +** the library (perhaps it is unable to allocate a needed resource such +** as a mutex) it returns an [error code] other than [SQLITE_OK]. +** +** ^The sqlite3_initialize() routine is called internally by many other +** SQLite interfaces so that an application usually does not need to +** invoke sqlite3_initialize() directly. For example, [sqlite3_open()] +** calls sqlite3_initialize() so the SQLite library will be automatically +** initialized when [sqlite3_open()] is called if it has not be initialized +** already. ^However, if SQLite is compiled with the [SQLITE_OMIT_AUTOINIT] +** compile-time option, then the automatic calls to sqlite3_initialize() +** are omitted and the application must call sqlite3_initialize() directly +** prior to using any other SQLite interface. For maximum portability, +** it is recommended that applications always invoke sqlite3_initialize() +** directly prior to using any other SQLite interface. Future releases +** of SQLite may require this. In other words, the behavior exhibited +** when SQLite is compiled with [SQLITE_OMIT_AUTOINIT] might become the +** default behavior in some future release of SQLite. +** +** The sqlite3_os_init() routine does operating-system specific +** initialization of the SQLite library. The sqlite3_os_end() +** routine undoes the effect of sqlite3_os_init(). Typical tasks +** performed by these routines include allocation or deallocation +** of static resources, initialization of global variables, +** setting up a default [sqlite3_vfs] module, or setting up +** a default configuration using [sqlite3_config()]. +** +** The application should never invoke either sqlite3_os_init() +** or sqlite3_os_end() directly. The application should only invoke +** sqlite3_initialize() and sqlite3_shutdown(). The sqlite3_os_init() +** interface is called automatically by sqlite3_initialize() and +** sqlite3_os_end() is called by sqlite3_shutdown(). Appropriate +** implementations for sqlite3_os_init() and sqlite3_os_end() +** are built into SQLite when it is compiled for Unix, Windows, or OS/2. +** When [custom builds | built for other platforms] +** (using the [SQLITE_OS_OTHER=1] compile-time +** option) the application must supply a suitable implementation for +** sqlite3_os_init() and sqlite3_os_end(). An application-supplied +** implementation of sqlite3_os_init() or sqlite3_os_end() +** must return [SQLITE_OK] on success and some other [error code] upon +** failure. +*/ +SQLITE_API int sqlite3_initialize(void); +SQLITE_API int sqlite3_shutdown(void); +SQLITE_API int sqlite3_os_init(void); +SQLITE_API int sqlite3_os_end(void); + +/* +** CAPI3REF: Configuring The SQLite Library +** +** The sqlite3_config() interface is used to make global configuration +** changes to SQLite in order to tune SQLite to the specific needs of +** the application. The default configuration is recommended for most +** applications and so this routine is usually not necessary. It is +** provided to support rare applications with unusual needs. +** +** The sqlite3_config() interface is not threadsafe. The application +** must insure that no other SQLite interfaces are invoked by other +** threads while sqlite3_config() is running. Furthermore, sqlite3_config() +** may only be invoked prior to library initialization using +** [sqlite3_initialize()] or after shutdown by [sqlite3_shutdown()]. +** ^If sqlite3_config() is called after [sqlite3_initialize()] and before +** [sqlite3_shutdown()] then it will return SQLITE_MISUSE. +** Note, however, that ^sqlite3_config() can be called as part of the +** implementation of an application-defined [sqlite3_os_init()]. +** +** The first argument to sqlite3_config() is an integer +** [SQLITE_CONFIG_SINGLETHREAD | configuration option] that determines +** what property of SQLite is to be configured. Subsequent arguments +** vary depending on the [SQLITE_CONFIG_SINGLETHREAD | configuration option] +** in the first argument. +** +** ^When a configuration option is set, sqlite3_config() returns [SQLITE_OK]. +** ^If the option is unknown or SQLite is unable to set the option +** then this routine returns a non-zero [error code]. +*/ +SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_config(int, ...); + +/* +** CAPI3REF: Configure database connections +** EXPERIMENTAL +** +** The sqlite3_db_config() interface is used to make configuration +** changes to a [database connection]. The interface is similar to +** [sqlite3_config()] except that the changes apply to a single +** [database connection] (specified in the first argument). The +** sqlite3_db_config() interface should only be used immediately after +** the database connection is created using [sqlite3_open()], +** [sqlite3_open16()], or [sqlite3_open_v2()]. +** +** The second argument to sqlite3_db_config(D,V,...) is the +** configuration verb - an integer code that indicates what +** aspect of the [database connection] is being configured. +** The only choice for this value is [SQLITE_DBCONFIG_LOOKASIDE]. +** New verbs are likely to be added in future releases of SQLite. +** Additional arguments depend on the verb. +** +** ^Calls to sqlite3_db_config() return SQLITE_OK if and only if +** the call is considered successful. +*/ +SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_db_config(sqlite3*, int op, ...); + +/* +** CAPI3REF: Memory Allocation Routines +** EXPERIMENTAL +** +** An instance of this object defines the interface between SQLite +** and low-level memory allocation routines. +** +** This object is used in only one place in the SQLite interface. +** A pointer to an instance of this object is the argument to +** [sqlite3_config()] when the configuration option is +** [SQLITE_CONFIG_MALLOC] or [SQLITE_CONFIG_GETMALLOC]. +** By creating an instance of this object +** and passing it to [sqlite3_config]([SQLITE_CONFIG_MALLOC]) +** during configuration, an application can specify an alternative +** memory allocation subsystem for SQLite to use for all of its +** dynamic memory needs. +** +** Note that SQLite comes with several [built-in memory allocators] +** that are perfectly adequate for the overwhelming majority of applications +** and that this object is only useful to a tiny minority of applications +** with specialized memory allocation requirements. This object is +** also used during testing of SQLite in order to specify an alternative +** memory allocator that simulates memory out-of-memory conditions in +** order to verify that SQLite recovers gracefully from such +** conditions. +** +** The xMalloc and xFree methods must work like the +** malloc() and free() functions from the standard C library. +** The xRealloc method must work like realloc() from the standard C library +** with the exception that if the second argument to xRealloc is zero, +** xRealloc must be a no-op - it must not perform any allocation or +** deallocation. ^SQLite guarantees that the second argument to +** xRealloc is always a value returned by a prior call to xRoundup. +** And so in cases where xRoundup always returns a positive number, +** xRealloc can perform exactly as the standard library realloc() and +** still be in compliance with this specification. +** +** xSize should return the allocated size of a memory allocation +** previously obtained from xMalloc or xRealloc. The allocated size +** is always at least as big as the requested size but may be larger. +** +** The xRoundup method returns what would be the allocated size of +** a memory allocation given a particular requested size. Most memory +** allocators round up memory allocations at least to the next multiple +** of 8. Some allocators round up to a larger multiple or to a power of 2. +** Every memory allocation request coming in through [sqlite3_malloc()] +** or [sqlite3_realloc()] first calls xRoundup. If xRoundup returns 0, +** that causes the corresponding memory allocation to fail. +** +** The xInit method initializes the memory allocator. (For example, +** it might allocate any require mutexes or initialize internal data +** structures. The xShutdown method is invoked (indirectly) by +** [sqlite3_shutdown()] and should deallocate any resources acquired +** by xInit. The pAppData pointer is used as the only parameter to +** xInit and xShutdown. +** +** SQLite holds the [SQLITE_MUTEX_STATIC_MASTER] mutex when it invokes +** the xInit method, so the xInit method need not be threadsafe. The +** xShutdown method is only called from [sqlite3_shutdown()] so it does +** not need to be threadsafe either. For all other methods, SQLite +** holds the [SQLITE_MUTEX_STATIC_MEM] mutex as long as the +** [SQLITE_CONFIG_MEMSTATUS] configuration option is turned on (which +** it is by default) and so the methods are automatically serialized. +** However, if [SQLITE_CONFIG_MEMSTATUS] is disabled, then the other +** methods must be threadsafe or else make their own arrangements for +** serialization. +** +** SQLite will never invoke xInit() more than once without an intervening +** call to xShutdown(). +*/ +typedef struct sqlite3_mem_methods sqlite3_mem_methods; +struct sqlite3_mem_methods { + void *(*xMalloc)(int); /* Memory allocation function */ + void (*xFree)(void*); /* Free a prior allocation */ + void *(*xRealloc)(void*,int); /* Resize an allocation */ + int (*xSize)(void*); /* Return the size of an allocation */ + int (*xRoundup)(int); /* Round up request size to allocation size */ + int (*xInit)(void*); /* Initialize the memory allocator */ + void (*xShutdown)(void*); /* Deinitialize the memory allocator */ + void *pAppData; /* Argument to xInit() and xShutdown() */ +}; + +/* +** CAPI3REF: Configuration Options +** EXPERIMENTAL +** +** These constants are the available integer configuration options that +** can be passed as the first argument to the [sqlite3_config()] interface. +** +** New configuration options may be added in future releases of SQLite. +** Existing configuration options might be discontinued. Applications +** should check the return code from [sqlite3_config()] to make sure that +** the call worked. The [sqlite3_config()] interface will return a +** non-zero [error code] if a discontinued or unsupported configuration option +** is invoked. +** +**
+**
SQLITE_CONFIG_SINGLETHREAD
+**
There are no arguments to this option. ^This option sets the +** [threading mode] to Single-thread. In other words, it disables +** all mutexing and puts SQLite into a mode where it can only be used +** by a single thread. ^If SQLite is compiled with +** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then +** it is not possible to change the [threading mode] from its default +** value of Single-thread and so [sqlite3_config()] will return +** [SQLITE_ERROR] if called with the SQLITE_CONFIG_SINGLETHREAD +** configuration option.
+** +**
SQLITE_CONFIG_MULTITHREAD
+**
There are no arguments to this option. ^This option sets the +** [threading mode] to Multi-thread. In other words, it disables +** mutexing on [database connection] and [prepared statement] objects. +** The application is responsible for serializing access to +** [database connections] and [prepared statements]. But other mutexes +** are enabled so that SQLite will be safe to use in a multi-threaded +** environment as long as no two threads attempt to use the same +** [database connection] at the same time. ^If SQLite is compiled with +** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then +** it is not possible to set the Multi-thread [threading mode] and +** [sqlite3_config()] will return [SQLITE_ERROR] if called with the +** SQLITE_CONFIG_MULTITHREAD configuration option.
+** +**
SQLITE_CONFIG_SERIALIZED
+**
There are no arguments to this option. ^This option sets the +** [threading mode] to Serialized. In other words, this option enables +** all mutexes including the recursive +** mutexes on [database connection] and [prepared statement] objects. +** In this mode (which is the default when SQLite is compiled with +** [SQLITE_THREADSAFE=1]) the SQLite library will itself serialize access +** to [database connections] and [prepared statements] so that the +** application is free to use the same [database connection] or the +** same [prepared statement] in different threads at the same time. +** ^If SQLite is compiled with +** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then +** it is not possible to set the Serialized [threading mode] and +** [sqlite3_config()] will return [SQLITE_ERROR] if called with the +** SQLITE_CONFIG_SERIALIZED configuration option.
+** +**
SQLITE_CONFIG_MALLOC
+**
^(This option takes a single argument which is a pointer to an +** instance of the [sqlite3_mem_methods] structure. The argument specifies +** alternative low-level memory allocation routines to be used in place of +** the memory allocation routines built into SQLite.)^ ^SQLite makes +** its own private copy of the content of the [sqlite3_mem_methods] structure +** before the [sqlite3_config()] call returns.
+** +**
SQLITE_CONFIG_GETMALLOC
+**
^(This option takes a single argument which is a pointer to an +** instance of the [sqlite3_mem_methods] structure. The [sqlite3_mem_methods] +** structure is filled with the currently defined memory allocation routines.)^ +** This option can be used to overload the default memory allocation +** routines with a wrapper that simulations memory allocation failure or +** tracks memory usage, for example.
+** +**
SQLITE_CONFIG_MEMSTATUS
+**
^This option takes single argument of type int, interpreted as a +** boolean, which enables or disables the collection of memory allocation +** statistics. ^(When memory allocation statistics are disabled, the +** following SQLite interfaces become non-operational: +**
    +**
  • [sqlite3_memory_used()] +**
  • [sqlite3_memory_highwater()] +**
  • [sqlite3_soft_heap_limit()] +**
  • [sqlite3_status()] +**
)^ +** ^Memory allocation statistics are enabled by default unless SQLite is +** compiled with [SQLITE_DEFAULT_MEMSTATUS]=0 in which case memory +** allocation statistics are disabled by default. +**
+** +**
SQLITE_CONFIG_SCRATCH
+**
^This option specifies a static memory buffer that SQLite can use for +** scratch memory. There are three arguments: A pointer an 8-byte +** aligned memory buffer from which the scrach allocations will be +** drawn, the size of each scratch allocation (sz), +** and the maximum number of scratch allocations (N). The sz +** argument must be a multiple of 16. The sz parameter should be a few bytes +** larger than the actual scratch space required due to internal overhead. +** The first argument must be a pointer to an 8-byte aligned buffer +** of at least sz*N bytes of memory. +** ^SQLite will use no more than one scratch buffer per thread. So +** N should be set to the expected maximum number of threads. ^SQLite will +** never require a scratch buffer that is more than 6 times the database +** page size. ^If SQLite needs needs additional scratch memory beyond +** what is provided by this configuration option, then +** [sqlite3_malloc()] will be used to obtain the memory needed.
+** +**
SQLITE_CONFIG_PAGECACHE
+**
^This option specifies a static memory buffer that SQLite can use for +** the database page cache with the default page cache implemenation. +** This configuration should not be used if an application-define page +** cache implementation is loaded using the SQLITE_CONFIG_PCACHE option. +** There are three arguments to this option: A pointer to 8-byte aligned +** memory, the size of each page buffer (sz), and the number of pages (N). +** The sz argument should be the size of the largest database page +** (a power of two between 512 and 32768) plus a little extra for each +** page header. ^The page header size is 20 to 40 bytes depending on +** the host architecture. ^It is harmless, apart from the wasted memory, +** to make sz a little too large. The first +** argument should point to an allocation of at least sz*N bytes of memory. +** ^SQLite will use the memory provided by the first argument to satisfy its +** memory needs for the first N pages that it adds to cache. ^If additional +** page cache memory is needed beyond what is provided by this option, then +** SQLite goes to [sqlite3_malloc()] for the additional storage space. +** ^The implementation might use one or more of the N buffers to hold +** memory accounting information. The pointer in the first argument must +** be aligned to an 8-byte boundary or subsequent behavior of SQLite +** will be undefined.
+** +**
SQLITE_CONFIG_HEAP
+**
^This option specifies a static memory buffer that SQLite will use +** for all of its dynamic memory allocation needs beyond those provided +** for by [SQLITE_CONFIG_SCRATCH] and [SQLITE_CONFIG_PAGECACHE]. +** There are three arguments: An 8-byte aligned pointer to the memory, +** the number of bytes in the memory buffer, and the minimum allocation size. +** ^If the first pointer (the memory pointer) is NULL, then SQLite reverts +** to using its default memory allocator (the system malloc() implementation), +** undoing any prior invocation of [SQLITE_CONFIG_MALLOC]. ^If the +** memory pointer is not NULL and either [SQLITE_ENABLE_MEMSYS3] or +** [SQLITE_ENABLE_MEMSYS5] are defined, then the alternative memory +** allocator is engaged to handle all of SQLites memory allocation needs. +** The first pointer (the memory pointer) must be aligned to an 8-byte +** boundary or subsequent behavior of SQLite will be undefined.
+** +**
SQLITE_CONFIG_MUTEX
+**
^(This option takes a single argument which is a pointer to an +** instance of the [sqlite3_mutex_methods] structure. The argument specifies +** alternative low-level mutex routines to be used in place +** the mutex routines built into SQLite.)^ ^SQLite makes a copy of the +** content of the [sqlite3_mutex_methods] structure before the call to +** [sqlite3_config()] returns. ^If SQLite is compiled with +** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then +** the entire mutexing subsystem is omitted from the build and hence calls to +** [sqlite3_config()] with the SQLITE_CONFIG_MUTEX configuration option will +** return [SQLITE_ERROR].
+** +**
SQLITE_CONFIG_GETMUTEX
+**
^(This option takes a single argument which is a pointer to an +** instance of the [sqlite3_mutex_methods] structure. The +** [sqlite3_mutex_methods] +** structure is filled with the currently defined mutex routines.)^ +** This option can be used to overload the default mutex allocation +** routines with a wrapper used to track mutex usage for performance +** profiling or testing, for example. ^If SQLite is compiled with +** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then +** the entire mutexing subsystem is omitted from the build and hence calls to +** [sqlite3_config()] with the SQLITE_CONFIG_GETMUTEX configuration option will +** return [SQLITE_ERROR].
+** +**
SQLITE_CONFIG_LOOKASIDE
+**
^(This option takes two arguments that determine the default +** memory allocation for the lookaside memory allocator on each +** [database connection]. The first argument is the +** size of each lookaside buffer slot and the second is the number of +** slots allocated to each database connection.)^ ^(This option sets the +** default lookaside size. The [SQLITE_DBCONFIG_LOOKASIDE] +** verb to [sqlite3_db_config()] can be used to change the lookaside +** configuration on individual connections.)^
+** +**
SQLITE_CONFIG_PCACHE
+**
^(This option takes a single argument which is a pointer to +** an [sqlite3_pcache_methods] object. This object specifies the interface +** to a custom page cache implementation.)^ ^SQLite makes a copy of the +** object and uses it for page cache memory allocations.
+** +**
SQLITE_CONFIG_GETPCACHE
+**
^(This option takes a single argument which is a pointer to an +** [sqlite3_pcache_methods] object. SQLite copies of the current +** page cache implementation into that object.)^
+** +**
+*/ +#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ +#define SQLITE_CONFIG_MULTITHREAD 2 /* nil */ +#define SQLITE_CONFIG_SERIALIZED 3 /* nil */ +#define SQLITE_CONFIG_MALLOC 4 /* sqlite3_mem_methods* */ +#define SQLITE_CONFIG_GETMALLOC 5 /* sqlite3_mem_methods* */ +#define SQLITE_CONFIG_SCRATCH 6 /* void*, int sz, int N */ +#define SQLITE_CONFIG_PAGECACHE 7 /* void*, int sz, int N */ +#define SQLITE_CONFIG_HEAP 8 /* void*, int nByte, int min */ +#define SQLITE_CONFIG_MEMSTATUS 9 /* boolean */ +#define SQLITE_CONFIG_MUTEX 10 /* sqlite3_mutex_methods* */ +#define SQLITE_CONFIG_GETMUTEX 11 /* sqlite3_mutex_methods* */ +/* previously SQLITE_CONFIG_CHUNKALLOC 12 which is now unused. */ +#define SQLITE_CONFIG_LOOKASIDE 13 /* int int */ +#define SQLITE_CONFIG_PCACHE 14 /* sqlite3_pcache_methods* */ +#define SQLITE_CONFIG_GETPCACHE 15 /* sqlite3_pcache_methods* */ +#define SQLITE_CONFIG_LOG 16 /* xFunc, void* */ + +/* +** CAPI3REF: Configuration Options +** EXPERIMENTAL +** +** These constants are the available integer configuration options that +** can be passed as the second argument to the [sqlite3_db_config()] interface. +** +** New configuration options may be added in future releases of SQLite. +** Existing configuration options might be discontinued. Applications +** should check the return code from [sqlite3_db_config()] to make sure that +** the call worked. ^The [sqlite3_db_config()] interface will return a +** non-zero [error code] if a discontinued or unsupported configuration option +** is invoked. +** +**
+**
SQLITE_DBCONFIG_LOOKASIDE
+**
^This option takes three additional arguments that determine the +** [lookaside memory allocator] configuration for the [database connection]. +** ^The first argument (the third parameter to [sqlite3_db_config()] is a +** pointer to an memory buffer to use for lookaside memory. +** ^The first argument after the SQLITE_DBCONFIG_LOOKASIDE verb +** may be NULL in which case SQLite will allocate the +** lookaside buffer itself using [sqlite3_malloc()]. ^The second argument is the +** size of each lookaside buffer slot. ^The third argument is the number of +** slots. The size of the buffer in the first argument must be greater than +** or equal to the product of the second and third arguments. The buffer +** must be aligned to an 8-byte boundary. ^If the second argument to +** SQLITE_DBCONFIG_LOOKASIDE is not a multiple of 8, it is internally +** rounded down to the next smaller +** multiple of 8. See also: [SQLITE_CONFIG_LOOKASIDE]
+** +**
+*/ +#define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */ + + +/* +** CAPI3REF: Enable Or Disable Extended Result Codes +** +** ^The sqlite3_extended_result_codes() routine enables or disables the +** [extended result codes] feature of SQLite. ^The extended result +** codes are disabled by default for historical compatibility. +*/ +SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff); + +/* +** CAPI3REF: Last Insert Rowid +** +** ^Each entry in an SQLite table has a unique 64-bit signed +** integer key called the [ROWID | "rowid"]. ^The rowid is always available +** as an undeclared column named ROWID, OID, or _ROWID_ as long as those +** names are not also used by explicitly declared columns. ^If +** the table has a column of type [INTEGER PRIMARY KEY] then that column +** is another alias for the rowid. +** +** ^This routine returns the [rowid] of the most recent +** successful [INSERT] into the database from the [database connection] +** in the first argument. ^If no successful [INSERT]s +** have ever occurred on that database connection, zero is returned. +** +** ^(If an [INSERT] occurs within a trigger, then the [rowid] of the inserted +** row is returned by this routine as long as the trigger is running. +** But once the trigger terminates, the value returned by this routine +** reverts to the last value inserted before the trigger fired.)^ +** +** ^An [INSERT] that fails due to a constraint violation is not a +** successful [INSERT] and does not change the value returned by this +** routine. ^Thus INSERT OR FAIL, INSERT OR IGNORE, INSERT OR ROLLBACK, +** and INSERT OR ABORT make no changes to the return value of this +** routine when their insertion fails. ^(When INSERT OR REPLACE +** encounters a constraint violation, it does not fail. The +** INSERT continues to completion after deleting rows that caused +** the constraint problem so INSERT OR REPLACE will always change +** the return value of this interface.)^ +** +** ^For the purposes of this routine, an [INSERT] is considered to +** be successful even if it is subsequently rolled back. +** +** This function is accessible to SQL statements via the +** [last_insert_rowid() SQL function]. +** +** If a separate thread performs a new [INSERT] on the same +** database connection while the [sqlite3_last_insert_rowid()] +** function is running and thus changes the last insert [rowid], +** then the value returned by [sqlite3_last_insert_rowid()] is +** unpredictable and might not equal either the old or the new +** last insert [rowid]. +*/ +SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*); + +/* +** CAPI3REF: Count The Number Of Rows Modified +** +** ^This function returns the number of database rows that were changed +** or inserted or deleted by the most recently completed SQL statement +** on the [database connection] specified by the first parameter. +** ^(Only changes that are directly specified by the [INSERT], [UPDATE], +** or [DELETE] statement are counted. Auxiliary changes caused by +** triggers or [foreign key actions] are not counted.)^ Use the +** [sqlite3_total_changes()] function to find the total number of changes +** including changes caused by triggers and foreign key actions. +** +** ^Changes to a view that are simulated by an [INSTEAD OF trigger] +** are not counted. Only real table changes are counted. +** +** ^(A "row change" is a change to a single row of a single table +** caused by an INSERT, DELETE, or UPDATE statement. Rows that +** are changed as side effects of [REPLACE] constraint resolution, +** rollback, ABORT processing, [DROP TABLE], or by any other +** mechanisms do not count as direct row changes.)^ +** +** A "trigger context" is a scope of execution that begins and +** ends with the script of a [CREATE TRIGGER | trigger]. +** Most SQL statements are +** evaluated outside of any trigger. This is the "top level" +** trigger context. If a trigger fires from the top level, a +** new trigger context is entered for the duration of that one +** trigger. Subtriggers create subcontexts for their duration. +** +** ^Calling [sqlite3_exec()] or [sqlite3_step()] recursively does +** not create a new trigger context. +** +** ^This function returns the number of direct row changes in the +** most recent INSERT, UPDATE, or DELETE statement within the same +** trigger context. +** +** ^Thus, when called from the top level, this function returns the +** number of changes in the most recent INSERT, UPDATE, or DELETE +** that also occurred at the top level. ^(Within the body of a trigger, +** the sqlite3_changes() interface can be called to find the number of +** changes in the most recently completed INSERT, UPDATE, or DELETE +** statement within the body of the same trigger. +** However, the number returned does not include changes +** caused by subtriggers since those have their own context.)^ +** +** See also the [sqlite3_total_changes()] interface, the +** [count_changes pragma], and the [changes() SQL function]. +** +** If a separate thread makes changes on the same database connection +** while [sqlite3_changes()] is running then the value returned +** is unpredictable and not meaningful. +*/ +SQLITE_API int sqlite3_changes(sqlite3*); + +/* +** CAPI3REF: Total Number Of Rows Modified +** +** ^This function returns the number of row changes caused by [INSERT], +** [UPDATE] or [DELETE] statements since the [database connection] was opened. +** ^(The count returned by sqlite3_total_changes() includes all changes +** from all [CREATE TRIGGER | trigger] contexts and changes made by +** [foreign key actions]. However, +** the count does not include changes used to implement [REPLACE] constraints, +** do rollbacks or ABORT processing, or [DROP TABLE] processing. The +** count does not include rows of views that fire an [INSTEAD OF trigger], +** though if the INSTEAD OF trigger makes changes of its own, those changes +** are counted.)^ +** ^The sqlite3_total_changes() function counts the changes as soon as +** the statement that makes them is completed (when the statement handle +** is passed to [sqlite3_reset()] or [sqlite3_finalize()]). +** +** See also the [sqlite3_changes()] interface, the +** [count_changes pragma], and the [total_changes() SQL function]. +** +** If a separate thread makes changes on the same database connection +** while [sqlite3_total_changes()] is running then the value +** returned is unpredictable and not meaningful. +*/ +SQLITE_API int sqlite3_total_changes(sqlite3*); + +/* +** CAPI3REF: Interrupt A Long-Running Query +** +** ^This function causes any pending database operation to abort and +** return at its earliest opportunity. This routine is typically +** called in response to a user action such as pressing "Cancel" +** or Ctrl-C where the user wants a long query operation to halt +** immediately. +** +** ^It is safe to call this routine from a thread different from the +** thread that is currently running the database operation. But it +** is not safe to call this routine with a [database connection] that +** is closed or might close before sqlite3_interrupt() returns. +** +** ^If an SQL operation is very nearly finished at the time when +** sqlite3_interrupt() is called, then it might not have an opportunity +** to be interrupted and might continue to completion. +** +** ^An SQL operation that is interrupted will return [SQLITE_INTERRUPT]. +** ^If the interrupted SQL operation is an INSERT, UPDATE, or DELETE +** that is inside an explicit transaction, then the entire transaction +** will be rolled back automatically. +** +** ^The sqlite3_interrupt(D) call is in effect until all currently running +** SQL statements on [database connection] D complete. ^Any new SQL statements +** that are started after the sqlite3_interrupt() call and before the +** running statements reaches zero are interrupted as if they had been +** running prior to the sqlite3_interrupt() call. ^New SQL statements +** that are started after the running statement count reaches zero are +** not effected by the sqlite3_interrupt(). +** ^A call to sqlite3_interrupt(D) that occurs when there are no running +** SQL statements is a no-op and has no effect on SQL statements +** that are started after the sqlite3_interrupt() call returns. +** +** If the database connection closes while [sqlite3_interrupt()] +** is running then bad things will likely happen. +*/ +SQLITE_API void sqlite3_interrupt(sqlite3*); + +/* +** CAPI3REF: Determine If An SQL Statement Is Complete +** +** These routines are useful during command-line input to determine if the +** currently entered text seems to form a complete SQL statement or +** if additional input is needed before sending the text into +** SQLite for parsing. ^These routines return 1 if the input string +** appears to be a complete SQL statement. ^A statement is judged to be +** complete if it ends with a semicolon token and is not a prefix of a +** well-formed CREATE TRIGGER statement. ^Semicolons that are embedded within +** string literals or quoted identifier names or comments are not +** independent tokens (they are part of the token in which they are +** embedded) and thus do not count as a statement terminator. ^Whitespace +** and comments that follow the final semicolon are ignored. +** +** ^These routines return 0 if the statement is incomplete. ^If a +** memory allocation fails, then SQLITE_NOMEM is returned. +** +** ^These routines do not parse the SQL statements thus +** will not detect syntactically incorrect SQL. +** +** ^(If SQLite has not been initialized using [sqlite3_initialize()] prior +** to invoking sqlite3_complete16() then sqlite3_initialize() is invoked +** automatically by sqlite3_complete16(). If that initialization fails, +** then the return value from sqlite3_complete16() will be non-zero +** regardless of whether or not the input SQL is complete.)^ +** +** The input to [sqlite3_complete()] must be a zero-terminated +** UTF-8 string. +** +** The input to [sqlite3_complete16()] must be a zero-terminated +** UTF-16 string in native byte order. +*/ +SQLITE_API int sqlite3_complete(const char *sql); +SQLITE_API int sqlite3_complete16(const void *sql); + +/* +** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors +** +** ^This routine sets a callback function that might be invoked whenever +** an attempt is made to open a database table that another thread +** or process has locked. +** +** ^If the busy callback is NULL, then [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED] +** is returned immediately upon encountering the lock. ^If the busy callback +** is not NULL, then the callback might be invoked with two arguments. +** +** ^The first argument to the busy handler is a copy of the void* pointer which +** is the third argument to sqlite3_busy_handler(). ^The second argument to +** the busy handler callback is the number of times that the busy handler has +** been invoked for this locking event. ^If the +** busy callback returns 0, then no additional attempts are made to +** access the database and [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED] is returned. +** ^If the callback returns non-zero, then another attempt +** is made to open the database for reading and the cycle repeats. +** +** The presence of a busy handler does not guarantee that it will be invoked +** when there is lock contention. ^If SQLite determines that invoking the busy +** handler could result in a deadlock, it will go ahead and return [SQLITE_BUSY] +** or [SQLITE_IOERR_BLOCKED] instead of invoking the busy handler. +** Consider a scenario where one process is holding a read lock that +** it is trying to promote to a reserved lock and +** a second process is holding a reserved lock that it is trying +** to promote to an exclusive lock. The first process cannot proceed +** because it is blocked by the second and the second process cannot +** proceed because it is blocked by the first. If both processes +** invoke the busy handlers, neither will make any progress. Therefore, +** SQLite returns [SQLITE_BUSY] for the first process, hoping that this +** will induce the first process to release its read lock and allow +** the second process to proceed. +** +** ^The default busy callback is NULL. +** +** ^The [SQLITE_BUSY] error is converted to [SQLITE_IOERR_BLOCKED] +** when SQLite is in the middle of a large transaction where all the +** changes will not fit into the in-memory cache. SQLite will +** already hold a RESERVED lock on the database file, but it needs +** to promote this lock to EXCLUSIVE so that it can spill cache +** pages into the database file without harm to concurrent +** readers. ^If it is unable to promote the lock, then the in-memory +** cache will be left in an inconsistent state and so the error +** code is promoted from the relatively benign [SQLITE_BUSY] to +** the more severe [SQLITE_IOERR_BLOCKED]. ^This error code promotion +** forces an automatic rollback of the changes. See the +** +** CorruptionFollowingBusyError wiki page for a discussion of why +** this is important. +** +** ^(There can only be a single busy handler defined for each +** [database connection]. Setting a new busy handler clears any +** previously set handler.)^ ^Note that calling [sqlite3_busy_timeout()] +** will also set or clear the busy handler. +** +** The busy callback should not take any actions which modify the +** database connection that invoked the busy handler. Any such actions +** result in undefined behavior. +** +** A busy handler must not close the database connection +** or [prepared statement] that invoked the busy handler. +*/ +SQLITE_API int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*); + +/* +** CAPI3REF: Set A Busy Timeout +** +** ^This routine sets a [sqlite3_busy_handler | busy handler] that sleeps +** for a specified amount of time when a table is locked. ^The handler +** will sleep multiple times until at least "ms" milliseconds of sleeping +** have accumulated. ^After at least "ms" milliseconds of sleeping, +** the handler returns 0 which causes [sqlite3_step()] to return +** [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED]. +** +** ^Calling this routine with an argument less than or equal to zero +** turns off all busy handlers. +** +** ^(There can only be a single busy handler for a particular +** [database connection] any any given moment. If another busy handler +** was defined (using [sqlite3_busy_handler()]) prior to calling +** this routine, that other busy handler is cleared.)^ +*/ +SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms); + +/* +** CAPI3REF: Convenience Routines For Running Queries +** +** Definition: A result table is memory data structure created by the +** [sqlite3_get_table()] interface. A result table records the +** complete query results from one or more queries. +** +** The table conceptually has a number of rows and columns. But +** these numbers are not part of the result table itself. These +** numbers are obtained separately. Let N be the number of rows +** and M be the number of columns. +** +** A result table is an array of pointers to zero-terminated UTF-8 strings. +** There are (N+1)*M elements in the array. The first M pointers point +** to zero-terminated strings that contain the names of the columns. +** The remaining entries all point to query results. NULL values result +** in NULL pointers. All other values are in their UTF-8 zero-terminated +** string representation as returned by [sqlite3_column_text()]. +** +** A result table might consist of one or more memory allocations. +** It is not safe to pass a result table directly to [sqlite3_free()]. +** A result table should be deallocated using [sqlite3_free_table()]. +** +** As an example of the result table format, suppose a query result +** is as follows: +** +**
+**        Name        | Age
+**        -----------------------
+**        Alice       | 43
+**        Bob         | 28
+**        Cindy       | 21
+** 
+** +** There are two column (M==2) and three rows (N==3). Thus the +** result table has 8 entries. Suppose the result table is stored +** in an array names azResult. Then azResult holds this content: +** +**
+**        azResult[0] = "Name";
+**        azResult[1] = "Age";
+**        azResult[2] = "Alice";
+**        azResult[3] = "43";
+**        azResult[4] = "Bob";
+**        azResult[5] = "28";
+**        azResult[6] = "Cindy";
+**        azResult[7] = "21";
+** 
+** +** ^The sqlite3_get_table() function evaluates one or more +** semicolon-separated SQL statements in the zero-terminated UTF-8 +** string of its 2nd parameter and returns a result table to the +** pointer given in its 3rd parameter. +** +** After the application has finished with the result from sqlite3_get_table(), +** it should pass the result table pointer to sqlite3_free_table() in order to +** release the memory that was malloced. Because of the way the +** [sqlite3_malloc()] happens within sqlite3_get_table(), the calling +** function must not try to call [sqlite3_free()] directly. Only +** [sqlite3_free_table()] is able to release the memory properly and safely. +** +** ^(The sqlite3_get_table() interface is implemented as a wrapper around +** [sqlite3_exec()]. The sqlite3_get_table() routine does not have access +** to any internal data structures of SQLite. It uses only the public +** interface defined here. As a consequence, errors that occur in the +** wrapper layer outside of the internal [sqlite3_exec()] call are not +** reflected in subsequent calls to [sqlite3_errcode()] or +** [sqlite3_errmsg()].)^ +*/ +SQLITE_API int sqlite3_get_table( + sqlite3 *db, /* An open database */ + const char *zSql, /* SQL to be evaluated */ + char ***pazResult, /* Results of the query */ + int *pnRow, /* Number of result rows written here */ + int *pnColumn, /* Number of result columns written here */ + char **pzErrmsg /* Error msg written here */ +); +SQLITE_API void sqlite3_free_table(char **result); + +/* +** CAPI3REF: Formatted String Printing Functions +** +** These routines are work-alikes of the "printf()" family of functions +** from the standard C library. +** +** ^The sqlite3_mprintf() and sqlite3_vmprintf() routines write their +** results into memory obtained from [sqlite3_malloc()]. +** The strings returned by these two routines should be +** released by [sqlite3_free()]. ^Both routines return a +** NULL pointer if [sqlite3_malloc()] is unable to allocate enough +** memory to hold the resulting string. +** +** ^(In sqlite3_snprintf() routine is similar to "snprintf()" from +** the standard C library. The result is written into the +** buffer supplied as the second parameter whose size is given by +** the first parameter. Note that the order of the +** first two parameters is reversed from snprintf().)^ This is an +** historical accident that cannot be fixed without breaking +** backwards compatibility. ^(Note also that sqlite3_snprintf() +** returns a pointer to its buffer instead of the number of +** characters actually written into the buffer.)^ We admit that +** the number of characters written would be a more useful return +** value but we cannot change the implementation of sqlite3_snprintf() +** now without breaking compatibility. +** +** ^As long as the buffer size is greater than zero, sqlite3_snprintf() +** guarantees that the buffer is always zero-terminated. ^The first +** parameter "n" is the total size of the buffer, including space for +** the zero terminator. So the longest string that can be completely +** written will be n-1 characters. +** +** These routines all implement some additional formatting +** options that are useful for constructing SQL statements. +** All of the usual printf() formatting options apply. In addition, there +** is are "%q", "%Q", and "%z" options. +** +** ^(The %q option works like %s in that it substitutes a null-terminated +** string from the argument list. But %q also doubles every '\'' character. +** %q is designed for use inside a string literal.)^ By doubling each '\'' +** character it escapes that character and allows it to be inserted into +** the string. +** +** For example, assume the string variable zText contains text as follows: +** +**
+**  char *zText = "It's a happy day!";
+** 
+** +** One can use this text in an SQL statement as follows: +** +**
+**  char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES('%q')", zText);
+**  sqlite3_exec(db, zSQL, 0, 0, 0);
+**  sqlite3_free(zSQL);
+** 
+** +** Because the %q format string is used, the '\'' character in zText +** is escaped and the SQL generated is as follows: +** +**
+**  INSERT INTO table1 VALUES('It''s a happy day!')
+** 
+** +** This is correct. Had we used %s instead of %q, the generated SQL +** would have looked like this: +** +**
+**  INSERT INTO table1 VALUES('It's a happy day!');
+** 
+** +** This second example is an SQL syntax error. As a general rule you should +** always use %q instead of %s when inserting text into a string literal. +** +** ^(The %Q option works like %q except it also adds single quotes around +** the outside of the total string. Additionally, if the parameter in the +** argument list is a NULL pointer, %Q substitutes the text "NULL" (without +** single quotes).)^ So, for example, one could say: +** +**
+**  char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES(%Q)", zText);
+**  sqlite3_exec(db, zSQL, 0, 0, 0);
+**  sqlite3_free(zSQL);
+** 
+** +** The code above will render a correct SQL statement in the zSQL +** variable even if the zText variable is a NULL pointer. +** +** ^(The "%z" formatting option works like "%s" but with the +** addition that after the string has been read and copied into +** the result, [sqlite3_free()] is called on the input string.)^ +*/ +SQLITE_API char *sqlite3_mprintf(const char*,...); +SQLITE_API char *sqlite3_vmprintf(const char*, va_list); +SQLITE_API char *sqlite3_snprintf(int,char*,const char*, ...); + +/* +** CAPI3REF: Memory Allocation Subsystem +** +** The SQLite core uses these three routines for all of its own +** internal memory allocation needs. "Core" in the previous sentence +** does not include operating-system specific VFS implementation. The +** Windows VFS uses native malloc() and free() for some operations. +** +** ^The sqlite3_malloc() routine returns a pointer to a block +** of memory at least N bytes in length, where N is the parameter. +** ^If sqlite3_malloc() is unable to obtain sufficient free +** memory, it returns a NULL pointer. ^If the parameter N to +** sqlite3_malloc() is zero or negative then sqlite3_malloc() returns +** a NULL pointer. +** +** ^Calling sqlite3_free() with a pointer previously returned +** by sqlite3_malloc() or sqlite3_realloc() releases that memory so +** that it might be reused. ^The sqlite3_free() routine is +** a no-op if is called with a NULL pointer. Passing a NULL pointer +** to sqlite3_free() is harmless. After being freed, memory +** should neither be read nor written. Even reading previously freed +** memory might result in a segmentation fault or other severe error. +** Memory corruption, a segmentation fault, or other severe error +** might result if sqlite3_free() is called with a non-NULL pointer that +** was not obtained from sqlite3_malloc() or sqlite3_realloc(). +** +** ^(The sqlite3_realloc() interface attempts to resize a +** prior memory allocation to be at least N bytes, where N is the +** second parameter. The memory allocation to be resized is the first +** parameter.)^ ^ If the first parameter to sqlite3_realloc() +** is a NULL pointer then its behavior is identical to calling +** sqlite3_malloc(N) where N is the second parameter to sqlite3_realloc(). +** ^If the second parameter to sqlite3_realloc() is zero or +** negative then the behavior is exactly the same as calling +** sqlite3_free(P) where P is the first parameter to sqlite3_realloc(). +** ^sqlite3_realloc() returns a pointer to a memory allocation +** of at least N bytes in size or NULL if sufficient memory is unavailable. +** ^If M is the size of the prior allocation, then min(N,M) bytes +** of the prior allocation are copied into the beginning of buffer returned +** by sqlite3_realloc() and the prior allocation is freed. +** ^If sqlite3_realloc() returns NULL, then the prior allocation +** is not freed. +** +** ^The memory returned by sqlite3_malloc() and sqlite3_realloc() +** is always aligned to at least an 8 byte boundary. +** +** In SQLite version 3.5.0 and 3.5.1, it was possible to define +** the SQLITE_OMIT_MEMORY_ALLOCATION which would cause the built-in +** implementation of these routines to be omitted. That capability +** is no longer provided. Only built-in memory allocators can be used. +** +** The Windows OS interface layer calls +** the system malloc() and free() directly when converting +** filenames between the UTF-8 encoding used by SQLite +** and whatever filename encoding is used by the particular Windows +** installation. Memory allocation errors are detected, but +** they are reported back as [SQLITE_CANTOPEN] or +** [SQLITE_IOERR] rather than [SQLITE_NOMEM]. +** +** The pointer arguments to [sqlite3_free()] and [sqlite3_realloc()] +** must be either NULL or else pointers obtained from a prior +** invocation of [sqlite3_malloc()] or [sqlite3_realloc()] that have +** not yet been released. +** +** The application must not read or write any part of +** a block of memory after it has been released using +** [sqlite3_free()] or [sqlite3_realloc()]. +*/ +SQLITE_API void *sqlite3_malloc(int); +SQLITE_API void *sqlite3_realloc(void*, int); +SQLITE_API void sqlite3_free(void*); + +/* +** CAPI3REF: Memory Allocator Statistics +** +** SQLite provides these two interfaces for reporting on the status +** of the [sqlite3_malloc()], [sqlite3_free()], and [sqlite3_realloc()] +** routines, which form the built-in memory allocation subsystem. +** +** ^The [sqlite3_memory_used()] routine returns the number of bytes +** of memory currently outstanding (malloced but not freed). +** ^The [sqlite3_memory_highwater()] routine returns the maximum +** value of [sqlite3_memory_used()] since the high-water mark +** was last reset. ^The values returned by [sqlite3_memory_used()] and +** [sqlite3_memory_highwater()] include any overhead +** added by SQLite in its implementation of [sqlite3_malloc()], +** but not overhead added by the any underlying system library +** routines that [sqlite3_malloc()] may call. +** +** ^The memory high-water mark is reset to the current value of +** [sqlite3_memory_used()] if and only if the parameter to +** [sqlite3_memory_highwater()] is true. ^The value returned +** by [sqlite3_memory_highwater(1)] is the high-water mark +** prior to the reset. +*/ +SQLITE_API sqlite3_int64 sqlite3_memory_used(void); +SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag); + +/* +** CAPI3REF: Pseudo-Random Number Generator +** +** SQLite contains a high-quality pseudo-random number generator (PRNG) used to +** select random [ROWID | ROWIDs] when inserting new records into a table that +** already uses the largest possible [ROWID]. The PRNG is also used for +** the build-in random() and randomblob() SQL functions. This interface allows +** applications to access the same PRNG for other purposes. +** +** ^A call to this routine stores N bytes of randomness into buffer P. +** +** ^The first time this routine is invoked (either internally or by +** the application) the PRNG is seeded using randomness obtained +** from the xRandomness method of the default [sqlite3_vfs] object. +** ^On all subsequent invocations, the pseudo-randomness is generated +** internally and without recourse to the [sqlite3_vfs] xRandomness +** method. +*/ +SQLITE_API void sqlite3_randomness(int N, void *P); + +/* +** CAPI3REF: Compile-Time Authorization Callbacks +** +** ^This routine registers a authorizer callback with a particular +** [database connection], supplied in the first argument. +** ^The authorizer callback is invoked as SQL statements are being compiled +** by [sqlite3_prepare()] or its variants [sqlite3_prepare_v2()], +** [sqlite3_prepare16()] and [sqlite3_prepare16_v2()]. ^At various +** points during the compilation process, as logic is being created +** to perform various actions, the authorizer callback is invoked to +** see if those actions are allowed. ^The authorizer callback should +** return [SQLITE_OK] to allow the action, [SQLITE_IGNORE] to disallow the +** specific action but allow the SQL statement to continue to be +** compiled, or [SQLITE_DENY] to cause the entire SQL statement to be +** rejected with an error. ^If the authorizer callback returns +** any value other than [SQLITE_IGNORE], [SQLITE_OK], or [SQLITE_DENY] +** then the [sqlite3_prepare_v2()] or equivalent call that triggered +** the authorizer will fail with an error message. +** +** When the callback returns [SQLITE_OK], that means the operation +** requested is ok. ^When the callback returns [SQLITE_DENY], the +** [sqlite3_prepare_v2()] or equivalent call that triggered the +** authorizer will fail with an error message explaining that +** access is denied. +** +** ^The first parameter to the authorizer callback is a copy of the third +** parameter to the sqlite3_set_authorizer() interface. ^The second parameter +** to the callback is an integer [SQLITE_COPY | action code] that specifies +** the particular action to be authorized. ^The third through sixth parameters +** to the callback are zero-terminated strings that contain additional +** details about the action to be authorized. +** +** ^If the action code is [SQLITE_READ] +** and the callback returns [SQLITE_IGNORE] then the +** [prepared statement] statement is constructed to substitute +** a NULL value in place of the table column that would have +** been read if [SQLITE_OK] had been returned. The [SQLITE_IGNORE] +** return can be used to deny an untrusted user access to individual +** columns of a table. +** ^If the action code is [SQLITE_DELETE] and the callback returns +** [SQLITE_IGNORE] then the [DELETE] operation proceeds but the +** [truncate optimization] is disabled and all rows are deleted individually. +** +** An authorizer is used when [sqlite3_prepare | preparing] +** SQL statements from an untrusted source, to ensure that the SQL statements +** do not try to access data they are not allowed to see, or that they do not +** try to execute malicious statements that damage the database. For +** example, an application may allow a user to enter arbitrary +** SQL queries for evaluation by a database. But the application does +** not want the user to be able to make arbitrary changes to the +** database. An authorizer could then be put in place while the +** user-entered SQL is being [sqlite3_prepare | prepared] that +** disallows everything except [SELECT] statements. +** +** Applications that need to process SQL from untrusted sources +** might also consider lowering resource limits using [sqlite3_limit()] +** and limiting database size using the [max_page_count] [PRAGMA] +** in addition to using an authorizer. +** +** ^(Only a single authorizer can be in place on a database connection +** at a time. Each call to sqlite3_set_authorizer overrides the +** previous call.)^ ^Disable the authorizer by installing a NULL callback. +** The authorizer is disabled by default. +** +** The authorizer callback must not do anything that will modify +** the database connection that invoked the authorizer callback. +** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their +** database connections for the meaning of "modify" in this paragraph. +** +** ^When [sqlite3_prepare_v2()] is used to prepare a statement, the +** statement might be re-prepared during [sqlite3_step()] due to a +** schema change. Hence, the application should ensure that the +** correct authorizer callback remains in place during the [sqlite3_step()]. +** +** ^Note that the authorizer callback is invoked only during +** [sqlite3_prepare()] or its variants. Authorization is not +** performed during statement evaluation in [sqlite3_step()], unless +** as stated in the previous paragraph, sqlite3_step() invokes +** sqlite3_prepare_v2() to reprepare a statement after a schema change. +*/ +SQLITE_API int sqlite3_set_authorizer( + sqlite3*, + int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), + void *pUserData +); + +/* +** CAPI3REF: Authorizer Return Codes +** +** The [sqlite3_set_authorizer | authorizer callback function] must +** return either [SQLITE_OK] or one of these two constants in order +** to signal SQLite whether or not the action is permitted. See the +** [sqlite3_set_authorizer | authorizer documentation] for additional +** information. +*/ +#define SQLITE_DENY 1 /* Abort the SQL statement with an error */ +#define SQLITE_IGNORE 2 /* Don't allow access, but don't generate an error */ + +/* +** CAPI3REF: Authorizer Action Codes +** +** The [sqlite3_set_authorizer()] interface registers a callback function +** that is invoked to authorize certain SQL statement actions. The +** second parameter to the callback is an integer code that specifies +** what action is being authorized. These are the integer action codes that +** the authorizer callback may be passed. +** +** These action code values signify what kind of operation is to be +** authorized. The 3rd and 4th parameters to the authorization +** callback function will be parameters or NULL depending on which of these +** codes is used as the second parameter. ^(The 5th parameter to the +** authorizer callback is the name of the database ("main", "temp", +** etc.) if applicable.)^ ^The 6th parameter to the authorizer callback +** is the name of the inner-most trigger or view that is responsible for +** the access attempt or NULL if this access attempt is directly from +** top-level SQL code. +*/ +/******************************************* 3rd ************ 4th ***********/ +#define SQLITE_CREATE_INDEX 1 /* Index Name Table Name */ +#define SQLITE_CREATE_TABLE 2 /* Table Name NULL */ +#define SQLITE_CREATE_TEMP_INDEX 3 /* Index Name Table Name */ +#define SQLITE_CREATE_TEMP_TABLE 4 /* Table Name NULL */ +#define SQLITE_CREATE_TEMP_TRIGGER 5 /* Trigger Name Table Name */ +#define SQLITE_CREATE_TEMP_VIEW 6 /* View Name NULL */ +#define SQLITE_CREATE_TRIGGER 7 /* Trigger Name Table Name */ +#define SQLITE_CREATE_VIEW 8 /* View Name NULL */ +#define SQLITE_DELETE 9 /* Table Name NULL */ +#define SQLITE_DROP_INDEX 10 /* Index Name Table Name */ +#define SQLITE_DROP_TABLE 11 /* Table Name NULL */ +#define SQLITE_DROP_TEMP_INDEX 12 /* Index Name Table Name */ +#define SQLITE_DROP_TEMP_TABLE 13 /* Table Name NULL */ +#define SQLITE_DROP_TEMP_TRIGGER 14 /* Trigger Name Table Name */ +#define SQLITE_DROP_TEMP_VIEW 15 /* View Name NULL */ +#define SQLITE_DROP_TRIGGER 16 /* Trigger Name Table Name */ +#define SQLITE_DROP_VIEW 17 /* View Name NULL */ +#define SQLITE_INSERT 18 /* Table Name NULL */ +#define SQLITE_PRAGMA 19 /* Pragma Name 1st arg or NULL */ +#define SQLITE_READ 20 /* Table Name Column Name */ +#define SQLITE_SELECT 21 /* NULL NULL */ +#define SQLITE_TRANSACTION 22 /* Operation NULL */ +#define SQLITE_UPDATE 23 /* Table Name Column Name */ +#define SQLITE_ATTACH 24 /* Filename NULL */ +#define SQLITE_DETACH 25 /* Database Name NULL */ +#define SQLITE_ALTER_TABLE 26 /* Database Name Table Name */ +#define SQLITE_REINDEX 27 /* Index Name NULL */ +#define SQLITE_ANALYZE 28 /* Table Name NULL */ +#define SQLITE_CREATE_VTABLE 29 /* Table Name Module Name */ +#define SQLITE_DROP_VTABLE 30 /* Table Name Module Name */ +#define SQLITE_FUNCTION 31 /* NULL Function Name */ +#define SQLITE_SAVEPOINT 32 /* Operation Savepoint Name */ +#define SQLITE_COPY 0 /* No longer used */ + +/* +** CAPI3REF: Tracing And Profiling Functions +** EXPERIMENTAL +** +** These routines register callback functions that can be used for +** tracing and profiling the execution of SQL statements. +** +** ^The callback function registered by sqlite3_trace() is invoked at +** various times when an SQL statement is being run by [sqlite3_step()]. +** ^The sqlite3_trace() callback is invoked with a UTF-8 rendering of the +** SQL statement text as the statement first begins executing. +** ^(Additional sqlite3_trace() callbacks might occur +** as each triggered subprogram is entered. The callbacks for triggers +** contain a UTF-8 SQL comment that identifies the trigger.)^ +** +** ^The callback function registered by sqlite3_profile() is invoked +** as each SQL statement finishes. ^The profile callback contains +** the original statement text and an estimate of wall-clock time +** of how long that statement took to run. +*/ +SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*); +SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_profile(sqlite3*, + void(*xProfile)(void*,const char*,sqlite3_uint64), void*); + +/* +** CAPI3REF: Query Progress Callbacks +** +** ^This routine configures a callback function - the +** progress callback - that is invoked periodically during long +** running calls to [sqlite3_exec()], [sqlite3_step()] and +** [sqlite3_get_table()]. An example use for this +** interface is to keep a GUI updated during a large query. +** +** ^If the progress callback returns non-zero, the operation is +** interrupted. This feature can be used to implement a +** "Cancel" button on a GUI progress dialog box. +** +** The progress handler must not do anything that will modify +** the database connection that invoked the progress handler. +** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their +** database connections for the meaning of "modify" in this paragraph. +** +*/ +SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); + +/* +** CAPI3REF: Opening A New Database Connection +** +** ^These routines open an SQLite database file whose name is given by the +** filename argument. ^The filename argument is interpreted as UTF-8 for +** sqlite3_open() and sqlite3_open_v2() and as UTF-16 in the native byte +** order for sqlite3_open16(). ^(A [database connection] handle is usually +** returned in *ppDb, even if an error occurs. The only exception is that +** if SQLite is unable to allocate memory to hold the [sqlite3] object, +** a NULL will be written into *ppDb instead of a pointer to the [sqlite3] +** object.)^ ^(If the database is opened (and/or created) successfully, then +** [SQLITE_OK] is returned. Otherwise an [error code] is returned.)^ ^The +** [sqlite3_errmsg()] or [sqlite3_errmsg16()] routines can be used to obtain +** an English language description of the error following a failure of any +** of the sqlite3_open() routines. +** +** ^The default encoding for the database will be UTF-8 if +** sqlite3_open() or sqlite3_open_v2() is called and +** UTF-16 in the native byte order if sqlite3_open16() is used. +** +** Whether or not an error occurs when it is opened, resources +** associated with the [database connection] handle should be released by +** passing it to [sqlite3_close()] when it is no longer required. +** +** The sqlite3_open_v2() interface works like sqlite3_open() +** except that it accepts two additional parameters for additional control +** over the new database connection. ^(The flags parameter to +** sqlite3_open_v2() can take one of +** the following three values, optionally combined with the +** [SQLITE_OPEN_NOMUTEX], [SQLITE_OPEN_FULLMUTEX], [SQLITE_OPEN_SHAREDCACHE], +** and/or [SQLITE_OPEN_PRIVATECACHE] flags:)^ +** +**
+** ^(
[SQLITE_OPEN_READONLY]
+**
The database is opened in read-only mode. If the database does not +** already exist, an error is returned.
)^ +** +** ^(
[SQLITE_OPEN_READWRITE]
+**
The database is opened for reading and writing if possible, or reading +** only if the file is write protected by the operating system. In either +** case the database must already exist, otherwise an error is returned.
)^ +** +** ^(
[SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]
+**
The database is opened for reading and writing, and is creates it if +** it does not already exist. This is the behavior that is always used for +** sqlite3_open() and sqlite3_open16().
)^ +**
+** +** If the 3rd parameter to sqlite3_open_v2() is not one of the +** combinations shown above or one of the combinations shown above combined +** with the [SQLITE_OPEN_NOMUTEX], [SQLITE_OPEN_FULLMUTEX], +** [SQLITE_OPEN_SHAREDCACHE] and/or [SQLITE_OPEN_SHAREDCACHE] flags, +** then the behavior is undefined. +** +** ^If the [SQLITE_OPEN_NOMUTEX] flag is set, then the database connection +** opens in the multi-thread [threading mode] as long as the single-thread +** mode has not been set at compile-time or start-time. ^If the +** [SQLITE_OPEN_FULLMUTEX] flag is set then the database connection opens +** in the serialized [threading mode] unless single-thread was +** previously selected at compile-time or start-time. +** ^The [SQLITE_OPEN_SHAREDCACHE] flag causes the database connection to be +** eligible to use [shared cache mode], regardless of whether or not shared +** cache is enabled using [sqlite3_enable_shared_cache()]. ^The +** [SQLITE_OPEN_PRIVATECACHE] flag causes the database connection to not +** participate in [shared cache mode] even if it is enabled. +** +** ^If the filename is ":memory:", then a private, temporary in-memory database +** is created for the connection. ^This in-memory database will vanish when +** the database connection is closed. Future versions of SQLite might +** make use of additional special filenames that begin with the ":" character. +** It is recommended that when a database filename actually does begin with +** a ":" character you should prefix the filename with a pathname such as +** "./" to avoid ambiguity. +** +** ^If the filename is an empty string, then a private, temporary +** on-disk database will be created. ^This private database will be +** automatically deleted as soon as the database connection is closed. +** +** ^The fourth parameter to sqlite3_open_v2() is the name of the +** [sqlite3_vfs] object that defines the operating system interface that +** the new database connection should use. ^If the fourth parameter is +** a NULL pointer then the default [sqlite3_vfs] object is used. +** +** Note to Windows users: The encoding used for the filename argument +** of sqlite3_open() and sqlite3_open_v2() must be UTF-8, not whatever +** codepage is currently defined. Filenames containing international +** characters must be converted to UTF-8 prior to passing them into +** sqlite3_open() or sqlite3_open_v2(). +*/ +SQLITE_API int sqlite3_open( + const char *filename, /* Database filename (UTF-8) */ + sqlite3 **ppDb /* OUT: SQLite db handle */ +); +SQLITE_API int sqlite3_open16( + const void *filename, /* Database filename (UTF-16) */ + sqlite3 **ppDb /* OUT: SQLite db handle */ +); +SQLITE_API int sqlite3_open_v2( + const char *filename, /* Database filename (UTF-8) */ + sqlite3 **ppDb, /* OUT: SQLite db handle */ + int flags, /* Flags */ + const char *zVfs /* Name of VFS module to use */ +); + +/* +** CAPI3REF: Error Codes And Messages +** +** ^The sqlite3_errcode() interface returns the numeric [result code] or +** [extended result code] for the most recent failed sqlite3_* API call +** associated with a [database connection]. If a prior API call failed +** but the most recent API call succeeded, the return value from +** sqlite3_errcode() is undefined. ^The sqlite3_extended_errcode() +** interface is the same except that it always returns the +** [extended result code] even when extended result codes are +** disabled. +** +** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language +** text that describes the error, as either UTF-8 or UTF-16 respectively. +** ^(Memory to hold the error message string is managed internally. +** The application does not need to worry about freeing the result. +** However, the error string might be overwritten or deallocated by +** subsequent calls to other SQLite interface functions.)^ +** +** When the serialized [threading mode] is in use, it might be the +** case that a second error occurs on a separate thread in between +** the time of the first error and the call to these interfaces. +** When that happens, the second error will be reported since these +** interfaces always report the most recent result. To avoid +** this, each thread can obtain exclusive use of the [database connection] D +** by invoking [sqlite3_mutex_enter]([sqlite3_db_mutex](D)) before beginning +** to use D and invoking [sqlite3_mutex_leave]([sqlite3_db_mutex](D)) after +** all calls to the interfaces listed here are completed. +** +** If an interface fails with SQLITE_MISUSE, that means the interface +** was invoked incorrectly by the application. In that case, the +** error code and message may or may not be set. +*/ +SQLITE_API int sqlite3_errcode(sqlite3 *db); +SQLITE_API int sqlite3_extended_errcode(sqlite3 *db); +SQLITE_API const char *sqlite3_errmsg(sqlite3*); +SQLITE_API const void *sqlite3_errmsg16(sqlite3*); + +/* +** CAPI3REF: SQL Statement Object +** KEYWORDS: {prepared statement} {prepared statements} +** +** An instance of this object represents a single SQL statement. +** This object is variously known as a "prepared statement" or a +** "compiled SQL statement" or simply as a "statement". +** +** The life of a statement object goes something like this: +** +**
    +**
  1. Create the object using [sqlite3_prepare_v2()] or a related +** function. +**
  2. Bind values to [host parameters] using the sqlite3_bind_*() +** interfaces. +**
  3. Run the SQL by calling [sqlite3_step()] one or more times. +**
  4. Reset the statement using [sqlite3_reset()] then go back +** to step 2. Do this zero or more times. +**
  5. Destroy the object using [sqlite3_finalize()]. +**
+** +** Refer to documentation on individual methods above for additional +** information. +*/ +typedef struct sqlite3_stmt sqlite3_stmt; + +/* +** CAPI3REF: Run-time Limits +** +** ^(This interface allows the size of various constructs to be limited +** on a connection by connection basis. The first parameter is the +** [database connection] whose limit is to be set or queried. The +** second parameter is one of the [limit categories] that define a +** class of constructs to be size limited. The third parameter is the +** new limit for that construct. The function returns the old limit.)^ +** +** ^If the new limit is a negative number, the limit is unchanged. +** ^(For the limit category of SQLITE_LIMIT_XYZ there is a +** [limits | hard upper bound] +** set by a compile-time C preprocessor macro named +** [limits | SQLITE_MAX_XYZ]. +** (The "_LIMIT_" in the name is changed to "_MAX_".))^ +** ^Attempts to increase a limit above its hard upper bound are +** silently truncated to the hard upper bound. +** +** Run-time limits are intended for use in applications that manage +** both their own internal database and also databases that are controlled +** by untrusted external sources. An example application might be a +** web browser that has its own databases for storing history and +** separate databases controlled by JavaScript applications downloaded +** off the Internet. The internal databases can be given the +** large, default limits. Databases managed by external sources can +** be given much smaller limits designed to prevent a denial of service +** attack. Developers might also want to use the [sqlite3_set_authorizer()] +** interface to further control untrusted SQL. The size of the database +** created by an untrusted script can be contained using the +** [max_page_count] [PRAGMA]. +** +** New run-time limit categories may be added in future releases. +*/ +SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); + +/* +** CAPI3REF: Run-Time Limit Categories +** KEYWORDS: {limit category} {*limit categories} +** +** These constants define various performance limits +** that can be lowered at run-time using [sqlite3_limit()]. +** The synopsis of the meanings of the various limits is shown below. +** Additional information is available at [limits | Limits in SQLite]. +** +**
+** ^(
SQLITE_LIMIT_LENGTH
+**
The maximum size of any string or BLOB or table row.
)^ +** +** ^(
SQLITE_LIMIT_SQL_LENGTH
+**
The maximum length of an SQL statement, in bytes.
)^ +** +** ^(
SQLITE_LIMIT_COLUMN
+**
The maximum number of columns in a table definition or in the +** result set of a [SELECT] or the maximum number of columns in an index +** or in an ORDER BY or GROUP BY clause.
)^ +** +** ^(
SQLITE_LIMIT_EXPR_DEPTH
+**
The maximum depth of the parse tree on any expression.
)^ +** +** ^(
SQLITE_LIMIT_COMPOUND_SELECT
+**
The maximum number of terms in a compound SELECT statement.
)^ +** +** ^(
SQLITE_LIMIT_VDBE_OP
+**
The maximum number of instructions in a virtual machine program +** used to implement an SQL statement.
)^ +** +** ^(
SQLITE_LIMIT_FUNCTION_ARG
+**
The maximum number of arguments on a function.
)^ +** +** ^(
SQLITE_LIMIT_ATTACHED
+**
The maximum number of [ATTACH | attached databases].)^
+** +** ^(
SQLITE_LIMIT_LIKE_PATTERN_LENGTH
+**
The maximum length of the pattern argument to the [LIKE] or +** [GLOB] operators.
)^ +** +** ^(
SQLITE_LIMIT_VARIABLE_NUMBER
+**
The maximum number of variables in an SQL statement that can +** be bound.
)^ +** +** ^(
SQLITE_LIMIT_TRIGGER_DEPTH
+**
The maximum depth of recursion for triggers.
)^ +**
+*/ +#define SQLITE_LIMIT_LENGTH 0 +#define SQLITE_LIMIT_SQL_LENGTH 1 +#define SQLITE_LIMIT_COLUMN 2 +#define SQLITE_LIMIT_EXPR_DEPTH 3 +#define SQLITE_LIMIT_COMPOUND_SELECT 4 +#define SQLITE_LIMIT_VDBE_OP 5 +#define SQLITE_LIMIT_FUNCTION_ARG 6 +#define SQLITE_LIMIT_ATTACHED 7 +#define SQLITE_LIMIT_LIKE_PATTERN_LENGTH 8 +#define SQLITE_LIMIT_VARIABLE_NUMBER 9 +#define SQLITE_LIMIT_TRIGGER_DEPTH 10 + +/* +** CAPI3REF: Compiling An SQL Statement +** KEYWORDS: {SQL statement compiler} +** +** To execute an SQL query, it must first be compiled into a byte-code +** program using one of these routines. +** +** The first argument, "db", is a [database connection] obtained from a +** prior successful call to [sqlite3_open()], [sqlite3_open_v2()] or +** [sqlite3_open16()]. The database connection must not have been closed. +** +** The second argument, "zSql", is the statement to be compiled, encoded +** as either UTF-8 or UTF-16. The sqlite3_prepare() and sqlite3_prepare_v2() +** interfaces use UTF-8, and sqlite3_prepare16() and sqlite3_prepare16_v2() +** use UTF-16. +** +** ^If the nByte argument is less than zero, then zSql is read up to the +** first zero terminator. ^If nByte is non-negative, then it is the maximum +** number of bytes read from zSql. ^When nByte is non-negative, the +** zSql string ends at either the first '\000' or '\u0000' character or +** the nByte-th byte, whichever comes first. If the caller knows +** that the supplied string is nul-terminated, then there is a small +** performance advantage to be gained by passing an nByte parameter that +** is equal to the number of bytes in the input string including +** the nul-terminator bytes. +** +** ^If pzTail is not NULL then *pzTail is made to point to the first byte +** past the end of the first SQL statement in zSql. These routines only +** compile the first statement in zSql, so *pzTail is left pointing to +** what remains uncompiled. +** +** ^*ppStmt is left pointing to a compiled [prepared statement] that can be +** executed using [sqlite3_step()]. ^If there is an error, *ppStmt is set +** to NULL. ^If the input text contains no SQL (if the input is an empty +** string or a comment) then *ppStmt is set to NULL. +** The calling procedure is responsible for deleting the compiled +** SQL statement using [sqlite3_finalize()] after it has finished with it. +** ppStmt may not be NULL. +** +** ^On success, the sqlite3_prepare() family of routines return [SQLITE_OK]; +** otherwise an [error code] is returned. +** +** The sqlite3_prepare_v2() and sqlite3_prepare16_v2() interfaces are +** recommended for all new programs. The two older interfaces are retained +** for backwards compatibility, but their use is discouraged. +** ^In the "v2" interfaces, the prepared statement +** that is returned (the [sqlite3_stmt] object) contains a copy of the +** original SQL text. This causes the [sqlite3_step()] interface to +** behave differently in three ways: +** +**
    +**
  1. +** ^If the database schema changes, instead of returning [SQLITE_SCHEMA] as it +** always used to do, [sqlite3_step()] will automatically recompile the SQL +** statement and try to run it again. ^If the schema has changed in +** a way that makes the statement no longer valid, [sqlite3_step()] will still +** return [SQLITE_SCHEMA]. But unlike the legacy behavior, [SQLITE_SCHEMA] is +** now a fatal error. Calling [sqlite3_prepare_v2()] again will not make the +** error go away. Note: use [sqlite3_errmsg()] to find the text +** of the parsing error that results in an [SQLITE_SCHEMA] return. +**
  2. +** +**
  3. +** ^When an error occurs, [sqlite3_step()] will return one of the detailed +** [error codes] or [extended error codes]. ^The legacy behavior was that +** [sqlite3_step()] would only return a generic [SQLITE_ERROR] result code +** and the application would have to make a second call to [sqlite3_reset()] +** in order to find the underlying cause of the problem. With the "v2" prepare +** interfaces, the underlying reason for the error is returned immediately. +**
  4. +** +**
  5. +** ^If the value of a [parameter | host parameter] in the WHERE clause might +** change the query plan for a statement, then the statement may be +** automatically recompiled (as if there had been a schema change) on the first +** [sqlite3_step()] call following any change to the +** [sqlite3_bind_text | bindings] of the [parameter]. +**
  6. +**
+*/ +SQLITE_API int sqlite3_prepare( + sqlite3 *db, /* Database handle */ + const char *zSql, /* SQL statement, UTF-8 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const char **pzTail /* OUT: Pointer to unused portion of zSql */ +); +SQLITE_API int sqlite3_prepare_v2( + sqlite3 *db, /* Database handle */ + const char *zSql, /* SQL statement, UTF-8 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const char **pzTail /* OUT: Pointer to unused portion of zSql */ +); +SQLITE_API int sqlite3_prepare16( + sqlite3 *db, /* Database handle */ + const void *zSql, /* SQL statement, UTF-16 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const void **pzTail /* OUT: Pointer to unused portion of zSql */ +); +SQLITE_API int sqlite3_prepare16_v2( + sqlite3 *db, /* Database handle */ + const void *zSql, /* SQL statement, UTF-16 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const void **pzTail /* OUT: Pointer to unused portion of zSql */ +); + +/* +** CAPI3REF: Retrieving Statement SQL +** +** ^This interface can be used to retrieve a saved copy of the original +** SQL text used to create a [prepared statement] if that statement was +** compiled using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()]. +*/ +SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Dynamically Typed Value Object +** KEYWORDS: {protected sqlite3_value} {unprotected sqlite3_value} +** +** SQLite uses the sqlite3_value object to represent all values +** that can be stored in a database table. SQLite uses dynamic typing +** for the values it stores. ^Values stored in sqlite3_value objects +** can be integers, floating point values, strings, BLOBs, or NULL. +** +** An sqlite3_value object may be either "protected" or "unprotected". +** Some interfaces require a protected sqlite3_value. Other interfaces +** will accept either a protected or an unprotected sqlite3_value. +** Every interface that accepts sqlite3_value arguments specifies +** whether or not it requires a protected sqlite3_value. +** +** The terms "protected" and "unprotected" refer to whether or not +** a mutex is held. A internal mutex is held for a protected +** sqlite3_value object but no mutex is held for an unprotected +** sqlite3_value object. If SQLite is compiled to be single-threaded +** (with [SQLITE_THREADSAFE=0] and with [sqlite3_threadsafe()] returning 0) +** or if SQLite is run in one of reduced mutex modes +** [SQLITE_CONFIG_SINGLETHREAD] or [SQLITE_CONFIG_MULTITHREAD] +** then there is no distinction between protected and unprotected +** sqlite3_value objects and they can be used interchangeably. However, +** for maximum code portability it is recommended that applications +** still make the distinction between between protected and unprotected +** sqlite3_value objects even when not strictly required. +** +** ^The sqlite3_value objects that are passed as parameters into the +** implementation of [application-defined SQL functions] are protected. +** ^The sqlite3_value object returned by +** [sqlite3_column_value()] is unprotected. +** Unprotected sqlite3_value objects may only be used with +** [sqlite3_result_value()] and [sqlite3_bind_value()]. +** The [sqlite3_value_blob | sqlite3_value_type()] family of +** interfaces require protected sqlite3_value objects. +*/ +typedef struct Mem sqlite3_value; + +/* +** CAPI3REF: SQL Function Context Object +** +** The context in which an SQL function executes is stored in an +** sqlite3_context object. ^A pointer to an sqlite3_context object +** is always first parameter to [application-defined SQL functions]. +** The application-defined SQL function implementation will pass this +** pointer through into calls to [sqlite3_result_int | sqlite3_result()], +** [sqlite3_aggregate_context()], [sqlite3_user_data()], +** [sqlite3_context_db_handle()], [sqlite3_get_auxdata()], +** and/or [sqlite3_set_auxdata()]. +*/ +typedef struct sqlite3_context sqlite3_context; + +/* +** CAPI3REF: Binding Values To Prepared Statements +** KEYWORDS: {host parameter} {host parameters} {host parameter name} +** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding} +** +** ^(In the SQL statement text input to [sqlite3_prepare_v2()] and its variants, +** literals may be replaced by a [parameter] that matches one of following +** templates: +** +**
    +**
  • ? +**
  • ?NNN +**
  • :VVV +**
  • @VVV +**
  • $VVV +**
+** +** In the templates above, NNN represents an integer literal, +** and VVV represents an alphanumeric identifer.)^ ^The values of these +** parameters (also called "host parameter names" or "SQL parameters") +** can be set using the sqlite3_bind_*() routines defined here. +** +** ^The first argument to the sqlite3_bind_*() routines is always +** a pointer to the [sqlite3_stmt] object returned from +** [sqlite3_prepare_v2()] or its variants. +** +** ^The second argument is the index of the SQL parameter to be set. +** ^The leftmost SQL parameter has an index of 1. ^When the same named +** SQL parameter is used more than once, second and subsequent +** occurrences have the same index as the first occurrence. +** ^The index for named parameters can be looked up using the +** [sqlite3_bind_parameter_index()] API if desired. ^The index +** for "?NNN" parameters is the value of NNN. +** ^The NNN value must be between 1 and the [sqlite3_limit()] +** parameter [SQLITE_LIMIT_VARIABLE_NUMBER] (default value: 999). +** +** ^The third argument is the value to bind to the parameter. +** +** ^(In those routines that have a fourth argument, its value is the +** number of bytes in the parameter. To be clear: the value is the +** number of bytes in the value, not the number of characters.)^ +** ^If the fourth parameter is negative, the length of the string is +** the number of bytes up to the first zero terminator. +** +** ^The fifth argument to sqlite3_bind_blob(), sqlite3_bind_text(), and +** sqlite3_bind_text16() is a destructor used to dispose of the BLOB or +** string after SQLite has finished with it. ^If the fifth argument is +** the special value [SQLITE_STATIC], then SQLite assumes that the +** information is in static, unmanaged space and does not need to be freed. +** ^If the fifth argument has the value [SQLITE_TRANSIENT], then +** SQLite makes its own private copy of the data immediately, before +** the sqlite3_bind_*() routine returns. +** +** ^The sqlite3_bind_zeroblob() routine binds a BLOB of length N that +** is filled with zeroes. ^A zeroblob uses a fixed amount of memory +** (just an integer to hold its size) while it is being processed. +** Zeroblobs are intended to serve as placeholders for BLOBs whose +** content is later written using +** [sqlite3_blob_open | incremental BLOB I/O] routines. +** ^A negative value for the zeroblob results in a zero-length BLOB. +** +** ^If any of the sqlite3_bind_*() routines are called with a NULL pointer +** for the [prepared statement] or with a prepared statement for which +** [sqlite3_step()] has been called more recently than [sqlite3_reset()], +** then the call will return [SQLITE_MISUSE]. If any sqlite3_bind_() +** routine is passed a [prepared statement] that has been finalized, the +** result is undefined and probably harmful. +** +** ^Bindings are not cleared by the [sqlite3_reset()] routine. +** ^Unbound parameters are interpreted as NULL. +** +** ^The sqlite3_bind_* routines return [SQLITE_OK] on success or an +** [error code] if anything goes wrong. +** ^[SQLITE_RANGE] is returned if the parameter +** index is out of range. ^[SQLITE_NOMEM] is returned if malloc() fails. +** +** See also: [sqlite3_bind_parameter_count()], +** [sqlite3_bind_parameter_name()], and [sqlite3_bind_parameter_index()]. +*/ +SQLITE_API int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*)); +SQLITE_API int sqlite3_bind_double(sqlite3_stmt*, int, double); +SQLITE_API int sqlite3_bind_int(sqlite3_stmt*, int, int); +SQLITE_API int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64); +SQLITE_API int sqlite3_bind_null(sqlite3_stmt*, int); +SQLITE_API int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*)); +SQLITE_API int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*)); +SQLITE_API int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); +SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n); + +/* +** CAPI3REF: Number Of SQL Parameters +** +** ^This routine can be used to find the number of [SQL parameters] +** in a [prepared statement]. SQL parameters are tokens of the +** form "?", "?NNN", ":AAA", "$AAA", or "@AAA" that serve as +** placeholders for values that are [sqlite3_bind_blob | bound] +** to the parameters at a later time. +** +** ^(This routine actually returns the index of the largest (rightmost) +** parameter. For all forms except ?NNN, this will correspond to the +** number of unique parameters. If parameters of the ?NNN form are used, +** there may be gaps in the list.)^ +** +** See also: [sqlite3_bind_blob|sqlite3_bind()], +** [sqlite3_bind_parameter_name()], and +** [sqlite3_bind_parameter_index()]. +*/ +SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt*); + +/* +** CAPI3REF: Name Of A Host Parameter +** +** ^The sqlite3_bind_parameter_name(P,N) interface returns +** the name of the N-th [SQL parameter] in the [prepared statement] P. +** ^(SQL parameters of the form "?NNN" or ":AAA" or "@AAA" or "$AAA" +** have a name which is the string "?NNN" or ":AAA" or "@AAA" or "$AAA" +** respectively. +** In other words, the initial ":" or "$" or "@" or "?" +** is included as part of the name.)^ +** ^Parameters of the form "?" without a following integer have no name +** and are referred to as "nameless" or "anonymous parameters". +** +** ^The first host parameter has an index of 1, not 0. +** +** ^If the value N is out of range or if the N-th parameter is +** nameless, then NULL is returned. ^The returned string is +** always in UTF-8 encoding even if the named parameter was +** originally specified as UTF-16 in [sqlite3_prepare16()] or +** [sqlite3_prepare16_v2()]. +** +** See also: [sqlite3_bind_blob|sqlite3_bind()], +** [sqlite3_bind_parameter_count()], and +** [sqlite3_bind_parameter_index()]. +*/ +SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int); + +/* +** CAPI3REF: Index Of A Parameter With A Given Name +** +** ^Return the index of an SQL parameter given its name. ^The +** index value returned is suitable for use as the second +** parameter to [sqlite3_bind_blob|sqlite3_bind()]. ^A zero +** is returned if no matching parameter is found. ^The parameter +** name must be given in UTF-8 even if the original statement +** was prepared from UTF-16 text using [sqlite3_prepare16_v2()]. +** +** See also: [sqlite3_bind_blob|sqlite3_bind()], +** [sqlite3_bind_parameter_count()], and +** [sqlite3_bind_parameter_index()]. +*/ +SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName); + +/* +** CAPI3REF: Reset All Bindings On A Prepared Statement +** +** ^Contrary to the intuition of many, [sqlite3_reset()] does not reset +** the [sqlite3_bind_blob | bindings] on a [prepared statement]. +** ^Use this routine to reset all host parameters to NULL. +*/ +SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt*); + +/* +** CAPI3REF: Number Of Columns In A Result Set +** +** ^Return the number of columns in the result set returned by the +** [prepared statement]. ^This routine returns 0 if pStmt is an SQL +** statement that does not return data (for example an [UPDATE]). +*/ +SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Column Names In A Result Set +** +** ^These routines return the name assigned to a particular column +** in the result set of a [SELECT] statement. ^The sqlite3_column_name() +** interface returns a pointer to a zero-terminated UTF-8 string +** and sqlite3_column_name16() returns a pointer to a zero-terminated +** UTF-16 string. ^The first parameter is the [prepared statement] +** that implements the [SELECT] statement. ^The second parameter is the +** column number. ^The leftmost column is number 0. +** +** ^The returned string pointer is valid until either the [prepared statement] +** is destroyed by [sqlite3_finalize()] or until the next call to +** sqlite3_column_name() or sqlite3_column_name16() on the same column. +** +** ^If sqlite3_malloc() fails during the processing of either routine +** (for example during a conversion from UTF-8 to UTF-16) then a +** NULL pointer is returned. +** +** ^The name of a result column is the value of the "AS" clause for +** that column, if there is an AS clause. If there is no AS clause +** then the name of the column is unspecified and may change from +** one release of SQLite to the next. +*/ +SQLITE_API const char *sqlite3_column_name(sqlite3_stmt*, int N); +SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N); + +/* +** CAPI3REF: Source Of Data In A Query Result +** +** ^These routines provide a means to determine the database, table, and +** table column that is the origin of a particular result column in +** [SELECT] statement. +** ^The name of the database or table or column can be returned as +** either a UTF-8 or UTF-16 string. ^The _database_ routines return +** the database name, the _table_ routines return the table name, and +** the origin_ routines return the column name. +** ^The returned string is valid until the [prepared statement] is destroyed +** using [sqlite3_finalize()] or until the same information is requested +** again in a different encoding. +** +** ^The names returned are the original un-aliased names of the +** database, table, and column. +** +** ^The first argument to these interfaces is a [prepared statement]. +** ^These functions return information about the Nth result column returned by +** the statement, where N is the second function argument. +** ^The left-most column is column 0 for these routines. +** +** ^If the Nth column returned by the statement is an expression or +** subquery and is not a column value, then all of these functions return +** NULL. ^These routine might also return NULL if a memory allocation error +** occurs. ^Otherwise, they return the name of the attached database, table, +** or column that query result column was extracted from. +** +** ^As with all other SQLite APIs, those whose names end with "16" return +** UTF-16 encoded strings and the other functions return UTF-8. +** +** ^These APIs are only available if the library was compiled with the +** [SQLITE_ENABLE_COLUMN_METADATA] C-preprocessor symbol. +** +** If two or more threads call one or more of these routines against the same +** prepared statement and column at the same time then the results are +** undefined. +** +** If two or more threads call one or more +** [sqlite3_column_database_name | column metadata interfaces] +** for the same [prepared statement] and result column +** at the same time then the results are undefined. +*/ +SQLITE_API const char *sqlite3_column_database_name(sqlite3_stmt*,int); +SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt*,int); +SQLITE_API const char *sqlite3_column_table_name(sqlite3_stmt*,int); +SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt*,int); +SQLITE_API const char *sqlite3_column_origin_name(sqlite3_stmt*,int); +SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt*,int); + +/* +** CAPI3REF: Declared Datatype Of A Query Result +** +** ^(The first parameter is a [prepared statement]. +** If this statement is a [SELECT] statement and the Nth column of the +** returned result set of that [SELECT] is a table column (not an +** expression or subquery) then the declared type of the table +** column is returned.)^ ^If the Nth column of the result set is an +** expression or subquery, then a NULL pointer is returned. +** ^The returned string is always UTF-8 encoded. +** +** ^(For example, given the database schema: +** +** CREATE TABLE t1(c1 VARIANT); +** +** and the following statement to be compiled: +** +** SELECT c1 + 1, c1 FROM t1; +** +** this routine would return the string "VARIANT" for the second result +** column (i==1), and a NULL pointer for the first result column (i==0).)^ +** +** ^SQLite uses dynamic run-time typing. ^So just because a column +** is declared to contain a particular type does not mean that the +** data stored in that column is of the declared type. SQLite is +** strongly typed, but the typing is dynamic not static. ^Type +** is associated with individual values, not with the containers +** used to hold those values. +*/ +SQLITE_API const char *sqlite3_column_decltype(sqlite3_stmt*,int); +SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int); + +/* +** CAPI3REF: Evaluate An SQL Statement +** +** After a [prepared statement] has been prepared using either +** [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] or one of the legacy +** interfaces [sqlite3_prepare()] or [sqlite3_prepare16()], this function +** must be called one or more times to evaluate the statement. +** +** The details of the behavior of the sqlite3_step() interface depend +** on whether the statement was prepared using the newer "v2" interface +** [sqlite3_prepare_v2()] and [sqlite3_prepare16_v2()] or the older legacy +** interface [sqlite3_prepare()] and [sqlite3_prepare16()]. The use of the +** new "v2" interface is recommended for new applications but the legacy +** interface will continue to be supported. +** +** ^In the legacy interface, the return value will be either [SQLITE_BUSY], +** [SQLITE_DONE], [SQLITE_ROW], [SQLITE_ERROR], or [SQLITE_MISUSE]. +** ^With the "v2" interface, any of the other [result codes] or +** [extended result codes] might be returned as well. +** +** ^[SQLITE_BUSY] means that the database engine was unable to acquire the +** database locks it needs to do its job. ^If the statement is a [COMMIT] +** or occurs outside of an explicit transaction, then you can retry the +** statement. If the statement is not a [COMMIT] and occurs within a +** explicit transaction then you should rollback the transaction before +** continuing. +** +** ^[SQLITE_DONE] means that the statement has finished executing +** successfully. sqlite3_step() should not be called again on this virtual +** machine without first calling [sqlite3_reset()] to reset the virtual +** machine back to its initial state. +** +** ^If the SQL statement being executed returns any data, then [SQLITE_ROW] +** is returned each time a new row of data is ready for processing by the +** caller. The values may be accessed using the [column access functions]. +** sqlite3_step() is called again to retrieve the next row of data. +** +** ^[SQLITE_ERROR] means that a run-time error (such as a constraint +** violation) has occurred. sqlite3_step() should not be called again on +** the VM. More information may be found by calling [sqlite3_errmsg()]. +** ^With the legacy interface, a more specific error code (for example, +** [SQLITE_INTERRUPT], [SQLITE_SCHEMA], [SQLITE_CORRUPT], and so forth) +** can be obtained by calling [sqlite3_reset()] on the +** [prepared statement]. ^In the "v2" interface, +** the more specific error code is returned directly by sqlite3_step(). +** +** [SQLITE_MISUSE] means that the this routine was called inappropriately. +** Perhaps it was called on a [prepared statement] that has +** already been [sqlite3_finalize | finalized] or on one that had +** previously returned [SQLITE_ERROR] or [SQLITE_DONE]. Or it could +** be the case that the same database connection is being used by two or +** more threads at the same moment in time. +** +** Goofy Interface Alert: In the legacy interface, the sqlite3_step() +** API always returns a generic error code, [SQLITE_ERROR], following any +** error other than [SQLITE_BUSY] and [SQLITE_MISUSE]. You must call +** [sqlite3_reset()] or [sqlite3_finalize()] in order to find one of the +** specific [error codes] that better describes the error. +** We admit that this is a goofy design. The problem has been fixed +** with the "v2" interface. If you prepare all of your SQL statements +** using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] instead +** of the legacy [sqlite3_prepare()] and [sqlite3_prepare16()] interfaces, +** then the more specific [error codes] are returned directly +** by sqlite3_step(). The use of the "v2" interface is recommended. +*/ +SQLITE_API int sqlite3_step(sqlite3_stmt*); + +/* +** CAPI3REF: Number of columns in a result set +** +** ^The sqlite3_data_count(P) the number of columns in the +** of the result set of [prepared statement] P. +*/ +SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Fundamental Datatypes +** KEYWORDS: SQLITE_TEXT +** +** ^(Every value in SQLite has one of five fundamental datatypes: +** +**
    +**
  • 64-bit signed integer +**
  • 64-bit IEEE floating point number +**
  • string +**
  • BLOB +**
  • NULL +**
)^ +** +** These constants are codes for each of those types. +** +** Note that the SQLITE_TEXT constant was also used in SQLite version 2 +** for a completely different meaning. Software that links against both +** SQLite version 2 and SQLite version 3 should use SQLITE3_TEXT, not +** SQLITE_TEXT. +*/ +#define SQLITE_INTEGER 1 +#define SQLITE_FLOAT 2 +#define SQLITE_BLOB 4 +#define SQLITE_NULL 5 +#ifdef SQLITE_TEXT +# undef SQLITE_TEXT +#else +# define SQLITE_TEXT 3 +#endif +#define SQLITE3_TEXT 3 + +/* +** CAPI3REF: Result Values From A Query +** KEYWORDS: {column access functions} +** +** These routines form the "result set" interface. +** +** ^These routines return information about a single column of the current +** result row of a query. ^In every case the first argument is a pointer +** to the [prepared statement] that is being evaluated (the [sqlite3_stmt*] +** that was returned from [sqlite3_prepare_v2()] or one of its variants) +** and the second argument is the index of the column for which information +** should be returned. ^The leftmost column of the result set has the index 0. +** ^The number of columns in the result can be determined using +** [sqlite3_column_count()]. +** +** If the SQL statement does not currently point to a valid row, or if the +** column index is out of range, the result is undefined. +** These routines may only be called when the most recent call to +** [sqlite3_step()] has returned [SQLITE_ROW] and neither +** [sqlite3_reset()] nor [sqlite3_finalize()] have been called subsequently. +** If any of these routines are called after [sqlite3_reset()] or +** [sqlite3_finalize()] or after [sqlite3_step()] has returned +** something other than [SQLITE_ROW], the results are undefined. +** If [sqlite3_step()] or [sqlite3_reset()] or [sqlite3_finalize()] +** are called from a different thread while any of these routines +** are pending, then the results are undefined. +** +** ^The sqlite3_column_type() routine returns the +** [SQLITE_INTEGER | datatype code] for the initial data type +** of the result column. ^The returned value is one of [SQLITE_INTEGER], +** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL]. The value +** returned by sqlite3_column_type() is only meaningful if no type +** conversions have occurred as described below. After a type conversion, +** the value returned by sqlite3_column_type() is undefined. Future +** versions of SQLite may change the behavior of sqlite3_column_type() +** following a type conversion. +** +** ^If the result is a BLOB or UTF-8 string then the sqlite3_column_bytes() +** routine returns the number of bytes in that BLOB or string. +** ^If the result is a UTF-16 string, then sqlite3_column_bytes() converts +** the string to UTF-8 and then returns the number of bytes. +** ^If the result is a numeric value then sqlite3_column_bytes() uses +** [sqlite3_snprintf()] to convert that value to a UTF-8 string and returns +** the number of bytes in that string. +** ^The value returned does not include the zero terminator at the end +** of the string. ^For clarity: the value returned is the number of +** bytes in the string, not the number of characters. +** +** ^Strings returned by sqlite3_column_text() and sqlite3_column_text16(), +** even empty strings, are always zero terminated. ^The return +** value from sqlite3_column_blob() for a zero-length BLOB is an arbitrary +** pointer, possibly even a NULL pointer. +** +** ^The sqlite3_column_bytes16() routine is similar to sqlite3_column_bytes() +** but leaves the result in UTF-16 in native byte order instead of UTF-8. +** ^The zero terminator is not included in this count. +** +** ^The object returned by [sqlite3_column_value()] is an +** [unprotected sqlite3_value] object. An unprotected sqlite3_value object +** may only be used with [sqlite3_bind_value()] and [sqlite3_result_value()]. +** If the [unprotected sqlite3_value] object returned by +** [sqlite3_column_value()] is used in any other way, including calls +** to routines like [sqlite3_value_int()], [sqlite3_value_text()], +** or [sqlite3_value_bytes()], then the behavior is undefined. +** +** These routines attempt to convert the value where appropriate. ^For +** example, if the internal representation is FLOAT and a text result +** is requested, [sqlite3_snprintf()] is used internally to perform the +** conversion automatically. ^(The following table details the conversions +** that are applied: +** +**
+** +**
Internal
Type
Requested
Type
Conversion +** +**
NULL INTEGER Result is 0 +**
NULL FLOAT Result is 0.0 +**
NULL TEXT Result is NULL pointer +**
NULL BLOB Result is NULL pointer +**
INTEGER FLOAT Convert from integer to float +**
INTEGER TEXT ASCII rendering of the integer +**
INTEGER BLOB Same as INTEGER->TEXT +**
FLOAT INTEGER Convert from float to integer +**
FLOAT TEXT ASCII rendering of the float +**
FLOAT BLOB Same as FLOAT->TEXT +**
TEXT INTEGER Use atoi() +**
TEXT FLOAT Use atof() +**
TEXT BLOB No change +**
BLOB INTEGER Convert to TEXT then use atoi() +**
BLOB FLOAT Convert to TEXT then use atof() +**
BLOB TEXT Add a zero terminator if needed +**
+**
)^ +** +** The table above makes reference to standard C library functions atoi() +** and atof(). SQLite does not really use these functions. It has its +** own equivalent internal routines. The atoi() and atof() names are +** used in the table for brevity and because they are familiar to most +** C programmers. +** +** ^Note that when type conversions occur, pointers returned by prior +** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or +** sqlite3_column_text16() may be invalidated. +** ^(Type conversions and pointer invalidations might occur +** in the following cases: +** +**
    +**
  • The initial content is a BLOB and sqlite3_column_text() or +** sqlite3_column_text16() is called. A zero-terminator might +** need to be added to the string.
  • +**
  • The initial content is UTF-8 text and sqlite3_column_bytes16() or +** sqlite3_column_text16() is called. The content must be converted +** to UTF-16.
  • +**
  • The initial content is UTF-16 text and sqlite3_column_bytes() or +** sqlite3_column_text() is called. The content must be converted +** to UTF-8.
  • +**
)^ +** +** ^Conversions between UTF-16be and UTF-16le are always done in place and do +** not invalidate a prior pointer, though of course the content of the buffer +** that the prior pointer points to will have been modified. Other kinds +** of conversion are done in place when it is possible, but sometimes they +** are not possible and in those cases prior pointers are invalidated. +** +** ^(The safest and easiest to remember policy is to invoke these routines +** in one of the following ways: +** +**
    +**
  • sqlite3_column_text() followed by sqlite3_column_bytes()
  • +**
  • sqlite3_column_blob() followed by sqlite3_column_bytes()
  • +**
  • sqlite3_column_text16() followed by sqlite3_column_bytes16()
  • +**
)^ +** +** In other words, you should call sqlite3_column_text(), +** sqlite3_column_blob(), or sqlite3_column_text16() first to force the result +** into the desired format, then invoke sqlite3_column_bytes() or +** sqlite3_column_bytes16() to find the size of the result. Do not mix calls +** to sqlite3_column_text() or sqlite3_column_blob() with calls to +** sqlite3_column_bytes16(), and do not mix calls to sqlite3_column_text16() +** with calls to sqlite3_column_bytes(). +** +** ^The pointers returned are valid until a type conversion occurs as +** described above, or until [sqlite3_step()] or [sqlite3_reset()] or +** [sqlite3_finalize()] is called. ^The memory space used to hold strings +** and BLOBs is freed automatically. Do not pass the pointers returned +** [sqlite3_column_blob()], [sqlite3_column_text()], etc. into +** [sqlite3_free()]. +** +** ^(If a memory allocation error occurs during the evaluation of any +** of these routines, a default value is returned. The default value +** is either the integer 0, the floating point number 0.0, or a NULL +** pointer. Subsequent calls to [sqlite3_errcode()] will return +** [SQLITE_NOMEM].)^ +*/ +SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); +SQLITE_API int sqlite3_column_bytes(sqlite3_stmt*, int iCol); +SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt*, int iCol); +SQLITE_API double sqlite3_column_double(sqlite3_stmt*, int iCol); +SQLITE_API int sqlite3_column_int(sqlite3_stmt*, int iCol); +SQLITE_API sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol); +SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol); +SQLITE_API const void *sqlite3_column_text16(sqlite3_stmt*, int iCol); +SQLITE_API int sqlite3_column_type(sqlite3_stmt*, int iCol); +SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol); + +/* +** CAPI3REF: Destroy A Prepared Statement Object +** +** ^The sqlite3_finalize() function is called to delete a [prepared statement]. +** ^If the statement was executed successfully or not executed at all, then +** SQLITE_OK is returned. ^If execution of the statement failed then an +** [error code] or [extended error code] is returned. +** +** ^This routine can be called at any point during the execution of the +** [prepared statement]. ^If the virtual machine has not +** completed execution when this routine is called, that is like +** encountering an error or an [sqlite3_interrupt | interrupt]. +** ^Incomplete updates may be rolled back and transactions canceled, +** depending on the circumstances, and the +** [error code] returned will be [SQLITE_ABORT]. +*/ +SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Reset A Prepared Statement Object +** +** The sqlite3_reset() function is called to reset a [prepared statement] +** object back to its initial state, ready to be re-executed. +** ^Any SQL statement variables that had values bound to them using +** the [sqlite3_bind_blob | sqlite3_bind_*() API] retain their values. +** Use [sqlite3_clear_bindings()] to reset the bindings. +** +** ^The [sqlite3_reset(S)] interface resets the [prepared statement] S +** back to the beginning of its program. +** +** ^If the most recent call to [sqlite3_step(S)] for the +** [prepared statement] S returned [SQLITE_ROW] or [SQLITE_DONE], +** or if [sqlite3_step(S)] has never before been called on S, +** then [sqlite3_reset(S)] returns [SQLITE_OK]. +** +** ^If the most recent call to [sqlite3_step(S)] for the +** [prepared statement] S indicated an error, then +** [sqlite3_reset(S)] returns an appropriate [error code]. +** +** ^The [sqlite3_reset(S)] interface does not change the values +** of any [sqlite3_bind_blob|bindings] on the [prepared statement] S. +*/ +SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Create Or Redefine SQL Functions +** KEYWORDS: {function creation routines} +** KEYWORDS: {application-defined SQL function} +** KEYWORDS: {application-defined SQL functions} +** +** ^These two functions (collectively known as "function creation routines") +** are used to add SQL functions or aggregates or to redefine the behavior +** of existing SQL functions or aggregates. The only difference between the +** two is that the second parameter, the name of the (scalar) function or +** aggregate, is encoded in UTF-8 for sqlite3_create_function() and UTF-16 +** for sqlite3_create_function16(). +** +** ^The first parameter is the [database connection] to which the SQL +** function is to be added. ^If an application uses more than one database +** connection then application-defined SQL functions must be added +** to each database connection separately. +** +** The second parameter is the name of the SQL function to be created or +** redefined. ^The length of the name is limited to 255 bytes, exclusive of +** the zero-terminator. Note that the name length limit is in bytes, not +** characters. ^Any attempt to create a function with a longer name +** will result in [SQLITE_ERROR] being returned. +** +** ^The third parameter (nArg) +** is the number of arguments that the SQL function or +** aggregate takes. ^If this parameter is -1, then the SQL function or +** aggregate may take any number of arguments between 0 and the limit +** set by [sqlite3_limit]([SQLITE_LIMIT_FUNCTION_ARG]). If the third +** parameter is less than -1 or greater than 127 then the behavior is +** undefined. +** +** The fourth parameter, eTextRep, specifies what +** [SQLITE_UTF8 | text encoding] this SQL function prefers for +** its parameters. Any SQL function implementation should be able to work +** work with UTF-8, UTF-16le, or UTF-16be. But some implementations may be +** more efficient with one encoding than another. ^An application may +** invoke sqlite3_create_function() or sqlite3_create_function16() multiple +** times with the same function but with different values of eTextRep. +** ^When multiple implementations of the same function are available, SQLite +** will pick the one that involves the least amount of data conversion. +** If there is only a single implementation which does not care what text +** encoding is used, then the fourth argument should be [SQLITE_ANY]. +** +** ^(The fifth parameter is an arbitrary pointer. The implementation of the +** function can gain access to this pointer using [sqlite3_user_data()].)^ +** +** The seventh, eighth and ninth parameters, xFunc, xStep and xFinal, are +** pointers to C-language functions that implement the SQL function or +** aggregate. ^A scalar SQL function requires an implementation of the xFunc +** callback only; NULL pointers should be passed as the xStep and xFinal +** parameters. ^An aggregate SQL function requires an implementation of xStep +** and xFinal and NULL should be passed for xFunc. ^To delete an existing +** SQL function or aggregate, pass NULL for all three function callbacks. +** +** ^It is permitted to register multiple implementations of the same +** functions with the same name but with either differing numbers of +** arguments or differing preferred text encodings. ^SQLite will use +** the implementation that most closely matches the way in which the +** SQL function is used. ^A function implementation with a non-negative +** nArg parameter is a better match than a function implementation with +** a negative nArg. ^A function where the preferred text encoding +** matches the database encoding is a better +** match than a function where the encoding is different. +** ^A function where the encoding difference is between UTF16le and UTF16be +** is a closer match than a function where the encoding difference is +** between UTF8 and UTF16. +** +** ^Built-in functions may be overloaded by new application-defined functions. +** ^The first application-defined function with a given name overrides all +** built-in functions in the same [database connection] with the same name. +** ^Subsequent application-defined functions of the same name only override +** prior application-defined functions that are an exact match for the +** number of parameters and preferred encoding. +** +** ^An application-defined function is permitted to call other +** SQLite interfaces. However, such calls must not +** close the database connection nor finalize or reset the prepared +** statement in which the function is running. +*/ +SQLITE_API int sqlite3_create_function( + sqlite3 *db, + const char *zFunctionName, + int nArg, + int eTextRep, + void *pApp, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*) +); +SQLITE_API int sqlite3_create_function16( + sqlite3 *db, + const void *zFunctionName, + int nArg, + int eTextRep, + void *pApp, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*) +); + +/* +** CAPI3REF: Text Encodings +** +** These constant define integer codes that represent the various +** text encodings supported by SQLite. +*/ +#define SQLITE_UTF8 1 +#define SQLITE_UTF16LE 2 +#define SQLITE_UTF16BE 3 +#define SQLITE_UTF16 4 /* Use native byte order */ +#define SQLITE_ANY 5 /* sqlite3_create_function only */ +#define SQLITE_UTF16_ALIGNED 8 /* sqlite3_create_collation only */ + +/* +** CAPI3REF: Deprecated Functions +** DEPRECATED +** +** These functions are [deprecated]. In order to maintain +** backwards compatibility with older code, these functions continue +** to be supported. However, new applications should avoid +** the use of these functions. To help encourage people to avoid +** using these functions, we are not going to tell you what they do. +*/ +#ifndef SQLITE_OMIT_DEPRECATED +SQLITE_API SQLITE_DEPRECATED int sqlite3_aggregate_count(sqlite3_context*); +SQLITE_API SQLITE_DEPRECATED int sqlite3_expired(sqlite3_stmt*); +SQLITE_API SQLITE_DEPRECATED int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*); +SQLITE_API SQLITE_DEPRECATED int sqlite3_global_recover(void); +SQLITE_API SQLITE_DEPRECATED void sqlite3_thread_cleanup(void); +SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),void*,sqlite3_int64); +#endif + +/* +** CAPI3REF: Obtaining SQL Function Parameter Values +** +** The C-language implementation of SQL functions and aggregates uses +** this set of interface routines to access the parameter values on +** the function or aggregate. +** +** The xFunc (for scalar functions) or xStep (for aggregates) parameters +** to [sqlite3_create_function()] and [sqlite3_create_function16()] +** define callbacks that implement the SQL functions and aggregates. +** The 4th parameter to these callbacks is an array of pointers to +** [protected sqlite3_value] objects. There is one [sqlite3_value] object for +** each parameter to the SQL function. These routines are used to +** extract values from the [sqlite3_value] objects. +** +** These routines work only with [protected sqlite3_value] objects. +** Any attempt to use these routines on an [unprotected sqlite3_value] +** object results in undefined behavior. +** +** ^These routines work just like the corresponding [column access functions] +** except that these routines take a single [protected sqlite3_value] object +** pointer instead of a [sqlite3_stmt*] pointer and an integer column number. +** +** ^The sqlite3_value_text16() interface extracts a UTF-16 string +** in the native byte-order of the host machine. ^The +** sqlite3_value_text16be() and sqlite3_value_text16le() interfaces +** extract UTF-16 strings as big-endian and little-endian respectively. +** +** ^(The sqlite3_value_numeric_type() interface attempts to apply +** numeric affinity to the value. This means that an attempt is +** made to convert the value to an integer or floating point. If +** such a conversion is possible without loss of information (in other +** words, if the value is a string that looks like a number) +** then the conversion is performed. Otherwise no conversion occurs. +** The [SQLITE_INTEGER | datatype] after conversion is returned.)^ +** +** Please pay particular attention to the fact that the pointer returned +** from [sqlite3_value_blob()], [sqlite3_value_text()], or +** [sqlite3_value_text16()] can be invalidated by a subsequent call to +** [sqlite3_value_bytes()], [sqlite3_value_bytes16()], [sqlite3_value_text()], +** or [sqlite3_value_text16()]. +** +** These routines must be called from the same thread as +** the SQL function that supplied the [sqlite3_value*] parameters. +*/ +SQLITE_API const void *sqlite3_value_blob(sqlite3_value*); +SQLITE_API int sqlite3_value_bytes(sqlite3_value*); +SQLITE_API int sqlite3_value_bytes16(sqlite3_value*); +SQLITE_API double sqlite3_value_double(sqlite3_value*); +SQLITE_API int sqlite3_value_int(sqlite3_value*); +SQLITE_API sqlite3_int64 sqlite3_value_int64(sqlite3_value*); +SQLITE_API const unsigned char *sqlite3_value_text(sqlite3_value*); +SQLITE_API const void *sqlite3_value_text16(sqlite3_value*); +SQLITE_API const void *sqlite3_value_text16le(sqlite3_value*); +SQLITE_API const void *sqlite3_value_text16be(sqlite3_value*); +SQLITE_API int sqlite3_value_type(sqlite3_value*); +SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*); + +/* +** CAPI3REF: Obtain Aggregate Function Context +** +** Implementions of aggregate SQL functions use this +** routine to allocate memory for storing their state. +** +** ^The first time the sqlite3_aggregate_context(C,N) routine is called +** for a particular aggregate function, SQLite +** allocates N of memory, zeroes out that memory, and returns a pointer +** to the new memory. ^On second and subsequent calls to +** sqlite3_aggregate_context() for the same aggregate function instance, +** the same buffer is returned. Sqlite3_aggregate_context() is normally +** called once for each invocation of the xStep callback and then one +** last time when the xFinal callback is invoked. ^(When no rows match +** an aggregate query, the xStep() callback of the aggregate function +** implementation is never called and xFinal() is called exactly once. +** In those cases, sqlite3_aggregate_context() might be called for the +** first time from within xFinal().)^ +** +** ^The sqlite3_aggregate_context(C,N) routine returns a NULL pointer if N is +** less than or equal to zero or if a memory allocate error occurs. +** +** ^(The amount of space allocated by sqlite3_aggregate_context(C,N) is +** determined by the N parameter on first successful call. Changing the +** value of N in subsequent call to sqlite3_aggregate_context() within +** the same aggregate function instance will not resize the memory +** allocation.)^ +** +** ^SQLite automatically frees the memory allocated by +** sqlite3_aggregate_context() when the aggregate query concludes. +** +** The first parameter must be a copy of the +** [sqlite3_context | SQL function context] that is the first parameter +** to the xStep or xFinal callback routine that implements the aggregate +** function. +** +** This routine must be called from the same thread in which +** the aggregate SQL function is running. +*/ +SQLITE_API void *sqlite3_aggregate_context(sqlite3_context*, int nBytes); + +/* +** CAPI3REF: User Data For Functions +** +** ^The sqlite3_user_data() interface returns a copy of +** the pointer that was the pUserData parameter (the 5th parameter) +** of the [sqlite3_create_function()] +** and [sqlite3_create_function16()] routines that originally +** registered the application defined function. +** +** This routine must be called from the same thread in which +** the application-defined function is running. +*/ +SQLITE_API void *sqlite3_user_data(sqlite3_context*); + +/* +** CAPI3REF: Database Connection For Functions +** +** ^The sqlite3_context_db_handle() interface returns a copy of +** the pointer to the [database connection] (the 1st parameter) +** of the [sqlite3_create_function()] +** and [sqlite3_create_function16()] routines that originally +** registered the application defined function. +*/ +SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*); + +/* +** CAPI3REF: Function Auxiliary Data +** +** The following two functions may be used by scalar SQL functions to +** associate metadata with argument values. If the same value is passed to +** multiple invocations of the same SQL function during query execution, under +** some circumstances the associated metadata may be preserved. This may +** be used, for example, to add a regular-expression matching scalar +** function. The compiled version of the regular expression is stored as +** metadata associated with the SQL value passed as the regular expression +** pattern. The compiled regular expression can be reused on multiple +** invocations of the same function so that the original pattern string +** does not need to be recompiled on each invocation. +** +** ^The sqlite3_get_auxdata() interface returns a pointer to the metadata +** associated by the sqlite3_set_auxdata() function with the Nth argument +** value to the application-defined function. ^If no metadata has been ever +** been set for the Nth argument of the function, or if the corresponding +** function parameter has changed since the meta-data was set, +** then sqlite3_get_auxdata() returns a NULL pointer. +** +** ^The sqlite3_set_auxdata() interface saves the metadata +** pointed to by its 3rd parameter as the metadata for the N-th +** argument of the application-defined function. Subsequent +** calls to sqlite3_get_auxdata() might return this data, if it has +** not been destroyed. +** ^If it is not NULL, SQLite will invoke the destructor +** function given by the 4th parameter to sqlite3_set_auxdata() on +** the metadata when the corresponding function parameter changes +** or when the SQL statement completes, whichever comes first. +** +** SQLite is free to call the destructor and drop metadata on any +** parameter of any function at any time. ^The only guarantee is that +** the destructor will be called before the metadata is dropped. +** +** ^(In practice, metadata is preserved between function calls for +** expressions that are constant at compile time. This includes literal +** values and [parameters].)^ +** +** These routines must be called from the same thread in which +** the SQL function is running. +*/ +SQLITE_API void *sqlite3_get_auxdata(sqlite3_context*, int N); +SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*)); + + +/* +** CAPI3REF: Constants Defining Special Destructor Behavior +** +** These are special values for the destructor that is passed in as the +** final argument to routines like [sqlite3_result_blob()]. ^If the destructor +** argument is SQLITE_STATIC, it means that the content pointer is constant +** and will never change. It does not need to be destroyed. ^The +** SQLITE_TRANSIENT value means that the content will likely change in +** the near future and that SQLite should make its own private copy of +** the content before returning. +** +** The typedef is necessary to work around problems in certain +** C++ compilers. See ticket #2191. +*/ +typedef void (*sqlite3_destructor_type)(void*); +#define SQLITE_STATIC ((sqlite3_destructor_type)0) +#define SQLITE_TRANSIENT ((sqlite3_destructor_type)-1) + +/* +** CAPI3REF: Setting The Result Of An SQL Function +** +** These routines are used by the xFunc or xFinal callbacks that +** implement SQL functions and aggregates. See +** [sqlite3_create_function()] and [sqlite3_create_function16()] +** for additional information. +** +** These functions work very much like the [parameter binding] family of +** functions used to bind values to host parameters in prepared statements. +** Refer to the [SQL parameter] documentation for additional information. +** +** ^The sqlite3_result_blob() interface sets the result from +** an application-defined function to be the BLOB whose content is pointed +** to by the second parameter and which is N bytes long where N is the +** third parameter. +** +** ^The sqlite3_result_zeroblob() interfaces set the result of +** the application-defined function to be a BLOB containing all zero +** bytes and N bytes in size, where N is the value of the 2nd parameter. +** +** ^The sqlite3_result_double() interface sets the result from +** an application-defined function to be a floating point value specified +** by its 2nd argument. +** +** ^The sqlite3_result_error() and sqlite3_result_error16() functions +** cause the implemented SQL function to throw an exception. +** ^SQLite uses the string pointed to by the +** 2nd parameter of sqlite3_result_error() or sqlite3_result_error16() +** as the text of an error message. ^SQLite interprets the error +** message string from sqlite3_result_error() as UTF-8. ^SQLite +** interprets the string from sqlite3_result_error16() as UTF-16 in native +** byte order. ^If the third parameter to sqlite3_result_error() +** or sqlite3_result_error16() is negative then SQLite takes as the error +** message all text up through the first zero character. +** ^If the third parameter to sqlite3_result_error() or +** sqlite3_result_error16() is non-negative then SQLite takes that many +** bytes (not characters) from the 2nd parameter as the error message. +** ^The sqlite3_result_error() and sqlite3_result_error16() +** routines make a private copy of the error message text before +** they return. Hence, the calling function can deallocate or +** modify the text after they return without harm. +** ^The sqlite3_result_error_code() function changes the error code +** returned by SQLite as a result of an error in a function. ^By default, +** the error code is SQLITE_ERROR. ^A subsequent call to sqlite3_result_error() +** or sqlite3_result_error16() resets the error code to SQLITE_ERROR. +** +** ^The sqlite3_result_toobig() interface causes SQLite to throw an error +** indicating that a string or BLOB is too long to represent. +** +** ^The sqlite3_result_nomem() interface causes SQLite to throw an error +** indicating that a memory allocation failed. +** +** ^The sqlite3_result_int() interface sets the return value +** of the application-defined function to be the 32-bit signed integer +** value given in the 2nd argument. +** ^The sqlite3_result_int64() interface sets the return value +** of the application-defined function to be the 64-bit signed integer +** value given in the 2nd argument. +** +** ^The sqlite3_result_null() interface sets the return value +** of the application-defined function to be NULL. +** +** ^The sqlite3_result_text(), sqlite3_result_text16(), +** sqlite3_result_text16le(), and sqlite3_result_text16be() interfaces +** set the return value of the application-defined function to be +** a text string which is represented as UTF-8, UTF-16 native byte order, +** UTF-16 little endian, or UTF-16 big endian, respectively. +** ^SQLite takes the text result from the application from +** the 2nd parameter of the sqlite3_result_text* interfaces. +** ^If the 3rd parameter to the sqlite3_result_text* interfaces +** is negative, then SQLite takes result text from the 2nd parameter +** through the first zero character. +** ^If the 3rd parameter to the sqlite3_result_text* interfaces +** is non-negative, then as many bytes (not characters) of the text +** pointed to by the 2nd parameter are taken as the application-defined +** function result. +** ^If the 4th parameter to the sqlite3_result_text* interfaces +** or sqlite3_result_blob is a non-NULL pointer, then SQLite calls that +** function as the destructor on the text or BLOB result when it has +** finished using that result. +** ^If the 4th parameter to the sqlite3_result_text* interfaces or to +** sqlite3_result_blob is the special constant SQLITE_STATIC, then SQLite +** assumes that the text or BLOB result is in constant space and does not +** copy the content of the parameter nor call a destructor on the content +** when it has finished using that result. +** ^If the 4th parameter to the sqlite3_result_text* interfaces +** or sqlite3_result_blob is the special constant SQLITE_TRANSIENT +** then SQLite makes a copy of the result into space obtained from +** from [sqlite3_malloc()] before it returns. +** +** ^The sqlite3_result_value() interface sets the result of +** the application-defined function to be a copy the +** [unprotected sqlite3_value] object specified by the 2nd parameter. ^The +** sqlite3_result_value() interface makes a copy of the [sqlite3_value] +** so that the [sqlite3_value] specified in the parameter may change or +** be deallocated after sqlite3_result_value() returns without harm. +** ^A [protected sqlite3_value] object may always be used where an +** [unprotected sqlite3_value] object is required, so either +** kind of [sqlite3_value] object can be used with this interface. +** +** If these routines are called from within the different thread +** than the one containing the application-defined function that received +** the [sqlite3_context] pointer, the results are undefined. +*/ +SQLITE_API void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*)); +SQLITE_API void sqlite3_result_double(sqlite3_context*, double); +SQLITE_API void sqlite3_result_error(sqlite3_context*, const char*, int); +SQLITE_API void sqlite3_result_error16(sqlite3_context*, const void*, int); +SQLITE_API void sqlite3_result_error_toobig(sqlite3_context*); +SQLITE_API void sqlite3_result_error_nomem(sqlite3_context*); +SQLITE_API void sqlite3_result_error_code(sqlite3_context*, int); +SQLITE_API void sqlite3_result_int(sqlite3_context*, int); +SQLITE_API void sqlite3_result_int64(sqlite3_context*, sqlite3_int64); +SQLITE_API void sqlite3_result_null(sqlite3_context*); +SQLITE_API void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*)); +SQLITE_API void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*)); +SQLITE_API void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*)); +SQLITE_API void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*)); +SQLITE_API void sqlite3_result_value(sqlite3_context*, sqlite3_value*); +SQLITE_API void sqlite3_result_zeroblob(sqlite3_context*, int n); + +/* +** CAPI3REF: Define New Collating Sequences +** +** These functions are used to add new collation sequences to the +** [database connection] specified as the first argument. +** +** ^The name of the new collation sequence is specified as a UTF-8 string +** for sqlite3_create_collation() and sqlite3_create_collation_v2() +** and a UTF-16 string for sqlite3_create_collation16(). ^In all cases +** the name is passed as the second function argument. +** +** ^The third argument may be one of the constants [SQLITE_UTF8], +** [SQLITE_UTF16LE], or [SQLITE_UTF16BE], indicating that the user-supplied +** routine expects to be passed pointers to strings encoded using UTF-8, +** UTF-16 little-endian, or UTF-16 big-endian, respectively. ^The +** third argument might also be [SQLITE_UTF16] to indicate that the routine +** expects pointers to be UTF-16 strings in the native byte order, or the +** argument can be [SQLITE_UTF16_ALIGNED] if the +** the routine expects pointers to 16-bit word aligned strings +** of UTF-16 in the native byte order. +** +** A pointer to the user supplied routine must be passed as the fifth +** argument. ^If it is NULL, this is the same as deleting the collation +** sequence (so that SQLite cannot call it anymore). +** ^Each time the application supplied function is invoked, it is passed +** as its first parameter a copy of the void* passed as the fourth argument +** to sqlite3_create_collation() or sqlite3_create_collation16(). +** +** ^The remaining arguments to the application-supplied routine are two strings, +** each represented by a (length, data) pair and encoded in the encoding +** that was passed as the third argument when the collation sequence was +** registered. The application defined collation routine should +** return negative, zero or positive if the first string is less than, +** equal to, or greater than the second string. i.e. (STRING1 - STRING2). +** +** ^The sqlite3_create_collation_v2() works like sqlite3_create_collation() +** except that it takes an extra argument which is a destructor for +** the collation. ^The destructor is called when the collation is +** destroyed and is passed a copy of the fourth parameter void* pointer +** of the sqlite3_create_collation_v2(). +** ^Collations are destroyed when they are overridden by later calls to the +** collation creation functions or when the [database connection] is closed +** using [sqlite3_close()]. +** +** See also: [sqlite3_collation_needed()] and [sqlite3_collation_needed16()]. +*/ +SQLITE_API int sqlite3_create_collation( + sqlite3*, + const char *zName, + int eTextRep, + void*, + int(*xCompare)(void*,int,const void*,int,const void*) +); +SQLITE_API int sqlite3_create_collation_v2( + sqlite3*, + const char *zName, + int eTextRep, + void*, + int(*xCompare)(void*,int,const void*,int,const void*), + void(*xDestroy)(void*) +); +SQLITE_API int sqlite3_create_collation16( + sqlite3*, + const void *zName, + int eTextRep, + void*, + int(*xCompare)(void*,int,const void*,int,const void*) +); + +/* +** CAPI3REF: Collation Needed Callbacks +** +** ^To avoid having to register all collation sequences before a database +** can be used, a single callback function may be registered with the +** [database connection] to be invoked whenever an undefined collation +** sequence is required. +** +** ^If the function is registered using the sqlite3_collation_needed() API, +** then it is passed the names of undefined collation sequences as strings +** encoded in UTF-8. ^If sqlite3_collation_needed16() is used, +** the names are passed as UTF-16 in machine native byte order. +** ^A call to either function replaces the existing collation-needed callback. +** +** ^(When the callback is invoked, the first argument passed is a copy +** of the second argument to sqlite3_collation_needed() or +** sqlite3_collation_needed16(). The second argument is the database +** connection. The third argument is one of [SQLITE_UTF8], [SQLITE_UTF16BE], +** or [SQLITE_UTF16LE], indicating the most desirable form of the collation +** sequence function required. The fourth parameter is the name of the +** required collation sequence.)^ +** +** The callback function should register the desired collation using +** [sqlite3_create_collation()], [sqlite3_create_collation16()], or +** [sqlite3_create_collation_v2()]. +*/ +SQLITE_API int sqlite3_collation_needed( + sqlite3*, + void*, + void(*)(void*,sqlite3*,int eTextRep,const char*) +); +SQLITE_API int sqlite3_collation_needed16( + sqlite3*, + void*, + void(*)(void*,sqlite3*,int eTextRep,const void*) +); + +#if SQLITE_HAS_CODEC +/* +** Specify the key for an encrypted database. This routine should be +** called right after sqlite3_open(). +** +** The code to implement this API is not available in the public release +** of SQLite. +*/ +SQLITE_API int sqlite3_key( + sqlite3 *db, /* Database to be rekeyed */ + const void *pKey, int nKey /* The key */ +); + +/* +** Change the key on an open database. If the current database is not +** encrypted, this routine will encrypt it. If pNew==0 or nNew==0, the +** database is decrypted. +** +** The code to implement this API is not available in the public release +** of SQLite. +*/ +SQLITE_API int sqlite3_rekey( + sqlite3 *db, /* Database to be rekeyed */ + const void *pKey, int nKey /* The new key */ +); + +/* +** Specify the activation key for a SEE database. Unless +** activated, none of the SEE routines will work. +*/ +SQLITE_API void sqlite3_activate_see( + const char *zPassPhrase /* Activation phrase */ +); +#endif + +#ifdef SQLITE_ENABLE_CEROD +/* +** Specify the activation key for a CEROD database. Unless +** activated, none of the CEROD routines will work. +*/ +SQLITE_API void sqlite3_activate_cerod( + const char *zPassPhrase /* Activation phrase */ +); +#endif + +/* +** CAPI3REF: Suspend Execution For A Short Time +** +** ^The sqlite3_sleep() function causes the current thread to suspend execution +** for at least a number of milliseconds specified in its parameter. +** +** ^If the operating system does not support sleep requests with +** millisecond time resolution, then the time will be rounded up to +** the nearest second. ^The number of milliseconds of sleep actually +** requested from the operating system is returned. +** +** ^SQLite implements this interface by calling the xSleep() +** method of the default [sqlite3_vfs] object. +*/ +SQLITE_API int sqlite3_sleep(int); + +/* +** CAPI3REF: Name Of The Folder Holding Temporary Files +** +** ^(If this global variable is made to point to a string which is +** the name of a folder (a.k.a. directory), then all temporary files +** created by SQLite when using a built-in [sqlite3_vfs | VFS] +** will be placed in that directory.)^ ^If this variable +** is a NULL pointer, then SQLite performs a search for an appropriate +** temporary file directory. +** +** It is not safe to read or modify this variable in more than one +** thread at a time. It is not safe to read or modify this variable +** if a [database connection] is being used at the same time in a separate +** thread. +** It is intended that this variable be set once +** as part of process initialization and before any SQLite interface +** routines have been called and that this variable remain unchanged +** thereafter. +** +** ^The [temp_store_directory pragma] may modify this variable and cause +** it to point to memory obtained from [sqlite3_malloc]. ^Furthermore, +** the [temp_store_directory pragma] always assumes that any string +** that this variable points to is held in memory obtained from +** [sqlite3_malloc] and the pragma may attempt to free that memory +** using [sqlite3_free]. +** Hence, if this variable is modified directly, either it should be +** made NULL or made to point to memory obtained from [sqlite3_malloc] +** or else the use of the [temp_store_directory pragma] should be avoided. +*/ +SQLITE_API SQLITE_EXTERN char *sqlite3_temp_directory; + +/* +** CAPI3REF: Test For Auto-Commit Mode +** KEYWORDS: {autocommit mode} +** +** ^The sqlite3_get_autocommit() interface returns non-zero or +** zero if the given database connection is or is not in autocommit mode, +** respectively. ^Autocommit mode is on by default. +** ^Autocommit mode is disabled by a [BEGIN] statement. +** ^Autocommit mode is re-enabled by a [COMMIT] or [ROLLBACK]. +** +** If certain kinds of errors occur on a statement within a multi-statement +** transaction (errors including [SQLITE_FULL], [SQLITE_IOERR], +** [SQLITE_NOMEM], [SQLITE_BUSY], and [SQLITE_INTERRUPT]) then the +** transaction might be rolled back automatically. The only way to +** find out whether SQLite automatically rolled back the transaction after +** an error is to use this function. +** +** If another thread changes the autocommit status of the database +** connection while this routine is running, then the return value +** is undefined. +*/ +SQLITE_API int sqlite3_get_autocommit(sqlite3*); + +/* +** CAPI3REF: Find The Database Handle Of A Prepared Statement +** +** ^The sqlite3_db_handle interface returns the [database connection] handle +** to which a [prepared statement] belongs. ^The [database connection] +** returned by sqlite3_db_handle is the same [database connection] +** that was the first argument +** to the [sqlite3_prepare_v2()] call (or its variants) that was used to +** create the statement in the first place. +*/ +SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*); + +/* +** CAPI3REF: Find the next prepared statement +** +** ^This interface returns a pointer to the next [prepared statement] after +** pStmt associated with the [database connection] pDb. ^If pStmt is NULL +** then this interface returns a pointer to the first prepared statement +** associated with the database connection pDb. ^If no prepared statement +** satisfies the conditions of this routine, it returns NULL. +** +** The [database connection] pointer D in a call to +** [sqlite3_next_stmt(D,S)] must refer to an open database +** connection and in particular must not be a NULL pointer. +*/ +SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Commit And Rollback Notification Callbacks +** +** ^The sqlite3_commit_hook() interface registers a callback +** function to be invoked whenever a transaction is [COMMIT | committed]. +** ^Any callback set by a previous call to sqlite3_commit_hook() +** for the same database connection is overridden. +** ^The sqlite3_rollback_hook() interface registers a callback +** function to be invoked whenever a transaction is [ROLLBACK | rolled back]. +** ^Any callback set by a previous call to sqlite3_rollback_hook() +** for the same database connection is overridden. +** ^The pArg argument is passed through to the callback. +** ^If the callback on a commit hook function returns non-zero, +** then the commit is converted into a rollback. +** +** ^The sqlite3_commit_hook(D,C,P) and sqlite3_rollback_hook(D,C,P) functions +** return the P argument from the previous call of the same function +** on the same [database connection] D, or NULL for +** the first call for each function on D. +** +** The callback implementation must not do anything that will modify +** the database connection that invoked the callback. Any actions +** to modify the database connection must be deferred until after the +** completion of the [sqlite3_step()] call that triggered the commit +** or rollback hook in the first place. +** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their +** database connections for the meaning of "modify" in this paragraph. +** +** ^Registering a NULL function disables the callback. +** +** ^When the commit hook callback routine returns zero, the [COMMIT] +** operation is allowed to continue normally. ^If the commit hook +** returns non-zero, then the [COMMIT] is converted into a [ROLLBACK]. +** ^The rollback hook is invoked on a rollback that results from a commit +** hook returning non-zero, just as it would be with any other rollback. +** +** ^For the purposes of this API, a transaction is said to have been +** rolled back if an explicit "ROLLBACK" statement is executed, or +** an error or constraint causes an implicit rollback to occur. +** ^The rollback callback is not invoked if a transaction is +** automatically rolled back because the database connection is closed. +** ^The rollback callback is not invoked if a transaction is +** rolled back because a commit callback returned non-zero. +** +** See also the [sqlite3_update_hook()] interface. +*/ +SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*); +SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); + +/* +** CAPI3REF: Data Change Notification Callbacks +** +** ^The sqlite3_update_hook() interface registers a callback function +** with the [database connection] identified by the first argument +** to be invoked whenever a row is updated, inserted or deleted. +** ^Any callback set by a previous call to this function +** for the same database connection is overridden. +** +** ^The second argument is a pointer to the function to invoke when a +** row is updated, inserted or deleted. +** ^The first argument to the callback is a copy of the third argument +** to sqlite3_update_hook(). +** ^The second callback argument is one of [SQLITE_INSERT], [SQLITE_DELETE], +** or [SQLITE_UPDATE], depending on the operation that caused the callback +** to be invoked. +** ^The third and fourth arguments to the callback contain pointers to the +** database and table name containing the affected row. +** ^The final callback parameter is the [rowid] of the row. +** ^In the case of an update, this is the [rowid] after the update takes place. +** +** ^(The update hook is not invoked when internal system tables are +** modified (i.e. sqlite_master and sqlite_sequence).)^ +** +** ^In the current implementation, the update hook +** is not invoked when duplication rows are deleted because of an +** [ON CONFLICT | ON CONFLICT REPLACE] clause. ^Nor is the update hook +** invoked when rows are deleted using the [truncate optimization]. +** The exceptions defined in this paragraph might change in a future +** release of SQLite. +** +** The update hook implementation must not do anything that will modify +** the database connection that invoked the update hook. Any actions +** to modify the database connection must be deferred until after the +** completion of the [sqlite3_step()] call that triggered the update hook. +** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their +** database connections for the meaning of "modify" in this paragraph. +** +** ^The sqlite3_update_hook(D,C,P) function +** returns the P argument from the previous call +** on the same [database connection] D, or NULL for +** the first call on D. +** +** See also the [sqlite3_commit_hook()] and [sqlite3_rollback_hook()] +** interfaces. +*/ +SQLITE_API void *sqlite3_update_hook( + sqlite3*, + void(*)(void *,int ,char const *,char const *,sqlite3_int64), + void* +); + +/* +** CAPI3REF: Enable Or Disable Shared Pager Cache +** KEYWORDS: {shared cache} +** +** ^(This routine enables or disables the sharing of the database cache +** and schema data structures between [database connection | connections] +** to the same database. Sharing is enabled if the argument is true +** and disabled if the argument is false.)^ +** +** ^Cache sharing is enabled and disabled for an entire process. +** This is a change as of SQLite version 3.5.0. In prior versions of SQLite, +** sharing was enabled or disabled for each thread separately. +** +** ^(The cache sharing mode set by this interface effects all subsequent +** calls to [sqlite3_open()], [sqlite3_open_v2()], and [sqlite3_open16()]. +** Existing database connections continue use the sharing mode +** that was in effect at the time they were opened.)^ +** +** ^(This routine returns [SQLITE_OK] if shared cache was enabled or disabled +** successfully. An [error code] is returned otherwise.)^ +** +** ^Shared cache is disabled by default. But this might change in +** future releases of SQLite. Applications that care about shared +** cache setting should set it explicitly. +** +** See Also: [SQLite Shared-Cache Mode] +*/ +SQLITE_API int sqlite3_enable_shared_cache(int); + +/* +** CAPI3REF: Attempt To Free Heap Memory +** +** ^The sqlite3_release_memory() interface attempts to free N bytes +** of heap memory by deallocating non-essential memory allocations +** held by the database library. Memory used to cache database +** pages to improve performance is an example of non-essential memory. +** ^sqlite3_release_memory() returns the number of bytes actually freed, +** which might be more or less than the amount requested. +*/ +SQLITE_API int sqlite3_release_memory(int); + +/* +** CAPI3REF: Impose A Limit On Heap Size +** +** ^The sqlite3_soft_heap_limit() interface places a "soft" limit +** on the amount of heap memory that may be allocated by SQLite. +** ^If an internal allocation is requested that would exceed the +** soft heap limit, [sqlite3_release_memory()] is invoked one or +** more times to free up some space before the allocation is performed. +** +** ^The limit is called "soft" because if [sqlite3_release_memory()] +** cannot free sufficient memory to prevent the limit from being exceeded, +** the memory is allocated anyway and the current operation proceeds. +** +** ^A negative or zero value for N means that there is no soft heap limit and +** [sqlite3_release_memory()] will only be called when memory is exhausted. +** ^The default value for the soft heap limit is zero. +** +** ^(SQLite makes a best effort to honor the soft heap limit. +** But if the soft heap limit cannot be honored, execution will +** continue without error or notification.)^ This is why the limit is +** called a "soft" limit. It is advisory only. +** +** Prior to SQLite version 3.5.0, this routine only constrained the memory +** allocated by a single thread - the same thread in which this routine +** runs. Beginning with SQLite version 3.5.0, the soft heap limit is +** applied to all threads. The value specified for the soft heap limit +** is an upper bound on the total memory allocation for all threads. In +** version 3.5.0 there is no mechanism for limiting the heap usage for +** individual threads. +*/ +SQLITE_API void sqlite3_soft_heap_limit(int); + +/* +** CAPI3REF: Extract Metadata About A Column Of A Table +** +** ^This routine returns metadata about a specific column of a specific +** database table accessible using the [database connection] handle +** passed as the first function argument. +** +** ^The column is identified by the second, third and fourth parameters to +** this function. ^The second parameter is either the name of the database +** (i.e. "main", "temp", or an attached database) containing the specified +** table or NULL. ^If it is NULL, then all attached databases are searched +** for the table using the same algorithm used by the database engine to +** resolve unqualified table references. +** +** ^The third and fourth parameters to this function are the table and column +** name of the desired column, respectively. Neither of these parameters +** may be NULL. +** +** ^Metadata is returned by writing to the memory locations passed as the 5th +** and subsequent parameters to this function. ^Any of these arguments may be +** NULL, in which case the corresponding element of metadata is omitted. +** +** ^(
+** +**
Parameter Output
Type
Description +** +**
5th const char* Data type +**
6th const char* Name of default collation sequence +**
7th int True if column has a NOT NULL constraint +**
8th int True if column is part of the PRIMARY KEY +**
9th int True if column is [AUTOINCREMENT] +**
+**
)^ +** +** ^The memory pointed to by the character pointers returned for the +** declaration type and collation sequence is valid only until the next +** call to any SQLite API function. +** +** ^If the specified table is actually a view, an [error code] is returned. +** +** ^If the specified column is "rowid", "oid" or "_rowid_" and an +** [INTEGER PRIMARY KEY] column has been explicitly declared, then the output +** parameters are set for the explicitly declared column. ^(If there is no +** explicitly declared [INTEGER PRIMARY KEY] column, then the output +** parameters are set as follows: +** +**
+**     data type: "INTEGER"
+**     collation sequence: "BINARY"
+**     not null: 0
+**     primary key: 1
+**     auto increment: 0
+** 
)^ +** +** ^(This function may load one or more schemas from database files. If an +** error occurs during this process, or if the requested table or column +** cannot be found, an [error code] is returned and an error message left +** in the [database connection] (to be retrieved using sqlite3_errmsg()).)^ +** +** ^This API is only available if the library was compiled with the +** [SQLITE_ENABLE_COLUMN_METADATA] C-preprocessor symbol defined. +*/ +SQLITE_API int sqlite3_table_column_metadata( + sqlite3 *db, /* Connection handle */ + const char *zDbName, /* Database name or NULL */ + const char *zTableName, /* Table name */ + const char *zColumnName, /* Column name */ + char const **pzDataType, /* OUTPUT: Declared data type */ + char const **pzCollSeq, /* OUTPUT: Collation sequence name */ + int *pNotNull, /* OUTPUT: True if NOT NULL constraint exists */ + int *pPrimaryKey, /* OUTPUT: True if column part of PK */ + int *pAutoinc /* OUTPUT: True if column is auto-increment */ +); + +/* +** CAPI3REF: Load An Extension +** +** ^This interface loads an SQLite extension library from the named file. +** +** ^The sqlite3_load_extension() interface attempts to load an +** SQLite extension library contained in the file zFile. +** +** ^The entry point is zProc. +** ^zProc may be 0, in which case the name of the entry point +** defaults to "sqlite3_extension_init". +** ^The sqlite3_load_extension() interface returns +** [SQLITE_OK] on success and [SQLITE_ERROR] if something goes wrong. +** ^If an error occurs and pzErrMsg is not 0, then the +** [sqlite3_load_extension()] interface shall attempt to +** fill *pzErrMsg with error message text stored in memory +** obtained from [sqlite3_malloc()]. The calling function +** should free this memory by calling [sqlite3_free()]. +** +** ^Extension loading must be enabled using +** [sqlite3_enable_load_extension()] prior to calling this API, +** otherwise an error will be returned. +** +** See also the [load_extension() SQL function]. +*/ +SQLITE_API int sqlite3_load_extension( + sqlite3 *db, /* Load the extension into this database connection */ + const char *zFile, /* Name of the shared library containing extension */ + const char *zProc, /* Entry point. Derived from zFile if 0 */ + char **pzErrMsg /* Put error message here if not 0 */ +); + +/* +** CAPI3REF: Enable Or Disable Extension Loading +** +** ^So as not to open security holes in older applications that are +** unprepared to deal with extension loading, and as a means of disabling +** extension loading while evaluating user-entered SQL, the following API +** is provided to turn the [sqlite3_load_extension()] mechanism on and off. +** +** ^Extension loading is off by default. See ticket #1863. +** ^Call the sqlite3_enable_load_extension() routine with onoff==1 +** to turn extension loading on and call it with onoff==0 to turn +** it back off again. +*/ +SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff); + +/* +** CAPI3REF: Automatically Load An Extensions +** +** ^This API can be invoked at program startup in order to register +** one or more statically linked extensions that will be available +** to all new [database connections]. +** +** ^(This routine stores a pointer to the extension entry point +** in an array that is obtained from [sqlite3_malloc()]. That memory +** is deallocated by [sqlite3_reset_auto_extension()].)^ +** +** ^This function registers an extension entry point that is +** automatically invoked whenever a new [database connection] +** is opened using [sqlite3_open()], [sqlite3_open16()], +** or [sqlite3_open_v2()]. +** ^Duplicate extensions are detected so calling this routine +** multiple times with the same extension is harmless. +** ^Automatic extensions apply across all threads. +*/ +SQLITE_API int sqlite3_auto_extension(void (*xEntryPoint)(void)); + +/* +** CAPI3REF: Reset Automatic Extension Loading +** +** ^(This function disables all previously registered automatic +** extensions. It undoes the effect of all prior +** [sqlite3_auto_extension()] calls.)^ +** +** ^This function disables automatic extensions in all threads. +*/ +SQLITE_API void sqlite3_reset_auto_extension(void); + +/* +****** EXPERIMENTAL - subject to change without notice ************** +** +** The interface to the virtual-table mechanism is currently considered +** to be experimental. The interface might change in incompatible ways. +** If this is a problem for you, do not use the interface at this time. +** +** When the virtual-table mechanism stabilizes, we will declare the +** interface fixed, support it indefinitely, and remove this comment. +*/ + +/* +** Structures used by the virtual table interface +*/ +typedef struct sqlite3_vtab sqlite3_vtab; +typedef struct sqlite3_index_info sqlite3_index_info; +typedef struct sqlite3_vtab_cursor sqlite3_vtab_cursor; +typedef struct sqlite3_module sqlite3_module; + +/* +** CAPI3REF: Virtual Table Object +** KEYWORDS: sqlite3_module {virtual table module} +** EXPERIMENTAL +** +** This structure, sometimes called a a "virtual table module", +** defines the implementation of a [virtual tables]. +** This structure consists mostly of methods for the module. +** +** ^A virtual table module is created by filling in a persistent +** instance of this structure and passing a pointer to that instance +** to [sqlite3_create_module()] or [sqlite3_create_module_v2()]. +** ^The registration remains valid until it is replaced by a different +** module or until the [database connection] closes. The content +** of this structure must not change while it is registered with +** any database connection. +*/ +struct sqlite3_module { + int iVersion; + int (*xCreate)(sqlite3*, void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVTab, char**); + int (*xConnect)(sqlite3*, void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVTab, char**); + int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*); + int (*xDisconnect)(sqlite3_vtab *pVTab); + int (*xDestroy)(sqlite3_vtab *pVTab); + int (*xOpen)(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor); + int (*xClose)(sqlite3_vtab_cursor*); + int (*xFilter)(sqlite3_vtab_cursor*, int idxNum, const char *idxStr, + int argc, sqlite3_value **argv); + int (*xNext)(sqlite3_vtab_cursor*); + int (*xEof)(sqlite3_vtab_cursor*); + int (*xColumn)(sqlite3_vtab_cursor*, sqlite3_context*, int); + int (*xRowid)(sqlite3_vtab_cursor*, sqlite3_int64 *pRowid); + int (*xUpdate)(sqlite3_vtab *, int, sqlite3_value **, sqlite3_int64 *); + int (*xBegin)(sqlite3_vtab *pVTab); + int (*xSync)(sqlite3_vtab *pVTab); + int (*xCommit)(sqlite3_vtab *pVTab); + int (*xRollback)(sqlite3_vtab *pVTab); + int (*xFindFunction)(sqlite3_vtab *pVtab, int nArg, const char *zName, + void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), + void **ppArg); + int (*xRename)(sqlite3_vtab *pVtab, const char *zNew); +}; + +/* +** CAPI3REF: Virtual Table Indexing Information +** KEYWORDS: sqlite3_index_info +** EXPERIMENTAL +** +** The sqlite3_index_info structure and its substructures is used to +** pass information into and receive the reply from the [xBestIndex] +** method of a [virtual table module]. The fields under **Inputs** are the +** inputs to xBestIndex and are read-only. xBestIndex inserts its +** results into the **Outputs** fields. +** +** ^(The aConstraint[] array records WHERE clause constraints of the form: +** +**
column OP expr
+** +** where OP is =, <, <=, >, or >=.)^ ^(The particular operator is +** stored in aConstraint[].op.)^ ^(The index of the column is stored in +** aConstraint[].iColumn.)^ ^(aConstraint[].usable is TRUE if the +** expr on the right-hand side can be evaluated (and thus the constraint +** is usable) and false if it cannot.)^ +** +** ^The optimizer automatically inverts terms of the form "expr OP column" +** and makes other simplifications to the WHERE clause in an attempt to +** get as many WHERE clause terms into the form shown above as possible. +** ^The aConstraint[] array only reports WHERE clause terms that are +** relevant to the particular virtual table being queried. +** +** ^Information about the ORDER BY clause is stored in aOrderBy[]. +** ^Each term of aOrderBy records a column of the ORDER BY clause. +** +** The [xBestIndex] method must fill aConstraintUsage[] with information +** about what parameters to pass to xFilter. ^If argvIndex>0 then +** the right-hand side of the corresponding aConstraint[] is evaluated +** and becomes the argvIndex-th entry in argv. ^(If aConstraintUsage[].omit +** is true, then the constraint is assumed to be fully handled by the +** virtual table and is not checked again by SQLite.)^ +** +** ^The idxNum and idxPtr values are recorded and passed into the +** [xFilter] method. +** ^[sqlite3_free()] is used to free idxPtr if and only if +** needToFreeIdxPtr is true. +** +** ^The orderByConsumed means that output from [xFilter]/[xNext] will occur in +** the correct order to satisfy the ORDER BY clause so that no separate +** sorting step is required. +** +** ^The estimatedCost value is an estimate of the cost of doing the +** particular lookup. A full scan of a table with N entries should have +** a cost of N. A binary search of a table of N entries should have a +** cost of approximately log(N). +*/ +struct sqlite3_index_info { + /* Inputs */ + int nConstraint; /* Number of entries in aConstraint */ + struct sqlite3_index_constraint { + int iColumn; /* Column on left-hand side of constraint */ + unsigned char op; /* Constraint operator */ + unsigned char usable; /* True if this constraint is usable */ + int iTermOffset; /* Used internally - xBestIndex should ignore */ + } *aConstraint; /* Table of WHERE clause constraints */ + int nOrderBy; /* Number of terms in the ORDER BY clause */ + struct sqlite3_index_orderby { + int iColumn; /* Column number */ + unsigned char desc; /* True for DESC. False for ASC. */ + } *aOrderBy; /* The ORDER BY clause */ + /* Outputs */ + struct sqlite3_index_constraint_usage { + int argvIndex; /* if >0, constraint is part of argv to xFilter */ + unsigned char omit; /* Do not code a test for this constraint */ + } *aConstraintUsage; + int idxNum; /* Number used to identify the index */ + char *idxStr; /* String, possibly obtained from sqlite3_malloc */ + int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if true */ + int orderByConsumed; /* True if output is already ordered */ + double estimatedCost; /* Estimated cost of using this index */ +}; +#define SQLITE_INDEX_CONSTRAINT_EQ 2 +#define SQLITE_INDEX_CONSTRAINT_GT 4 +#define SQLITE_INDEX_CONSTRAINT_LE 8 +#define SQLITE_INDEX_CONSTRAINT_LT 16 +#define SQLITE_INDEX_CONSTRAINT_GE 32 +#define SQLITE_INDEX_CONSTRAINT_MATCH 64 + +/* +** CAPI3REF: Register A Virtual Table Implementation +** EXPERIMENTAL +** +** ^These routines are used to register a new [virtual table module] name. +** ^Module names must be registered before +** creating a new [virtual table] using the module and before using a +** preexisting [virtual table] for the module. +** +** ^The module name is registered on the [database connection] specified +** by the first parameter. ^The name of the module is given by the +** second parameter. ^The third parameter is a pointer to +** the implementation of the [virtual table module]. ^The fourth +** parameter is an arbitrary client data pointer that is passed through +** into the [xCreate] and [xConnect] methods of the virtual table module +** when a new virtual table is be being created or reinitialized. +** +** ^The sqlite3_create_module_v2() interface has a fifth parameter which +** is a pointer to a destructor for the pClientData. ^SQLite will +** invoke the destructor function (if it is not NULL) when SQLite +** no longer needs the pClientData pointer. ^The sqlite3_create_module() +** interface is equivalent to sqlite3_create_module_v2() with a NULL +** destructor. +*/ +SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_create_module( + sqlite3 *db, /* SQLite connection to register module with */ + const char *zName, /* Name of the module */ + const sqlite3_module *p, /* Methods for the module */ + void *pClientData /* Client data for xCreate/xConnect */ +); +SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_create_module_v2( + sqlite3 *db, /* SQLite connection to register module with */ + const char *zName, /* Name of the module */ + const sqlite3_module *p, /* Methods for the module */ + void *pClientData, /* Client data for xCreate/xConnect */ + void(*xDestroy)(void*) /* Module destructor function */ +); + +/* +** CAPI3REF: Virtual Table Instance Object +** KEYWORDS: sqlite3_vtab +** EXPERIMENTAL +** +** Every [virtual table module] implementation uses a subclass +** of this object to describe a particular instance +** of the [virtual table]. Each subclass will +** be tailored to the specific needs of the module implementation. +** The purpose of this superclass is to define certain fields that are +** common to all module implementations. +** +** ^Virtual tables methods can set an error message by assigning a +** string obtained from [sqlite3_mprintf()] to zErrMsg. The method should +** take care that any prior string is freed by a call to [sqlite3_free()] +** prior to assigning a new string to zErrMsg. ^After the error message +** is delivered up to the client application, the string will be automatically +** freed by sqlite3_free() and the zErrMsg field will be zeroed. +*/ +struct sqlite3_vtab { + const sqlite3_module *pModule; /* The module for this virtual table */ + int nRef; /* NO LONGER USED */ + char *zErrMsg; /* Error message from sqlite3_mprintf() */ + /* Virtual table implementations will typically add additional fields */ +}; + +/* +** CAPI3REF: Virtual Table Cursor Object +** KEYWORDS: sqlite3_vtab_cursor {virtual table cursor} +** EXPERIMENTAL +** +** Every [virtual table module] implementation uses a subclass of the +** following structure to describe cursors that point into the +** [virtual table] and are used +** to loop through the virtual table. Cursors are created using the +** [sqlite3_module.xOpen | xOpen] method of the module and are destroyed +** by the [sqlite3_module.xClose | xClose] method. Cursors are used +** by the [xFilter], [xNext], [xEof], [xColumn], and [xRowid] methods +** of the module. Each module implementation will define +** the content of a cursor structure to suit its own needs. +** +** This superclass exists in order to define fields of the cursor that +** are common to all implementations. +*/ +struct sqlite3_vtab_cursor { + sqlite3_vtab *pVtab; /* Virtual table of this cursor */ + /* Virtual table implementations will typically add additional fields */ +}; + +/* +** CAPI3REF: Declare The Schema Of A Virtual Table +** EXPERIMENTAL +** +** ^The [xCreate] and [xConnect] methods of a +** [virtual table module] call this interface +** to declare the format (the names and datatypes of the columns) of +** the virtual tables they implement. +*/ +SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_declare_vtab(sqlite3*, const char *zSQL); + +/* +** CAPI3REF: Overload A Function For A Virtual Table +** EXPERIMENTAL +** +** ^(Virtual tables can provide alternative implementations of functions +** using the [xFindFunction] method of the [virtual table module]. +** But global versions of those functions +** must exist in order to be overloaded.)^ +** +** ^(This API makes sure a global version of a function with a particular +** name and number of parameters exists. If no such function exists +** before this API is called, a new function is created.)^ ^The implementation +** of the new function always causes an exception to be thrown. So +** the new function is not good for anything by itself. Its only +** purpose is to be a placeholder function that can be overloaded +** by a [virtual table]. +*/ +SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg); + +/* +** The interface to the virtual-table mechanism defined above (back up +** to a comment remarkably similar to this one) is currently considered +** to be experimental. The interface might change in incompatible ways. +** If this is a problem for you, do not use the interface at this time. +** +** When the virtual-table mechanism stabilizes, we will declare the +** interface fixed, support it indefinitely, and remove this comment. +** +****** EXPERIMENTAL - subject to change without notice ************** +*/ + +/* +** CAPI3REF: A Handle To An Open BLOB +** KEYWORDS: {BLOB handle} {BLOB handles} +** +** An instance of this object represents an open BLOB on which +** [sqlite3_blob_open | incremental BLOB I/O] can be performed. +** ^Objects of this type are created by [sqlite3_blob_open()] +** and destroyed by [sqlite3_blob_close()]. +** ^The [sqlite3_blob_read()] and [sqlite3_blob_write()] interfaces +** can be used to read or write small subsections of the BLOB. +** ^The [sqlite3_blob_bytes()] interface returns the size of the BLOB in bytes. +*/ +typedef struct sqlite3_blob sqlite3_blob; + +/* +** CAPI3REF: Open A BLOB For Incremental I/O +** +** ^(This interfaces opens a [BLOB handle | handle] to the BLOB located +** in row iRow, column zColumn, table zTable in database zDb; +** in other words, the same BLOB that would be selected by: +** +**
+**     SELECT zColumn FROM zDb.zTable WHERE [rowid] = iRow;
+** 
)^ +** +** ^If the flags parameter is non-zero, then the BLOB is opened for read +** and write access. ^If it is zero, the BLOB is opened for read access. +** ^It is not possible to open a column that is part of an index or primary +** key for writing. ^If [foreign key constraints] are enabled, it is +** not possible to open a column that is part of a [child key] for writing. +** +** ^Note that the database name is not the filename that contains +** the database but rather the symbolic name of the database that +** appears after the AS keyword when the database is connected using [ATTACH]. +** ^For the main database file, the database name is "main". +** ^For TEMP tables, the database name is "temp". +** +** ^(On success, [SQLITE_OK] is returned and the new [BLOB handle] is written +** to *ppBlob. Otherwise an [error code] is returned and *ppBlob is set +** to be a null pointer.)^ +** ^This function sets the [database connection] error code and message +** accessible via [sqlite3_errcode()] and [sqlite3_errmsg()] and related +** functions. ^Note that the *ppBlob variable is always initialized in a +** way that makes it safe to invoke [sqlite3_blob_close()] on *ppBlob +** regardless of the success or failure of this routine. +** +** ^(If the row that a BLOB handle points to is modified by an +** [UPDATE], [DELETE], or by [ON CONFLICT] side-effects +** then the BLOB handle is marked as "expired". +** This is true if any column of the row is changed, even a column +** other than the one the BLOB handle is open on.)^ +** ^Calls to [sqlite3_blob_read()] and [sqlite3_blob_write()] for +** a expired BLOB handle fail with an return code of [SQLITE_ABORT]. +** ^(Changes written into a BLOB prior to the BLOB expiring are not +** rolled back by the expiration of the BLOB. Such changes will eventually +** commit if the transaction continues to completion.)^ +** +** ^Use the [sqlite3_blob_bytes()] interface to determine the size of +** the opened blob. ^The size of a blob may not be changed by this +** interface. Use the [UPDATE] SQL command to change the size of a +** blob. +** +** ^The [sqlite3_bind_zeroblob()] and [sqlite3_result_zeroblob()] interfaces +** and the built-in [zeroblob] SQL function can be used, if desired, +** to create an empty, zero-filled blob in which to read or write using +** this interface. +** +** To avoid a resource leak, every open [BLOB handle] should eventually +** be released by a call to [sqlite3_blob_close()]. +*/ +SQLITE_API int sqlite3_blob_open( + sqlite3*, + const char *zDb, + const char *zTable, + const char *zColumn, + sqlite3_int64 iRow, + int flags, + sqlite3_blob **ppBlob +); + +/* +** CAPI3REF: Close A BLOB Handle +** +** ^Closes an open [BLOB handle]. +** +** ^Closing a BLOB shall cause the current transaction to commit +** if there are no other BLOBs, no pending prepared statements, and the +** database connection is in [autocommit mode]. +** ^If any writes were made to the BLOB, they might be held in cache +** until the close operation if they will fit. +** +** ^(Closing the BLOB often forces the changes +** out to disk and so if any I/O errors occur, they will likely occur +** at the time when the BLOB is closed. Any errors that occur during +** closing are reported as a non-zero return value.)^ +** +** ^(The BLOB is closed unconditionally. Even if this routine returns +** an error code, the BLOB is still closed.)^ +** +** ^Calling this routine with a null pointer (such as would be returned +** by a failed call to [sqlite3_blob_open()]) is a harmless no-op. +*/ +SQLITE_API int sqlite3_blob_close(sqlite3_blob *); + +/* +** CAPI3REF: Return The Size Of An Open BLOB +** +** ^Returns the size in bytes of the BLOB accessible via the +** successfully opened [BLOB handle] in its only argument. ^The +** incremental blob I/O routines can only read or overwriting existing +** blob content; they cannot change the size of a blob. +** +** This routine only works on a [BLOB handle] which has been created +** by a prior successful call to [sqlite3_blob_open()] and which has not +** been closed by [sqlite3_blob_close()]. Passing any other pointer in +** to this routine results in undefined and probably undesirable behavior. +*/ +SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *); + +/* +** CAPI3REF: Read Data From A BLOB Incrementally +** +** ^(This function is used to read data from an open [BLOB handle] into a +** caller-supplied buffer. N bytes of data are copied into buffer Z +** from the open BLOB, starting at offset iOffset.)^ +** +** ^If offset iOffset is less than N bytes from the end of the BLOB, +** [SQLITE_ERROR] is returned and no data is read. ^If N or iOffset is +** less than zero, [SQLITE_ERROR] is returned and no data is read. +** ^The size of the blob (and hence the maximum value of N+iOffset) +** can be determined using the [sqlite3_blob_bytes()] interface. +** +** ^An attempt to read from an expired [BLOB handle] fails with an +** error code of [SQLITE_ABORT]. +** +** ^(On success, sqlite3_blob_read() returns SQLITE_OK. +** Otherwise, an [error code] or an [extended error code] is returned.)^ +** +** This routine only works on a [BLOB handle] which has been created +** by a prior successful call to [sqlite3_blob_open()] and which has not +** been closed by [sqlite3_blob_close()]. Passing any other pointer in +** to this routine results in undefined and probably undesirable behavior. +** +** See also: [sqlite3_blob_write()]. +*/ +SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset); + +/* +** CAPI3REF: Write Data Into A BLOB Incrementally +** +** ^This function is used to write data into an open [BLOB handle] from a +** caller-supplied buffer. ^N bytes of data are copied from the buffer Z +** into the open BLOB, starting at offset iOffset. +** +** ^If the [BLOB handle] passed as the first argument was not opened for +** writing (the flags parameter to [sqlite3_blob_open()] was zero), +** this function returns [SQLITE_READONLY]. +** +** ^This function may only modify the contents of the BLOB; it is +** not possible to increase the size of a BLOB using this API. +** ^If offset iOffset is less than N bytes from the end of the BLOB, +** [SQLITE_ERROR] is returned and no data is written. ^If N is +** less than zero [SQLITE_ERROR] is returned and no data is written. +** The size of the BLOB (and hence the maximum value of N+iOffset) +** can be determined using the [sqlite3_blob_bytes()] interface. +** +** ^An attempt to write to an expired [BLOB handle] fails with an +** error code of [SQLITE_ABORT]. ^Writes to the BLOB that occurred +** before the [BLOB handle] expired are not rolled back by the +** expiration of the handle, though of course those changes might +** have been overwritten by the statement that expired the BLOB handle +** or by other independent statements. +** +** ^(On success, sqlite3_blob_write() returns SQLITE_OK. +** Otherwise, an [error code] or an [extended error code] is returned.)^ +** +** This routine only works on a [BLOB handle] which has been created +** by a prior successful call to [sqlite3_blob_open()] and which has not +** been closed by [sqlite3_blob_close()]. Passing any other pointer in +** to this routine results in undefined and probably undesirable behavior. +** +** See also: [sqlite3_blob_read()]. +*/ +SQLITE_API int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset); + +/* +** CAPI3REF: Virtual File System Objects +** +** A virtual filesystem (VFS) is an [sqlite3_vfs] object +** that SQLite uses to interact +** with the underlying operating system. Most SQLite builds come with a +** single default VFS that is appropriate for the host computer. +** New VFSes can be registered and existing VFSes can be unregistered. +** The following interfaces are provided. +** +** ^The sqlite3_vfs_find() interface returns a pointer to a VFS given its name. +** ^Names are case sensitive. +** ^Names are zero-terminated UTF-8 strings. +** ^If there is no match, a NULL pointer is returned. +** ^If zVfsName is NULL then the default VFS is returned. +** +** ^New VFSes are registered with sqlite3_vfs_register(). +** ^Each new VFS becomes the default VFS if the makeDflt flag is set. +** ^The same VFS can be registered multiple times without injury. +** ^To make an existing VFS into the default VFS, register it again +** with the makeDflt flag set. If two different VFSes with the +** same name are registered, the behavior is undefined. If a +** VFS is registered with a name that is NULL or an empty string, +** then the behavior is undefined. +** +** ^Unregister a VFS with the sqlite3_vfs_unregister() interface. +** ^(If the default VFS is unregistered, another VFS is chosen as +** the default. The choice for the new VFS is arbitrary.)^ +*/ +SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *zVfsName); +SQLITE_API int sqlite3_vfs_register(sqlite3_vfs*, int makeDflt); +SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*); + +/* +** CAPI3REF: Mutexes +** +** The SQLite core uses these routines for thread +** synchronization. Though they are intended for internal +** use by SQLite, code that links against SQLite is +** permitted to use any of these routines. +** +** The SQLite source code contains multiple implementations +** of these mutex routines. An appropriate implementation +** is selected automatically at compile-time. ^(The following +** implementations are available in the SQLite core: +** +**
    +**
  • SQLITE_MUTEX_OS2 +**
  • SQLITE_MUTEX_PTHREAD +**
  • SQLITE_MUTEX_W32 +**
  • SQLITE_MUTEX_NOOP +**
)^ +** +** ^The SQLITE_MUTEX_NOOP implementation is a set of routines +** that does no real locking and is appropriate for use in +** a single-threaded application. ^The SQLITE_MUTEX_OS2, +** SQLITE_MUTEX_PTHREAD, and SQLITE_MUTEX_W32 implementations +** are appropriate for use on OS/2, Unix, and Windows. +** +** ^(If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor +** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex +** implementation is included with the library. In this case the +** application must supply a custom mutex implementation using the +** [SQLITE_CONFIG_MUTEX] option of the sqlite3_config() function +** before calling sqlite3_initialize() or any other public sqlite3_ +** function that calls sqlite3_initialize().)^ +** +** ^The sqlite3_mutex_alloc() routine allocates a new +** mutex and returns a pointer to it. ^If it returns NULL +** that means that a mutex could not be allocated. ^SQLite +** will unwind its stack and return an error. ^(The argument +** to sqlite3_mutex_alloc() is one of these integer constants: +** +**
    +**
  • SQLITE_MUTEX_FAST +**
  • SQLITE_MUTEX_RECURSIVE +**
  • SQLITE_MUTEX_STATIC_MASTER +**
  • SQLITE_MUTEX_STATIC_MEM +**
  • SQLITE_MUTEX_STATIC_MEM2 +**
  • SQLITE_MUTEX_STATIC_PRNG +**
  • SQLITE_MUTEX_STATIC_LRU +**
  • SQLITE_MUTEX_STATIC_LRU2 +**
)^ +** +** ^The first two constants (SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE) +** cause sqlite3_mutex_alloc() to create +** a new mutex. ^The new mutex is recursive when SQLITE_MUTEX_RECURSIVE +** is used but not necessarily so when SQLITE_MUTEX_FAST is used. +** The mutex implementation does not need to make a distinction +** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does +** not want to. ^SQLite will only request a recursive mutex in +** cases where it really needs one. ^If a faster non-recursive mutex +** implementation is available on the host platform, the mutex subsystem +** might return such a mutex in response to SQLITE_MUTEX_FAST. +** +** ^The other allowed parameters to sqlite3_mutex_alloc() (anything other +** than SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE) each return +** a pointer to a static preexisting mutex. ^Six static mutexes are +** used by the current version of SQLite. Future versions of SQLite +** may add additional static mutexes. Static mutexes are for internal +** use by SQLite only. Applications that use SQLite mutexes should +** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or +** SQLITE_MUTEX_RECURSIVE. +** +** ^Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST +** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() +** returns a different mutex on every call. ^But for the static +** mutex types, the same mutex is returned on every call that has +** the same type number. +** +** ^The sqlite3_mutex_free() routine deallocates a previously +** allocated dynamic mutex. ^SQLite is careful to deallocate every +** dynamic mutex that it allocates. The dynamic mutexes must not be in +** use when they are deallocated. Attempting to deallocate a static +** mutex results in undefined behavior. ^SQLite never deallocates +** a static mutex. +** +** ^The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt +** to enter a mutex. ^If another thread is already within the mutex, +** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return +** SQLITE_BUSY. ^The sqlite3_mutex_try() interface returns [SQLITE_OK] +** upon successful entry. ^(Mutexes created using +** SQLITE_MUTEX_RECURSIVE can be entered multiple times by the same thread. +** In such cases the, +** mutex must be exited an equal number of times before another thread +** can enter.)^ ^(If the same thread tries to enter any other +** kind of mutex more than once, the behavior is undefined. +** SQLite will never exhibit +** such behavior in its own use of mutexes.)^ +** +** ^(Some systems (for example, Windows 95) do not support the operation +** implemented by sqlite3_mutex_try(). On those systems, sqlite3_mutex_try() +** will always return SQLITE_BUSY. The SQLite core only ever uses +** sqlite3_mutex_try() as an optimization so this is acceptable behavior.)^ +** +** ^The sqlite3_mutex_leave() routine exits a mutex that was +** previously entered by the same thread. ^(The behavior +** is undefined if the mutex is not currently entered by the +** calling thread or is not currently allocated. SQLite will +** never do either.)^ +** +** ^If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), or +** sqlite3_mutex_leave() is a NULL pointer, then all three routines +** behave as no-ops. +** +** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()]. +*/ +SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int); +SQLITE_API void sqlite3_mutex_free(sqlite3_mutex*); +SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex*); +SQLITE_API int sqlite3_mutex_try(sqlite3_mutex*); +SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*); + +/* +** CAPI3REF: Mutex Methods Object +** EXPERIMENTAL +** +** An instance of this structure defines the low-level routines +** used to allocate and use mutexes. +** +** Usually, the default mutex implementations provided by SQLite are +** sufficient, however the user has the option of substituting a custom +** implementation for specialized deployments or systems for which SQLite +** does not provide a suitable implementation. In this case, the user +** creates and populates an instance of this structure to pass +** to sqlite3_config() along with the [SQLITE_CONFIG_MUTEX] option. +** Additionally, an instance of this structure can be used as an +** output variable when querying the system for the current mutex +** implementation, using the [SQLITE_CONFIG_GETMUTEX] option. +** +** ^The xMutexInit method defined by this structure is invoked as +** part of system initialization by the sqlite3_initialize() function. +** ^The xMutexInit routine is calle by SQLite exactly once for each +** effective call to [sqlite3_initialize()]. +** +** ^The xMutexEnd method defined by this structure is invoked as +** part of system shutdown by the sqlite3_shutdown() function. The +** implementation of this method is expected to release all outstanding +** resources obtained by the mutex methods implementation, especially +** those obtained by the xMutexInit method. ^The xMutexEnd() +** interface is invoked exactly once for each call to [sqlite3_shutdown()]. +** +** ^(The remaining seven methods defined by this structure (xMutexAlloc, +** xMutexFree, xMutexEnter, xMutexTry, xMutexLeave, xMutexHeld and +** xMutexNotheld) implement the following interfaces (respectively): +** +**
    +**
  • [sqlite3_mutex_alloc()]
  • +**
  • [sqlite3_mutex_free()]
  • +**
  • [sqlite3_mutex_enter()]
  • +**
  • [sqlite3_mutex_try()]
  • +**
  • [sqlite3_mutex_leave()]
  • +**
  • [sqlite3_mutex_held()]
  • +**
  • [sqlite3_mutex_notheld()]
  • +**
)^ +** +** The only difference is that the public sqlite3_XXX functions enumerated +** above silently ignore any invocations that pass a NULL pointer instead +** of a valid mutex handle. The implementations of the methods defined +** by this structure are not required to handle this case, the results +** of passing a NULL pointer instead of a valid mutex handle are undefined +** (i.e. it is acceptable to provide an implementation that segfaults if +** it is passed a NULL pointer). +** +** The xMutexInit() method must be threadsafe. ^It must be harmless to +** invoke xMutexInit() mutiple times within the same process and without +** intervening calls to xMutexEnd(). Second and subsequent calls to +** xMutexInit() must be no-ops. +** +** ^xMutexInit() must not use SQLite memory allocation ([sqlite3_malloc()] +** and its associates). ^Similarly, xMutexAlloc() must not use SQLite memory +** allocation for a static mutex. ^However xMutexAlloc() may use SQLite +** memory allocation for a fast or recursive mutex. +** +** ^SQLite will invoke the xMutexEnd() method when [sqlite3_shutdown()] is +** called, but only if the prior call to xMutexInit returned SQLITE_OK. +** If xMutexInit fails in any way, it is expected to clean up after itself +** prior to returning. +*/ +typedef struct sqlite3_mutex_methods sqlite3_mutex_methods; +struct sqlite3_mutex_methods { + int (*xMutexInit)(void); + int (*xMutexEnd)(void); + sqlite3_mutex *(*xMutexAlloc)(int); + void (*xMutexFree)(sqlite3_mutex *); + void (*xMutexEnter)(sqlite3_mutex *); + int (*xMutexTry)(sqlite3_mutex *); + void (*xMutexLeave)(sqlite3_mutex *); + int (*xMutexHeld)(sqlite3_mutex *); + int (*xMutexNotheld)(sqlite3_mutex *); +}; + +/* +** CAPI3REF: Mutex Verification Routines +** +** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routines +** are intended for use inside assert() statements. ^The SQLite core +** never uses these routines except inside an assert() and applications +** are advised to follow the lead of the core. ^The SQLite core only +** provides implementations for these routines when it is compiled +** with the SQLITE_DEBUG flag. ^External mutex implementations +** are only required to provide these routines if SQLITE_DEBUG is +** defined and if NDEBUG is not defined. +** +** ^These routines should return true if the mutex in their argument +** is held or not held, respectively, by the calling thread. +** +** ^The implementation is not required to provided versions of these +** routines that actually work. If the implementation does not provide working +** versions of these routines, it should at least provide stubs that always +** return true so that one does not get spurious assertion failures. +** +** ^If the argument to sqlite3_mutex_held() is a NULL pointer then +** the routine should return 1. This seems counter-intuitive since +** clearly the mutex cannot be held if it does not exist. But the +** the reason the mutex does not exist is because the build is not +** using mutexes. And we do not want the assert() containing the +** call to sqlite3_mutex_held() to fail, so a non-zero return is +** the appropriate thing to do. ^The sqlite3_mutex_notheld() +** interface should also return 1 when given a NULL pointer. +*/ +#ifndef NDEBUG +SQLITE_API int sqlite3_mutex_held(sqlite3_mutex*); +SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*); +#endif + +/* +** CAPI3REF: Mutex Types +** +** The [sqlite3_mutex_alloc()] interface takes a single argument +** which is one of these integer constants. +** +** The set of static mutexes may change from one SQLite release to the +** next. Applications that override the built-in mutex logic must be +** prepared to accommodate additional static mutexes. +*/ +#define SQLITE_MUTEX_FAST 0 +#define SQLITE_MUTEX_RECURSIVE 1 +#define SQLITE_MUTEX_STATIC_MASTER 2 +#define SQLITE_MUTEX_STATIC_MEM 3 /* sqlite3_malloc() */ +#define SQLITE_MUTEX_STATIC_MEM2 4 /* NOT USED */ +#define SQLITE_MUTEX_STATIC_OPEN 4 /* sqlite3BtreeOpen() */ +#define SQLITE_MUTEX_STATIC_PRNG 5 /* sqlite3_random() */ +#define SQLITE_MUTEX_STATIC_LRU 6 /* lru page list */ +#define SQLITE_MUTEX_STATIC_LRU2 7 /* lru page list */ + +/* +** CAPI3REF: Retrieve the mutex for a database connection +** +** ^This interface returns a pointer the [sqlite3_mutex] object that +** serializes access to the [database connection] given in the argument +** when the [threading mode] is Serialized. +** ^If the [threading mode] is Single-thread or Multi-thread then this +** routine returns a NULL pointer. +*/ +SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*); + +/* +** CAPI3REF: Low-Level Control Of Database Files +** +** ^The [sqlite3_file_control()] interface makes a direct call to the +** xFileControl method for the [sqlite3_io_methods] object associated +** with a particular database identified by the second argument. ^The +** name of the database "main" for the main database or "temp" for the +** TEMP database, or the name that appears after the AS keyword for +** databases that are added using the [ATTACH] SQL command. +** ^A NULL pointer can be used in place of "main" to refer to the +** main database file. +** ^The third and fourth parameters to this routine +** are passed directly through to the second and third parameters of +** the xFileControl method. ^The return value of the xFileControl +** method becomes the return value of this routine. +** +** ^If the second parameter (zDbName) does not match the name of any +** open database file, then SQLITE_ERROR is returned. ^This error +** code is not remembered and will not be recalled by [sqlite3_errcode()] +** or [sqlite3_errmsg()]. The underlying xFileControl method might +** also return SQLITE_ERROR. There is no way to distinguish between +** an incorrect zDbName and an SQLITE_ERROR return from the underlying +** xFileControl method. +** +** See also: [SQLITE_FCNTL_LOCKSTATE] +*/ +SQLITE_API int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*); + +/* +** CAPI3REF: Testing Interface +** +** ^The sqlite3_test_control() interface is used to read out internal +** state of SQLite and to inject faults into SQLite for testing +** purposes. ^The first parameter is an operation code that determines +** the number, meaning, and operation of all subsequent parameters. +** +** This interface is not for use by applications. It exists solely +** for verifying the correct operation of the SQLite library. Depending +** on how the SQLite library is compiled, this interface might not exist. +** +** The details of the operation codes, their meanings, the parameters +** they take, and what they do are all subject to change without notice. +** Unlike most of the SQLite API, this function is not guaranteed to +** operate consistently from one release to the next. +*/ +SQLITE_API int sqlite3_test_control(int op, ...); + +/* +** CAPI3REF: Testing Interface Operation Codes +** +** These constants are the valid operation code parameters used +** as the first argument to [sqlite3_test_control()]. +** +** These parameters and their meanings are subject to change +** without notice. These values are for testing purposes only. +** Applications should not use any of these parameters or the +** [sqlite3_test_control()] interface. +*/ +#define SQLITE_TESTCTRL_FIRST 5 +#define SQLITE_TESTCTRL_PRNG_SAVE 5 +#define SQLITE_TESTCTRL_PRNG_RESTORE 6 +#define SQLITE_TESTCTRL_PRNG_RESET 7 +#define SQLITE_TESTCTRL_BITVEC_TEST 8 +#define SQLITE_TESTCTRL_FAULT_INSTALL 9 +#define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS 10 +#define SQLITE_TESTCTRL_PENDING_BYTE 11 +#define SQLITE_TESTCTRL_ASSERT 12 +#define SQLITE_TESTCTRL_ALWAYS 13 +#define SQLITE_TESTCTRL_RESERVE 14 +#define SQLITE_TESTCTRL_OPTIMIZATIONS 15 +#define SQLITE_TESTCTRL_ISKEYWORD 16 +#define SQLITE_TESTCTRL_LAST 16 + +/* +** CAPI3REF: SQLite Runtime Status +** EXPERIMENTAL +** +** ^This interface is used to retrieve runtime status information +** about the preformance of SQLite, and optionally to reset various +** highwater marks. ^The first argument is an integer code for +** the specific parameter to measure. ^(Recognized integer codes +** are of the form [SQLITE_STATUS_MEMORY_USED | SQLITE_STATUS_...].)^ +** ^The current value of the parameter is returned into *pCurrent. +** ^The highest recorded value is returned in *pHighwater. ^If the +** resetFlag is true, then the highest record value is reset after +** *pHighwater is written. ^(Some parameters do not record the highest +** value. For those parameters +** nothing is written into *pHighwater and the resetFlag is ignored.)^ +** ^(Other parameters record only the highwater mark and not the current +** value. For these latter parameters nothing is written into *pCurrent.)^ +** +** ^The sqlite3_db_status() routine returns SQLITE_OK on success and a +** non-zero [error code] on failure. +** +** This routine is threadsafe but is not atomic. This routine can be +** called while other threads are running the same or different SQLite +** interfaces. However the values returned in *pCurrent and +** *pHighwater reflect the status of SQLite at different points in time +** and it is possible that another thread might change the parameter +** in between the times when *pCurrent and *pHighwater are written. +** +** See also: [sqlite3_db_status()] +*/ +SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag); + + +/* +** CAPI3REF: Status Parameters +** EXPERIMENTAL +** +** These integer constants designate various run-time status parameters +** that can be returned by [sqlite3_status()]. +** +**
+** ^(
SQLITE_STATUS_MEMORY_USED
+**
This parameter is the current amount of memory checked out +** using [sqlite3_malloc()], either directly or indirectly. The +** figure includes calls made to [sqlite3_malloc()] by the application +** and internal memory usage by the SQLite library. Scratch memory +** controlled by [SQLITE_CONFIG_SCRATCH] and auxiliary page-cache +** memory controlled by [SQLITE_CONFIG_PAGECACHE] is not included in +** this parameter. The amount returned is the sum of the allocation +** sizes as reported by the xSize method in [sqlite3_mem_methods].
)^ +** +** ^(
SQLITE_STATUS_MALLOC_SIZE
+**
This parameter records the largest memory allocation request +** handed to [sqlite3_malloc()] or [sqlite3_realloc()] (or their +** internal equivalents). Only the value returned in the +** *pHighwater parameter to [sqlite3_status()] is of interest. +** The value written into the *pCurrent parameter is undefined.
)^ +** +** ^(
SQLITE_STATUS_PAGECACHE_USED
+**
This parameter returns the number of pages used out of the +** [pagecache memory allocator] that was configured using +** [SQLITE_CONFIG_PAGECACHE]. The +** value returned is in pages, not in bytes.
)^ +** +** ^(
SQLITE_STATUS_PAGECACHE_OVERFLOW
+**
This parameter returns the number of bytes of page cache +** allocation which could not be statisfied by the [SQLITE_CONFIG_PAGECACHE] +** buffer and where forced to overflow to [sqlite3_malloc()]. The +** returned value includes allocations that overflowed because they +** where too large (they were larger than the "sz" parameter to +** [SQLITE_CONFIG_PAGECACHE]) and allocations that overflowed because +** no space was left in the page cache.
)^ +** +** ^(
SQLITE_STATUS_PAGECACHE_SIZE
+**
This parameter records the largest memory allocation request +** handed to [pagecache memory allocator]. Only the value returned in the +** *pHighwater parameter to [sqlite3_status()] is of interest. +** The value written into the *pCurrent parameter is undefined.
)^ +** +** ^(
SQLITE_STATUS_SCRATCH_USED
+**
This parameter returns the number of allocations used out of the +** [scratch memory allocator] configured using +** [SQLITE_CONFIG_SCRATCH]. The value returned is in allocations, not +** in bytes. Since a single thread may only have one scratch allocation +** outstanding at time, this parameter also reports the number of threads +** using scratch memory at the same time.
)^ +** +** ^(
SQLITE_STATUS_SCRATCH_OVERFLOW
+**
This parameter returns the number of bytes of scratch memory +** allocation which could not be statisfied by the [SQLITE_CONFIG_SCRATCH] +** buffer and where forced to overflow to [sqlite3_malloc()]. The values +** returned include overflows because the requested allocation was too +** larger (that is, because the requested allocation was larger than the +** "sz" parameter to [SQLITE_CONFIG_SCRATCH]) and because no scratch buffer +** slots were available. +**
)^ +** +** ^(
SQLITE_STATUS_SCRATCH_SIZE
+**
This parameter records the largest memory allocation request +** handed to [scratch memory allocator]. Only the value returned in the +** *pHighwater parameter to [sqlite3_status()] is of interest. +** The value written into the *pCurrent parameter is undefined.
)^ +** +** ^(
SQLITE_STATUS_PARSER_STACK
+**
This parameter records the deepest parser stack. It is only +** meaningful if SQLite is compiled with [YYTRACKMAXSTACKDEPTH].
)^ +**
+** +** New status parameters may be added from time to time. +*/ +#define SQLITE_STATUS_MEMORY_USED 0 +#define SQLITE_STATUS_PAGECACHE_USED 1 +#define SQLITE_STATUS_PAGECACHE_OVERFLOW 2 +#define SQLITE_STATUS_SCRATCH_USED 3 +#define SQLITE_STATUS_SCRATCH_OVERFLOW 4 +#define SQLITE_STATUS_MALLOC_SIZE 5 +#define SQLITE_STATUS_PARSER_STACK 6 +#define SQLITE_STATUS_PAGECACHE_SIZE 7 +#define SQLITE_STATUS_SCRATCH_SIZE 8 + +/* +** CAPI3REF: Database Connection Status +** EXPERIMENTAL +** +** ^This interface is used to retrieve runtime status information +** about a single [database connection]. ^The first argument is the +** database connection object to be interrogated. ^The second argument +** is the parameter to interrogate. ^Currently, the only allowed value +** for the second parameter is [SQLITE_DBSTATUS_LOOKASIDE_USED]. +** Additional options will likely appear in future releases of SQLite. +** +** ^The current value of the requested parameter is written into *pCur +** and the highest instantaneous value is written into *pHiwtr. ^If +** the resetFlg is true, then the highest instantaneous value is +** reset back down to the current value. +** +** See also: [sqlite3_status()] and [sqlite3_stmt_status()]. +*/ +SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg); + +/* +** CAPI3REF: Status Parameters for database connections +** EXPERIMENTAL +** +** These constants are the available integer "verbs" that can be passed as +** the second argument to the [sqlite3_db_status()] interface. +** +** New verbs may be added in future releases of SQLite. Existing verbs +** might be discontinued. Applications should check the return code from +** [sqlite3_db_status()] to make sure that the call worked. +** The [sqlite3_db_status()] interface will return a non-zero error code +** if a discontinued or unsupported verb is invoked. +** +**
+** ^(
SQLITE_DBSTATUS_LOOKASIDE_USED
+**
This parameter returns the number of lookaside memory slots currently +** checked out.
)^ +**
+*/ +#define SQLITE_DBSTATUS_LOOKASIDE_USED 0 + + +/* +** CAPI3REF: Prepared Statement Status +** EXPERIMENTAL +** +** ^(Each prepared statement maintains various +** [SQLITE_STMTSTATUS_SORT | counters] that measure the number +** of times it has performed specific operations.)^ These counters can +** be used to monitor the performance characteristics of the prepared +** statements. For example, if the number of table steps greatly exceeds +** the number of table searches or result rows, that would tend to indicate +** that the prepared statement is using a full table scan rather than +** an index. +** +** ^(This interface is used to retrieve and reset counter values from +** a [prepared statement]. The first argument is the prepared statement +** object to be interrogated. The second argument +** is an integer code for a specific [SQLITE_STMTSTATUS_SORT | counter] +** to be interrogated.)^ +** ^The current value of the requested counter is returned. +** ^If the resetFlg is true, then the counter is reset to zero after this +** interface call returns. +** +** See also: [sqlite3_status()] and [sqlite3_db_status()]. +*/ +SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); + +/* +** CAPI3REF: Status Parameters for prepared statements +** EXPERIMENTAL +** +** These preprocessor macros define integer codes that name counter +** values associated with the [sqlite3_stmt_status()] interface. +** The meanings of the various counters are as follows: +** +**
+**
SQLITE_STMTSTATUS_FULLSCAN_STEP
+**
^This is the number of times that SQLite has stepped forward in +** a table as part of a full table scan. Large numbers for this counter +** may indicate opportunities for performance improvement through +** careful use of indices.
+** +**
SQLITE_STMTSTATUS_SORT
+**
^This is the number of sort operations that have occurred. +** A non-zero value in this counter may indicate an opportunity to +** improvement performance through careful use of indices.
+** +**
+*/ +#define SQLITE_STMTSTATUS_FULLSCAN_STEP 1 +#define SQLITE_STMTSTATUS_SORT 2 + +/* +** CAPI3REF: Custom Page Cache Object +** EXPERIMENTAL +** +** The sqlite3_pcache type is opaque. It is implemented by +** the pluggable module. The SQLite core has no knowledge of +** its size or internal structure and never deals with the +** sqlite3_pcache object except by holding and passing pointers +** to the object. +** +** See [sqlite3_pcache_methods] for additional information. +*/ +typedef struct sqlite3_pcache sqlite3_pcache; + +/* +** CAPI3REF: Application Defined Page Cache. +** KEYWORDS: {page cache} +** EXPERIMENTAL +** +** ^(The [sqlite3_config]([SQLITE_CONFIG_PCACHE], ...) interface can +** register an alternative page cache implementation by passing in an +** instance of the sqlite3_pcache_methods structure.)^ The majority of the +** heap memory used by SQLite is used by the page cache to cache data read +** from, or ready to be written to, the database file. By implementing a +** custom page cache using this API, an application can control more +** precisely the amount of memory consumed by SQLite, the way in which +** that memory is allocated and released, and the policies used to +** determine exactly which parts of a database file are cached and for +** how long. +** +** ^(The contents of the sqlite3_pcache_methods structure are copied to an +** internal buffer by SQLite within the call to [sqlite3_config]. Hence +** the application may discard the parameter after the call to +** [sqlite3_config()] returns.)^ +** +** ^The xInit() method is called once for each call to [sqlite3_initialize()] +** (usually only once during the lifetime of the process). ^(The xInit() +** method is passed a copy of the sqlite3_pcache_methods.pArg value.)^ +** ^The xInit() method can set up up global structures and/or any mutexes +** required by the custom page cache implementation. +** +** ^The xShutdown() method is called from within [sqlite3_shutdown()], +** if the application invokes this API. It can be used to clean up +** any outstanding resources before process shutdown, if required. +** +** ^SQLite holds a [SQLITE_MUTEX_RECURSIVE] mutex when it invokes +** the xInit method, so the xInit method need not be threadsafe. ^The +** xShutdown method is only called from [sqlite3_shutdown()] so it does +** not need to be threadsafe either. All other methods must be threadsafe +** in multithreaded applications. +** +** ^SQLite will never invoke xInit() more than once without an intervening +** call to xShutdown(). +** +** ^The xCreate() method is used to construct a new cache instance. SQLite +** will typically create one cache instance for each open database file, +** though this is not guaranteed. ^The +** first parameter, szPage, is the size in bytes of the pages that must +** be allocated by the cache. ^szPage will not be a power of two. ^szPage +** will the page size of the database file that is to be cached plus an +** increment (here called "R") of about 100 or 200. ^SQLite will use the +** extra R bytes on each page to store metadata about the underlying +** database page on disk. The value of R depends +** on the SQLite version, the target platform, and how SQLite was compiled. +** ^R is constant for a particular build of SQLite. ^The second argument to +** xCreate(), bPurgeable, is true if the cache being created will +** be used to cache database pages of a file stored on disk, or +** false if it is used for an in-memory database. ^The cache implementation +** does not have to do anything special based with the value of bPurgeable; +** it is purely advisory. ^On a cache where bPurgeable is false, SQLite will +** never invoke xUnpin() except to deliberately delete a page. +** ^In other words, a cache created with bPurgeable set to false will +** never contain any unpinned pages. +** +** ^(The xCachesize() method may be called at any time by SQLite to set the +** suggested maximum cache-size (number of pages stored by) the cache +** instance passed as the first argument. This is the value configured using +** the SQLite "[PRAGMA cache_size]" command.)^ ^As with the bPurgeable +** parameter, the implementation is not required to do anything with this +** value; it is advisory only. +** +** ^The xPagecount() method should return the number of pages currently +** stored in the cache. +** +** ^The xFetch() method is used to fetch a page and return a pointer to it. +** ^A 'page', in this context, is a buffer of szPage bytes aligned at an +** 8-byte boundary. ^The page to be fetched is determined by the key. ^The +** mimimum key value is 1. After it has been retrieved using xFetch, the page +** is considered to be "pinned". +** +** ^If the requested page is already in the page cache, then the page cache +** implementation must return a pointer to the page buffer with its content +** intact. ^(If the requested page is not already in the cache, then the +** behavior of the cache implementation is determined by the value of the +** createFlag parameter passed to xFetch, according to the following table: +** +** +**
createFlag Behaviour when page is not already in cache +**
0 Do not allocate a new page. Return NULL. +**
1 Allocate a new page if it easy and convenient to do so. +** Otherwise return NULL. +**
2 Make every effort to allocate a new page. Only return +** NULL if allocating a new page is effectively impossible. +**
)^ +** +** SQLite will normally invoke xFetch() with a createFlag of 0 or 1. If +** a call to xFetch() with createFlag==1 returns NULL, then SQLite will +** attempt to unpin one or more cache pages by spilling the content of +** pinned pages to disk and synching the operating system disk cache. After +** attempting to unpin pages, the xFetch() method will be invoked again with +** a createFlag of 2. +** +** ^xUnpin() is called by SQLite with a pointer to a currently pinned page +** as its second argument. ^(If the third parameter, discard, is non-zero, +** then the page should be evicted from the cache. In this case SQLite +** assumes that the next time the page is retrieved from the cache using +** the xFetch() method, it will be zeroed.)^ ^If the discard parameter is +** zero, then the page is considered to be unpinned. ^The cache implementation +** may choose to evict unpinned pages at any time. +** +** ^(The cache is not required to perform any reference counting. A single +** call to xUnpin() unpins the page regardless of the number of prior calls +** to xFetch().)^ +** +** ^The xRekey() method is used to change the key value associated with the +** page passed as the second argument from oldKey to newKey. ^If the cache +** previously contains an entry associated with newKey, it should be +** discarded. ^Any prior cache entry associated with newKey is guaranteed not +** to be pinned. +** +** ^When SQLite calls the xTruncate() method, the cache must discard all +** existing cache entries with page numbers (keys) greater than or equal +** to the value of the iLimit parameter passed to xTruncate(). ^If any +** of these pages are pinned, they are implicitly unpinned, meaning that +** they can be safely discarded. +** +** ^The xDestroy() method is used to delete a cache allocated by xCreate(). +** All resources associated with the specified cache should be freed. ^After +** calling the xDestroy() method, SQLite considers the [sqlite3_pcache*] +** handle invalid, and will not use it with any other sqlite3_pcache_methods +** functions. +*/ +typedef struct sqlite3_pcache_methods sqlite3_pcache_methods; +struct sqlite3_pcache_methods { + void *pArg; + int (*xInit)(void*); + void (*xShutdown)(void*); + sqlite3_pcache *(*xCreate)(int szPage, int bPurgeable); + void (*xCachesize)(sqlite3_pcache*, int nCachesize); + int (*xPagecount)(sqlite3_pcache*); + void *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag); + void (*xUnpin)(sqlite3_pcache*, void*, int discard); + void (*xRekey)(sqlite3_pcache*, void*, unsigned oldKey, unsigned newKey); + void (*xTruncate)(sqlite3_pcache*, unsigned iLimit); + void (*xDestroy)(sqlite3_pcache*); +}; + +/* +** CAPI3REF: Online Backup Object +** EXPERIMENTAL +** +** The sqlite3_backup object records state information about an ongoing +** online backup operation. ^The sqlite3_backup object is created by +** a call to [sqlite3_backup_init()] and is destroyed by a call to +** [sqlite3_backup_finish()]. +** +** See Also: [Using the SQLite Online Backup API] +*/ +typedef struct sqlite3_backup sqlite3_backup; + +/* +** CAPI3REF: Online Backup API. +** EXPERIMENTAL +** +** The backup API copies the content of one database into another. +** It is useful either for creating backups of databases or +** for copying in-memory databases to or from persistent files. +** +** See Also: [Using the SQLite Online Backup API] +** +** ^Exclusive access is required to the destination database for the +** duration of the operation. ^However the source database is only +** read-locked while it is actually being read; it is not locked +** continuously for the entire backup operation. ^Thus, the backup may be +** performed on a live source database without preventing other users from +** reading or writing to the source database while the backup is underway. +** +** ^(To perform a backup operation: +**
    +**
  1. sqlite3_backup_init() is called once to initialize the +** backup, +**
  2. sqlite3_backup_step() is called one or more times to transfer +** the data between the two databases, and finally +**
  3. sqlite3_backup_finish() is called to release all resources +** associated with the backup operation. +**
)^ +** There should be exactly one call to sqlite3_backup_finish() for each +** successful call to sqlite3_backup_init(). +** +** sqlite3_backup_init() +** +** ^The D and N arguments to sqlite3_backup_init(D,N,S,M) are the +** [database connection] associated with the destination database +** and the database name, respectively. +** ^The database name is "main" for the main database, "temp" for the +** temporary database, or the name specified after the AS keyword in +** an [ATTACH] statement for an attached database. +** ^The S and M arguments passed to +** sqlite3_backup_init(D,N,S,M) identify the [database connection] +** and database name of the source database, respectively. +** ^The source and destination [database connections] (parameters S and D) +** must be different or else sqlite3_backup_init(D,N,S,M) will file with +** an error. +** +** ^If an error occurs within sqlite3_backup_init(D,N,S,M), then NULL is +** returned and an error code and error message are store3d in the +** destination [database connection] D. +** ^The error code and message for the failed call to sqlite3_backup_init() +** can be retrieved using the [sqlite3_errcode()], [sqlite3_errmsg()], and/or +** [sqlite3_errmsg16()] functions. +** ^A successful call to sqlite3_backup_init() returns a pointer to an +** [sqlite3_backup] object. +** ^The [sqlite3_backup] object may be used with the sqlite3_backup_step() and +** sqlite3_backup_finish() functions to perform the specified backup +** operation. +** +** sqlite3_backup_step() +** +** ^Function sqlite3_backup_step(B,N) will copy up to N pages between +** the source and destination databases specified by [sqlite3_backup] object B. +** ^If N is negative, all remaining source pages are copied. +** ^If sqlite3_backup_step(B,N) successfully copies N pages and there +** are still more pages to be copied, then the function resturns [SQLITE_OK]. +** ^If sqlite3_backup_step(B,N) successfully finishes copying all pages +** from source to destination, then it returns [SQLITE_DONE]. +** ^If an error occurs while running sqlite3_backup_step(B,N), +** then an [error code] is returned. ^As well as [SQLITE_OK] and +** [SQLITE_DONE], a call to sqlite3_backup_step() may return [SQLITE_READONLY], +** [SQLITE_NOMEM], [SQLITE_BUSY], [SQLITE_LOCKED], or an +** [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX] extended error code. +** +** ^The sqlite3_backup_step() might return [SQLITE_READONLY] if the destination +** database was opened read-only or if +** the destination is an in-memory database with a different page size +** from the source database. +** +** ^If sqlite3_backup_step() cannot obtain a required file-system lock, then +** the [sqlite3_busy_handler | busy-handler function] +** is invoked (if one is specified). ^If the +** busy-handler returns non-zero before the lock is available, then +** [SQLITE_BUSY] is returned to the caller. ^In this case the call to +** sqlite3_backup_step() can be retried later. ^If the source +** [database connection] +** is being used to write to the source database when sqlite3_backup_step() +** is called, then [SQLITE_LOCKED] is returned immediately. ^Again, in this +** case the call to sqlite3_backup_step() can be retried later on. ^(If +** [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX], [SQLITE_NOMEM], or +** [SQLITE_READONLY] is returned, then +** there is no point in retrying the call to sqlite3_backup_step(). These +** errors are considered fatal.)^ The application must accept +** that the backup operation has failed and pass the backup operation handle +** to the sqlite3_backup_finish() to release associated resources. +** +** ^The first call to sqlite3_backup_step() obtains an exclusive lock +** on the destination file. ^The exclusive lock is not released until either +** sqlite3_backup_finish() is called or the backup operation is complete +** and sqlite3_backup_step() returns [SQLITE_DONE]. ^Every call to +** sqlite3_backup_step() obtains a [shared lock] on the source database that +** lasts for the duration of the sqlite3_backup_step() call. +** ^Because the source database is not locked between calls to +** sqlite3_backup_step(), the source database may be modified mid-way +** through the backup process. ^If the source database is modified by an +** external process or via a database connection other than the one being +** used by the backup operation, then the backup will be automatically +** restarted by the next call to sqlite3_backup_step(). ^If the source +** database is modified by the using the same database connection as is used +** by the backup operation, then the backup database is automatically +** updated at the same time. +** +** sqlite3_backup_finish() +** +** When sqlite3_backup_step() has returned [SQLITE_DONE], or when the +** application wishes to abandon the backup operation, the application +** should destroy the [sqlite3_backup] by passing it to sqlite3_backup_finish(). +** ^The sqlite3_backup_finish() interfaces releases all +** resources associated with the [sqlite3_backup] object. +** ^If sqlite3_backup_step() has not yet returned [SQLITE_DONE], then any +** active write-transaction on the destination database is rolled back. +** The [sqlite3_backup] object is invalid +** and may not be used following a call to sqlite3_backup_finish(). +** +** ^The value returned by sqlite3_backup_finish is [SQLITE_OK] if no +** sqlite3_backup_step() errors occurred, regardless or whether or not +** sqlite3_backup_step() completed. +** ^If an out-of-memory condition or IO error occurred during any prior +** sqlite3_backup_step() call on the same [sqlite3_backup] object, then +** sqlite3_backup_finish() returns the corresponding [error code]. +** +** ^A return of [SQLITE_BUSY] or [SQLITE_LOCKED] from sqlite3_backup_step() +** is not a permanent error and does not affect the return value of +** sqlite3_backup_finish(). +** +** sqlite3_backup_remaining(), sqlite3_backup_pagecount() +** +** ^Each call to sqlite3_backup_step() sets two values inside +** the [sqlite3_backup] object: the number of pages still to be backed +** up and the total number of pages in the source databae file. +** The sqlite3_backup_remaining() and sqlite3_backup_pagecount() interfaces +** retrieve these two values, respectively. +** +** ^The values returned by these functions are only updated by +** sqlite3_backup_step(). ^If the source database is modified during a backup +** operation, then the values are not updated to account for any extra +** pages that need to be updated or the size of the source database file +** changing. +** +** Concurrent Usage of Database Handles +** +** ^The source [database connection] may be used by the application for other +** purposes while a backup operation is underway or being initialized. +** ^If SQLite is compiled and configured to support threadsafe database +** connections, then the source database connection may be used concurrently +** from within other threads. +** +** However, the application must guarantee that the destination +** [database connection] is not passed to any other API (by any thread) after +** sqlite3_backup_init() is called and before the corresponding call to +** sqlite3_backup_finish(). SQLite does not currently check to see +** if the application incorrectly accesses the destination [database connection] +** and so no error code is reported, but the operations may malfunction +** nevertheless. Use of the destination database connection while a +** backup is in progress might also also cause a mutex deadlock. +** +** If running in [shared cache mode], the application must +** guarantee that the shared cache used by the destination database +** is not accessed while the backup is running. In practice this means +** that the application must guarantee that the disk file being +** backed up to is not accessed by any connection within the process, +** not just the specific connection that was passed to sqlite3_backup_init(). +** +** The [sqlite3_backup] object itself is partially threadsafe. Multiple +** threads may safely make multiple concurrent calls to sqlite3_backup_step(). +** However, the sqlite3_backup_remaining() and sqlite3_backup_pagecount() +** APIs are not strictly speaking threadsafe. If they are invoked at the +** same time as another thread is invoking sqlite3_backup_step() it is +** possible that they return invalid values. +*/ +SQLITE_API sqlite3_backup *sqlite3_backup_init( + sqlite3 *pDest, /* Destination database handle */ + const char *zDestName, /* Destination database name */ + sqlite3 *pSource, /* Source database handle */ + const char *zSourceName /* Source database name */ +); +SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage); +SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p); +SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p); +SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p); + +/* +** CAPI3REF: Unlock Notification +** EXPERIMENTAL +** +** ^When running in shared-cache mode, a database operation may fail with +** an [SQLITE_LOCKED] error if the required locks on the shared-cache or +** individual tables within the shared-cache cannot be obtained. See +** [SQLite Shared-Cache Mode] for a description of shared-cache locking. +** ^This API may be used to register a callback that SQLite will invoke +** when the connection currently holding the required lock relinquishes it. +** ^This API is only available if the library was compiled with the +** [SQLITE_ENABLE_UNLOCK_NOTIFY] C-preprocessor symbol defined. +** +** See Also: [Using the SQLite Unlock Notification Feature]. +** +** ^Shared-cache locks are released when a database connection concludes +** its current transaction, either by committing it or rolling it back. +** +** ^When a connection (known as the blocked connection) fails to obtain a +** shared-cache lock and SQLITE_LOCKED is returned to the caller, the +** identity of the database connection (the blocking connection) that +** has locked the required resource is stored internally. ^After an +** application receives an SQLITE_LOCKED error, it may call the +** sqlite3_unlock_notify() method with the blocked connection handle as +** the first argument to register for a callback that will be invoked +** when the blocking connections current transaction is concluded. ^The +** callback is invoked from within the [sqlite3_step] or [sqlite3_close] +** call that concludes the blocking connections transaction. +** +** ^(If sqlite3_unlock_notify() is called in a multi-threaded application, +** there is a chance that the blocking connection will have already +** concluded its transaction by the time sqlite3_unlock_notify() is invoked. +** If this happens, then the specified callback is invoked immediately, +** from within the call to sqlite3_unlock_notify().)^ +** +** ^If the blocked connection is attempting to obtain a write-lock on a +** shared-cache table, and more than one other connection currently holds +** a read-lock on the same table, then SQLite arbitrarily selects one of +** the other connections to use as the blocking connection. +** +** ^(There may be at most one unlock-notify callback registered by a +** blocked connection. If sqlite3_unlock_notify() is called when the +** blocked connection already has a registered unlock-notify callback, +** then the new callback replaces the old.)^ ^If sqlite3_unlock_notify() is +** called with a NULL pointer as its second argument, then any existing +** unlock-notify callback is cancelled. ^The blocked connections +** unlock-notify callback may also be canceled by closing the blocked +** connection using [sqlite3_close()]. +** +** The unlock-notify callback is not reentrant. If an application invokes +** any sqlite3_xxx API functions from within an unlock-notify callback, a +** crash or deadlock may be the result. +** +** ^Unless deadlock is detected (see below), sqlite3_unlock_notify() always +** returns SQLITE_OK. +** +** Callback Invocation Details +** +** When an unlock-notify callback is registered, the application provides a +** single void* pointer that is passed to the callback when it is invoked. +** However, the signature of the callback function allows SQLite to pass +** it an array of void* context pointers. The first argument passed to +** an unlock-notify callback is a pointer to an array of void* pointers, +** and the second is the number of entries in the array. +** +** When a blocking connections transaction is concluded, there may be +** more than one blocked connection that has registered for an unlock-notify +** callback. ^If two or more such blocked connections have specified the +** same callback function, then instead of invoking the callback function +** multiple times, it is invoked once with the set of void* context pointers +** specified by the blocked connections bundled together into an array. +** This gives the application an opportunity to prioritize any actions +** related to the set of unblocked database connections. +** +** Deadlock Detection +** +** Assuming that after registering for an unlock-notify callback a +** database waits for the callback to be issued before taking any further +** action (a reasonable assumption), then using this API may cause the +** application to deadlock. For example, if connection X is waiting for +** connection Y's transaction to be concluded, and similarly connection +** Y is waiting on connection X's transaction, then neither connection +** will proceed and the system may remain deadlocked indefinitely. +** +** To avoid this scenario, the sqlite3_unlock_notify() performs deadlock +** detection. ^If a given call to sqlite3_unlock_notify() would put the +** system in a deadlocked state, then SQLITE_LOCKED is returned and no +** unlock-notify callback is registered. The system is said to be in +** a deadlocked state if connection A has registered for an unlock-notify +** callback on the conclusion of connection B's transaction, and connection +** B has itself registered for an unlock-notify callback when connection +** A's transaction is concluded. ^Indirect deadlock is also detected, so +** the system is also considered to be deadlocked if connection B has +** registered for an unlock-notify callback on the conclusion of connection +** C's transaction, where connection C is waiting on connection A. ^Any +** number of levels of indirection are allowed. +** +** The "DROP TABLE" Exception +** +** When a call to [sqlite3_step()] returns SQLITE_LOCKED, it is almost +** always appropriate to call sqlite3_unlock_notify(). There is however, +** one exception. When executing a "DROP TABLE" or "DROP INDEX" statement, +** SQLite checks if there are any currently executing SELECT statements +** that belong to the same connection. If there are, SQLITE_LOCKED is +** returned. In this case there is no "blocking connection", so invoking +** sqlite3_unlock_notify() results in the unlock-notify callback being +** invoked immediately. If the application then re-attempts the "DROP TABLE" +** or "DROP INDEX" query, an infinite loop might be the result. +** +** One way around this problem is to check the extended error code returned +** by an sqlite3_step() call. ^(If there is a blocking connection, then the +** extended error code is set to SQLITE_LOCKED_SHAREDCACHE. Otherwise, in +** the special "DROP TABLE/INDEX" case, the extended error code is just +** SQLITE_LOCKED.)^ +*/ +SQLITE_API int sqlite3_unlock_notify( + sqlite3 *pBlocked, /* Waiting connection */ + void (*xNotify)(void **apArg, int nArg), /* Callback function to invoke */ + void *pNotifyArg /* Argument to pass to xNotify */ +); + + +/* +** CAPI3REF: String Comparison +** EXPERIMENTAL +** +** ^The [sqlite3_strnicmp()] API allows applications and extensions to +** compare the contents of two buffers containing UTF-8 strings in a +** case-indendent fashion, using the same definition of case independence +** that SQLite uses internally when comparing identifiers. +*/ +SQLITE_API int sqlite3_strnicmp(const char *, const char *, int); + +/* +** CAPI3REF: Error Logging Interface +** EXPERIMENTAL +** +** ^The [sqlite3_log()] interface writes a message into the error log +** established by the [SQLITE_CONFIG_LOG] option to [sqlite3_config()]. +** ^If logging is enabled, the zFormat string and subsequent arguments are +** passed through to [sqlite3_vmprintf()] to generate the final output string. +** +** The sqlite3_log() interface is intended for use by extensions such as +** virtual tables, collating functions, and SQL functions. While there is +** nothing to prevent an application from calling sqlite3_log(), doing so +** is considered bad form. +** +** The zFormat string must not be NULL. +** +** To avoid deadlocks and other threading problems, the sqlite3_log() routine +** will not use dynamically allocated memory. The log message is stored in +** a fixed-length buffer on the stack. If the log message is longer than +** a few hundred characters, it will be truncated to the length of the +** buffer. +*/ +SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...); + +/* +** Undo the hack that converts floating point types to integer for +** builds on processors without floating point support. +*/ +#ifdef SQLITE_OMIT_FLOATING_POINT +# undef double +#endif + +#ifdef __cplusplus +} /* End of the 'extern "C"' block */ +#endif +#endif + diff --git a/libodbc/include/ss6API.h b/libodbc/include/ss6API.h new file mode 100644 index 0000000000..e91d178223 --- /dev/null +++ b/libodbc/include/ss6API.h @@ -0,0 +1,375 @@ +// ss6API.h +// +////////////////////////////////////////////////////////////////////// + +#if !defined(__SS6API_H__) +#define __SS6API_H__ + +#include "SQLAPI.h" + +// API header(s) +#define DBNTWIN32 +#include "./ss_win/sqlfront.h" +#include "./ss_win/sqldb.h" + +extern long g_nSSDBLibDLLVersionLoaded; + +extern void AddSSDbLibSupport(); +extern void ReleaseSSDbLibSupport(); + +typedef DBERRHANDLE_PROC (SQLAPI *dberrhandle_t)(DBERRHANDLE_PROC); +typedef DBMSGHANDLE_PROC (SQLAPI *dbmsghandle_t)(DBMSGHANDLE_PROC); +typedef DBERRHANDLE_PROC (SQLAPI *dbprocerrhandle_t)(PDBHANDLE, DBERRHANDLE_PROC); +typedef DBMSGHANDLE_PROC (SQLAPI *dbprocmsghandle_t)(PDBHANDLE, DBMSGHANDLE_PROC); + +// Two-phase commit functions +typedef RETCODE (SQLAPI *abort_xact_t) (PDBPROCESS, DBINT); +typedef void (SQLAPI *build_xact_string_t) (LPCSTR, LPCSTR, DBINT, LPSTR); +typedef void (SQLAPI *close_commit_t) (PDBPROCESS); +typedef RETCODE (SQLAPI *commit_xact_t) (PDBPROCESS, DBINT); +typedef PDBPROCESS (SQLAPI *open_commit_t) (PLOGINREC, LPCSTR); +typedef RETCODE (SQLAPI *remove_xact_t) (PDBPROCESS, DBINT, INT); +typedef RETCODE (SQLAPI *scan_xact_t) (PDBPROCESS, DBINT); +typedef DBINT (SQLAPI *start_xact_t) (PDBPROCESS, LPCSTR, LPCSTR, INT); +typedef INT (SQLAPI *stat_xact_t) (PDBPROCESS, DBINT); + +// BCP functions +typedef DBINT (SQLAPI *bcp_batch_t) (PDBPROCESS); +typedef RETCODE (SQLAPI *bcp_bind_t) (PDBPROCESS, LPCBYTE, INT, DBINT, LPCBYTE, INT, INT, INT); +typedef RETCODE (SQLAPI *bcp_colfmt_t) (PDBPROCESS, INT, BYTE, INT, DBINT, LPCBYTE, INT, INT); +typedef RETCODE (SQLAPI *bcp_collen_t) (PDBPROCESS, DBINT, INT); +typedef RETCODE (SQLAPI *bcp_colptr_t) (PDBPROCESS, LPCBYTE, INT); +typedef RETCODE (SQLAPI *bcp_columns_t) (PDBPROCESS, INT); +typedef RETCODE (SQLAPI *bcp_control_t) (PDBPROCESS, INT, DBINT); +typedef DBINT (SQLAPI *bcp_done_t) (PDBPROCESS); +typedef RETCODE (SQLAPI *bcp_exec_t) (PDBPROCESS, LPDBINT); +typedef RETCODE (SQLAPI *bcp_init_t) (PDBPROCESS, LPCSTR, LPCSTR, LPCSTR, INT); +typedef RETCODE (SQLAPI *bcp_moretext_t) (PDBPROCESS, DBINT, LPCBYTE); +typedef RETCODE (SQLAPI *bcp_readfmt_t) (PDBPROCESS, LPCSTR); +typedef RETCODE (SQLAPI *bcp_sendrow_t) (PDBPROCESS); +typedef RETCODE (SQLAPI *bcp_setl_t) (PLOGINREC, BOOL); +typedef RETCODE (SQLAPI *bcp_writefmt_t) (PDBPROCESS, LPCSTR); + +// Standard DB-Library functions +typedef LPCBYTE (SQLAPI *dbadata_t) (PDBPROCESS, INT, INT); +typedef DBINT (SQLAPI *dbadlen_t) (PDBPROCESS, INT, INT); +typedef RETCODE (SQLAPI *dbaltbind_t) (PDBPROCESS, INT, INT, INT, DBINT, LPCBYTE); +typedef INT (SQLAPI *dbaltcolid_t) (PDBPROCESS, INT, INT); +typedef DBINT (SQLAPI *dbaltlen_t) (PDBPROCESS, INT, INT); +typedef INT (SQLAPI *dbaltop_t) (PDBPROCESS, INT, INT); +typedef INT (SQLAPI *dbalttype_t) (PDBPROCESS, INT, INT); +typedef DBINT (SQLAPI *dbaltutype_t) (PDBPROCESS, INT, INT); +typedef RETCODE (SQLAPI *dbanullbind_t) (PDBPROCESS, INT, INT, LPCDBINT); +typedef RETCODE (SQLAPI *dbbind_t) (PDBPROCESS, INT, INT, DBINT, LPBYTE); +typedef LPCBYTE (SQLAPI *dbbylist_t) (PDBPROCESS, INT, LPINT); +typedef RETCODE (SQLAPI *dbcancel_t) (PDBPROCESS); +typedef RETCODE (SQLAPI *dbcanquery_t) (PDBPROCESS); +typedef LPCSTR (SQLAPI *dbchange_t) (PDBPROCESS); +typedef RETCODE (SQLAPI *dbclose_t) (PDBPROCESS); +typedef void (SQLAPI *dbclrbuf_t) (PDBPROCESS, DBINT); +typedef RETCODE (SQLAPI *dbclropt_t) (PDBPROCESS, INT, LPCSTR); +typedef RETCODE (SQLAPI *dbcmd_t) (PDBPROCESS, LPCSTR); +typedef RETCODE (SQLAPI *dbcmdrow_t) (PDBPROCESS); +typedef BOOL (SQLAPI *dbcolbrowse_t) (PDBPROCESS, INT); +typedef RETCODE (SQLAPI *dbcolinfo_t) (PDBHANDLE, INT, INT, INT, LPDBCOL); +typedef DBINT (SQLAPI *dbcollen_t) (PDBPROCESS, INT); +typedef LPCSTR (SQLAPI *dbcolname_t) (PDBPROCESS, INT); +typedef LPCSTR (SQLAPI *dbcolsource_t) (PDBPROCESS, INT); +typedef INT (SQLAPI *dbcoltype_t) (PDBPROCESS, INT); +typedef DBINT (SQLAPI *dbcolutype_t) (PDBPROCESS, INT); +typedef INT (SQLAPI *dbconvert_t) (PDBPROCESS, INT, LPCBYTE, DBINT, INT, LPBYTE, DBINT); +typedef DBINT (SQLAPI *dbcount_t) (PDBPROCESS); +typedef INT (SQLAPI *dbcurcmd_t) (PDBPROCESS); +typedef DBINT (SQLAPI *dbcurrow_t) (PDBPROCESS); +typedef RETCODE (SQLAPI *dbcursor_t) (PDBCURSOR, INT, INT, LPCSTR, LPCSTR); +typedef RETCODE (SQLAPI *dbcursorbind_t) (PDBCURSOR, INT, INT, DBINT, LPDBINT, LPBYTE); +typedef RETCODE (SQLAPI *dbcursorclose_t) (PDBHANDLE); +typedef RETCODE (SQLAPI *dbcursorcolinfo_t) (PDBCURSOR, INT, LPSTR, LPINT, LPDBINT, LPINT); +typedef RETCODE (SQLAPI *dbcursorfetch_t) (PDBCURSOR, INT, INT); +typedef RETCODE (SQLAPI *dbcursorfetchex_t) (PDBCURSOR, INT, DBINT, DBINT, DBINT); +typedef RETCODE (SQLAPI *dbcursorinfo_t) (PDBCURSOR, LPINT, LPDBINT); +typedef RETCODE (SQLAPI *dbcursorinfoex_t) (PDBCURSOR, LPDBCURSORINFO); +typedef PDBCURSOR (SQLAPI *dbcursoropen_t) (PDBPROCESS, LPCSTR, INT, INT,UINT, LPDBINT); +typedef LPCBYTE (SQLAPI *dbdata_t) (PDBPROCESS, INT); +typedef BOOL (SQLAPI *dbdataready_t) (PDBPROCESS); +typedef RETCODE (SQLAPI *dbdatecrack_t) (PDBPROCESS, LPDBDATEREC, LPCDBDATETIME); +typedef DBINT (SQLAPI *dbdatlen_t) (PDBPROCESS, INT); +typedef BOOL (SQLAPI *dbdead_t) (PDBPROCESS); +typedef void (SQLAPI *dbexit_t) (void); +typedef RETCODE (SQLAPI *dbenlisttrans_t) (PDBPROCESS, LPVOID); +typedef RETCODE (SQLAPI *dbenlistxatrans_t) (PDBPROCESS, BOOL); +typedef RETCODE (SQLAPI *dbfcmd_t) (PDBPROCESS, LPCSTR, ...); +typedef DBINT (SQLAPI *dbfirstrow_t) (PDBPROCESS); +typedef void (SQLAPI *dbfreebuf_t) (PDBPROCESS); +typedef void (SQLAPI *dbfreelogin_t) (PLOGINREC); +typedef void (SQLAPI *dbfreequal_t) (LPCSTR); +typedef LPSTR (SQLAPI *dbgetchar_t) (PDBPROCESS, INT); +typedef SHORT (SQLAPI *dbgetmaxprocs_t) (void); +typedef INT (SQLAPI *dbgetoff_t) (PDBPROCESS, DBUSMALLINT, INT); +typedef UINT (SQLAPI *dbgetpacket_t) (PDBPROCESS); +typedef STATUS (SQLAPI *dbgetrow_t) (PDBPROCESS, DBINT); +typedef INT (SQLAPI *dbgettime_t) (void); +typedef LPVOID (SQLAPI *dbgetuserdata_t) (PDBPROCESS); +typedef BOOL (SQLAPI *dbhasretstat_t) (PDBPROCESS); +typedef LPCSTR (SQLAPI *dbinit_t) (void); +typedef BOOL (SQLAPI *dbisavail_t) (PDBPROCESS); +typedef BOOL (SQLAPI *dbiscount_t) (PDBPROCESS); +typedef BOOL (SQLAPI *dbisopt_t) (PDBPROCESS, INT, LPCSTR); +typedef DBINT (SQLAPI *dblastrow_t) (PDBPROCESS); +typedef PLOGINREC (SQLAPI *dblogin_t) (void); +typedef RETCODE (SQLAPI *dbmorecmds_t) (PDBPROCESS); +typedef RETCODE (SQLAPI *dbmoretext_t) (PDBPROCESS, DBINT, LPCBYTE); +typedef LPCSTR (SQLAPI *dbname_t) (PDBPROCESS); +typedef STATUS (SQLAPI *dbnextrow_t) (PDBPROCESS); +typedef RETCODE (SQLAPI *dbnullbind_t) (PDBPROCESS, INT, LPCDBINT); +typedef INT (SQLAPI *dbnumalts_t) (PDBPROCESS, INT); +typedef INT (SQLAPI *dbnumcols_t) (PDBPROCESS); +typedef INT (SQLAPI *dbnumcompute_t) (PDBPROCESS); +typedef INT (SQLAPI *dbnumorders_t) (PDBPROCESS); +typedef INT (SQLAPI *dbnumrets_t) (PDBPROCESS); +typedef PDBPROCESS (SQLAPI *dbopen_t) (PLOGINREC, LPCSTR); +typedef INT (SQLAPI *dbordercol_t) (PDBPROCESS, INT); +typedef RETCODE (SQLAPI *dbprocinfo_t) (PDBPROCESS, LPDBPROCINFO); +typedef void (SQLAPI *dbprhead_t) (PDBPROCESS); +typedef RETCODE (SQLAPI *dbprrow_t) (PDBPROCESS); +typedef LPCSTR (SQLAPI *dbprtype_t) (INT); +typedef LPCSTR (SQLAPI *dbqual_t) (PDBPROCESS, INT, LPCSTR); +typedef DBINT (SQLAPI *dbreadpage_t) (PDBPROCESS, LPCSTR, DBINT, LPBYTE); +typedef DBINT (SQLAPI *dbreadtext_t) (PDBPROCESS, LPVOID, DBINT); +typedef RETCODE (SQLAPI *dbresults_t) (PDBPROCESS); +typedef LPCBYTE (SQLAPI *dbretdata_t) (PDBPROCESS, INT); +typedef DBINT (SQLAPI *dbretlen_t) (PDBPROCESS, INT); +typedef LPCSTR (SQLAPI *dbretname_t) (PDBPROCESS, INT); +typedef DBINT (SQLAPI *dbretstatus_t) (PDBPROCESS); +typedef INT (SQLAPI *dbrettype_t) (PDBPROCESS, INT); +typedef RETCODE (SQLAPI *dbrows_t) (PDBPROCESS); +typedef STATUS (SQLAPI *dbrowtype_t) (PDBPROCESS); +typedef RETCODE (SQLAPI *dbrpcinit_t) (PDBPROCESS, LPCSTR, DBSMALLINT); +typedef RETCODE (SQLAPI *dbrpcparam_t) (PDBPROCESS, LPCSTR, BYTE, INT, DBINT, DBINT, LPCBYTE); +typedef RETCODE (SQLAPI *dbrpcsend_t) (PDBPROCESS); +typedef RETCODE (SQLAPI *dbrpcexec_t) (PDBPROCESS); +typedef void (SQLAPI *dbrpwclr_t) (PLOGINREC); +typedef RETCODE (SQLAPI *dbrpwset_t) (PLOGINREC, LPCSTR, LPCSTR, INT); +typedef INT (SQLAPI *dbserverenum_t) (USHORT, LPSTR, USHORT, LPUSHORT); +typedef void (SQLAPI *dbsetavail_t) (PDBPROCESS); +typedef RETCODE (SQLAPI *dbsetmaxprocs_t) (SHORT); +typedef RETCODE (SQLAPI *dbsetlname_t) (PLOGINREC, LPCSTR, INT); +typedef RETCODE (SQLAPI *dbsetlogintime_t) (INT); +typedef RETCODE (SQLAPI *dbsetlpacket_t) (PLOGINREC, USHORT); +typedef RETCODE (SQLAPI *dbsetnull_t) (PDBPROCESS, INT, INT, LPCBYTE); +typedef RETCODE (SQLAPI *dbsetopt_t) (PDBPROCESS, INT, LPCSTR); +typedef RETCODE (SQLAPI *dbsettime_t) (INT); +typedef void (SQLAPI *dbsetuserdata_t) (PDBPROCESS, LPVOID); +typedef RETCODE (SQLAPI *dbsqlexec_t) (PDBPROCESS); +typedef RETCODE (SQLAPI *dbsqlok_t) (PDBPROCESS); +typedef RETCODE (SQLAPI *dbsqlsend_t) (PDBPROCESS); +typedef RETCODE (SQLAPI *dbstrcpy_t) (PDBPROCESS, INT, INT, LPSTR); +typedef INT (SQLAPI *dbstrlen_t) (PDBPROCESS); +typedef BOOL (SQLAPI *dbtabbrowse_t) (PDBPROCESS, INT); +typedef INT (SQLAPI *dbtabcount_t) (PDBPROCESS); +typedef LPCSTR (SQLAPI *dbtabname_t) (PDBPROCESS, INT); +typedef LPCSTR (SQLAPI *dbtabsource_t) (PDBPROCESS, INT, LPINT); +typedef INT (SQLAPI *dbtsnewlen_t) (PDBPROCESS); +typedef LPCDBBINARY (SQLAPI *dbtsnewval_t) (PDBPROCESS); +typedef RETCODE (SQLAPI *dbtsput_t) (PDBPROCESS, LPCDBBINARY, INT, INT, LPCSTR); +typedef LPCDBBINARY (SQLAPI *dbtxptr_t) (PDBPROCESS, INT); +typedef LPCDBBINARY (SQLAPI *dbtxtimestamp_t) (PDBPROCESS, INT); +typedef LPCDBBINARY (SQLAPI *dbtxtsnewval_t) (PDBPROCESS); +typedef RETCODE (SQLAPI *dbtxtsput_t) (PDBPROCESS, LPCDBBINARY, INT); +typedef RETCODE (SQLAPI *dbuse_t) (PDBPROCESS, LPCSTR); +typedef BOOL (SQLAPI *dbvarylen_t) (PDBPROCESS, INT); +typedef BOOL (SQLAPI *dbwillconvert_t) (INT, INT); +typedef RETCODE (SQLAPI *dbwritepage_t) (PDBPROCESS, LPCSTR, DBINT, DBINT, LPBYTE); +typedef RETCODE (SQLAPI *dbwritetext_t) (PDBPROCESS, LPCSTR, LPCDBBINARY, DBTINYINT, LPCDBBINARY, BOOL, DBINT, LPCBYTE); +typedef RETCODE (SQLAPI *dbupdatetext_t) (PDBPROCESS, LPCSTR, LPCDBBINARY, LPCDBBINARY, INT, DBINT, DBINT, LPCSTR, DBINT, LPCDBBINARY); + +// API declarations +class ssAPI : public saAPI +{ +public: + ssAPI(); + + dberrhandle_t dberrhandle; + dbmsghandle_t dbmsghandle; + dbprocerrhandle_t dbprocerrhandle; + dbprocmsghandle_t dbprocmsghandle; + + // Two-phase commit functions + abort_xact_t abort_xact; + build_xact_string_t build_xact_string; + close_commit_t close_commit; + commit_xact_t commit_xact; + open_commit_t open_commit; + remove_xact_t remove_xact; + scan_xact_t scan_xact; + start_xact_t start_xact; + stat_xact_t stat_xact; + + // BCP functions + bcp_batch_t bcp_batch; + bcp_bind_t bcp_bind; + bcp_colfmt_t bcp_colfmt; + bcp_collen_t bcp_collen; + bcp_colptr_t bcp_colptr; + bcp_columns_t bcp_columns; + bcp_control_t bcp_control; + bcp_done_t bcp_done; + bcp_exec_t bcp_exec; + bcp_init_t bcp_init; + bcp_moretext_t bcp_moretext; + bcp_readfmt_t bcp_readfmt; + bcp_sendrow_t bcp_sendrow; + bcp_setl_t bcp_setl; + bcp_writefmt_t bcp_writefmt; + + // Standard DB-Library functions + dbadata_t dbadata; + dbadlen_t dbadlen; + dbaltbind_t dbaltbind; + dbaltcolid_t dbaltcolid; + dbaltlen_t dbaltlen; + dbaltop_t dbaltop; + dbalttype_t dbalttype; + dbaltutype_t dbaltutype; + dbanullbind_t dbanullbind; + dbbind_t dbbind; + dbbylist_t dbbylist; + dbcancel_t dbcancel; + dbcanquery_t dbcanquery; + dbchange_t dbchange; + dbclose_t dbclose; + dbclrbuf_t dbclrbuf; + dbclropt_t dbclropt; + dbcmd_t dbcmd; + dbcmdrow_t dbcmdrow; + dbcolbrowse_t dbcolbrowse; + dbcolinfo_t dbcolinfo; + dbcollen_t dbcollen; + dbcolname_t dbcolname; + dbcolsource_t dbcolsource; + dbcoltype_t dbcoltype; + dbcolutype_t dbcolutype; + dbconvert_t dbconvert; + dbcount_t dbcount; + dbcurcmd_t dbcurcmd; + dbcurrow_t dbcurrow; + dbcursor_t dbcursor; + dbcursorbind_t dbcursorbind; + dbcursorclose_t dbcursorclose; + dbcursorcolinfo_t dbcursorcolinfo; + dbcursorfetch_t dbcursorfetch; + dbcursorfetchex_t dbcursorfetchex; + dbcursorinfo_t dbcursorinfo; + dbcursorinfoex_t dbcursorinfoex; + dbcursoropen_t dbcursoropen; + dbdata_t dbdata; + dbdataready_t dbdataready; + dbdatecrack_t dbdatecrack; + dbdatlen_t dbdatlen; + dbdead_t dbdead; + dbexit_t dbexit; + dbenlisttrans_t dbenlisttrans; + dbenlistxatrans_t dbenlistxatrans; + dbfcmd_t dbfcmd; + dbfirstrow_t dbfirstrow; + dbfreebuf_t dbfreebuf; + dbfreelogin_t dbfreelogin; + dbfreequal_t dbfreequal; + dbgetchar_t dbgetchar; + dbgetmaxprocs_t dbgetmaxprocs; + dbgetoff_t dbgetoff; + dbgetpacket_t dbgetpacket; + dbgetrow_t dbgetrow; + dbgettime_t dbgettime; + dbgetuserdata_t dbgetuserdata; + dbhasretstat_t dbhasretstat; + dbinit_t dbinit; + dbisavail_t dbisavail; + dbiscount_t dbiscount; + dbisopt_t dbisopt; + dblastrow_t dblastrow; + dblogin_t dblogin; + dbmorecmds_t dbmorecmds; + dbmoretext_t dbmoretext; + dbname_t dbname; + dbnextrow_t dbnextrow; + dbnullbind_t dbnullbind; + dbnumalts_t dbnumalts; + dbnumcols_t dbnumcols; + dbnumcompute_t dbnumcompute; + dbnumorders_t dbnumorders; + dbnumrets_t dbnumrets; + dbopen_t dbopen; + dbordercol_t dbordercol; + dbprocinfo_t dbprocinfo; + dbprhead_t dbprhead; + dbprrow_t dbprrow; + dbprtype_t dbprtype; + dbqual_t dbqual; + dbreadpage_t dbreadpage; + dbreadtext_t dbreadtext; + dbresults_t dbresults; + dbretdata_t dbretdata; + dbretlen_t dbretlen; + dbretname_t dbretname; + dbretstatus_t dbretstatus; + dbrettype_t dbrettype; + dbrows_t dbrows; + dbrowtype_t dbrowtype; + dbrpcinit_t dbrpcinit; + dbrpcparam_t dbrpcparam; + dbrpcsend_t dbrpcsend; + dbrpcexec_t dbrpcexec; + dbrpwclr_t dbrpwclr; + dbrpwset_t dbrpwset; + dbserverenum_t dbserverenum; + dbsetavail_t dbsetavail; + dbsetmaxprocs_t dbsetmaxprocs; + dbsetlname_t dbsetlname; + dbsetlogintime_t dbsetlogintime; + dbsetlpacket_t dbsetlpacket; + dbsetnull_t dbsetnull; + dbsetopt_t dbsetopt; + dbsettime_t dbsettime; + dbsetuserdata_t dbsetuserdata; + dbsqlexec_t dbsqlexec; + dbsqlok_t dbsqlok; + dbsqlsend_t dbsqlsend; + dbstrcpy_t dbstrcpy; + dbstrlen_t dbstrlen; + dbtabbrowse_t dbtabbrowse; + dbtabcount_t dbtabcount; + dbtabname_t dbtabname; + dbtabsource_t dbtabsource; + dbtsnewlen_t dbtsnewlen; + dbtsnewval_t dbtsnewval; + dbtsput_t dbtsput; + dbtxptr_t dbtxptr; + dbtxtimestamp_t dbtxtimestamp; + dbtxtsnewval_t dbtxtsnewval; + dbtxtsput_t dbtxtsput; + dbuse_t dbuse; + dbvarylen_t dbvarylen; + dbwillconvert_t dbwillconvert; + dbwritepage_t dbwritepage; + dbwritetext_t dbwritetext; + dbupdatetext_t dbupdatetext; +}; + +class SQLAPI_API ssConnectionHandles : public saConnectionHandles +{ +public: + ssConnectionHandles(); + + PDBPROCESS m_dbproc; +}; + +class SQLAPI_API ssCommandHandles : public saCommandHandles +{ +public: + ssCommandHandles(); +}; + +extern ssAPI g_ssAPI; + +#endif // !defined(__SS6API_H__) diff --git a/libodbc/include/ssNcliAPI.h b/libodbc/include/ssNcliAPI.h new file mode 100644 index 0000000000..801ed9f064 --- /dev/null +++ b/libodbc/include/ssNcliAPI.h @@ -0,0 +1,551 @@ +// SQL Server Native API +// +////////////////////////////////////////////////////////////////////// + +#if !defined(__SSNCLIAPI_H__) +#define __SSNCLIAPI_H__ + +#include "SQLAPI.h" + +// MSVC++ 6.0 doesn't have this +#ifdef SQLAPI_WINDOWS +#ifndef DBROWCOUNT +#ifdef _WIN64 +typedef LONGLONG DBROWCOUNT; +#else +typedef LONG DBROWCOUNT; +#endif +#endif +#ifndef DBCOUNTITEM +#ifdef _WIN64 +typedef ULONGLONG DBCOUNTITEM; +#else +typedef ULONG DBCOUNTITEM; +#endif +#endif +#ifndef DBORDINAL +#ifdef _WIN64 +typedef ULONGLONG DBORDINAL; +#else +typedef ULONG DBORDINAL; +#endif +#endif +#ifndef DB_UPARAMS +#ifdef _WIN64 +typedef ULONGLONG DB_UPARAMS; +#else +typedef ULONG DB_UPARAMS; +#endif +#endif +#ifndef SQLLEN +#ifdef _WIN64 +typedef INT64 SQLLEN; +#else +#define SQLLEN SQLINTEGER +#endif +#endif +#ifndef SQLULEN +#ifdef _WIN64 +typedef UINT64 SQLULEN; +#else +#define SQLULEN SQLUINTEGER +#endif +#endif +#ifndef SQLSETPOSIROW +#ifdef _WIN64 +typedef UINT64 SQLSETPOSIROW; +#else +#define SQLSETPOSIROW SQLUSMALLINT +#endif +#endif +#endif + +// API header(s) +#include +#include +#ifdef SQLAPI_WINDOWS +#include +#else +#include +#endif + +extern void AddNCliSupport(const SAConnection *pCon); +extern void ReleaseNCliSupport(); + +typedef SQLRETURN (SQL_API *SQLAllocHandle_t)(SQLSMALLINT HandleType, + SQLHANDLE InputHandle, SQLHANDLE *OutputHandle); +typedef SQLRETURN (SQL_API *SQLBindCol_t)( + SQLHSTMT StatementHandle, + SQLUSMALLINT ColumnNumber, + SQLSMALLINT TargetType, + SQLPOINTER TargetValue, + SQLLEN BufferLength, + SQLLEN *StrLen_or_Ind); +typedef SQLRETURN (SQL_API *SQLBindParameter_t)( + SQLHSTMT hstmt, + SQLUSMALLINT ipar, + SQLSMALLINT fParamType, + SQLSMALLINT fCType, + SQLSMALLINT fSqlType, + SQLULEN cbColDef, + SQLSMALLINT ibScale, + SQLPOINTER rgbValue, + SQLLEN cbValueMax, + SQLLEN *pcbValue); +typedef SQLRETURN (SQL_API *SQLBulkOperations_t)( + SQLHSTMT StatementHandle, + SQLSMALLINT Operation); +typedef SQLRETURN (SQL_API *SQLBrowseConnectW_t)( + SQLHDBC hdbc, + SQLWCHAR *szConnStrIn, + SQLSMALLINT cbConnStrIn, + SQLWCHAR *szConnStrOut, + SQLSMALLINT cbConnStrOutMax, + SQLSMALLINT *pcbConnStrOut); +typedef SQLRETURN (SQL_API *SQLCancel_t)(SQLHSTMT StatementHandle); +typedef SQLRETURN (SQL_API *SQLCloseCursor_t)(SQLHSTMT StatementHandle); +#if defined(_WIN64) || defined(SA_64BIT) +typedef SQLRETURN (SQL_API *SQLColAttributeW_t)( + SQLHSTMT hstmt, + SQLUSMALLINT iCol, + SQLUSMALLINT iField, + SQLPOINTER pCharAttr, + SQLSMALLINT cbCharAttrMax, + SQLSMALLINT *pcbCharAttr, + SQLLEN *pNumAttr); +#else +typedef SQLRETURN (SQL_API *SQLColAttributeW_t)( + SQLHSTMT hstmt, + SQLUSMALLINT iCol, + SQLUSMALLINT iField, + SQLPOINTER pCharAttr, + SQLSMALLINT cbCharAttrMax, + SQLSMALLINT *pcbCharAttr, + SQLPOINTER pNumAttr); +#endif +typedef SQLRETURN (SQL_API *SQLColumnPrivilegesW_t)( + SQLHSTMT hstmt, + SQLWCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLWCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLWCHAR *szTableName, + SQLSMALLINT cbTableName, + SQLWCHAR *szColumnName, + SQLSMALLINT cbColumnName); +typedef SQLRETURN (SQL_API *SQLColumnsW_t)( + SQLHSTMT hstmt, + SQLWCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLWCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLWCHAR *szTableName, + SQLSMALLINT cbTableName, + SQLWCHAR *szColumnName, + SQLSMALLINT cbColumnName); +typedef SQLRETURN (SQL_API *SQLConnectW_t)( + SQLHDBC hdbc, + SQLWCHAR *szDSN, + SQLSMALLINT cbDSN, + SQLWCHAR *szUID, + SQLSMALLINT cbUID, + SQLWCHAR *szAuthStr, + SQLSMALLINT cbAuthStr); +typedef SQLRETURN (SQL_API *SQLCopyDesc_t)(SQLHDESC SourceDescHandle, + SQLHDESC TargetDescHandle); +typedef SQLRETURN (SQL_API *SQLDescribeColW_t)( + SQLHSTMT hstmt, + SQLUSMALLINT icol, + SQLWCHAR *szColName, + SQLSMALLINT cbColNameMax, + SQLSMALLINT *pcbColName, + SQLSMALLINT *pfSqlType, + SQLULEN *pcbColDef, + SQLSMALLINT *pibScale, + SQLSMALLINT *pfNullable); +typedef SQLRETURN (SQL_API *SQLDescribeParam_t)( + SQLHSTMT hstmt, + SQLUSMALLINT ipar, + SQLSMALLINT *pfSqlType, + SQLULEN *pcbParamDef, + SQLSMALLINT *pibScale, + SQLSMALLINT *pfNullable); +typedef SQLRETURN (SQL_API *SQLDisconnect_t)(SQLHDBC ConnectionHandle); +typedef SQLRETURN (SQL_API *SQLDriverConnectW_t)( + SQLHDBC hdbc, + SQLHWND hwnd, + SQLWCHAR *szConnStrIn, + SQLSMALLINT cbConnStrIn, + SQLWCHAR *szConnStrOut, + SQLSMALLINT cbConnStrOutMax, + SQLSMALLINT *pcbConnStrOut, + SQLUSMALLINT fDriverCompletion); +typedef SQLRETURN (SQL_API *SQLEndTran_t)(SQLSMALLINT HandleType, SQLHANDLE Handle, + SQLSMALLINT CompletionType); +typedef SQLRETURN (SQL_API *SQLExecDirectW_t)( + SQLHSTMT hstmt, + SQLWCHAR *szSqlStr, + SQLINTEGER cbSqlStr); +typedef SQLRETURN (SQL_API *SQLExecute_t)(SQLHSTMT StatementHandle); +typedef SQLRETURN (SQL_API *SQLExtendedFetch_t)( + SQLHSTMT hstmt, + SQLUSMALLINT fFetchType, + SQLLEN irow, + SQLULEN *pcrow, + SQLUSMALLINT *rgfRowStatus); +typedef SQLRETURN (SQL_API *SQLFetch_t)(SQLHSTMT StatementHandle); +typedef SQLRETURN (SQL_API *SQLFetchScroll_t)( + SQLHSTMT StatementHandle, + SQLSMALLINT FetchOrientation, + SQLLEN FetchOffset); +typedef SQLRETURN (SQL_API *SQLFreeHandle_t)(SQLSMALLINT HandleType, SQLHANDLE Handle); +typedef SQLRETURN (SQL_API *SQLFreeStmt_t)(SQLHSTMT StatementHandle, + SQLUSMALLINT Option); +typedef SQLRETURN (SQL_API *SQLForeignKeysW_t)( + SQLHSTMT hstmt, + SQLWCHAR *szPkCatalogName, + SQLSMALLINT cbPkCatalogName, + SQLWCHAR *szPkSchemaName, + SQLSMALLINT cbPkSchemaName, + SQLWCHAR *szPkTableName, + SQLSMALLINT cbPkTableName, + SQLWCHAR *szFkCatalogName, + SQLSMALLINT cbFkCatalogName, + SQLWCHAR *szFkSchemaName, + SQLSMALLINT cbFkSchemaName, + SQLWCHAR *szFkTableName, + SQLSMALLINT cbFkTableName); +typedef SQLRETURN (SQL_API *SQLGetConnectAttrW_t)( + SQLHDBC hdbc, + SQLINTEGER fAttribute, + SQLPOINTER rgbValue, + SQLINTEGER cbValueMax, + SQLINTEGER *pcbValue); +typedef SQLRETURN (SQL_API *SQLGetConnectOptionW_t)( + SQLHDBC hdbc, + SQLUSMALLINT fOption, + SQLPOINTER pvParam); +typedef SQLRETURN (SQL_API *SQLGetCursorNameW_t)( + SQLHSTMT hstmt, + SQLWCHAR *szCursor, + SQLSMALLINT cbCursorMax, + SQLSMALLINT *pcbCursor); +typedef SQLRETURN (SQL_API *SQLGetData_t)( + SQLHSTMT StatementHandle, + SQLUSMALLINT ColumnNumber, + SQLSMALLINT TargetType, + SQLPOINTER TargetValue, + SQLLEN BufferLength, + SQLLEN *StrLen_or_Ind); +typedef SQLRETURN (SQL_API *SQLGetDescFieldW_t)( + SQLHDESC hdesc, + SQLSMALLINT iRecord, + SQLSMALLINT iField, + SQLPOINTER rgbValue, + SQLINTEGER cbValueMax, + SQLINTEGER *pcbValue); +typedef SQLRETURN (SQL_API *SQLGetDescRecW_t)( + SQLHDESC hdesc, + SQLSMALLINT iRecord, + SQLWCHAR *szName, + SQLSMALLINT cbNameMax, + SQLSMALLINT *pcbName, + SQLSMALLINT *pfType, + SQLSMALLINT *pfSubType, + SQLLEN *pLength, + SQLSMALLINT *pPrecision, + SQLSMALLINT *pScale, + SQLSMALLINT *pNullable); +typedef SQLRETURN (SQL_API *SQLGetDiagFieldW_t)( + SQLSMALLINT fHandleType, + SQLHANDLE handle, + SQLSMALLINT iRecord, + SQLSMALLINT fDiagField, + SQLPOINTER rgbDiagInfo, + SQLSMALLINT cbDiagInfoMax, + SQLSMALLINT *pcbDiagInfo); +typedef SQLRETURN (SQL_API *SQLGetDiagRecW_t)( + SQLSMALLINT fHandleType, + SQLHANDLE handle, + SQLSMALLINT iRecord, + SQLWCHAR *szSqlState, + SQLINTEGER *pfNativeError, + SQLWCHAR *szErrorMsg, + SQLSMALLINT cbErrorMsgMax, + SQLSMALLINT *pcbErrorMsg); +typedef SQLRETURN (SQL_API *SQLGetEnvAttr_t)( + SQLHENV EnvironmentHandle, + SQLINTEGER Attribute, + SQLPOINTER Value, + SQLINTEGER BufferLength, + SQLINTEGER *StringLength); +typedef SQLRETURN (SQL_API *SQLGetFunctions_t)( + SQLHDBC ConnectionHandle, + SQLUSMALLINT FunctionId, + SQLUSMALLINT *Supported); +typedef SQLRETURN (SQL_API *SQLGetInfoW_t)( + SQLHDBC hdbc, + SQLUSMALLINT fInfoType, + SQLPOINTER rgbInfoValue, + SQLSMALLINT cbInfoValueMax, + SQLSMALLINT *pcbInfoValue); +typedef SQLRETURN (SQL_API *SQLGetTypeInfoW_t)( + SQLHSTMT StatementHandle, + SQLSMALLINT DataType); +typedef SQLRETURN (SQL_API *SQLGetStmtAttrW_t)( + SQLHSTMT hstmt, + SQLINTEGER fAttribute, + SQLPOINTER rgbValue, + SQLINTEGER cbValueMax, + SQLINTEGER *pcbValue); +typedef SQLRETURN (SQL_API *SQLMoreResults_t)( + SQLHSTMT hstmt); +typedef SQLRETURN (SQL_API *SQLNativeSqlW_t)( + SQLHDBC hdbc, + SQLWCHAR *szSqlStrIn, + SQLINTEGER cbSqlStrIn, + SQLWCHAR *szSqlStr, + SQLINTEGER cbSqlStrMax, + SQLINTEGER *pcbSqlStr); +typedef SQLRETURN (SQL_API *SQLNumParams_t)( + SQLHSTMT hstmt, + SQLSMALLINT *pcpar); +typedef SQLRETURN (SQL_API *SQLNumResultCols_t)( + SQLHSTMT StatementHandle, + SQLSMALLINT *ColumnCount); +typedef SQLRETURN (SQL_API *SQLParamData_t)( + SQLHSTMT StatementHandle, + SQLPOINTER *Value); +typedef SQLRETURN (SQL_API *SQLParamOptions_t)( + SQLHSTMT hstmt, + SQLULEN crow, + SQLULEN *pirow); +typedef SQLRETURN (SQL_API *SQLPrepareW_t)( + SQLHSTMT hstmt, + SQLWCHAR *szSqlStr, + SQLINTEGER cbSqlStr); +typedef SQLRETURN (SQL_API *SQLPrimaryKeysW_t)( + SQLHSTMT hstmt, + SQLWCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLWCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLWCHAR *szTableName, + SQLSMALLINT cbTableName); +typedef SQLRETURN (SQL_API *SQLProcedureColumnsW_t)( + SQLHSTMT hstmt, + SQLWCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLWCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLWCHAR *szProcName, + SQLSMALLINT cbProcName, + SQLWCHAR *szColumnName, + SQLSMALLINT cbColumnName); +typedef SQLRETURN (SQL_API *SQLProceduresW_t)( + SQLHSTMT hstmt, + SQLWCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLWCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLWCHAR *szProcName, + SQLSMALLINT cbProcName); +typedef SQLRETURN (SQL_API *SQLPutData_t)( + SQLHSTMT StatementHandle, + SQLPOINTER Data, + SQLLEN StrLen_or_Ind); +typedef SQLRETURN (SQL_API *SQLRowCount_t)( + SQLHSTMT StatementHandle, + SQLLEN *RowCount); +typedef SQLRETURN (SQL_API *SQLSetConnectAttrW_t)( + SQLHDBC hdbc, + SQLINTEGER fAttribute, + SQLPOINTER rgbValue, + SQLINTEGER cbValue); +typedef SQLRETURN (SQL_API *SQLSetConnectOptionW_t)( + SQLHDBC hdbc, + SQLUSMALLINT fOption, + SQLULEN vParam); +typedef SQLRETURN (SQL_API *SQLSetCursorNameW_t)( + SQLHSTMT hstmt, + SQLWCHAR *szCursor, + SQLSMALLINT cbCursor); +typedef SQLRETURN (SQL_API *SQLSetDescFieldW_t)( + SQLHDESC DescriptorHandle, + SQLSMALLINT RecNumber, + SQLSMALLINT FieldIdentifier, + SQLPOINTER Value, + SQLINTEGER BufferLength); +typedef SQLRETURN (SQL_API *SQLSetDescRec_t)( + SQLHDESC DescriptorHandle, + SQLSMALLINT RecNumber, + SQLSMALLINT Type, + SQLSMALLINT SubType, + SQLLEN Length, + SQLSMALLINT Precision, + SQLSMALLINT Scale, + SQLPOINTER Data, + SQLLEN *StringLength, + SQLLEN *Indicator); +typedef SQLRETURN (SQL_API *SQLSetEnvAttr_t)(SQLHENV EnvironmentHandle, + SQLINTEGER Attribute, SQLPOINTER Value, + SQLINTEGER StringLength); +typedef SQLRETURN (SQL_API *SQLSetPos_t)( + SQLHSTMT hstmt, + SQLSETPOSIROW irow, + SQLUSMALLINT fOption, + SQLUSMALLINT fLock); +typedef SQLRETURN (SQL_API *SQLSetScrollOptions_t)( + SQLHSTMT hstmt, + SQLUSMALLINT fConcurrency, + SQLLEN crowKeyset, + SQLUSMALLINT crowRowset); +typedef SQLRETURN (SQL_API *SQLSetStmtAttrW_t)( + SQLHSTMT hstmt, + SQLINTEGER fAttribute, + SQLPOINTER rgbValue, + SQLINTEGER cbValueMax); +typedef SQLRETURN (SQL_API *SQLSpecialColumnsW_t)( + SQLHSTMT hstmt, + SQLUSMALLINT fColType, + SQLWCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLWCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLWCHAR *szTableName, + SQLSMALLINT cbTableName, + SQLUSMALLINT fScope, + SQLUSMALLINT fNullable); +typedef SQLRETURN (SQL_API *SQLStatisticsW_t)( + SQLHSTMT hstmt, + SQLWCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLWCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLWCHAR *szTableName, + SQLSMALLINT cbTableName, + SQLUSMALLINT fUnique, + SQLUSMALLINT fAccuracy); +typedef SQLRETURN (SQL_API *SQLTablePrivilegesW_t)( + SQLHSTMT hstmt, + SQLWCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLWCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLWCHAR *szTableName, + SQLSMALLINT cbTableName); +typedef SQLRETURN (SQL_API *SQLTablesW_t)( + SQLHSTMT hstmt, + SQLWCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLWCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLWCHAR *szTableName, + SQLSMALLINT cbTableName, + SQLWCHAR *szTableType, + SQLSMALLINT cbTableType); + +#ifdef SQLAPI_WINDOWS +typedef HANDLE (_stdcall *OpenSqlFilestream_t) ( + LPCWSTR FilestreamPath, + SQL_FILESTREAM_DESIRED_ACCESS DesiredAccess, + ULONG OpenOptions, + LPBYTE FilestreamTransactionContext, + SSIZE_T FilestreamTransactionContextLength, + PLARGE_INTEGER AllocationSize); +#endif + +class SQLAPI_API ssNCliAPI : public saAPI +{ +public: + ssNCliAPI(); + + SQLAllocHandle_t SQLAllocHandle; // 3.0 + SQLBindCol_t SQLBindCol; // 1.0 + SQLBindParameter_t SQLBindParameter; // 2.0 + SQLBulkOperations_t SQLBulkOperations; // 3.0 + SQLBrowseConnectW_t SQLBrowseConnectW; // 3.0 + SQLCancel_t SQLCancel; // 1.0 + SQLCloseCursor_t SQLCloseCursor; // 3.0 + SQLColAttributeW_t SQLColAttributeW; + SQLColumnPrivilegesW_t SQLColumnPrivilegesW; + SQLColumnsW_t SQLColumnsW; + SQLConnectW_t SQLConnectW; + SQLCopyDesc_t SQLCopyDesc; // 3.0 + SQLDescribeColW_t SQLDescribeColW; // 1.0 + SQLDescribeParam_t SQLDescribeParam; // 1.0 + SQLDisconnect_t SQLDisconnect; // 1.0 + SQLDriverConnectW_t SQLDriverConnectW; // 1.0 + SQLEndTran_t SQLEndTran; // 3.0 + SQLExecDirectW_t SQLExecDirectW; + SQLExecute_t SQLExecute; // 1.0 + SQLExtendedFetch_t SQLExtendedFetch; // 1.0 + SQLFetch_t SQLFetch; // 1.0 + SQLFetchScroll_t SQLFetchScroll; // 1.0 + SQLForeignKeysW_t SQLForeignKeysW; + SQLFreeHandle_t SQLFreeHandle; // 3.0 + SQLFreeStmt_t SQLFreeStmt; // 1.0 + SQLGetConnectAttrW_t SQLGetConnectAttrW; // 3.0 + SQLGetConnectOptionW_t SQLGetConnectOptionW; + SQLGetCursorNameW_t SQLGetCursorNameW; + SQLGetData_t SQLGetData; // 1.0 + SQLGetDescFieldW_t SQLGetDescFieldW; + SQLGetDescRecW_t SQLGetDescRecW; + SQLGetDiagFieldW_t SQLGetDiagFieldW; + SQLGetDiagRecW_t SQLGetDiagRecW; // 3.0 + SQLGetEnvAttr_t SQLGetEnvAttr; // 3.0 + SQLGetFunctions_t SQLGetFunctions; // 1.0 + SQLGetInfoW_t SQLGetInfoW; // 1.0 + SQLGetStmtAttrW_t SQLGetStmtAttrW; // 3.0 + SQLGetTypeInfoW_t SQLGetTypeInfoW; + SQLMoreResults_t SQLMoreResults; // 1.0 + SQLNativeSqlW_t SQLNativeSqlW; + SQLNumParams_t SQLNumParams; // 1.0 + SQLNumResultCols_t SQLNumResultCols; // 1.0 + SQLParamData_t SQLParamData; // 1.0 + SQLParamOptions_t SQLParamOptions; // 1.0 + SQLPrepareW_t SQLPrepareW; // 1.0 + SQLPrimaryKeysW_t SQLPrimaryKeysW; + SQLProcedureColumnsW_t SQLProcedureColumnsW;// 1.0 + SQLProceduresW_t SQLProceduresW; // 1.0 + SQLPutData_t SQLPutData; // 1.0 + SQLRowCount_t SQLRowCount; // 1.0 + SQLSetConnectAttrW_t SQLSetConnectAttrW; // 3.0 + SQLSetConnectOptionW_t SQLSetConnectOptionW;// 1.0 + SQLSetCursorNameW_t SQLSetCursorNameW; // 1.0 + SQLSetDescFieldW_t SQLSetDescFieldW; // 3.0 + SQLSetDescRec_t SQLSetDescRec; // 3.0 + SQLSetEnvAttr_t SQLSetEnvAttr; // 3.0 + SQLSetPos_t SQLSetPos; // 1.0 + SQLSetScrollOptions_t SQLSetScrollOptions;// 1.0 + SQLSetStmtAttrW_t SQLSetStmtAttrW; // 3.0 + SQLSpecialColumnsW_t SQLSpecialColumnsW; // 1.0 + SQLStatisticsW_t SQLStatisticsW; // 1.0 + SQLTablePrivilegesW_t SQLTablePrivilegesW;// 1.0 + SQLTablesW_t SQLTablesW; // 1.0 + +#ifdef SQLAPI_WINDOWS + OpenSqlFilestream_t OpenSqlFilestream; +#endif +}; + +class SQLAPI_API ssNCliConnectionHandles : public saConnectionHandles +{ +public: + ssNCliConnectionHandles(); + + SQLHENV m_hevn; + SQLHDBC m_hdbc; +}; + +class SQLAPI_API ssNCliCommandHandles : public saCommandHandles +{ +public: + ssNCliCommandHandles(); + + SQLHSTMT m_hstmt; +}; + +extern ssNCliAPI g_ssNCliAPI; + +#endif // !defined(__SSNCLIAPI_H__) diff --git a/libodbc/include/ssOleDbAPI.h b/libodbc/include/ssOleDbAPI.h new file mode 100644 index 0000000000..a408522da4 --- /dev/null +++ b/libodbc/include/ssOleDbAPI.h @@ -0,0 +1,46 @@ +// ssOleDbAPI.h +// +////////////////////////////////////////////////////////////////////// + +#if !defined(__SSOLEDBAPI_H__) +#define __SSOLEDBAPI_H__ + +#include "SQLAPI.h" + +// API header(s) +#include + +extern void AddSSOleDbSupport(); +extern void ReleaseSSOleDbSupport(); + +// API declarations +class ssOleDbAPI : public saAPI +{ +public: + ssOleDbAPI(); +}; + +class SQLAPI_API ssOleDbConnectionHandles : public saConnectionHandles +{ +public: + ssOleDbConnectionHandles(); + + IDBInitialize *pIDBInitialize; + IDBCreateCommand *pIDBCreateCommand; + ITransactionLocal *pITransactionLocal; + IDBDataSourceAdmin *pIDBDataSourceAdmin; +}; + +class SQLAPI_API ssOleDbCommandHandles : public saCommandHandles +{ +public: + ssOleDbCommandHandles(); + + ICommandText *pICommandText; + IMultipleResults *pIMultipleResults; + IRowset *pIRowset; +}; + +extern ssOleDbAPI g_ssOleDbAPI; + +#endif // !defined(__SSOLEDBAPI_H__) diff --git a/libodbc/include/ss_linux/msodbcsql.h b/libodbc/include/ss_linux/msodbcsql.h new file mode 100644 index 0000000000..ca933f0a46 --- /dev/null +++ b/libodbc/include/ss_linux/msodbcsql.h @@ -0,0 +1,338 @@ +#ifndef __msodbcsql_h__ +#define __msodbcsql_h__ + +/* + *----------------------------------------------------------------------------- + * File: msodbcsql.h + * + * Copyright: Copyright (c) Microsoft Corporation + * + * Contents: This SDK is not supported under any Microsoft standard support + * program or service. The information is provided AS IS without + * warranty of any kind. Microsoft disclaims all implied + * warranties including, without limitation, any implied + * warranties of merchantability or of fitness for a particular + * purpose. The entire risk arising out of the use of this SDK + * remains with you. In no event shall Microsoft, its authors, or + * anyone else involved in the creation, production, or delivery + * of this SDK be liable for any damages whatsoever (including, + * without limitation, damages for loss of business profits, + * business interruption, loss of business information, or other + * pecuniary loss) arising out of the use of or inability to use + * this SDK, even if Microsoft has been advised of the possibility + * of such damages. + * + *----------------------------------------------------------------------------- + */ + +#if !defined(SQLODBC_VER) +#define SQLODBC_VER 1100 +#endif + +#if SQLODBC_VER >= 1100 + +#define SQLODBC_PRODUCT_NAME_FULL_VER_ANSI "Microsoft ODBC Driver 11 for SQL Server" +#define SQLODBC_PRODUCT_NAME_FULL_ANSI "Microsoft ODBC Driver for SQL Server" +#define SQLODBC_PRODUCT_NAME_SHORT_VER_ANSI "ODBC Driver 11 for SQL Server" +#define SQLODBC_PRODUCT_NAME_SHORT_ANSI "ODBC Driver for SQL Server" + +#endif /* SQLODBC_VER >= 1100 */ + +#define SQLODBC_PRODUCT_NAME_FULL_VER SQLODBC_PRODUCT_NAME_FULL_VER_ANSI +#define SQLODBC_PRODUCT_NAME_FULL SQLODBC_PRODUCT_NAME_FULL_ANSI +#define SQLODBC_PRODUCT_NAME_SHORT_VER SQLODBC_PRODUCT_NAME_SHORT_VER_ANSI +#define SQLODBC_PRODUCT_NAME_SHORT SQLODBC_PRODUCT_NAME_SHORT_ANSI + +#define SQLODBC_DRIVER_NAME SQLODBC_PRODUCT_NAME_SHORT_VER + +/* max SQL Server identifier length */ +#define SQL_MAX_SQLSERVERNAME 128 + +/* + * SQLSetConnectAttr driver specific defines. + * Microsoft has 1200 thru 1249 reserved for Microsoft ODBC Driver for SQL Server usage. + * Connection attributes + */ +#define SQL_COPT_SS_BASE 1200 +#define SQL_COPT_SS_INTEGRATED_SECURITY (SQL_COPT_SS_BASE+3) /* Force integrated security on login */ +#define SQL_COPT_SS_TRANSLATE (SQL_COPT_SS_BASE+20) /* Perform code page translation */ +#define SQL_COPT_SS_ENCRYPT (SQL_COPT_SS_BASE+23) /* Allow strong encryption for data */ +#define SQL_COPT_SS_MARS_ENABLED (SQL_COPT_SS_BASE+24) /* Multiple active result set per connection */ +#define SQL_COPT_SS_TXN_ISOLATION (SQL_COPT_SS_BASE+27) /* Used to set/get any driver-specific or ODBC-defined TXN iso level */ +#define SQL_COPT_SS_TRUST_SERVER_CERTIFICATE (SQL_COPT_SS_BASE+28) /* Trust server certificate */ + +/* + * SQLSetStmtAttr Microsoft ODBC Driver for SQL Server specific defines. + * Statement attributes + */ +#define SQL_SOPT_SS_BASE 1225 +#define SQL_SOPT_SS_TEXTPTR_LOGGING (SQL_SOPT_SS_BASE+0) /* Text pointer logging */ +#define SQL_SOPT_SS_NOBROWSETABLE (SQL_SOPT_SS_BASE+3) /* Set NOBROWSETABLE option */ +/* Define old names */ +#define SQL_TEXTPTR_LOGGING SQL_SOPT_SS_TEXTPTR_LOGGING +#define SQL_COPT_SS_BASE_EX 1240 +#define SQL_COPT_SS_WARN_ON_CP_ERROR (SQL_COPT_SS_BASE_EX+3) /* Issues warning when data from the server had a loss during code page conversion. */ +#define SQL_COPT_SS_CONNECTION_DEAD (SQL_COPT_SS_BASE_EX+4) /* dbdead SQLGetConnectOption only. It will try to ping the server. Expensive connection check */ +#define SQL_COPT_SS_APPLICATION_INTENT (SQL_COPT_SS_BASE_EX+7) /* Application Intent */ +#define SQL_COPT_SS_MULTISUBNET_FAILOVER (SQL_COPT_SS_BASE_EX+8) /* Multi-subnet Failover */ + +/* + * SQLColAttributes driver specific defines. + * SQLSetDescField/SQLGetDescField driver specific defines. + * Microsoft has 1200 thru 1249 reserved for Microsoft ODBC Driver for SQL Server usage. + */ +#define SQL_CA_SS_BASE 1200 +#define SQL_CA_SS_COLUMN_SSTYPE (SQL_CA_SS_BASE+0) /* dbcoltype/dbalttype */ +#define SQL_CA_SS_COLUMN_UTYPE (SQL_CA_SS_BASE+1) /* dbcolutype/dbaltutype */ +#define SQL_CA_SS_NUM_ORDERS (SQL_CA_SS_BASE+2) /* dbnumorders */ +#define SQL_CA_SS_COLUMN_ORDER (SQL_CA_SS_BASE+3) /* dbordercol */ +#define SQL_CA_SS_COLUMN_VARYLEN (SQL_CA_SS_BASE+4) /* dbvarylen */ +#define SQL_CA_SS_NUM_COMPUTES (SQL_CA_SS_BASE+5) /* dbnumcompute */ +#define SQL_CA_SS_COMPUTE_ID (SQL_CA_SS_BASE+6) /* dbnextrow status return */ +#define SQL_CA_SS_COMPUTE_BYLIST (SQL_CA_SS_BASE+7) /* dbbylist */ +#define SQL_CA_SS_COLUMN_ID (SQL_CA_SS_BASE+8) /* dbaltcolid */ +#define SQL_CA_SS_COLUMN_OP (SQL_CA_SS_BASE+9) /* dbaltop */ +#define SQL_CA_SS_COLUMN_SIZE (SQL_CA_SS_BASE+10) /* dbcollen */ +#define SQL_CA_SS_COLUMN_HIDDEN (SQL_CA_SS_BASE+11) /* Column is hidden (FOR BROWSE) */ +#define SQL_CA_SS_COLUMN_KEY (SQL_CA_SS_BASE+12) /* Column is key column (FOR BROWSE) */ +#define SQL_CA_SS_COLUMN_COLLATION (SQL_CA_SS_BASE+14) /* Column collation (only for chars) */ +#define SQL_CA_SS_VARIANT_TYPE (SQL_CA_SS_BASE+15) +#define SQL_CA_SS_VARIANT_SQL_TYPE (SQL_CA_SS_BASE+16) +#define SQL_CA_SS_VARIANT_SERVER_TYPE (SQL_CA_SS_BASE+17) + +/* XML, CLR UDT, and table valued parameter related metadata */ +#define SQL_CA_SS_UDT_CATALOG_NAME (SQL_CA_SS_BASE+18) /* UDT catalog name */ +#define SQL_CA_SS_UDT_SCHEMA_NAME (SQL_CA_SS_BASE+19) /* UDT schema name */ +#define SQL_CA_SS_UDT_TYPE_NAME (SQL_CA_SS_BASE+20) /* UDT type name */ +#define SQL_CA_SS_XML_SCHEMACOLLECTION_CATALOG_NAME (SQL_CA_SS_BASE+22) /* Name of the catalog that contains XML Schema collection */ +#define SQL_CA_SS_XML_SCHEMACOLLECTION_SCHEMA_NAME (SQL_CA_SS_BASE+23) /* Name of the schema that contains XML Schema collection */ +#define SQL_CA_SS_XML_SCHEMACOLLECTION_NAME (SQL_CA_SS_BASE+24) /* Name of the XML Schema collection */ +#define SQL_CA_SS_CATALOG_NAME (SQL_CA_SS_BASE+25) /* Catalog name */ +#define SQL_CA_SS_SCHEMA_NAME (SQL_CA_SS_BASE+26) /* Schema name */ +#define SQL_CA_SS_TYPE_NAME (SQL_CA_SS_BASE+27) /* Type name */ + +/* table valued parameter related metadata */ +#define SQL_CA_SS_COLUMN_COMPUTED (SQL_CA_SS_BASE+29) /* column is computed */ +#define SQL_CA_SS_COLUMN_IN_UNIQUE_KEY (SQL_CA_SS_BASE+30) /* column is part of a unique key */ +#define SQL_CA_SS_COLUMN_SORT_ORDER (SQL_CA_SS_BASE+31) /* column sort order */ +#define SQL_CA_SS_COLUMN_SORT_ORDINAL (SQL_CA_SS_BASE+32) /* column sort ordinal */ +#define SQL_CA_SS_COLUMN_HAS_DEFAULT_VALUE (SQL_CA_SS_BASE+33) /* column has default value for all rows of the table valued parameter */ + +/* sparse column related metadata */ +#define SQL_CA_SS_IS_COLUMN_SET (SQL_CA_SS_BASE+34) /* column is a column-set column for sparse columns */ + +/* Legacy datetime related metadata */ +#define SQL_CA_SS_SERVER_TYPE (SQL_CA_SS_BASE+35) /* column type to send on the wire for datetime types */ + +/* Defines for use with SQL_COPT_SS_INTEGRATED_SECURITY - Pre-Connect Option only */ +#define SQL_IS_OFF 0L /* Integrated security isn't used */ +#define SQL_IS_ON 1L /* Integrated security is used */ +#define SQL_IS_DEFAULT SQL_IS_OFF +/* Defines for use with SQL_COPT_SS_TRANSLATE */ +#define SQL_XL_OFF 0L /* Code page translation is not performed */ +#define SQL_XL_ON 1L /* Code page translation is performed */ +#define SQL_XL_DEFAULT SQL_XL_ON +/* Defines for use with SQL_SOPT_SS_TEXTPTR_LOGGING */ +#define SQL_TL_OFF 0L /* No logging on text pointer ops */ +#define SQL_TL_ON 1L /* Logging occurs on text pointer ops */ +#define SQL_TL_DEFAULT SQL_TL_ON +/* Defines for use with SQL_SOPT_SS_NOBROWSETABLE */ +#define SQL_NB_OFF 0L /* NO_BROWSETABLE is off */ +#define SQL_NB_ON 1L /* NO_BROWSETABLE is on */ +#define SQL_NB_DEFAULT SQL_NB_OFF +/* SQL_COPT_SS_ENCRYPT */ +#define SQL_EN_OFF 0L +#define SQL_EN_ON 1L +/* SQL_COPT_SS_TRUST_SERVER_CERTIFICATE */ +#define SQL_TRUST_SERVER_CERTIFICATE_NO 0L +#define SQL_TRUST_SERVER_CERTIFICATE_YES 1L +/* SQL_COPT_SS_WARN_ON_CP_ERROR */ +#define SQL_WARN_NO 0L +#define SQL_WARN_YES 1L +/* SQL_COPT_SS_MARS_ENABLED */ +#define SQL_MARS_ENABLED_NO 0L +#define SQL_MARS_ENABLED_YES 1L +/* SQL_TXN_ISOLATION_OPTION bitmasks */ +#define SQL_TXN_SS_SNAPSHOT 0x00000020L + +/* The following are defines for SQL_CA_SS_COLUMN_SORT_ORDER */ +#define SQL_SS_ORDER_UNSPECIFIED 0L +#define SQL_SS_DESCENDING_ORDER 1L +#define SQL_SS_ASCENDING_ORDER 2L +#define SQL_SS_ORDER_DEFAULT SQL_SS_ORDER_UNSPECIFIED + +/* + * Driver specific SQL data type defines. + * Microsoft has -150 thru -199 reserved for Microsoft ODBC Driver for SQL Server usage. + */ +#define SQL_SS_VARIANT (-150) +#define SQL_SS_UDT (-151) +#define SQL_SS_XML (-152) +#define SQL_SS_TABLE (-153) +#define SQL_SS_TIME2 (-154) +#define SQL_SS_TIMESTAMPOFFSET (-155) + +/* Local types to be used with SQL_CA_SS_SERVER_TYPE */ +#define SQL_SS_TYPE_DEFAULT 0L +#define SQL_SS_TYPE_SMALLDATETIME 1L +#define SQL_SS_TYPE_DATETIME 2L + +/* Extended C Types range 4000 and above. Range of -100 thru 200 is reserved by Driver Manager. */ +#define SQL_C_TYPES_EXTENDED 0x04000L + +/* + * SQL_SS_LENGTH_UNLIMITED is used to describe the max length of + * VARCHAR(max), VARBINARY(max), NVARCHAR(max), and XML columns + */ +#define SQL_SS_LENGTH_UNLIMITED 0 + +/* + * User Data Type definitions. + * Returned by SQLColAttributes/SQL_CA_SS_COLUMN_UTYPE. + */ +#define SQLudtBINARY 3 +#define SQLudtBIT 16 +#define SQLudtBITN 0 +#define SQLudtCHAR 1 +#define SQLudtDATETIM4 22 +#define SQLudtDATETIME 12 +#define SQLudtDATETIMN 15 +#define SQLudtDECML 24 +#define SQLudtDECMLN 26 +#define SQLudtFLT4 23 +#define SQLudtFLT8 8 +#define SQLudtFLTN 14 +#define SQLudtIMAGE 20 +#define SQLudtINT1 5 +#define SQLudtINT2 6 +#define SQLudtINT4 7 +#define SQLudtINTN 13 +#define SQLudtMONEY 11 +#define SQLudtMONEY4 21 +#define SQLudtMONEYN 17 +#define SQLudtNUM 10 +#define SQLudtNUMN 25 +#define SQLudtSYSNAME 18 +#define SQLudtTEXT 19 +#define SQLudtTIMESTAMP 80 +#define SQLudtUNIQUEIDENTIFIER 0 +#define SQLudtVARBINARY 4 +#define SQLudtVARCHAR 2 +#define MIN_USER_DATATYPE 256 +/* + * Aggregate operator types. + * Returned by SQLColAttributes/SQL_CA_SS_COLUMN_OP. + */ +#define SQLAOPSTDEV 0x30 /* Standard deviation */ +#define SQLAOPSTDEVP 0x31 /* Standard deviation population */ +#define SQLAOPVAR 0x32 /* Variance */ +#define SQLAOPVARP 0x33 /* Variance population */ +#define SQLAOPCNT 0x4b /* Count */ +#define SQLAOPSUM 0x4d /* Sum */ +#define SQLAOPAVG 0x4f /* Average */ +#define SQLAOPMIN 0x51 /* Min */ +#define SQLAOPMAX 0x52 /* Max */ +#define SQLAOPANY 0x53 /* Any */ +#define SQLAOPNOOP 0x56 /* None */ +/* + * SQLGetDiagField driver specific defines. + * Microsoft has -1150 thru -1199 reserved for Microsoft ODBC Driver for SQL Server usage. + */ +#define SQL_DIAG_SS_BASE (-1150) +#define SQL_DIAG_SS_MSGSTATE (SQL_DIAG_SS_BASE) +#define SQL_DIAG_SS_SEVERITY (SQL_DIAG_SS_BASE-1) +#define SQL_DIAG_SS_SRVNAME (SQL_DIAG_SS_BASE-2) +#define SQL_DIAG_SS_PROCNAME (SQL_DIAG_SS_BASE-3) +#define SQL_DIAG_SS_LINE (SQL_DIAG_SS_BASE-4) +/* + * SQLGetDiagField/SQL_DIAG_DYNAMIC_FUNCTION_CODE driver specific defines. + * Microsoft has -200 thru -299 reserved for Microsoft ODBC Driver for SQL Server usage. + */ +#define SQL_DIAG_DFC_SS_BASE (-200) +#define SQL_DIAG_DFC_SS_ALTER_DATABASE (SQL_DIAG_DFC_SS_BASE-0) +#define SQL_DIAG_DFC_SS_CHECKPOINT (SQL_DIAG_DFC_SS_BASE-1) +#define SQL_DIAG_DFC_SS_CONDITION (SQL_DIAG_DFC_SS_BASE-2) +#define SQL_DIAG_DFC_SS_CREATE_DATABASE (SQL_DIAG_DFC_SS_BASE-3) +#define SQL_DIAG_DFC_SS_CREATE_DEFAULT (SQL_DIAG_DFC_SS_BASE-4) +#define SQL_DIAG_DFC_SS_CREATE_PROCEDURE (SQL_DIAG_DFC_SS_BASE-5) +#define SQL_DIAG_DFC_SS_CREATE_RULE (SQL_DIAG_DFC_SS_BASE-6) +#define SQL_DIAG_DFC_SS_CREATE_TRIGGER (SQL_DIAG_DFC_SS_BASE-7) +#define SQL_DIAG_DFC_SS_CURSOR_DECLARE (SQL_DIAG_DFC_SS_BASE-8) +#define SQL_DIAG_DFC_SS_CURSOR_OPEN (SQL_DIAG_DFC_SS_BASE-9) +#define SQL_DIAG_DFC_SS_CURSOR_FETCH (SQL_DIAG_DFC_SS_BASE-10) +#define SQL_DIAG_DFC_SS_CURSOR_CLOSE (SQL_DIAG_DFC_SS_BASE-11) +#define SQL_DIAG_DFC_SS_DEALLOCATE_CURSOR (SQL_DIAG_DFC_SS_BASE-12) +#define SQL_DIAG_DFC_SS_DBCC (SQL_DIAG_DFC_SS_BASE-13) +#define SQL_DIAG_DFC_SS_DISK (SQL_DIAG_DFC_SS_BASE-14) +#define SQL_DIAG_DFC_SS_DROP_DATABASE (SQL_DIAG_DFC_SS_BASE-15) +#define SQL_DIAG_DFC_SS_DROP_DEFAULT (SQL_DIAG_DFC_SS_BASE-16) +#define SQL_DIAG_DFC_SS_DROP_PROCEDURE (SQL_DIAG_DFC_SS_BASE-17) +#define SQL_DIAG_DFC_SS_DROP_RULE (SQL_DIAG_DFC_SS_BASE-18) +#define SQL_DIAG_DFC_SS_DROP_TRIGGER (SQL_DIAG_DFC_SS_BASE-19) +#define SQL_DIAG_DFC_SS_DUMP_DATABASE (SQL_DIAG_DFC_SS_BASE-20) +#define SQL_DIAG_DFC_SS_BACKUP_DATABASE (SQL_DIAG_DFC_SS_BASE-20) +#define SQL_DIAG_DFC_SS_DUMP_TABLE (SQL_DIAG_DFC_SS_BASE-21) +#define SQL_DIAG_DFC_SS_DUMP_TRANSACTION (SQL_DIAG_DFC_SS_BASE-22) +#define SQL_DIAG_DFC_SS_BACKUP_TRANSACTION (SQL_DIAG_DFC_SS_BASE-22) +#define SQL_DIAG_DFC_SS_GOTO (SQL_DIAG_DFC_SS_BASE-23) +#define SQL_DIAG_DFC_SS_INSERT_BULK (SQL_DIAG_DFC_SS_BASE-24) +#define SQL_DIAG_DFC_SS_KILL (SQL_DIAG_DFC_SS_BASE-25) +#define SQL_DIAG_DFC_SS_LOAD_DATABASE (SQL_DIAG_DFC_SS_BASE-26) +#define SQL_DIAG_DFC_SS_RESTORE_DATABASE (SQL_DIAG_DFC_SS_BASE-26) +#define SQL_DIAG_DFC_SS_LOAD_HEADERONLY (SQL_DIAG_DFC_SS_BASE-27) +#define SQL_DIAG_DFC_SS_RESTORE_HEADERONLY (SQL_DIAG_DFC_SS_BASE-27) +#define SQL_DIAG_DFC_SS_LOAD_TABLE (SQL_DIAG_DFC_SS_BASE-28) +#define SQL_DIAG_DFC_SS_LOAD_TRANSACTION (SQL_DIAG_DFC_SS_BASE-29) +#define SQL_DIAG_DFC_SS_RESTORE_TRANSACTION (SQL_DIAG_DFC_SS_BASE-29) +#define SQL_DIAG_DFC_SS_PRINT (SQL_DIAG_DFC_SS_BASE-30) +#define SQL_DIAG_DFC_SS_RAISERROR (SQL_DIAG_DFC_SS_BASE-31) +#define SQL_DIAG_DFC_SS_READTEXT (SQL_DIAG_DFC_SS_BASE-32) +#define SQL_DIAG_DFC_SS_RECONFIGURE (SQL_DIAG_DFC_SS_BASE-33) +#define SQL_DIAG_DFC_SS_RETURN (SQL_DIAG_DFC_SS_BASE-34) +#define SQL_DIAG_DFC_SS_SELECT_INTO (SQL_DIAG_DFC_SS_BASE-35) +#define SQL_DIAG_DFC_SS_SET (SQL_DIAG_DFC_SS_BASE-36) +#define SQL_DIAG_DFC_SS_SET_IDENTITY_INSERT (SQL_DIAG_DFC_SS_BASE-37) +#define SQL_DIAG_DFC_SS_SET_ROW_COUNT (SQL_DIAG_DFC_SS_BASE-38) +#define SQL_DIAG_DFC_SS_SET_STATISTICS (SQL_DIAG_DFC_SS_BASE-39) +#define SQL_DIAG_DFC_SS_SET_TEXTSIZE (SQL_DIAG_DFC_SS_BASE-40) +#define SQL_DIAG_DFC_SS_SETUSER (SQL_DIAG_DFC_SS_BASE-41) +#define SQL_DIAG_DFC_SS_SHUTDOWN (SQL_DIAG_DFC_SS_BASE-42) +#define SQL_DIAG_DFC_SS_TRANS_BEGIN (SQL_DIAG_DFC_SS_BASE-43) +#define SQL_DIAG_DFC_SS_TRANS_COMMIT (SQL_DIAG_DFC_SS_BASE-44) +#define SQL_DIAG_DFC_SS_TRANS_PREPARE (SQL_DIAG_DFC_SS_BASE-45) +#define SQL_DIAG_DFC_SS_TRANS_ROLLBACK (SQL_DIAG_DFC_SS_BASE-46) +#define SQL_DIAG_DFC_SS_TRANS_SAVE (SQL_DIAG_DFC_SS_BASE-47) +#define SQL_DIAG_DFC_SS_TRUNCATE_TABLE (SQL_DIAG_DFC_SS_BASE-48) +#define SQL_DIAG_DFC_SS_UPDATE_STATISTICS (SQL_DIAG_DFC_SS_BASE-49) +#define SQL_DIAG_DFC_SS_UPDATETEXT (SQL_DIAG_DFC_SS_BASE-50) +#define SQL_DIAG_DFC_SS_USE (SQL_DIAG_DFC_SS_BASE-51) +#define SQL_DIAG_DFC_SS_WAITFOR (SQL_DIAG_DFC_SS_BASE-52) +#define SQL_DIAG_DFC_SS_WRITETEXT (SQL_DIAG_DFC_SS_BASE-53) +#define SQL_DIAG_DFC_SS_DENY (SQL_DIAG_DFC_SS_BASE-54) +#define SQL_DIAG_DFC_SS_SET_XCTLVL (SQL_DIAG_DFC_SS_BASE-55) +#define SQL_DIAG_DFC_SS_MERGE (SQL_DIAG_DFC_SS_BASE-56) + +/* Severity codes for SQL_DIAG_SS_SEVERITY */ +#define EX_ANY 0 +#define EX_INFO 10 +#define EX_MAXISEVERITY EX_INFO +#define EX_MISSING 11 +#define EX_TYPE 12 +#define EX_DEADLOCK 13 +#define EX_PERMIT 14 +#define EX_SYNTAX 15 +#define EX_USER 16 +#define EX_RESOURCE 17 +#define EX_INTOK 18 +#define MAXUSEVERITY EX_INTOK +#define EX_LIMIT 19 +#define EX_CMDFATAL 20 +#define MINFATALERR EX_CMDFATAL +#define EX_DBFATAL 21 +#define EX_TABCORRUPT 22 +#define EX_DBCORRUPT 23 +#define EX_HARDWARE 24 +#define EX_CONTROL 25 + +#endif /* __msodbcsql_h__ */ + diff --git a/libodbc/include/ss_linux/sql.h b/libodbc/include/ss_linux/sql.h new file mode 100644 index 0000000000..7c736401d1 --- /dev/null +++ b/libodbc/include/ss_linux/sql.h @@ -0,0 +1,824 @@ +/************************************************** + * sql.h + * + * These should be consistent with the MS version. + * + **************************************************/ +#ifndef __SQL_H +#define __SQL_H + + +/**************************** + * default to 3.51 declare something else before here and you get a whole new ball of wax + ***************************/ +#ifndef ODBCVER +#define ODBCVER 0x0351 +#endif + +#ifndef __SQLTYPES_H +#include "sqltypes.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/**************************** + * some ret values + ***************************/ +#define SQL_NULL_DATA (-1) +#define SQL_DATA_AT_EXEC (-2) +#define SQL_SUCCESS 0 +#define SQL_SUCCESS_WITH_INFO 1 +#if (ODBCVER >= 0x0300) +#define SQL_NO_DATA 100 +#endif +#define SQL_ERROR (-1) +#define SQL_INVALID_HANDLE (-2) +#define SQL_STILL_EXECUTING 2 +#define SQL_NEED_DATA 99 +#define SQL_SUCCEEDED(rc) (((rc)&(~1))==0) + +/**************************** + * use these to indicate string termination to some function + ***************************/ +#define SQL_NTS (-3) +#define SQL_NTSL (-3L) + +/* maximum message length */ +#define SQL_MAX_MESSAGE_LENGTH 512 + +/* date/time length constants */ +#if (ODBCVER >= 0x0300) +#define SQL_DATE_LEN 10 +#define SQL_TIME_LEN 8 /* add P+1 if precision is nonzero */ +#define SQL_TIMESTAMP_LEN 19 /* add P+1 if precision is nonzero */ +#endif + +/* handle type identifiers */ +#if (ODBCVER >= 0x0300) +#define SQL_HANDLE_ENV 1 +#define SQL_HANDLE_DBC 2 +#define SQL_HANDLE_STMT 3 +#define SQL_HANDLE_DESC 4 +#endif + +/* environment attribute */ +#if (ODBCVER >= 0x0300) +#define SQL_ATTR_OUTPUT_NTS 10001 +#endif + +/* connection attributes */ +#if (ODBCVER >= 0x0300) +#define SQL_ATTR_AUTO_IPD 10001 +#define SQL_ATTR_METADATA_ID 10014 +#endif /* ODBCVER >= 0x0300 */ + +/* statement attributes */ +#if (ODBCVER >= 0x0300) +#define SQL_ATTR_APP_ROW_DESC 10010 +#define SQL_ATTR_APP_PARAM_DESC 10011 +#define SQL_ATTR_IMP_ROW_DESC 10012 +#define SQL_ATTR_IMP_PARAM_DESC 10013 +#define SQL_ATTR_CURSOR_SCROLLABLE (-1) +#define SQL_ATTR_CURSOR_SENSITIVITY (-2) +#endif + +/* SQL_ATTR_CURSOR_SCROLLABLE values */ +#if (ODBCVER >= 0x0300) +#define SQL_NONSCROLLABLE 0 +#define SQL_SCROLLABLE 1 +#endif /* ODBCVER >= 0x0300 */ + +/* identifiers of fields in the SQL descriptor */ +#if (ODBCVER >= 0x0300) +#define SQL_DESC_COUNT 1001 +#define SQL_DESC_TYPE 1002 +#define SQL_DESC_LENGTH 1003 +#define SQL_DESC_OCTET_LENGTH_PTR 1004 +#define SQL_DESC_PRECISION 1005 +#define SQL_DESC_SCALE 1006 +#define SQL_DESC_DATETIME_INTERVAL_CODE 1007 +#define SQL_DESC_NULLABLE 1008 +#define SQL_DESC_INDICATOR_PTR 1009 +#define SQL_DESC_DATA_PTR 1010 +#define SQL_DESC_NAME 1011 +#define SQL_DESC_UNNAMED 1012 +#define SQL_DESC_OCTET_LENGTH 1013 +#define SQL_DESC_ALLOC_TYPE 1099 +#endif + +/* identifiers of fields in the diagnostics area */ +#if (ODBCVER >= 0x0300) +#define SQL_DIAG_RETURNCODE 1 +#define SQL_DIAG_NUMBER 2 +#define SQL_DIAG_ROW_COUNT 3 +#define SQL_DIAG_SQLSTATE 4 +#define SQL_DIAG_NATIVE 5 +#define SQL_DIAG_MESSAGE_TEXT 6 +#define SQL_DIAG_DYNAMIC_FUNCTION 7 +#define SQL_DIAG_CLASS_ORIGIN 8 +#define SQL_DIAG_SUBCLASS_ORIGIN 9 +#define SQL_DIAG_CONNECTION_NAME 10 +#define SQL_DIAG_SERVER_NAME 11 +#define SQL_DIAG_DYNAMIC_FUNCTION_CODE 12 +#endif + +/* dynamic function codes */ +#if (ODBCVER >= 0x0300) +#define SQL_DIAG_ALTER_DOMAIN 3 +#define SQL_DIAG_ALTER_TABLE 4 +#define SQL_DIAG_CALL 7 +#define SQL_DIAG_CREATE_ASSERTION 6 +#define SQL_DIAG_CREATE_CHARACTER_SET 8 +#define SQL_DIAG_CREATE_COLLATION 10 +#define SQL_DIAG_CREATE_DOMAIN 23 +#define SQL_DIAG_CREATE_INDEX (-1) +#define SQL_DIAG_CREATE_SCHEMA 64 +#define SQL_DIAG_CREATE_TABLE 77 +#define SQL_DIAG_CREATE_TRANSLATION 79 +#define SQL_DIAG_CREATE_VIEW 84 +#define SQL_DIAG_DELETE_WHERE 19 +#define SQL_DIAG_DROP_ASSERTION 24 +#define SQL_DIAG_DROP_CHARACTER_SET 25 +#define SQL_DIAG_DROP_COLLATION 26 +#define SQL_DIAG_DROP_DOMAIN 27 +#define SQL_DIAG_DROP_INDEX (-2) +#define SQL_DIAG_DROP_SCHEMA 31 +#define SQL_DIAG_DROP_TABLE 32 +#define SQL_DIAG_DROP_TRANSLATION 33 +#define SQL_DIAG_DROP_VIEW 36 +#define SQL_DIAG_DYNAMIC_DELETE_CURSOR 38 +#define SQL_DIAG_DYNAMIC_UPDATE_CURSOR 81 +#define SQL_DIAG_GRANT 48 +#define SQL_DIAG_INSERT 50 +#define SQL_DIAG_REVOKE 59 +#define SQL_DIAG_SELECT_CURSOR 85 +#define SQL_DIAG_UNKNOWN_STATEMENT 0 +#define SQL_DIAG_UPDATE_WHERE 82 +#endif /* ODBCVER >= 0x0300 */ + +/* SQL data type codes */ +#define SQL_UNKNOWN_TYPE 0 +#define SQL_CHAR 1 +#define SQL_NUMERIC 2 +#define SQL_DECIMAL 3 +#define SQL_INTEGER 4 +#define SQL_SMALLINT 5 +#define SQL_FLOAT 6 +#define SQL_REAL 7 +#define SQL_DOUBLE 8 +#if (ODBCVER >= 0x0300) +#define SQL_DATETIME 9 +#endif +#define SQL_VARCHAR 12 + +/* One-parameter shortcuts for date/time data types */ +#if (ODBCVER >= 0x0300) +#define SQL_TYPE_DATE 91 +#define SQL_TYPE_TIME 92 +#define SQL_TYPE_TIMESTAMP 93 +#endif + +/* Statement attribute values for cursor sensitivity */ +#if (ODBCVER >= 0x0300) +#define SQL_UNSPECIFIED 0 +#define SQL_INSENSITIVE 1 +#define SQL_SENSITIVE 2 +#endif + +/* GetTypeInfo() request for all data types */ +#define SQL_ALL_TYPES 0 + +/* Default conversion code for SQLBindCol(), SQLBindParam() and SQLGetData() */ +#if (ODBCVER >= 0x0300) +#define SQL_DEFAULT 99 +#endif + +/* SQLGetData() code indicating that the application row descriptor + * specifies the data type + */ +#if (ODBCVER >= 0x0300) +#define SQL_ARD_TYPE (-99) +#endif + +/* SQL date/time type subcodes */ +#if (ODBCVER >= 0x0300) +#define SQL_CODE_DATE 1 +#define SQL_CODE_TIME 2 +#define SQL_CODE_TIMESTAMP 3 +#endif + +/* CLI option values */ +#if (ODBCVER >= 0x0300) +#define SQL_FALSE 0 +#define SQL_TRUE 1 +#endif + +/* values of NULLABLE field in descriptor */ +#define SQL_NO_NULLS 0 +#define SQL_NULLABLE 1 + +/* Value returned by SQLGetTypeInfo() to denote that it is + * not known whether or not a data type supports null values. + */ +#define SQL_NULLABLE_UNKNOWN 2 + +/* Values returned by SQLGetTypeInfo() to show WHERE clause + * supported + */ +#if (ODBCVER >= 0x0300) +#define SQL_PRED_NONE 0 +#define SQL_PRED_CHAR 1 +#define SQL_PRED_BASIC 2 +#endif + +/* values of UNNAMED field in descriptor */ +#if (ODBCVER >= 0x0300) +#define SQL_NAMED 0 +#define SQL_UNNAMED 1 +#endif + +/* values of ALLOC_TYPE field in descriptor */ +#if (ODBCVER >= 0x0300) +#define SQL_DESC_ALLOC_AUTO 1 +#define SQL_DESC_ALLOC_USER 2 +#endif + +/* FreeStmt() options */ +#define SQL_CLOSE 0 +#define SQL_DROP 1 +#define SQL_UNBIND 2 +#define SQL_RESET_PARAMS 3 + +/* Codes used for FetchOrientation in SQLFetchScroll(), + and in SQLDataSources() +*/ +#define SQL_FETCH_NEXT 1 +#define SQL_FETCH_FIRST 2 + +/* Other codes used for FetchOrientation in SQLFetchScroll() */ +#define SQL_FETCH_LAST 3 +#define SQL_FETCH_PRIOR 4 +#define SQL_FETCH_ABSOLUTE 5 +#define SQL_FETCH_RELATIVE 6 + +/* SQLEndTran() options */ +#define SQL_COMMIT 0 +#define SQL_ROLLBACK 1 + +/* null handles returned by SQLAllocHandle() */ +#define SQL_NULL_HENV 0 +#define SQL_NULL_HDBC 0 +#define SQL_NULL_HSTMT 0 +#if (ODBCVER >= 0x0300) +#define SQL_NULL_HDESC 0 +#define SQL_NULL_DESC 0 +#endif + +/* null handle used in place of parent handle when allocating HENV */ +#if (ODBCVER >= 0x0300) +#define SQL_NULL_HANDLE 0L +#endif + +/* Values that may appear in the result set of SQLSpecialColumns() */ +#define SQL_SCOPE_CURROW 0 +#define SQL_SCOPE_TRANSACTION 1 +#define SQL_SCOPE_SESSION 2 + +#define SQL_PC_UNKNOWN 0 +#if (ODBCVER >= 0x0300) +#define SQL_PC_NON_PSEUDO 1 +#endif +#define SQL_PC_PSEUDO 2 + +/* Reserved value for the IdentifierType argument of SQLSpecialColumns() */ +#if (ODBCVER >= 0x0300) +#define SQL_ROW_IDENTIFIER 1 +#endif + +/* Reserved values for UNIQUE argument of SQLStatistics() */ +#define SQL_INDEX_UNIQUE 0 +#define SQL_INDEX_ALL 1 + +/* Values that may appear in the result set of SQLStatistics() */ +#define SQL_INDEX_CLUSTERED 1 +#define SQL_INDEX_HASHED 2 +#define SQL_INDEX_OTHER 3 + +/* SQLGetFunctions() values to identify ODBC APIs */ +#define SQL_API_SQLALLOCCONNECT 1 +#define SQL_API_SQLALLOCENV 2 +#if (ODBCVER >= 0x0300) +#define SQL_API_SQLALLOCHANDLE 1001 +#endif +#define SQL_API_SQLALLOCSTMT 3 +#define SQL_API_SQLBINDCOL 4 +#if (ODBCVER >= 0x0300) +#define SQL_API_SQLBINDPARAM 1002 +#endif +#define SQL_API_SQLCANCEL 5 +#if (ODBCVER >= 0x0300) +#define SQL_API_SQLCLOSECURSOR 1003 +#define SQL_API_SQLCOLATTRIBUTE 6 +#endif +#define SQL_API_SQLCOLUMNS 40 +#define SQL_API_SQLCONNECT 7 +#if (ODBCVER >= 0x0300) +#define SQL_API_SQLCOPYDESC 1004 +#endif +#define SQL_API_SQLDATASOURCES 57 +#define SQL_API_SQLDESCRIBECOL 8 +#define SQL_API_SQLDISCONNECT 9 +#if (ODBCVER >= 0x0300) +#define SQL_API_SQLENDTRAN 1005 +#endif +#define SQL_API_SQLERROR 10 +#define SQL_API_SQLEXECDIRECT 11 +#define SQL_API_SQLEXECUTE 12 +#define SQL_API_SQLFETCH 13 +#if (ODBCVER >= 0x0300) +#define SQL_API_SQLFETCHSCROLL 1021 +#endif +#define SQL_API_SQLFREECONNECT 14 +#define SQL_API_SQLFREEENV 15 +#if (ODBCVER >= 0x0300) +#define SQL_API_SQLFREEHANDLE 1006 +#endif +#define SQL_API_SQLFREESTMT 16 +#if (ODBCVER >= 0x0300) +#define SQL_API_SQLGETCONNECTATTR 1007 +#endif +#define SQL_API_SQLGETCONNECTOPTION 42 +#define SQL_API_SQLGETCURSORNAME 17 +#define SQL_API_SQLGETDATA 43 +#if (ODBCVER >= 0x0300) +#define SQL_API_SQLGETDESCFIELD 1008 +#define SQL_API_SQLGETDESCREC 1009 +#define SQL_API_SQLGETDIAGFIELD 1010 +#define SQL_API_SQLGETDIAGREC 1011 +#define SQL_API_SQLGETENVATTR 1012 +#endif +#define SQL_API_SQLGETFUNCTIONS 44 +#define SQL_API_SQLGETINFO 45 +#if (ODBCVER >= 0x0300) +#define SQL_API_SQLGETSTMTATTR 1014 +#endif +#define SQL_API_SQLGETSTMTOPTION 46 +#define SQL_API_SQLGETTYPEINFO 47 +#define SQL_API_SQLNUMRESULTCOLS 18 +#define SQL_API_SQLPARAMDATA 48 +#define SQL_API_SQLPREPARE 19 +#define SQL_API_SQLPUTDATA 49 +#define SQL_API_SQLROWCOUNT 20 +#if (ODBCVER >= 0x0300) +#define SQL_API_SQLSETCONNECTATTR 1016 +#endif +#define SQL_API_SQLSETCONNECTOPTION 50 +#define SQL_API_SQLSETCURSORNAME 21 +#if (ODBCVER >= 0x0300) +#define SQL_API_SQLSETDESCFIELD 1017 +#define SQL_API_SQLSETDESCREC 1018 +#define SQL_API_SQLSETENVATTR 1019 +#endif +#define SQL_API_SQLSETPARAM 22 +#if (ODBCVER >= 0x0300) +#define SQL_API_SQLSETSTMTATTR 1020 +#endif +#define SQL_API_SQLSETSTMTOPTION 51 +#define SQL_API_SQLSPECIALCOLUMNS 52 +#define SQL_API_SQLSTATISTICS 53 +#define SQL_API_SQLTABLES 54 +#define SQL_API_SQLTRANSACT 23 + +/* Information requested by SQLGetInfo() */ +#if (ODBCVER >= 0x0300) +#define SQL_MAX_DRIVER_CONNECTIONS 0 +#define SQL_MAXIMUM_DRIVER_CONNECTIONS SQL_MAX_DRIVER_CONNECTIONS +#define SQL_MAX_CONCURRENT_ACTIVITIES 1 +#define SQL_MAXIMUM_CONCURRENT_ACTIVITIES SQL_MAX_CONCURRENT_ACTIVITIES +#endif +#define SQL_DATA_SOURCE_NAME 2 +#define SQL_FETCH_DIRECTION 8 +#define SQL_SERVER_NAME 13 +#define SQL_SEARCH_PATTERN_ESCAPE 14 +#define SQL_DBMS_NAME 17 +#define SQL_DBMS_VER 18 +#define SQL_ACCESSIBLE_TABLES 19 +#define SQL_ACCESSIBLE_PROCEDURES 20 +#define SQL_CURSOR_COMMIT_BEHAVIOR 23 +#define SQL_DATA_SOURCE_READ_ONLY 25 +#define SQL_DEFAULT_TXN_ISOLATION 26 +#define SQL_IDENTIFIER_CASE 28 +#define SQL_IDENTIFIER_QUOTE_CHAR 29 +#define SQL_MAX_COLUMN_NAME_LEN 30 +#define SQL_MAXIMUM_COLUMN_NAME_LENGTH SQL_MAX_COLUMN_NAME_LEN +#define SQL_MAX_CURSOR_NAME_LEN 31 +#define SQL_MAXIMUM_CURSOR_NAME_LENGTH SQL_MAX_CURSOR_NAME_LEN +#define SQL_MAX_SCHEMA_NAME_LEN 32 +#define SQL_MAXIMUM_SCHEMA_NAME_LENGTH SQL_MAX_SCHEMA_NAME_LEN +#define SQL_MAX_CATALOG_NAME_LEN 34 +#define SQL_MAXIMUM_CATALOG_NAME_LENGTH SQL_MAX_CATALOG_NAME_LEN +#define SQL_MAX_TABLE_NAME_LEN 35 +#define SQL_SCROLL_CONCURRENCY 43 +#define SQL_TXN_CAPABLE 46 +#define SQL_TRANSACTION_CAPABLE SQL_TXN_CAPABLE +#define SQL_USER_NAME 47 +#define SQL_TXN_ISOLATION_OPTION 72 +#define SQL_TRANSACTION_ISOLATION_OPTION SQL_TXN_ISOLATION_OPTION +#define SQL_INTEGRITY 73 +#define SQL_GETDATA_EXTENSIONS 81 +#define SQL_NULL_COLLATION 85 +#define SQL_ALTER_TABLE 86 +#define SQL_ORDER_BY_COLUMNS_IN_SELECT 90 +#define SQL_SPECIAL_CHARACTERS 94 +#define SQL_MAX_COLUMNS_IN_GROUP_BY 97 +#define SQL_MAXIMUM_COLUMNS_IN_GROUP_BY SQL_MAX_COLUMNS_IN_GROUP_BY +#define SQL_MAX_COLUMNS_IN_INDEX 98 +#define SQL_MAXIMUM_COLUMNS_IN_INDEX SQL_MAX_COLUMNS_IN_INDEX +#define SQL_MAX_COLUMNS_IN_ORDER_BY 99 +#define SQL_MAXIMUM_COLUMNS_IN_ORDER_BY SQL_MAX_COLUMNS_IN_ORDER_BY +#define SQL_MAX_COLUMNS_IN_SELECT 100 +#define SQL_MAXIMUM_COLUMNS_IN_SELECT SQL_MAX_COLUMNS_IN_SELECT +#define SQL_MAX_COLUMNS_IN_TABLE 101 +#define SQL_MAX_INDEX_SIZE 102 +#define SQL_MAXIMUM_INDEX_SIZE SQL_MAX_INDEX_SIZE +#define SQL_MAX_ROW_SIZE 104 +#define SQL_MAXIMUM_ROW_SIZE SQL_MAX_ROW_SIZE +#define SQL_MAX_STATEMENT_LEN 105 +#define SQL_MAXIMUM_STATEMENT_LENGTH SQL_MAX_STATEMENT_LEN +#define SQL_MAX_TABLES_IN_SELECT 106 +#define SQL_MAXIMUM_TABLES_IN_SELECT SQL_MAX_TABLES_IN_SELECT +#define SQL_MAX_USER_NAME_LEN 107 +#define SQL_MAXIMUM_USER_NAME_LENGTH SQL_MAX_USER_NAME_LEN +#if (ODBCVER >= 0x0300) +#define SQL_OJ_CAPABILITIES 115 +#define SQL_OUTER_JOIN_CAPABILITIES SQL_OJ_CAPABILITIES +#endif /* ODBCVER >= 0x0300 */ + +#if (ODBCVER >= 0x0300) +#define SQL_XOPEN_CLI_YEAR 10000 +#define SQL_CURSOR_SENSITIVITY 10001 +#define SQL_DESCRIBE_PARAMETER 10002 +#define SQL_CATALOG_NAME 10003 +#define SQL_COLLATION_SEQ 10004 +#define SQL_MAX_IDENTIFIER_LEN 10005 +#define SQL_MAXIMUM_IDENTIFIER_LENGTH SQL_MAX_IDENTIFIER_LEN +#endif /* ODBCVER >= 0x0300 */ + +/* SQL_ALTER_TABLE bitmasks */ +#if (ODBCVER >= 0x0200) +#define SQL_AT_ADD_COLUMN 0x00000001L +#define SQL_AT_DROP_COLUMN 0x00000002L +#endif /* ODBCVER >= 0x0200 */ + +#if (ODBCVER >= 0x0300) +#define SQL_AT_ADD_CONSTRAINT 0x00000008L + +/* The following bitmasks are ODBC extensions and defined in sqlext.h +*#define SQL_AT_COLUMN_SINGLE 0x00000020L +*#define SQL_AT_ADD_COLUMN_DEFAULT 0x00000040L +*#define SQL_AT_ADD_COLUMN_COLLATION 0x00000080L +*#define SQL_AT_SET_COLUMN_DEFAULT 0x00000100L +*#define SQL_AT_DROP_COLUMN_DEFAULT 0x00000200L +*#define SQL_AT_DROP_COLUMN_CASCADE 0x00000400L +*#define SQL_AT_DROP_COLUMN_RESTRICT 0x00000800L +*#define SQL_AT_ADD_TABLE_CONSTRAINT 0x00001000L +*#define SQL_AT_DROP_TABLE_CONSTRAINT_CASCADE 0x00002000L +*#define SQL_AT_DROP_TABLE_CONSTRAINT_RESTRICT 0x00004000L +*#define SQL_AT_CONSTRAINT_NAME_DEFINITION 0x00008000L +*#define SQL_AT_CONSTRAINT_INITIALLY_DEFERRED 0x00010000L +*#define SQL_AT_CONSTRAINT_INITIALLY_IMMEDIATE 0x00020000L +*#define SQL_AT_CONSTRAINT_DEFERRABLE 0x00040000L +*#define SQL_AT_CONSTRAINT_NON_DEFERRABLE 0x00080000L +*/ +#endif /* ODBCVER >= 0x0300 */ + + +/* SQL_ASYNC_MODE values */ +#if (ODBCVER >= 0x0300) +#define SQL_AM_NONE 0 +#define SQL_AM_CONNECTION 1 +#define SQL_AM_STATEMENT 2 +#endif + +/* SQL_CURSOR_COMMIT_BEHAVIOR values */ +#define SQL_CB_DELETE 0 +#define SQL_CB_CLOSE 1 +#define SQL_CB_PRESERVE 2 + +/* SQL_FETCH_DIRECTION bitmasks */ +#define SQL_FD_FETCH_NEXT 0x00000001L +#define SQL_FD_FETCH_FIRST 0x00000002L +#define SQL_FD_FETCH_LAST 0x00000004L +#define SQL_FD_FETCH_PRIOR 0x00000008L +#define SQL_FD_FETCH_ABSOLUTE 0x00000010L +#define SQL_FD_FETCH_RELATIVE 0x00000020L + +/* SQL_GETDATA_EXTENSIONS bitmasks */ +#define SQL_GD_ANY_COLUMN 0x00000001L +#define SQL_GD_ANY_ORDER 0x00000002L + +/* SQL_IDENTIFIER_CASE values */ +#define SQL_IC_UPPER 1 +#define SQL_IC_LOWER 2 +#define SQL_IC_SENSITIVE 3 +#define SQL_IC_MIXED 4 + +/* SQL_OJ_CAPABILITIES bitmasks */ +/* NB: this means 'outer join', not what you may be thinking */ + + +#if (ODBCVER >= 0x0201) +#define SQL_OJ_LEFT 0x00000001L +#define SQL_OJ_RIGHT 0x00000002L +#define SQL_OJ_FULL 0x00000004L +#define SQL_OJ_NESTED 0x00000008L +#define SQL_OJ_NOT_ORDERED 0x00000010L +#define SQL_OJ_INNER 0x00000020L +#define SQL_OJ_ALL_COMPARISON_OPS 0x00000040L +#endif + +/* SQL_SCROLL_CONCURRENCY bitmasks */ +#define SQL_SCCO_READ_ONLY 0x00000001L +#define SQL_SCCO_LOCK 0x00000002L +#define SQL_SCCO_OPT_ROWVER 0x00000004L +#define SQL_SCCO_OPT_VALUES 0x00000008L + +/* SQL_TXN_CAPABLE values */ +#define SQL_TC_NONE 0 +#define SQL_TC_DML 1 +#define SQL_TC_ALL 2 +#define SQL_TC_DDL_COMMIT 3 +#define SQL_TC_DDL_IGNORE 4 + +/* SQL_TXN_ISOLATION_OPTION bitmasks */ +#define SQL_TXN_READ_UNCOMMITTED 0x00000001L +#define SQL_TRANSACTION_READ_UNCOMMITTED SQL_TXN_READ_UNCOMMITTED +#define SQL_TXN_READ_COMMITTED 0x00000002L +#define SQL_TRANSACTION_READ_COMMITTED SQL_TXN_READ_COMMITTED +#define SQL_TXN_REPEATABLE_READ 0x00000004L +#define SQL_TRANSACTION_REPEATABLE_READ SQL_TXN_REPEATABLE_READ +#define SQL_TXN_SERIALIZABLE 0x00000008L +#define SQL_TRANSACTION_SERIALIZABLE SQL_TXN_SERIALIZABLE + +/* SQL_NULL_COLLATION values */ +#define SQL_NC_HIGH 0 +#define SQL_NC_LOW 1 + + SQLRETURN SQL_API SQLAllocConnect(SQLHENV EnvironmentHandle, + SQLHDBC *ConnectionHandle); + + SQLRETURN SQL_API SQLAllocEnv(SQLHENV *EnvironmentHandle); + +#if (ODBCVER >= 0x0300) + SQLRETURN SQL_API SQLAllocHandle(SQLSMALLINT HandleType, + SQLHANDLE InputHandle, SQLHANDLE *OutputHandle); +#endif + + SQLRETURN SQL_API SQLAllocStmt(SQLHDBC ConnectionHandle, + SQLHSTMT *StatementHandle); + + SQLRETURN SQL_API SQLBindCol(SQLHSTMT StatementHandle, + SQLUSMALLINT ColumnNumber, SQLSMALLINT TargetType, + SQLPOINTER TargetValue, SQLLEN BufferLength, + SQLLEN *StrLen_or_Ind); + +#if (ODBCVER >= 0x0300) + SQLRETURN SQL_API SQLBindParam(SQLHSTMT StatementHandle, + SQLUSMALLINT ParameterNumber, SQLSMALLINT ValueType, + SQLSMALLINT ParameterType, SQLULEN LengthPrecision, + SQLSMALLINT ParameterScale, SQLPOINTER ParameterValue, + SQLLEN *StrLen_or_Ind); +#endif + + SQLRETURN SQL_API SQLCancel(SQLHSTMT StatementHandle); + +#if (ODBCVER >= 0x0300) + SQLRETURN SQL_API SQLCloseCursor(SQLHSTMT StatementHandle); + + SQLRETURN SQL_API SQLColAttribute(SQLHSTMT StatementHandle, + SQLUSMALLINT ColumnNumber, SQLUSMALLINT FieldIdentifier, + SQLPOINTER CharacterAttribute, SQLSMALLINT BufferLength, + SQLSMALLINT *StringLength, SQLLEN *NumericAttribute + /* spec says (SQLPOINTER) not (SQLEN*) - PAH */ ); + /* Ms now say SQLLEN* http://msdn.microsoft.com/library/en-us/odbc/htm/dasdkodbcoverview_64bit.asp - NG */ + +#endif + + + SQLRETURN SQL_API SQLColumns(SQLHSTMT StatementHandle, + SQLCHAR *CatalogName, SQLSMALLINT NameLength1, + SQLCHAR *SchemaName, SQLSMALLINT NameLength2, + SQLCHAR *TableName, SQLSMALLINT NameLength3, + SQLCHAR *ColumnName, SQLSMALLINT NameLength4); + + + SQLRETURN SQL_API SQLConnect(SQLHDBC ConnectionHandle, + SQLCHAR *ServerName, SQLSMALLINT NameLength1, + SQLCHAR *UserName, SQLSMALLINT NameLength2, + SQLCHAR *Authentication, SQLSMALLINT NameLength3); + +#if (ODBCVER >= 0x0300) + SQLRETURN SQL_API SQLCopyDesc(SQLHDESC SourceDescHandle, + SQLHDESC TargetDescHandle); +#endif + + SQLRETURN SQL_API SQLDataSources(SQLHENV EnvironmentHandle, + SQLUSMALLINT Direction, SQLCHAR *ServerName, + SQLSMALLINT BufferLength1, SQLSMALLINT *NameLength1, + SQLCHAR *Description, SQLSMALLINT BufferLength2, + SQLSMALLINT *NameLength2); + + SQLRETURN SQL_API SQLDescribeCol(SQLHSTMT StatementHandle, + SQLUSMALLINT ColumnNumber, SQLCHAR *ColumnName, + SQLSMALLINT BufferLength, SQLSMALLINT *NameLength, + SQLSMALLINT *DataType, SQLULEN *ColumnSize, + SQLSMALLINT *DecimalDigits, SQLSMALLINT *Nullable); + + SQLRETURN SQL_API SQLDisconnect(SQLHDBC ConnectionHandle); + +#if (ODBCVER >= 0x0300) + SQLRETURN SQL_API SQLEndTran(SQLSMALLINT HandleType, SQLHANDLE Handle, + SQLSMALLINT CompletionType); +#endif + + SQLRETURN SQL_API SQLError(SQLHENV EnvironmentHandle, + SQLHDBC ConnectionHandle, SQLHSTMT StatementHandle, + SQLCHAR *Sqlstate, SQLINTEGER *NativeError, + SQLCHAR *MessageText, SQLSMALLINT BufferLength, + SQLSMALLINT *TextLength); + + SQLRETURN SQL_API SQLExecDirect(SQLHSTMT StatementHandle, + SQLCHAR *StatementText, SQLINTEGER TextLength); + + SQLRETURN SQL_API SQLExecute(SQLHSTMT StatementHandle); + + SQLRETURN SQL_API SQLFetch(SQLHSTMT StatementHandle); + +#if (ODBCVER >= 0x0300) + SQLRETURN SQL_API SQLFetchScroll(SQLHSTMT StatementHandle, + SQLSMALLINT FetchOrientation, SQLLEN FetchOffset); +#endif + + SQLRETURN SQL_API SQLFreeConnect(SQLHDBC ConnectionHandle); + + SQLRETURN SQL_API SQLFreeEnv(SQLHENV EnvironmentHandle); + +#if (ODBCVER >= 0x0300) + SQLRETURN SQL_API SQLFreeHandle(SQLSMALLINT HandleType, SQLHANDLE Handle); +#endif + + SQLRETURN SQL_API SQLFreeStmt(SQLHSTMT StatementHandle, + SQLUSMALLINT Option); + +#if (ODBCVER >= 0x0300) + SQLRETURN SQL_API SQLGetConnectAttr(SQLHDBC ConnectionHandle, + SQLINTEGER Attribute, SQLPOINTER Value, + SQLINTEGER BufferLength, SQLINTEGER *StringLength); +#endif + + SQLRETURN SQL_API SQLGetConnectOption(SQLHDBC ConnectionHandle, + SQLUSMALLINT Option, SQLPOINTER Value); + + SQLRETURN SQL_API SQLGetCursorName(SQLHSTMT StatementHandle, + SQLCHAR *CursorName, SQLSMALLINT BufferLength, + SQLSMALLINT *NameLength); + + SQLRETURN SQL_API SQLGetData(SQLHSTMT StatementHandle, + SQLUSMALLINT ColumnNumber, SQLSMALLINT TargetType, + SQLPOINTER TargetValue, SQLLEN BufferLength, + SQLLEN *StrLen_or_Ind); + +#if (ODBCVER >= 0x0300) + SQLRETURN SQLGetDescField(SQLHDESC DescriptorHandle, + SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier, + SQLPOINTER Value, SQLINTEGER BufferLength, + SQLINTEGER *StringLength); + + SQLRETURN SQL_API SQLGetDescRec(SQLHDESC DescriptorHandle, + SQLSMALLINT RecNumber, SQLCHAR *Name, + SQLSMALLINT BufferLength, SQLSMALLINT *StringLength, + SQLSMALLINT *Type, SQLSMALLINT *SubType, + SQLLEN *Length, SQLSMALLINT *Precision, + SQLSMALLINT *Scale, SQLSMALLINT *Nullable); + + SQLRETURN SQL_API SQLGetDiagField(SQLSMALLINT HandleType, SQLHANDLE Handle, + SQLSMALLINT RecNumber, SQLSMALLINT DiagIdentifier, + SQLPOINTER DiagInfo, SQLSMALLINT BufferLength, + SQLSMALLINT *StringLength); + + SQLRETURN SQL_API SQLGetDiagRec(SQLSMALLINT HandleType, SQLHANDLE Handle, + SQLSMALLINT RecNumber, SQLCHAR *Sqlstate, + SQLINTEGER *NativeError, SQLCHAR *MessageText, + SQLSMALLINT BufferLength, SQLSMALLINT *TextLength); + + SQLRETURN SQL_API SQLGetEnvAttr(SQLHENV EnvironmentHandle, + SQLINTEGER Attribute, SQLPOINTER Value, + SQLINTEGER BufferLength, SQLINTEGER *StringLength); +#endif /* ODBCVER >= 0x0300 */ + + SQLRETURN SQL_API SQLGetFunctions(SQLHDBC ConnectionHandle, + SQLUSMALLINT FunctionId, SQLUSMALLINT *Supported); + + SQLRETURN SQL_API SQLGetInfo(SQLHDBC ConnectionHandle, + SQLUSMALLINT InfoType, SQLPOINTER InfoValue, + SQLSMALLINT BufferLength, SQLSMALLINT *StringLength); + +#if (ODBCVER >= 0x0300) + SQLRETURN SQL_API SQLGetStmtAttr(SQLHSTMT StatementHandle, + SQLINTEGER Attribute, SQLPOINTER Value, + SQLINTEGER BufferLength, SQLINTEGER *StringLength); +#endif /* ODBCVER >= 0x0300 */ + + SQLRETURN SQL_API SQLGetStmtOption(SQLHSTMT StatementHandle, + SQLUSMALLINT Option, SQLPOINTER Value); + + SQLRETURN SQL_API SQLGetTypeInfo(SQLHSTMT StatementHandle, + SQLSMALLINT DataType); + + SQLRETURN SQL_API SQLNumResultCols(SQLHSTMT StatementHandle, + SQLSMALLINT *ColumnCount); + + SQLRETURN SQL_API SQLParamData(SQLHSTMT StatementHandle, + SQLPOINTER *Value); + + SQLRETURN SQL_API SQLPrepare(SQLHSTMT StatementHandle, + SQLCHAR *StatementText, SQLINTEGER TextLength); + + SQLRETURN SQL_API SQLPutData(SQLHSTMT StatementHandle, + SQLPOINTER Data, SQLLEN StrLen_or_Ind); + + SQLRETURN SQL_API SQLRowCount(SQLHSTMT StatementHandle, + SQLLEN *RowCount); + +#if (ODBCVER >= 0x0300) + SQLRETURN SQL_API SQLSetConnectAttr(SQLHDBC ConnectionHandle, + SQLINTEGER Attribute, SQLPOINTER Value, + SQLINTEGER StringLength); +#endif /* ODBCVER >= 0x0300 */ + + SQLRETURN SQL_API SQLSetConnectOption(SQLHDBC ConnectionHandle, + SQLUSMALLINT Option, SQLULEN Value); + + SQLRETURN SQL_API SQLSetCursorName(SQLHSTMT StatementHandle, + SQLCHAR *CursorName, SQLSMALLINT NameLength); + +#if (ODBCVER >= 0x0300) + SQLRETURN SQL_API SQLSetDescField(SQLHDESC DescriptorHandle, + SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier, + SQLPOINTER Value, SQLINTEGER BufferLength); + + SQLRETURN SQL_API SQLSetDescRec(SQLHDESC DescriptorHandle, + SQLSMALLINT RecNumber, SQLSMALLINT Type, + SQLSMALLINT SubType, SQLLEN Length, + SQLSMALLINT Precision, SQLSMALLINT Scale, + SQLPOINTER Data, SQLLEN *StringLength, + SQLLEN *Indicator); + + SQLRETURN SQL_API SQLSetEnvAttr(SQLHENV EnvironmentHandle, + SQLINTEGER Attribute, SQLPOINTER Value, + SQLINTEGER StringLength); +#endif /* ODBCVER >= 0x0300 */ + + SQLRETURN SQL_API SQLSetParam(SQLHSTMT StatementHandle, + SQLUSMALLINT ParameterNumber, SQLSMALLINT ValueType, + SQLSMALLINT ParameterType, SQLULEN LengthPrecision, + SQLSMALLINT ParameterScale, SQLPOINTER ParameterValue, + SQLLEN *StrLen_or_Ind); + +#if (ODBCVER >= 0x0300) + SQLRETURN SQL_API SQLSetStmtAttr(SQLHSTMT StatementHandle, + SQLINTEGER Attribute, SQLPOINTER Value, + SQLINTEGER StringLength); +#endif + + SQLRETURN SQL_API SQLSetStmtOption(SQLHSTMT StatementHandle, + SQLUSMALLINT Option, SQLULEN Value); + + SQLRETURN SQL_API SQLSpecialColumns(SQLHSTMT StatementHandle, + SQLUSMALLINT IdentifierType, SQLCHAR *CatalogName, + SQLSMALLINT NameLength1, SQLCHAR *SchemaName, + SQLSMALLINT NameLength2, SQLCHAR *TableName, + SQLSMALLINT NameLength3, SQLUSMALLINT Scope, + SQLUSMALLINT Nullable); + + SQLRETURN SQL_API SQLStatistics(SQLHSTMT StatementHandle, + SQLCHAR *CatalogName, SQLSMALLINT NameLength1, + SQLCHAR *SchemaName, SQLSMALLINT NameLength2, + SQLCHAR *TableName, SQLSMALLINT NameLength3, + SQLUSMALLINT Unique, SQLUSMALLINT Reserved); + + SQLRETURN SQL_API SQLTables(SQLHSTMT StatementHandle, + SQLCHAR *CatalogName, SQLSMALLINT NameLength1, + SQLCHAR *SchemaName, SQLSMALLINT NameLength2, + SQLCHAR *TableName, SQLSMALLINT NameLength3, + SQLCHAR *TableType, SQLSMALLINT NameLength4); + + SQLRETURN SQL_API SQLTransact(SQLHENV EnvironmentHandle, + SQLHDBC ConnectionHandle, SQLUSMALLINT CompletionType); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libodbc/include/ss_linux/sqlext.h b/libodbc/include/ss_linux/sqlext.h new file mode 100644 index 0000000000..fc3c5af8a6 --- /dev/null +++ b/libodbc/include/ss_linux/sqlext.h @@ -0,0 +1,2122 @@ +/***************************************************** + * sqlext.h + * + * These should be consistent with the MS version. + * + *****************************************************/ +#ifndef __SQLEXT_H +#define __SQLEXT_H + + +/* BEGIN - unixODBC ONLY (programs like ODBCConfig and DataManager use these) */ + +/* COLUMNS IN SQLTables() RESULT SET */ +#define SQLTables_TABLE_CATALOG 1 +#define SQLTables_TABLE_SCHEM 2 +#define SQLTables_TABLE_NAME 3 +#define SQLTables_TABLE_TYPE 4 +#define SQLTables_REMARKS 5 + +/* COLUMNS IN SQLColumns() RESULT SET */ +#define SQLColumns_TABLE_CAT 1 +#define SQLColumns_TABLE_SCHEM 2 +#define SQLColumns_TABLE_NAME 3 +#define SQLColumns_COLUMN_NAME 4 +#define SQLColumns_DATA_TYPE 5 +#define SQLColumns_TYPE_NAME 6 +#define SQLColumns_COLUMN_SIZE 7 +#define SQLColumns_BUFFER_LENGTH 8 +#define SQLColumns_DECIMAL_DIGITS 9 +#define SQLColumns_NUM_PREC_RADIX 10 +#define SQLColumns_NULLABLE 11 +#define SQLColumns_REMARKS 12 +#define SQLColumns_COLUMN_DEF 13 +#define SQLColumns_SQL_DATA_TYPE 14 +#define SQLColumns_SQL_DATETIME_SUB 15 +#define SQLColumns_CHAR_OCTET_LENGTH 16 +#define SQLColumns_ORDINAL_POSITION 17 +#define SQLColumns_IS_NULLABLE 18 + +/* END - unixODBC ONLY */ + +#ifndef __SQL_H +#include "sql.h" +#endif + +#ifdef __cplusplus +extern "C" { /* Assume C declarations for C++ */ +#endif + +/* generally useful constants */ +#define SQL_SPEC_MAJOR 3 /* Major version of specification */ +#define SQL_SPEC_MINOR 52 /* Minor version of specification */ +#define SQL_SPEC_STRING "03.52" /* String constant for version */ + +#define SQL_SQLSTATE_SIZE 5 /* size of SQLSTATE */ +#define SQL_MAX_DSN_LENGTH 32 /* maximum data source name size */ + +#define SQL_MAX_OPTION_STRING_LENGTH 256 + +/* return code SQL_NO_DATA_FOUND is the same as SQL_NO_DATA */ +#if (ODBCVER < 0x0300) +#define SQL_NO_DATA_FOUND 100 +#else +#define SQL_NO_DATA_FOUND SQL_NO_DATA +#endif + +/* an end handle type */ +#if (ODBCVER >= 0x0300) +#define SQL_HANDLE_SENV 5 +#endif /* ODBCVER >= 0x0300 */ + +/* env attribute */ +#if (ODBCVER >= 0x0300) +#define SQL_ATTR_ODBC_VERSION 200 +#define SQL_ATTR_CONNECTION_POOLING 201 +#define SQL_ATTR_CP_MATCH 202 + +/* unixODBC additions */ +#define SQL_ATTR_UNIXODBC_SYSPATH 65001 +#define SQL_ATTR_UNIXODBC_VERSION 65002 +#define SQL_ATTR_UNIXODBC_ENVATTR 65003 +#endif /* ODBCVER >= 0x0300 */ + +#if (ODBCVER >= 0x0300) +/* values for SQL_ATTR_CONNECTION_POOLING */ +#define SQL_CP_OFF 0UL +#define SQL_CP_ONE_PER_DRIVER 1UL +#define SQL_CP_ONE_PER_HENV 2UL +#define SQL_CP_DEFAULT SQL_CP_OFF + +/* values for SQL_ATTR_CP_MATCH */ +#define SQL_CP_STRICT_MATCH 0UL +#define SQL_CP_RELAXED_MATCH 1UL +#define SQL_CP_MATCH_DEFAULT SQL_CP_STRICT_MATCH + +/* values for SQL_ATTR_ODBC_VERSION */ +#define SQL_OV_ODBC2 2UL +#define SQL_OV_ODBC3 3UL +#endif /* ODBCVER >= 0x0300 */ + +/* connection attributes */ +#define SQL_ACCESS_MODE 101 +#define SQL_AUTOCOMMIT 102 +#define SQL_LOGIN_TIMEOUT 103 +#define SQL_OPT_TRACE 104 +#define SQL_OPT_TRACEFILE 105 +#define SQL_TRANSLATE_DLL 106 +#define SQL_TRANSLATE_OPTION 107 +#define SQL_TXN_ISOLATION 108 +#define SQL_CURRENT_QUALIFIER 109 +#define SQL_ODBC_CURSORS 110 +#define SQL_QUIET_MODE 111 +#define SQL_PACKET_SIZE 112 + +/* connection attributes with new names */ +#if (ODBCVER >= 0x0300) +#define SQL_ATTR_ACCESS_MODE SQL_ACCESS_MODE +#define SQL_ATTR_AUTOCOMMIT SQL_AUTOCOMMIT +#define SQL_ATTR_CONNECTION_TIMEOUT 113 +#define SQL_ATTR_CURRENT_CATALOG SQL_CURRENT_QUALIFIER +#define SQL_ATTR_DISCONNECT_BEHAVIOR 114 +#define SQL_ATTR_ENLIST_IN_DTC 1207 +#define SQL_ATTR_ENLIST_IN_XA 1208 +#define SQL_ATTR_LOGIN_TIMEOUT SQL_LOGIN_TIMEOUT +#define SQL_ATTR_ODBC_CURSORS SQL_ODBC_CURSORS +#define SQL_ATTR_PACKET_SIZE SQL_PACKET_SIZE +#define SQL_ATTR_QUIET_MODE SQL_QUIET_MODE +#define SQL_ATTR_TRACE SQL_OPT_TRACE +#define SQL_ATTR_TRACEFILE SQL_OPT_TRACEFILE +#define SQL_ATTR_TRANSLATE_LIB SQL_TRANSLATE_DLL +#define SQL_ATTR_TRANSLATE_OPTION SQL_TRANSLATE_OPTION +#define SQL_ATTR_TXN_ISOLATION SQL_TXN_ISOLATION +#endif /* ODBCVER >= 0x0300 */ + +#define SQL_ATTR_CONNECTION_DEAD 1209 /* GetConnectAttr only */ + +#define SQL_ATTR_DRIVER_THREADING 1028 /* Driver threading level */ + +#if (ODBCVER >= 0x0351) +/* ODBC Driver Manager sets this connection attribute to a unicode driver + (which supports SQLConnectW) when the application is an ANSI application + (which calls SQLConnect, SQLDriverConnect, or SQLBrowseConnect). + This is SetConnectAttr only and application does not set this attribute + This attribute was introduced because some unicode driver's some APIs may + need to behave differently on ANSI or Unicode applications. A unicode + driver, which has same behavior for both ANSI or Unicode applications, + should return SQL_ERROR when the driver manager sets this connection + attribute. When a unicode driver returns SQL_SUCCESS on this attribute, + the driver manager treates ANSI and Unicode connections differently in + connection pooling. +*/ +#define SQL_ATTR_ANSI_APP 115 +#endif + +/* SQL_CONNECT_OPT_DRVR_START is not meaningful for 3.0 driver */ +#if (ODBCVER < 0x0300) +#define SQL_CONNECT_OPT_DRVR_START 1000 +#endif /* ODBCVER < 0x0300 */ + +#if (ODBCVER < 0x0300) +#define SQL_CONN_OPT_MAX SQL_PACKET_SIZE +#define SQL_CONN_OPT_MIN SQL_ACCESS_MODE +#endif /* ODBCVER < 0x0300 */ + +/* SQL_ACCESS_MODE options */ +#define SQL_MODE_READ_WRITE 0UL +#define SQL_MODE_READ_ONLY 1UL +#define SQL_MODE_DEFAULT SQL_MODE_READ_WRITE + +/* SQL_AUTOCOMMIT options */ +#define SQL_AUTOCOMMIT_OFF 0UL +#define SQL_AUTOCOMMIT_ON 1UL +#define SQL_AUTOCOMMIT_DEFAULT SQL_AUTOCOMMIT_ON + +/* SQL_LOGIN_TIMEOUT options */ +#define SQL_LOGIN_TIMEOUT_DEFAULT 15UL + +/* SQL_OPT_TRACE options */ +#define SQL_OPT_TRACE_OFF 0UL +#define SQL_OPT_TRACE_ON 1UL +#define SQL_OPT_TRACE_DEFAULT SQL_OPT_TRACE_OFF +#define SQL_OPT_TRACE_FILE_DEFAULT "/tmp/SQL.LOG" + +/* SQL_ODBC_CURSORS options */ +#define SQL_CUR_USE_IF_NEEDED 0UL +#define SQL_CUR_USE_ODBC 1UL +#define SQL_CUR_USE_DRIVER 2UL +#define SQL_CUR_DEFAULT SQL_CUR_USE_DRIVER + +#if (ODBCVER >= 0x0300) +/* values for SQL_ATTR_DISCONNECT_BEHAVIOR */ +#define SQL_DB_RETURN_TO_POOL 0UL +#define SQL_DB_DISCONNECT 1UL +#define SQL_DB_DEFAULT SQL_DB_RETURN_TO_POOL + +/* values for SQL_ATTR_ENLIST_IN_DTC */ +#define SQL_DTC_DONE 0L +#endif /* ODBCVER >= 0x0300 */ + +/* values for SQL_ATTR_CONNECTION_DEAD */ +#define SQL_CD_TRUE 1L /* Connection is closed/dead */ +#define SQL_CD_FALSE 0L /* Connection is open/available */ + +/* values for SQL_ATTR_ANSI_APP */ +#if (ODBCVER >= 0x0351) +#define SQL_AA_TRUE 1L /* the application is an ANSI app */ +#define SQL_AA_FALSE 0L /* the application is a Unicode app */ +#endif + +/* statement attributes */ +#define SQL_QUERY_TIMEOUT 0 +#define SQL_MAX_ROWS 1 +#define SQL_NOSCAN 2 +#define SQL_MAX_LENGTH 3 +#define SQL_ASYNC_ENABLE 4 /* same as SQL_ATTR_ASYNC_ENABLE */ +#define SQL_BIND_TYPE 5 +#define SQL_CURSOR_TYPE 6 +#define SQL_CONCURRENCY 7 +#define SQL_KEYSET_SIZE 8 +#define SQL_ROWSET_SIZE 9 +#define SQL_SIMULATE_CURSOR 10 +#define SQL_RETRIEVE_DATA 11 +#define SQL_USE_BOOKMARKS 12 +#define SQL_GET_BOOKMARK 13 /* GetStmtOption Only */ +#define SQL_ROW_NUMBER 14 /* GetStmtOption Only */ + +/* statement attributes for ODBC 3.0 */ +#if (ODBCVER >= 0x0300) +#define SQL_ATTR_ASYNC_ENABLE 4 +#define SQL_ATTR_CONCURRENCY SQL_CONCURRENCY +#define SQL_ATTR_CURSOR_TYPE SQL_CURSOR_TYPE +#define SQL_ATTR_ENABLE_AUTO_IPD 15 +#define SQL_ATTR_FETCH_BOOKMARK_PTR 16 +#define SQL_ATTR_KEYSET_SIZE SQL_KEYSET_SIZE +#define SQL_ATTR_MAX_LENGTH SQL_MAX_LENGTH +#define SQL_ATTR_MAX_ROWS SQL_MAX_ROWS +#define SQL_ATTR_NOSCAN SQL_NOSCAN +#define SQL_ATTR_PARAM_BIND_OFFSET_PTR 17 +#define SQL_ATTR_PARAM_BIND_TYPE 18 +#define SQL_ATTR_PARAM_OPERATION_PTR 19 +#define SQL_ATTR_PARAM_STATUS_PTR 20 +#define SQL_ATTR_PARAMS_PROCESSED_PTR 21 +#define SQL_ATTR_PARAMSET_SIZE 22 +#define SQL_ATTR_QUERY_TIMEOUT SQL_QUERY_TIMEOUT +#define SQL_ATTR_RETRIEVE_DATA SQL_RETRIEVE_DATA +#define SQL_ATTR_ROW_BIND_OFFSET_PTR 23 +#define SQL_ATTR_ROW_BIND_TYPE SQL_BIND_TYPE +#define SQL_ATTR_ROW_NUMBER SQL_ROW_NUMBER /*GetStmtAttr*/ +#define SQL_ATTR_ROW_OPERATION_PTR 24 +#define SQL_ATTR_ROW_STATUS_PTR 25 +#define SQL_ATTR_ROWS_FETCHED_PTR 26 +#define SQL_ATTR_ROW_ARRAY_SIZE 27 +#define SQL_ATTR_SIMULATE_CURSOR SQL_SIMULATE_CURSOR +#define SQL_ATTR_USE_BOOKMARKS SQL_USE_BOOKMARKS + +#endif /* ODBCVER >= 0x0300 */ + +#if (ODBCVER < 0x0300) +#define SQL_STMT_OPT_MAX SQL_ROW_NUMBER +#define SQL_STMT_OPT_MIN SQL_QUERY_TIMEOUT +#endif /* ODBCVER < 0x0300 */ + +/* New defines for SEARCHABLE column in SQLGetTypeInfo */ + +#if (ODBCVER >= 0x0300) +#define SQL_COL_PRED_CHAR SQL_LIKE_ONLY +#define SQL_COL_PRED_BASIC SQL_ALL_EXCEPT_LIKE +#endif /* ODBCVER >= 0x0300 */ + + + +/* whether an attribute is a pointer or not */ +#if (ODBCVER >= 0x0300) +#define SQL_IS_POINTER (-4) +#define SQL_IS_UINTEGER (-5) +#define SQL_IS_INTEGER (-6) +#define SQL_IS_USMALLINT (-7) +#define SQL_IS_SMALLINT (-8) +#endif /* ODBCVER >= 0x0300 */ + +/* the value of SQL_ATTR_PARAM_BIND_TYPE */ +#if (ODBCVER >= 0x0300) +#define SQL_PARAM_BIND_BY_COLUMN 0UL +#define SQL_PARAM_BIND_TYPE_DEFAULT SQL_PARAM_BIND_BY_COLUMN +#endif /* ODBCVER >= 0x0300 */ + +/* SQL_QUERY_TIMEOUT options */ +#define SQL_QUERY_TIMEOUT_DEFAULT 0UL + +/* SQL_MAX_ROWS options */ +#define SQL_MAX_ROWS_DEFAULT 0UL + +/* SQL_NOSCAN options */ +#define SQL_NOSCAN_OFF 0UL /* 1.0 FALSE */ +#define SQL_NOSCAN_ON 1UL /* 1.0 TRUE */ +#define SQL_NOSCAN_DEFAULT SQL_NOSCAN_OFF + +/* SQL_MAX_LENGTH options */ +#define SQL_MAX_LENGTH_DEFAULT 0UL + +/* values for SQL_ATTR_ASYNC_ENABLE */ +#define SQL_ASYNC_ENABLE_OFF 0UL +#define SQL_ASYNC_ENABLE_ON 1UL +#define SQL_ASYNC_ENABLE_DEFAULT SQL_ASYNC_ENABLE_OFF + +/* SQL_BIND_TYPE options */ +#define SQL_BIND_BY_COLUMN 0UL +#define SQL_BIND_TYPE_DEFAULT SQL_BIND_BY_COLUMN /* Default value */ + +/* SQL_CONCURRENCY options */ +#define SQL_CONCUR_READ_ONLY 1 +#define SQL_CONCUR_LOCK 2 +#define SQL_CONCUR_ROWVER 3 +#define SQL_CONCUR_VALUES 4 +#define SQL_CONCUR_DEFAULT SQL_CONCUR_READ_ONLY /* Default value */ + +/* SQL_CURSOR_TYPE options */ +#define SQL_CURSOR_FORWARD_ONLY 0UL +#define SQL_CURSOR_KEYSET_DRIVEN 1UL +#define SQL_CURSOR_DYNAMIC 2UL +#define SQL_CURSOR_STATIC 3UL +#define SQL_CURSOR_TYPE_DEFAULT SQL_CURSOR_FORWARD_ONLY /* Default value */ + +/* SQL_ROWSET_SIZE options */ +#define SQL_ROWSET_SIZE_DEFAULT 1UL + +/* SQL_KEYSET_SIZE options */ +#define SQL_KEYSET_SIZE_DEFAULT 0UL + +/* SQL_SIMULATE_CURSOR options */ +#define SQL_SC_NON_UNIQUE 0UL +#define SQL_SC_TRY_UNIQUE 1UL +#define SQL_SC_UNIQUE 2UL + +/* SQL_RETRIEVE_DATA options */ +#define SQL_RD_OFF 0UL +#define SQL_RD_ON 1UL +#define SQL_RD_DEFAULT SQL_RD_ON + +/* SQL_USE_BOOKMARKS options */ +#define SQL_UB_OFF 0UL +#define SQL_UB_ON 01UL +#define SQL_UB_DEFAULT SQL_UB_OFF + +/* New values for SQL_USE_BOOKMARKS attribute */ +#if (ODBCVER >= 0x0300) +#define SQL_UB_FIXED SQL_UB_ON +#define SQL_UB_VARIABLE 2UL +#endif /* ODBCVER >= 0x0300 */ + +/* extended descriptor field */ +#if (ODBCVER >= 0x0300) +#define SQL_DESC_ARRAY_SIZE 20 +#define SQL_DESC_ARRAY_STATUS_PTR 21 +#define SQL_DESC_AUTO_UNIQUE_VALUE SQL_COLUMN_AUTO_INCREMENT +#define SQL_DESC_BASE_COLUMN_NAME 22 +#define SQL_DESC_BASE_TABLE_NAME 23 +#define SQL_DESC_BIND_OFFSET_PTR 24 +#define SQL_DESC_BIND_TYPE 25 +#define SQL_DESC_CASE_SENSITIVE SQL_COLUMN_CASE_SENSITIVE +#define SQL_DESC_CATALOG_NAME SQL_COLUMN_QUALIFIER_NAME +#define SQL_DESC_CONCISE_TYPE SQL_COLUMN_TYPE +#define SQL_DESC_DATETIME_INTERVAL_PRECISION 26 +#define SQL_DESC_DISPLAY_SIZE SQL_COLUMN_DISPLAY_SIZE +#define SQL_DESC_FIXED_PREC_SCALE SQL_COLUMN_MONEY +#define SQL_DESC_LABEL SQL_COLUMN_LABEL +#define SQL_DESC_LITERAL_PREFIX 27 +#define SQL_DESC_LITERAL_SUFFIX 28 +#define SQL_DESC_LOCAL_TYPE_NAME 29 +#define SQL_DESC_MAXIMUM_SCALE 30 +#define SQL_DESC_MINIMUM_SCALE 31 +#define SQL_DESC_NUM_PREC_RADIX 32 +#define SQL_DESC_PARAMETER_TYPE 33 +#define SQL_DESC_ROWS_PROCESSED_PTR 34 +#if (ODBCVER >= 0x0350) +#define SQL_DESC_ROWVER 35 +#endif /* ODBCVER >= 0x0350 */ +#define SQL_DESC_SCHEMA_NAME SQL_COLUMN_OWNER_NAME +#define SQL_DESC_SEARCHABLE SQL_COLUMN_SEARCHABLE +#define SQL_DESC_TYPE_NAME SQL_COLUMN_TYPE_NAME +#define SQL_DESC_TABLE_NAME SQL_COLUMN_TABLE_NAME +#define SQL_DESC_UNSIGNED SQL_COLUMN_UNSIGNED +#define SQL_DESC_UPDATABLE SQL_COLUMN_UPDATABLE +#endif /* ODBCVER >= 0x0300 */ + + +/* defines for diagnostics fields */ +#if (ODBCVER >= 0x0300) +#define SQL_DIAG_CURSOR_ROW_COUNT (-1249) +#define SQL_DIAG_ROW_NUMBER (-1248) +#define SQL_DIAG_COLUMN_NUMBER (-1247) +#endif /* ODBCVER >= 0x0300 */ + +/* SQL extended datatypes */ +#define SQL_DATE 9 +#if (ODBCVER >= 0x0300) +#define SQL_INTERVAL 10 +#endif /* ODBCVER >= 0x0300 */ +#define SQL_TIME 10 +#define SQL_TIMESTAMP 11 +#define SQL_LONGVARCHAR (-1) +#define SQL_BINARY (-2) +#define SQL_VARBINARY (-3) +#define SQL_LONGVARBINARY (-4) +#define SQL_BIGINT (-5) +#define SQL_TINYINT (-6) +#define SQL_BIT (-7) +#if (ODBCVER >= 0x0350) +#define SQL_GUID (-11) +#endif /* ODBCVER >= 0x0350 */ + +#if (ODBCVER >= 0x0300) +/* interval code */ +#define SQL_CODE_YEAR 1 +#define SQL_CODE_MONTH 2 +#define SQL_CODE_DAY 3 +#define SQL_CODE_HOUR 4 +#define SQL_CODE_MINUTE 5 +#define SQL_CODE_SECOND 6 +#define SQL_CODE_YEAR_TO_MONTH 7 +#define SQL_CODE_DAY_TO_HOUR 8 +#define SQL_CODE_DAY_TO_MINUTE 9 +#define SQL_CODE_DAY_TO_SECOND 10 +#define SQL_CODE_HOUR_TO_MINUTE 11 +#define SQL_CODE_HOUR_TO_SECOND 12 +#define SQL_CODE_MINUTE_TO_SECOND 13 + +#define SQL_INTERVAL_YEAR (100 + SQL_CODE_YEAR) +#define SQL_INTERVAL_MONTH (100 + SQL_CODE_MONTH) +#define SQL_INTERVAL_DAY (100 + SQL_CODE_DAY) +#define SQL_INTERVAL_HOUR (100 + SQL_CODE_HOUR) +#define SQL_INTERVAL_MINUTE (100 + SQL_CODE_MINUTE) +#define SQL_INTERVAL_SECOND (100 + SQL_CODE_SECOND) +#define SQL_INTERVAL_YEAR_TO_MONTH (100 + SQL_CODE_YEAR_TO_MONTH) +#define SQL_INTERVAL_DAY_TO_HOUR (100 + SQL_CODE_DAY_TO_HOUR) +#define SQL_INTERVAL_DAY_TO_MINUTE (100 + SQL_CODE_DAY_TO_MINUTE) +#define SQL_INTERVAL_DAY_TO_SECOND (100 + SQL_CODE_DAY_TO_SECOND) +#define SQL_INTERVAL_HOUR_TO_MINUTE (100 + SQL_CODE_HOUR_TO_MINUTE) +#define SQL_INTERVAL_HOUR_TO_SECOND (100 + SQL_CODE_HOUR_TO_SECOND) +#define SQL_INTERVAL_MINUTE_TO_SECOND (100 + SQL_CODE_MINUTE_TO_SECOND) + +#else +#define SQL_INTERVAL_YEAR (-80) +#define SQL_INTERVAL_MONTH (-81) +#define SQL_INTERVAL_YEAR_TO_MONTH (-82) +#define SQL_INTERVAL_DAY (-83) +#define SQL_INTERVAL_HOUR (-84) +#define SQL_INTERVAL_MINUTE (-85) +#define SQL_INTERVAL_SECOND (-86) +#define SQL_INTERVAL_DAY_TO_HOUR (-87) +#define SQL_INTERVAL_DAY_TO_MINUTE (-88) +#define SQL_INTERVAL_DAY_TO_SECOND (-89) +#define SQL_INTERVAL_HOUR_TO_MINUTE (-90) +#define SQL_INTERVAL_HOUR_TO_SECOND (-91) +#define SQL_INTERVAL_MINUTE_TO_SECOND (-92) +#endif /* ODBCVER >= 0x0300 */ + + +#if (ODBCVER <= 0x0300) +#define SQL_UNICODE (-95) +#define SQL_UNICODE_VARCHAR (-96) +#define SQL_UNICODE_LONGVARCHAR (-97) +#define SQL_UNICODE_CHAR SQL_UNICODE +#else +/* The previous definitions for SQL_UNICODE_ are historical and obsolete */ + +#define SQL_UNICODE SQL_WCHAR +#define SQL_UNICODE_VARCHAR SQL_WVARCHAR +#define SQL_UNICODE_LONGVARCHAR SQL_WLONGVARCHAR +#define SQL_UNICODE_CHAR SQL_WCHAR +#endif + +#if (ODBCVER < 0x0300) +#define SQL_TYPE_DRIVER_START SQL_INTERVAL_YEAR +#define SQL_TYPE_DRIVER_END SQL_UNICODE_LONGVARCHAR +#endif /* ODBCVER < 0x0300 */ + +/* C datatype to SQL datatype mapping SQL types + ------------------- */ +#define SQL_C_CHAR SQL_CHAR /* CHAR, VARCHAR, DECIMAL, NUMERIC */ +#define SQL_C_LONG SQL_INTEGER /* INTEGER */ +#define SQL_C_SHORT SQL_SMALLINT /* SMALLINT */ +#define SQL_C_FLOAT SQL_REAL /* REAL */ +#define SQL_C_DOUBLE SQL_DOUBLE /* FLOAT, DOUBLE */ +#if (ODBCVER >= 0x0300) +#define SQL_C_NUMERIC SQL_NUMERIC +#endif /* ODBCVER >= 0x0300 */ +#define SQL_C_DEFAULT 99 + +#define SQL_SIGNED_OFFSET (-20) +#define SQL_UNSIGNED_OFFSET (-22) + +/* C datatype to SQL datatype mapping */ +#define SQL_C_DATE SQL_DATE +#define SQL_C_TIME SQL_TIME +#define SQL_C_TIMESTAMP SQL_TIMESTAMP +#if (ODBCVER >= 0x0300) +#define SQL_C_TYPE_DATE SQL_TYPE_DATE +#define SQL_C_TYPE_TIME SQL_TYPE_TIME +#define SQL_C_TYPE_TIMESTAMP SQL_TYPE_TIMESTAMP +#define SQL_C_INTERVAL_YEAR SQL_INTERVAL_YEAR +#define SQL_C_INTERVAL_MONTH SQL_INTERVAL_MONTH +#define SQL_C_INTERVAL_DAY SQL_INTERVAL_DAY +#define SQL_C_INTERVAL_HOUR SQL_INTERVAL_HOUR +#define SQL_C_INTERVAL_MINUTE SQL_INTERVAL_MINUTE +#define SQL_C_INTERVAL_SECOND SQL_INTERVAL_SECOND +#define SQL_C_INTERVAL_YEAR_TO_MONTH SQL_INTERVAL_YEAR_TO_MONTH +#define SQL_C_INTERVAL_DAY_TO_HOUR SQL_INTERVAL_DAY_TO_HOUR +#define SQL_C_INTERVAL_DAY_TO_MINUTE SQL_INTERVAL_DAY_TO_MINUTE +#define SQL_C_INTERVAL_DAY_TO_SECOND SQL_INTERVAL_DAY_TO_SECOND +#define SQL_C_INTERVAL_HOUR_TO_MINUTE SQL_INTERVAL_HOUR_TO_MINUTE +#define SQL_C_INTERVAL_HOUR_TO_SECOND SQL_INTERVAL_HOUR_TO_SECOND +#define SQL_C_INTERVAL_MINUTE_TO_SECOND SQL_INTERVAL_MINUTE_TO_SECOND +#endif /* ODBCVER >= 0x0300 */ +#define SQL_C_BINARY SQL_BINARY +#define SQL_C_BIT SQL_BIT +#if (ODBCVER >= 0x0300) +#define SQL_C_SBIGINT (SQL_BIGINT+SQL_SIGNED_OFFSET) /* SIGNED BIGINT */ +#define SQL_C_UBIGINT (SQL_BIGINT+SQL_UNSIGNED_OFFSET) /* UNSIGNED BIGINT */ +#endif /* ODBCVER >= 0x0300 */ +#define SQL_C_TINYINT SQL_TINYINT +#define SQL_C_SLONG (SQL_C_LONG+SQL_SIGNED_OFFSET) /* SIGNED INTEGER */ +#define SQL_C_SSHORT (SQL_C_SHORT+SQL_SIGNED_OFFSET) /* SIGNED SMALLINT */ +#define SQL_C_STINYINT (SQL_TINYINT+SQL_SIGNED_OFFSET) /* SIGNED TINYINT */ +#define SQL_C_ULONG (SQL_C_LONG+SQL_UNSIGNED_OFFSET) /* UNSIGNED INTEGER*/ +#define SQL_C_USHORT (SQL_C_SHORT+SQL_UNSIGNED_OFFSET) /* UNSIGNED SMALLINT*/ +#define SQL_C_UTINYINT (SQL_TINYINT+SQL_UNSIGNED_OFFSET) /* UNSIGNED TINYINT*/ + +#if (ODBCVER >= 0x0300) && (SIZEOF_LONG_INT == 8) && !defined(BUILD_LEGACY_64_BIT_MODE) +#define SQL_C_BOOKMARK SQL_C_UBIGINT /* BOOKMARK */ +#else +#define SQL_C_BOOKMARK SQL_C_ULONG /* BOOKMARK */ +#endif + +#if (ODBCVER >= 0x0350) +#define SQL_C_GUID SQL_GUID +#endif /* ODBCVER >= 0x0350 */ + +#define SQL_TYPE_NULL 0 +#if (ODBCVER < 0x0300) +#define SQL_TYPE_MIN SQL_BIT +#define SQL_TYPE_MAX SQL_VARCHAR +#endif + +#if (ODBCVER >= 0x0300) +#define SQL_C_VARBOOKMARK SQL_C_BINARY +#endif /* ODBCVER >= 0x0300 */ + +/* define for SQL_DIAG_ROW_NUMBER and SQL_DIAG_COLUMN_NUMBER */ +#if (ODBCVER >= 0x0300) +#define SQL_NO_ROW_NUMBER (-1) +#define SQL_NO_COLUMN_NUMBER (-1) +#define SQL_ROW_NUMBER_UNKNOWN (-2) +#define SQL_COLUMN_NUMBER_UNKNOWN (-2) +#endif + +/* SQLBindParameter extensions */ +#define SQL_DEFAULT_PARAM (-5) +#define SQL_IGNORE (-6) +#if (ODBCVER >= 0x0300) +#define SQL_COLUMN_IGNORE SQL_IGNORE +#endif /* ODBCVER >= 0x0300 */ +#define SQL_LEN_DATA_AT_EXEC_OFFSET (-100) +#define SQL_LEN_DATA_AT_EXEC(length) (-(length)+SQL_LEN_DATA_AT_EXEC_OFFSET) + +/* binary length for driver specific attributes */ +#define SQL_LEN_BINARY_ATTR_OFFSET (-100) +#define SQL_LEN_BINARY_ATTR(length) (-(length)+SQL_LEN_BINARY_ATTR_OFFSET) + +/* Defines used by Driver Manager when mapping SQLSetParam to SQLBindParameter +*/ +#define SQL_PARAM_TYPE_DEFAULT SQL_PARAM_INPUT_OUTPUT +#define SQL_SETPARAM_VALUE_MAX (-1L) + +/* SQLColAttributes defines */ +#define SQL_COLUMN_COUNT 0 +#define SQL_COLUMN_NAME 1 +#define SQL_COLUMN_TYPE 2 +#define SQL_COLUMN_LENGTH 3 +#define SQL_COLUMN_PRECISION 4 +#define SQL_COLUMN_SCALE 5 +#define SQL_COLUMN_DISPLAY_SIZE 6 +#define SQL_COLUMN_NULLABLE 7 +#define SQL_COLUMN_UNSIGNED 8 +#define SQL_COLUMN_MONEY 9 +#define SQL_COLUMN_UPDATABLE 10 +#define SQL_COLUMN_AUTO_INCREMENT 11 +#define SQL_COLUMN_CASE_SENSITIVE 12 +#define SQL_COLUMN_SEARCHABLE 13 +#define SQL_COLUMN_TYPE_NAME 14 +#define SQL_COLUMN_TABLE_NAME 15 +#define SQL_COLUMN_OWNER_NAME 16 +#define SQL_COLUMN_QUALIFIER_NAME 17 +#define SQL_COLUMN_LABEL 18 +#define SQL_COLATT_OPT_MAX SQL_COLUMN_LABEL +#if (ODBCVER < 0x0300) +#define SQL_COLUMN_DRIVER_START 1000 +#endif /* ODBCVER < 0x0300 */ + +#define SQL_COLATT_OPT_MIN SQL_COLUMN_COUNT + +/* SQLColAttributes subdefines for SQL_COLUMN_UPDATABLE */ +#define SQL_ATTR_READONLY 0 +#define SQL_ATTR_WRITE 1 +#define SQL_ATTR_READWRITE_UNKNOWN 2 + +/* SQLColAttributes subdefines for SQL_COLUMN_SEARCHABLE */ +/* These are also used by SQLGetInfo */ +#define SQL_UNSEARCHABLE 0 +#define SQL_LIKE_ONLY 1 +#define SQL_ALL_EXCEPT_LIKE 2 +#define SQL_SEARCHABLE 3 +#define SQL_PRED_SEARCHABLE SQL_SEARCHABLE + + +/* Special return values for SQLGetData */ +#define SQL_NO_TOTAL (-4) + +/********************************************/ +/* SQLGetFunctions: additional values for */ +/* fFunction to represent functions that */ +/* are not in the X/Open spec. */ +/********************************************/ + +#if (ODBCVER >= 0x0300) +#define SQL_API_SQLALLOCHANDLESTD 73 +#define SQL_API_SQLBULKOPERATIONS 24 +#endif /* ODBCVER >= 0x0300 */ +#define SQL_API_SQLBINDPARAMETER 72 +#define SQL_API_SQLBROWSECONNECT 55 +#define SQL_API_SQLCOLATTRIBUTES 6 +#define SQL_API_SQLCOLUMNPRIVILEGES 56 +#define SQL_API_SQLDESCRIBEPARAM 58 +#define SQL_API_SQLDRIVERCONNECT 41 +#define SQL_API_SQLDRIVERS 71 +#define SQL_API_SQLEXTENDEDFETCH 59 +#define SQL_API_SQLFOREIGNKEYS 60 +#define SQL_API_SQLMORERESULTS 61 +#define SQL_API_SQLNATIVESQL 62 +#define SQL_API_SQLNUMPARAMS 63 +#define SQL_API_SQLPARAMOPTIONS 64 +#define SQL_API_SQLPRIMARYKEYS 65 +#define SQL_API_SQLPROCEDURECOLUMNS 66 +#define SQL_API_SQLPROCEDURES 67 +#define SQL_API_SQLSETPOS 68 +#define SQL_API_SQLSETSCROLLOPTIONS 69 +#define SQL_API_SQLTABLEPRIVILEGES 70 + +/*-------------------------------------------*/ +/* SQL_EXT_API_LAST is not useful with ODBC */ +/* version 3.0 because some of the values */ +/* from X/Open are in the 10000 range. */ +/*-------------------------------------------*/ + +#if (ODBCVER < 0x0300) +#define SQL_EXT_API_LAST SQL_API_SQLBINDPARAMETER +#define SQL_NUM_FUNCTIONS 23 +#define SQL_EXT_API_START 40 +#define SQL_NUM_EXTENSIONS (SQL_EXT_API_LAST-SQL_EXT_API_START+1) +#endif + +/*--------------------------------------------*/ +/* SQL_API_ALL_FUNCTIONS returns an array */ +/* of 'booleans' representing whether a */ +/* function is implemented by the driver. */ +/* */ +/* CAUTION: Only functions defined in ODBC */ +/* version 2.0 and earlier are returned, the */ +/* new high-range function numbers defined by */ +/* X/Open break this scheme. See the new */ +/* method -- SQL_API_ODBC3_ALL_FUNCTIONS */ +/*--------------------------------------------*/ + +#define SQL_API_ALL_FUNCTIONS 0 /* See CAUTION above */ + +/*----------------------------------------------*/ +/* 2.X drivers export a dummy function with */ +/* ordinal number SQL_API_LOADBYORDINAL to speed*/ +/* loading under the windows operating system. */ +/* */ +/* CAUTION: Loading by ordinal is not supported */ +/* for 3.0 and above drivers. */ +/*----------------------------------------------*/ + +#define SQL_API_LOADBYORDINAL 199 /* See CAUTION above */ + +/*----------------------------------------------*/ +/* SQL_API_ODBC3_ALL_FUNCTIONS */ +/* This returns a bitmap, which allows us to */ +/* handle the higher-valued function numbers. */ +/* Use SQL_FUNC_EXISTS(bitmap,function_number) */ +/* to determine if the function exists. */ +/*----------------------------------------------*/ + + +#if (ODBCVER >= 0x0300) +#define SQL_API_ODBC3_ALL_FUNCTIONS 999 +#define SQL_API_ODBC3_ALL_FUNCTIONS_SIZE 250 /* array of 250 words */ + + +#define SQL_FUNC_EXISTS(pfExists, uwAPI) ((*(((UWORD*) (pfExists)) + ((uwAPI) >> 4)) & (1 << ((uwAPI) & 0x000F)) ) ? SQL_TRUE : SQL_FALSE ) + +#endif /* ODBCVER >= 0x0300 */ + + +/************************************************/ +/* Extended definitions for SQLGetInfo */ +/************************************************/ + +/*---------------------------------*/ +/* Values in ODBC 2.0 that are not */ +/* in the X/Open spec */ +/*---------------------------------*/ + +#define SQL_INFO_FIRST 0 +#define SQL_ACTIVE_CONNECTIONS 0 /* MAX_DRIVER_CONNECTIONS */ +#define SQL_ACTIVE_STATEMENTS 1 /* MAX_CONCURRENT_ACTIVITIES */ +#define SQL_DRIVER_HDBC 3 +#define SQL_DRIVER_HENV 4 +#define SQL_DRIVER_HSTMT 5 +#define SQL_DRIVER_NAME 6 +#define SQL_DRIVER_VER 7 +#define SQL_ODBC_API_CONFORMANCE 9 +#define SQL_ODBC_VER 10 +#define SQL_ROW_UPDATES 11 +#define SQL_ODBC_SAG_CLI_CONFORMANCE 12 +#define SQL_ODBC_SQL_CONFORMANCE 15 +#define SQL_PROCEDURES 21 +#define SQL_CONCAT_NULL_BEHAVIOR 22 +#define SQL_CURSOR_ROLLBACK_BEHAVIOR 24 +#define SQL_EXPRESSIONS_IN_ORDERBY 27 +#define SQL_MAX_OWNER_NAME_LEN 32 /* MAX_SCHEMA_NAME_LEN */ +#define SQL_MAX_PROCEDURE_NAME_LEN 33 +#define SQL_MAX_QUALIFIER_NAME_LEN 34 /* MAX_CATALOG_NAME_LEN */ +#define SQL_MULT_RESULT_SETS 36 +#define SQL_MULTIPLE_ACTIVE_TXN 37 +#define SQL_OUTER_JOINS 38 +#define SQL_OWNER_TERM 39 +#define SQL_PROCEDURE_TERM 40 +#define SQL_QUALIFIER_NAME_SEPARATOR 41 +#define SQL_QUALIFIER_TERM 42 +#define SQL_SCROLL_OPTIONS 44 +#define SQL_TABLE_TERM 45 +#define SQL_CONVERT_FUNCTIONS 48 +#define SQL_NUMERIC_FUNCTIONS 49 +#define SQL_STRING_FUNCTIONS 50 +#define SQL_SYSTEM_FUNCTIONS 51 +#define SQL_TIMEDATE_FUNCTIONS 52 +#define SQL_CONVERT_BIGINT 53 +#define SQL_CONVERT_BINARY 54 +#define SQL_CONVERT_BIT 55 +#define SQL_CONVERT_CHAR 56 +#define SQL_CONVERT_DATE 57 +#define SQL_CONVERT_DECIMAL 58 +#define SQL_CONVERT_DOUBLE 59 +#define SQL_CONVERT_FLOAT 60 +#define SQL_CONVERT_INTEGER 61 +#define SQL_CONVERT_LONGVARCHAR 62 +#define SQL_CONVERT_NUMERIC 63 +#define SQL_CONVERT_REAL 64 +#define SQL_CONVERT_SMALLINT 65 +#define SQL_CONVERT_TIME 66 +#define SQL_CONVERT_TIMESTAMP 67 +#define SQL_CONVERT_TINYINT 68 +#define SQL_CONVERT_VARBINARY 69 +#define SQL_CONVERT_VARCHAR 70 +#define SQL_CONVERT_LONGVARBINARY 71 +#define SQL_CONVERT_GUID 173 +#define SQL_ODBC_SQL_OPT_IEF 73 /* SQL_INTEGRITY */ +#define SQL_CORRELATION_NAME 74 +#define SQL_NON_NULLABLE_COLUMNS 75 +#define SQL_DRIVER_HLIB 76 +#define SQL_DRIVER_ODBC_VER 77 +#define SQL_LOCK_TYPES 78 +#define SQL_POS_OPERATIONS 79 +#define SQL_POSITIONED_STATEMENTS 80 +#define SQL_BOOKMARK_PERSISTENCE 82 +#define SQL_STATIC_SENSITIVITY 83 +#define SQL_FILE_USAGE 84 +#define SQL_COLUMN_ALIAS 87 +#define SQL_GROUP_BY 88 +#define SQL_KEYWORDS 89 +#define SQL_OWNER_USAGE 91 +#define SQL_QUALIFIER_USAGE 92 +#define SQL_QUOTED_IDENTIFIER_CASE 93 +#define SQL_SUBQUERIES 95 +#define SQL_UNION 96 +#define SQL_MAX_ROW_SIZE_INCLUDES_LONG 103 +#define SQL_MAX_CHAR_LITERAL_LEN 108 +#define SQL_TIMEDATE_ADD_INTERVALS 109 +#define SQL_TIMEDATE_DIFF_INTERVALS 110 +#define SQL_NEED_LONG_DATA_LEN 111 +#define SQL_MAX_BINARY_LITERAL_LEN 112 +#define SQL_LIKE_ESCAPE_CLAUSE 113 +#define SQL_QUALIFIER_LOCATION 114 + +#if (ODBCVER >= 0x0201 && ODBCVER < 0x0300) +#ifndef SQL_OJ_CAPABILITIES +#define SQL_OJ_CAPABILITIES 65003 /* Temp value until ODBC 3.0 */ +#endif +#endif /* ODBCVER >= 0x0201 && ODBCVER < 0x0300 */ + +/*----------------------------------------------*/ +/* SQL_INFO_LAST and SQL_INFO_DRIVER_START are */ +/* not useful anymore, because X/Open has */ +/* values in the 10000 range. You */ +/* must contact X/Open directly to get a range */ +/* of numbers for driver-specific values. */ +/*----------------------------------------------*/ + +#if (ODBCVER < 0x0300) +#define SQL_INFO_LAST SQL_QUALIFIER_LOCATION +#define SQL_INFO_DRIVER_START 1000 +#endif /* ODBCVER < 0x0300 */ + +/*-----------------------------------------------*/ +/* ODBC 3.0 SQLGetInfo values that are not part */ +/* of the X/Open standard at this time. X/Open */ +/* standard values are in sql.h. */ +/*-----------------------------------------------*/ + +#if (ODBCVER >= 0x0300) +#define SQL_ACTIVE_ENVIRONMENTS 116 +#define SQL_ALTER_DOMAIN 117 + +#define SQL_SQL_CONFORMANCE 118 +#define SQL_DATETIME_LITERALS 119 + +#define SQL_ASYNC_MODE 10021 /* new X/Open spec */ +#define SQL_BATCH_ROW_COUNT 120 +#define SQL_BATCH_SUPPORT 121 +#define SQL_CATALOG_LOCATION SQL_QUALIFIER_LOCATION +#define SQL_CATALOG_NAME_SEPARATOR SQL_QUALIFIER_NAME_SEPARATOR +#define SQL_CATALOG_TERM SQL_QUALIFIER_TERM +#define SQL_CATALOG_USAGE SQL_QUALIFIER_USAGE +#define SQL_CONVERT_WCHAR 122 +#define SQL_CONVERT_INTERVAL_DAY_TIME 123 +#define SQL_CONVERT_INTERVAL_YEAR_MONTH 124 +#define SQL_CONVERT_WLONGVARCHAR 125 +#define SQL_CONVERT_WVARCHAR 126 +#define SQL_CREATE_ASSERTION 127 +#define SQL_CREATE_CHARACTER_SET 128 +#define SQL_CREATE_COLLATION 129 +#define SQL_CREATE_DOMAIN 130 +#define SQL_CREATE_SCHEMA 131 +#define SQL_CREATE_TABLE 132 +#define SQL_CREATE_TRANSLATION 133 +#define SQL_CREATE_VIEW 134 +#define SQL_DRIVER_HDESC 135 +#define SQL_DROP_ASSERTION 136 +#define SQL_DROP_CHARACTER_SET 137 +#define SQL_DROP_COLLATION 138 +#define SQL_DROP_DOMAIN 139 +#define SQL_DROP_SCHEMA 140 +#define SQL_DROP_TABLE 141 +#define SQL_DROP_TRANSLATION 142 +#define SQL_DROP_VIEW 143 +#define SQL_DYNAMIC_CURSOR_ATTRIBUTES1 144 +#define SQL_DYNAMIC_CURSOR_ATTRIBUTES2 145 +#define SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1 146 +#define SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2 147 +#define SQL_INDEX_KEYWORDS 148 +#define SQL_INFO_SCHEMA_VIEWS 149 +#define SQL_KEYSET_CURSOR_ATTRIBUTES1 150 +#define SQL_KEYSET_CURSOR_ATTRIBUTES2 151 +#define SQL_MAX_ASYNC_CONCURRENT_STATEMENTS 10022 /* new X/Open spec */ +#define SQL_ODBC_INTERFACE_CONFORMANCE 152 +#define SQL_PARAM_ARRAY_ROW_COUNTS 153 +#define SQL_PARAM_ARRAY_SELECTS 154 +#define SQL_SCHEMA_TERM SQL_OWNER_TERM +#define SQL_SCHEMA_USAGE SQL_OWNER_USAGE +#define SQL_SQL92_DATETIME_FUNCTIONS 155 +#define SQL_SQL92_FOREIGN_KEY_DELETE_RULE 156 +#define SQL_SQL92_FOREIGN_KEY_UPDATE_RULE 157 +#define SQL_SQL92_GRANT 158 +#define SQL_SQL92_NUMERIC_VALUE_FUNCTIONS 159 +#define SQL_SQL92_PREDICATES 160 +#define SQL_SQL92_RELATIONAL_JOIN_OPERATORS 161 +#define SQL_SQL92_REVOKE 162 +#define SQL_SQL92_ROW_VALUE_CONSTRUCTOR 163 +#define SQL_SQL92_STRING_FUNCTIONS 164 +#define SQL_SQL92_VALUE_EXPRESSIONS 165 +#define SQL_STANDARD_CLI_CONFORMANCE 166 +#define SQL_STATIC_CURSOR_ATTRIBUTES1 167 +#define SQL_STATIC_CURSOR_ATTRIBUTES2 168 + +#define SQL_AGGREGATE_FUNCTIONS 169 +#define SQL_DDL_INDEX 170 +#define SQL_DM_VER 171 +#define SQL_INSERT_STATEMENT 172 +#define SQL_UNION_STATEMENT SQL_UNION +#endif /* ODBCVER >= 0x0300 */ + +#define SQL_DTC_TRANSITION_COST 1750 + +/* SQL_ALTER_TABLE bitmasks */ +#if (ODBCVER >= 0x0300) +/* the following 5 bitmasks are defined in sql.h +*#define SQL_AT_ADD_COLUMN 0x00000001L +*#define SQL_AT_DROP_COLUMN 0x00000002L +*#define SQL_AT_ADD_CONSTRAINT 0x00000008L +*/ +#define SQL_AT_ADD_COLUMN_SINGLE 0x00000020L +#define SQL_AT_ADD_COLUMN_DEFAULT 0x00000040L +#define SQL_AT_ADD_COLUMN_COLLATION 0x00000080L +#define SQL_AT_SET_COLUMN_DEFAULT 0x00000100L +#define SQL_AT_DROP_COLUMN_DEFAULT 0x00000200L +#define SQL_AT_DROP_COLUMN_CASCADE 0x00000400L +#define SQL_AT_DROP_COLUMN_RESTRICT 0x00000800L +#define SQL_AT_ADD_TABLE_CONSTRAINT 0x00001000L +#define SQL_AT_DROP_TABLE_CONSTRAINT_CASCADE 0x00002000L +#define SQL_AT_DROP_TABLE_CONSTRAINT_RESTRICT 0x00004000L +#define SQL_AT_CONSTRAINT_NAME_DEFINITION 0x00008000L +#define SQL_AT_CONSTRAINT_INITIALLY_DEFERRED 0x00010000L +#define SQL_AT_CONSTRAINT_INITIALLY_IMMEDIATE 0x00020000L +#define SQL_AT_CONSTRAINT_DEFERRABLE 0x00040000L +#define SQL_AT_CONSTRAINT_NON_DEFERRABLE 0x00080000L +#endif /* ODBCVER >= 0x0300 */ + +/* SQL_CONVERT_* return value bitmasks */ + +#define SQL_CVT_CHAR 0x00000001L +#define SQL_CVT_NUMERIC 0x00000002L +#define SQL_CVT_DECIMAL 0x00000004L +#define SQL_CVT_INTEGER 0x00000008L +#define SQL_CVT_SMALLINT 0x00000010L +#define SQL_CVT_FLOAT 0x00000020L +#define SQL_CVT_REAL 0x00000040L +#define SQL_CVT_DOUBLE 0x00000080L +#define SQL_CVT_VARCHAR 0x00000100L +#define SQL_CVT_LONGVARCHAR 0x00000200L +#define SQL_CVT_BINARY 0x00000400L +#define SQL_CVT_VARBINARY 0x00000800L +#define SQL_CVT_BIT 0x00001000L +#define SQL_CVT_TINYINT 0x00002000L +#define SQL_CVT_BIGINT 0x00004000L +#define SQL_CVT_DATE 0x00008000L +#define SQL_CVT_TIME 0x00010000L +#define SQL_CVT_TIMESTAMP 0x00020000L +#define SQL_CVT_LONGVARBINARY 0x00040000L +#if (ODBCVER >= 0x0300) +#define SQL_CVT_INTERVAL_YEAR_MONTH 0x00080000L +#define SQL_CVT_INTERVAL_DAY_TIME 0x00100000L +#define SQL_CVT_WCHAR 0x00200000L +#define SQL_CVT_WLONGVARCHAR 0x00400000L +#define SQL_CVT_WVARCHAR 0x00800000L +#define SQL_CVT_GUID 0x01000000L + +#endif /* ODBCVER >= 0x0300 */ + + +/* SQL_CONVERT_FUNCTIONS functions */ +#define SQL_FN_CVT_CONVERT 0x00000001L +#if (ODBCVER >= 0x0300) +#define SQL_FN_CVT_CAST 0x00000002L +#endif /* ODBCVER >= 0x0300 */ + + +/* SQL_STRING_FUNCTIONS functions */ + +#define SQL_FN_STR_CONCAT 0x00000001L +#define SQL_FN_STR_INSERT 0x00000002L +#define SQL_FN_STR_LEFT 0x00000004L +#define SQL_FN_STR_LTRIM 0x00000008L +#define SQL_FN_STR_LENGTH 0x00000010L +#define SQL_FN_STR_LOCATE 0x00000020L +#define SQL_FN_STR_LCASE 0x00000040L +#define SQL_FN_STR_REPEAT 0x00000080L +#define SQL_FN_STR_REPLACE 0x00000100L +#define SQL_FN_STR_RIGHT 0x00000200L +#define SQL_FN_STR_RTRIM 0x00000400L +#define SQL_FN_STR_SUBSTRING 0x00000800L +#define SQL_FN_STR_UCASE 0x00001000L +#define SQL_FN_STR_ASCII 0x00002000L +#define SQL_FN_STR_CHAR 0x00004000L +#define SQL_FN_STR_DIFFERENCE 0x00008000L +#define SQL_FN_STR_LOCATE_2 0x00010000L +#define SQL_FN_STR_SOUNDEX 0x00020000L +#define SQL_FN_STR_SPACE 0x00040000L +#if (ODBCVER >= 0x0300) +#define SQL_FN_STR_BIT_LENGTH 0x00080000L +#define SQL_FN_STR_CHAR_LENGTH 0x00100000L +#define SQL_FN_STR_CHARACTER_LENGTH 0x00200000L +#define SQL_FN_STR_OCTET_LENGTH 0x00400000L +#define SQL_FN_STR_POSITION 0x00800000L +#endif /* ODBCVER >= 0x0300 */ + +/* SQL_SQL92_STRING_FUNCTIONS */ +#if (ODBCVER >= 0x0300) +#define SQL_SSF_CONVERT 0x00000001L +#define SQL_SSF_LOWER 0x00000002L +#define SQL_SSF_UPPER 0x00000004L +#define SQL_SSF_SUBSTRING 0x00000008L +#define SQL_SSF_TRANSLATE 0x00000010L +#define SQL_SSF_TRIM_BOTH 0x00000020L +#define SQL_SSF_TRIM_LEADING 0x00000040L +#define SQL_SSF_TRIM_TRAILING 0x00000080L +#endif /* ODBCVER >= 0x0300 */ + +/* SQL_NUMERIC_FUNCTIONS functions */ + +#define SQL_FN_NUM_ABS 0x00000001L +#define SQL_FN_NUM_ACOS 0x00000002L +#define SQL_FN_NUM_ASIN 0x00000004L +#define SQL_FN_NUM_ATAN 0x00000008L +#define SQL_FN_NUM_ATAN2 0x00000010L +#define SQL_FN_NUM_CEILING 0x00000020L +#define SQL_FN_NUM_COS 0x00000040L +#define SQL_FN_NUM_COT 0x00000080L +#define SQL_FN_NUM_EXP 0x00000100L +#define SQL_FN_NUM_FLOOR 0x00000200L +#define SQL_FN_NUM_LOG 0x00000400L +#define SQL_FN_NUM_MOD 0x00000800L +#define SQL_FN_NUM_SIGN 0x00001000L +#define SQL_FN_NUM_SIN 0x00002000L +#define SQL_FN_NUM_SQRT 0x00004000L +#define SQL_FN_NUM_TAN 0x00008000L +#define SQL_FN_NUM_PI 0x00010000L +#define SQL_FN_NUM_RAND 0x00020000L +#define SQL_FN_NUM_DEGREES 0x00040000L +#define SQL_FN_NUM_LOG10 0x00080000L +#define SQL_FN_NUM_POWER 0x00100000L +#define SQL_FN_NUM_RADIANS 0x00200000L +#define SQL_FN_NUM_ROUND 0x00400000L +#define SQL_FN_NUM_TRUNCATE 0x00800000L + +/* SQL_SQL92_NUMERIC_VALUE_FUNCTIONS */ +#if (ODBCVER >= 0x0300) +#define SQL_SNVF_BIT_LENGTH 0x00000001L +#define SQL_SNVF_CHAR_LENGTH 0x00000002L +#define SQL_SNVF_CHARACTER_LENGTH 0x00000004L +#define SQL_SNVF_EXTRACT 0x00000008L +#define SQL_SNVF_OCTET_LENGTH 0x00000010L +#define SQL_SNVF_POSITION 0x00000020L +#endif /* ODBCVER >= 0x0300 */ + +/* SQL_TIMEDATE_FUNCTIONS functions */ + +#define SQL_FN_TD_NOW 0x00000001L +#define SQL_FN_TD_CURDATE 0x00000002L +#define SQL_FN_TD_DAYOFMONTH 0x00000004L +#define SQL_FN_TD_DAYOFWEEK 0x00000008L +#define SQL_FN_TD_DAYOFYEAR 0x00000010L +#define SQL_FN_TD_MONTH 0x00000020L +#define SQL_FN_TD_QUARTER 0x00000040L +#define SQL_FN_TD_WEEK 0x00000080L +#define SQL_FN_TD_YEAR 0x00000100L +#define SQL_FN_TD_CURTIME 0x00000200L +#define SQL_FN_TD_HOUR 0x00000400L +#define SQL_FN_TD_MINUTE 0x00000800L +#define SQL_FN_TD_SECOND 0x00001000L +#define SQL_FN_TD_TIMESTAMPADD 0x00002000L +#define SQL_FN_TD_TIMESTAMPDIFF 0x00004000L +#define SQL_FN_TD_DAYNAME 0x00008000L +#define SQL_FN_TD_MONTHNAME 0x00010000L +#if (ODBCVER >= 0x0300) +#define SQL_FN_TD_CURRENT_DATE 0x00020000L +#define SQL_FN_TD_CURRENT_TIME 0x00040000L +#define SQL_FN_TD_CURRENT_TIMESTAMP 0x00080000L +#define SQL_FN_TD_EXTRACT 0x00100000L +#endif /* ODBCVER >= 0x0300 */ + +/* SQL_SQL92_DATETIME_FUNCTIONS */ +#if (ODBCVER >= 0x0300) +#define SQL_SDF_CURRENT_DATE 0x00000001L +#define SQL_SDF_CURRENT_TIME 0x00000002L +#define SQL_SDF_CURRENT_TIMESTAMP 0x00000004L +#endif /* ODBCVER >= 0x0300 */ + +/* SQL_SYSTEM_FUNCTIONS functions */ + +#define SQL_FN_SYS_USERNAME 0x00000001L +#define SQL_FN_SYS_DBNAME 0x00000002L +#define SQL_FN_SYS_IFNULL 0x00000004L + +/* SQL_TIMEDATE_ADD_INTERVALS and SQL_TIMEDATE_DIFF_INTERVALS functions */ + +#define SQL_FN_TSI_FRAC_SECOND 0x00000001L +#define SQL_FN_TSI_SECOND 0x00000002L +#define SQL_FN_TSI_MINUTE 0x00000004L +#define SQL_FN_TSI_HOUR 0x00000008L +#define SQL_FN_TSI_DAY 0x00000010L +#define SQL_FN_TSI_WEEK 0x00000020L +#define SQL_FN_TSI_MONTH 0x00000040L +#define SQL_FN_TSI_QUARTER 0x00000080L +#define SQL_FN_TSI_YEAR 0x00000100L + +/* bitmasks for SQL_DYNAMIC_CURSOR_ATTRIBUTES1, + * SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1, + * SQL_KEYSET_CURSOR_ATTRIBUTES1, and SQL_STATIC_CURSOR_ATTRIBUTES1 + */ +#if (ODBCVER >= 0x0300) +/* supported SQLFetchScroll FetchOrientation's */ +#define SQL_CA1_NEXT 0x00000001L +#define SQL_CA1_ABSOLUTE 0x00000002L +#define SQL_CA1_RELATIVE 0x00000004L +#define SQL_CA1_BOOKMARK 0x00000008L + +/* supported SQLSetPos LockType's */ +#define SQL_CA1_LOCK_NO_CHANGE 0x00000040L +#define SQL_CA1_LOCK_EXCLUSIVE 0x00000080L +#define SQL_CA1_LOCK_UNLOCK 0x00000100L + +/* supported SQLSetPos Operations */ +#define SQL_CA1_POS_POSITION 0x00000200L +#define SQL_CA1_POS_UPDATE 0x00000400L +#define SQL_CA1_POS_DELETE 0x00000800L +#define SQL_CA1_POS_REFRESH 0x00001000L + +/* positioned updates and deletes */ +#define SQL_CA1_POSITIONED_UPDATE 0x00002000L +#define SQL_CA1_POSITIONED_DELETE 0x00004000L +#define SQL_CA1_SELECT_FOR_UPDATE 0x00008000L + +/* supported SQLBulkOperations operations */ +#define SQL_CA1_BULK_ADD 0x00010000L +#define SQL_CA1_BULK_UPDATE_BY_BOOKMARK 0x00020000L +#define SQL_CA1_BULK_DELETE_BY_BOOKMARK 0x00040000L +#define SQL_CA1_BULK_FETCH_BY_BOOKMARK 0x00080000L +#endif /* ODBCVER >= 0x0300 */ + +/* bitmasks for SQL_DYNAMIC_CURSOR_ATTRIBUTES2, + * SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2, + * SQL_KEYSET_CURSOR_ATTRIBUTES2, and SQL_STATIC_CURSOR_ATTRIBUTES2 + */ +#if (ODBCVER >= 0x0300) +/* supported values for SQL_ATTR_SCROLL_CONCURRENCY */ +#define SQL_CA2_READ_ONLY_CONCURRENCY 0x00000001L +#define SQL_CA2_LOCK_CONCURRENCY 0x00000002L +#define SQL_CA2_OPT_ROWVER_CONCURRENCY 0x00000004L +#define SQL_CA2_OPT_VALUES_CONCURRENCY 0x00000008L + +/* sensitivity of the cursor to its own inserts, deletes, and updates */ +#define SQL_CA2_SENSITIVITY_ADDITIONS 0x00000010L +#define SQL_CA2_SENSITIVITY_DELETIONS 0x00000020L +#define SQL_CA2_SENSITIVITY_UPDATES 0x00000040L + +/* semantics of SQL_ATTR_MAX_ROWS */ +#define SQL_CA2_MAX_ROWS_SELECT 0x00000080L +#define SQL_CA2_MAX_ROWS_INSERT 0x00000100L +#define SQL_CA2_MAX_ROWS_DELETE 0x00000200L +#define SQL_CA2_MAX_ROWS_UPDATE 0x00000400L +#define SQL_CA2_MAX_ROWS_CATALOG 0x00000800L +#define SQL_CA2_MAX_ROWS_AFFECTS_ALL (SQL_CA2_MAX_ROWS_SELECT | SQL_CA2_MAX_ROWS_INSERT | SQL_CA2_MAX_ROWS_DELETE | SQL_CA2_MAX_ROWS_UPDATE | SQL_CA2_MAX_ROWS_CATALOG) + +/* semantics of SQL_DIAG_CURSOR_ROW_COUNT */ +#define SQL_CA2_CRC_EXACT 0x00001000L +#define SQL_CA2_CRC_APPROXIMATE 0x00002000L + +/* the kinds of positioned statements that can be simulated */ +#define SQL_CA2_SIMULATE_NON_UNIQUE 0x00004000L +#define SQL_CA2_SIMULATE_TRY_UNIQUE 0x00008000L +#define SQL_CA2_SIMULATE_UNIQUE 0x00010000L +#endif /* ODBCVER >= 0x0300 */ + +/* SQL_ODBC_API_CONFORMANCE values */ + +#define SQL_OAC_NONE 0x0000 +#define SQL_OAC_LEVEL1 0x0001 +#define SQL_OAC_LEVEL2 0x0002 + +/* SQL_ODBC_SAG_CLI_CONFORMANCE values */ + +#define SQL_OSCC_NOT_COMPLIANT 0x0000 +#define SQL_OSCC_COMPLIANT 0x0001 + +/* SQL_ODBC_SQL_CONFORMANCE values */ + +#define SQL_OSC_MINIMUM 0x0000 +#define SQL_OSC_CORE 0x0001 +#define SQL_OSC_EXTENDED 0x0002 + + +/* SQL_CONCAT_NULL_BEHAVIOR values */ + +#define SQL_CB_NULL 0x0000 +#define SQL_CB_NON_NULL 0x0001 + +/* SQL_SCROLL_OPTIONS masks */ + +#define SQL_SO_FORWARD_ONLY 0x00000001L +#define SQL_SO_KEYSET_DRIVEN 0x00000002L +#define SQL_SO_DYNAMIC 0x00000004L +#define SQL_SO_MIXED 0x00000008L +#define SQL_SO_STATIC 0x00000010L + +/* SQL_FETCH_DIRECTION masks */ + +/* SQL_FETCH_RESUME is no longer supported +#define SQL_FD_FETCH_RESUME 0x00000040L +*/ +#define SQL_FD_FETCH_BOOKMARK 0x00000080L + +/* SQL_TXN_ISOLATION_OPTION masks */ +/* SQL_TXN_VERSIONING is no longer supported +#define SQL_TXN_VERSIONING 0x00000010L +*/ + +/* SQL_CORRELATION_NAME values */ + +#define SQL_CN_NONE 0x0000 +#define SQL_CN_DIFFERENT 0x0001 +#define SQL_CN_ANY 0x0002 + +/* SQL_NON_NULLABLE_COLUMNS values */ + +#define SQL_NNC_NULL 0x0000 +#define SQL_NNC_NON_NULL 0x0001 + +/* SQL_NULL_COLLATION values */ + +#define SQL_NC_START 0x0002 +#define SQL_NC_END 0x0004 + +/* SQL_FILE_USAGE values */ + +#define SQL_FILE_NOT_SUPPORTED 0x0000 +#define SQL_FILE_TABLE 0x0001 +#define SQL_FILE_QUALIFIER 0x0002 +#define SQL_FILE_CATALOG SQL_FILE_QUALIFIER /* ODBC 3.0 */ + + +/* SQL_GETDATA_EXTENSIONS values */ + +#define SQL_GD_BLOCK 0x00000004L +#define SQL_GD_BOUND 0x00000008L + +/* SQL_POSITIONED_STATEMENTS masks */ + +#define SQL_PS_POSITIONED_DELETE 0x00000001L +#define SQL_PS_POSITIONED_UPDATE 0x00000002L +#define SQL_PS_SELECT_FOR_UPDATE 0x00000004L + +/* SQL_GROUP_BY values */ + +#define SQL_GB_NOT_SUPPORTED 0x0000 +#define SQL_GB_GROUP_BY_EQUALS_SELECT 0x0001 +#define SQL_GB_GROUP_BY_CONTAINS_SELECT 0x0002 +#define SQL_GB_NO_RELATION 0x0003 +#if (ODBCVER >= 0x0300) +#define SQL_GB_COLLATE 0x0004 + +#endif /* ODBCVER >= 0x0300 */ + +/* SQL_OWNER_USAGE masks */ + +#define SQL_OU_DML_STATEMENTS 0x00000001L +#define SQL_OU_PROCEDURE_INVOCATION 0x00000002L +#define SQL_OU_TABLE_DEFINITION 0x00000004L +#define SQL_OU_INDEX_DEFINITION 0x00000008L +#define SQL_OU_PRIVILEGE_DEFINITION 0x00000010L + +/* SQL_SCHEMA_USAGE masks */ +#if (ODBCVER >= 0x0300) +#define SQL_SU_DML_STATEMENTS SQL_OU_DML_STATEMENTS +#define SQL_SU_PROCEDURE_INVOCATION SQL_OU_PROCEDURE_INVOCATION +#define SQL_SU_TABLE_DEFINITION SQL_OU_TABLE_DEFINITION +#define SQL_SU_INDEX_DEFINITION SQL_OU_INDEX_DEFINITION +#define SQL_SU_PRIVILEGE_DEFINITION SQL_OU_PRIVILEGE_DEFINITION +#endif /* ODBCVER >= 0x0300 */ + +/* SQL_QUALIFIER_USAGE masks */ + +#define SQL_QU_DML_STATEMENTS 0x00000001L +#define SQL_QU_PROCEDURE_INVOCATION 0x00000002L +#define SQL_QU_TABLE_DEFINITION 0x00000004L +#define SQL_QU_INDEX_DEFINITION 0x00000008L +#define SQL_QU_PRIVILEGE_DEFINITION 0x00000010L + +#if (ODBCVER >= 0x0300) +/* SQL_CATALOG_USAGE masks */ +#define SQL_CU_DML_STATEMENTS SQL_QU_DML_STATEMENTS +#define SQL_CU_PROCEDURE_INVOCATION SQL_QU_PROCEDURE_INVOCATION +#define SQL_CU_TABLE_DEFINITION SQL_QU_TABLE_DEFINITION +#define SQL_CU_INDEX_DEFINITION SQL_QU_INDEX_DEFINITION +#define SQL_CU_PRIVILEGE_DEFINITION SQL_QU_PRIVILEGE_DEFINITION +#endif /* ODBCVER >= 0x0300 */ + +/* SQL_SUBQUERIES masks */ + +#define SQL_SQ_COMPARISON 0x00000001L +#define SQL_SQ_EXISTS 0x00000002L +#define SQL_SQ_IN 0x00000004L +#define SQL_SQ_QUANTIFIED 0x00000008L +#define SQL_SQ_CORRELATED_SUBQUERIES 0x00000010L + +/* SQL_UNION masks */ + +#define SQL_U_UNION 0x00000001L +#define SQL_U_UNION_ALL 0x00000002L + +/* SQL_BOOKMARK_PERSISTENCE values */ + +#define SQL_BP_CLOSE 0x00000001L +#define SQL_BP_DELETE 0x00000002L +#define SQL_BP_DROP 0x00000004L +#define SQL_BP_TRANSACTION 0x00000008L +#define SQL_BP_UPDATE 0x00000010L +#define SQL_BP_OTHER_HSTMT 0x00000020L +#define SQL_BP_SCROLL 0x00000040L + +/* SQL_STATIC_SENSITIVITY values */ + +#define SQL_SS_ADDITIONS 0x00000001L +#define SQL_SS_DELETIONS 0x00000002L +#define SQL_SS_UPDATES 0x00000004L + +/* SQL_VIEW values */ +#define SQL_CV_CREATE_VIEW 0x00000001L +#define SQL_CV_CHECK_OPTION 0x00000002L +#define SQL_CV_CASCADED 0x00000004L +#define SQL_CV_LOCAL 0x00000008L + +/* SQL_LOCK_TYPES masks */ + +#define SQL_LCK_NO_CHANGE 0x00000001L +#define SQL_LCK_EXCLUSIVE 0x00000002L +#define SQL_LCK_UNLOCK 0x00000004L + +/* SQL_POS_OPERATIONS masks */ + +#define SQL_POS_POSITION 0x00000001L +#define SQL_POS_REFRESH 0x00000002L +#define SQL_POS_UPDATE 0x00000004L +#define SQL_POS_DELETE 0x00000008L +#define SQL_POS_ADD 0x00000010L + +/* SQL_QUALIFIER_LOCATION values */ + +#define SQL_QL_START 0x0001 +#define SQL_QL_END 0x0002 + +/* Here start return values for ODBC 3.0 SQLGetInfo */ + +#if (ODBCVER >= 0x0300) +/* SQL_AGGREGATE_FUNCTIONS bitmasks */ +#define SQL_AF_AVG 0x00000001L +#define SQL_AF_COUNT 0x00000002L +#define SQL_AF_MAX 0x00000004L +#define SQL_AF_MIN 0x00000008L +#define SQL_AF_SUM 0x00000010L +#define SQL_AF_DISTINCT 0x00000020L +#define SQL_AF_ALL 0x00000040L + +/* SQL_SQL_CONFORMANCE bit masks */ +#define SQL_SC_SQL92_ENTRY 0x00000001L +#define SQL_SC_FIPS127_2_TRANSITIONAL 0x00000002L +#define SQL_SC_SQL92_INTERMEDIATE 0x00000004L +#define SQL_SC_SQL92_FULL 0x00000008L + +/* SQL_DATETIME_LITERALS masks */ +#define SQL_DL_SQL92_DATE 0x00000001L +#define SQL_DL_SQL92_TIME 0x00000002L +#define SQL_DL_SQL92_TIMESTAMP 0x00000004L +#define SQL_DL_SQL92_INTERVAL_YEAR 0x00000008L +#define SQL_DL_SQL92_INTERVAL_MONTH 0x00000010L +#define SQL_DL_SQL92_INTERVAL_DAY 0x00000020L +#define SQL_DL_SQL92_INTERVAL_HOUR 0x00000040L +#define SQL_DL_SQL92_INTERVAL_MINUTE 0x00000080L +#define SQL_DL_SQL92_INTERVAL_SECOND 0x00000100L +#define SQL_DL_SQL92_INTERVAL_YEAR_TO_MONTH 0x00000200L +#define SQL_DL_SQL92_INTERVAL_DAY_TO_HOUR 0x00000400L +#define SQL_DL_SQL92_INTERVAL_DAY_TO_MINUTE 0x00000800L +#define SQL_DL_SQL92_INTERVAL_DAY_TO_SECOND 0x00001000L +#define SQL_DL_SQL92_INTERVAL_HOUR_TO_MINUTE 0x00002000L +#define SQL_DL_SQL92_INTERVAL_HOUR_TO_SECOND 0x00004000L +#define SQL_DL_SQL92_INTERVAL_MINUTE_TO_SECOND 0x00008000L + +/* SQL_CATALOG_LOCATION values */ +#define SQL_CL_START SQL_QL_START +#define SQL_CL_END SQL_QL_END + +/* values for SQL_BATCH_ROW_COUNT */ +#define SQL_BRC_PROCEDURES 0x0000001 +#define SQL_BRC_EXPLICIT 0x0000002 +#define SQL_BRC_ROLLED_UP 0x0000004 + +/* bitmasks for SQL_BATCH_SUPPORT */ +#define SQL_BS_SELECT_EXPLICIT 0x00000001L +#define SQL_BS_ROW_COUNT_EXPLICIT 0x00000002L +#define SQL_BS_SELECT_PROC 0x00000004L +#define SQL_BS_ROW_COUNT_PROC 0x00000008L + +/* Values for SQL_PARAM_ARRAY_ROW_COUNTS getinfo */ +#define SQL_PARC_BATCH 1 +#define SQL_PARC_NO_BATCH 2 + +/* values for SQL_PARAM_ARRAY_SELECTS */ +#define SQL_PAS_BATCH 1 +#define SQL_PAS_NO_BATCH 2 +#define SQL_PAS_NO_SELECT 3 + +/* Bitmasks for SQL_INDEX_KEYWORDS */ +#define SQL_IK_NONE 0x00000000L +#define SQL_IK_ASC 0x00000001L +#define SQL_IK_DESC 0x00000002L +#define SQL_IK_ALL (SQL_IK_ASC | SQL_IK_DESC) + +/* Bitmasks for SQL_INFO_SCHEMA_VIEWS */ + +#define SQL_ISV_ASSERTIONS 0x00000001L +#define SQL_ISV_CHARACTER_SETS 0x00000002L +#define SQL_ISV_CHECK_CONSTRAINTS 0x00000004L +#define SQL_ISV_COLLATIONS 0x00000008L +#define SQL_ISV_COLUMN_DOMAIN_USAGE 0x00000010L +#define SQL_ISV_COLUMN_PRIVILEGES 0x00000020L +#define SQL_ISV_COLUMNS 0x00000040L +#define SQL_ISV_CONSTRAINT_COLUMN_USAGE 0x00000080L +#define SQL_ISV_CONSTRAINT_TABLE_USAGE 0x00000100L +#define SQL_ISV_DOMAIN_CONSTRAINTS 0x00000200L +#define SQL_ISV_DOMAINS 0x00000400L +#define SQL_ISV_KEY_COLUMN_USAGE 0x00000800L +#define SQL_ISV_REFERENTIAL_CONSTRAINTS 0x00001000L +#define SQL_ISV_SCHEMATA 0x00002000L +#define SQL_ISV_SQL_LANGUAGES 0x00004000L +#define SQL_ISV_TABLE_CONSTRAINTS 0x00008000L +#define SQL_ISV_TABLE_PRIVILEGES 0x00010000L +#define SQL_ISV_TABLES 0x00020000L +#define SQL_ISV_TRANSLATIONS 0x00040000L +#define SQL_ISV_USAGE_PRIVILEGES 0x00080000L +#define SQL_ISV_VIEW_COLUMN_USAGE 0x00100000L +#define SQL_ISV_VIEW_TABLE_USAGE 0x00200000L +#define SQL_ISV_VIEWS 0x00400000L + +/* Bitmasks for SQL_ASYNC_MODE */ + +#define SQL_AM_NONE 0 +#define SQL_AM_CONNECTION 1 +#define SQL_AM_STATEMENT 2 + +/* Bitmasks for SQL_ALTER_DOMAIN */ +#define SQL_AD_CONSTRAINT_NAME_DEFINITION 0x00000001L +#define SQL_AD_ADD_DOMAIN_CONSTRAINT 0x00000002L +#define SQL_AD_DROP_DOMAIN_CONSTRAINT 0x00000004L +#define SQL_AD_ADD_DOMAIN_DEFAULT 0x00000008L +#define SQL_AD_DROP_DOMAIN_DEFAULT 0x00000010L +#define SQL_AD_ADD_CONSTRAINT_INITIALLY_DEFERRED 0x00000020L +#define SQL_AD_ADD_CONSTRAINT_INITIALLY_IMMEDIATE 0x00000040L +#define SQL_AD_ADD_CONSTRAINT_DEFERRABLE 0x00000080L +#define SQL_AD_ADD_CONSTRAINT_NON_DEFERRABLE 0x00000100L + + +/* SQL_CREATE_SCHEMA bitmasks */ +#define SQL_CS_CREATE_SCHEMA 0x00000001L +#define SQL_CS_AUTHORIZATION 0x00000002L +#define SQL_CS_DEFAULT_CHARACTER_SET 0x00000004L + +/* SQL_CREATE_TRANSLATION bitmasks */ +#define SQL_CTR_CREATE_TRANSLATION 0x00000001L + +/* SQL_CREATE_ASSERTION bitmasks */ +#define SQL_CA_CREATE_ASSERTION 0x00000001L +#define SQL_CA_CONSTRAINT_INITIALLY_DEFERRED 0x00000010L +#define SQL_CA_CONSTRAINT_INITIALLY_IMMEDIATE 0x00000020L +#define SQL_CA_CONSTRAINT_DEFERRABLE 0x00000040L +#define SQL_CA_CONSTRAINT_NON_DEFERRABLE 0x00000080L + +/* SQL_CREATE_CHARACTER_SET bitmasks */ +#define SQL_CCS_CREATE_CHARACTER_SET 0x00000001L +#define SQL_CCS_COLLATE_CLAUSE 0x00000002L +#define SQL_CCS_LIMITED_COLLATION 0x00000004L + +/* SQL_CREATE_COLLATION bitmasks */ +#define SQL_CCOL_CREATE_COLLATION 0x00000001L + +/* SQL_CREATE_DOMAIN bitmasks */ +#define SQL_CDO_CREATE_DOMAIN 0x00000001L +#define SQL_CDO_DEFAULT 0x00000002L +#define SQL_CDO_CONSTRAINT 0x00000004L +#define SQL_CDO_COLLATION 0x00000008L +#define SQL_CDO_CONSTRAINT_NAME_DEFINITION 0x00000010L +#define SQL_CDO_CONSTRAINT_INITIALLY_DEFERRED 0x00000020L +#define SQL_CDO_CONSTRAINT_INITIALLY_IMMEDIATE 0x00000040L +#define SQL_CDO_CONSTRAINT_DEFERRABLE 0x00000080L +#define SQL_CDO_CONSTRAINT_NON_DEFERRABLE 0x00000100L + +/* SQL_CREATE_TABLE bitmasks */ +#define SQL_CT_CREATE_TABLE 0x00000001L +#define SQL_CT_COMMIT_PRESERVE 0x00000002L +#define SQL_CT_COMMIT_DELETE 0x00000004L +#define SQL_CT_GLOBAL_TEMPORARY 0x00000008L +#define SQL_CT_LOCAL_TEMPORARY 0x00000010L +#define SQL_CT_CONSTRAINT_INITIALLY_DEFERRED 0x00000020L +#define SQL_CT_CONSTRAINT_INITIALLY_IMMEDIATE 0x00000040L +#define SQL_CT_CONSTRAINT_DEFERRABLE 0x00000080L +#define SQL_CT_CONSTRAINT_NON_DEFERRABLE 0x00000100L +#define SQL_CT_COLUMN_CONSTRAINT 0x00000200L +#define SQL_CT_COLUMN_DEFAULT 0x00000400L +#define SQL_CT_COLUMN_COLLATION 0x00000800L +#define SQL_CT_TABLE_CONSTRAINT 0x00001000L +#define SQL_CT_CONSTRAINT_NAME_DEFINITION 0x00002000L + +/* SQL_DDL_INDEX bitmasks */ +#define SQL_DI_CREATE_INDEX 0x00000001L +#define SQL_DI_DROP_INDEX 0x00000002L + +/* SQL_DROP_COLLATION bitmasks */ +#define SQL_DC_DROP_COLLATION 0x00000001L + +/* SQL_DROP_DOMAIN bitmasks */ +#define SQL_DD_DROP_DOMAIN 0x00000001L +#define SQL_DD_RESTRICT 0x00000002L +#define SQL_DD_CASCADE 0x00000004L + +/* SQL_DROP_SCHEMA bitmasks */ +#define SQL_DS_DROP_SCHEMA 0x00000001L +#define SQL_DS_RESTRICT 0x00000002L +#define SQL_DS_CASCADE 0x00000004L + +/* SQL_DROP_CHARACTER_SET bitmasks */ +#define SQL_DCS_DROP_CHARACTER_SET 0x00000001L + +/* SQL_DROP_ASSERTION bitmasks */ +#define SQL_DA_DROP_ASSERTION 0x00000001L + +/* SQL_DROP_TABLE bitmasks */ +#define SQL_DT_DROP_TABLE 0x00000001L +#define SQL_DT_RESTRICT 0x00000002L +#define SQL_DT_CASCADE 0x00000004L + +/* SQL_DROP_TRANSLATION bitmasks */ +#define SQL_DTR_DROP_TRANSLATION 0x00000001L + +/* SQL_DROP_VIEW bitmasks */ +#define SQL_DV_DROP_VIEW 0x00000001L +#define SQL_DV_RESTRICT 0x00000002L +#define SQL_DV_CASCADE 0x00000004L + +/* SQL_INSERT_STATEMENT bitmasks */ +#define SQL_IS_INSERT_LITERALS 0x00000001L +#define SQL_IS_INSERT_SEARCHED 0x00000002L +#define SQL_IS_SELECT_INTO 0x00000004L + +/* SQL_ODBC_INTERFACE_CONFORMANCE values */ +#define SQL_OIC_CORE 1UL +#define SQL_OIC_LEVEL1 2UL +#define SQL_OIC_LEVEL2 3UL + +/* SQL_SQL92_FOREIGN_KEY_DELETE_RULE bitmasks */ +#define SQL_SFKD_CASCADE 0x00000001L +#define SQL_SFKD_NO_ACTION 0x00000002L +#define SQL_SFKD_SET_DEFAULT 0x00000004L +#define SQL_SFKD_SET_NULL 0x00000008L + +/* SQL_SQL92_FOREIGN_KEY_UPDATE_RULE bitmasks */ +#define SQL_SFKU_CASCADE 0x00000001L +#define SQL_SFKU_NO_ACTION 0x00000002L +#define SQL_SFKU_SET_DEFAULT 0x00000004L +#define SQL_SFKU_SET_NULL 0x00000008L + +/* SQL_SQL92_GRANT bitmasks */ +#define SQL_SG_USAGE_ON_DOMAIN 0x00000001L +#define SQL_SG_USAGE_ON_CHARACTER_SET 0x00000002L +#define SQL_SG_USAGE_ON_COLLATION 0x00000004L +#define SQL_SG_USAGE_ON_TRANSLATION 0x00000008L +#define SQL_SG_WITH_GRANT_OPTION 0x00000010L +#define SQL_SG_DELETE_TABLE 0x00000020L +#define SQL_SG_INSERT_TABLE 0x00000040L +#define SQL_SG_INSERT_COLUMN 0x00000080L +#define SQL_SG_REFERENCES_TABLE 0x00000100L +#define SQL_SG_REFERENCES_COLUMN 0x00000200L +#define SQL_SG_SELECT_TABLE 0x00000400L +#define SQL_SG_UPDATE_TABLE 0x00000800L +#define SQL_SG_UPDATE_COLUMN 0x00001000L + +/* SQL_SQL92_PREDICATES bitmasks */ +#define SQL_SP_EXISTS 0x00000001L +#define SQL_SP_ISNOTNULL 0x00000002L +#define SQL_SP_ISNULL 0x00000004L +#define SQL_SP_MATCH_FULL 0x00000008L +#define SQL_SP_MATCH_PARTIAL 0x00000010L +#define SQL_SP_MATCH_UNIQUE_FULL 0x00000020L +#define SQL_SP_MATCH_UNIQUE_PARTIAL 0x00000040L +#define SQL_SP_OVERLAPS 0x00000080L +#define SQL_SP_UNIQUE 0x00000100L +#define SQL_SP_LIKE 0x00000200L +#define SQL_SP_IN 0x00000400L +#define SQL_SP_BETWEEN 0x00000800L +#define SQL_SP_COMPARISON 0x00001000L +#define SQL_SP_QUANTIFIED_COMPARISON 0x00002000L + +/* SQL_SQL92_RELATIONAL_JOIN_OPERATORS bitmasks */ +#define SQL_SRJO_CORRESPONDING_CLAUSE 0x00000001L +#define SQL_SRJO_CROSS_JOIN 0x00000002L +#define SQL_SRJO_EXCEPT_JOIN 0x00000004L +#define SQL_SRJO_FULL_OUTER_JOIN 0x00000008L +#define SQL_SRJO_INNER_JOIN 0x00000010L +#define SQL_SRJO_INTERSECT_JOIN 0x00000020L +#define SQL_SRJO_LEFT_OUTER_JOIN 0x00000040L +#define SQL_SRJO_NATURAL_JOIN 0x00000080L +#define SQL_SRJO_RIGHT_OUTER_JOIN 0x00000100L +#define SQL_SRJO_UNION_JOIN 0x00000200L + +/* SQL_SQL92_REVOKE bitmasks */ +#define SQL_SR_USAGE_ON_DOMAIN 0x00000001L +#define SQL_SR_USAGE_ON_CHARACTER_SET 0x00000002L +#define SQL_SR_USAGE_ON_COLLATION 0x00000004L +#define SQL_SR_USAGE_ON_TRANSLATION 0x00000008L +#define SQL_SR_GRANT_OPTION_FOR 0x00000010L +#define SQL_SR_CASCADE 0x00000020L +#define SQL_SR_RESTRICT 0x00000040L +#define SQL_SR_DELETE_TABLE 0x00000080L +#define SQL_SR_INSERT_TABLE 0x00000100L +#define SQL_SR_INSERT_COLUMN 0x00000200L +#define SQL_SR_REFERENCES_TABLE 0x00000400L +#define SQL_SR_REFERENCES_COLUMN 0x00000800L +#define SQL_SR_SELECT_TABLE 0x00001000L +#define SQL_SR_UPDATE_TABLE 0x00002000L +#define SQL_SR_UPDATE_COLUMN 0x00004000L + +/* SQL_SQL92_ROW_VALUE_CONSTRUCTOR bitmasks */ +#define SQL_SRVC_VALUE_EXPRESSION 0x00000001L +#define SQL_SRVC_NULL 0x00000002L +#define SQL_SRVC_DEFAULT 0x00000004L +#define SQL_SRVC_ROW_SUBQUERY 0x00000008L + +/* SQL_SQL92_VALUE_EXPRESSIONS bitmasks */ +#define SQL_SVE_CASE 0x00000001L +#define SQL_SVE_CAST 0x00000002L +#define SQL_SVE_COALESCE 0x00000004L +#define SQL_SVE_NULLIF 0x00000008L + +/* SQL_STANDARD_CLI_CONFORMANCE bitmasks */ +#define SQL_SCC_XOPEN_CLI_VERSION1 0x00000001L +#define SQL_SCC_ISO92_CLI 0x00000002L + +/* SQL_UNION_STATEMENT bitmasks */ +#define SQL_US_UNION SQL_U_UNION +#define SQL_US_UNION_ALL SQL_U_UNION_ALL + +#endif /* ODBCVER >= 0x0300 */ + +/* SQL_DTC_TRANSITION_COST bitmasks */ +#define SQL_DTC_ENLIST_EXPENSIVE 0x00000001L +#define SQL_DTC_UNENLIST_EXPENSIVE 0x00000002L + +/* additional SQLDataSources fetch directions */ +#if (ODBCVER >= 0x0300) +#define SQL_FETCH_FIRST_USER 31 +#define SQL_FETCH_FIRST_SYSTEM 32 +#endif /* ODBCVER >= 0x0300 */ + + +/* Defines for SQLSetPos */ +#define SQL_ENTIRE_ROWSET 0 + +/* Operations in SQLSetPos */ +#define SQL_POSITION 0 /* 1.0 FALSE */ +#define SQL_REFRESH 1 /* 1.0 TRUE */ +#define SQL_UPDATE 2 +#define SQL_DELETE 3 + +/* Operations in SQLBulkOperations */ +#define SQL_ADD 4 +#define SQL_SETPOS_MAX_OPTION_VALUE SQL_ADD +#if (ODBCVER >= 0x0300) +#define SQL_UPDATE_BY_BOOKMARK 5 +#define SQL_DELETE_BY_BOOKMARK 6 +#define SQL_FETCH_BY_BOOKMARK 7 + +#endif /* ODBCVER >= 0x0300 */ + +/* Lock options in SQLSetPos */ +#define SQL_LOCK_NO_CHANGE 0 /* 1.0 FALSE */ +#define SQL_LOCK_EXCLUSIVE 1 /* 1.0 TRUE */ +#define SQL_LOCK_UNLOCK 2 + +#define SQL_SETPOS_MAX_LOCK_VALUE SQL_LOCK_UNLOCK + +/* Macros for SQLSetPos */ +#define SQL_POSITION_TO(hstmt,irow) SQLSetPos(hstmt,irow,SQL_POSITION,SQL_LOCK_NO_CHANGE) +#define SQL_LOCK_RECORD(hstmt,irow,fLock) SQLSetPos(hstmt,irow,SQL_POSITION,fLock) +#define SQL_REFRESH_RECORD(hstmt,irow,fLock) SQLSetPos(hstmt,irow,SQL_REFRESH,fLock) +#define SQL_UPDATE_RECORD(hstmt,irow) SQLSetPos(hstmt,irow,SQL_UPDATE,SQL_LOCK_NO_CHANGE) +#define SQL_DELETE_RECORD(hstmt,irow) SQLSetPos(hstmt,irow,SQL_DELETE,SQL_LOCK_NO_CHANGE) +#define SQL_ADD_RECORD(hstmt,irow) SQLSetPos(hstmt,irow,SQL_ADD,SQL_LOCK_NO_CHANGE) + +/* Column types and scopes in SQLSpecialColumns. */ +#define SQL_BEST_ROWID 1 +#define SQL_ROWVER 2 + +/* Defines for SQLSpecialColumns (returned in the result set) + SQL_PC_UNKNOWN and SQL_PC_PSEUDO are defined in sql.h */ +#define SQL_PC_NOT_PSEUDO 1 + +/* Defines for SQLStatistics */ +#define SQL_QUICK 0 +#define SQL_ENSURE 1 + +/* Defines for SQLStatistics (returned in the result set) + SQL_INDEX_CLUSTERED, SQL_INDEX_HASHED, and SQL_INDEX_OTHER are + defined in sql.h */ +#define SQL_TABLE_STAT 0 + + +/* Defines for SQLTables */ +#if (ODBCVER >= 0x0300) +#define SQL_ALL_CATALOGS "%" +#define SQL_ALL_SCHEMAS "%" +#define SQL_ALL_TABLE_TYPES "%" +#endif /* ODBCVER >= 0x0300 */ + +/* Options for SQLDriverConnect */ +#define SQL_DRIVER_NOPROMPT 0 +#define SQL_DRIVER_COMPLETE 1 +#define SQL_DRIVER_PROMPT 2 +#define SQL_DRIVER_COMPLETE_REQUIRED 3 + +SQLRETURN SQL_API SQLDriverConnect( + SQLHDBC hdbc, + SQLHWND hwnd, + SQLCHAR *szConnStrIn, + SQLSMALLINT cbConnStrIn, + SQLCHAR *szConnStrOut, + SQLSMALLINT cbConnStrOutMax, + SQLSMALLINT *pcbConnStrOut, + SQLUSMALLINT fDriverCompletion); + +/* Level 2 Functions */ + +/* SQLExtendedFetch "fFetchType" values */ +#define SQL_FETCH_BOOKMARK 8 + +/* SQLExtendedFetch "rgfRowStatus" element values */ +#define SQL_ROW_SUCCESS 0 +#define SQL_ROW_DELETED 1 +#define SQL_ROW_UPDATED 2 +#define SQL_ROW_NOROW 3 +#define SQL_ROW_ADDED 4 +#define SQL_ROW_ERROR 5 +#if (ODBCVER >= 0x0300) +#define SQL_ROW_SUCCESS_WITH_INFO 6 +#define SQL_ROW_PROCEED 0 +#define SQL_ROW_IGNORE 1 +#endif + +/* value for SQL_DESC_ARRAY_STATUS_PTR */ +#if (ODBCVER >= 0x0300) +#define SQL_PARAM_SUCCESS 0 +#define SQL_PARAM_SUCCESS_WITH_INFO 6 +#define SQL_PARAM_ERROR 5 +#define SQL_PARAM_UNUSED 7 +#define SQL_PARAM_DIAG_UNAVAILABLE 1 + +#define SQL_PARAM_PROCEED 0 +#define SQL_PARAM_IGNORE 1 +#endif /* ODBCVER >= 0x0300 */ + +/* Defines for SQLForeignKeys (UPDATE_RULE and DELETE_RULE) */ +#define SQL_CASCADE 0 +#define SQL_RESTRICT 1 +#define SQL_SET_NULL 2 +#if (ODBCVER >= 0x0250) +#define SQL_NO_ACTION 3 +#define SQL_SET_DEFAULT 4 +#endif /* ODBCVER >= 0x0250 */ + +#if (ODBCVER >= 0x0300) +/* Note that the following are in a different column of SQLForeignKeys than */ +/* the previous #defines. These are for DEFERRABILITY. */ + +#define SQL_INITIALLY_DEFERRED 5 +#define SQL_INITIALLY_IMMEDIATE 6 +#define SQL_NOT_DEFERRABLE 7 + +#endif /* ODBCVER >= 0x0300 */ + +/* Defines for SQLBindParameter and + SQLProcedureColumns (returned in the result set) */ +#define SQL_PARAM_TYPE_UNKNOWN 0 +#define SQL_PARAM_INPUT 1 +#define SQL_PARAM_INPUT_OUTPUT 2 +#define SQL_RESULT_COL 3 +#define SQL_PARAM_OUTPUT 4 +#define SQL_RETURN_VALUE 5 + +/* Defines for SQLProcedures (returned in the result set) */ +#define SQL_PT_UNKNOWN 0 +#define SQL_PT_PROCEDURE 1 +#define SQL_PT_FUNCTION 2 + +/* This define is too large for RC */ +#define SQL_ODBC_KEYWORDS "ABSOLUTE,ACTION,ADA,ADD,ALL,ALLOCATE,ALTER,AND,ANY,ARE,AS,"\ +"ASC,ASSERTION,AT,AUTHORIZATION,AVG,"\ +"BEGIN,BETWEEN,BIT,BIT_LENGTH,BOTH,BY,CASCADE,CASCADED,CASE,CAST,CATALOG,"\ +"CHAR,CHAR_LENGTH,CHARACTER,CHARACTER_LENGTH,CHECK,CLOSE,COALESCE,"\ +"COLLATE,COLLATION,COLUMN,COMMIT,CONNECT,CONNECTION,CONSTRAINT,"\ +"CONSTRAINTS,CONTINUE,CONVERT,CORRESPONDING,COUNT,CREATE,CROSS,CURRENT,"\ +"CURRENT_DATE,CURRENT_TIME,CURRENT_TIMESTAMP,CURRENT_USER,CURSOR,"\ +"DATE,DAY,DEALLOCATE,DEC,DECIMAL,DECLARE,DEFAULT,DEFERRABLE,"\ +"DEFERRED,DELETE,DESC,DESCRIBE,DESCRIPTOR,DIAGNOSTICS,DISCONNECT,"\ +"DISTINCT,DOMAIN,DOUBLE,DROP,"\ +"ELSE,END,END-EXEC,ESCAPE,EXCEPT,EXCEPTION,EXEC,EXECUTE,"\ +"EXISTS,EXTERNAL,EXTRACT,"\ +"FALSE,FETCH,FIRST,FLOAT,FOR,FOREIGN,FORTRAN,FOUND,FROM,FULL,"\ +"GET,GLOBAL,GO,GOTO,GRANT,GROUP,HAVING,HOUR,"\ +"IDENTITY,IMMEDIATE,IN,INCLUDE,INDEX,INDICATOR,INITIALLY,INNER,"\ +"INPUT,INSENSITIVE,INSERT,INT,INTEGER,INTERSECT,INTERVAL,INTO,IS,ISOLATION,"\ +"JOIN,KEY,LANGUAGE,LAST,LEADING,LEFT,LEVEL,LIKE,LOCAL,LOWER,"\ +"MATCH,MAX,MIN,MINUTE,MODULE,MONTH,"\ +"NAMES,NATIONAL,NATURAL,NCHAR,NEXT,NO,NONE,NOT,NULL,NULLIF,NUMERIC,"\ +"OCTET_LENGTH,OF,ON,ONLY,OPEN,OPTION,OR,ORDER,OUTER,OUTPUT,OVERLAPS,"\ +"PAD,PARTIAL,PASCAL,PLI,POSITION,PRECISION,PREPARE,PRESERVE,"\ +"PRIMARY,PRIOR,PRIVILEGES,PROCEDURE,PUBLIC,"\ +"READ,REAL,REFERENCES,RELATIVE,RESTRICT,REVOKE,RIGHT,ROLLBACK,ROWS"\ +"SCHEMA,SCROLL,SECOND,SECTION,SELECT,SESSION,SESSION_USER,SET,SIZE,"\ +"SMALLINT,SOME,SPACE,SQL,SQLCA,SQLCODE,SQLERROR,SQLSTATE,SQLWARNING,"\ +"SUBSTRING,SUM,SYSTEM_USER,"\ +"TABLE,TEMPORARY,THEN,TIME,TIMESTAMP,TIMEZONE_HOUR,TIMEZONE_MINUTE,"\ +"TO,TRAILING,TRANSACTION,TRANSLATE,TRANSLATION,TRIM,TRUE,"\ +"UNION,UNIQUE,UNKNOWN,UPDATE,UPPER,USAGE,USER,USING,"\ +"VALUE,VALUES,VARCHAR,VARYING,VIEW,WHEN,WHENEVER,WHERE,WITH,WORK,WRITE,"\ +"YEAR,ZONE" + +SQLRETURN SQL_API SQLBrowseConnect( + SQLHDBC hdbc, + SQLCHAR *szConnStrIn, + SQLSMALLINT cbConnStrIn, + SQLCHAR *szConnStrOut, + SQLSMALLINT cbConnStrOutMax, + SQLSMALLINT *pcbConnStrOut); + +#if (ODBCVER >= 0x0300) +SQLRETURN SQL_API SQLBulkOperations( + SQLHSTMT StatementHandle, + SQLSMALLINT Operation); +#endif /* ODBCVER >= 0x0300 */ + +SQLRETURN SQL_API SQLColAttributes( + SQLHSTMT hstmt, + SQLUSMALLINT icol, + SQLUSMALLINT fDescType, + SQLPOINTER rgbDesc, + SQLSMALLINT cbDescMax, + SQLSMALLINT *pcbDesc, + SQLLEN *pfDesc); + +SQLRETURN SQL_API SQLColumnPrivileges( + SQLHSTMT hstmt, + SQLCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR *szTableName, + SQLSMALLINT cbTableName, + SQLCHAR *szColumnName, + SQLSMALLINT cbColumnName); + +SQLRETURN SQL_API SQLDescribeParam( + SQLHSTMT hstmt, + SQLUSMALLINT ipar, + SQLSMALLINT *pfSqlType, + SQLULEN *pcbParamDef, + SQLSMALLINT *pibScale, + SQLSMALLINT *pfNullable); + +SQLRETURN SQL_API SQLExtendedFetch( + SQLHSTMT hstmt, + SQLUSMALLINT fFetchType, + SQLLEN irow, + SQLULEN *pcrow, + SQLUSMALLINT *rgfRowStatus); + +SQLRETURN SQL_API SQLForeignKeys( + SQLHSTMT hstmt, + SQLCHAR *szPkCatalogName, + SQLSMALLINT cbPkCatalogName, + SQLCHAR *szPkSchemaName, + SQLSMALLINT cbPkSchemaName, + SQLCHAR *szPkTableName, + SQLSMALLINT cbPkTableName, + SQLCHAR *szFkCatalogName, + SQLSMALLINT cbFkCatalogName, + SQLCHAR *szFkSchemaName, + SQLSMALLINT cbFkSchemaName, + SQLCHAR *szFkTableName, + SQLSMALLINT cbFkTableName); + +SQLRETURN SQL_API SQLMoreResults( + SQLHSTMT hstmt); + +SQLRETURN SQL_API SQLNativeSql( + SQLHDBC hdbc, + SQLCHAR *szSqlStrIn, + SQLINTEGER cbSqlStrIn, + SQLCHAR *szSqlStr, + SQLINTEGER cbSqlStrMax, + SQLINTEGER *pcbSqlStr); + +SQLRETURN SQL_API SQLNumParams( + SQLHSTMT hstmt, + SQLSMALLINT *pcpar); + +SQLRETURN SQL_API SQLParamOptions( + SQLHSTMT hstmt, + SQLULEN crow, + SQLULEN *pirow); + +SQLRETURN SQL_API SQLPrimaryKeys( + SQLHSTMT hstmt, + SQLCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR *szTableName, + SQLSMALLINT cbTableName); + +SQLRETURN SQL_API SQLProcedureColumns( + SQLHSTMT hstmt, + SQLCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR *szProcName, + SQLSMALLINT cbProcName, + SQLCHAR *szColumnName, + SQLSMALLINT cbColumnName); + +SQLRETURN SQL_API SQLProcedures( + SQLHSTMT hstmt, + SQLCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR *szProcName, + SQLSMALLINT cbProcName); + +SQLRETURN SQL_API SQLSetPos( + SQLHSTMT hstmt, + SQLSETPOSIROW irow, + SQLUSMALLINT fOption, + SQLUSMALLINT fLock); + +SQLRETURN SQL_API SQLTablePrivileges( + SQLHSTMT hstmt, + SQLCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR *szTableName, + SQLSMALLINT cbTableName); + +SQLRETURN SQL_API SQLDrivers( + SQLHENV henv, + SQLUSMALLINT fDirection, + SQLCHAR *szDriverDesc, + SQLSMALLINT cbDriverDescMax, + SQLSMALLINT *pcbDriverDesc, + SQLCHAR *szDriverAttributes, + SQLSMALLINT cbDrvrAttrMax, + SQLSMALLINT *pcbDrvrAttr); + +SQLRETURN SQL_API SQLBindParameter( + SQLHSTMT hstmt, + SQLUSMALLINT ipar, + SQLSMALLINT fParamType, + SQLSMALLINT fCType, + SQLSMALLINT fSqlType, + SQLULEN cbColDef, + SQLSMALLINT ibScale, + SQLPOINTER rgbValue, + SQLLEN cbValueMax, + SQLLEN *pcbValue); + +/*---------------------------------------------------------*/ +/* SQLAllocHandleStd is implemented to make SQLAllocHandle */ +/* compatible with X/Open standard. an application should */ +/* not call SQLAllocHandleStd directly */ +/*---------------------------------------------------------*/ +#ifdef ODBC_STD +#define SQLAllocHandle SQLAllocHandleStd +#define SQLAllocEnv(phenv) SQLAllocHandleStd(SQL_HANDLE_ENV, SQL_NULL_HANDLE, phenv) + +/* Internal type subcodes */ +#define SQL_YEAR SQL_CODE_YEAR +#define SQL_MONTH SQL_CODE_MONTH +#define SQL_DAY SQL_CODE_DAY +#define SQL_HOUR SQL_CODE_HOUR +#define SQL_MINUTE SQL_CODE_MINUTE +#define SQL_SECOND SQL_CODE_SECOND +#define SQL_YEAR_TO_MONTH SQL_CODE_YEAR_TO_MONTH +#define SQL_DAY_TO_HOUR SQL_CODE_DAY_TO_HOUR +#define SQL_DAY_TO_MINUTE SQL_CODE_DAY_TO_MINUTE +#define SQL_DAY_TO_SECOND SQL_CODE_DAY_TO_SECOND +#define SQL_HOUR_TO_MINUTE SQL_CODE_HOUR_TO_MINUTE +#define SQL_HOUR_TO_SECOND SQL_CODE_HOUR_TO_SECOND +#define SQL_MINUTE_TO_SECOND SQL_CODE_MINUTE_TO_SECOND +#endif /* ODBC_STD */ + +#if (ODBCVER >= 0x0300) +SQLRETURN SQL_API SQLAllocHandleStd( + SQLSMALLINT fHandleType, + SQLHANDLE hInput, + SQLHANDLE *phOutput); +#endif + +/* Deprecated defines from prior versions of ODBC */ +#define SQL_DATABASE_NAME 16 /* Use SQLGetConnectOption/SQL_CURRENT_QUALIFIER */ +#define SQL_FD_FETCH_PREV SQL_FD_FETCH_PRIOR +#define SQL_FETCH_PREV SQL_FETCH_PRIOR +#define SQL_CONCUR_TIMESTAMP SQL_CONCUR_ROWVER +#define SQL_SCCO_OPT_TIMESTAMP SQL_SCCO_OPT_ROWVER +#define SQL_CC_DELETE SQL_CB_DELETE +#define SQL_CR_DELETE SQL_CB_DELETE +#define SQL_CC_CLOSE SQL_CB_CLOSE +#define SQL_CR_CLOSE SQL_CB_CLOSE +#define SQL_CC_PRESERVE SQL_CB_PRESERVE +#define SQL_CR_PRESERVE SQL_CB_PRESERVE +/* SQL_FETCH_RESUME is not supported by 2.0+ drivers +#define SQL_FETCH_RESUME 7 +*/ +#define SQL_SCROLL_FORWARD_ONLY 0L /*-SQL_CURSOR_FORWARD_ONLY */ +#define SQL_SCROLL_KEYSET_DRIVEN (-1L) /*-SQL_CURSOR_KEYSET_DRIVEN */ +#define SQL_SCROLL_DYNAMIC (-2L) /*-SQL_CURSOR_DYNAMIC */ +#define SQL_SCROLL_STATIC (-3L) /*-SQL_CURSOR_STATIC */ + +/* Deprecated functions from prior versions of ODBC */ +SQLRETURN SQL_API SQLSetScrollOptions( /* Use SQLSetStmtOptions */ + SQLHSTMT hstmt, + SQLUSMALLINT fConcurrency, + SQLLEN crowKeyset, + SQLUSMALLINT crowRowset); + +/*! + * \defgroup Tracing. + * + * unixODBC implements a slight variation of the tracing mechanism used + * on MS platforms. The unixODBC method loses the ability to produce trace + * output for invalid handles but gains the following; + * + * - better concurrency + * - allows tracing to be turned on/off and configured at finer granularity + * - hopefully; better performance + * + * unixODBC provides a cross-platform helper library called 'trace' and an + * example/default trace plugin called 'odbctrac'. Those writing an ODBC + * driver can use the 'trace' helper library (a static library). Those wanting + * to create custom trace output can implement a different version of the + * 'odbctrac' plugin. + * + * The text file driver (odbctxt) included with unixODBC is an example of a + * driver using the 'trace' helper library. + * + * The 'trace' library and the example plugin 'odbctrac' are designed to be + * portable on all platforms where unixODBC is available and on MS platforms. + * This will allow drivers using 'trace' and 'odbctrac' plugin to equilly + * portable. On MS platforms - this compliments traditional tracing (mostly + * just used by the Driver Manager). + * + * \sa trace + * odbctxt + * odbctrac + */ +/*@{*/ +#define TRACE_VERSION 1000 /*!< Version of trace API */ +#ifdef UNICODE +RETCODE TraceOpenLogFile(SQLPOINTER,LPWSTR,LPWSTR,DWORD); /*!< open a trace log file */ +#else +RETCODE TraceOpenLogFile(SQLPOINTER,LPSTR,LPSTR,DWORD); /*!< open a trace log file */ +#endif +RETCODE TraceCloseLogFile(SQLPOINTER); /*!< Request to close a trace log */ +SQLRETURN TraceReturn(SQLPOINTER,SQLRETURN); /*!< Call to produce trace output upon function return. */ +#ifdef __cplusplus +DWORD TraceVersion(); /*!< Returns trace API version */ +#else +DWORD TraceVersion(VOID); /*!< Returns trace API version */ +#endif + +/* Functions for Visual Studio Analyzer*/ +/* to turn on/off tracing or VS events, call TraceVSControl by setting or clearing the following bits */ +#define TRACE_ON 0x00000001L +#define TRACE_VS_EVENT_ON 0x00000002L + +RETCODE TraceVSControl(DWORD); + +/* the flags in ODBC_VS_ARGS */ +#define ODBC_VS_FLAG_UNICODE_ARG 0x00000001L /* the argument is unicode */ +#define ODBC_VS_FLAG_UNICODE_COR 0x00000002L /* the correlation is unicode */ +#define ODBC_VS_FLAG_RETCODE 0x00000004L /* RetCode field is set */ +#define ODBC_VS_FLAG_STOP 0x00000008L /* Stop firing visual studio analyzer events */ + +typedef struct tagODBC_VS_ARGS { +#ifdef GUID_DEFINED + const GUID *pguidEvent; /* the GUID for event */ +#else + const void *pguidEvent; /* the GUID for event */ +#endif + DWORD dwFlags; /* flags for the call */ + union { + WCHAR *wszArg; + CHAR *szArg; + }u1; + union { + WCHAR *wszCorrelation; + CHAR *szCorrelation; + }u2; + RETCODE RetCode; +} ODBC_VS_ARGS, *PODBC_VS_ARGS; + +VOID FireVSDebugEvent(PODBC_VS_ARGS); +/*@}*/ + +#ifdef __cplusplus +} +#endif + +/* + * connection pooling retry times + */ + +BOOL ODBCSetTryWaitValue ( DWORD dwValue ); +#ifdef __cplusplus +DWORD ODBCGetTryWaitValue ( ); +#else +DWORD ODBCGetTryWaitValue ( VOID ); +#endif + +#ifndef __SQLUCODE_H +#include "sqlucode.h" +#endif + +#endif diff --git a/libodbc/include/ss_linux/sqltypes.h b/libodbc/include/ss_linux/sqltypes.h new file mode 100644 index 0000000000..d9366547fa --- /dev/null +++ b/libodbc/include/ss_linux/sqltypes.h @@ -0,0 +1,462 @@ +/************************************************************* + * sqltypes.h + * + * This is the lowest level include in unixODBC. It defines + * the basic types required by unixODBC and is heavily based + * upon the MS include of the same name (it has to be for + * binary compatability between drivers developed under different + * packages). + * + * You can include this file directly but it is almost always + * included indirectly, by including.. for example sqlext.h + * + * This include makes no effort to be usefull on any platforms other + * than Linux (with some exceptions for UNIX in general). + * + * !!!DO NOT CONTAMINATE THIS FILE WITH NON-Linux CODE!!! + * + *************************************************************/ +#ifndef __SQLTYPES_H +#define __SQLTYPES_H + +/**************************** + * default to the 3.51 definitions. should define ODBCVER before here if you want an older set of defines + ***************************/ +#ifndef ODBCVER +#define ODBCVER 0x0351 +#endif + +/* + * if thi sis set, then use a 4 byte unicode definition, insteead of the 2 bye that MS use + */ + +#ifdef SQL_WCHART_CONVERT +/* + * Use this if you want to use the C/C++ portable definition of a wide char, wchar_t + * Microsoft hardcoded a definition of unsigned short which may not be compatible with + * your platform specific wide char definition. + */ +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * this is defined by configure, but will not be on a normal application build + * the install creates a unixodbc_conf.h file that contains the current build settings + */ + +#ifndef SIZEOF_LONG_INT +#include +#endif + +#ifndef SIZEOF_LONG_INT +#error "Needs to know how big a long int is to continue!!!" +#endif + +/**************************** + * These make up for having no windows.h + ***************************/ +#ifndef ALLREADY_HAVE_WINDOWS_TYPE + +#define FAR +#define CALLBACK +#ifdef __OS2__ +#define SQL_API _System +#else +#define SQL_API +#endif +#define BOOL int +typedef void* HWND; +typedef char CHAR; +#ifdef UNICODE + +/* + * NOTE: The Microsoft unicode define is only for apps that want to use TCHARs and + * be able to compile for both unicode and non-unicode with the same source. + * This is not recommanded for linux applications and is not supported + * by the standard linux string header files. + */ +#ifdef SQL_WCHART_CONVERT +typedef wchar_t TCHAR; +#else +typedef signed short TCHAR; +#endif + +#else +typedef char TCHAR; +#endif + +#ifndef DONT_TD_VOID +typedef void VOID; +#endif + +typedef unsigned short WORD; +#if (SIZEOF_LONG_INT == 4) +typedef unsigned long DWORD; +#else +typedef unsigned int DWORD; +#endif +typedef unsigned char BYTE; + +#ifdef SQL_WCHART_CONVERT +typedef wchar_t WCHAR; +#else +typedef unsigned short WCHAR; +#endif + +typedef WCHAR* LPWSTR; +typedef const char* LPCSTR; +typedef const WCHAR* LPCWSTR; +typedef TCHAR* LPTSTR; +typedef char* LPSTR; +typedef DWORD* LPDWORD; + +typedef void* HINSTANCE; + +#endif + + +/**************************** + * standard SQL* data types. use these as much as possible when using ODBC calls/vars + ***************************/ +typedef unsigned char SQLCHAR; + +#if (ODBCVER >= 0x0300) +typedef unsigned char SQLDATE; +typedef unsigned char SQLDECIMAL; +typedef double SQLDOUBLE; +typedef double SQLFLOAT; +#endif + +/* + * can't use a long it fails on 64 platforms + */ + +/* + * Hopefully by now it should be safe to assume most drivers know about SQLLEN now + * and the defaukt is now sizeof( SQLLEN ) = 8 on 64 bit platforms + * + */ + +#if (SIZEOF_LONG_INT == 8) +#ifdef BUILD_LEGACY_64_BIT_MODE +typedef int SQLINTEGER; +typedef unsigned int SQLUINTEGER; +#define SQLLEN SQLINTEGER +#define SQLULEN SQLUINTEGER +#define SQLSETPOSIROW SQLUSMALLINT +/* + * These are not supprted on 64bit ODBC according to MS, removed, so use at your peril + * + typedef SQLULEN SQLROWCOUNT; + typedef SQLULEN SQLROWSETSIZE; + typedef SQLULEN SQLTRANSID; + typedef SQLLEN SQLROWOFFSET; +*/ +#else +typedef int SQLINTEGER; +typedef unsigned int SQLUINTEGER; +typedef long SQLLEN; +typedef unsigned long SQLULEN; +typedef unsigned long SQLSETPOSIROW; +/* + * These are not supprted on 64bit ODBC according to MS, removed, so use at your peril + * + typedef SQLULEN SQLTRANSID; + typedef SQLULEN SQLROWCOUNT; + typedef SQLUINTEGER SQLROWSETSIZE; + typedef SQLLEN SQLROWOFFSET; + */ +#endif +#else +typedef long SQLINTEGER; +typedef unsigned long SQLUINTEGER; +#define SQLLEN SQLINTEGER +#define SQLULEN SQLUINTEGER +#define SQLSETPOSIROW SQLUSMALLINT +typedef SQLULEN SQLROWCOUNT; +typedef SQLULEN SQLROWSETSIZE; +typedef SQLULEN SQLTRANSID; +typedef SQLLEN SQLROWOFFSET; +#endif + +#if (ODBCVER >= 0x0300) +typedef unsigned char SQLNUMERIC; +#endif + +typedef void * SQLPOINTER; + +#if (ODBCVER >= 0x0300) +typedef float SQLREAL; +#endif + +typedef signed short int SQLSMALLINT; +typedef unsigned short SQLUSMALLINT; + +#if (ODBCVER >= 0x0300) +typedef unsigned char SQLTIME; +typedef unsigned char SQLTIMESTAMP; +typedef unsigned char SQLVARCHAR; +#endif + +typedef SQLSMALLINT SQLRETURN; + +#if (ODBCVER >= 0x0300) +typedef void * SQLHANDLE; +typedef SQLHANDLE SQLHENV; +typedef SQLHANDLE SQLHDBC; +typedef SQLHANDLE SQLHSTMT; +typedef SQLHANDLE SQLHDESC; +#else +typedef void * SQLHENV; +typedef void * SQLHDBC; +typedef void * SQLHSTMT; +/* + * some things like PHP won't build without this + */ +typedef void * SQLHANDLE; +#endif + +/**************************** + * These are cast into the actual struct that is being passed around. The + * DriverManager knows what its structs look like and the Driver knows about its + * structs... the app knows nothing about them... just void* + * These are deprecated in favour of SQLHENV, SQLHDBC, SQLHSTMT + ***************************/ + +#if (ODBCVER >= 0x0300) +typedef SQLHANDLE HENV; +typedef SQLHANDLE HDBC; +typedef SQLHANDLE HSTMT; +#else +typedef void * HENV; +typedef void * HDBC; +typedef void * HSTMT; +#endif + + +/**************************** + * more basic data types to augment what windows.h provides + ***************************/ +#ifndef ALLREADY_HAVE_WINDOWS_TYPE + +typedef unsigned char UCHAR; +typedef signed char SCHAR; +typedef SCHAR SQLSCHAR; +#if (SIZEOF_LONG_INT == 4) +typedef long int SDWORD; +typedef unsigned long int UDWORD; +#else +typedef int SDWORD; +typedef unsigned int UDWORD; +#endif +typedef signed short int SWORD; +typedef unsigned short int UWORD; +typedef unsigned int UINT; +typedef signed long SLONG; +typedef signed short SSHORT; +typedef unsigned long ULONG; +typedef unsigned short USHORT; +typedef double SDOUBLE; +typedef double LDOUBLE; +typedef float SFLOAT; +typedef void* PTR; +typedef signed short RETCODE; +typedef void* SQLHWND; + +#endif + +/**************************** + * standard structs for working with date/times + ***************************/ +#ifndef __SQLDATE +#define __SQLDATE +typedef struct tagDATE_STRUCT +{ + SQLSMALLINT year; + SQLUSMALLINT month; + SQLUSMALLINT day; +} DATE_STRUCT; + +#if (ODBCVER >= 0x0300) +typedef DATE_STRUCT SQL_DATE_STRUCT; +#endif + +typedef struct tagTIME_STRUCT +{ + SQLUSMALLINT hour; + SQLUSMALLINT minute; + SQLUSMALLINT second; +} TIME_STRUCT; + +#if (ODBCVER >= 0x0300) +typedef TIME_STRUCT SQL_TIME_STRUCT; +#endif + +typedef struct tagTIMESTAMP_STRUCT +{ + SQLSMALLINT year; + SQLUSMALLINT month; + SQLUSMALLINT day; + SQLUSMALLINT hour; + SQLUSMALLINT minute; + SQLUSMALLINT second; + SQLUINTEGER fraction; +} TIMESTAMP_STRUCT; + +#if (ODBCVER >= 0x0300) +typedef TIMESTAMP_STRUCT SQL_TIMESTAMP_STRUCT; +#endif + + +#if (ODBCVER >= 0x0300) +typedef enum +{ + SQL_IS_YEAR = 1, + SQL_IS_MONTH = 2, + SQL_IS_DAY = 3, + SQL_IS_HOUR = 4, + SQL_IS_MINUTE = 5, + SQL_IS_SECOND = 6, + SQL_IS_YEAR_TO_MONTH = 7, + SQL_IS_DAY_TO_HOUR = 8, + SQL_IS_DAY_TO_MINUTE = 9, + SQL_IS_DAY_TO_SECOND = 10, + SQL_IS_HOUR_TO_MINUTE = 11, + SQL_IS_HOUR_TO_SECOND = 12, + SQL_IS_MINUTE_TO_SECOND = 13 +} SQLINTERVAL; + +#endif + +#if (ODBCVER >= 0x0300) +typedef struct tagSQL_YEAR_MONTH +{ + SQLUINTEGER year; + SQLUINTEGER month; +} SQL_YEAR_MONTH_STRUCT; + +typedef struct tagSQL_DAY_SECOND +{ + SQLUINTEGER day; + SQLUINTEGER hour; + SQLUINTEGER minute; + SQLUINTEGER second; + SQLUINTEGER fraction; +} SQL_DAY_SECOND_STRUCT; + +typedef struct tagSQL_INTERVAL_STRUCT +{ + SQLINTERVAL interval_type; + SQLSMALLINT interval_sign; + union { + SQL_YEAR_MONTH_STRUCT year_month; + SQL_DAY_SECOND_STRUCT day_second; + } intval; + +} SQL_INTERVAL_STRUCT; + +#endif + +#endif + +/**************************** + * + ***************************/ +#ifndef ODBCINT64 +# if (ODBCVER >= 0x0300) +# if (SIZEOF_LONG_INT == 8) +# define ODBCINT64 long +# define UODBCINT64 unsigned long +# else +# ifdef HAVE_LONG_LONG +# define ODBCINT64 long long +# define UODBCINT64 unsigned long long +# else +/* + * may fail in some cases, but what else can we do ? + */ +struct __bigint_struct +{ + int hiword; + unsigned int loword; +}; +struct __bigint_struct_u +{ + unsigned int hiword; + unsigned int loword; +}; +# define ODBCINT64 struct __bigint_struct +# define UODBCINT64 struct __bigint_struct_u +# endif +# endif +#endif +#endif + +#ifdef ODBCINT64 +typedef ODBCINT64 SQLBIGINT; +#endif +#ifdef UODBCINT64 +typedef UODBCINT64 SQLUBIGINT; +#endif + + +/**************************** + * cursor and bookmark + ***************************/ +#if (ODBCVER >= 0x0300) +#define SQL_MAX_NUMERIC_LEN 16 +typedef struct tagSQL_NUMERIC_STRUCT +{ + SQLCHAR precision; + SQLSCHAR scale; + SQLCHAR sign; /* 1=pos 0=neg */ + SQLCHAR val[SQL_MAX_NUMERIC_LEN]; +} SQL_NUMERIC_STRUCT; +#endif + +#if (ODBCVER >= 0x0350) +#ifdef GUID_DEFINED +#ifndef ALLREADY_HAVE_WINDOWS_TYPE +typedef GUID SQLGUID; +#else +typedef struct tagSQLGUID +{ + DWORD Data1; + WORD Data2; + WORD Data3; + BYTE Data4[ 8 ]; +} SQLGUID; +#endif +#else +typedef struct tagSQLGUID +{ + DWORD Data1; + WORD Data2; + WORD Data3; + BYTE Data4[ 8 ]; +} SQLGUID; +#endif +#endif + +typedef SQLULEN BOOKMARK; + +typedef WCHAR SQLWCHAR; + +#ifdef UNICODE +typedef SQLWCHAR SQLTCHAR; +#else +typedef SQLCHAR SQLTCHAR; +#endif + +#ifdef __cplusplus +} +#endif + +#endif + + + diff --git a/libodbc/include/ss_linux/sqlucode.h b/libodbc/include/ss_linux/sqlucode.h new file mode 100644 index 0000000000..7bf97b2b40 --- /dev/null +++ b/libodbc/include/ss_linux/sqlucode.h @@ -0,0 +1,789 @@ +/************************************************** + * sqlucode.h + * + * These should be consistent with the MS version. + * + **************************************************/ +#ifndef __SQLUCODE_H +#define __SQLUCODE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define SQL_WCHAR (-8) +#define SQL_WVARCHAR (-9) +#define SQL_WLONGVARCHAR (-10) +#define SQL_C_WCHAR SQL_WCHAR + +#ifdef UNICODE +#define SQL_C_TCHAR SQL_C_WCHAR +#else +#define SQL_C_TCHAR SQL_C_CHAR +#endif + +#define SQL_SQLSTATE_SIZEW 10 /* size of SQLSTATE for unicode */ + +/* UNICODE versions */ + +SQLRETURN SQL_API SQLColAttributeW( + SQLHSTMT hstmt, + SQLUSMALLINT iCol, + SQLUSMALLINT iField, + SQLPOINTER pCharAttr, + SQLSMALLINT cbCharAttrMax, + SQLSMALLINT *pcbCharAttr, + SQLLEN *pNumAttr); + +SQLRETURN SQL_API SQLColAttributesW( + SQLHSTMT hstmt, + SQLUSMALLINT icol, + SQLUSMALLINT fDescType, + SQLPOINTER rgbDesc, + SQLSMALLINT cbDescMax, + SQLSMALLINT *pcbDesc, + SQLLEN *pfDesc); + +SQLRETURN SQL_API SQLConnectW( + SQLHDBC hdbc, + SQLWCHAR *szDSN, + SQLSMALLINT cbDSN, + SQLWCHAR *szUID, + SQLSMALLINT cbUID, + SQLWCHAR *szAuthStr, + SQLSMALLINT cbAuthStr); + + +SQLRETURN SQL_API SQLDescribeColW( + SQLHSTMT hstmt, + SQLUSMALLINT icol, + SQLWCHAR *szColName, + SQLSMALLINT cbColNameMax, + SQLSMALLINT *pcbColName, + SQLSMALLINT *pfSqlType, + SQLULEN *pcbColDef, + SQLSMALLINT *pibScale, + SQLSMALLINT *pfNullable); + + +SQLRETURN SQL_API SQLErrorW( + SQLHENV henv, + SQLHDBC hdbc, + SQLHSTMT hstmt, + SQLWCHAR *szSqlState, + SQLINTEGER *pfNativeError, + SQLWCHAR *szErrorMsg, + SQLSMALLINT cbErrorMsgMax, + SQLSMALLINT *pcbErrorMsg); + +SQLRETURN SQL_API SQLExecDirectW( + SQLHSTMT hstmt, + SQLWCHAR *szSqlStr, + SQLINTEGER cbSqlStr); + +SQLRETURN SQL_API SQLGetConnectAttrW( + SQLHDBC hdbc, + SQLINTEGER fAttribute, + SQLPOINTER rgbValue, + SQLINTEGER cbValueMax, + SQLINTEGER *pcbValue); + +SQLRETURN SQL_API SQLGetCursorNameW( + SQLHSTMT hstmt, + SQLWCHAR *szCursor, + SQLSMALLINT cbCursorMax, + SQLSMALLINT *pcbCursor); + +#if (ODBCVER >= 0x0300) +SQLRETURN SQL_API SQLSetDescFieldW(SQLHDESC DescriptorHandle, + SQLSMALLINT RecNumber, + SQLSMALLINT FieldIdentifier, + SQLPOINTER Value, + SQLINTEGER BufferLength); + + + +SQLRETURN SQL_API SQLGetDescFieldW( + SQLHDESC hdesc, + SQLSMALLINT iRecord, + SQLSMALLINT iField, + SQLPOINTER rgbValue, + SQLINTEGER cbValueMax, + SQLINTEGER *pcbValue); + +SQLRETURN SQL_API SQLGetDescRecW( + SQLHDESC hdesc, + SQLSMALLINT iRecord, + SQLWCHAR *szName, + SQLSMALLINT cbNameMax, + SQLSMALLINT *pcbName, + SQLSMALLINT *pfType, + SQLSMALLINT *pfSubType, + SQLLEN *pLength, + SQLSMALLINT *pPrecision, + SQLSMALLINT *pScale, + SQLSMALLINT *pNullable); + +SQLRETURN SQL_API SQLGetDiagFieldW( + SQLSMALLINT fHandleType, + SQLHANDLE handle, + SQLSMALLINT iRecord, + SQLSMALLINT fDiagField, + SQLPOINTER rgbDiagInfo, + SQLSMALLINT cbDiagInfoMax, + SQLSMALLINT *pcbDiagInfo); + +SQLRETURN SQL_API SQLGetDiagRecW( + SQLSMALLINT fHandleType, + SQLHANDLE handle, + SQLSMALLINT iRecord, + SQLWCHAR *szSqlState, + SQLINTEGER *pfNativeError, + SQLWCHAR *szErrorMsg, + SQLSMALLINT cbErrorMsgMax, + SQLSMALLINT *pcbErrorMsg); + + +#endif + + +SQLRETURN SQL_API SQLPrepareW( + SQLHSTMT hstmt, + SQLWCHAR *szSqlStr, + SQLINTEGER cbSqlStr); + +SQLRETURN SQL_API SQLSetConnectAttrW( + SQLHDBC hdbc, + SQLINTEGER fAttribute, + SQLPOINTER rgbValue, + SQLINTEGER cbValue); + +SQLRETURN SQL_API SQLSetCursorNameW( + SQLHSTMT hstmt, + SQLWCHAR *szCursor, + SQLSMALLINT cbCursor); + + + + + + + +SQLRETURN SQL_API SQLColumnsW( + SQLHSTMT hstmt, + SQLWCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLWCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLWCHAR *szTableName, + SQLSMALLINT cbTableName, + SQLWCHAR *szColumnName, + SQLSMALLINT cbColumnName); + +SQLRETURN SQL_API SQLGetConnectOptionW( + SQLHDBC hdbc, + SQLUSMALLINT fOption, + SQLPOINTER pvParam); + + + +SQLRETURN SQL_API SQLGetInfoW( + SQLHDBC hdbc, + SQLUSMALLINT fInfoType, + SQLPOINTER rgbInfoValue, + SQLSMALLINT cbInfoValueMax, + SQLSMALLINT *pcbInfoValue); + +SQLRETURN SQL_API SQLGetTypeInfoW( + SQLHSTMT StatementHandle, + SQLSMALLINT DataType); + + +SQLRETURN SQL_API SQLSetConnectOptionW( + SQLHDBC hdbc, + SQLUSMALLINT fOption, + SQLULEN vParam); + + +SQLRETURN SQL_API SQLSpecialColumnsW( + SQLHSTMT hstmt, + SQLUSMALLINT fColType, + SQLWCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLWCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLWCHAR *szTableName, + SQLSMALLINT cbTableName, + SQLUSMALLINT fScope, + SQLUSMALLINT fNullable); + +SQLRETURN SQL_API SQLStatisticsW( + SQLHSTMT hstmt, + SQLWCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLWCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLWCHAR *szTableName, + SQLSMALLINT cbTableName, + SQLUSMALLINT fUnique, + SQLUSMALLINT fAccuracy); + +SQLRETURN SQL_API SQLTablesW( + SQLHSTMT hstmt, + SQLWCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLWCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLWCHAR *szTableName, + SQLSMALLINT cbTableName, + SQLWCHAR *szTableType, + SQLSMALLINT cbTableType); + + + +SQLRETURN SQL_API SQLDataSourcesW( + SQLHENV henv, + SQLUSMALLINT fDirection, + SQLWCHAR *szDSN, + SQLSMALLINT cbDSNMax, + SQLSMALLINT *pcbDSN, + SQLWCHAR *szDescription, + SQLSMALLINT cbDescriptionMax, + SQLSMALLINT *pcbDescription); + + + + +SQLRETURN SQL_API SQLDriverConnectW( + SQLHDBC hdbc, + SQLHWND hwnd, + SQLWCHAR *szConnStrIn, + SQLSMALLINT cbConnStrIn, + SQLWCHAR *szConnStrOut, + SQLSMALLINT cbConnStrOutMax, + SQLSMALLINT *pcbConnStrOut, + SQLUSMALLINT fDriverCompletion); + + +SQLRETURN SQL_API SQLBrowseConnectW( + SQLHDBC hdbc, + SQLWCHAR *szConnStrIn, + SQLSMALLINT cbConnStrIn, + SQLWCHAR *szConnStrOut, + SQLSMALLINT cbConnStrOutMax, + SQLSMALLINT *pcbConnStrOut); + +SQLRETURN SQL_API SQLColumnPrivilegesW( + SQLHSTMT hstmt, + SQLWCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLWCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLWCHAR *szTableName, + SQLSMALLINT cbTableName, + SQLWCHAR *szColumnName, + SQLSMALLINT cbColumnName); + +SQLRETURN SQL_API SQLGetStmtAttrW( + SQLHSTMT hstmt, + SQLINTEGER fAttribute, + SQLPOINTER rgbValue, + SQLINTEGER cbValueMax, + SQLINTEGER *pcbValue); + +SQLRETURN SQL_API SQLSetStmtAttrW( + SQLHSTMT hstmt, + SQLINTEGER fAttribute, + SQLPOINTER rgbValue, + SQLINTEGER cbValueMax); + +SQLRETURN SQL_API SQLForeignKeysW( + SQLHSTMT hstmt, + SQLWCHAR *szPkCatalogName, + SQLSMALLINT cbPkCatalogName, + SQLWCHAR *szPkSchemaName, + SQLSMALLINT cbPkSchemaName, + SQLWCHAR *szPkTableName, + SQLSMALLINT cbPkTableName, + SQLWCHAR *szFkCatalogName, + SQLSMALLINT cbFkCatalogName, + SQLWCHAR *szFkSchemaName, + SQLSMALLINT cbFkSchemaName, + SQLWCHAR *szFkTableName, + SQLSMALLINT cbFkTableName); + + +SQLRETURN SQL_API SQLNativeSqlW( + SQLHDBC hdbc, + SQLWCHAR *szSqlStrIn, + SQLINTEGER cbSqlStrIn, + SQLWCHAR *szSqlStr, + SQLINTEGER cbSqlStrMax, + SQLINTEGER *pcbSqlStr); + + +SQLRETURN SQL_API SQLPrimaryKeysW( + SQLHSTMT hstmt, + SQLWCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLWCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLWCHAR *szTableName, + SQLSMALLINT cbTableName); + +SQLRETURN SQL_API SQLProcedureColumnsW( + SQLHSTMT hstmt, + SQLWCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLWCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLWCHAR *szProcName, + SQLSMALLINT cbProcName, + SQLWCHAR *szColumnName, + SQLSMALLINT cbColumnName); + +SQLRETURN SQL_API SQLProceduresW( + SQLHSTMT hstmt, + SQLWCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLWCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLWCHAR *szProcName, + SQLSMALLINT cbProcName); + + +SQLRETURN SQL_API SQLTablePrivilegesW( + SQLHSTMT hstmt, + SQLWCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLWCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLWCHAR *szTableName, + SQLSMALLINT cbTableName); + +SQLRETURN SQL_API SQLDriversW( + SQLHENV henv, + SQLUSMALLINT fDirection, + SQLWCHAR *szDriverDesc, + SQLSMALLINT cbDriverDescMax, + SQLSMALLINT *pcbDriverDesc, + SQLWCHAR *szDriverAttributes, + SQLSMALLINT cbDrvrAttrMax, + SQLSMALLINT *pcbDrvrAttr); + + +/* ANSI versions */ + +SQLRETURN SQL_API SQLColAttributeA( + SQLHSTMT hstmt, + SQLSMALLINT iCol, + SQLSMALLINT iField, + SQLPOINTER pCharAttr, + SQLSMALLINT cbCharAttrMax, + SQLSMALLINT *pcbCharAttr, + SQLLEN *pNumAttr); + +SQLRETURN SQL_API SQLColAttributesA( + SQLHSTMT hstmt, + SQLUSMALLINT icol, + SQLUSMALLINT fDescType, + SQLPOINTER rgbDesc, + SQLSMALLINT cbDescMax, + SQLSMALLINT *pcbDesc, + SQLLEN *pfDesc); + +SQLRETURN SQL_API SQLConnectA( + SQLHDBC hdbc, + SQLCHAR *szDSN, + SQLSMALLINT cbDSN, + SQLCHAR *szUID, + SQLSMALLINT cbUID, + SQLCHAR *szAuthStr, + SQLSMALLINT cbAuthStr); + + +SQLRETURN SQL_API SQLDescribeColA( + SQLHSTMT hstmt, + SQLUSMALLINT icol, + SQLCHAR *szColName, + SQLSMALLINT cbColNameMax, + SQLSMALLINT *pcbColName, + SQLSMALLINT *pfSqlType, + SQLULEN *pcbColDef, + SQLSMALLINT *pibScale, + SQLSMALLINT *pfNullable); + + +SQLRETURN SQL_API SQLErrorA( + SQLHENV henv, + SQLHDBC hdbc, + SQLHSTMT hstmt, + SQLCHAR *szSqlState, + SQLINTEGER *pfNativeError, + SQLCHAR *szErrorMsg, + SQLSMALLINT cbErrorMsgMax, + SQLSMALLINT *pcbErrorMsg); + +SQLRETURN SQL_API SQLExecDirectA( + SQLHSTMT hstmt, + SQLCHAR *szSqlStr, + SQLINTEGER cbSqlStr); + +SQLRETURN SQL_API SQLGetConnectAttrA( + SQLHDBC hdbc, + SQLINTEGER fAttribute, + SQLPOINTER rgbValue, + SQLINTEGER cbValueMax, + SQLINTEGER *pcbValue); + +SQLRETURN SQL_API SQLGetCursorNameA( + SQLHSTMT hstmt, + SQLCHAR *szCursor, + SQLSMALLINT cbCursorMax, + SQLSMALLINT *pcbCursor); + +#if (ODBCVER >= 0x0300) +SQLRETURN SQL_API SQLGetDescFieldA( + SQLHDESC hdesc, + SQLSMALLINT iRecord, + SQLSMALLINT iField, + SQLPOINTER rgbValue, + SQLINTEGER cbValueMax, + SQLINTEGER *pcbValue); + +SQLRETURN SQL_API SQLGetDescRecA( + SQLHDESC hdesc, + SQLSMALLINT iRecord, + SQLCHAR *szName, + SQLSMALLINT cbNameMax, + SQLSMALLINT *pcbName, + SQLSMALLINT *pfType, + SQLSMALLINT *pfSubType, + SQLLEN *pLength, + SQLSMALLINT *pPrecision, + SQLSMALLINT *pScale, + SQLSMALLINT *pNullable); + +SQLRETURN SQL_API SQLGetDiagFieldA( + SQLSMALLINT fHandleType, + SQLHANDLE handle, + SQLSMALLINT iRecord, + SQLSMALLINT fDiagField, + SQLPOINTER rgbDiagInfo, + SQLSMALLINT cbDiagInfoMax, + SQLSMALLINT *pcbDiagInfo); + +SQLRETURN SQL_API SQLGetDiagRecA( + SQLSMALLINT fHandleType, + SQLHANDLE handle, + SQLSMALLINT iRecord, + SQLCHAR *szSqlState, + SQLINTEGER *pfNativeError, + SQLCHAR *szErrorMsg, + SQLSMALLINT cbErrorMsgMax, + SQLSMALLINT *pcbErrorMsg); + + +SQLRETURN SQL_API SQLGetStmtAttrA( + SQLHSTMT hstmt, + SQLINTEGER fAttribute, + SQLPOINTER rgbValue, + SQLINTEGER cbValueMax, + SQLINTEGER *pcbValue); + +#endif + +SQLRETURN SQL_API SQLGetTypeInfoA( + SQLHSTMT StatementHandle, + SQLSMALLINT DataTyoe); + +SQLRETURN SQL_API SQLPrepareA( + SQLHSTMT hstmt, + SQLCHAR *szSqlStr, + SQLINTEGER cbSqlStr); + +SQLRETURN SQL_API SQLSetConnectAttrA( + SQLHDBC hdbc, + SQLINTEGER fAttribute, + SQLPOINTER rgbValue, + SQLINTEGER cbValue); + +SQLRETURN SQL_API SQLSetCursorNameA( + SQLHSTMT hstmt, + SQLCHAR *szCursor, + SQLSMALLINT cbCursor); + + + + + + + +SQLRETURN SQL_API SQLColumnsA( + SQLHSTMT hstmt, + SQLCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR *szTableName, + SQLSMALLINT cbTableName, + SQLCHAR *szColumnName, + SQLSMALLINT cbColumnName); + +SQLRETURN SQL_API SQLGetConnectOptionA( + SQLHDBC hdbc, + SQLUSMALLINT fOption, + SQLPOINTER pvParam); + + + +SQLRETURN SQL_API SQLGetInfoA( + SQLHDBC hdbc, + SQLUSMALLINT fInfoType, + SQLPOINTER rgbInfoValue, + SQLSMALLINT cbInfoValueMax, + SQLSMALLINT* pcbInfoValue); + +SQLRETURN SQL_API SQLGetStmtOptionA( + SQLHSTMT hstmt, + SQLUSMALLINT fOption, + SQLPOINTER pvParam); + +SQLRETURN SQL_API SQLSetConnectOptionA( + SQLHDBC hdbc, + SQLUSMALLINT fOption, + SQLULEN vParam); + +SQLRETURN SQL_API SQLSetStmtOptionA( + SQLHSTMT hstmt, + SQLUSMALLINT fOption, + SQLULEN vParam); + +SQLRETURN SQL_API SQLSpecialColumnsA( + SQLHSTMT hstmt, + SQLUSMALLINT fColType, + SQLCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR *szTableName, + SQLSMALLINT cbTableName, + SQLUSMALLINT fScope, + SQLUSMALLINT fNullable); + +SQLRETURN SQL_API SQLStatisticsA( + SQLHSTMT hstmt, + + SQLCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR *szTableName, + SQLSMALLINT cbTableName, + SQLUSMALLINT fUnique, + SQLUSMALLINT fAccuracy); + +SQLRETURN SQL_API SQLTablesA( + SQLHSTMT hstmt, + + SQLCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR *szTableName, + SQLSMALLINT cbTableName, + SQLCHAR *szTableType, + + SQLSMALLINT cbTableType); + + + +SQLRETURN SQL_API SQLDataSourcesA( + SQLHENV henv, + SQLUSMALLINT fDirection, + SQLCHAR *szDSN, + SQLSMALLINT cbDSNMax, + SQLSMALLINT *pcbDSN, + SQLCHAR *szDescription, + SQLSMALLINT cbDescriptionMax, + SQLSMALLINT *pcbDescription); + + + + +SQLRETURN SQL_API SQLDriverConnectA( + SQLHDBC hdbc, + SQLHWND hwnd, + SQLCHAR *szConnStrIn, + SQLSMALLINT cbConnStrIn, + SQLCHAR *szConnStrOut, + SQLSMALLINT cbConnStrOutMax, + SQLSMALLINT *pcbConnStrOut, + SQLUSMALLINT fDriverCompletion); + + +SQLRETURN SQL_API SQLBrowseConnectA( + SQLHDBC hdbc, + SQLCHAR *szConnStrIn, + SQLSMALLINT cbConnStrIn, + SQLCHAR *szConnStrOut, + SQLSMALLINT cbConnStrOutMax, + SQLSMALLINT *pcbConnStrOut); + +SQLRETURN SQL_API SQLColumnPrivilegesA( + SQLHSTMT hstmt, + SQLCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR *szTableName, + SQLSMALLINT cbTableName, + SQLCHAR *szColumnName, + SQLSMALLINT cbColumnName); + +SQLRETURN SQL_API SQLDescribeParamA( + SQLHSTMT hstmt, + SQLUSMALLINT ipar, + SQLSMALLINT *pfSqlType, + SQLUINTEGER *pcbParamDef, + SQLSMALLINT *pibScale, + SQLSMALLINT *pfNullable); + + +SQLRETURN SQL_API SQLForeignKeysA( + SQLHSTMT hstmt, + SQLCHAR *szPkCatalogName, + SQLSMALLINT cbPkCatalogName, + SQLCHAR *szPkSchemaName, + SQLSMALLINT cbPkSchemaName, + SQLCHAR *szPkTableName, + SQLSMALLINT cbPkTableName, + SQLCHAR *szFkCatalogName, + SQLSMALLINT cbFkCatalogName, + SQLCHAR *szFkSchemaName, + SQLSMALLINT cbFkSchemaName, + SQLCHAR *szFkTableName, + SQLSMALLINT cbFkTableName); + + +SQLRETURN SQL_API SQLNativeSqlA( + SQLHDBC hdbc, + SQLCHAR *szSqlStrIn, + SQLINTEGER cbSqlStrIn, + SQLCHAR *szSqlStr, + SQLINTEGER cbSqlStrMax, + SQLINTEGER *pcbSqlStr); + + +SQLRETURN SQL_API SQLPrimaryKeysA( + SQLHSTMT hstmt, + SQLCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR *szTableName, + SQLSMALLINT cbTableName); + +SQLRETURN SQL_API SQLProcedureColumnsA( + SQLHSTMT hstmt, + SQLCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR *szProcName, + SQLSMALLINT cbProcName, + SQLCHAR *szColumnName, + SQLSMALLINT cbColumnName); + +SQLRETURN SQL_API SQLProceduresA( + SQLHSTMT hstmt, + SQLCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR *szProcName, + SQLSMALLINT cbProcName); + + +SQLRETURN SQL_API SQLTablePrivilegesA( + SQLHSTMT hstmt, + SQLCHAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR *szTableName, + SQLSMALLINT cbTableName); + +SQLRETURN SQL_API SQLDriversA( + SQLHENV henv, + SQLUSMALLINT fDirection, + SQLCHAR *szDriverDesc, + SQLSMALLINT cbDriverDescMax, + SQLSMALLINT *pcbDriverDesc, + SQLCHAR *szDriverAttributes, + SQLSMALLINT cbDrvrAttrMax, + SQLSMALLINT *pcbDrvrAttr); + + + + + +/*---------------------------------------------*/ +/* Mapping macros for Unicode */ +/*---------------------------------------------*/ + +#ifndef SQL_NOUNICODEMAP /* define this to disable the mapping */ +#ifdef UNICODE + +#define SQLColAttribute SQLColAttributeW +#define SQLColAttributes SQLColAttributesW +#define SQLConnect SQLConnectW +#define SQLDescribeCol SQLDescribeColW +#define SQLError SQLErrorW +#define SQLExecDirect SQLExecDirectW +#define SQLGetConnectAttr SQLGetConnectAttrW +#define SQLGetCursorName SQLGetCursorNameW +#define SQLGetDescField SQLGetDescFieldW +#define SQLGetDescRec SQLGetDescRecW +#define SQLGetDiagField SQLGetDiagFieldW +#define SQLGetDiagRec SQLGetDiagRecW +#define SQLPrepare SQLPrepareW +#define SQLSetConnectAttr SQLSetConnectAttrW +#define SQLSetCursorName SQLSetCursorNameW +#define SQLSetDescField SQLSetDescFieldW +#define SQLSetStmtAttr SQLSetStmtAttrW +#define SQLGetStmtAttr SQLGetStmtAttrW +#define SQLColumns SQLColumnsW +#define SQLGetConnectOption SQLGetConnectOptionW +#define SQLGetInfo SQLGetInfoW +#define SQLGetTypeInfo SQLGetTypeInfoW +#define SQLSetConnectOption SQLSetConnectOptionW +#define SQLSpecialColumns SQLSpecialColumnsW +#define SQLStatistics SQLStatisticsW +#define SQLTables SQLTablesW +#define SQLDataSources SQLDataSourcesW +#define SQLDriverConnect SQLDriverConnectW +#define SQLBrowseConnect SQLBrowseConnectW +#define SQLColumnPrivileges SQLColumnPrivilegesW +#define SQLForeignKeys SQLForeignKeysW +#define SQLNativeSql SQLNativeSqlW +#define SQLPrimaryKeys SQLPrimaryKeysW +#define SQLProcedureColumns SQLProcedureColumnsW +#define SQLProcedures SQLProceduresW +#define SQLTablePrivileges SQLTablePrivilegesW +#define SQLDrivers SQLDriversW + +#endif /* UNICODE */ +#endif /* SQL_NOUNICODEMAP */ + +#ifdef __cplusplus +} +#endif + +#ifndef __SQLEXT_H +#include + +#endif + + +#endif diff --git a/libodbc/include/ss_linux/unixodbc_conf.h b/libodbc/include/ss_linux/unixodbc_conf.h new file mode 100644 index 0000000000..cbda156bf4 --- /dev/null +++ b/libodbc/include/ss_linux/unixodbc_conf.h @@ -0,0 +1,15 @@ +#ifndef HAVE_UNISTD_H + #define HAVE_UNISTD_H +#endif +#ifndef HAVE_PWD_H + #define HAVE_PWD_H +#endif +#ifndef HAVE_SYS_TYPES_H + #define HAVE_SYS_TYPES_H +#endif +#ifndef HAVE_LONG_LONG + #define HAVE_LONG_LONG +#endif +#ifndef SIZEOF_LONG_INT + #define SIZEOF_LONG_INT 8 +#endif diff --git a/libodbc/include/ss_linux/uodbc_extras.h b/libodbc/include/ss_linux/uodbc_extras.h new file mode 100644 index 0000000000..29e3b27acb --- /dev/null +++ b/libodbc/include/ss_linux/uodbc_extras.h @@ -0,0 +1,85 @@ +/********************************************************************* + * + * This is based on code created by Peter Harvey, + * (pharvey@codebydesign.com). + * + * Modified and extended by Nick Gorham + * (nick@easysoft.com). + * + * Further modified and extend by Eric Sharkey + * (sharkey@netrics.com). + * + * Any bugs or problems should be considered the fault of Nick or + * Eric and not Peter. + * + * copyright (c) 2005 Eric Sharkey + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + ********************************************************************** + * + * $Id: uodbc_extras.h,v 1.1 2013-05-01 20:49:05 yas Exp $ + * + **********************************************************************/ +#ifndef UODBC__extras_h +#define UODBC__extras_h 1 + +#if defined(HAVE_STDARG_H) +# include +# define HAVE_STDARGS +#else +# if defined(HAVE_VARARGS_H) +# include +# ifdef HAVE_STDARGS +# undef HAVE_STDARGS +# endif +# endif +#endif + +#if defined(__cplusplus) + extern "C" { +#endif + +extern int uodbc_vsnprintf (char *str, size_t count, const char *fmt, va_list args); + +#ifdef HAVE_STDARGS + int uodbc_snprintf (char *str,size_t count,const char *fmt,...); +#else + int uodbc_snprintf (va_alist) va_dcl; +#endif + +#ifndef HAVE_SNPRINTF +#define snprintf uodbc_snprintf +#endif + +#ifndef HAVE_VSNPRINTF +#define vsnprintf uodbc_vsnprintf +#endif + +#ifndef HAVE_STRCASECMP +extern int strcasecmp( const char *s1, const char * s2 ); +#endif + +#ifndef HAVE_STRNCASECMP +extern int strncasecmp (const char *s1, const char *s2, int n ); +#endif + + +#if defined(__cplusplus) + } +#endif + +#endif /* UODBC__extras_h */ + diff --git a/libodbc/include/ss_linux/uodbc_stats.h b/libodbc/include/ss_linux/uodbc_stats.h new file mode 100644 index 0000000000..fc53c2b66c --- /dev/null +++ b/libodbc/include/ss_linux/uodbc_stats.h @@ -0,0 +1,86 @@ +/********************************************************************* + * + * This is based on code created by Peter Harvey, + * (pharvey@codebydesign.com). + * + * Modified and extended by Nick Gorham + * (nick@easysoft.com). + * + * Any bugs or problems should be considered the fault of Nick and not + * Peter. + * + * copyright (c) 1999 Nick Gorham + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + ********************************************************************** + * + * $Id: uodbc_stats.h,v 1.1 2013-05-01 20:49:06 yas Exp $ + * + * $Log: uodbc_stats.h,v $ + * Revision 1.1 2013-05-01 20:49:06 yas + * intermediate commit + * + * Revision 1.1.1.1 2001/10/17 16:40:28 lurcher + * + * First upload to SourceForge + * + * Revision 1.2 2000/12/19 07:28:45 pharvey + * - added first pass at Stats page content + * - wrapped public stats functions for C++ + * + * Revision 1.1 2000/12/18 11:54:22 martin + * + * handle statistic API. + * + * + **********************************************************************/ +#ifndef UODBC__stats_h +#define UODBC__stats_h 1 + +#include +#include + +typedef struct uodbc_stats_retentry +{ + unsigned long type; /* type of statistic */ +# define UODBC_STAT_STRING 1 +# define UODBC_STAT_LONG 2 + union + { + char s_value[256]; /* string type */ + long l_value; /* number type */ + } value; + char name[32]; /* name of statistic */ +} uodbc_stats_retentry; + +#if defined(__cplusplus) + extern "C" { +#endif + +int uodbc_open_stats(void **rh, unsigned int mode); +#define UODBC_STATS_READ 0x1 +#define UODBC_STATS_WRITE 0x2 +int uodbc_close_stats(void *rh); +int uodbc_get_stats(void *h, pid_t request_pid, + uodbc_stats_retentry *s, int n_stats); +char *uodbc_stats_error(char *buf, size_t buflen); + +#if defined(__cplusplus) + } +#endif + +#endif /* UODBC__stats_h */ + diff --git a/libodbc/include/sybAPI.h b/libodbc/include/sybAPI.h new file mode 100644 index 0000000000..da4f1cd2a8 --- /dev/null +++ b/libodbc/include/sybAPI.h @@ -0,0 +1,649 @@ +// sybAPI.h +// +////////////////////////////////////////////////////////////////////// + +#if !defined(__SYBAPI_H__) +#define __SYBAPI_H__ + +#include "SQLAPI.h" + +// API header(s) +#include + +//! Sybase client and server messages handling callback +typedef void (SQLAPI_CALLBACK *saSybMsgHandler_t)(void *pMessageStruct, bool bIsServerMessage, void *pAddInfo); + +class SQLAPI_API SASybErrInfo : public SAMutex +{ +public: + SASybErrInfo(); + +public: + CS_MSGNUM msgnumber; + CS_CHAR msgstring[CS_MAX_MSG]; + CS_INT line; + + saSybMsgHandler_t fMsgHandler; + void * pMsgAddInfo; +} ; + +extern void AddSybSupport(const SAConnection *pCon); +extern void ReleaseSybSupport(); + +typedef CS_RETCODE (CS_PUBLIC *ct_debug_t)( + CS_CONTEXT *context, + CS_CONNECTION *connection, + CS_INT operation, + CS_INT flag, + CS_CHAR *filename, + CS_INT fnamelen + ); +typedef CS_RETCODE (CS_PUBLIC *ct_bind_t)( + CS_COMMAND *cmd, + CS_INT item, + CS_DATAFMT *datafmt, + CS_VOID *buf, + CS_INT *outputlen, + CS_SMALLINT *indicator + ); +typedef CS_RETCODE (CS_PUBLIC *ct_br_column_t)( + CS_COMMAND *cmd, + CS_INT colnum, + CS_BROWSEDESC *browsedesc + ); +typedef CS_RETCODE (CS_PUBLIC *ct_br_table_t)( + CS_COMMAND *cmd, + CS_INT tabnum, + CS_INT type, + CS_VOID *buf, + CS_INT buflen, + CS_INT *outlen + ); +typedef CS_RETCODE (CS_PUBLIC *ct_callback_t)( + CS_CONTEXT *context, + CS_CONNECTION *connection, + CS_INT action, + CS_INT type, + CS_VOID *func + ); +typedef CS_RETCODE (CS_PUBLIC *ct_cancel_t)( + CS_CONNECTION *connection, + CS_COMMAND *cmd, + CS_INT type + ); +typedef CS_RETCODE (CS_PUBLIC *ct_capability_t)( + CS_CONNECTION *connection, + CS_INT action, + CS_INT type, + CS_INT capability, + CS_VOID *val + ); +typedef CS_RETCODE (CS_PUBLIC *ct_compute_info_t)( + CS_COMMAND *cmd, + CS_INT type, + CS_INT colnum, + CS_VOID *buf, + CS_INT buflen, + CS_INT *outlen + ); +typedef CS_RETCODE (CS_PUBLIC *ct_close_t)( + CS_CONNECTION *connection, + CS_INT option + ); +typedef CS_RETCODE (CS_PUBLIC *ct_cmd_alloc_t)( + CS_CONNECTION *connection, + CS_COMMAND **cmdptr + ); +typedef CS_RETCODE (CS_PUBLIC *ct_cmd_drop_t)( + CS_COMMAND *cmd + ); +typedef CS_RETCODE (CS_PUBLIC *ct_cmd_props_t)( + CS_COMMAND *cmd, + CS_INT action, + CS_INT property, + CS_VOID *buf, + CS_INT buflen, + CS_INT *outlen + ); +typedef CS_RETCODE (CS_PUBLIC *ct_command_t)( + CS_COMMAND *cmd, + CS_INT type, + CS_CHAR *buf, + CS_INT buflen, + CS_INT option + ); +typedef CS_RETCODE (CS_PUBLIC *ct_con_alloc_t)( + CS_CONTEXT *context, + CS_CONNECTION **connection + ); +typedef CS_RETCODE (CS_PUBLIC *ct_con_drop_t)( + CS_CONNECTION *connection + ); +typedef CS_RETCODE (CS_PUBLIC *ct_con_props_t)( + CS_CONNECTION *connection, + CS_INT action, + CS_INT property, + CS_VOID *buf, + CS_INT buflen, + CS_INT *outlen + ); +typedef CS_RETCODE (CS_PUBLIC *ct_connect_t)( + CS_CONNECTION *connection, + CS_CHAR *server_name, + CS_INT snamelen + ); +typedef CS_RETCODE (CS_PUBLIC *ct_config_t)( + CS_CONTEXT *context, + CS_INT action, + CS_INT property, + CS_VOID *buf, + CS_INT buflen, + CS_INT *outlen + ); +typedef CS_RETCODE (CS_PUBLIC *ct_cursor_t)( + CS_COMMAND *cmd, + CS_INT type, + CS_CHAR *name, + CS_INT namelen, + CS_CHAR *text, + CS_INT tlen, + CS_INT option + ); +typedef CS_RETCODE (CS_PUBLIC *ct_dyndesc_t)( + CS_COMMAND *cmd, + CS_CHAR *descriptor, + CS_INT desclen, + CS_INT operation, + CS_INT idx, + CS_DATAFMT *datafmt, + CS_VOID *buffer, + CS_INT buflen, + CS_INT *copied, + CS_SMALLINT *indicator + ); +typedef CS_RETCODE (CS_PUBLIC *ct_describe_t)( + CS_COMMAND *cmd, + CS_INT item, + CS_DATAFMT *datafmt + ); +typedef CS_RETCODE (CS_PUBLIC *ct_diag_t)( + CS_CONNECTION *connection, + CS_INT operation, + CS_INT type, + CS_INT idx, + CS_VOID *buffer + ); +typedef CS_RETCODE (CS_PUBLIC *ct_dynamic_t)( + CS_COMMAND *cmd, + CS_INT type, + CS_CHAR *id, + CS_INT idlen, + CS_CHAR *buf, + CS_INT buflen + ); +typedef CS_RETCODE (CS_PUBLIC *ct_dynsqlda_t)( + CS_COMMAND *cmd, + CS_INT type, + SQLDA *dap, + CS_INT operation + ); +typedef CS_RETCODE (CS_PUBLIC *ct_exit_t)( + CS_CONTEXT *context, + CS_INT option + ); +typedef CS_RETCODE (CS_PUBLIC *ct_fetch_t)( + CS_COMMAND *cmd, + CS_INT type, + CS_INT offset, + CS_INT option, + CS_INT *count + ); +typedef CS_RETCODE (CS_PUBLIC *ct_getformat_t)( + CS_COMMAND *cmd, + CS_INT colnum, + CS_VOID *buf, + CS_INT buflen, + CS_INT *outlen + ); +typedef CS_RETCODE (CS_PUBLIC *ct_keydata_t)( + CS_COMMAND *cmd, + CS_INT action, + CS_INT colnum, + CS_VOID *buffer, + CS_INT buflen, + CS_INT *outlen + ); +typedef CS_RETCODE (CS_PUBLIC *ct_init_t)( + CS_CONTEXT *context, + CS_INT version + ); +typedef CS_RETCODE (CS_PUBLIC *ct_options_t)( + CS_CONNECTION *connection, + CS_INT action, + CS_INT option, + CS_VOID *param, + CS_INT paramlen, + CS_INT *outlen + ); +typedef CS_RETCODE (CS_PUBLIC *syb_ct_param_t)( + CS_COMMAND *cmd, + CS_DATAFMT *datafmt, + CS_VOID *data, + CS_INT datalen, + CS_SMALLINT indicator + ); +typedef CS_RETCODE (CS_PUBLIC *ct_getloginfo_t)( + CS_CONNECTION *connection, + CS_LOGINFO **logptr + ); +typedef CS_RETCODE (CS_PUBLIC *ct_setloginfo_t)( + CS_CONNECTION *connection, + CS_LOGINFO *loginfo + ); +typedef CS_RETCODE (CS_PUBLIC *ct_recvpassthru_t)( + CS_COMMAND *cmd, + CS_VOID **recvptr + ); +typedef CS_RETCODE (CS_PUBLIC *ct_sendpassthru_t)( + CS_COMMAND *cmd, + CS_VOID *send_bufp + ); +typedef CS_RETCODE (CS_PUBLIC *ct_poll_t)( + CS_CONTEXT *context, + CS_CONNECTION *connection, + CS_INT milliseconds, + CS_CONNECTION **compconn, + CS_COMMAND **compcmd, + CS_INT *compid, + CS_INT *compstatus + ); +typedef CS_RETCODE (CS_PUBLIC *ct_remote_pwd_t)( + CS_CONNECTION *connection, + CS_INT action, + CS_CHAR *server_name, + CS_INT snamelen, + CS_CHAR *password, + CS_INT pwdlen + ); +typedef CS_RETCODE (CS_PUBLIC *ct_results_t)( + CS_COMMAND *cmd, + CS_INT *result_type + ); +typedef CS_RETCODE (CS_PUBLIC *ct_res_info_t)( + CS_COMMAND *cmd, + CS_INT operation, + CS_VOID *buf, + CS_INT buflen, + CS_INT *outlen + ); +typedef CS_RETCODE (CS_PUBLIC *ct_send_t)( + CS_COMMAND *cmd + ); +typedef CS_RETCODE (CS_PUBLIC *ct_get_data_t)( + CS_COMMAND *cmd, + CS_INT colnum, + CS_VOID *buf, + CS_INT buflen, + CS_INT *outlen + ); +typedef CS_RETCODE (CS_PUBLIC *ct_send_data_t)( + CS_COMMAND *cmd, + CS_VOID *buf, + CS_INT buflen + ); +typedef CS_RETCODE (CS_PUBLIC *ct_data_info_t)( + CS_COMMAND *cmd, + CS_INT action, + CS_INT colnum, + CS_IODESC *iodesc + ); +typedef CS_RETCODE (CS_PUBLIC *ct_wakeup_t)( + CS_CONNECTION *connection, + CS_COMMAND *cmd, + CS_INT func_id, + CS_RETCODE status + ); +typedef CS_RETCODE (CS_PUBLIC *ct_labels_t)( + CS_CONNECTION *connection, + CS_INT action, + CS_CHAR *labelname, + CS_INT namelen, + CS_CHAR *labelvalue, + CS_INT valuelen, + CS_INT *outlen + ); +typedef CS_RETCODE (CS_PUBLIC *ct_ds_lookup_t)( + CS_CONNECTION *connection, + CS_INT action, + CS_INT *reqidp, + CS_DS_LOOKUP_INFO *lookupinfo, + CS_VOID *userdatap + ); +typedef CS_RETCODE (CS_PUBLIC *ct_ds_dropobj_t)( + CS_CONNECTION *connection, + CS_DS_OBJECT *object + ); +typedef CS_RETCODE (CS_PUBLIC *ct_ds_objinfo_t)( + CS_DS_OBJECT *objclass, + CS_INT action, + CS_INT objinfo, + CS_INT number, + CS_VOID *buffer, + CS_INT buflen, + CS_INT *outlen + ); +typedef CS_RETCODE (CS_PUBLIC *ct_setparam_t)( + CS_COMMAND *cmd, + CS_DATAFMT *datafmt, + CS_VOID *data, + CS_INT *datalenp, + CS_SMALLINT *indp + ); + +typedef CS_RETCODE (CS_PUBLIC *cs_calc_t)( + CS_CONTEXT *context, + CS_INT op, + CS_INT datatype, + CS_VOID *var1, + CS_VOID *var2, + CS_VOID *dest + ); +typedef CS_RETCODE (CS_PUBLIC *cs_cmp_t)( + CS_CONTEXT *context, + CS_INT datatype, + CS_VOID *var1, + CS_VOID *var2, + CS_INT *result + ); +typedef CS_RETCODE (CS_PUBLIC *cs_convert_t)( + CS_CONTEXT *context, + CS_DATAFMT *srcfmt, + CS_VOID *srcdata, + CS_DATAFMT *destfmt, + CS_VOID *destdata, + CS_INT *outlen + ); +typedef CS_RETCODE (CS_PUBLIC *cs_will_convert_t)( + CS_CONTEXT *context, + CS_INT srctype, + CS_INT desttype, + CS_BOOL *result + ); +typedef CS_RETCODE (CS_PUBLIC *cs_set_convert_t)( + CS_CONTEXT *context, + CS_INT action, + CS_INT srctype, + CS_INT desttype, + CS_CONV_FUNC *buffer + ); +typedef CS_RETCODE (CS_PUBLIC *cs_setnull_t)( + CS_CONTEXT *context, + CS_DATAFMT *datafmt, + CS_VOID *buf, + CS_INT buflen + ); +typedef CS_RETCODE (CS_PUBLIC *cs_config_t)( + CS_CONTEXT *context, + CS_INT action, + CS_INT property, + CS_VOID *buf, + CS_INT buflen, + CS_INT *outlen + ); +typedef CS_RETCODE (CS_PUBLIC *cs_ctx_alloc_t)( + CS_INT version, + CS_CONTEXT **outptr + ); +typedef CS_RETCODE (CS_PUBLIC *cs_ctx_drop_t)( + CS_CONTEXT *context + ); +typedef CS_RETCODE (CS_PUBLIC *cs_ctx_global_t)( + CS_INT version, + CS_CONTEXT **outptr + ); +typedef CS_RETCODE (CS_PUBLIC *cs_objects_t)( + CS_CONTEXT *context, + CS_INT action, + CS_OBJNAME *objname, + CS_OBJDATA *objdata + ); +typedef CS_RETCODE (CS_PUBLIC *cs_diag_t)( + CS_CONTEXT *context, + CS_INT operation, + CS_INT type, + CS_INT idx, + CS_VOID *buffer + ); +typedef CS_RETCODE (CS_PUBLIC *cs_dt_crack_t)( + CS_CONTEXT *context, + CS_INT datetype, + CS_VOID *dateval, + CS_DATEREC *daterec + ); +typedef CS_RETCODE (CS_PUBLIC *cs_dt_info_t)( + CS_CONTEXT *context, + CS_INT action, + CS_LOCALE *locale, + CS_INT type, + CS_INT item, + CS_VOID *buffer, + CS_INT buflen, + CS_INT *outlen + ); +typedef CS_RETCODE (CS_PUBLIC *cs_locale_t)( + CS_CONTEXT *context, + CS_INT action, + CS_LOCALE *locale, + CS_INT type, + CS_CHAR *buffer, + CS_INT buflen, + CS_INT *outlen + ); +typedef CS_RETCODE (CS_PUBLIC *cs_loc_alloc_t)( + CS_CONTEXT *context, + CS_LOCALE **loc_pointer + ); +typedef CS_RETCODE (CS_PUBLIC *cs_loc_drop_t)( + CS_CONTEXT *context, + CS_LOCALE *locale + ); +#ifdef CS__INTERNAL_STRUCTS +typedef CS_RETCODE (CS_VARARGS *cs_strbuild_t)( + CS_CONTEXT *context, + ... + ); +#else +typedef CS_RETCODE (CS_VARARGS *cs_strbuild_t)( + CS_CONTEXT *context, + CS_CHAR *buf, + CS_INT buflen, + CS_INT *outlen, + CS_CHAR *text, + CS_INT textlen, + ... + ); +#endif /* CS__INTERNAL_STRUCTS */ +typedef CS_RETCODE (CS_PUBLIC *cs_strcmp_t)( + CS_CONTEXT *context, + CS_LOCALE *locale, + CS_INT type, + CS_CHAR *str1, + CS_INT len1, + CS_CHAR *str2, + CS_INT len2, + CS_INT *result + ); +typedef CS_RETCODE (CS_PUBLIC *cs_time_t)( + CS_CONTEXT *context, + CS_LOCALE *locale, + CS_VOID *buf, + CS_INT buflen, + CS_INT *outlen, + CS_DATEREC *drec + ); +typedef CS_RETCODE (CS_PUBLIC *cs_manage_convert_t)( + CS_CONTEXT *context, + CS_INT action, + CS_INT srctype, + CS_CHAR *srcname, + CS_INT srcnamelen, + CS_INT desttype, + CS_CHAR *destname, + CS_INT destnamelen, + CS_INT *maxmultiplier, + CS_CONV_FUNC *func + ); +typedef CS_RETCODE (CS_PUBLIC *cs_conv_mult_t)( + CS_CONTEXT *context, + CS_LOCALE *srcloc, + CS_LOCALE *destloc, + CS_INT *multiplier + ); + +typedef CS_RETCODE (CS_PUBLIC *ct_scroll_fetch_t)( + CS_COMMAND *cmd, + CS_INT type, + CS_INT offset, + CS_INT option, + CS_INT *count + ); + +// API declarations +class SQLAPI_API sybAPI : public saAPI +{ +public: + sybAPI(); + + ct_debug_t ct_debug; + ct_bind_t ct_bind; + ct_br_column_t ct_br_column; + ct_br_table_t ct_br_table; + ct_callback_t ct_callback; + ct_cancel_t ct_cancel; + ct_capability_t ct_capability; + ct_compute_info_t ct_compute_info; + ct_close_t ct_close; + ct_cmd_alloc_t ct_cmd_alloc; + ct_cmd_drop_t ct_cmd_drop; + ct_cmd_props_t ct_cmd_props; + ct_command_t ct_command; + ct_con_alloc_t ct_con_alloc; + ct_con_drop_t ct_con_drop; + ct_con_props_t ct_con_props; + ct_connect_t ct_connect; + ct_config_t ct_config; + ct_cursor_t ct_cursor; + ct_dyndesc_t ct_dyndesc; + ct_describe_t ct_describe; + ct_diag_t ct_diag; + ct_dynamic_t ct_dynamic; + ct_dynsqlda_t ct_dynsqlda; + ct_exit_t ct_exit; + ct_fetch_t ct_fetch; + ct_getformat_t ct_getformat; + ct_keydata_t ct_keydata; + ct_init_t ct_init; + ct_options_t ct_options; + syb_ct_param_t ct_param; + ct_getloginfo_t ct_getloginfo; + ct_setloginfo_t ct_setloginfo; + ct_recvpassthru_t ct_recvpassthru; + ct_sendpassthru_t ct_sendpassthru; + ct_poll_t ct_poll; + ct_remote_pwd_t ct_remote_pwd; + ct_results_t ct_results; + ct_res_info_t ct_res_info; + ct_send_t ct_send; + ct_get_data_t ct_get_data; + ct_send_data_t ct_send_data; + ct_data_info_t ct_data_info; + ct_wakeup_t ct_wakeup; + ct_labels_t ct_labels; + ct_ds_lookup_t ct_ds_lookup; + ct_ds_dropobj_t ct_ds_dropobj; + ct_ds_objinfo_t ct_ds_objinfo; + ct_setparam_t ct_setparam; + + cs_calc_t cs_calc; + cs_cmp_t cs_cmp; + cs_convert_t cs_convert; + cs_will_convert_t cs_will_convert; + cs_set_convert_t cs_set_convert; + cs_setnull_t cs_setnull; + cs_config_t cs_config; + cs_ctx_alloc_t cs_ctx_alloc; + cs_ctx_drop_t cs_ctx_drop; + cs_ctx_global_t cs_ctx_global; + cs_objects_t cs_objects; + cs_diag_t cs_diag; + cs_dt_crack_t cs_dt_crack; + cs_dt_info_t cs_dt_info; + cs_locale_t cs_locale; + cs_loc_alloc_t cs_loc_alloc; + cs_loc_drop_t cs_loc_drop; + cs_strbuild_t cs_strbuild; + cs_strcmp_t cs_strcmp; + cs_time_t cs_time; + cs_manage_convert_t cs_manage_convert; + cs_conv_mult_t cs_conv_mult; + + ct_scroll_fetch_t ct_scroll_fetch; + + static void SetMessageCallback(saSybMsgHandler_t fHandler, void *pAddInfo, SAConnection *pCon = NULL); + static int& DefaultLongMaxLength(); + + SASybErrInfo errorInfo; +}; + +class SQLAPI_API sybConnectionHandles : public saConnectionHandles +{ +public: + sybConnectionHandles(); + + CS_CONTEXT *m_context; + CS_CONNECTION *m_connection; + CS_LOCALE* m_locale; +}; + +class SQLAPI_API sybCommandHandles : public saCommandHandles +{ +public: + sybCommandHandles(); + + CS_COMMAND *m_command; +}; + +class SQLAPI_API sybExternalConnection +{ + bool m_bAttached; + + SAConnection *m_pCon; + CS_CONTEXT *m_contextSaved; + CS_CONNECTION *m_connectionSaved; + + CS_CONTEXT *m_context; + CS_CONNECTION *m_connection; + CS_VOID *m_ExternalContextClientMsg_cb; + CS_VOID *m_ExternalContextServerMsg_cb; + CS_VOID *m_ExternalConnectionClientMsg_cb; + CS_VOID *m_ExternalConnectionServerMsg_cb; + CS_INT m_nExternalUserDataLen; + CS_VOID *m_pExternalUserData; + CS_INT m_nExternalUserDataAllocated; + SASybErrInfo m_SybErrInfo; + +public: + sybExternalConnection( + SAConnection *pCon, + CS_CONTEXT *context, + CS_CONNECTION *connection); + void Attach(); + void Detach(); + ~sybExternalConnection(); +}; + + + +extern sybAPI g_sybAPI; + +#endif // !defined(__SYBAPI_H__) diff --git a/libodbc/include/sybase/bkpublic.h b/libodbc/include/sybase/bkpublic.h new file mode 100644 index 0000000000..9cc80003af --- /dev/null +++ b/libodbc/include/sybase/bkpublic.h @@ -0,0 +1,286 @@ +/* +** Sybase OpenClient +** Confidential Property of Sybase, Inc. +** (c) Copyright Sybase, Inc. 1991 - 2005 +** All rights reserved +*/ + +/* +** blkpublic.h - for the bulk copy library API routines +*/ +#ifndef __BKPUBLIC_H__ + +#define __BKPUBLIC_H__ + + +#ifndef __NO_INCLUDE__ +#include +#endif /* __NO_INCLUDE__ */ + +/***************************************************************************** +** +** defines used in BLK-Lib applications +** +*****************************************************************************/ + +/* +** Define for a constant to differentiate the +** blklib api's/ +*/ +#define BLK_API_CONT (CS_INT) 500 +/* +** define for each BLK-Lib API +*/ + +#define BLK_NOAPI ((CS_INT) 0 + BLK_API_CONT) +#define BLK_BIND ((CS_INT) 1 + BLK_API_CONT) +#define BLK_DESCRIBE ((CS_INT) 2 + BLK_API_CONT) +#define BLK_DEFAULT ((CS_INT) 3 + BLK_API_CONT) +#define BLK_INIT ((CS_INT) 4 + BLK_API_CONT) +#define BLK_DONE ((CS_INT) 5 + BLK_API_CONT) +#define BLK_ROWXFER ((CS_INT) 6 + BLK_API_CONT) +#define BLK_TEXTXFER ((CS_INT) 7 + BLK_API_CONT) +#define BLK_SENDROW ((CS_INT) 8 + BLK_API_CONT) +#define BLK_SENDTEXT ((CS_INT) 9 + BLK_API_CONT) +#define BLK_DROP ((CS_INT) 10 + BLK_API_CONT) +#define BLK_GETROW ((CS_INT) 11 + BLK_API_CONT) +#define BLK_COLVAL ((CS_INT) 12 + BLK_API_CONT) +#define BLK_GETTEXT ((CS_INT) 13 + BLK_API_CONT) +#define BLK_PROPS ((CS_INT) 14 + BLK_API_CONT) + + +/* +** The direction of the bulk copy - set in blk_init() +*/ +#define CS_BLK_IN (CS_INT) 1 +#define CS_BLK_OUT (CS_INT) 2 + +/* +** For the blk_done - +** just send a batch of records over +** end the bulk copy operation +** Cancel the bulk copy operation +*/ +#define CS_BLK_BATCH (CS_INT) 1 +#define CS_BLK_ALL (CS_INT) 2 +#define CS_BLK_CANCEL (CS_INT) 3 + +/* +** For blk_default when there is no default value for the column +*/ +#define CS_NO_DEFAULT (CS_INT) (-999) + + +#ifndef BLK_VERSION_100 +#define BLK_VERSION_100 CS_VERSION_100 +#define BLK_VERSION_100_NO_LRGID CS_VERSION_100_NO_LRGID +#endif /* BLK_VERSION_100 */ + +/* +** define BLK_VERSION_110 as BLK_VERSION_100 +*/ +#ifndef BLK_VERSION_110 +#define BLK_VERSION_110 BLK_VERSION_100 +#define BLK_VERSION_110_NO_LRGID BLK_VERSION_100_NO_LRGID +#endif /* BLK_VERSION_110 */ + +/* +** define BLK_VERSION_120 as BLK_VERSION_100 +*/ +#ifndef BLK_VERSION_120 +#define BLK_VERSION_120 BLK_VERSION_100 +#define BLK_VERSION_12_NO_LRGID0 BLK_VERSION_100_NO_LRGID +#endif /* BLK_VERSION_120 */ + +/* +** define BLK_VERSION_125 as CS_VERSION_125 +*/ +#ifndef BLK_VERSION_125 +#define BLK_VERSION_125 CS_VERSION_125 +#define BLK_VERSION_125_NO_LRGID CS_VERSION_125_NO_LRGID +#endif /* BLK_VERSION_125 */ + +/* +** define BLK_VERSION_150 as CS_VERSION_150 +*/ +#ifndef BLK_VERSION_150 +#define BLK_VERSION_150 CS_VERSION_150 +#define BLK_VERSION_150_NO_LRGID CS_VERSION_150_NO_LRGID +#endif /* BLK_VERSION_150 */ + +/* +** define BLK_VERSION_155 as CS_VERSION_155 +*/ +#ifndef BLK_VERSION_155 +#define BLK_VERSION_155 CS_VERSION_155 +#endif /* BLK_VERSION_155 */ + +/* +** define BLK_VERSION_157 as CS_VERSION_157 +*/ +#ifndef BLK_VERSION_157 +#define BLK_VERSION_157 CS_VERSION_157 +#endif /* BLK_VERSION_157 */ + +/* +** For the bulk copy options - used with blk_props() +*/ +#define BLK_IDENTITY (CS_INT) (1) +#define BLK_SENSITIVITY_LBL (CS_INT) (2) +#define BLK_NOAPI_CHK (CS_INT) (3) +#define BLK_SLICENUM (CS_INT) (4) +#define BLK_IDSTARTNUM (CS_INT) (5) +#define BLK_ARRAY_INSERT (CS_INT) (6) +#define ARRAY_INSERT BLK_ARRAY_INSERT +#define BLK_CONV (CS_INT) (7) +#define BLK_PARTITION (CS_INT) (8) +#define BLK_CUSTOM_CLAUSE (CS_INT) (9) + +/* +** Special value for datafmt.status in blklib with array binding +*/ +#define CS_BLK_ARRAY_MAXLEN (CS_INT)0x1000 + +/***************************************************************************** +** +** define all user accessable functions here +** +*****************************************************************************/ + +/* +** declare all functions +*/ + +CS_START_EXTERN_C + +extern CS_RETCODE CS_PUBLIC blk_alloc PROTOTYPE(( + CS_CONNECTION *connection, + CS_INT version, + CS_BLKDESC **blkdesc + )); + +extern CS_RETCODE CS_PUBLIC blk_bind PROTOTYPE(( + CS_BLKDESC *blkdesc, + CS_INT colnum, + CS_DATAFMT *datafmt, + CS_VOID *buf, + CS_INT *datalen, + CS_SMALLINT *indicator + )); + +extern CS_RETCODE CS_PUBLIC blk_colval PROTOTYPE(( + CS_VOID *srvproc, + CS_BLKDESC *blkdesc, + CS_BLK_ROW *row, + CS_INT colnum, + CS_VOID *value, + CS_INT valuelen, + CS_INT *outlen + )); + +extern CS_RETCODE CS_PUBLIC blk_default PROTOTYPE(( + CS_BLKDESC *blkdesc, + CS_INT colnum, + CS_VOID *value, + CS_INT valuelen, + CS_INT *outlen + )); + +extern CS_RETCODE CS_PUBLIC blk_describe PROTOTYPE(( + CS_BLKDESC *blkdesc, + CS_INT colnum, + CS_DATAFMT *datafmt + )); + +extern CS_RETCODE CS_PUBLIC blk_done PROTOTYPE(( + CS_BLKDESC *blkdesc, + CS_INT option, + CS_INT *outrows + )); + +extern CS_RETCODE CS_PUBLIC blk_drop PROTOTYPE(( + CS_BLKDESC *blkdesc + )); + +extern CS_RETCODE CS_PUBLIC blk_getrow PROTOTYPE(( + CS_VOID *srvproc, + CS_BLKDESC *blkdesc, + CS_BLK_ROW *row + )); + +extern CS_RETCODE CS_PUBLIC blk_gettext PROTOTYPE(( + CS_VOID *srvproc, + CS_BLKDESC *blkdesc, + CS_BLK_ROW *row, + CS_BYTE *buf, + CS_INT buflen, + CS_INT *bytes_read + )); + +extern CS_RETCODE CS_PUBLIC blk_init PROTOTYPE(( + CS_BLKDESC *blkdesc, + CS_INT direction, + CS_CHAR *tblname, + CS_INT tblnamelen + )); + +extern CS_RETCODE CS_PUBLIC blk_rowalloc PROTOTYPE(( + CS_VOID *srvproc, + CS_BLK_ROW **row + )); + +extern CS_RETCODE CS_PUBLIC blk_rowdrop PROTOTYPE(( + CS_VOID *srvproc, + CS_BLK_ROW *row + )); + +extern CS_RETCODE CS_PUBLIC blk_rowxfer PROTOTYPE(( + CS_BLKDESC *blkdesc + )); + +extern CS_RETCODE CS_PUBLIC blk_rowxfer_mult PROTOTYPE(( + CS_BLKDESC *blkdesc, + CS_INT *rowcount + )); + +extern CS_RETCODE CS_PUBLIC blk_sendrow PROTOTYPE(( + CS_BLKDESC *blkdesc, + CS_BLK_ROW *row + )); + +extern CS_RETCODE CS_PUBLIC blk_sendtext PROTOTYPE(( + CS_BLKDESC *blkdesc, + CS_BLK_ROW *row, + CS_BYTE *buf, + CS_INT buflen + )); + +extern CS_RETCODE CS_PUBLIC blk_srvinit PROTOTYPE(( + CS_VOID *srvproc, + CS_BLKDESC *blkdesc + )); + +extern CS_RETCODE CS_PUBLIC blk_textxfer PROTOTYPE(( + CS_BLKDESC *blkdesc, + CS_BYTE *buf, + CS_INT buflen, + CS_INT *outlen + )); + +extern CS_RETCODE CS_PUBLIC blk_props PROTOTYPE(( + CS_BLKDESC *blkdesc, + CS_INT action, + CS_INT property, + CS_VOID *buffer, + CS_INT buflen, + CS_INT *outlen + )); + +extern CS_RETCODE CS_PUBLIC blk_bcp_indicator PROTOTYPE(( + CS_BLKDESC *blkdesc, + CS_BOOL action + )); + +CS_END_EXTERN_C + +#endif /* end of __BKPUBLIC_H__ */ diff --git a/libodbc/include/sybase/csconfig.h b/libodbc/include/sybase/csconfig.h new file mode 100644 index 0000000000..480fbdfa1d --- /dev/null +++ b/libodbc/include/sybase/csconfig.h @@ -0,0 +1,167 @@ +/* +** Sybase Open Client/Server +** Confidential Property of Sybase, Inc. +** Copyright Sybase, Inc. 1992 - 2005 +** All rights reserved +*/ + +#ifndef __CSCONFIG_H__ +#define __CSCONFIG_H__ + +/* +** This file will try to hide any interface differences found on various +** platform/compiler combinations. Any datatype or define that is +** dependant on a particular platform/compiler should have its definition +** here. +*/ + +/***************************************************************************** +** +** Function interface definitions. +** +*****************************************************************************/ + +/* +** Define the scoping rules that will be used in all libraries. These defines +** exist to support different compiler-specific keywords describing the +** calling convention of a C function. +** +** CS_PUBLIC Interface define for functions which are called +** outside of a library or DLL. +** +** CS_INTERNAL Interface define for functions which are only called +** within a library or DLL. +** +** CS_VARARGS Interface define for functions with variable argument +** lists which are called outside of a library or DLL. +** +** CS_STATIC Interface define for functions which are only called +** within a C module. +*/ + +/* +** We need to check to value of some compiler #defined macros +** but some compilers will give warnings for trying to use the +** value of a macro which has not been defined -- to avoid these +** warnings we define 'SYB' versions of the macros we need here +*/ +#if defined(_MSC_VER) +#define SYB_MSC_VER _MSC_VER +#else /* _MSC_VER */ +#define SYB_MSC_VER 0 +#endif /* _MSC_VER */ +#if defined(__STDC__) +#define SYB__STDC__ 1 +#else /* __STDC__ */ +#define SYB__STDC__ 0 +#endif /* __STDC__ */ + +#if defined(_CPROTO_) + +/* +** The _CPROTO_ ifdef allows users to have the cproto tool generate +** prototype definitions that include the scoping rules. We typedef all of +** the interface defines to allow the cproto tool to preserve the names +** (instead of replacing them with the defined values). +*/ +typedef void CS_PUBLIC; +typedef void CS_INTERNAL; +typedef void CS_VARARGS; +typedef void CS_STATIC; + +#else /* defined(_CPROTO_) */ + +#if ((SYB_MSC_VER >= 800) || defined(__BORLANDC__)) + +/* +** Defines for Windows NT calling conventions. +*/ +#define CS_PUBLIC __stdcall +#define CS_INTERNAL CS_PUBLIC +#define CS_VARARGS __stdcall +#define CS_STATIC static + +#else /* ((SYB_MSC_VER >= 800) || defined(__BORLANDC__)) */ + +/* +** Default defines for all other platform/compilers. +*/ +#define CS_PUBLIC +#define CS_INTERNAL +#define CS_VARARGS +#define CS_STATIC static + +#endif /* ((SYB_MSC_VER >= 800) || defined(__BORLANDC__)) */ + +#endif /* defined(_CPROTO_) */ + +/* +** Define wrappers to insure that all function prototypes defined in the +** Open Client and Open Server header files have the correct C function +** linkage when used with C++ compilers. +*/ +#if defined(__cplusplus) +#define CS_START_EXTERN_C extern "C" { +#define CS_END_EXTERN_C } +#else +#define CS_START_EXTERN_C +#define CS_END_EXTERN_C +#endif /* defined(__cplusplus) */ + +/* +** PROTOTYPE macro which produces the prototype +*/ +#ifndef PROTOTYPE +# define PROTOTYPE(s) s +#endif /* PROTOTYPE */ + +/* +** Define whether the compiler supports the "const" keyword. +*/ +#if (SYB__STDC__) || defined(__cplusplus) +# define CS_CONST const +#else +# define CS_CONST +#endif + +/* +** Define CS_ELLIPSE. It is used in function pointer prototypes where +** the arguments aren't known. Win3 uses ,... for CS_ELLIPSE, too. +*/ +#define CS_ELLIPSE , ... + +/***************************************************************************** +** +** Datatype definitions. +** +*****************************************************************************/ + +/* +** Certain Sybase C datatypes must be defined as 4 bytes in size. The +** following insures that all platforms (including 64 bit machines) use +** the correct C native types. +*/ +#if defined( __alpha) || defined(SYB_LP64) || defined(SYB_LLP64) || defined(_AIX) +typedef int CS_INT; +typedef int CS_RETCODE; +typedef int CS_BOOL; +typedef unsigned int CS_UINT; +#else +typedef long CS_INT; +typedef long CS_RETCODE; +typedef long CS_BOOL; +typedef unsigned long CS_UINT; +#endif + +typedef void CS_VOID; +typedef void CS_THRDRES; + +typedef double CS_FLOAT; /* 8 byte float type */ + +/* +** Define the number of bits that a CS_BYTE can hold. +*/ +#define CS_BITS_PER_BYTE 8 + +#endif /* __CSCONFIG_H__ */ + diff --git a/libodbc/include/sybase/cspublic.h b/libodbc/include/sybase/cspublic.h new file mode 100644 index 0000000000..63990d14f5 --- /dev/null +++ b/libodbc/include/sybase/cspublic.h @@ -0,0 +1,1895 @@ +/* +** Sybase Open Client/Server +** Confidential Property of Sybase, Inc. +** Copyright Sybase, Inc. 1992 - 2012 +** All rights reserved +*/ +#ifndef __CSPUBLIC_H__ +#define __CSPUBLIC_H__ + +#include + +/* +** Include the core header files. These files contain the defines and +** data structures that are shared by all libraries. +*/ +#ifndef __NO_INCLUDE__ +#include +#include +#endif /* __NO_INCLUDE__ */ + +/***************************************************************************** +** +** Size defines used in client/server applications. +** +*****************************************************************************/ + +/* +** Defines for the safe string funtions. +*/ +#define CS_STRLCPY cs_strlcpy +#define CS_STRLCAT cs_strlcat +#define CS_SNPRINTF cs_snprintf + +/* +** Define the maximum size of a fully qualified table name. +*/ +#define CS_OBJ_NAME (CS_INT)((CS_MAX_NAME * 3) + 4) + +/* +** The maximum number of bytes in the server message or error message +** stored in the CS_SERVERMSG and CS_CLIENTMSG structures. If the total +** message is longer than this, multiple structures will be passed to the +** application program. +*/ +#define CS_MAX_MSG (CS_INT)1024 + +/* +** The maximum number of bytes in a Sybase timestamp. +*/ +#define CS_TS_SIZE (CS_INT)8 + +/* +** The maximum number of bytes in Sybase text pointers. +*/ +#define CS_TP_SIZE (CS_INT)16 + +/* +** The size of the sqlstate array in the CS_SERVERMSG and CS_CLIENTMSG +** structures. Please note that this size is 2 bytes greater than what the +** standard specifies. Users should look at only the first 6 bytes in +** the array. That last 2 bytes are reserved to insure modulo 4 byte +** structure alignment. +*/ +#define CS_SQLSTATE_SIZE (CS_INT)8 + +/***************************************************************************** +** +** Defines passed into Open Client/Server APIs. +** +*****************************************************************************/ + +/* +** Define all the library versions currently supported. +** If compile flag 'CS_NO_LARGE_IDENTIFIERS' is set, we need to use +** the old values for CS_VERSION_xxx for compatibility reasons. +** The compile flag 'CS_NO_LARGE_IDENTIFIERS' isn't supported anymore +** as of CS_VERSION_155. +** We want the compiler to return errors when the CS_NO_LARGE_IDENTIFIERS +** flag is used with versions >= CS_VERSION_155 +*/ +#ifdef CS_NO_LARGE_IDENTIFIERS +#define CS_VERSION_100 (CS_INT)112 +#define CS_VERSION_110 (CS_INT)1100 +#define CS_VERSION_120 CS_VERSION_110 +#define CS_VERSION_125 (CS_INT)12500 +#define CS_VERSION_150 (CS_INT)15000 +#else +#define CS_VERSION_100 (CS_INT)113 +#define CS_VERSION_110 (CS_INT)1101 +#define CS_VERSION_120 CS_VERSION_110 +#define CS_VERSION_125 (CS_INT)12501 +#define CS_VERSION_150 (CS_INT)15001 +#define CS_VERSION_155 (CS_INT)15501 +#define CS_VERSION_157 (CS_INT)15701 +#endif /* CS_NO_LARGE_IDENTIFIERS */ + +#define CS_CURRENT_VERSION CS_VERSION_157 + +/* +** Action flags used. +** CS_CACHE currently only used by OMI apis +*/ +#define CS_GET (CS_INT)33 +#define CS_SET (CS_INT)34 +#define CS_CLEAR (CS_INT)35 +#define CS_INIT (CS_INT)36 +#define CS_STATUS (CS_INT)37 +#define CS_MSGLIMIT (CS_INT)38 +#define CS_SEND (CS_INT)39 +#define CS_SUPPORTED (CS_INT)40 +#define CS_CACHE (CS_INT)41 + +/* +** Bind indicator values. These are preferred when passing data into +** Client Library or Server Library, since they add the appropriate cast. +*/ +#define CS_GOODDATA (CS_SMALLINT)0 +#define CS_NULLDATA (CS_SMALLINT)(-1) + +/* +** Define ct_debug() operations. +*/ +#define CS_SET_FLAG (CS_INT)1700 +#define CS_CLEAR_FLAG (CS_INT)1701 +#define CS_SET_DBG_FILE (CS_INT)1702 +#define CS_SET_PROTOCOL_FILE (CS_INT)1703 + +/* +** Define ct_debug() types of trace information. +*/ +#define CS_DBG_ALL (CS_INT)0x1 +#define CS_DBG_ASYNC (CS_INT)0x2 +#define CS_DBG_ERROR (CS_INT)0x4 +#define CS_DBG_MEM (CS_INT)0x8 +#define CS_DBG_PROTOCOL (CS_INT)0x10 +#define CS_DBG_PROTOCOL_STATES (CS_INT)0x20 +#define CS_DBG_API_STATES (CS_INT)0x40 +#define CS_DBG_DIAG (CS_INT)0x80 +#define CS_DBG_NETWORK (CS_INT)0x100 +#define CS_DBG_API_LOGCALL (CS_INT)0x200 +#define CS_DBG_CTL_INFO (CS_INT)0x400 +#define CS_DBG_SSL (CS_INT)0x800 + +/* +** Cancel types. +*/ +#define CS_CANCEL_CURRENT (CS_INT)6000 +#define CS_CANCEL_ALL (CS_INT)6001 +#define CS_CANCEL_ATTN (CS_INT)6002 +#define CS_CANCEL_ABORT_NOTIF (CS_INT)6003 + +/* +** Cursor fetch options. +*/ +#define CS_FIRST (CS_INT)3000 +#define CS_NEXT (CS_INT)3001 +#define CS_PREV (CS_INT)3002 +#define CS_LAST (CS_INT)3003 +#define CS_ABSOLUTE (CS_INT)3004 +#define CS_RELATIVE (CS_INT)3005 + +/* +** Op codes used in cs_calc(). +*/ +#define CS_ADD (CS_INT)1 +#define CS_SUB (CS_INT)2 +#define CS_MULT (CS_INT)3 +#define CS_DIV (CS_INT)4 +#define CS_ZERO (CS_INT)5 + +/* +** The cs_dt_info() types. +*/ +#define CS_MONTH (CS_INT)7340 +#define CS_SHORTMONTH (CS_INT)7341 +#define CS_DAYNAME (CS_INT)7342 +#define CS_DATEORDER (CS_INT)7343 +#define CS_12HOUR (CS_INT)7344 +#define CS_DT_CONVFMT (CS_INT)7345 + +/* +** The cs_strcmp() options. +*/ +#define CS_COMPARE (CS_INT)7440 +#define CS_SORT (CS_INT)7441 + +/* +** Callback types. +*/ +#define CS_COMPLETION_CB (CS_INT)1 +#define CS_SERVERMSG_CB (CS_INT)2 +#define CS_CLIENTMSG_CB (CS_INT)3 +#define CS_NOTIF_CB (CS_INT)4 +#define CS_ENCRYPT_CB (CS_INT)5 +#define CS_CHALLENGE_CB (CS_INT)6 +#define CS_DS_LOOKUP_CB (CS_INT)7 +#define CS_SECSESSION_CB (CS_INT)8 +#define CS_SSLVALIDATE_CB (CS_INT)9 +#define CS_DONEPROC_CB (CS_INT)10 +#define CS_EXTENDED_ENCRYPT_CB (CS_INT)11 + +/* +** To install a signal callback, the type needs to calculated as an +** offset of the operating-system-specific signal number and the +** following define. For example, to install a callback handler for a +** SIGALRM signal, pass (CS_SIGNAL_CB + SIGALRM) to the ct_callback() +** routine. +*/ +#define CS_SIGNAL_CB (CS_INT)100 + +/* +** Exit and close flags. +*/ +#define CS_FORCE_EXIT (CS_INT)300 +#define CS_FORCE_CLOSE (CS_INT)301 + +/* +** ct_diag() and cs_diag() type flags. +*/ +#define CS_CLIENTMSG_TYPE (CS_INT)4700 +#define CS_SERVERMSG_TYPE (CS_INT)4701 +#define CS_ALLMSG_TYPE (CS_INT)4702 +#define SQLCA_TYPE (CS_INT)4703 +#define SQLCODE_TYPE (CS_INT)4704 +#define SQLSTATE_TYPE (CS_INT)4705 + +/* +** Compute info types. +*/ +#define CS_COMP_OP (CS_INT)5350 +#define CS_COMP_ID (CS_INT)5351 +#define CS_COMP_COLID (CS_INT)5352 +#define CS_COMP_BYLIST (CS_INT)5353 +#define CS_BYLIST_LEN (CS_INT)5354 + +/* +** Compute info operators. +*/ +#define CS_OP_SUM (CS_INT)5370 +#define CS_OP_AVG (CS_INT)5371 +#define CS_OP_COUNT (CS_INT)5372 +#define CS_OP_MIN (CS_INT)5373 +#define CS_OP_MAX (CS_INT)5374 + +/* +** Browse types. +*/ +#define CS_ISBROWSE (CS_INT)9000 +#define CS_TABNUM (CS_INT)9001 +#define CS_TABNAME (CS_INT)9002 + +/* +** Result types from ct_results(). +*/ +#define CS_ROW_RESULT (CS_INT)4040 +#define CS_CURSOR_RESULT (CS_INT)4041 +#define CS_PARAM_RESULT (CS_INT)4042 +#define CS_STATUS_RESULT (CS_INT)4043 +#define CS_MSG_RESULT (CS_INT)4044 +#define CS_COMPUTE_RESULT (CS_INT)4045 +#define CS_CMD_DONE (CS_INT)4046 +#define CS_CMD_SUCCEED (CS_INT)4047 +#define CS_CMD_FAIL (CS_INT)4048 +#define CS_ROWFMT_RESULT (CS_INT)4049 +#define CS_COMPUTEFMT_RESULT (CS_INT)4050 +#define CS_DESCRIBE_RESULT (CS_INT)4051 + +/* +** Flags for getting result info using ct_res_info(). +*/ +#define CS_ROW_COUNT (CS_INT)800 +#define CS_CMD_NUMBER (CS_INT)801 +#define CS_NUM_COMPUTES (CS_INT)802 +#define CS_NUMDATA (CS_INT)803 +#define CS_ORDERBY_COLS (CS_INT)804 +#define CS_NUMORDERCOLS (CS_INT)805 +#define CS_MSGTYPE (CS_INT)806 +#define CS_BROWSE_INFO (CS_INT)807 +#define CS_TRANS_STATE (CS_INT)808 +#define CS_TOKEN_TYPE (CS_INT)809 + +/* +** Possible values for CS_TRANS_STATE. +*/ +#define CS_TRAN_UNDEFINED (CS_INT)0 +#define CS_TRAN_IN_PROGRESS (CS_INT)1 +#define CS_TRAN_COMPLETED (CS_INT)2 +#define CS_TRAN_FAIL (CS_INT)3 +#define CS_TRAN_STMT_FAIL (CS_INT)4 + +/* +** Define the invalid count that the application gets when +** ct_res_info() is called at the wrong time. +*/ +#define CS_NO_COUNT (CS_INT)-1 + +/***************************************************************************** +** +** Commands in Open Client/Server APIs. +** +*****************************************************************************/ + +/* +** ct_command() command types. +*/ +#define CS_LANG_CMD (CS_INT)148 +#define CS_RPC_CMD (CS_INT)149 +#define CS_MSG_CMD (CS_INT)150 +#define CS_SEND_DATA_CMD (CS_INT)151 +#define CS_PACKAGE_CMD (CS_INT)152 +#define CS_SEND_BULK_CMD (CS_INT)153 +#define CS_SEND_DATA_NOCMD (CS_INT)154 + +/* +** ct_cursor() command types. +*/ +#define CS_CURSOR_DECLARE (CS_INT)700 +#define CS_CURSOR_OPEN (CS_INT)701 +#define CS_CURSOR_ROWS (CS_INT)703 +#define CS_CURSOR_UPDATE (CS_INT)704 +#define CS_CURSOR_DELETE (CS_INT)705 +#define CS_CURSOR_CLOSE (CS_INT)706 +#define CS_CURSOR_DEALLOC (CS_INT)707 +#define CS_CURSOR_OPTION (CS_INT)725 + +/* +** Open Server-specific cursor command types. +*/ +#define CS_CURSOR_FETCH (CS_INT)708 +#define CS_CURSOR_INFO (CS_INT)709 + +/* +** ct_dyndesc() command types. +*/ +#define CS_ALLOC (CS_INT)710 +#define CS_DEALLOC (CS_INT)711 +#define CS_USE_DESC (CS_INT)712 +#define CS_GETCNT (CS_INT)713 +#define CS_SETCNT (CS_INT)714 +#define CS_GETATTR (CS_INT)715 +#define CS_SETATTR (CS_INT)716 + +/* +** ct_dynamic() command types. +*/ +#define CS_PREPARE (CS_INT)717 +#define CS_EXECUTE (CS_INT)718 +#define CS_EXEC_IMMEDIATE (CS_INT)719 +#define CS_DESCRIBE_INPUT (CS_INT)720 +#define CS_DESCRIBE_INPUTIN (CS_INT)320 /* CS_DESCRIBE_INPUT & CS_INPUT */ +#define CS_DESCRIBE_OUTPUT (CS_INT)721 +#define CS_DYN_CURSOR_DECLARE (CS_INT)722 + + +/* +** ct_dynsqlda() arguments and actions +*/ +#define CS_SQLDA_SYBASE (CS_INT)729 +#define CS_GET_IN (CS_INT)730 +#define CS_GET_OUT (CS_INT)731 +#define CS_SQLDA_BIND (CS_INT)732 +#define CS_SQLDA_PARAM (CS_INT)733 + +/* +** Open Server-specific dynamic command types. +*/ +#define CS_PROCNAME (CS_INT)723 +#define CS_ACK (CS_INT)724 + + +/* +** ct_ds_objinfo() objinfo types. +*/ +#define CS_OBJ_CLASSOID (CS_INT)725 +#define CS_OBJ_DNAME (CS_INT)726 +#define CS_OBJ_NUMATTR (CS_INT)727 +#define CS_OBJ_ATRRIBUTE (CS_INT)728 + +/* +** Command options +*/ +#define CS_RECOMPILE (CS_INT)188 +#define CS_NO_RECOMPILE (CS_INT)189 +#define CS_BULK_INIT (CS_INT)190 +#define CS_BULK_CONT (CS_INT)191 +#define CS_BULK_DATA (CS_INT)192 +#define CS_COLUMN_DATA (CS_INT)193 + +/* +** Cursor options. +*/ +#define CS_FOR_UPDATE (CS_INT)0x0001 +#define CS_READ_ONLY (CS_INT)0x0002 +#define CS_DYNAMIC (CS_INT)0x0004 /* Open Server only */ +#define CS_RESTORE_OPEN (CS_INT)0x0008 /* CT-Lib only */ +#define CS_MORE (CS_INT)0x0010 +#define CS_END (CS_INT)0x0020 +#define CS_IMPLICIT_CURSOR (CS_INT)0x0040 /* Implicit, CT-Lib */ +#define CS_SCROLL_SENSITIVE (CS_INT)0x0080 /* Scrollable cursor, reserved */ +#define CS_SCROLL_INSENSITIVE (CS_INT)0x0100 /* Scrollable cursor, as default */ +#define CS_SCROLL_SEMISENSITIVE (CS_INT)0x0200 /* Scrollable cursor */ +#define CS_SCROLL_KEYSETDRIVEN (CS_INT)0x0400 /* Scrollable cursor, reserved */ +#define CS_SCROLL_CURSOR (CS_INT)0x0800 /* "Default", internal */ +#define CS_NOSCROLL_INSENSITIVE (CS_INT)0x1000 /* Non-scroll insensitive */ +#define CS_CUR_RELLOCKS_ONCLOSE (CS_INT)0x2000 /* Release locks on curclose */ + +/* +** Sybase-defined message ids for CS_MSG_CMDs. +*/ +#define CS_MSG_GETLABELS (CS_INT)6 +#define CS_MSG_LABELS (CS_INT)7 +#define CS_MSG_TABLENAME (CS_INT)8 +#define CS_PARSE_TREE (CS_INT)8710 + +/* +** Minimum and maximum user-defined message id for CS_MSG_CMDs. +*/ +#define CS_USER_MSGID (CS_INT)32768 +#define CS_USER_MAX_MSGID (CS_INT)65535 + +/* +** Defines for sp_regwatch registered procedure +*/ +#define CS_NOTIFY_ONCE 0x0002 /* one-time notification request. */ +#define CS_NOTIFY_ALWAYS 0x0004 /* permanent notification request. */ +#define CS_NOTIFY_WAIT 0x0020 /* blocking notification request. */ +#define CS_NOTIFY_NOWAIT 0x0040 /* non-blocking notification request. */ + + +/***************************************************************************** +** +** Open Client properties. +** +*****************************************************************************/ + +/* +** Properties that are used in *_props() functions. +*/ +#define CS_USERNAME (CS_INT)9100 +#define CS_PASSWORD (CS_INT)9101 +#define CS_APPNAME (CS_INT)9102 +#define CS_HOSTNAME (CS_INT)9103 +#define CS_LOGIN_STATUS (CS_INT)9104 +#define CS_TDS_VERSION (CS_INT)9105 +#define CS_CHARSETCNV (CS_INT)9106 +#define CS_PACKETSIZE (CS_INT)9107 +#define CS_USERDATA (CS_INT)9108 +#define CS_COMMBLOCK (CS_INT)9109 +#define CS_NETIO (CS_INT)9110 +#define CS_NOINTERRUPT (CS_INT)9111 +#define CS_TEXTLIMIT (CS_INT)9112 +#define CS_HIDDEN_KEYS (CS_INT)9113 +#define CS_VERSION (CS_INT)9114 +#define CS_IFILE (CS_INT)9115 +#define CS_LOGIN_TIMEOUT (CS_INT)9116 +#define CS_TIMEOUT (CS_INT)9117 +#define CS_MAX_CONNECT (CS_INT)9118 +#define CS_MESSAGE_CB (CS_INT)9119 +#define CS_EXPOSE_FMTS (CS_INT)9120 +#define CS_EXTRA_INF (CS_INT)9121 +#define CS_TRANSACTION_NAME (CS_INT)9122 +#define CS_ANSI_BINDS (CS_INT)9123 +#define CS_BULK_LOGIN (CS_INT)9124 +#define CS_LOC_PROP (CS_INT)9125 +#define CS_CUR_STATUS (CS_INT)9126 +#define CS_CUR_ID (CS_INT)9127 +#define CS_CUR_NAME (CS_INT)9128 +#define CS_CUR_ROWCOUNT (CS_INT)9129 +#define CS_PARENT_HANDLE (CS_INT)9130 +#define CS_EED_CMD (CS_INT)9131 +#define CS_DIAG_TIMEOUT (CS_INT)9132 +#define CS_DISABLE_POLL (CS_INT)9133 +#define CS_NOTIF_CMD (CS_INT)9134 +#define CS_SEC_ENCRYPTION (CS_INT)9135 +#define CS_SEC_CHALLENGE (CS_INT)9136 +#define CS_SEC_NEGOTIATE (CS_INT)9137 +#define CS_MEM_POOL (CS_INT)9138 +#define CS_USER_ALLOC (CS_INT)9139 +#define CS_USER_FREE (CS_INT)9140 +#define CS_ENDPOINT (CS_INT)9141 +#define CS_NO_TRUNCATE (CS_INT)9142 +#define CS_CON_STATUS (CS_INT)9143 +#define CS_VER_STRING (CS_INT)9144 +#define CS_ASYNC_NOTIFS (CS_INT)9145 +#define CS_SERVERNAME (CS_INT)9146 +/* For CS_SERVERADDR (9206) see below */ +#define CS_THREAD_RESOURCE (CS_INT)9147 +#define CS_NOAPI_CHK (CS_INT)9148 +#define CS_SEC_APPDEFINED (CS_INT)9149 +#define CS_NOCHARSETCNV_REQD (CS_INT)9150 +#define CS_STICKY_BINDS (CS_INT)9151 +#define CS_HAVE_CMD (CS_INT)9152 +#define CS_HAVE_BINDS (CS_INT)9153 +#define CS_HAVE_CUROPEN (CS_INT)9154 +#define CS_EXTERNAL_CONFIG (CS_INT)9155 +#define CS_CONFIG_FILE (CS_INT)9156 +#define CS_CONFIG_BY_SERVERNAME (CS_INT)9157 + +/* +** Directory Service connection properties +*/ +#define CS_DS_CHAIN (CS_INT)9158 +#define CS_DS_EXPANDALIAS (CS_INT)9159 +#define CS_DS_COPY (CS_INT)9160 +#define CS_DS_LOCALSCOPE (CS_INT)9161 +#define CS_DS_PREFERCHAIN (CS_INT)9162 +#define CS_DS_SCOPE (CS_INT)9163 +#define CS_DS_SIZELIMIT (CS_INT)9164 +#define CS_DS_TIMELIMIT (CS_INT)9165 +#define CS_DS_PRINCIPAL (CS_INT)9166 +/* For CS_DS_PASSWORD (9198) see below */ +#define CS_DS_REFERRAL (CS_INT)9167 +#define CS_DS_SEARCH (CS_INT)9168 +#define CS_DS_DITBASE (CS_INT)9169 +#define CS_DS_FAILOVER (CS_INT)9170 +#define CS_NET_TRANADDR (CS_INT)9171 +#define CS_DS_PROVIDER (CS_INT)9172 +#define CS_RETRY_COUNT (CS_INT)9173 +#define CS_LOOP_DELAY (CS_INT)9174 + +/* +** Properties for Security services support +*/ +#define CS_SEC_NETWORKAUTH (CS_INT)9175 +#define CS_SEC_DELEGATION (CS_INT)9176 +#define CS_SEC_MUTUALAUTH (CS_INT)9177 +#define CS_SEC_INTEGRITY (CS_INT)9178 +#define CS_SEC_CONFIDENTIALITY (CS_INT)9179 +#define CS_SEC_CREDTIMEOUT (CS_INT)9180 +#define CS_SEC_SESSTIMEOUT (CS_INT)9181 +#define CS_SEC_DETECTREPLAY (CS_INT)9182 +#define CS_SEC_DETECTSEQ (CS_INT)9183 +#define CS_SEC_DATAORIGIN (CS_INT)9184 +#define CS_SEC_MECHANISM (CS_INT)9185 +#define CS_SEC_CREDENTIALS (CS_INT)9186 +#define CS_SEC_CHANBIND (CS_INT)9187 +#define CS_SEC_SERVERPRINCIPAL (CS_INT)9188 +#define CS_SEC_KEYTAB (CS_INT)9189 + +/* +** More properties +*/ +#define CS_ABORTCHK_INTERVAL (CS_INT)9190 +#define CS_LOGIN_TYPE (CS_INT)9191 +#define CS_CON_KEEPALIVE (CS_INT)9192 +#define CS_CON_TCP_NODELAY (CS_INT)9193 +#define CS_LOGIN_REMOTE_SERVER (CS_INT)9194 +#define CS_LOGIN_REMOTE_PASSWD (CS_INT)9195 + +/* +** Property for reverting to behavior of earlier versions +*/ +#define CS_BEHAVIOR (CS_INT)9197 + +/* +** Property for HA failover +*/ +#define CS_HAFAILOVER (CS_INT)9196 + +/* +** Property for Directory services. (belongs with CS_DS_* above) +** Added at LDAP implementation time. +*/ +#define CS_DS_PASSWORD (CS_INT)9198 + +/* +** Property for blklib user data. +*/ +#define CS_BLKDATA (CS_INT)9199 + +/* +** Properties for SSL +*/ +#define CS_PROP_SSL_PROTOVERSION (CS_INT)9200 +#define CS_PROP_SSL_CIPHER (CS_INT)9201 +#define CS_PROP_SSL_LOCALID (CS_INT)9202 +#define CS_PROP_SSL_CA (CS_INT)9203 +#define CS_PROP_TLS_KEYREGEN (CS_INT)9205 + +/* +** Property for connecting to ASE using host and port. +*/ +#define CS_SERVERADDR (CS_INT)9206 + +/* +** Properties related to use of login redirection and +** Cluster HA extensions. +*/ +#define CS_PROP_REDIRECT (CS_INT)9207 +#define CS_PROP_EXTENDEDFAILOVER (CS_INT)9208 +#define CS_DS_RAND_OFFSET (CS_INT)9209 + +/* +** Property used to retrieve the ASE database SPID +** that is returned at login time. Note that this value +** may change should migration occur! +*/ +#define CS_PROP_APPLICATION_SPID (CS_INT)9210 + +/* +** For ct_cmd_props(), scrollable cursor. +** CS_CUR_ROWPOSITION is reserved for future use. +*/ +#define CS_CUR_TOTALROWS (CS_INT)9211 +#define CS_CUR_ROWPOSITION (CS_INT)9212 + +/* +** For extended password encryption +*/ +#define CS_SEC_EXTENDED_ENCRYPTION (CS_INT)9213 +#define CS_SEC_NON_ENCRYPTION_RETRY (CS_INT)9214 + +/* +** For connection migration +*/ +#define CS_PROP_MIGRATABLE (CS_INT)9215 + +/* +** For setting sybase home and an alternate libtcl config file location. +*/ +#define CS_SYBASE_HOME (CS_INT)9216 +#define CS_LIBTCL_CFG (CS_INT)9217 + +/* +** For setting default interfaces file +*/ +#define CS_DEFAULT_IFILE (CS_INT)9218 + +/* +** To retrieve the CS_TRANADDR ct_connect successfully used to +** establish communication with the server. +*/ +#define CS_CONNECTED_ADDR (CS_INT)9219 + +/* +** The connection allows partial text/image updates. +*/ +#define CS_PARTIAL_TEXT (CS_INT)9220 + +/* +** The connection omits 'writetext' with ct_send_data(). +*/ +#define CS_SENDDATA_NOCMD (CS_INT)9221 + +/* +** When the application name was set to the executable name, this name +** will be used to parse ocs.cfg for its application specific section. +*/ +#define CS_USE_DISCOVERED_APPNAME (CS_INT)9222 + +/* +** When the application name was set to the executable name, this setting +** will indicate how to 'sanitize' that name: all upper case, all lower case +** or no sanitization. +*/ +#define CS_SANITIZE_DISC_APPNAME (CS_INT)9223 + +/* +** Allow an application to set the TCP send and receive buffer sizes. +** These are negotiated at the TCP layer and must be set before calling +** ct_connect. +*/ +#define CS_TCP_RCVBUF (CS_INT)9224 +#define CS_TCP_SNDBUF (CS_INT)9225 +#define CS_TCP_LRGBUF 2146304 + +/* +** Allow row format information to be suppressed on subsequent execution +** of a prepared statement. +*/ +#define CS_CMD_SUPPRESS_FMT (CS_INT)9226 + +/* +** CS_DS_SCOPE Values +*/ +#define CS_SCOPE_COUNTRY (CS_INT)1 +#define CS_SCOPE_DMD (CS_INT)2 +#define CS_SCOPE_WORLD (CS_INT)3 + +/* +** CS_DS_SEARCH Values +*/ +#define CS_SEARCH_OBJECT (CS_INT)1 +#define CS_SEARCH_ONE_LEVEL (CS_INT)2 +#define CS_SEARCH_SUBTREE (CS_INT)3 + +/* +** Possible values for the CS_NETIO property. +*/ +#define CS_SYNC_IO (CS_INT)8111 +#define CS_ASYNC_IO (CS_INT)8112 +#define CS_DEFER_IO (CS_INT)8113 + +/* +** Possible bit values for the CS_LOGIN_STATUS property. +*/ +#define CS_CONSTAT_CONNECTED (CS_INT)0x1 +#define CS_CONSTAT_DEAD (CS_INT)0x2 + + +/* +** Possible bit values for the CS_CUR_STATUS property. +*/ +#define CS_CURSTAT_NONE (CS_INT)0x0000 +#define CS_CURSTAT_DECLARED (CS_INT)0x0001 +#define CS_CURSTAT_OPEN (CS_INT)0x0002 +#define CS_CURSTAT_CLOSED (CS_INT)0x0004 +#define CS_CURSTAT_RDONLY (CS_INT)0x0008 +#define CS_CURSTAT_UPDATABLE (CS_INT)0x0010 +#define CS_CURSTAT_ROWCOUNT (CS_INT)0x0020 +#define CS_CURSTAT_DEALLOC (CS_INT)0x0040 +#define CS_CURSTAT_SCROLLABLE (CS_INT)0x0080 +#define CS_CURSTAT_IMPLICIT (CS_INT)0x0100 +#define CS_CURSTAT_SENSITIVE (CS_INT)0x0200 +#define CS_CURSTAT_INSENSITIVE (CS_INT)0x0400 +#define CS_CURSTAT_SEMISENSITIVE (CS_INT)0x0800 +#define CS_CURSTAT_KEYSETDRIVEN (CS_INT)0x1000 +#define CS_CURSTAT_RELLOCKS_ONCLOSE (CS_INT)0x2000 + +/* +** Possible bit values for implicit cursor status +*/ +#define CS_IMPCURSTAT_NONE (CS_INT)0x0000 +#define CS_IMPCURSTAT_DECLARED (CS_INT)0x0001 +#define CS_IMPCURSTAT_READROWS (CS_INT)0x0002 +#define CS_IMPCURSTAT_CLOSED (CS_INT)0x0004 +#define CS_IMPCURSTAT_SENDSUCCESS (CS_INT)0x0008 +#define CS_IMPCURSTAT_FINALREAD (CS_INT)0x0010 +#define CS_IMPCURSTAT_NOSEND (CS_INT)0x0020 +#define CS_IMPCURSTAT_NOSENDDONE (CS_INT)0x0040 + +/* +** Possible values for the CS_TDS_VERSION property. +*/ +#define CS_TDS_40 (CS_INT)7360 +#define CS_TDS_42 (CS_INT)7361 +#define CS_TDS_46 (CS_INT)7362 +#define CS_TDS_495 (CS_INT)7363 +#define CS_TDS_50 (CS_INT)7364 + +/* +** Possible values for the CS_BEHAVIOR property. +*/ +#define CS_BEHAVIOR_080 (CS_INT)7369 +#define CS_BEHAVIOR_100 (CS_INT)7370 +#define CS_BEHAVIOR_110 (CS_INT)7371 +#define CS_BEHAVIOR_120 (CS_INT)7372 +#define CS_BEHAVIOR_125 (CS_INT)7373 + +/* +** Possible values for the CS_PROP_SSL_PROTOVERSION property. +** +** If 2.0 handshake is desired with SSL 3.0 or TLS 1.0, or +** CS_SSLVER_20HAND +*/ +#define CS_SSLVER_20 (CS_INT)1 +#define CS_SSLVER_30 (CS_INT)2 +#define CS_SSLVER_TLS1 (CS_INT)3 +#define CS_SSLVER_20HAND (CS_INT)0x80000000 + +/* +** Valid values for the CS_SANITIZE_DISC_APPNAME property. +*/ +typedef enum cs_sanitize_conversion +{ + CS_CNVRT_NOTHING, + CS_CNVRT_LOWERCASE, + CS_CNVRT_UPPERCASE +} CS_SANITIZE_CONVERSION; + +/* +** Structure used with the CS_PROP_SSL_LOCALID property. +*/ +typedef struct _cs_sslid +{ + CS_CHAR *identity_file; + CS_CHAR *identity_password; +} CS_SSLIDENTITY; + +/* +** Structure used to deal with certificates in the validate callback. +*/ +typedef struct _cs_sslcertfield +{ + CS_VOID *value; + CS_INT field_id; + CS_INT length; +} CS_SSLCERT_FIELD; +typedef struct _cs_sslcert +{ + CS_INT field_count; + CS_INT extension_count; + CS_UINT start_date; + CS_UINT end_date; + CS_SSLCERT_FIELD *fieldptr; + CS_SSLCERT_FIELD *extensionptr; +} CS_SSLCERT; + +typedef CS_INT (CS_PUBLIC * CS_CERT_CB) ( + CS_VOID *user_data, + CS_SSLCERT *certptr, + CS_INT cert_count, + CS_INT valid + ); + +/* +** Defines for valid certificate fields. +*/ +#define CS_SSLFLD_noMatch 0 +#define CS_SSLFLD_md2 1 +#define CS_SSLFLD_md4 2 +#define CS_SSLFLD_md5 3 +#define CS_SSLFLD_sha1 4 +#define CS_SSLFLD_rsaEncryption 5 +#define CS_SSLFLD_md2WithRSA 6 +#define CS_SSLFLD_md4WithRSA 7 +#define CS_SSLFLD_md5WithRSA 8 +#define CS_SSLFLD_sha1WithRSA 9 +#define CS_SSLFLD_dhKeyAgreement 10 +#define CS_SSLFLD_pbeWithMD2AndDES_CBC 11 +#define CS_SSLFLD_pbeWithMD5AndDES_CBC 12 +#define CS_SSLFLD_emailAddress 13 +#define CS_SSLFLD_unstructuredName 14 +#define CS_SSLFLD_contentType 15 +#define CS_SSLFLD_messageDigest 16 +#define CS_SSLFLD_signingTime 17 +#define CS_SSLFLD_counterSignature 18 +#define CS_SSLFLD_challengePassword 19 +#define CS_SSLFLD_unstructuredAddress 20 +#define CS_SSLFLD_extendedCertificateAttributes 21 +#define CS_SSLFLD_commonName 22 +#define CS_SSLFLD_surName 23 +#define CS_SSLFLD_serialNumber 24 +#define CS_SSLFLD_countryName 25 +#define CS_SSLFLD_localityName 26 +#define CS_SSLFLD_stateProvinceName 27 +#define CS_SSLFLD_streetAddress 28 +#define CS_SSLFLD_organizationName 29 +#define CS_SSLFLD_organizationalUnitName 30 +#define CS_SSLFLD_title 31 +#define CS_SSLFLD_description 32 +#define CS_SSLFLD_businessCategory 33 +#define CS_SSLFLD_postalAddress 34 +#define CS_SSLFLD_postalCode 35 +#define CS_SSLFLD_postOfficeBox 36 +#define CS_SSLFLD_physicalDeliveryOfficeName 37 +#define CS_SSLFLD_telephoneNumber 38 +#define CS_SSLFLD_telexNumber 39 +#define CS_SSLFLD_telexTerminalIdentifier 40 +#define CS_SSLFLD_facsimileTelephoneNumber 41 +#define CS_SSLFLD_x_121Address 42 +#define CS_SSLFLD_internationalISDNNumber 43 +#define CS_SSLFLD_registeredAddress 44 +#define CS_SSLFLD_destinationIndicator 45 +#define CS_SSLFLD_preferredDeliveryMethod 46 +#define CS_SSLFLD_presentationAddress 47 +#define CS_SSLFLD_supportedApplicationContext 48 +#define CS_SSLFLD_member 49 +#define CS_SSLFLD_owner 50 +#define CS_SSLFLD_roleOccupant 51 +#define CS_SSLFLD_mysteryPKCS7_PKCS5 52 +#define CS_SSLFLD_netscapeCertType 53 +#define CS_SSLFLD_netscapeBaseURL 54 +#define CS_SSLFLD_netscapeRevocationURL 55 +#define CS_SSLFLD_netscapeCARevocationURL 56 +#define CS_SSLFLD_netscapeCertRenewalURL 57 +#define CS_SSLFLD_netscapeCAPolicyURL 58 +#define CS_SSLFLD_netscapeSSLServerName 59 +#define CS_SSLFLD_netscapeComment 60 +#define CS_SSLFLD_subjectDirectoryAttributes 61 +#define CS_SSLFLD_subjectKeyIdentifier 62 +#define CS_SSLFLD_keyUsage 63 +#define CS_SSLFLD_privateKeyUsagePeriod 64 +#define CS_SSLFLD_subjectAltName 65 +#define CS_SSLFLD_issuerAltName 66 +#define CS_SSLFLD_basicConstraints 67 +#define CS_SSLFLD_crlNumber 68 +#define CS_SSLFLD_crlReason 69 +#define CS_SSLFLD_holdInstructionCode 70 +#define CS_SSLFLD_invalidityDate 71 +#define CS_SSLFLD_deltaCRLIndicator 72 +#define CS_SSLFLD_issuingDistributionPoint 73 +#define CS_SSLFLD_nameConstraints 74 +#define CS_SSLFLD_certificatePolicies 75 +#define CS_SSLFLD_policyMappings 76 +#define CS_SSLFLD_policyConstraints 77 +#define CS_SSLFLD_authorityKeyIdentifier 78 +#define CS_SSLFLD_extendedKeyUsage 79 +#define CS_SSLFLD_pkixSubjectInfoAccess 80 +#define CS_SSLFLD_pkixAuthorityInfoAccess 81 +#define CS_SSLFLD_pkixCPS 82 +#define CS_SSLFLD_pkixUserNotice 83 +#define CS_SSLFLD_pkixKPServerAuth 84 +#define CS_SSLFLD_pkixKPClientAuth 85 +#define CS_SSLFLD_pkixKPCodeSigning 86 +#define CS_SSLFLD_pkixKPEmailProtection 87 +#define CS_SSLFLD_pkixKPIPSECEndSystem 88 +#define CS_SSLFLD_pkixKPIPSECTunnel 89 +#define CS_SSLFLD_pkixKPIPSECUser 90 +#define CS_SSLFLD_pkixKPTimeStamping 91 +#define CS_SSLFLD_netscapeKPStepUp 92 +#define CS_SSLFLD_microsoftKPServerGatedCrypto 93 +#define CS_SSLFLD_sha1WithDSA 94 +#define CS_SSLFLD_dsa 95 +#define CS_SSLFLD_contentInfoData 96 +#define CS_SSLFLD_contentInfoSignedData 97 +#define CS_SSLFLD_contentInfoEnvelopedData 98 +#define CS_SSLFLD_contentInfoSignedAndEnvelopedData 99 +#define CS_SSLFLD_contentInfoDigestedData 100 +#define CS_SSLFLD_contentInfoEncryptedData 101 +#define CS_SSLFLD_keyBag 102 +#define CS_SSLFLD_pkcs8ShroudedKeyBag 103 +#define CS_SSLFLD_certBag 104 +#define CS_SSLFLD_crlBag 105 +#define CS_SSLFLD_secretBag 106 +#define CS_SSLFLD_safeContentBag 107 +#define CS_SSLFLD_pbeWithSHA1And128RC4 108 +#define CS_SSLFLD_pbeWithSHA1And40BitRC4 109 +#define CS_SSLFLD_pbeWithSHA1And3KeyTripleDESCBC 110 +#define CS_SSLFLD_pbeWithSHA1And2KeyTripleDESCBC 111 +#define CS_SSLFLD_pbeWithSHA1And128BitRC2CBC 112 +#define CS_SSLFLD_pbeWithSHA1And40BitRC2CBC 113 +#define CS_SSLFLD_desEDECBC3 114 +#define CS_SSLFLD_rc2CBC 115 +#define CS_SSLFLD_x509Certificate 116 +#define CS_SSLFLD_dhPublicNumber 117 +#define CS_SSLFLD_ecdhPublicNumber 118 +#define CS_SSLFLD_ecdhPrivateNumber 119 +#define CS_SSLFLD_ecPublicKey 120 +#define CS_SSLFLD_ecPrivateKey 121 +#define CS_SSLFLD_ecdsaWithSHA1 122 +#define CS_SSLFLD_ecdsaec163a01 123 +#define CS_SSLFLD_ecdsaec163a02 124 +#define CS_SSLFLD_ecdsaec155b01 125 +#define CS_SSLFLD_ecdsaec163b01 126 +#define CS_SSLFLD_ecdsaec210b01 127 +#define CS_SSLFLD_ecnraec163a01 128 +#define CS_SSLFLD_ecnraec163a02 129 +#define CS_SSLFLD_ecnraec155b01 130 +#define CS_SSLFLD_ecnraec163b01 131 +#define CS_SSLFLD_ecnraec210b01 132 +#define CS_SSLFLD_curve113a01 133 +#define CS_SSLFLD_curve163a01 134 +#define CS_SSLFLD_curve163a02 135 +#define CS_SSLFLD_curve163b01 136 + +/* +** Define values for SSL/TLS certificate validation checks +*/ +#define CS_SSL_VALID_CERT 0 +#define CS_SSL_INVALID_BADCHAIN 1 +#define CS_SSL_INVALID_EXPCERT 2 +#define CS_SSL_INVALID_INCOMPLETE 3 +#define CS_SSL_INVALID_UNKNOWN 4 +#define CS_SSL_INVALID_UNTRUSTED 5 +#define CS_SSL_INVALID_MISSINGNAME 6 +#define CS_SSL_INVALID_MISMATCHNAME 7 +#define CS_SSL_INVALID_CERT 8 + +/***************************************************************************** +** +** Open Client/Server options. +** +*****************************************************************************/ + +/* +** The following is the list of all valid options: +*/ +#define CS_OPT_DATEFIRST (CS_INT)5001 /* Set first day of week */ +#define CS_OPT_TEXTSIZE (CS_INT)5002 /* Text size */ +#define CS_OPT_STATS_TIME (CS_INT)5003 /* Server time statistics */ +#define CS_OPT_STATS_IO (CS_INT)5004 /* Server I/O statistics */ +#define CS_OPT_ROWCOUNT (CS_INT)5005 /* Maximum row count */ +#define CS_OPT_NATLANG (CS_INT)5006 /* National Language */ +#define CS_OPT_DATEFORMAT (CS_INT)5007 /* Date format */ +#define CS_OPT_ISOLATION (CS_INT)5008 /* Transaction isolation + ** level */ +#define CS_OPT_AUTHON (CS_INT)5009 /* Set authority level on */ +#define CS_OPT_CHARSET (CS_INT)5010 /* Character set */ +#define CS_OPT_SHOWPLAN (CS_INT)5013 /* show execution plan */ +#define CS_OPT_NOEXEC (CS_INT)5014 /* don't execute query */ +#define CS_OPT_ARITHIGNORE (CS_INT)5015 /* ignore arithmetic + ** exceptions */ +#define CS_OPT_TRUNCIGNORE (CS_INT)5016 /* support ANSI null values */ +#define CS_OPT_ARITHABORT (CS_INT)5017 /* abort on arithmetic + ** exceptions */ +#define CS_OPT_PARSEONLY (CS_INT)5018 /* parse only, return error + ** msgs */ +#define CS_OPT_GETDATA (CS_INT)5020 /* return trigger data */ +#define CS_OPT_NOCOUNT (CS_INT)5021 /* don't print done count */ +#define CS_OPT_FORCEPLAN (CS_INT)5023 /* force variable substitute + ** order */ +#define CS_OPT_FORMATONLY (CS_INT)5024 /* send format w/o row */ +#define CS_OPT_CHAINXACTS (CS_INT)5025 /* chained transaction mode */ +#define CS_OPT_CURCLOSEONXACT (CS_INT)5026 /* close cursor on end trans */ +#define CS_OPT_FIPSFLAG (CS_INT)5027 /* FIPS flag */ +#define CS_OPT_RESTREES (CS_INT)5028 /* return resolution trees */ +#define CS_OPT_IDENTITYON (CS_INT)5029 /* turn on explicit identity */ +#define CS_OPT_CURREAD (CS_INT)5030 /* Set session label @@curread */ +#define CS_OPT_CURWRITE (CS_INT)5031 /* Set session label @@curwrite */ +#define CS_OPT_IDENTITYOFF (CS_INT)5032 /* turn off explicit identity */ +#define CS_OPT_AUTHOFF (CS_INT)5033 /* Set authority level off */ +#define CS_OPT_ANSINULL (CS_INT)5034 /* ANSI NULLS behavior */ +#define CS_OPT_QUOTED_IDENT (CS_INT)5035 /* Quoted identifiers */ +#define CS_OPT_ANSIPERM (CS_INT)5036 /* ANSI permission checking */ +#define CS_OPT_STR_RTRUNC (CS_INT)5037 /* ANSI right truncation */ +#define CS_OPT_SORTMERGE (CS_INT)5038 /* Sort merge join status */ +#define CS_OPT_JTC (CS_INT)5039 /* Enable/disable JTC for session */ +#define CS_OPT_CLIENTREALNAME (CS_INT)5040 /* Set client real name */ +#define CS_OPT_CLIENTHOSTNAME (CS_INT)5041 /* Set client host name */ +#define CS_OPT_CLIENTAPPLNAME (CS_INT)5042 /* Set client appl name */ +#define CS_OPT_IDENTITYUPD_ON (CS_INT)5043 /* turn on identity update */ +#define CS_OPT_IDENTITYUPD_OFF (CS_INT)5044 /* turn off identity update */ +#define CS_OPT_NODATA (CS_INT)5045 /* turn on/off nodata option */ +#define CS_OPT_CIPHERTEXT (CS_INT)5046 /* turn on/off ciphertext + ** encryption */ +#define CS_OPT_SHOW_FI (CS_INT)5047 /* Show Functional Indexes */ +#define CS_OPT_HIDE_VCC (CS_INT)5048 /* Hide Virtual Computed Columns */ +#define CS_OPT_LOBLOCATOR (CS_INT)5049 /* Enable/disable Lob locator */ +#define CS_OPT_LOBLOCFETCHSIZE (CS_INT)5050 /* Lob locator fetch size */ + +#define CS_MIN_OPTION CS_OPT_DATEFIRST +#define CS_MAX_OPTION CS_OPT_LOBLOCFETCHSIZE + +/* +** The supported options are summarized below with their defined values +** for `ArgSize' and `OptionArg'. ArgSize specifies the domain of valid +** values that are allowed. +** +** Option ArgSize OptionArg +** --------------- --------- --------- +** CS_OPT_DATEFIRST 1 byte Defines below +** CS_OPT_TEXTSIZE 4 bytes Size in bytes +** CS_OPT_ROWCOUNT 4 bytes Number of rows +** CS_OPT_NATLANG OptionArg Len National Lang (string) +** CS_OPT_DATEFORMAT 1 byte Defines below +** CS_OPT_ISOLATION 1 byte Defines below +** CS_OPT_AUTHON OptionArg Len Table Name (string) +** CS_OPT_CHARSET OptionArg Len Character set (string) +** CS_OPT_IDENTITYON OptionArg Len Table Name (string) +** CS_OPT_CURREAD OptionArg Len Read Label(string) +** CS_OPT_CURWRITE OptionArg Len Write Label(string) +** CS_OPT_IDENTITYOFF OptionArg Len Table Name (string) +** CS_OPT_AUTHOFF OptionArg Len Table Name (string) +** CS_OPT_IDENTITYUPD_ON OptionArg Len Table Name (string) +** CS_OPT_IDENTITYUPD_OFF OptionArg Len Table Name (string) +** (All remaining options) 1 byte Boolean value +** +** All string values must be sent in 7 bit ASCII. +** +*/ + + +/* CS_OPT_DATEFIRST */ +#define CS_OPT_MONDAY (CS_INT)1 +#define CS_OPT_TUESDAY (CS_INT)2 +#define CS_OPT_WEDNESDAY (CS_INT)3 +#define CS_OPT_THURSDAY (CS_INT)4 +#define CS_OPT_FRIDAY (CS_INT)5 +#define CS_OPT_SATURDAY (CS_INT)6 +#define CS_OPT_SUNDAY (CS_INT)7 + +/* CS_OPT_DATEFORMAT */ +#define CS_OPT_FMTMDY (CS_INT)1 +#define CS_OPT_FMTDMY (CS_INT)2 +#define CS_OPT_FMTYMD (CS_INT)3 +#define CS_OPT_FMTYDM (CS_INT)4 +#define CS_OPT_FMTMYD (CS_INT)5 +#define CS_OPT_FMTDYM (CS_INT)6 + +/* CS_OPT_ISOLATION */ +#define CS_OPT_LEVEL0 (CS_INT)0 +#define CS_OPT_LEVEL1 (CS_INT)1 +#define CS_OPT_LEVEL2 (CS_INT)2 +#define CS_OPT_LEVEL3 (CS_INT)3 + +/***************************************************************************** +** +** Open Client/Server capabilities. +** +*****************************************************************************/ + +/* +** Capability types. +*/ +#define CS_CAP_REQUEST (CS_INT)1 +#define CS_CAP_RESPONSE (CS_INT)2 + +/* +** Special capability value to set/get all capability values at once. +*/ +#define CS_ALL_CAPS (CS_INT)2700 + +/* +** Capability request values. +*/ +#define CS_REQ_LANG (CS_INT)1 +#define CS_REQ_RPC (CS_INT)2 +#define CS_REQ_NOTIF (CS_INT)3 +#define CS_REQ_MSTMT (CS_INT)4 +#define CS_REQ_BCP (CS_INT)5 +#define CS_REQ_CURSOR (CS_INT)6 +#define CS_REQ_DYN (CS_INT)7 +#define CS_REQ_MSG (CS_INT)8 +#define CS_REQ_PARAM (CS_INT)9 +#define CS_DATA_INT1 (CS_INT)10 +#define CS_DATA_INT2 (CS_INT)11 +#define CS_DATA_INT4 (CS_INT)12 +#define CS_DATA_BIT (CS_INT)13 +#define CS_DATA_CHAR (CS_INT)14 +#define CS_DATA_VCHAR (CS_INT)15 +#define CS_DATA_BIN (CS_INT)16 +#define CS_DATA_VBIN (CS_INT)17 +#define CS_DATA_MNY8 (CS_INT)18 +#define CS_DATA_MNY4 (CS_INT)19 +#define CS_DATA_DATE8 (CS_INT)20 +#define CS_DATA_DATE4 (CS_INT)21 +#define CS_DATA_FLT4 (CS_INT)22 +#define CS_DATA_FLT8 (CS_INT)23 +#define CS_DATA_NUM (CS_INT)24 +#define CS_DATA_TEXT (CS_INT)25 +#define CS_DATA_IMAGE (CS_INT)26 +#define CS_DATA_DEC (CS_INT)27 +#define CS_DATA_LCHAR (CS_INT)28 +#define CS_DATA_LBIN (CS_INT)29 +#define CS_DATA_INTN (CS_INT)30 +#define CS_DATA_DATETIMEN (CS_INT)31 +#define CS_DATA_MONEYN (CS_INT)32 +#define CS_CSR_PREV (CS_INT)33 +#define CS_CSR_FIRST (CS_INT)34 +#define CS_CSR_LAST (CS_INT)35 +#define CS_CSR_ABS (CS_INT)36 +#define CS_CSR_REL (CS_INT)37 +#define CS_CSR_MULTI (CS_INT)38 +#define CS_CON_OOB (CS_INT)39 +#define CS_CON_INBAND (CS_INT)40 +#define CS_CON_LOGICAL (CS_INT)41 +#define CS_PROTO_TEXT (CS_INT)42 +#define CS_PROTO_BULK (CS_INT)43 +#define CS_REQ_URGNOTIF (CS_INT)44 +#define CS_DATA_SENSITIVITY (CS_INT)45 +#define CS_DATA_BOUNDARY (CS_INT)46 +#define CS_PROTO_DYNAMIC (CS_INT)47 +#define CS_PROTO_DYNPROC (CS_INT)48 +#define CS_DATA_FLTN (CS_INT)49 +#define CS_DATA_BITN (CS_INT)50 +#define CS_OPTION_GET (CS_INT)51 +#define CS_DATA_INT8 (CS_INT)52 +#define CS_DATA_VOID (CS_INT)53 +#define CS_DOL_BULK (CS_INT)54 +#define CS_OBJECT_JAVA1 (CS_INT)55 +#define CS_OBJECT_CHAR (CS_INT)56 +#define CS_DATA_COLUMNSTATUS (CS_INT)57 +#define CS_OBJECT_BINARY (CS_INT)58 +#define CS_REQ_RESERVED1 (CS_INT)59 +#define CS_WIDETABLES (CS_INT)60 +#define CS_REQ_RESERVED2 (CS_INT)61 +#define CS_DATA_UINT2 (CS_INT)62 +#define CS_DATA_UINT4 (CS_INT)63 +#define CS_DATA_UINT8 (CS_INT)64 +#define CS_DATA_UINTN (CS_INT)65 +#define CS_CUR_IMPLICIT (CS_INT)66 +#define CS_DATA_UCHAR (CS_INT)67 +#define CS_IMAGE_NCHAR (CS_INT)68 +#define CS_BLOB_NCHAR_16 (CS_INT)69 +#define CS_BLOB_NCHAR_8 (CS_INT)70 +#define CS_BLOB_NCHAR_SCSU (CS_INT)71 +#define CS_DATA_DATE (CS_INT)72 +#define CS_DATA_TIME (CS_INT)73 +#define CS_DATA_INTERVAL (CS_INT)74 +#define CS_CSR_SCROLL (CS_INT)75 +#define CS_CSR_SENSITIVE (CS_INT)76 +#define CS_CSR_INSENSITIVE (CS_INT)77 +#define CS_CSR_SEMISENSITIVE (CS_INT)78 +#define CS_CSR_KEYSETDRIVEN (CS_INT)79 +#define CS_REQ_SRVPKTSIZE (CS_INT)80 +#define CS_DATA_UNITEXT (CS_INT)81 +#define CS_CAP_EXTENDEDFAILOVER (CS_INT)82 +#define CS_DATA_SINT1 (CS_INT)83 +#define CS_REQ_LARGEIDENT (CS_INT)84 +#define CS_REQ_BLOB_NCHAR_16 (CS_INT)85 +#define CS_DATA_XML (CS_INT)86 +#define CS_REQ_CURINFO3 (CS_INT)87 +#define CS_REQ_DBRPC2 (CS_INT)88 +#define CS_REQ_MIGRATE (CS_INT)89 +#define CS_REQ_UNDEFINED (CS_INT)90 +#define CS_REQ_RESERVED_091 (CS_INT)91 +#define CS_REQ_RESERVED_092 (CS_INT)92 +#define CS_REQ_RESERVED_093 (CS_INT)93 +#define CS_DATA_BIGDATETIME (CS_INT)94 +#define CS_DATA_BIGTIME (CS_INT)95 +#define CS_RPCPARAM_LOB (CS_INT)96 +#define CS_REQ_INSTID (CS_INT)97 +#define CS_REQ_GRID (CS_INT)98 +#define CS_REQ_DYN_BATCH (CS_INT)99 +#define CS_REQ_LANG_BATCH (CS_INT)100 +#define CS_REQ_RPC_BATCH (CS_INT)101 +#define CS_DATA_LOBLOCATOR (CS_INT)102 +#define CS_REQ_RESERVED_103 (CS_INT)103 +#define CS_REQ_RESERVED_104 (CS_INT)104 +#define CS_REQ_DYNAMIC_SUPPRESS_PARAMFMT (CS_INT)105 + +/* +** Minimum and maximum request capability values. +*/ +#define CS_MIN_REQ_CAP CS_REQ_LANG +#define CS_MAX_REQ_CAP CS_REQ_DYNAMIC_SUPPRESS_PARAMFMT + +/* +** Capability response values. +*/ +#define CS_RES_NOMSG (CS_INT)1 +#define CS_RES_NOEED (CS_INT)2 +#define CS_RES_NOPARAM (CS_INT)3 +#define CS_DATA_NOINT1 (CS_INT)4 +#define CS_DATA_NOINT2 (CS_INT)5 +#define CS_DATA_NOINT4 (CS_INT)6 +#define CS_DATA_NOBIT (CS_INT)7 +#define CS_DATA_NOCHAR (CS_INT)8 +#define CS_DATA_NOVCHAR (CS_INT)9 +#define CS_DATA_NOBIN (CS_INT)10 +#define CS_DATA_NOVBIN (CS_INT)11 +#define CS_DATA_NOMNY8 (CS_INT)12 +#define CS_DATA_NOMNY4 (CS_INT)13 +#define CS_DATA_NODATE8 (CS_INT)14 +#define CS_DATA_NODATE4 (CS_INT)15 +#define CS_DATA_NOFLT4 (CS_INT)16 +#define CS_DATA_NOFLT8 (CS_INT)17 +#define CS_DATA_NONUM (CS_INT)18 +#define CS_DATA_NOTEXT (CS_INT)19 +#define CS_DATA_NOIMAGE (CS_INT)20 +#define CS_DATA_NODEC (CS_INT)21 +#define CS_DATA_NOLCHAR (CS_INT)22 +#define CS_DATA_NOLBIN (CS_INT)23 +#define CS_DATA_NOINTN (CS_INT)24 +#define CS_DATA_NODATETIMEN (CS_INT)25 +#define CS_DATA_NOMONEYN (CS_INT)26 +#define CS_CON_NOOOB (CS_INT)27 +#define CS_CON_NOINBAND (CS_INT)28 +#define CS_PROTO_NOTEXT (CS_INT)29 +#define CS_PROTO_NOBULK (CS_INT)30 +#define CS_DATA_NOSENSITIVITY (CS_INT)31 +#define CS_DATA_NOBOUNDARY (CS_INT)32 +#define CS_RES_NOTDSDEBUG (CS_INT)33 +#define CS_RES_NOSTRIPBLANKS (CS_INT)34 +#define CS_DATA_NOINT8 (CS_INT)35 +#define CS_OBJECT_NOJAVA1 (CS_INT)36 +#define CS_OBJECT_NOCHAR (CS_INT)37 +#define CS_DATA_NOCOLUMNSTATUS (CS_INT)38 +#define CS_OBJECT_NOBINARY (CS_INT)39 +#define CS_RES_RESERVED (CS_INT)40 +#define CS_DATA_NOUINT2 (CS_INT)41 +#define CS_DATA_NOUINT4 (CS_INT)42 +#define CS_DATA_NOUINT8 (CS_INT)43 +#define CS_DATA_NOUINTN (CS_INT)44 +#define CS_NOWIDETABLES (CS_INT)45 +#define CS_DATA_NOUCHAR (CS_INT)46 +#define CS_IMAGE_NONCHAR (CS_INT)47 +#define CS_BLOB_NONCHAR_16 (CS_INT)48 +#define CS_BLOB_NONCHAR_8 (CS_INT)49 +#define CS_BLOB_NONCHAR_SCSU (CS_INT)50 +#define CS_DATA_NODATE (CS_INT)51 +#define CS_DATA_NOTIME (CS_INT)52 +#define CS_DATA_NOINTERVAL (CS_INT)53 +#define CS_DATA_NOUNITEXT (CS_INT)54 +#define CS_DATA_NOSINT1 (CS_INT)55 +#define CS_NO_LARGEIDENT (CS_INT)56 +#define CS_NO_BLOB_NCHAR_16 (CS_INT)57 +#define CS_NO_SRVPKTSIZE (CS_INT)58 +#define CS_DATA_NOXML (CS_INT)59 +#define CS_NONINT_RETURN_VALUE (CS_INT)60 +#define CS_RES_NOXNLMETADATA (CS_INT)61 +#define CS_RES_SUPPRESS_FMT (CS_INT)62 +#define CS_RES_SUPPRESS_DONEINPROC (CS_INT)63 +#define CS_UNUSED_RES (CS_INT)64 +#define CS_DATA_NOBIGDATETIME (CS_INT)65 +#define CS_DATA_NOBIGTIME (CS_INT)66 +#define CS_RES_NO_TDSCONTROL (CS_INT)67 +#define CS_RPCPARAM_NOLOB (CS_INT)68 +#define CS_DATA_NOLOBLOCATOR (CS_INT)69 +#define CS_RES_RESERVED_70 (CS_INT)70 + +/* +** Minimum and maximum response capability values. +*/ +#define CS_MIN_RES_CAP CS_RES_NOMSG +#define CS_MAX_RES_CAP CS_RES_RESERVED_70 + +/* +** Minimum and maximum of all capabilities defined above. +*/ +#define CS_MIN_CAPVALUE CS_REQ_LANG +#define CS_MAX_CAPVALUE CS_REQ_RESERVED_103 + +/* +** Size of area to store capabilities. The array len must be greater +** than CS_CAP_ARRAYLEN additional capabilities to be added. +*/ +#define CS_CAP_ARRAYLEN 16 + +/* +** Maximum OID length (bytes) +*/ +#define CS_MAX_OIDLEN 255 + +/* +** Index used by access macros so that the first byte in the array will +** contain the high order bit. +*/ +#define CS_CAP_IDX(B) ((CS_CAP_ARRAYLEN - (B)/ CS_BITS_PER_BYTE) - 1) + +/* +** Data structure defining storage for capabilities. +*/ +typedef struct _cs_cap_type +{ + CS_BYTE mask[CS_CAP_ARRAYLEN]; +} CS_CAP_TYPE; + +/* +** Access macros for CS_CAP_TYPE structure. +*/ +#define CS_SET_CAPMASK(M, B) ((M)->mask[CS_CAP_IDX(B)] |= \ + (1 << ((B) % CS_BITS_PER_BYTE))) +#define CS_CLR_CAPMASK(M, B) ((M)->mask[CS_CAP_IDX(B)] &= \ + ~(1 << ((B) % CS_BITS_PER_BYTE))) +#define CS_TST_CAPMASK(M, B) ((M)->mask[CS_CAP_IDX(B)] & \ + (1 << ((B) % CS_BITS_PER_BYTE))) + +/***************************************************************************** +** +** Defines used in Open Client/Server structures. +** +*****************************************************************************/ + +/* +** Define I/O types in the CS_IODESC structure. +*/ +#define CS_IODATA (CS_INT)1600 +#define CS_IOPARTIAL (CS_INT)1601 + +/* +** Define status values for the status field of the CS_SERVERMSG and +** CS_CLIENTMSG structures. +*/ +#define CS_HASEED (CS_INT)0x1 +#define CS_FIRST_CHUNK (CS_INT)0x2 +#define CS_LAST_CHUNK (CS_INT)0x4 +#define CS_EEDINFO (CS_INT)0x8 + +/***************************************************************************** +** +** Hidden information structures. +** +*****************************************************************************/ + +#ifndef CS__INTERNAL_STRUCTS + +/* +** If passing code through lint, define the hidden structures as void. +*/ +#ifdef lint + +#ifndef CS_LOGINFO +#define CS_LOGINFO CS_VOID +#endif /* CS_LOGINFO */ + +#ifndef CS_BLKDESC +#define CS_BLKDESC CS_VOID +#endif /* CS_BLKDESC */ + +#ifndef CS_BLK_ROW +#define CS_BLK_ROW CS_VOID +#endif /* CS_BLK_ROW */ + +#else /* lint */ + +/* +** Use anonymous structure tags to define the hidden structures. +*/ +typedef struct _csloginfo CS_LOGINFO; +typedef struct _cs_blkdesc CS_BLKDESC; +typedef struct _bulkrow CS_BLK_ROW; + +#endif /* lint */ + +#endif /* CS__INTERNAL_STRUCTS */ + +/***************************************************************************** +** +** User-accessible information structures. +** +*****************************************************************************/ + +/* +** Define the I/O descriptor structure used by Open Client/Server. +** +** iotype Indicates the type of I/O to perform. For text +** and image operations, iotype always has the +** value CS_IODATA. +** +** datatype The datatype of the data object. The only legal +** values for datatype are CS_TEXT_TYPE and +** CS_IMAGE_TYPE and CS_XML_TYPE. +** +** *locale A pointer to a CS_LOCALE structure containing +** localization information for the text or image +** value. Set locale to NULL if localization +** information is not required. +** +** usertype The SQL Server user-defined datatype of the data +** object, if any. +** +** total_txtlen The total length, in bytes, of the text or image +** value. +** +** offset Reserved for future use. +** +** log_on_update Whether the update for this text object should +** be logged or not. +** +** name The name of the text or image column. name is a +** string of the form table.column. +** +** namelen The actual length of name +** +** timestamp The text timestamp of the column. A text +** timestamp marks the time of a text or image +** column's last modification. +** +** timestamplen The length, in bytes, of timestamp. +** +** textptr The text pointer for the column. A text pointer +** is an internal server pointer that points to the +** data for a text or image column. textptr identifies +** the target column in a send-data operation. +** +** textptrlen The length, in bytes, of textptr. +*/ + +typedef struct _cs_iodesc +{ + CS_INT iotype; + CS_INT datatype; + CS_LOCALE *locale; + CS_INT usertype; + CS_INT total_txtlen; + CS_INT offset; + CS_BOOL log_on_update; + CS_CHAR name[CS_OBJ_NAME]; + CS_INT namelen; + CS_BYTE timestamp[CS_TS_SIZE]; + CS_INT timestamplen; + CS_BYTE textptr[CS_TP_SIZE]; + CS_INT textptrlen; + CS_INT delete_length; +} CS_IODESC; + +/* +** Define the browse descriptor structure used by Open Client/Server. +** +** status A bit mask of either CS_EXPRESSION and/or CS_RENAMED. +** +** isbrowse CS_TRUE the column can be browse-mode updated. +** +** origname The original name of the column in the database. +** +** orignlen Length of origname in bytes. +** +** tablenum The number of the table to which the column +** belongs. The first table in a select statement's +** from-list is table number 1, the second number 2, +** and so forth. +** +** tablename The name of the table to which the column belongs. +** +** tabnlen Length of tablename in bytes. +** +*/ +#if defined(CS_NO_LARGE_IDENTIFIERS) +/* +** In pre-15.0 versions the (old) value for CS_MAX_NAME was used for the +** origname array declaration. Starting from version 15.0, CS_MAX_CHAR +** is used to define this character array size. +*/ +typedef struct _cs_browsedesc +{ + CS_INT status; + CS_BOOL isbrowse; + CS_CHAR origname[CS_MAX_NAME]; + CS_INT orignlen; + CS_INT tablenum; + CS_CHAR tablename[CS_OBJ_NAME]; + CS_INT tabnlen; +} CS_BROWSEDESC; +#else +typedef struct _cs_browsedesc +{ + CS_INT status; + CS_BOOL isbrowse; + CS_CHAR origname[CS_MAX_CHAR]; + CS_INT orignlen; + CS_INT tablenum; + CS_CHAR tablename[CS_OBJ_NAME]; + CS_INT tabnlen; +} CS_BROWSEDESC; +#endif + +/* +** Define the server message structure used by Open Client/Server. +** +** msgnumber The server message number. +** +** state The server error state. +** +** severity The severity of the message. +** +** text The text of the error string. If an application +** is not sequencing messages, text is guaranteed +** to be null-terminated, even if it has been +** truncated. If an application is sequencing +** messages, text is null-terminated only if it is +** the last chunk of a sequenced message. +** +** textlen The length, in bytes, of text. +** +** svrname The name of the server that generated the message. +** +** svrnlen The length, in bytes, of svrname. +** +** proc The name of the stored procedure which caused +** the message, if any. +** +** proclen The length, in bytes, of proc. +** +** line The line number, if any, of the line that caused +** the message. line can be a line number in a +** stored procedure or a line number in a command +** batch. +** +** status A bitmask used to indicate various types of +** information, such as whether or not extended +** error data is included with the message. +** +** sqlstate SQL state information. +** +** sqlstatelen The length, in bytes, of sqlstate. +** +*/ +#if defined(CS_NO_LARGE_IDENTIFIERS) +/* +** In pre-15.0 versions the (old) value for CS_MAX_NAME was used for the +** name array declarations. Starting from version 15.0, CS_MAX_CHAR is +** used to define these character array sizes. +*/ +typedef struct _cs_servermsg +{ + CS_MSGNUM msgnumber; + CS_INT state; + CS_INT severity; + CS_CHAR text[CS_MAX_MSG]; + CS_INT textlen; + CS_CHAR svrname[CS_MAX_NAME]; + CS_INT svrnlen; + CS_CHAR proc[CS_MAX_NAME]; + CS_INT proclen; + CS_INT line; + CS_INT status; + CS_BYTE sqlstate[CS_SQLSTATE_SIZE]; + CS_INT sqlstatelen; +} CS_SERVERMSG; +#else +typedef struct _cs_servermsg +{ + CS_MSGNUM msgnumber; + CS_INT state; + CS_INT severity; + CS_CHAR text[CS_MAX_MSG]; + CS_INT textlen; + CS_CHAR svrname[CS_MAX_CHAR]; + CS_INT svrnlen; + CS_CHAR proc[CS_MAX_CHAR]; + CS_INT proclen; + CS_INT line; + CS_INT status; + CS_BYTE sqlstate[CS_SQLSTATE_SIZE]; + CS_INT sqlstatelen; +} CS_SERVERMSG; +#endif + +/* +** Define the client message structure used by Open Client/Server. +** +** severity A symbolic value representing the severity of +** the message. +** +** msgnumber The message number. For information on how to +** interpret this number in Client-Library +** applications, see the Client-Library Messages +** topics in the Open Client documentation. +** +** msgstring The message string. If an application is not +** sequencing messages, msgstring is guaranteed to +** be null-terminated, even if it has been truncated. +** If an application is sequencing messages, +** msgstring is null-terminated only if it is the +** last chunk of a sequenced message. +** +** msgstringlen The length, in bytes, of msgstring. +** +** osnumber An error may have involved interactions the +** operating system (OS). If so, the OS error +** number would be stored here. Otherwise, +** this will be zero. +** +** osstring The operating system error text (if any). +** +** osstringlen The length, in bytes, of osstring. +** +** status A bitmask used to indicate various types of +** information, such as whether or not this is the +** first, a middle, or the last chunk of an error +** message. +** +** sqlstate SQL state information. +** +** sqlstatelen The length, in bytes, of sqlstate. +** +*/ +typedef struct _cs_clientmsg +{ + CS_INT severity; + CS_MSGNUM msgnumber; + CS_CHAR msgstring[CS_MAX_MSG]; + CS_INT msgstringlen; + CS_INT osnumber; + CS_CHAR osstring[CS_MAX_MSG]; + CS_INT osstringlen; + CS_INT status; + CS_BYTE sqlstate[CS_SQLSTATE_SIZE]; + CS_INT sqlstatelen; +} CS_CLIENTMSG; + +/* +** Define the constants an application tests for in the DONEPROC callback +*/ +#define CS_TDS_DONEPROC_TYPE (CS_INT)1 +#define CS_TDS_DONEINPROC_TYPE (CS_INT)2 + +/***************************************************************************** +** +** Define user-accessable functions for Client/Server Library here. +** +*****************************************************************************/ + +/* +** Declare all functions. +*/ +CS_START_EXTERN_C + +/* cscalc.c */ +extern CS_RETCODE CS_PUBLIC cs_calc( + CS_CONTEXT *context, + CS_INT op, + CS_INT datatype, + CS_VOID *var1, + CS_VOID *var2, + CS_VOID *dest + ); + +/* cscmp.c */ +extern CS_RETCODE CS_PUBLIC cs_cmp( + CS_CONTEXT *context, + CS_INT datatype, + CS_VOID *var1, + CS_VOID *var2, + CS_INT *result + ); + +/* cscnvrt.c */ +extern CS_RETCODE CS_PUBLIC cs_convert( + CS_CONTEXT *context, + CS_DATAFMT *srcfmt, + CS_VOID *srcdata, + CS_DATAFMT *destfmt, + CS_VOID *destdata, + CS_INT *outlen + ); +extern CS_RETCODE CS_PUBLIC cs_will_convert( + CS_CONTEXT *context, + CS_INT srctype, + CS_INT desttype, + CS_BOOL *result + ); +extern CS_RETCODE CS_PUBLIC cs_set_convert( + CS_CONTEXT *context, + CS_INT action, + CS_INT srctype, + CS_INT desttype, + CS_CONV_FUNC *buffer + ); +extern CS_RETCODE CS_PUBLIC cs_setnull( + CS_CONTEXT *context, + CS_DATAFMT *datafmt, + CS_VOID *buf, + CS_INT buflen + ); + +/* csconfig.c */ +extern CS_RETCODE CS_PUBLIC cs_config( + CS_CONTEXT *context, + CS_INT action, + CS_INT property, + CS_VOID *buf, + CS_INT buflen, + CS_INT *outlen + ); + +/* csctxall.c */ +extern CS_RETCODE CS_PUBLIC cs_ctx_alloc( + CS_INT version, + CS_CONTEXT **outptr + ); + +/* csctxdrp.c */ +extern CS_RETCODE CS_PUBLIC cs_ctx_drop( + CS_CONTEXT *context + ); + +/* csctxglb.c */ +extern CS_RETCODE CS_PUBLIC cs_ctx_global( + CS_INT version, + CS_CONTEXT **outptr + ); + +/* csobjs.c */ +extern CS_RETCODE CS_PUBLIC cs_objects( + CS_CONTEXT *context, + CS_INT action, + CS_OBJNAME *objname, + CS_OBJDATA *objdata + ); + +/* csdiag.c */ +extern CS_RETCODE CS_PUBLIC cs_diag( + CS_CONTEXT *context, + CS_INT operation, + CS_INT type, + CS_INT idx, + CS_VOID *buffer + ); + +/* csdtcrak.c */ +extern CS_RETCODE CS_PUBLIC cs_dt_crack( + CS_CONTEXT *context, + CS_INT datetype, + CS_VOID *dateval, + CS_DATEREC *daterec + ); + +/* csdtinfo.c */ +extern CS_RETCODE CS_PUBLIC cs_dt_info( + CS_CONTEXT *context, + CS_INT action, + CS_LOCALE *locale, + CS_INT type, + CS_INT item, + CS_VOID *buffer, + CS_INT buflen, + CS_INT *outlen + ); + +/* csloc.c */ +extern CS_RETCODE CS_PUBLIC cs_locale( + CS_CONTEXT *context, + CS_INT action, + CS_LOCALE *locale, + CS_INT type, + CS_CHAR *buffer, + CS_INT buflen, + CS_INT *outlen + ); + +/* cslocall.c */ +extern CS_RETCODE CS_PUBLIC cs_loc_alloc( + CS_CONTEXT *context, + CS_LOCALE **loc_pointer + ); + +/* cslocator.c */ +extern CS_RETCODE CS_PUBLIC cs_locator( + CS_CONTEXT *context, + CS_INT action, + CS_LOCATOR *locator, + CS_INT type, + CS_VOID *buffer, + CS_INT buflen, + CS_INT *outlen); +extern CS_RETCODE CS_PUBLIC cs_locator_alloc( + CS_CONTEXT *context, + CS_LOCATOR **locator); +extern CS_RETCODE CS_PUBLIC cs_locator_drop( + CS_CONTEXT *context, + CS_LOCATOR *locator); + +/* cslocdrp.c */ +extern CS_RETCODE CS_PUBLIC cs_loc_drop( + CS_CONTEXT *context, + CS_LOCALE *locale + ); + +/* csstr.c */ +extern size_t CS_PUBLIC cs_strlcpy( + char *target_str, + const char *source_str, + size_t target_size + ); + +extern size_t CS_PUBLIC cs_strlcat( + char *target_str, + const char *source_str, + size_t target_size + ); + +extern void CS_PUBLIC cs_snprintf( + char *str, + size_t size, + const char *format, + ... + ); + +#ifdef CS__INTERNAL_STRUCTS +extern CS_RETCODE CS_VARARGS cs_strbuild( + CS_CONTEXT *context, + ... + ); +#else +extern CS_RETCODE CS_VARARGS cs_strbuild( + CS_CONTEXT *context, + CS_CHAR *buf, + CS_INT buflen, + CS_INT *outlen, + CS_CHAR *text, + CS_INT textlen, + ... + ); +#endif /* CS__INTERNAL_STRUCTS */ + +/* csstrcmp.c */ +extern CS_RETCODE CS_PUBLIC cs_strcmp( + CS_CONTEXT *context, + CS_LOCALE *locale, + CS_INT type, + CS_CHAR *str1, + CS_INT len1, + CS_CHAR *str2, + CS_INT len2, + CS_INT *result + ); + +/* cstime.c */ +extern CS_RETCODE CS_PUBLIC cs_time( + CS_CONTEXT *context, + CS_LOCALE *locale, + CS_VOID *buf, + CS_INT buflen, + CS_INT *outlen, + CS_DATEREC *drec + ); + +/* csmancnt.c */ +extern CS_RETCODE CS_PUBLIC cs_manage_convert( + CS_CONTEXT *context, + CS_INT action, + CS_INT srctype, + CS_CHAR *srcname, + CS_INT srcnamelen, + CS_INT desttype, + CS_CHAR *destname, + CS_INT destnamelen, + CS_INT *maxmultiplier, + CS_CONV_FUNC *func + ); + +/* csmaxmul.c */ +extern CS_RETCODE CS_PUBLIC cs_conv_mult( + CS_CONTEXT *context, + CS_LOCALE *srcloc, + CS_LOCALE *destloc, + CS_INT *multiplier + ); + +CS_END_EXTERN_C + +#endif /* __CSPUBLIC_H__ */ diff --git a/libodbc/include/sybase/cstypes.h b/libodbc/include/sybase/cstypes.h new file mode 100644 index 0000000000..294d7810e9 --- /dev/null +++ b/libodbc/include/sybase/cstypes.h @@ -0,0 +1,1217 @@ +/* +** Sybase Open Client/Server +** Confidential Property of Sybase, Inc. +** Copyright Sybase, Inc. 1992 - 2012 +** All rights reserved +*/ +#ifndef __CSTYPES_H__ +#define __CSTYPES_H__ + +/* +** This file defines basic error codes and data types used in all Open +** Client/Server Products. +*/ + +/* +** Include the configuration header file. This file contains the defines and +** type definitions that are platform/compiler specific. +*/ +#ifndef __NO_INCLUDE__ +#include +#endif /* __NO_INCLUDE__ */ + +/***************************************************************************** +** +** Return code defines used in client/server applications. +** +*****************************************************************************/ + +/* +** See the csconfig.h header file for the definition of CS_RETCODE. +*/ + +/* +** Define the core return codes. +*/ +#define CS_SUCCEED (CS_RETCODE)1 +#define CS_FAIL (CS_RETCODE)0 +#define CS_MEM_ERROR (CS_RETCODE)-1 +#define CS_PENDING (CS_RETCODE)-2 +#define CS_QUIET (CS_RETCODE)-3 +#define CS_BUSY (CS_RETCODE)-4 +#define CS_INTERRUPT (CS_RETCODE)-5 +#define CS_BLK_HAS_TEXT (CS_RETCODE)-6 +#define CS_CONTINUE (CS_RETCODE)-7 +#define CS_FATAL (CS_RETCODE)-8 +#define CS_RET_HAFAILOVER (CS_RETCODE)-9 +#define CS_UNSUPPORTED (CS_RETCODE)-10 + +/* +** Return codes for the srv_xferdata(). Indicates that a set of parameters has +** been copied during parameter batching. +** CS_PARAMS_MORE indicates that there are more parameters to be read. +** CS_PARAMS_END indicates that this set of parameters was the last. +*/ +#define CS_PARAMS_MORE (CS_RETCODE)-11 +#define CS_PARAMS_END (CS_RETCODE)-12 + +/* +** Define error offsets. All other CS_RETCODE error codes should be +** based off of these values to avoid define conflicts. +*/ +#define CS_CONV_ERR (CS_RETCODE)(-100) +#define CS_EXTERNAL_ERR (CS_RETCODE)(-200) +#define CS_INTERNAL_ERR (CS_RETCODE)(-300) + +/* common library errors */ +#define CS_COMN_ERR (CS_RETCODE)(-400) + +/* +** Return code for a routine which was cancelled via ct_cancel(). +*/ +#define CS_CANCELED (CS_RETCODE)(CS_EXTERNAL_ERR - 2) + +/* +** Special returns for ct_fetch(). +*/ +#define CS_ROW_FAIL (CS_RETCODE)(CS_EXTERNAL_ERR - 3) +#define CS_END_DATA (CS_RETCODE)(CS_EXTERNAL_ERR - 4) + +/* +** Special return for ct_results(). +*/ +#define CS_END_RESULTS (CS_RETCODE)(CS_EXTERNAL_ERR - 5) + +/* +** Special return for ct_get_data(). +*/ +#define CS_END_ITEM (CS_RETCODE)(CS_EXTERNAL_ERR - 6) + +/* +** Special return for ct_diag(). +*/ +#define CS_NOMSG (CS_RETCODE)(CS_EXTERNAL_ERR - 7) + +/* +** Special return for ct_poll(). +*/ +#define CS_TIMED_OUT (CS_RETCODE)(CS_EXTERNAL_ERR - 8) + +/* +** Special returns for passthru(). +*/ +#define CS_PASSTHRU_EOM (CS_RETCODE)(CS_EXTERNAL_ERR - 10) +#define CS_PASSTHRU_MORE (CS_RETCODE)(CS_EXTERNAL_ERR - 11) + +/* +** Special return for ct_cancel(). +*/ +#define CS_TRYING (CS_RETCODE)(CS_EXTERNAL_ERR - 13) + +/* +** Errors caused by external events (i.e. bad params supplied by user). +*/ +#define CS_EBADPARAM (CS_RETCODE)(CS_EXTERNAL_ERR - 14) +#define CS_EBADLEN (CS_RETCODE)(CS_EXTERNAL_ERR - 15) +#define CS_ENOCNVRT (CS_RETCODE)(CS_EXTERNAL_ERR - 16) + +/* +** Special returns for the new ct_scroll_fetch() API. For Scrollable +** Cursor only. +*/ +#define CS_SCROLL_CURSOR_ENDS (CS_RETCODE)(CS_EXTERNAL_ERR - 17) +#define CS_CURSOR_BEFORE_FIRST (CS_RETCODE)(CS_EXTERNAL_ERR - 18) +#define CS_CURSOR_AFTER_LAST (CS_RETCODE)(CS_EXTERNAL_ERR - 19) + +/* +** Special return for CS_BLOB_TYPE parameter data. +*/ +#define CS_BLOBDATA (CS_RETCODE)(CS_EXTERNAL_ERR - 20) + +/* +** Return codes for conversion errors. These should be used in any user- +** defined conversion routines that are install via cs_set_convert(). +*/ +#define CS_EOVERFLOW (CS_RETCODE)(CS_CONV_ERR - 1) +#define CS_EUNDERFLOW (CS_RETCODE)(CS_CONV_ERR - 2) +#define CS_EPRECISION (CS_RETCODE)(CS_CONV_ERR - 3) +#define CS_ESCALE (CS_RETCODE)(CS_CONV_ERR - 4) +#define CS_ESYNTAX (CS_RETCODE)(CS_CONV_ERR - 5) +#define CS_EFORMAT (CS_RETCODE)(CS_CONV_ERR - 6) +#define CS_EDOMAIN (CS_RETCODE)(CS_CONV_ERR - 7) +#define CS_EDIVZERO (CS_RETCODE)(CS_CONV_ERR - 8) +#define CS_ERESOURCE (CS_RETCODE)(CS_CONV_ERR - 9) +#define CS_ENULLNOIND (CS_RETCODE)(CS_CONV_ERR - 10) +#define CS_ETRUNCNOIND (CS_RETCODE)(CS_CONV_ERR - 11) +#define CS_ENOBIND (CS_RETCODE)(CS_CONV_ERR - 12) +#define CS_TRUNCATED (CS_RETCODE)(CS_CONV_ERR - 13) +#define CS_ESTYLE (CS_RETCODE)(CS_CONV_ERR - 14) +#define CS_EBADXLT (CS_RETCODE)(CS_CONV_ERR - 15) +#define CS_ENOXLT (CS_RETCODE)(CS_CONV_ERR - 16) +#define CS_USEREP (CS_RETCODE)(CS_CONV_ERR - 17) + +/* +** Error Severities. +*/ +#define CS_SV_INFORM (CS_INT)0 +#define CS_SV_API_FAIL (CS_INT)1 +#define CS_SV_RETRY_FAIL (CS_INT)2 +#define CS_SV_RESOURCE_FAIL (CS_INT)3 +#define CS_SV_CONFIG_FAIL (CS_INT)4 +#define CS_SV_COMM_FAIL (CS_INT)5 +#define CS_SV_INTERNAL_FAIL (CS_INT)6 +#define CS_SV_FATAL (CS_INT)7 + + +/***************************************************************************** +** +** Error numbers, and macros for extracting information from a +** Client-Library error number. +** +** Error numbers are broken down into four components: +** +** Layer - Represents which layer is reporting the error. +** Origin - Indicates where the error manifested itself. +** Severity - How bad is the error? +** Number - The actual layer specific error number being +** reported. +** +*****************************************************************************/ + +/* +** The error message number. +*/ +#if defined (SYB_LP64) || defined (SYB_LLP64) || defined (_AIX) +typedef unsigned int CS_MSGNUM; +#else +typedef long CS_MSGNUM; +#endif + +/* +** The following macros are used to extract the components from a composite +** error number. +*/ +#define CS_LAYER(L) (CS_MSGNUM) (((L) >> 24) & 0xff) +#define CS_ORIGIN(O) (CS_MSGNUM) (((O) >> 16) & 0xff) +#define CS_SEVERITY(S) (CS_MSGNUM) (((S) >> 8) & 0xff) +#define CS_NUMBER(N) (CS_MSGNUM) ((N) & 0xff) + +/* +** The following are the possible values for cs_status field of +** CHAR_ATTRIB structure defined in intl_nls.h +*/ + +# define CS_STAT_DEFAULT 0x0000 +# define CS_STAT_MULTIBYTE 0x0001 +# define CS_STAT_SPACELAST 0x0002 +# define CS_STAT_NONASCIISP 0x0004 + +/***************************************************************************** +** +** Defines used in client/server applications. +** +*****************************************************************************/ + +/* +** The maximum localization name allowed. A four byte value is added (instead +** of 1 byte) to provide space for null-termination and remain on a modulo 4 +** byte boundary. +*/ +#define CS_MAX_LOCALE (CS_INT)(64 + 4) + +/* +** The maximum column name length allowed. This maximum length does not +** include a null-terminator. For declarations of character arrays with +** the maximum possible size, including a null-terminator, CS_MAX_CHAR +** should be used. +** +** If the compile flag CS_NO_LARGE_IDENTIFIERS has been set, we need to +** use the old size for CS_MAX_NAME, defined as CS_MAX_NAME_NO_LRGID. +*/ +#define CS_MAX_NAME_NO_LRGID (CS_INT)(128 + 4) +#if defined(CS_NO_LARGE_IDENTIFIERS) +#define CS_MAX_NAME CS_MAX_NAME_NO_LRGID +#else +#define CS_MAX_NAME (CS_INT)(255) +#endif /* CS_NO_LARGE_IDENTIFIERS */ + +/* +** The maximum password length allowed. +*/ +#define CS_MAX_PASS (CS_INT)(30) + +/* +** The maximum number of characters in arrays, including a null-terminator. +** Please note that this define does not correspond to any server definition +** of lengths (particularly the length of the character data type, which +** is 255 bytes for the Sybase server). +*/ +#define CS_MAX_CHAR (CS_INT)256 + +/* +** Maximum string in Directory Services +*/ +#define CS_MAX_DS_STRING (CS_INT)512 + +/* +** Maximum data length of numeric/decimal datatypes. +*/ +#define CS_MAX_NUMLEN (CS_INT)33 + +/* +** To be true or not true. +*/ +#define CS_TRUE (CS_BOOL)1 +#define CS_FALSE (CS_BOOL)0 + +/* +** Define basic default types. +*/ +#define CS_NULLTERM (CS_INT)(-9) +#define CS_WILDCARD (CS_INT)(-99) +#define CS_NO_LIMIT (CS_INT)(-9999) +#define CS_UNUSED (CS_INT)(-99999) + +/* +** timeout values +** +** CS_NO_LIMIT Resource will never expire. +** CS_UNEXPIRED Resource did not expire. +*/ +#define CS_UNEXPIRED (CS_INT)(-999999) + +/* +** Enumerate part of usertypes dataserver support. +*/ +#define USER_UNICHAR_TYPE (CS_INT)34 +#define USER_UNIVARCHAR_TYPE (CS_INT)35 + +/* +** Enumerate what datatypes we support. +*/ +#define CS_ILLEGAL_TYPE (CS_INT)(-1) +#define CS_CHAR_TYPE (CS_INT)0 +#define CS_BINARY_TYPE (CS_INT)1 +#define CS_LONGCHAR_TYPE (CS_INT)2 +#define CS_LONGBINARY_TYPE (CS_INT)3 +#define CS_TEXT_TYPE (CS_INT)4 +#define CS_IMAGE_TYPE (CS_INT)5 +#define CS_TINYINT_TYPE (CS_INT)6 +#define CS_SMALLINT_TYPE (CS_INT)7 +#define CS_INT_TYPE (CS_INT)8 +#define CS_REAL_TYPE (CS_INT)9 +#define CS_FLOAT_TYPE (CS_INT)10 +#define CS_BIT_TYPE (CS_INT)11 +#define CS_DATETIME_TYPE (CS_INT)12 +#define CS_DATETIME4_TYPE (CS_INT)13 +#define CS_MONEY_TYPE (CS_INT)14 +#define CS_MONEY4_TYPE (CS_INT)15 +#define CS_NUMERIC_TYPE (CS_INT)16 +#define CS_DECIMAL_TYPE (CS_INT)17 +#define CS_VARCHAR_TYPE (CS_INT)18 +#define CS_VARBINARY_TYPE (CS_INT)19 +#define CS_LONG_TYPE (CS_INT)20 +#define CS_SENSITIVITY_TYPE (CS_INT)21 +#define CS_BOUNDARY_TYPE (CS_INT)22 +#define CS_VOID_TYPE (CS_INT)23 +#define CS_USHORT_TYPE (CS_INT)24 +#define CS_UNICHAR_TYPE (CS_INT)25 +#define CS_BLOB_TYPE (CS_INT)26 +#define CS_DATE_TYPE (CS_INT)27 +#define CS_TIME_TYPE (CS_INT)28 +#define CS_UNITEXT_TYPE (CS_INT)29 +#define CS_BIGINT_TYPE (CS_INT)30 +#define CS_USMALLINT_TYPE (CS_INT)31 +#define CS_UINT_TYPE (CS_INT)32 +#define CS_UBIGINT_TYPE (CS_INT)33 +#define CS_XML_TYPE (CS_INT)34 +#define CS_BIGDATETIME_TYPE (CS_INT)35 +#define CS_BIGTIME_TYPE (CS_INT)36 +#define CS_TEXTLOCATOR_TYPE (CS_INT)37 +#define CS_IMAGELOCATOR_TYPE (CS_INT)38 +#define CS_UNITEXTLOCATOR_TYPE (CS_INT)39 + +/* +** Define the minimum and maximum datatype values. +*/ +#define CS_MIN_SYBTYPE CS_CHAR_TYPE +#define CS_MAX_SYBTYPE CS_UNITEXTLOCATOR_TYPE + +/* +** Define the number of datatypes that are supported by Sybase. +*/ +#define CS_MAXSYB_TYPE (CS_MAX_SYBTYPE + 1) + +/* +** The minumum user-defined data type. +*/ +#define CS_USER_TYPE (CS_INT)100 + +/* +** Define the bit values used in the format element of the CS_DATAFMT +** structure. The CS_FMT_JUSTIFY_RT flag exists for future use only. +*/ +#define CS_FMT_UNUSED (CS_INT)0x0 +#define CS_FMT_NULLTERM (CS_INT)0x1 +#define CS_FMT_PADNULL (CS_INT)0x2 +#define CS_FMT_PADBLANK (CS_INT)0x4 +#define CS_FMT_JUSTIFY_RT (CS_INT)0x8 +#define CS_FMT_STRIPBLANKS (CS_INT)0x10 +#define CS_FMT_SAFESTR (CS_INT)0x20 + +/* +** The following are bit values for the status field in the CS_DATAFMT +** structure. +** +** CS_HIDDEN Set if this column would normally be hidden +** from the user. +** +** CS_KEY Set if the column is a key column. +** +** CS_VERSION_KEY Set if the column is part of the version key for +** the row. +** +** CS_NODATA Not currently used in Open Client/Server. +** +** CS_UPDATABLE Set if the column is an updatable cursor column. +** +** CS_CANBENULL Set if the column can contain NULL values. +** +** CS_DESCIN +** CS_DESCOUT Open Server-specific values for dynamic SQL. +** +** CS_INPUTVALUE Set if the parameter is an input parameter value +** for a Client-Library command. +** +** CS_UPDATECOL Set if the parameter is the name of a column in +** the update clause of a cursor declare command. +** +** CS_RETURN Set if the parameter is a return parameter to +** an RPC command. +** +** CS_TIMESTAMP Set if the column is a timestamp column. +** +** CS_NODEFAULT Open Server-specific status values for RPC parameters. +** +** CS_IDENTITY Set if the column is an identity column. +** +** CS_PADCHAR Do not truncate trailing zeroes on varbinary columns. +** +*/ +#define CS_HIDDEN (CS_INT)0x1 +#define CS_KEY (CS_INT)0x2 +#define CS_VERSION_KEY (CS_INT)0x4 +#define CS_NODATA (CS_INT)0x8 +#define CS_UPDATABLE (CS_INT)0x10 +#define CS_CANBENULL (CS_INT)0x20 +#define CS_DESCIN (CS_INT)0x40 +#define CS_DESCOUT (CS_INT)0x80 +#define CS_INPUTVALUE (CS_INT)0x100 +#define CS_UPDATECOL (CS_INT)0x200 +#define CS_RETURN (CS_INT)0x400 +#define CS_RETURN_CANBENULL (CS_INT) 0x420 +#define CS_TIMESTAMP (CS_INT)0x2000 +#define CS_NODEFAULT (CS_INT)0x4000 +#define CS_IDENTITY (CS_INT)0x8000 +#define CS_PADCHAR (CS_INT)0x10000 + +/* +** The following are bit values for the status field in the CS_BROWSEDESC +** structure. +** +** CS_EXPRESSION Set when the column is the result of an expression. +** +** CS_RENAMED Set when that the column's heading is not the +** original name of the column. +*/ +#define CS_EXPRESSION (CS_INT)0x800 +#define CS_RENAMED (CS_INT)0x1000 + +/* +** Define special precision/scale value for using the precision/scale of the +** source element when doing a conversion from a numeric/decimal datatype to a +** numeric/decimal datatype. +*/ +#define CS_SRC_VALUE (CS_INT)-2562 + +/* +** Minimum/maximum/default precision and scale values for numeric/decimal +** datatypes. +*/ +#define CS_MIN_PREC (CS_INT)1 +#define CS_MAX_PREC (CS_INT)77 +#define CS_DEF_PREC (CS_INT)18 + +#define CS_MIN_SCALE (CS_INT)0 +#define CS_MAX_SCALE (CS_INT)77 +#define CS_DEF_SCALE (CS_INT)0 + +/* +** The datetime format for converting datetime to char. +** +** Note: The style code of a 4-digit-year date is its 2-digit-year date +** counterpart plus 100. For example, CS_DATES_MDY1 is defined as 1, so +** CS_DATES_MDY1_YYYY is defined as 101. +*/ +#define CS_DATES_SHORT (CS_INT)0 /* default */ +#define CS_DATES_MDY1 (CS_INT)1 /* mm/dd/yy */ +#define CS_DATES_YMD1 (CS_INT)2 /* yy.mm.dd */ +#define CS_DATES_DMY1 (CS_INT)3 /* dd/mm/yy */ +#define CS_DATES_DMY2 (CS_INT)4 /* dd.mm.yy */ +#define CS_DATES_DMY3 (CS_INT)5 /* dd-mm-yy */ +#define CS_DATES_DMY4 (CS_INT)6 /* dd mon yy */ +#define CS_DATES_MDY2 (CS_INT)7 /* mon dd, yy */ +#define CS_DATES_HMS (CS_INT)8 /* hh:mm:ss */ +#define CS_DATES_LONG (CS_INT)9 /* default with micro secs */ +#define CS_DATES_MDY3 (CS_INT)10 /* mm-dd-yy */ +#define CS_DATES_YMD2 (CS_INT)11 /* yy/mm/dd */ +#define CS_DATES_YMD3 (CS_INT)12 /* yymmdd */ +#define CS_DATES_YDM1 (CS_INT)13 /* yy/dd/mm */ +#define CS_DATES_MYD1 (CS_INT)14 /* mm/yy/dd */ +#define CS_DATES_DYM1 (CS_INT)15 /* dd/yy/mm */ +#define CS_DATES_MDYHMS (CS_INT)16 /* mon dd yyyy hh:mm:ss */ +#define CS_DATES_HMA (CS_INT)17 /* hh:mmAM(PM) */ +#define CS_DATES_HM (CS_INT)18 /* hh:mm */ +#define CS_DATES_HMSZA (CS_INT)19 /* hh:mm:ss:zzzAM(PM) */ +#define CS_DATES_HMSZ (CS_INT)20 /* hh:mm:ss:zzz */ +#define CS_DATES_YMDHMS (CS_INT)21 /* yy/mm/dd hh:mm:ss */ +#define CS_DATES_YMDHMA (CS_INT)22 /* yy/mm/dd hh:mmAM */ +#define CS_DATES_YMDTHMS (CS_INT)23 /* yyyy-mm-ddThh:mm:ss */ +#define CS_DATES_HMSUSA (CS_INT)36 /* hh:mm:ss.zzzzzzAM(PM) */ +#define CS_DATES_HMSUS (CS_INT)37 /* hh:mm:ss.zzzzzz */ +#define CS_DATES_LONGUSA (CS_INT)38 /* mon dd yy hh:mm:ss.zzzzzzAM(PM) */ +#define CS_DATES_LONGUS (CS_INT)39 /* mon dd yy hh:mm:ss.zzzzzz */ +#define CS_DATES_YMDHMSUS (CS_INT)40 /* yy-mm-dd hh:mm:ss.zzzzzz */ +#define CS_DATES_SHORT_ALT (CS_INT)100 /* default */ +#define CS_DATES_MDY1_YYYY (CS_INT)101 /* mm/dd/yyyy */ +#define CS_DATES_YMD1_YYYY (CS_INT)102 /* yyyy.mm.dd */ +#define CS_DATES_DMY1_YYYY (CS_INT)103 /* dd/mm/yyyy */ +#define CS_DATES_DMY2_YYYY (CS_INT)104 /* dd.mm.yyyy */ +#define CS_DATES_DMY3_YYYY (CS_INT)105 /* dd-mm-yyyy */ +#define CS_DATES_DMY4_YYYY (CS_INT)106 /* dd mon yyyy */ +#define CS_DATES_MDY2_YYYY (CS_INT)107 /* mon dd, yyyy */ +#define CS_DATES_HMS_ALT (CS_INT)108 /* hh:mm:ss */ +#define CS_DATES_LONG_ALT (CS_INT)109 /* default with micro secs */ +#define CS_DATES_MDY3_YYYY (CS_INT)110 /* mm-dd-yyyy */ +#define CS_DATES_YMD2_YYYY (CS_INT)111 /* yyyy/mm/dd */ +#define CS_DATES_YMD3_YYYY (CS_INT)112 /* yyyymmdd */ +#define CS_DATES_YDM1_YYYY (CS_INT)113 /* yyyy/dd/mm */ +#define CS_DATES_MYD1_YYYY (CS_INT)114 /* mm/yyyy/dd */ +#define CS_DATES_DYM1_YYYY (CS_INT)115 /* dd/yyyy/mm */ +#define CS_DATES_MDYHMS_ALT (CS_INT)116 /* mon dd yyyy hh:mm:ss */ +#define CS_DATES_HMA_ALT (CS_INT)117 /* hh:mmAM(PM) */ +#define CS_DATES_HM_ALT (CS_INT)118 /* hh:mm */ +#define CS_DATES_YMDHMS_YYYY (CS_INT)121 /* yyyy/mm/dd hh:mm:ss */ +#define CS_DATES_YMDHMA_YYYY (CS_INT)122 /* yyyy/mm/dd hh:mmAM */ +#define CS_DATES_HMSUSA_YYYY (CS_INT)136 /* hh:mm:ss.zzzzzzAM(PM) */ +#define CS_DATES_HMSUS_YYYY (CS_INT)137 /* hh:mm:ss.zzzzzz */ +#define CS_DATES_LONGUSA_YYYY (CS_INT)138 /* mon dd yyyy hh:mm:ss.zzzzzzAM(PM) */ +#define CS_DATES_LONGUS_YYYY (CS_INT)139 /* mon dd yyyy hh:mm:ss.zzzzzz */ +#define CS_DATES_YMDHMSUS_YYYY (CS_INT)140 /* yyyy-mm-dd hh:mm:ss.zzzzzz */ + + +/* +** sizeof macro which forces a CS_INT cast for portability. +*/ +#define CS_SIZEOF (CS_INT)sizeof + +/* +** Locale type information. CS_LC_MONETARY and CS_LC_NUMERIC are defined +** for future use. +*/ +#define CS_LC_COLLATE (CS_INT)1 +#define CS_LC_CTYPE (CS_INT)2 +#define CS_LC_MESSAGE (CS_INT)3 +#define CS_LC_MONETARY (CS_INT)4 +#define CS_LC_NUMERIC (CS_INT)5 +#define CS_LC_TIME (CS_INT)6 +#define CS_LC_ALL (CS_INT)7 +#define CS_SYB_LANG (CS_INT)8 +#define CS_SYB_CHARSET (CS_INT)9 +#define CS_SYB_SORTORDER (CS_INT)10 +#define CS_SYB_COLLATE CS_SYB_SORTORDER +#define CS_SYB_LANG_CHARSET (CS_INT)11 +#define CS_SYB_TIME (CS_INT)12 +#define CS_SYB_MONETARY (CS_INT)13 +#define CS_SYB_NUMERIC (CS_INT)14 + +/* +** Object type information for the cs_objects() API. +*/ +#define CS_CONNECTNAME (CS_INT)1 +#define CS_CURSORNAME (CS_INT)2 +#define CS_STATEMENTNAME (CS_INT)3 +#define CS_CURRENT_CONNECTION (CS_INT)4 +#define CS_MIN_USERDATA (CS_INT)100 + +/* +** Info type information for the ct_ds_objinfo() API. +*/ +#define CS_DS_CLASSOID (CS_INT)1 +#define CS_DS_DIST_NAME (CS_INT)2 +#define CS_DS_NUMATTR (CS_INT)3 +#define CS_DS_ATTRIBUTE (CS_INT)4 +#define CS_DS_ATTRVALS (CS_INT)5 + +/* +** type information for cs_locator() API +*/ +#define CS_LCTR_LOBLEN (CS_INT)1 +#define CS_LCTR_PREFETCHLEN (CS_INT)2 +#define CS_LCTR_PREFETCHDATA (CS_INT)3 +#define CS_LCTR_LOCATOR (CS_INT)4 +#define CS_LCTR_DATATYPE (CS_INT)5 + +/***************************************************************************** +** +** Common datatype typedefs and structures used in client/server applications. +** +*****************************************************************************/ + +/* +** Define client/server datatypes. +** +** CS_INT is defined in csconfig.h +** CS_FLOAT is defined in csconfig.h +** CS_UINT is defined in csconfig.h +*/ +typedef unsigned char CS_TINYINT; /* 1 byte integer */ +typedef short CS_SMALLINT; /* 2 byte integer */ +typedef unsigned short CS_USMALLINT; /* 2 byte unsigned integer */ +typedef char CS_CHAR; /* char type */ +typedef unsigned char CS_BINARY; /* binary type */ +typedef unsigned char CS_BIT; /* bit type */ +typedef float CS_REAL; /* 4 byte float type */ +typedef unsigned char CS_BYTE; /* 1 byte byte */ +typedef unsigned char CS_TEXT; /* text data */ +typedef unsigned char CS_IMAGE; /* image data */ +typedef unsigned char CS_LONGCHAR; /* long char type */ +typedef unsigned char CS_LONGBINARY; /* long binary type */ +#if defined (SYB_LLP64) +typedef __int64 CS_LONG; /* long integer type */ +typedef unsigned __int64 CS_ULONG; /* unsigned long integer type */ +#else +typedef long CS_LONG; /* long integer type */ +#endif +typedef CS_INT CS_VOIDDATA; /* void data */ +typedef unsigned short CS_UNICHAR; /* 2-byte unichar type */ +typedef CS_INT CS_BLOB; /* blob data type */ +typedef CS_INT CS_DATE; /* 4-byte date type */ +typedef CS_INT CS_TIME; /* 4-byte time type */ +typedef unsigned short CS_UNITEXT; /* 2-byte unitext type */ + +#if defined(__alpha) || defined(SYB_LP64) +typedef long CS_BIGINT; /* 8-byte integer */ +typedef unsigned long CS_UBIGINT; /* 8-byte unsigned integer */ +#elif defined(_WIN32) || defined(SYB_LLP64) +typedef __int64 CS_BIGINT; /* 8-byte integer */ +typedef unsigned __int64 CS_UBIGINT; /* 8-byte unsigned integer */ +#else +typedef long long CS_BIGINT; /* 8-byte integer */ +typedef unsigned long long CS_UBIGINT; /* 8-byte unsigned integer */ +#endif + +#if defined(SYB_LLP64) +typedef unsigned __int64 CS_SOCKET; +#else +typedef int CS_SOCKET; +#endif + +typedef unsigned char CS_XML; /* xml data */ + +/* +** CS_BIGDATETIME is an 8-byte unsigned int containing the number +** of micro seconds (sec*10^-6) passed since midnight 1/1/0000 +*/ +typedef CS_UBIGINT CS_BIGDATETIME; + +/* +** CS_BIGTIME is an 8-byte unsigned int containing the number +** of micro seconds (sec*10^-6) passed since midnight +*/ +typedef CS_UBIGINT CS_BIGTIME; + +typedef struct cs_ctx_globs CS_CTX_GLOBS; +typedef struct cs_ctx_locglobs CS_CTX_LOCGLOBS; + +/* +** The following typedefs are platform specific. +** +** CS_VOID (compiler void differences) +** CS_THRDRES (compiler void differences) +** CS_INT (need to force it to 4 bytes) +** +** Please see the csconfig.h file for the actual definitions. +*/ + +/* +** Unsigned types (CS_UINT can be found in csconfig.h). +*/ +typedef unsigned short CS_USHORT; + +/* +** The datetime structures. +*/ +typedef struct _cs_datetime +{ + CS_INT dtdays; /* number of days since 1/1/1900 */ + CS_INT dttime; /* number 300th second since mid */ +} CS_DATETIME; + +typedef struct _cs_datetime4 +{ + CS_USHORT days; /* number of days since 1/1/1900 */ + CS_USHORT minutes; /* number of minutes since midnight */ +} CS_DATETIME4; + +/* +** The money structures. +*/ +typedef struct _cs_money +{ + CS_INT mnyhigh; + CS_UINT mnylow; +} CS_MONEY; + +typedef struct _cs_money4 +{ + CS_INT mny4; +} CS_MONEY4; + +/* +** The numeric structures. +*/ +typedef struct _cs_numeric +{ + CS_BYTE precision; + CS_BYTE scale; + CS_BYTE array[CS_MAX_NUMLEN]; +} CS_NUMERIC; + +typedef CS_NUMERIC CS_DECIMAL; + +/* +** The var (pascal like) structures. Please don't confuse these datatypes +** with the Sybase server "varchar" column type. +*/ +typedef struct _cs_varychar +{ + CS_SMALLINT len; /* length of the string */ + CS_CHAR str[CS_MAX_CHAR]; /* string, no NULL terminator */ +} CS_VARCHAR; + +typedef struct _cs_varybin +{ + CS_SMALLINT len; /* length of the binary array */ + CS_BYTE array[CS_MAX_CHAR]; /* the array itself. */ +} CS_VARBINARY; + +/* +** Datetime value information. +*/ +typedef struct _cs_daterec +{ + CS_INT dateyear; /* 1900 to the future */ + CS_INT datemonth; /* 0 - 11 */ + CS_INT datedmonth; /* 1 - 31 */ + CS_INT datedyear; /* 1 - 366 */ + CS_INT datedweek; /* 0 - 6 (Mon. - Sun.) */ + CS_INT datehour; /* 0 - 23 */ + CS_INT dateminute; /* 0 - 59 */ + CS_INT datesecond; /* 0 - 59 */ + CS_INT datemsecond; /* 0 - 997 */ + CS_INT datetzone; /* 0 - 127 */ + CS_INT datesecfrac; /* 0 - 999999 */ + CS_INT datesecprec; /* For now 10^6 only */ +} CS_DATEREC; + +/***************************************************************************** +** +** Hidden information structures. +** +*****************************************************************************/ + +#ifndef CS__INTERNAL_STRUCTS + +/* +** If passing code through lint, define the hidden structures as void. +*/ +#ifdef lint + +#ifndef CS_CONTEXT +#define CS_CONTEXT CS_VOID +#endif /* CS_CONTEXT */ + +#ifndef CS_LOCALE +#define CS_LOCALE CS_VOID +#endif /* CS_LOCALE */ + +#ifndef CS_CONNECTION +#define CS_CONNECTION CS_VOID +#endif /* CS_CONNECTION */ + +#ifndef CS_COMMAND +#define CS_COMMAND CS_VOID +#endif /* CS_COMMAND */ + +#ifndef CS_DS_OBJECT +#define CS_DS_OBJECT CS_VOID +#endif /* CS_DS_OBJECT */ + +#ifndef CS_DS_RESULT +#define CS_DS_RESULT CS_VOID +#endif /* CS_DS_RESULT */ + +#ifndef CS_LOCATOR +#define CS_LOCATOR CS_VOID +#endif /* CS_LOCATOR */ + +#else /* lint */ + +/* +** Use anonymous structure tags to define the hidden structures. +*/ +typedef struct _cscontext CS_CONTEXT; +typedef struct _cslocale CS_LOCALE; +typedef struct _csconnection CS_CONNECTION; +typedef struct _cscommand CS_COMMAND; +typedef struct _csdsobject CS_DS_OBJECT; +typedef struct _csdsresult CS_DS_RESULT; +typedef struct _cslocator CS_LOCATOR; /* locator pointer type */ + +#endif /* lint */ + +#endif /* CS__INTERNAL_STRUCTS */ + +/***************************************************************************** +** +** User-accessible information structures. +** +*****************************************************************************/ + +/* +** The data format structure used by Open Client/Server. +** +** name[CS_MAX_CHAR] The name of the data. +** +** namelen The actual length of the name. +** +** datatype The datatype field indicates what Sybase +** or user defined datatype is being represented. +** +** format The format field tells whether or not data +** should be padded to the full length of the +** variable. This will only be used if the type +** of the variable is character or binary. The +** format field also tells whether the data +** should be null-terminated (for char +** variables, only). This is a bit field in which +** the format values are or'd together. +** +** maxlength The max length the data might be. +** +** scale This is used if dataytype needs it (e.g. +** CS_NUMERIC) +** +** precision This is used if dataytype needs it. +** +** status Additional data status values. This is a bit +** field in which the status values are or'd +** together. +** +** count If binding data, the count field tells how +** many rows should be bound. +** +** usertype User-defined datatype code passed back from +** the Server. +** +** *locale Pointer to the locale for this data. +*/ +#if defined(CS_NO_LARGE_IDENTIFIERS) +/* +** In pre-15.0 versions the (old) value for CS_MAX_NAME was used for the +** name array declarations. Starting from version 15.0, CS_MAX_CHAR is +** used to define these character array sizes. +*/ +typedef struct _cs_datafmt +{ + CS_CHAR name[CS_MAX_NAME]; + CS_INT namelen; + CS_INT datatype; + CS_INT format; + CS_INT maxlength; + CS_INT scale; + CS_INT precision; + CS_INT status; + CS_INT count; + CS_INT usertype; + CS_LOCALE *locale; +} CS_DATAFMT; +#else +typedef struct _cs_datafmt +{ + CS_CHAR name[CS_MAX_CHAR]; + CS_INT namelen; + CS_INT datatype; + CS_INT format; + CS_INT maxlength; + CS_INT scale; + CS_INT precision; + CS_INT status; + CS_INT count; + CS_INT usertype; + CS_LOCALE *locale; +} CS_DATAFMT; +#endif + +/* +** The object name structure used by Client-Library cs_object() API. +** +** thinkexists indicates whether the application expects +** this object to exist. +** +** object_type The type of the object. This field is the +** first part of a 5-part key. +** +** last_name The `last name' associated with the object of +** interest, if any. This field is the second +** part of a 5-part key. +** +** lnlen The length, in bytes, of last_name. +** +** first_name The `first name' associated with the object of +** interest, if any. This field is the third part +** of a 5-part key. +** +** fnlen The length, in bytes, of first_name. +** +** scope Data that describes the scope of the object. +** This field is the fourth part of a 5-part key. +** +** scopelen The length, in bytes, of scope. +** +** thread Platform-specific data that is used to distinguish +** threads in a multi-threaded execution environment. +** This field is the fifth part of a 5-part key. +** +** threadlen The length, in bytes, of thread. +*/ +#if defined(CS_NO_LARGE_IDENTIFIERS) +/* +** In pre-15.0 versions the (old) value for CS_MAX_NAME was used for the +** name array declarations. Starting from version 15.0, CS_MAX_CHAR is +** used to define these character array sizes. +*/ +typedef struct _cs_objname +{ + CS_BOOL thinkexists; + CS_INT object_type; + CS_CHAR last_name[CS_MAX_NAME]; + CS_INT lnlen; + CS_CHAR first_name[CS_MAX_NAME]; + CS_INT fnlen; + CS_VOID *scope; + CS_INT scopelen; + CS_VOID *thread; + CS_INT threadlen; +} CS_OBJNAME; +#else +typedef struct _cs_objname +{ + CS_BOOL thinkexists; + CS_INT object_type; + CS_CHAR last_name[CS_MAX_CHAR]; + CS_INT lnlen; + CS_CHAR first_name[CS_MAX_CHAR]; + CS_INT fnlen; + CS_VOID *scope; + CS_INT scopelen; + CS_VOID *thread; + CS_INT threadlen; +} CS_OBJNAME; +#endif + +/* +** The object data structure used by Client-Library cs_object() API. +** +** actuallyexists Indicates whether this object actually exists. +** cs_objects sets actuallyexists to CS_TRUE +** if it finds a matching object. +** cs_objects sets actuallyexists to CS_FALSE +** if it does not find a matching object. +** +** connection A pointer to the CS_CONNECTION structure +** representing the connection in which the object exists. +** +** command A pointer to the CS_COMMAND structure representing the +** command space with which the object is associated, +** if any. +** +** buffer A pointer to data space. An application can +** use buffer to associate data with a saved object. +** +** buflen The length, in bytes, of *buffer. +** +*/ +typedef struct _cs_objdata +{ + CS_BOOL actuallyexists; + CS_CONNECTION *connection; + CS_COMMAND *command; + CS_VOID *buffer; + CS_INT buflen; +} CS_OBJDATA; + +/* +** Typedef to make using session ids more convenient. +*/ +typedef CS_BYTE CS_SESSIONID[6]; + +/* +** Definition of a pointer to a function for all conversion routines. +*/ + +CS_START_EXTERN_C + +typedef CS_RETCODE (CS_PUBLIC * CS_CONV_FUNC)PROTOTYPE(( + CS_CONTEXT *context, + CS_DATAFMT *srcfmt, + CS_VOID *src, + CS_DATAFMT *destfmt, + CS_VOID *dest, + CS_INT *destlen + )); +/* +** Pointers to the thread primitive functions used in Open Client. +*/ +typedef CS_RETCODE (CS_PUBLIC * CS_THRDM_FUNC)PROTOTYPE(( + CS_THRDRES *resource + )); +typedef CS_RETCODE (CS_PUBLIC * CS_THRDE_FUNC)PROTOTYPE(( + CS_THRDRES *resource + )); +typedef CS_RETCODE (CS_PUBLIC * CS_THRDC_FUNC)PROTOTYPE(( + CS_THRDRES **resource + )); +typedef CS_RETCODE (CS_PUBLIC * CS_THRDW_FUNC)PROTOTYPE(( + CS_THRDRES *resource, + CS_INT millisecs + )); +typedef CS_RETCODE (CS_PUBLIC * CS_THRDID_FUNC)PROTOTYPE(( + CS_VOID *buffer, + CS_INT buflen, + CS_INT *outlen + )); +CS_END_EXTERN_C + +/* +** Define the thread primitive structure. This structure is used by +** application programs to pass thread primitives into Client-Library. +** These primitives are used internally in Client-Library to run in a +** threaded environment. +** +** create_mutex_fn Create a recursive mutex. +** +** delete_mutex_fn Delete a mutex. +** +** take_mutex_fn Lock a mutex. +** +** release_mutex_fn Release a mutex. +** +** create_event_fn Create an event variable. +** +** delete_event_fn Delete an event variable. +** +** signal_event_fn Signal event variable. +** +** reset_event_fn Reset event variable. +** +** waitfor_event_fn Wait for event to be signaled. +** +** thread_id_fn Return id of currently executing thread. +*/ +typedef struct _cs_thread +{ + CS_THRDC_FUNC create_mutex_fn; + CS_THRDM_FUNC delete_mutex_fn; + CS_THRDM_FUNC take_mutex_fn; + CS_THRDM_FUNC release_mutex_fn; + CS_THRDC_FUNC create_event_fn; + CS_THRDE_FUNC delete_event_fn; + CS_THRDE_FUNC signal_event_fn; + CS_THRDE_FUNC reset_event_fn; + CS_THRDW_FUNC waitfor_event_fn; + CS_THRDID_FUNC thread_id_fn; +} CS_THREAD; + + +/* +** Directory Service definitions +*/ + +/* +** Token name for predefined OID strings. +*/ +#define CS_OID_SYBASE "1.3.6.1.4.1.897" +#define CS_OID_DIRECTORY "1.3.6.1.4.1.897.4" +#define CS_OID_OBJCLASS "1.3.6.1.4.1.897.4.1" +#define CS_OID_ATTRTYPE "1.3.6.1.4.1.897.4.2" +#define CS_OID_ATTRSYNTAX "1.3.6.1.4.1.897.4.3" +#define CS_OID_OBJSERVER "1.3.6.1.4.1.897.4.1.1" +#define CS_OID_ATTRVERSION "1.3.6.1.4.1.897.4.2.1" +#define CS_OID_ATTRSERVNAME "1.3.6.1.4.1.897.4.2.2" +#define CS_OID_ATTRSERVICE "1.3.6.1.4.1.897.4.2.3" +#define CS_OID_ATTRSTATUS "1.3.6.1.4.1.897.4.2.4" +#define CS_OID_ATTRADDRESS "1.3.6.1.4.1.897.4.2.5" +#define CS_OID_ATTRSECMECH "1.3.6.1.4.1.897.4.2.6" +#define CS_OID_ATTRRETRYCOUNT "1.3.6.1.4.1.897.4.2.7" +#define CS_OID_ATTRLOOPDELAY "1.3.6.1.4.1.897.4.2.8" + +#define CS_OID_ATTRJCPROTOCOL "1.3.6.1.4.1.897.4.2.9" +#define CS_OID_ATTRJCPROPERTY "1.3.6.1.4.1.897.4.2.10" +#define CS_OID_ATTRDATABASENAME "1.3.6.1.4.1.897.4.2.11" + +#define CS_OID_ATTRHAFAILOVER "1.3.6.1.4.1.897.4.2.15" +#define CS_OID_ATTRRMNAME "1.3.6.1.4.1.897.4.2.16" +#define CS_OID_ATTRRMTYPE "1.3.6.1.4.1.897.4.2.17" +#define CS_OID_ATTRJDBCDSI "1.3.6.1.4.1.897.4.2.18" +#define CS_OID_ATTRSERVERTYPE "1.3.6.1.4.1.897.4.2.19" + +/* +** Current status of server object. +*/ +#define CS_STATUS_ACTIVE (CS_INT)1 +#define CS_STATUS_STOPPED (CS_INT)2 +#define CS_STATUS_FAILED (CS_INT)3 +#define CS_STATUS_UNKNOWN (CS_INT)4 + + +/* +** Server object access type +*/ +#define CS_ACCESS_CLIENT (CS_INT)1 +#define CS_ACCESS_ADMIN (CS_INT)2 +#define CS_ACCESS_MGMTAGENT (CS_INT)3 +#define CS_ACCESS_CLIENT_QUERY (CS_INT)1 +#define CS_ACCESS_CLIENT_MASTER (CS_INT)2 +#define CS_ACCESS_ADMIN_QUERY (CS_INT)3 +#define CS_ACCESS_ADMIN_MASTER (CS_INT)4 +#define CS_ACCESS_MGMTAGENT_QUERY (CS_INT)5 +#define CS_ACCESS_MGMTAGENT_MASTER (CS_INT)6 + + +/* +** String Attribute Value +** +** This structure is used to describe a string attribute +** value. +** +** str_length Length of string. +** str_buffer String data. +*/ +typedef struct _cs_string +{ + CS_INT str_length; + CS_CHAR str_buffer[CS_MAX_DS_STRING]; +} CS_STRING; + +/* +** Transport Address attribute value +** +** This structure is used to describe a server address attribute +** value. +** +** addr_accesstype Access type provided on transport +** address. +** addr_trantype Transport address type +** addr_tranaddress The address string. +*/ +typedef struct _cs_tranaddr +{ + CS_INT addr_accesstype; + CS_STRING addr_trantype; + CS_STRING addr_tranaddress; +} CS_TRANADDR; + +/* +** Object Identifier +** +** This structure is used to represent an Object +** Identifier. +** +** oid_length Length of Object Identifier. +** oid_buffer Buffer containing object identifier. +*/ +typedef struct _cs_oid +{ + CS_INT oid_length; + CS_CHAR oid_buffer[CS_MAX_DS_STRING]; +} CS_OID; + +/* +** Attribute Value +** +** This union is used to represent an attribute value. +** +*/ +typedef union _cs_attrvalue +{ + CS_STRING value_string; + CS_BOOL value_boolean; + CS_INT value_enumeration; + CS_INT value_integer; + CS_OID value_oid; + CS_TRANADDR value_tranaddr; +} CS_ATTRVALUE; + + +/* +** Attribute +** +** This structure describes an attribute. +** +*/ +typedef struct _cs_attribute +{ + CS_OID attr_type; + CS_INT attr_syntax; + CS_INT attr_numvals; +} CS_ATTRIBUTE; + +/* +** Syntax identifier tokens for the CS_ATTRIBUTE union. +*/ +#define CS_ATTR_SYNTAX_NOOP (CS_INT) 0 +#define CS_ATTR_SYNTAX_STRING (CS_INT) 1 +#define CS_ATTR_SYNTAX_INTEGER (CS_INT) 2 +#define CS_ATTR_SYNTAX_BOOLEAN (CS_INT) 3 +#define CS_ATTR_SYNTAX_ENUMERATION (CS_INT) 4 +#define CS_ATTR_SYNTAX_TRANADDR (CS_INT) 5 +#define CS_ATTR_SYNTAX_OID (CS_INT) 6 + + +/* +** Structure for defining directory lookup criteria when using +** ct_ds_lookup api. +*/ +typedef struct _cs_ds_lookup_info +{ + CS_OID *objclass; + CS_CHAR *path; + CS_INT pathlen; + CS_DS_OBJECT *attrfilter; + CS_DS_OBJECT *attrselect; +} CS_DS_LOOKUP_INFO; + +/* +** Predefined signal handlers for client and server signal handler +** libraries. +*/ + +#define CS_SIGNAL_IGNORE -1 +#define CS_SIGNAL_DEFAULT -2 +#define CS_ASYNC_RESTORE -3 +#define CS_SIGNAL_BLOCK -4 +#define CS_SIGNAL_UNBLOCK -5 + +#endif /* __CSTYPES_H__ */ diff --git a/libodbc/include/sybase/ctpublic.h b/libodbc/include/sybase/ctpublic.h new file mode 100644 index 0000000000..0d303bfa3b --- /dev/null +++ b/libodbc/include/sybase/ctpublic.h @@ -0,0 +1,466 @@ +/* +** Sybase CT-LIBRARY +** Confidential Property of Sybase, Inc. +** (c) Copyright Sybase, Inc. 1991 - 2012 +** All rights reserved +*/ + +/* +** ctpublic.h - This is the public header file for CT-Lib. +*/ +#ifndef __CTPUBLIC_H__ +#define __CTPUBLIC_H__ + +/* +** include common defines and typedefs +*/ +#ifndef __NO_INCLUDE__ +#include +#include +#endif /* __NO_INCLUDE__ */ + +/***************************************************************************** +** +** defines used in CT-Lib applications +** +*****************************************************************************/ + +/* +** define for each CT-Lib API +*/ +#define CT_BIND (CS_INT) 0 +#define CT_BR_COLUMN (CS_INT) 1 +#define CT_BR_TABLE (CS_INT) 2 +#define CT_CALLBACK (CS_INT) 3 +#define CT_CANCEL (CS_INT) 4 +#define CT_CAPABILITY (CS_INT) 5 +#define CT_CLOSE (CS_INT) 6 +#define CT_CMD_ALLOC (CS_INT) 7 +#define CT_CMD_DROP (CS_INT) 8 +#define CT_CMD_PROPS (CS_INT) 9 +#define CT_COMMAND (CS_INT) 10 +#define CT_COMPUTE_INFO (CS_INT) 11 +#define CT_CON_ALLOC (CS_INT) 12 +#define CT_CON_DROP (CS_INT) 13 +#define CT_CON_PROPS (CS_INT) 14 +#define CT_CON_XFER (CS_INT) 15 +#define CT_CONFIG (CS_INT) 16 +#define CT_CONNECT (CS_INT) 17 +#define CT_CURSOR (CS_INT) 18 +#define CT_DATA_INFO (CS_INT) 19 +#define CT_DEBUG (CS_INT) 20 +#define CT_DESCRIBE (CS_INT) 21 +#define CT_DIAG (CS_INT) 22 +#define CT_DYNAMIC (CS_INT) 23 +#define CT_DYNDESC (CS_INT) 24 +#define CT_EXIT (CS_INT) 25 +#define CT_FETCH (CS_INT) 26 +#define CT_GET_DATA (CS_INT) 27 +#define CT_GETFORMAT (CS_INT) 28 +#define CT_GETLOGINFO (CS_INT) 29 +#define CT_INIT (CS_INT) 30 +#define CT_KEYDATA (CS_INT) 31 +#define CT_OPTIONS (CS_INT) 32 +#define CT_PARAM (CS_INT) 33 +#define CT_POLL (CS_INT) 34 +#define CT_RECVPASSTHRU (CS_INT) 35 +#define CT_REMOTE_PWD (CS_INT) 36 +#define CT_RES_INFO (CS_INT) 37 +#define CT_RESULTS (CS_INT) 38 +#define CT_SEND (CS_INT) 39 +#define CT_SEND_DATA (CS_INT) 40 +#define CT_SENDPASSTHRU (CS_INT) 41 +#define CT_SETLOGINFO (CS_INT) 42 +#define CT_WAKEUP (CS_INT) 43 +#define CT_LABELS (CS_INT) 44 +#define CT_DS_LOOKUP (CS_INT) 45 +#define CT_DS_DROP (CS_INT) 46 +#define CT_DS_OBJINFO (CS_INT) 47 +#define CT_SETPARAM (CS_INT) 48 +#define CT_DYNSQLDA (CS_INT) 49 +#define CT_SCROLL_FETCH (CS_INT) 50 +#define CT_SEND_PARAMS (CS_INT) 51 + +#define CT_NOTIFICATION (CS_INT) 1000 /* id for event notfication + ** completion + */ +#define CT_USER_FUNC (CS_INT) 10000 /* minimum user-defined + ** function id + */ + + +/***************************************************************************** +** +** define all user accessable functions here +** +*****************************************************************************/ + +/* +** declare all functions +*/ +CS_START_EXTERN_C + +/* ctdebug.c */ +extern CS_RETCODE CS_PUBLIC ct_debug( + CS_CONTEXT *context, + CS_CONNECTION *connection, + CS_INT operation, + CS_INT flag, + CS_CHAR *filename, + CS_INT fnamelen + ); +/* ctbind.c */ +extern CS_RETCODE CS_PUBLIC ct_bind( + CS_COMMAND *cmd, + CS_INT item, + CS_DATAFMT *datafmt, + CS_VOID *buf, + CS_INT *outputlen, + CS_SMALLINT *indicator + ); +/* ctbr.c */ +extern CS_RETCODE CS_PUBLIC ct_br_column( + CS_COMMAND *cmd, + CS_INT colnum, + CS_BROWSEDESC *browsedesc + ); +extern CS_RETCODE CS_PUBLIC ct_br_table( + CS_COMMAND *cmd, + CS_INT tabnum, + CS_INT type, + CS_VOID *buf, + CS_INT buflen, + CS_INT *outlen + ); +/* ctcallbk.c */ +extern CS_RETCODE CS_PUBLIC ct_callback( + CS_CONTEXT *context, + CS_CONNECTION *connection, + CS_INT action, + CS_INT type, + CS_VOID *func + ); +/* ctcancel.c */ +extern CS_RETCODE CS_PUBLIC ct_cancel( + CS_CONNECTION *connection, + CS_COMMAND *cmd, + CS_INT type + ); +/* ctcap.c */ +extern CS_RETCODE CS_PUBLIC ct_capability( + CS_CONNECTION *connection, + CS_INT action, + CS_INT type, + CS_INT capability, + CS_VOID *val + ); +/* ctcinfo.c */ +extern CS_RETCODE CS_PUBLIC ct_compute_info( + CS_COMMAND *cmd, + CS_INT type, + CS_INT colnum, + CS_VOID *buf, + CS_INT buflen, + CS_INT *outlen + ); +/* ctclose.c */ +extern CS_RETCODE CS_PUBLIC ct_close( + CS_CONNECTION *connection, + CS_INT option + ); +/* ctcmd.c */ +extern CS_RETCODE CS_PUBLIC ct_cmd_alloc( + CS_CONNECTION *connection, + CS_COMMAND **cmdptr + ); +extern CS_RETCODE CS_PUBLIC ct_cmd_drop( + CS_COMMAND *cmd + ); +extern CS_RETCODE CS_PUBLIC ct_cmd_props( + CS_COMMAND *cmd, + CS_INT action, + CS_INT property, + CS_VOID *buf, + CS_INT buflen, + CS_INT *outlen + ); +extern CS_RETCODE CS_PUBLIC ct_command( + CS_COMMAND *cmd, + CS_INT type, + CS_CHAR *buf, + CS_INT buflen, + CS_INT option + ); +/* ctcon.c */ +extern CS_RETCODE CS_PUBLIC ct_con_alloc( + CS_CONTEXT *context, + CS_CONNECTION **connection + ); +extern CS_RETCODE CS_PUBLIC ct_con_drop( + CS_CONNECTION *connection + ); +extern CS_RETCODE CS_PUBLIC ct_con_props( + CS_CONNECTION *connection, + CS_INT action, + CS_INT property, + CS_VOID *buf, + CS_INT buflen, + CS_INT *outlen + ); +extern CS_RETCODE CS_PUBLIC ct_connect( + CS_CONNECTION *connection, + CS_CHAR *server_name, + CS_INT snamelen + ); +/* ctconfig.c */ +extern CS_RETCODE CS_PUBLIC ct_config( + CS_CONTEXT *context, + CS_INT action, + CS_INT property, + CS_VOID *buf, + CS_INT buflen, + CS_INT *outlen + ); +/* ctcursor.c */ +extern CS_RETCODE CS_PUBLIC ct_cursor( + CS_COMMAND *cmd, + CS_INT type, + CS_CHAR *name, + CS_INT namelen, + CS_CHAR *text, + CS_INT tlen, + CS_INT option + ); +/* ctddesc.c */ +extern CS_RETCODE CS_PUBLIC ct_dyndesc( + CS_COMMAND *cmd, + CS_CHAR *descriptor, + CS_INT desclen, + CS_INT operation, + CS_INT idx, + CS_DATAFMT *datafmt, + CS_VOID *buffer, + CS_INT buflen, + CS_INT *copied, + CS_SMALLINT *indicator + ); +/* ctdesc.c */ +extern CS_RETCODE CS_PUBLIC ct_describe( + CS_COMMAND *cmd, + CS_INT item, + CS_DATAFMT *datafmt + ); +/* ctdiag.c */ +extern CS_RETCODE CS_PUBLIC ct_diag( + CS_CONNECTION *connection, + CS_INT operation, + CS_INT type, + CS_INT idx, + CS_VOID *buffer + ); +/* ctdyn.c */ +extern CS_RETCODE CS_PUBLIC ct_dynamic( + CS_COMMAND *cmd, + CS_INT type, + CS_CHAR *id, + CS_INT idlen, + CS_CHAR *buf, + CS_INT buflen + ); +/* ctdynsqd.c */ +extern CS_RETCODE CS_PUBLIC ct_dynsqlda( + CS_COMMAND *cmd, + CS_INT type, + SQLDA *dap, + CS_INT operation + ); +/* ctexit.c */ +extern CS_RETCODE CS_PUBLIC ct_exit( + CS_CONTEXT *context, + CS_INT option + ); +/* ctfetch.c */ +extern CS_RETCODE CS_PUBLIC ct_fetch( + CS_COMMAND *cmd, + CS_INT type, + CS_INT offset, + CS_INT option, + CS_INT *count + ); +/* ctfetch.c */ +extern CS_RETCODE CS_PUBLIC ct_scroll_fetch( + CS_COMMAND *cmd, + CS_INT type, + CS_INT offset, + CS_INT option, + CS_INT *count + ); +/* ctgfmt.c */ +extern CS_RETCODE CS_PUBLIC ct_getformat( + CS_COMMAND *cmd, + CS_INT colnum, + CS_VOID *buf, + CS_INT buflen, + CS_INT *outlen + ); +/* ctkeydat.c */ +extern CS_RETCODE CS_PUBLIC ct_keydata( + CS_COMMAND *cmd, + CS_INT action, + CS_INT colnum, + CS_VOID *buffer, + CS_INT buflen, + CS_INT *outlen + ); +/* ctinit.c */ +extern CS_RETCODE CS_PUBLIC ct_init( + CS_CONTEXT *context, + CS_INT version + ); +/* ctopt.c */ +extern CS_RETCODE CS_PUBLIC ct_options( + CS_CONNECTION *connection, + CS_INT action, + CS_INT option, + CS_VOID *param, + CS_INT paramlen, + CS_INT *outlen + ); +/* ctparam.c */ +extern CS_RETCODE CS_PUBLIC ct_param( + CS_COMMAND *cmd, + CS_DATAFMT *datafmt, + CS_VOID *data, + CS_INT datalen, + CS_SMALLINT indicator + ); +/* ctpass.c */ +extern CS_RETCODE CS_PUBLIC ct_getloginfo( + CS_CONNECTION *connection, + CS_LOGINFO **logptr + ); +extern CS_RETCODE CS_PUBLIC ct_setloginfo( + CS_CONNECTION *connection, + CS_LOGINFO *loginfo + ); +extern CS_RETCODE CS_PUBLIC ct_recvpassthru( + CS_COMMAND *cmd, + CS_VOID **recvptr + ); +extern CS_RETCODE CS_PUBLIC ct_sendpassthru( + CS_COMMAND *cmd, + CS_VOID *send_bufp + ); +/* ctpoll.c */ +extern CS_RETCODE CS_PUBLIC ct_poll( + CS_CONTEXT *context, + CS_CONNECTION *connection, + CS_INT milliseconds, + CS_CONNECTION **compconn, + CS_COMMAND **compcmd, + CS_INT *compid, + CS_INT *compstatus + ); +/* ctrempwd.c */ +extern CS_RETCODE CS_PUBLIC ct_remote_pwd( + CS_CONNECTION *connection, + CS_INT action, + CS_CHAR *server_name, + CS_INT snamelen, + CS_CHAR *password, + CS_INT pwdlen + ); +/* ctresult.c */ +extern CS_RETCODE CS_PUBLIC ct_results( + CS_COMMAND *cmd, + CS_INT *result_type + ); +/* ctrinfo.c */ +extern CS_RETCODE CS_PUBLIC ct_res_info( + CS_COMMAND *cmd, + CS_INT operation, + CS_VOID *buf, + CS_INT buflen, + CS_INT *outlen + ); +/* ctsend.c */ +extern CS_RETCODE CS_PUBLIC ct_send( + CS_COMMAND *cmd + ); +extern CS_RETCODE CS_PUBLIC ct_send_params( + CS_COMMAND *cmd, + CS_INT unused + ); + +/* ctgtdata.c */ +extern CS_RETCODE CS_PUBLIC ct_get_data( + CS_COMMAND *cmd, + CS_INT colnum, + CS_VOID *buf, + CS_INT buflen, + CS_INT *outlen + ); +/* ctsndata.c */ +extern CS_RETCODE CS_PUBLIC ct_send_data( + CS_COMMAND *cmd, + CS_VOID *buf, + CS_INT buflen + ); +/* ctdinfo.c */ +extern CS_RETCODE CS_PUBLIC ct_data_info( + CS_COMMAND *cmd, + CS_INT action, + CS_INT colnum, + CS_IODESC *iodesc + ); +/* ctwakeup.c */ +extern CS_RETCODE CS_PUBLIC ct_wakeup( + CS_CONNECTION *connection, + CS_COMMAND *cmd, + CS_INT func_id, + CS_RETCODE status + ); +/* ctsetlab.c */ +extern CS_RETCODE CS_PUBLIC ct_labels( + CS_CONNECTION *connection, + CS_INT action, + CS_CHAR *labelname, + CS_INT namelen, + CS_CHAR *labelvalue, + CS_INT valuelen, + CS_INT *outlen + ); +/* ctdsbrse.c */ +extern CS_RETCODE CS_PUBLIC ct_ds_lookup( + CS_CONNECTION *connection, + CS_INT action, + CS_INT *reqidp, + CS_DS_LOOKUP_INFO *lookupinfo, + CS_VOID *userdatap + ); +/* ctdsdrop.c */ +extern CS_RETCODE CS_PUBLIC ct_ds_dropobj( + CS_CONNECTION *connection, + CS_DS_OBJECT *object + ); +/* ctdsobji.c */ +extern CS_RETCODE CS_PUBLIC ct_ds_objinfo( + CS_DS_OBJECT *objclass, + CS_INT action, + CS_INT objinfo, + CS_INT number, + CS_VOID *buffer, + CS_INT buflen, + CS_INT *outlen + ); +/* ctsetpar.c */ +extern CS_RETCODE CS_PUBLIC ct_setparam( + CS_COMMAND *cmd, + CS_DATAFMT *datafmt, + CS_VOID *data, + CS_INT *datalenp, + CS_SMALLINT *indp + ); +CS_END_EXTERN_C + +#endif /* __CTPUBLIC_H__ */ diff --git a/libodbc/include/sybase/sqlca.h b/libodbc/include/sybase/sqlca.h new file mode 100644 index 0000000000..056c3aac34 --- /dev/null +++ b/libodbc/include/sybase/sqlca.h @@ -0,0 +1,40 @@ +/* +** Sybase OC-LIBRARY +** Confidential Property of Sybase, Inc. +** (c) Copyright Sybase, Inc. 1991 - 2005 +** All rights reserved +*/ + +/* +** sqlca.h - This is the header file for the sqlca structure for precompilers +*/ +#ifndef __SQLCA_H__ + +#define __SQLCA_H__ + +/***************************************************************************** +** +** sqlca structure used +** +*****************************************************************************/ + +typedef struct _sqlca +{ + char sqlcaid[8]; + long sqlcabc; + long sqlcode; + + struct + { + long sqlerrml; + char sqlerrmc[256]; + } sqlerrm; + + char sqlerrp[8]; + long sqlerrd[6]; + char sqlwarn[8]; + char sqlext[8]; + +} SQLCA; + +#endif /* __SQLCA_H__ */ diff --git a/libodbc/include/sybase/sqlda.h b/libodbc/include/sybase/sqlda.h new file mode 100644 index 0000000000..4fbfcd839e --- /dev/null +++ b/libodbc/include/sybase/sqlda.h @@ -0,0 +1,47 @@ +/* +** Sybase CT-LIBRARY +** Confidential Property of Sybase, Inc. +** (c) Copyright Sybase, Inc. 1995 - 2005 +** All rights reserved +** +*/ + +#ifndef __SQLDA_H__ +#define __SQLDA_H__ + +typedef struct _sqlda +{ + CS_SMALLINT sd_sqln; + CS_SMALLINT sd_sqld; + struct _sd_column + { + CS_DATAFMT sd_datafmt; + CS_VOID *sd_sqldata; + CS_SMALLINT sd_sqlind; + CS_INT sd_sqllen; + CS_VOID *sd_sqlmore; + } sd_column[1]; +} syb_sqlda; + +typedef syb_sqlda SQLDA; + +#define SYB_SQLDA_SIZE(n) (sizeof(SQLDA) \ + - sizeof(struct _sd_column) \ + + (n) * sizeof(struct _sd_column)) + +#ifndef SQLDA_DECL +#define SQLDA_DECL(name, size) \ +struct { \ + CS_SMALLINT sd_sqln; \ + CS_SMALLINT sd_sqld; \ + struct { \ + CS_DATAFMT sd_datafmt; \ + CS_VOID *sd_sqldata; \ + CS_SMALLINT sd_sqlind; \ + CS_INT sd_sqllen; \ + CS_VOID *sd_sqlmore; \ + } sd_column[(size)]; \ +} name +#endif /* SQLDA_DECL */ + +#endif /* __SQLDA_H__ */ diff --git a/libp2p/All.h b/libp2p/All.h new file mode 100644 index 0000000000..a461b96cbe --- /dev/null +++ b/libp2p/All.h @@ -0,0 +1,8 @@ +#pragma once + +#include "Common.h" +#include "HostCapability.h" +#include "Capability.h" +#include "Host.h" +#include "Session.h" + diff --git a/libp2p/CMakeLists.txt b/libp2p/CMakeLists.txt new file mode 100644 index 0000000000..7cc5b09cd1 --- /dev/null +++ b/libp2p/CMakeLists.txt @@ -0,0 +1,28 @@ +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") + +aux_source_directory(. SRC_LIST) + +file(GLOB HEADERS "*.h") + +add_library(p2p ${SRC_LIST} ${HEADERS}) + +eth_use(p2p OPTIONAL Miniupnpc) + +find_package(Dev) +include_directories(../libodbc/include + ../libodbc/include/db2_linux + ../libodbc/include/ibase + ../libodbc/include/infomix + ../libodbc/include/mysql + ../libodbc/include/odbc_linux + ../libodbc/include/pgsql + ../libodbc/include/sqlbase + ../libodbc/include/sqllite + ../libodbc/include/ss_linux + ../libodbc/include/sybase) + +target_include_directories(p2p PRIVATE ..) +target_link_libraries(p2p ${Dev_DEVCORE_LIBRARIES}) +target_link_libraries(p2p ${Dev_DEVCRYPTO_LIBRARIES}) + +install(TARGETS p2p RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib) diff --git a/libp2p/Capability.cpp b/libp2p/Capability.cpp new file mode 100644 index 0000000000..bab136bd99 --- /dev/null +++ b/libp2p/Capability.cpp @@ -0,0 +1,61 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Capability.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "Capability.h" + +#include +//#include +#include "Session.h" +#include "Host.h" +using namespace std; +using namespace dev; +using namespace dev::p2p; + +Capability::Capability(std::shared_ptr _s, HostCapabilityFace* _h, unsigned _idOffset, uint16_t _protocolID): + c_protocolID(_protocolID), m_session(_s), m_hostCap(_h), m_idOffset(_idOffset) +{ + LOG(WARNING) << "New session for capability" << m_hostCap->name() << "; idOffset:" << m_idOffset << "; protocolID:" << c_protocolID; +} + +void Capability::disable(std::string const& _problem) +{ + LOG(WARNING) << "DISABLE: Disabling capability '" << m_hostCap->name() << "'. Reason:" << _problem; + m_enabled = false; +} + +RLPStream& Capability::prep(RLPStream& _s, unsigned _id, unsigned _args) +{ + return _s.appendRaw(bytes(1, _id + m_idOffset)).appendList(_args); +} + +void Capability::sealAndSend(RLPStream& _s) +{ + shared_ptr session = m_session.lock(); + if (session) + session->sealAndSend(_s, c_protocolID); +} + +void Capability::addRating(int _r) +{ + shared_ptr session = m_session.lock(); + if (session) + session->addRating(_r); +} diff --git a/libp2p/Capability.h b/libp2p/Capability.h new file mode 100644 index 0000000000..6e5f85cc55 --- /dev/null +++ b/libp2p/Capability.h @@ -0,0 +1,70 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Capability.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include "Common.h" +#include "HostCapability.h" + +namespace dev +{ +namespace p2p +{ + +class ReputationManager; + +class Capability: public std::enable_shared_from_this +{ + friend class Session; + +public: + Capability(std::shared_ptr _s, HostCapabilityFace* _h, unsigned _idOffset, uint16_t _protocolID); + virtual ~Capability() {} + + // Implement these in the derived class. + /* static std::string name() { return ""; } + static u256 version() { return 0; } + static unsigned messageCount() { return 0; } + */ + std::shared_ptr session() const { return m_session.lock(); } + + HostCapabilityFace* hostCapability() const { return m_hostCap; } + + void disable(std::string const& _problem); + + RLPStream& prep(RLPStream& _s, unsigned _id, unsigned _args = 0); + void sealAndSend(RLPStream& _s); + void addRating(int _r); + +protected: + virtual bool interpret(unsigned _id, RLP const&) = 0; + + uint16_t const c_protocolID; + +private: + std::weak_ptr m_session; + HostCapabilityFace* m_hostCap; + bool m_enabled = true; + unsigned m_idOffset; +}; + +} +} diff --git a/libp2p/Common.cpp b/libp2p/Common.cpp new file mode 100644 index 0000000000..cbbba47cf9 --- /dev/null +++ b/libp2p/Common.cpp @@ -0,0 +1,267 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Common.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "Common.h" +#include "Network.h" +using namespace std; +using namespace dev; +using namespace dev::p2p; + +const unsigned dev::p2p::c_protocolVersion = 4; + unsigned dev::p2p::c_defaultIPPort = 16789; +static_assert(dev::p2p::c_protocolVersion == 4, "Replace v3 compatbility with v4 compatibility before updating network version."); + +const dev::p2p::NodeIPEndpoint dev::p2p::UnspecifiedNodeIPEndpoint = NodeIPEndpoint(bi::address(), 0, 0); +const dev::p2p::Node dev::p2p::UnspecifiedNode = dev::p2p::Node(NodeID(), UnspecifiedNodeIPEndpoint); + +bool dev::p2p::NodeIPEndpoint::test_allowLocal = false; + +//⊳⊲◀▶■▣▢□▷◁▧▨▩▲◆◉◈◇◎●◍◌○◼☑☒☎☢☣☰☀♽♥♠✩✭❓✔✓✖✕✘✓✔✅⚒⚡⦸⬌∅⁕«««»»»⚙━┅┉▬ + +#if defined(_WIN32) +const char* NetWarn::name() { return EthYellow "N" EthRed " X"; } +const char* NetImpolite::name() { return EthYellow "N" EthRed " !"; } +const char* NetNote::name() { return EthYellow "N" EthBlue " i"; } +const char* NetConnect::name() { return EthYellow "N" EthYellow " C"; } +const char* NetMessageSummary::name() { return EthYellow "N" EthWhite " ."; } +const char* NetMessageDetail::name() { return EthYellow "N" EthGray " o"; } +const char* NetTriviaSummary::name() { return EthYellow "N" EthGray " O"; } +const char* NetTriviaDetail::name() { return EthYellow "N" EthCoal " 0"; } +const char* NetAllDetail::name() { return EthYellow "N" EthCoal " A"; } +const char* NetRight::name() { return EthYellow "N" EthGreen "->"; } +const char* NetLeft::name() { return EthYellow "N" EthNavy "<-"; } +const char* NetP2PWarn::name() { return EthYellow "N" EthRed " X"; } +const char* NetP2PNote::name() { return EthYellow "N" EthBlue " i"; } +const char* NetP2PConnect::name() { return EthYellow "N" EthYellow " C"; } +#else +const char* NetWarn::name() { return EthYellow "⧎" EthRed " ✘"; } +const char* NetImpolite::name() { return EthYellow "⧎" EthRed " !"; } +const char* NetNote::name() { return EthYellow "⧎" EthBlue " ℹ"; } +const char* NetConnect::name() { return EthYellow "⧎" EthYellow " ▢"; } +const char* NetMessageSummary::name() { return EthYellow "⧎" EthWhite " ◌"; } +const char* NetMessageDetail::name() { return EthYellow "⧎" EthGray " ○"; } +const char* NetTriviaSummary::name() { return EthYellow "⧎" EthGray " ◎"; } +const char* NetTriviaDetail::name() { return EthYellow "⧎" EthCoal " ◍"; } +const char* NetAllDetail::name() { return EthYellow "⧎" EthCoal " ●"; } +const char* NetRight::name() { return EthYellow "⧎" EthGreen "▬▶"; } +const char* NetLeft::name() { return EthYellow "⧎" EthNavy "◀▬"; } +const char* NetP2PWarn::name() { return EthYellow "⧎" EthRed " ✘"; } +const char* NetP2PNote::name() { return EthYellow "⧎" EthBlue " ℹ"; } +const char* NetP2PConnect::name() { return EthYellow "⧎" EthYellow " ▢"; } +#endif + +bool p2p::isPublicAddress(std::string const& _addressToCheck) +{ + return _addressToCheck.empty() ? false : isPublicAddress(bi::address::from_string(_addressToCheck)); +} + +bool p2p::isPublicAddress(bi::address const& _addressToCheck) +{ + + return true; + return !(isPrivateAddress(_addressToCheck) || isLocalHostAddress(_addressToCheck)); +} + +// Helper function to determine if an address falls within one of the reserved ranges +// For V4: +// Class A "10.*", Class B "172.[16->31].*", Class C "192.168.*" +bool p2p::isPrivateAddress(bi::address const& _addressToCheck) +{ + if (_addressToCheck.is_v4()) + { + bi::address_v4 v4Address = _addressToCheck.to_v4(); + bi::address_v4::bytes_type bytesToCheck = v4Address.to_bytes(); + if (bytesToCheck[0] == 10 || bytesToCheck[0] == 127) + return true; + if (bytesToCheck[0] == 172 && (bytesToCheck[1] >= 16 && bytesToCheck[1] <= 31)) + return true; + if (bytesToCheck[0] == 192 && bytesToCheck[1] == 168) + return true; + } + else if (_addressToCheck.is_v6()) + { + bi::address_v6 v6Address = _addressToCheck.to_v6(); + bi::address_v6::bytes_type bytesToCheck = v6Address.to_bytes(); + if (bytesToCheck[0] == 0xfd && bytesToCheck[1] == 0) + return true; + if (!bytesToCheck[0] && !bytesToCheck[1] && !bytesToCheck[2] && !bytesToCheck[3] && !bytesToCheck[4] && !bytesToCheck[5] && !bytesToCheck[6] && !bytesToCheck[7] + && !bytesToCheck[8] && !bytesToCheck[9] && !bytesToCheck[10] && !bytesToCheck[11] && !bytesToCheck[12] && !bytesToCheck[13] && !bytesToCheck[14] && (bytesToCheck[15] == 0 || bytesToCheck[15] == 1)) + return true; + } + return false; +} + +bool p2p::isPrivateAddress(std::string const& _addressToCheck) +{ + return _addressToCheck.empty() ? false : isPrivateAddress(bi::address::from_string(_addressToCheck)); +} + +// Helper function to determine if an address is localhost +bool p2p::isLocalHostAddress(bi::address const& _addressToCheck) +{ + // @todo: ivp6 link-local adresses (macos), ex: fe80::1%lo0 + static const set c_rejectAddresses = { + {bi::address_v4::from_string("127.0.0.1")}, + {bi::address_v4::from_string("0.0.0.0")}, + {bi::address_v6::from_string("::1")}, + {bi::address_v6::from_string("::")} + }; + + return find(c_rejectAddresses.begin(), c_rejectAddresses.end(), _addressToCheck) != c_rejectAddresses.end(); +} + +bool p2p::isLocalHostAddress(std::string const& _addressToCheck) +{ + return _addressToCheck.empty() ? false : isLocalHostAddress(bi::address::from_string(_addressToCheck)); +} + +std::string p2p::reasonOf(DisconnectReason _r) +{ + switch (_r) + { + case DisconnectRequested: return "Disconnect was requested."; + case TCPError: return "Low-level TCP communication error."; + case BadProtocol: return "Data format error."; + case UselessPeer: return "Peer had no use for this node."; + case TooManyPeers: return "Peer had too many connections."; + case DuplicatePeer: return "Peer was already connected."; + case IncompatibleProtocol: return "Peer protocol versions are incompatible."; + case NullIdentity: return "Null identity given."; + case ClientQuit: return "Peer is exiting."; + case UnexpectedIdentity: return "Unexpected identity given."; + case LocalIdentity: return "Connected to ourselves."; + case UserReason: return "Subprotocol reason."; + case NoDisconnect: return "(No disconnect has happened.)"; + default: return "Unknown reason."; + } +} + +void NodeIPEndpoint::streamRLP(RLPStream& _s, RLPAppend _append) const +{ + if (_append == StreamList) + _s.appendList(3); + if (address.is_v4()) + _s << bytesConstRef(&address.to_v4().to_bytes()[0], 4); + else if (address.is_v6()) + _s << bytesConstRef(&address.to_v6().to_bytes()[0], 16); + else + _s << bytes(); + _s << udpPort << tcpPort; +} + +void NodeIPEndpoint::interpretRLP(RLP const& _r) +{ + if (_r[0].size() == 4) + address = bi::address_v4(*(bi::address_v4::bytes_type*)_r[0].toBytes().data()); + else if (_r[0].size() == 16) + address = bi::address_v6(*(bi::address_v6::bytes_type*)_r[0].toBytes().data()); + else + address = bi::address(); + udpPort = _r[1].toInt(); + tcpPort = _r[2].toInt(); +} + +void DeadlineOps::reap() +{ + if (m_stopped) + return; + + Guard l(x_timers); + std::vector::iterator t = m_timers.begin(); + while (t != m_timers.end()) + if (t->expired()) + { + t->wait(); + t = m_timers.erase(t); + } + else + t++; + + m_timers.emplace_back(m_io, m_reapIntervalMs, [this](boost::system::error_code const& ec) + { + if (!ec && !m_stopped) + reap(); + }); +} + +Node::Node(NodeSpec const& _s, PeerType _p): + id(_s.id()), + endpoint(_s.nodeIPEndpoint()), + peerType(_p) +{} + +NodeSpec::NodeSpec(string const& _user) +{ + m_address = _user; + if (m_address.substr(0, 8) == "enode://" && m_address.find('@') == 136) + { + m_id = p2p::NodeID(m_address.substr(8, 128)); + m_address = m_address.substr(137); + } + size_t colon = m_address.find_first_of(":"); + if (colon != string::npos) + { + string ports = m_address.substr(colon + 1); + m_address = m_address.substr(0, colon); + size_t p2 = ports.find_first_of("."); + if (p2 != string::npos) + { + m_udpPort = stoi(ports.substr(p2 + 1)); + m_tcpPort = stoi(ports.substr(0, p2)); + } + else + m_tcpPort = m_udpPort = stoi(ports); + } +} + +NodeIPEndpoint NodeSpec::nodeIPEndpoint() const +{ + return NodeIPEndpoint(p2p::Network::resolveHost(m_address).address(), m_udpPort, m_tcpPort); +} + +std::string NodeSpec::enode() const +{ + string ret = m_address; + + if (m_tcpPort) + if (m_udpPort && m_tcpPort != m_udpPort) + ret += ":" + toString(m_tcpPort) + "." + toString(m_udpPort); + else + ret += ":" + toString(m_tcpPort); + else if (m_udpPort) + ret += ":" + toString(m_udpPort); + + if (m_id) + return "enode://" + m_id.hex() + "@" + ret; + return ret; +} + +namespace dev +{ + +std::ostream& operator<<(std::ostream& _out, dev::p2p::NodeIPEndpoint const& _ep) +{ + _out << _ep.address << _ep.udpPort << _ep.tcpPort; + return _out; +} + +} + diff --git a/libp2p/Common.h b/libp2p/Common.h new file mode 100644 index 0000000000..6e3f569021 --- /dev/null +++ b/libp2p/Common.h @@ -0,0 +1,342 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Common.h + * @author Gav Wood + * @author Alex Leverington + * @date 2014 + * + * Miscellanea required for the Host/Session/NodeTable classes. + */ + +#pragma once + +#include +#include +#include + +// Make sure boost/asio.hpp is included before windows.h. +#include +#include + +#include +#include +#include +#include +#include +#include +namespace ba = boost::asio; +namespace bi = boost::asio::ip; + +namespace dev +{ + +class RLP; +class RLPStream; + +namespace p2p +{ + +/// Peer network protocol version. +extern const unsigned c_protocolVersion; +extern unsigned c_defaultIPPort; + +class NodeIPEndpoint; +class Node; +extern const NodeIPEndpoint UnspecifiedNodeIPEndpoint; +extern const Node UnspecifiedNode; + +using NodeID = h512; + +bool isPrivateAddress(bi::address const& _addressToCheck); +bool isPrivateAddress(std::string const& _addressToCheck); +bool isLocalHostAddress(bi::address const& _addressToCheck); +bool isLocalHostAddress(std::string const& _addressToCheck); +bool isPublicAddress(bi::address const& _addressToCheck); +bool isPublicAddress(std::string const& _addressToCheck); + +class UPnP; +class Capability; +class Host; +class Session; + +struct NetworkStartRequired: virtual dev::Exception {}; +struct InvalidPublicIPAddress: virtual dev::Exception {}; +struct InvalidHostIPAddress: virtual dev::Exception {}; + +struct NetWarn: public LogChannel { static const char* name(); static const int verbosity = 0; }; +struct NetNote: public LogChannel { static const char* name(); static const int verbosity = 2; }; +struct NetImpolite: public LogChannel { static const char* name(); static const int verbosity = 3; }; +struct NetMessageSummary: public LogChannel { static const char* name(); static const int verbosity = 4; }; +struct NetConnect: public LogChannel { static const char* name(); static const int verbosity = 10; }; +struct NetMessageDetail: public LogChannel { static const char* name(); static const int verbosity = 5; }; +struct NetTriviaSummary: public LogChannel { static const char* name(); static const int verbosity = 10; }; +struct NetTriviaDetail: public LogChannel { static const char* name(); static const int verbosity = 11; }; +struct NetAllDetail: public LogChannel { static const char* name(); static const int verbosity = 13; }; +struct NetRight: public LogChannel { static const char* name(); static const int verbosity = 14; }; +struct NetLeft: public LogChannel { static const char* name(); static const int verbosity = 15; }; +struct NetP2PWarn: public LogChannel { static const char* name(); static const int verbosity = 2; }; +struct NetP2PNote: public LogChannel { static const char* name(); static const int verbosity = 6; }; +struct NetP2PConnect: public LogChannel { static const char* name(); static const int verbosity = 10; }; + +enum PacketType +{ + HelloPacket = 0, + DisconnectPacket, + PingPacket, + PongPacket, + GetPeersPacket, + PeersPacket, + UserPacket = 0x10 +}; + +enum DisconnectReason +{ + DisconnectRequested = 0, + TCPError, + BadProtocol, + UselessPeer, + TooManyPeers, + DuplicatePeer, + IncompatibleProtocol, + NullIdentity, + ClientQuit, + UnexpectedIdentity, + LocalIdentity, + PingTimeout, + UserReason = 0x10, + NoDisconnect = 0xffff +}; + +inline bool isPermanentProblem(DisconnectReason _r) +{ + switch (_r) + { + case DuplicatePeer: + case IncompatibleProtocol: + case NullIdentity: + case UnexpectedIdentity: + case LocalIdentity: + return true; + default: + return false; + } +} + +/// @returns the string form of the given disconnection reason. +std::string reasonOf(DisconnectReason _r); + +using CapDesc = std::pair; +using CapDescSet = std::set; +using CapDescs = std::vector; + +/* + * Used by Host to pass negotiated information about a connection to a + * new Peer Session; PeerSessionInfo is then maintained by Session and can + * be queried for point-in-time status information via Host. + */ +struct PeerSessionInfo +{ + NodeID const id; + std::string const clientVersion; + std::string const host; + unsigned short const port; + std::chrono::steady_clock::duration lastPing; + std::set const caps; + unsigned socketId; + std::map notes; + unsigned const protocolVersion; +}; + +using PeerSessionInfos = std::vector; + +enum class PeerType +{ + Optional, + Required +}; + +/** + * @brief IPv4,UDP/TCP endpoints. + */ +class NodeIPEndpoint +{ +public: + enum RLPAppend + { + StreamList, + StreamInline + }; + + /// Setting true causes isAllowed to return true for all addresses. (Used by test fixtures) + static bool test_allowLocal; + + NodeIPEndpoint() = default; + NodeIPEndpoint(bi::address _addr, uint16_t _udp, uint16_t _tcp): address(_addr), udpPort(_udp), tcpPort(_tcp) {} + NodeIPEndpoint(RLP const& _r) { interpretRLP(_r); } + + operator bi::udp::endpoint() const { return bi::udp::endpoint(address, udpPort); } + operator bi::tcp::endpoint() const { return bi::tcp::endpoint(address, tcpPort); } + + operator bool() const { return !address.is_unspecified() && udpPort > 0 && tcpPort > 0; } + + bool isAllowed() const + { + return NodeIPEndpoint::test_allowLocal ? !address.is_unspecified() : isPublicAddress(address); + } + + bool operator==(NodeIPEndpoint const& _cmp) const { + return address == _cmp.address && udpPort == _cmp.udpPort && tcpPort == _cmp.tcpPort; + } + bool operator!=(NodeIPEndpoint const& _cmp) const { + return !operator==(_cmp); + } + + void streamRLP(RLPStream& _s, RLPAppend _append = StreamList) const; + void interpretRLP(RLP const& _r); + + // TODO: make private, give accessors and rename m_... + bi::address address; + uint16_t udpPort = 0; + uint16_t tcpPort = 0; +}; + +struct NodeSpec +{ + NodeSpec() {} + + /// Accepts user-readable strings of the form (enode://pubkey@)host({:port,:tcpport.udpport}) + NodeSpec(std::string const& _user); + + NodeSpec(std::string const& _addr, uint16_t _port, int _udpPort = -1): + m_address(_addr), + m_tcpPort(_port), + m_udpPort(_udpPort == -1 ? _port : (uint16_t)_udpPort) + {} + + NodeID id() const { return m_id; } + + NodeIPEndpoint nodeIPEndpoint() const; + + std::string enode() const; + +private: + std::string m_address; + uint16_t m_tcpPort = 0; + uint16_t m_udpPort = 0; + NodeID m_id; +}; + +class Node +{ +public: + Node() = default; + Node(Node const&) = default; + Node(Public _publicKey, NodeIPEndpoint const& _ip, PeerType _peerType = PeerType::Optional): id(_publicKey), endpoint(_ip), peerType(_peerType) {} + Node(NodeSpec const& _s, PeerType _peerType = PeerType::Optional); + + virtual NodeID const& address() const { return id; } + virtual Public const& publicKey() const { return id; } + + virtual operator bool() const { return (bool)id; } + + // TODO: make private, give accessors and rename m_... + NodeID id; + + /// Endpoints by which we expect to reach node. + // TODO: make private, give accessors and rename m_... + NodeIPEndpoint endpoint; + + // TODO: p2p implement + PeerType peerType = PeerType::Optional; +}; + +class DeadlineOps +{ + class DeadlineOp + { + public: + DeadlineOp(ba::io_service& _io, unsigned _msInFuture, std::function const& _f): m_timer(new ba::deadline_timer(_io)) { m_timer->expires_from_now(boost::posix_time::milliseconds(_msInFuture)); m_timer->async_wait(_f); } + ~DeadlineOp() { if (m_timer) m_timer->cancel(); } + + DeadlineOp(DeadlineOp&& _s): m_timer(_s.m_timer.release()) {} + DeadlineOp& operator=(DeadlineOp&& _s) + { + assert(&_s != this); + + m_timer.reset(_s.m_timer.release()); + return *this; + } + + bool expired() { Guard l(x_timer); return m_timer->expires_from_now().total_nanoseconds() <= 0; } + void wait() { Guard l(x_timer); m_timer->wait(); } + + private: + std::unique_ptr m_timer; + Mutex x_timer; + }; + +public: + DeadlineOps(ba::io_service& _io, unsigned _reapIntervalMs = 100): m_io(_io), m_reapIntervalMs(_reapIntervalMs), m_stopped(false) { reap(); } + ~DeadlineOps() { stop(); } + + void schedule(unsigned _msInFuture, std::function const& _f) { if (m_stopped) return; DEV_GUARDED(x_timers) m_timers.emplace_back(m_io, _msInFuture, _f); } + + void stop() { m_stopped = true; DEV_GUARDED(x_timers) m_timers.clear(); } + + bool isStopped() const { return m_stopped; } + +protected: + void reap(); + +private: + ba::io_service& m_io; + unsigned m_reapIntervalMs; + + std::vector m_timers; + Mutex x_timers; + + std::atomic m_stopped; +}; + +} + +/// Simple stream output for a NodeIPEndpoint. +std::ostream& operator<<(std::ostream& _out, dev::p2p::NodeIPEndpoint const& _ep); +} + +/// std::hash for asio::adress +namespace std +{ + +template <> struct hash +{ + size_t operator()(bi::address const& _a) const + { + if (_a.is_v4()) + return std::hash()(_a.to_v4().to_ulong()); + if (_a.is_v6()) + { + auto const& range = _a.to_v6().to_bytes(); + return boost::hash_range(range.begin(), range.end()); + } + if (_a.is_unspecified()) + return static_cast(0x3487194039229152ull); // Chosen by fair dice roll, guaranteed to be random + return std::hash()(_a.to_string()); + } +}; + +} diff --git a/libp2p/HandshakeCAData.cpp b/libp2p/HandshakeCAData.cpp new file mode 100644 index 0000000000..b62b8332a8 --- /dev/null +++ b/libp2p/HandshakeCAData.cpp @@ -0,0 +1,14 @@ +#include "HandshakeCAData.h" + +using namespace dev; +using namespace dev::p2p; + +void RLPBaseData::setSeed(bytes seed) +{ + seed.swap(m_seed); +} + +bytes & RLPBaseData::getSeed() +{ + return m_seed; +} diff --git a/libp2p/HandshakeCAData.h b/libp2p/HandshakeCAData.h new file mode 100644 index 0000000000..e8d6d9d325 --- /dev/null +++ b/libp2p/HandshakeCAData.h @@ -0,0 +1,18 @@ + +#pragma once +#include +#include "Common.h" + +namespace dev { + namespace p2p { + class RLPBaseData { + public: + void setSeed(bytes seed); + + bytes &getSeed(); + + private: + bytes m_seed; + }; + } +} diff --git a/libp2p/HandshakeWBCAData.cpp b/libp2p/HandshakeWBCAData.cpp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/libp2p/HandshakeWBCAData.h b/libp2p/HandshakeWBCAData.h new file mode 100644 index 0000000000..7120be74ff --- /dev/null +++ b/libp2p/HandshakeWBCAData.h @@ -0,0 +1,15 @@ + +#pragma once +#include "HandshakeCAData.h" + +namespace dev +{ + namespace p2p + { + class WBRLPBaseData : public RLPBaseData + { + + }; + + } +} diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp new file mode 100644 index 0000000000..69bbaa5f2a --- /dev/null +++ b/libp2p/Host.cpp @@ -0,0 +1,1179 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Host.cpp + * @author Alex Leverington + * @author Gav Wood + * @date 2014 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Session.h" +#include "Common.h" +#include "Capability.h" +#include "UPnP.h" +#include "RLPxHandshake.h" +#include "SessionWBCAData.h" +#include "Host.h" +using namespace std; +using namespace dev; +using namespace dev::p2p; +using namespace dev::eth; +using namespace dev::crypto; + +/// Interval at which Host::run will call keepAlivePeers to ping peers. +std::chrono::seconds const c_keepAliveInterval = std::chrono::seconds(30); +std::chrono::seconds const c_reconnectNodesInterval = std::chrono::seconds(60); + +/// Disconnect timeout after failure to respond to keepAlivePeers ping. +std::chrono::milliseconds const c_keepAliveTimeOut = std::chrono::milliseconds(1000); + +void tickFun(const boost::system::error_code& _e, boost::asio::deadline_timer *_timer, unsigned _t, std::function _fun) +{ + (void)_e; + + _fun(); + + _timer->expires_from_now(boost::posix_time::milliseconds(_t)); + _timer->async_wait(boost::bind(tickFun, boost::asio::placeholders::error, _timer, _t, _fun)); +} + +HostNodeTableHandler::HostNodeTableHandler(Host& _host): m_host(_host) {} + +void HostNodeTableHandler::processEvent(NodeID const& _n, NodeTableEventType const& _e) +{ + m_host.onNodeTableEvent(_n, _e); +} + +ReputationManager::ReputationManager() +{ +} + +void ReputationManager::noteRude(SessionFace const& _s, std::string const& _sub) +{ + DEV_WRITE_GUARDED(x_nodes) + m_nodes[make_pair(_s.id(), _s.info().clientVersion)].subs[_sub].isRude = true; +} + +bool ReputationManager::isRude(SessionFace const& _s, std::string const& _sub) const +{ + DEV_READ_GUARDED(x_nodes) + { + auto nit = m_nodes.find(make_pair(_s.id(), _s.info().clientVersion)); + if (nit == m_nodes.end()) + return false; + auto sit = nit->second.subs.find(_sub); + bool ret = sit == nit->second.subs.end() ? false : sit->second.isRude; + return _sub.empty() ? ret : (ret || isRude(_s)); + } + return false; +} + +void ReputationManager::setData(SessionFace const& _s, std::string const& _sub, bytes const& _data) +{ + DEV_WRITE_GUARDED(x_nodes) + m_nodes[make_pair(_s.id(), _s.info().clientVersion)].subs[_sub].data = _data; +} + +bytes ReputationManager::data(SessionFace const& _s, std::string const& _sub) const +{ + DEV_READ_GUARDED(x_nodes) + { + auto nit = m_nodes.find(make_pair(_s.id(), _s.info().clientVersion)); + if (nit == m_nodes.end()) + return bytes(); + auto sit = nit->second.subs.find(_sub); + return sit == nit->second.subs.end() ? bytes() : sit->second.data; + } + return bytes(); +} + +Host::Host(string const& _clientVersion, KeyPair const& _alias, NetworkPreferences const& _n): + Worker("p2p", 0), + m_clientVersion(_clientVersion), + m_netPrefs(_n), + m_ifAddresses(Network::getInterfaceAddresses()), + m_ioService(2), + m_tcp4Acceptor(m_ioService), + m_alias(_alias), + m_lastPing(chrono::steady_clock::time_point::min()), + m_lastReconnect(chrono::steady_clock::time_point::min()) +{ + clog(NetNote) << "Id:" << id(); +} + +Host::Host(string const& _clientVersion, NetworkPreferences const& _n, bytesConstRef _restoreNetwork): + Host(_clientVersion, networkAlias(_restoreNetwork), _n) +{ + m_restoreNetwork = _restoreNetwork.toBytes(); +} + +Host::~Host() +{ + stop(); +} + +void Host::start() +{ + DEV_TIMED_FUNCTION_ABOVE(500); + startWorking();//启动work循环 + while (isWorking() && !haveNetwork()) + this_thread::sleep_for(chrono::milliseconds(10)); + + // network start failed! + if (isWorking()) + return; + + clog(NetWarn) << "Network start failed!"; + doneWorking(); +} + +void Host::stop() +{ + // called to force io_service to kill any remaining tasks it might have - + // such tasks may involve socket reads from Capabilities that maintain references + // to resources we're about to free. + + { + // Although m_run is set by stop() or start(), it effects m_runTimer so x_runTimer is used instead of a mutex for m_run. + Guard l(x_runTimer); + // ignore if already stopped/stopping + if (!m_run) + return; + + // signal run() to prepare for shutdown and reset m_timer + m_run = false; + } + + // wait for m_timer to reset (indicating network scheduler has stopped) + while (!!m_timer) + this_thread::sleep_for(chrono::milliseconds(50)); + + // stop worker thread + if (isWorking()) + stopWorking(); +} + +void Host::doneWorking() +{ + // reset ioservice (cancels all timers and allows manually polling network, below) + m_ioService.reset(); + + DEV_GUARDED(x_timers) + m_timers.clear(); + + // shutdown acceptor + m_tcp4Acceptor.cancel(); + if (m_tcp4Acceptor.is_open()) + m_tcp4Acceptor.close(); + + // There maybe an incoming connection which started but hasn't finished. + // Wait for acceptor to end itself instead of assuming it's complete. + // This helps ensure a peer isn't stopped at the same time it's starting + // and that socket for pending connection is closed. + while (m_accepting) + m_ioService.poll(); + + // stop capabilities (eth: stops syncing or block/tx broadcast) + for (auto const& h : m_capabilities) + h.second->onStopping(); + + // disconnect pending handshake, before peers, as a handshake may create a peer + for (unsigned n = 0;; n = 0) + { + DEV_GUARDED(x_connecting) + for (auto const& i : m_connecting) + if (auto h = i.lock()) + { + h->cancel(); + n++; + } + if (!n) + break; + m_ioService.poll(); + } + + // disconnect peers + for (unsigned n = 0;; n = 0) + { + DEV_RECURSIVE_GUARDED(x_sessions) + for (auto i : m_sessions) + if (auto p = i.second.lock()) + if (p->isConnected()) + { + p->disconnect(ClientQuit); + n++; + } + if (!n) + break; + + // poll so that peers send out disconnect packets + m_ioService.poll(); + } + + // stop network (again; helpful to call before subsequent reset()) + m_ioService.stop(); + + // reset network (allows reusing ioservice in future) + m_ioService.reset(); + + // finally, clear out peers (in case they're lingering) + RecursiveGuard l(x_sessions); + m_sessions.clear(); +} + +void Host::startPeerSession(Public const& _id, RLP const& _rlp, unique_ptr&& _io, std::shared_ptr const& _s, RLPBaseData &rlpBaseData) +{ + // session maybe ingress or egress so m_peers and node table entries may not exist + shared_ptr p; + DEV_RECURSIVE_GUARDED(x_sessions) + { + if (m_peers.count(_id)) + p = m_peers[_id]; + else + { + // peer doesn't exist, try to get port info from node table + if (m_nodeTable) + if (Node n = m_nodeTable->node(_id)) + p = make_shared(n); + + if (!p) + p = make_shared(Node(_id, UnspecifiedNodeIPEndpoint)); + + m_peers[_id] = p; + } + } + if (p->isOffline()) + p->m_lastConnected = std::chrono::system_clock::now(); + p->endpoint.address = _s->remoteEndpoint().address(); + + auto protocolVersion = _rlp[0].toInt(); + auto clientVersion = _rlp[1].toString(); + auto caps = _rlp[2].toVector(); + auto listenPort = _rlp[3].toInt(); + auto pub = _rlp[4].toHash(); + if (pub != _id) + { + LOG(DEBUG) << "Wrong ID: " << pub << " vs. " << _id; + return; + } + + // clang error (previously: ... << hex << caps ...) + // "'operator<<' should be declared prior to the call site or in an associated namespace of one of its arguments" + stringstream capslog; + + // leave only highset mutually supported capability version + caps.erase(remove_if(caps.begin(), caps.end(), [&](CapDesc const & _r) { return !haveCapability(_r) || any_of(caps.begin(), caps.end(), [&](CapDesc const & _o) { return _r.first == _o.first && _o.second > _r.second && haveCapability(_o); }); }), caps.end()); + + for (auto cap : caps) + capslog << "(" << cap.first << "," << dec << cap.second << ")"; + + clog(NetMessageSummary) << "Hello: " << clientVersion << "V[" << protocolVersion << "]" << _id << showbase << capslog.str() << dec << listenPort; + + // create session so disconnects are managed + shared_ptr ps = make_shared(this, move(_io), _s, p, PeerSessionInfo({_id, clientVersion, p->endpoint.address.to_string(), listenPort, chrono::steady_clock::duration(), _rlp[2].toSet(), 0, map(), protocolVersion})); + if (protocolVersion < dev::p2p::c_protocolVersion - 1) + { + ps->disconnect(IncompatibleProtocol); + return; + } + if (caps.empty()) + { + ps->disconnect(UselessPeer); + return; + } + + if (m_netPrefs.pin && !m_requiredPeers.count(_id)) + { + LOG(DEBUG) << "Unexpected identity from peer (got" << _id << ", must be one of " << m_requiredPeers << ")"; + ps->disconnect(UnexpectedIdentity); + return; + } + + //对协议进行定制化的解析 + WBCAData wbcaData; + bool ok = NodeConnManagerSingleton::GetInstance().CheckAndSerialize(_rlp, rlpBaseData, wbcaData); + if (!ok) + { + ps->disconnect(UnexpectedIdentity); + return; + } + + { + RecursiveGuard l(x_sessions); + if (m_sessions.count(_id) && !!m_sessions[_id].lock()) + if (auto s = m_sessions[_id].lock()) + if (s->isConnected()) + { + // Already connected. + clog(NetWarn) << "Session already exists for peer with id" << _id; + ps->disconnect(DuplicatePeer); + return; + } + + if (!peerSlotsAvailable()) + { + ps->disconnect(TooManyPeers); + return; + } + + unsigned offset = (unsigned)UserPacket; + uint16_t cnt = 1; + + // todo: mutex Session::m_capabilities and move for(:caps) out of mutex. + for (auto const& i : caps) + { + auto pcap = m_capabilities[i]; + if (!pcap) + return ps->disconnect(IncompatibleProtocol); + + if (Session::isFramingAllowedForVersion(protocolVersion)) + pcap->newPeerCapability(ps, 0, i, cnt++); + else + { + pcap->newPeerCapability(ps, offset, i, 0); + //里面会调用ps的newPeerCapability + //也会调用EthereumPeer的init lim 里面会发个StatusPacket包 + offset += pcap->messageCount(); + } + } + + ps->start();//启动session 发个ping包 + m_sessions[_id] = ps; + } + + NodeConnManagerSingleton::GetInstance().SaveCADataInSession(ps->id().hex(), wbcaData); + clog(NetP2PNote) << "p2p.host.peer.register" << _id; +} + +void Host::onNodeTableEvent(NodeID const& _n, NodeTableEventType const& _e) +{ + if (_e == NodeEntryAdded) + { + clog(NetP2PNote) << "p2p.host.nodeTable.events.nodeEntryAdded " << _n; + // only add iff node is in node table + if (Node n = m_nodeTable->node(_n)) + { + shared_ptr p; + DEV_RECURSIVE_GUARDED(x_sessions) + { + if (m_peers.count(_n)) + { + p = m_peers[_n]; + p->endpoint = n.endpoint; + } + else + { + p = make_shared(n); + m_peers[_n] = p; + clog(NetP2PNote) << "p2p.host.peers.events.peerAdded " << _n << p->endpoint; + } + } + if (peerSlotsAvailable(Egress)) + connect(p); + } + } + else if (_e == NodeEntryDropped) + { + clog(NetP2PNote) << "p2p.host.nodeTable.events.NodeEntryDropped " << _n; + RecursiveGuard l(x_sessions); + if (m_peers.count(_n) && m_peers[_n]->peerType == PeerType::Optional) + m_peers.erase(_n); + } +} + +void Host::determinePublic() +{ + // set m_tcpPublic := listenIP (if public) > public > upnp > unspecified address. + + auto ifAddresses = Network::getInterfaceAddresses(); + auto laddr = m_netPrefs.listenIPAddress.empty() ? bi::address() : bi::address::from_string(m_netPrefs.listenIPAddress); + auto lset = !laddr.is_unspecified(); + auto paddr = m_netPrefs.publicIPAddress.empty() ? bi::address() : bi::address::from_string(m_netPrefs.publicIPAddress); + auto pset = !paddr.is_unspecified(); + + bool listenIsPublic = lset && isPublicAddress(laddr); + bool publicIsHost = !lset && pset && ifAddresses.count(paddr); + + bi::tcp::endpoint ep(bi::address(), m_listenPort); + if (m_netPrefs.traverseNAT && listenIsPublic) + { + clog(NetNote) << "Listen address set to Public address:" << laddr << ". UPnP disabled."; + ep.address(laddr); + } + else if (m_netPrefs.traverseNAT && publicIsHost) + { + clog(NetNote) << "Public address set to Host configured address:" << paddr << ". UPnP disabled."; + ep.address(paddr); + } + else if (m_netPrefs.traverseNAT) + { + bi::address natIFAddr; + ep = Network::traverseNAT(lset && ifAddresses.count(laddr) ? std::set({laddr}) : ifAddresses, m_listenPort, natIFAddr); + + if (lset && natIFAddr != laddr) + // if listen address is set, Host will use it, even if upnp returns different + clog(NetWarn) << "Listen address" << laddr << "differs from local address" << natIFAddr << "returned by UPnP!"; + + if (pset && ep.address() != paddr) + { + // if public address is set, Host will advertise it, even if upnp returns different + clog(NetWarn) << "Specified public address" << paddr << "differs from external address" << ep.address() << "returned by UPnP!"; + ep.address(paddr); + } + } + else if (pset) + ep.address(paddr); + + m_tcpPublic = ep; +} + +void Host::runAcceptor() +{ + assert(m_listenPort > 0); + + if (m_run && !m_accepting) + { + clog(NetConnect) << "Listening on local port " << m_listenPort << " (public: " << m_tcpPublic << ")"; + m_accepting = true; + + auto socket = make_shared(m_ioService); + //设置匿名函数给监听是进行socket连接 + m_tcp4Acceptor.async_accept(socket->ref(), [ = ](boost::system::error_code ec) + { + m_accepting = false; + if (ec || !m_run) + { + socket->close(); + return; + } + if (peerCount() > peerSlots(Ingress)) + { + clog(NetConnect) << "Dropping incoming connect due to maximum peer count (" << Ingress << " * ideal peer count): " << socket->remoteEndpoint(); + socket->close(); + if (ec.value() < 1) + runAcceptor(); + return; + } + + bool success = false; + try + { + // incoming connection; we don't yet know nodeid + auto handshake = make_shared(this, socket); + m_connecting.push_back(handshake); + handshake->start();//握手成功后startPeerSession + success = true; + } + catch (Exception const& _e) + { + clog(NetWarn) << "ERROR: " << diagnostic_information(_e); + } + catch (std::exception const& _e) + { + clog(NetWarn) << "ERROR: " << _e.what(); + } + + if (!success) + socket->ref().close(); + runAcceptor(); //重复接客 + }); + } +} + +std::unordered_map Host::pocHosts() +{ + return { + }; +} + +void Host::addPeer(NodeSpec const& _s, PeerType _t) +{ + LOG(TRACE)<<"Host::addPeer"<<_s.enode(); + + if (_t == PeerType::Optional) + { + LOG(TRACE)<<"Host::addPeer Optional"; + addNode(_s.id(), _s.nodeIPEndpoint()); + } + else + { + LOG(TRACE)<<"Host::addPeer Required"; + requirePeer(_s.id(), _s.nodeIPEndpoint()); + } + +} + +void Host::addNode(NodeID const& _node, NodeIPEndpoint const& _endpoint) +{ + // return if network is stopped while waiting on Host::run() or nodeTable to start + while (!haveNetwork()) + if (isWorking()) + this_thread::sleep_for(chrono::milliseconds(50)); + else + return; + + if (_endpoint.tcpPort < 30300 || _endpoint.tcpPort > 30305) + clog(NetConnect) << "Non-standard port being recorded: " << _endpoint.tcpPort; + + if (m_nodeTable) + m_nodeTable->addNode(Node(_node, _endpoint)); +} + +void Host::requirePeer(NodeID const& _n, NodeIPEndpoint const& _endpoint) +{ + LOG(TRACE)<<"Host::requirePeer"<<_n; + + m_requiredPeers.insert(_n); + + if (!m_run) + return; + + Node node(_n, _endpoint, PeerType::Required); + if (_n) + { + // create or update m_peers entry + shared_ptr p; + DEV_RECURSIVE_GUARDED(x_sessions) + if (m_peers.count(_n)) + { + p = m_peers[_n]; + p->endpoint = node.endpoint; + p->peerType = PeerType::Required; + } + else + { + p = make_shared(node); + m_peers[_n] = p; + } + // required for discovery + if (m_nodeTable) + m_nodeTable->addNode(*p, NodeTable::NodeRelation::Known);//不用discover + } + else if (m_nodeTable) + { + m_nodeTable->addNode(node); + auto t = make_shared(m_ioService); + t->expires_from_now(boost::posix_time::milliseconds(600)); + t->async_wait([this, _n](boost::system::error_code const & _ec) + { + if (!_ec) + if (m_nodeTable) + if (auto n = m_nodeTable->node(_n)) + requirePeer(n.id, n.endpoint); + }); + DEV_GUARDED(x_timers) + m_timers.push_back(t); + } +} + +void Host::relinquishPeer(NodeID const& _node) +{ + Guard l(x_requiredPeers); + if (m_requiredPeers.count(_node)) + m_requiredPeers.erase(_node); +} + +void Host::connect(std::shared_ptr const& _p) +{ + if (!m_run) + return; + + if (havePeerSession(_p->id)) + { + clog(NetConnect) << "Aborted connect. Node already connected."; + return; + } + + if (!!m_nodeTable && !m_nodeTable->haveNode(_p->id) && _p->peerType == PeerType::Optional) + return; + + // prevent concurrently connecting to a node + Peer *nptr = _p.get(); + { + Guard l(x_pendingNodeConns); + if (m_pendingPeerConns.count(nptr)) + return; + m_pendingPeerConns.insert(nptr); + } + + _p->m_lastAttempted = std::chrono::system_clock::now(); + + bi::tcp::endpoint ep(_p->endpoint); + clog(NetConnect) << "Attempting connection to node" << _p->id << "@" << ep << "from" << id(); + auto socket = make_shared(m_ioService); + socket->ref().async_connect(ep, [ = ](boost::system::error_code const & ec) + { + _p->m_lastAttempted = std::chrono::system_clock::now(); + _p->m_failedAttempts++; + + if (ec) + { + clog(NetConnect) << "Connection refused to node" << _p->id << "@" << ep << "(" << ec.message() << ")"; + // Manually set error (session not present) + _p->m_lastDisconnect = TCPError; + } + else + { + clog(NetConnect) << "Connecting to" << _p->id << "@" << ep; + auto handshake = make_shared(this, socket, _p->id); + { + Guard l(x_connecting); + m_connecting.push_back(handshake); + } + + handshake->start(); + } + + Guard l(x_pendingNodeConns); + m_pendingPeerConns.erase(nptr); + }); +} + +PeerSessionInfos Host::peerSessionInfo() const +{ + if (!m_run) + return PeerSessionInfos(); + + std::vector ret; + RecursiveGuard l(x_sessions); + for (auto& i : m_sessions) + if (auto j = i.second.lock()) + if (j->isConnected()) + ret.push_back(j->info()); + return ret; +} + + +size_t Host::peerCount() const +{ + unsigned retCount = 0; + RecursiveGuard l(x_sessions); + for (auto& i : m_sessions) + if (std::shared_ptr j = i.second.lock()) + if (j->isConnected()) + retCount++; + return retCount; +} + +bool Host::onInit(std::function _fun) +{ + boost::asio::deadline_timer timer(m_ioService, boost::posix_time::milliseconds(0)); + timer.async_wait(boost::bind(_fun)); + + return true; +} + +bool Host::onTick(unsigned _t, std::function _fun) +{ + boost::asio::deadline_timer *timer = new boost::asio::deadline_timer(m_ioService, boost::posix_time::milliseconds(_t)); + timer->async_wait(boost::bind(tickFun, boost::asio::placeholders::error, timer, _t, _fun)); + + return true; +} + +void Host::run(boost::system::error_code const&) +{ + if (!m_run) + { + // reset NodeTable + m_nodeTable.reset(); + + // stopping io service allows running manual network operations for shutdown + // and also stops blocking worker thread, allowing worker thread to exit + m_ioService.stop(); + + // resetting timer signals network that nothing else can be scheduled to run + m_timer.reset(); + return; + } + + m_nodeTable->processEvents();// 定时循环 回来处理事件 + + // cleanup zombies + DEV_GUARDED(x_connecting) + m_connecting.remove_if([](std::weak_ptr h) { return h.expired(); }); + DEV_GUARDED(x_timers) + m_timers.remove_if([](std::shared_ptr t) + { + return t->expires_from_now().total_milliseconds() < 0; + }); + + keepAlivePeers(); + + // At this time peers will be disconnected based on natural TCP timeout. + // disconnectLatePeers needs to be updated for the assumption that Session + // is always live and to ensure reputation and fallback timers are properly + // updated. // disconnectLatePeers(); + + // todo: update peerSlotsAvailable() + + /* + list> toConnect; + unsigned reqConn = 0; + { + RecursiveGuard l(x_sessions); + for (auto const& p : m_peers) + { + bool haveSession = havePeerSession(p.second->id); + bool required = p.second->peerType == PeerType::Required; + if (haveSession && required) + reqConn++; + else if (!haveSession && p.second->shouldReconnect() && (!m_netPrefs.pin || required)) + toConnect.push_back(p.second); + } + } + + for (auto p : toConnect) + if (p->peerType == PeerType::Required && reqConn++ < m_idealPeerCount) + connect(p); + + + if (!m_netPrefs.pin) + { + unsigned pendingCount = 0; + DEV_GUARDED(x_pendingNodeConns) + pendingCount = m_pendingPeerConns.size(); + int openSlots = m_idealPeerCount - peerCount() - pendingCount + reqConn; + if (openSlots > 0) + for (auto p : toConnect) + if (p->peerType == PeerType::Optional && openSlots--) + connect(p); + } + */ + + //查看是否所有节点已经连接 如果断掉则进行连接 + reconnectAllNodes(); + + auto runcb = [this](boost::system::error_code const & error) { run(error); }; + m_timer->expires_from_now(boost::posix_time::milliseconds(c_timerInterval)); + m_timer->async_wait(runcb); //不断回调run() +} + +//work dowork循环之前,先执行这个 +void Host::startedWorking() +{ + asserts(!m_timer); + + { + // prevent m_run from being set to true at same time as set to false by stop() + // don't release mutex until m_timer is set so in case stop() is called at same + // time, stop will wait on m_timer and graceful network shutdown. + Guard l(x_runTimer); + // create deadline timer + m_timer.reset(new boost::asio::deadline_timer(m_ioService)); + m_run = true; + } + //在调这里之前Client初始化的时候已经将EthereumHost注册进来registerCapability + // start capability threads (ready for incoming connections) + //进行连接 根据已连接的状态值进行连接 + for (auto const& h : m_capabilities) + h.second->onStarting();// 启动多个线程 + + // try to open acceptor (todo: ipv6) + //已经进行bind和listen + int port = Network::tcp4Listen(m_tcp4Acceptor, m_netPrefs); + if (port > 0) + { + m_listenPort = port; + determinePublic(); + runAcceptor(); //开始接客 + } + else + { + clog(NetP2PNote) << "p2p.start.notice id:" << id() << "TCP Listen port is invalid or unavailable."; + std::cout<<"P2pPort 绑定失败!"<( + m_ioService, + m_alias, + NodeIPEndpoint(bi::address::from_string(listenAddress()), listenPort(), listenPort()), + m_netPrefs.discovery + ); + nodeTable->setEventHandler(new HostNodeTableHandler(*this)); + //将配置文件中的连接节点传入nodeTable中去 + m_nodeTable = nodeTable; + restoreNetwork(&m_restoreNetwork); + + clog(NetP2PNote) << "p2p.started id:" << id(); + + run(boost::system::error_code());//第一次执行 +} + +void Host::doWork() +{ + try + { + if (m_run) + m_ioService.run(); + } + catch (std::exception const& _e) + { + clog(NetP2PWarn) << "Exception in Network Thread:" << _e.what(); + clog(NetP2PWarn) << "Network Restart is Recommended."; + } +} + +void Host::keepAlivePeers() +{ + if (chrono::steady_clock::now() - c_keepAliveInterval < m_lastPing) + return; + + RecursiveGuard l(x_sessions); + for (auto it = m_sessions.begin(); it != m_sessions.end();) { + if (auto p = it->second.lock()) + { + p->ping(); + ++it; + } + else { + clog(NetWarn) << "Host::keepAlivePeers erase " << it->first; + it = m_sessions.erase(it); + } + } + + m_lastPing = chrono::steady_clock::now(); +} + +void Host::reconnectAllNodes() +{ + if (chrono::steady_clock::now() - c_reconnectNodesInterval < m_lastReconnect) + return; + + //使用合约和配置文件的全部数据 + std::map mNodeConnParams; + NodeConnManagerSingleton::GetInstance().getAllNodeConnInfoContractAndConf(mNodeConnParams); + + RecursiveGuard l(x_sessions); + //检查配置中的节点,进行连接 + for (auto stNode : mNodeConnParams) + { + if (m_sessions.find(dev::jsToPublic(dev::toJS(stNode.first))) == m_sessions.end() && stNode.first != id().hex()) + { + std::cout << " reconnect node :" << stNode.first << ". myself is " << id().hex() << std::endl; + NodeConnManagerSingleton::GetInstance().connNode(stNode.second); + } + } + + m_lastReconnect = chrono::steady_clock::now(); +} + +void Host::disconnectLatePeers() +{ + auto now = chrono::steady_clock::now(); + if (now - c_keepAliveTimeOut < m_lastPing) + return; + + RecursiveGuard l(x_sessions); + for (auto p : m_sessions) + if (auto pp = p.second.lock()) + if (now - c_keepAliveTimeOut > m_lastPing && pp->lastReceived() < m_lastPing) + pp->disconnect(PingTimeout); +} + +void Host::disconnectByNodeId(const std::string &sNodeId) +{ + if (id().hex() == sNodeId) + { + std::cout << "disconnectByNodeId self " << id().hex() << "|" << sNodeId << std::endl; + + return; + } + + RecursiveGuard l(x_sessions); + if (m_sessions.find(dev::jsToPublic(dev::toJS(sNodeId))) != m_sessions.end()) + { + auto pp = m_sessions[jsToPublic(toJS(sNodeId))].lock(); + if (pp && pp->isConnected()) + { + if (pp->isConnected()) + { + pp->disconnect(UserReason); + } + } + } + else { + std::cout << "disconnectByNodeId can not find " << sNodeId << std::endl; + } + +} + +void Host::disconnectByPub256(const std::string &_pub256) +{ + RecursiveGuard l(x_sessions); + std::unordered_map>::iterator it = m_sessions.begin(); + while(it != m_sessions.end()) + { + auto sp = it->second.lock(); + if (sp) + { + auto baseDataPtr = sp->getCABaseData(); + if (!baseDataPtr) + { + std::cout << "disconnectByPub256 baseData is nullptr" << std::endl; + return; + } + std::string pub256 = baseDataPtr->getPub256(); + if (pub256 == _pub256) + { + std::cout << "disconnectByPub256 nodeId:" << sp->id().hex() << ",pub256" << _pub256 << std::endl; + disconnectByNodeId(sp->id().hex()); + return; + } + } + it++; + } + + std::cout << "not found pub256:" << _pub256 << std::endl; +} + +void Host::recheckCAByPub256(const std::string &_pub256) +{ + std::cout << "Host recheckCAByPub256 pub256:" << _pub256 << std::endl; + RecursiveGuard l(x_sessions); + std::unordered_map>::iterator it = m_sessions.begin(); + while(it != m_sessions.end()) + { + auto sp = it->second.lock(); + if (sp && sp->isConnected()) + { + auto baseDataPtr = sp->getCABaseData(); + if (!baseDataPtr) + { + std::cout << "recheckCAByPub256 baseData is nullptr" << std::endl; + return; + } + std::string pub256 = baseDataPtr->getPub256(); + if (pub256 == _pub256) + { + WBCAData wbCAData; + wbCAData.setSeed(baseDataPtr->getSeed()); + wbCAData.setSign(baseDataPtr->getSign()); + wbCAData.setNodeSign(baseDataPtr->getNodeSign()); + wbCAData.setPub256(baseDataPtr->getPub256()); + bool ok = NodeConnManagerSingleton::GetInstance().CheckAll(sp->id().hex(), wbCAData); + if (!ok) + { + std::cout << "recheckCAByPub256 false.nodeId:" << sp->id().hex() << ",pub256" << _pub256 << std::endl; + disconnectByNodeId(sp->id().hex()); + } + return; + } + } + + it++; + } +} + +void Host::recheckAllCA() +{ + std::cout << "Host recheckAllCA" << std::endl; + RecursiveGuard l(x_sessions); + std::unordered_map>::iterator it = m_sessions.begin(); + while(it != m_sessions.end()) + { + auto sp = it->second.lock(); + if (sp && sp->isConnected()) + { + auto baseDataPtr = sp->getCABaseData(); + WBCAData wbCAData; + wbCAData.setSeed(baseDataPtr->getSeed()); + wbCAData.setSign(baseDataPtr->getSign()); + wbCAData.setNodeSign(baseDataPtr->getNodeSign()); + wbCAData.setPub256(baseDataPtr->getPub256()); + bool ok = NodeConnManagerSingleton::GetInstance().CheckAll(sp->id().hex(), wbCAData); + if (!ok) + { + std::cout << "recheckCAByPub256 nodeId:" << sp->id().hex() << std::endl; + disconnectByNodeId(sp->id().hex()); + } + } + it++; + } +} + +void Host::saveCADataByNodeId(const std::string nodeId, CABaseData &baseData) +{ + RecursiveGuard l(x_sessions); + if (m_sessions.find(dev::jsToPublic(dev::toJS(nodeId))) != m_sessions.end()) + { + auto pp = m_sessions[jsToPublic(toJS(nodeId))].lock(); + if (pp->isConnected()) + { + std::cout << "Host saveCADataByNodeId, nodeId:" << nodeId << ", seed:" << baseData.getSeed() << ",pub256:" << baseData.getPub256() << ",nodeSign:" << baseData.getNodeSign() << std::endl; + WBCAData *ptr = new WBCAData; + ptr->setSeed(baseData.getSeed()); + ptr->setSign(baseData.getSign()); + ptr->setPub256(baseData.getPub256()); + ptr->setNodeSign(baseData.getNodeSign()); + pp->saveCABaseData(ptr); + } + else + { + std::cout << "saveCADataByNodeId nodeId:" << nodeId << " is not connected."<< std::endl; + } + + } + else{ + std::cout << "saveCADataByNodeId can not find nodeId:" << nodeId << std::endl; + } +} + +bytes Host::saveNetwork() const +{ + + RLPStream ret(3); + ret << dev::p2p::c_protocolVersion << m_alias.secret().ref(); + int count = 0; + ret.appendList(count); + /*if (!!count) + ret.appendRaw(network.out(), count);*/ + return ret.out(); +} + +void Host::restoreNetwork(bytesConstRef _b) +{ + if (!_b.size()) + return; + + // nodes can only be added if network is added + if (!isStarted()) + BOOST_THROW_EXCEPTION(NetworkStartRequired()); + + if (m_dropPeers) + return; + + RecursiveGuard l(x_sessions); + RLP r(_b); + unsigned fileVersion = r[0].toInt(); + if (r.itemCount() > 0 && r[0].isInt() && fileVersion >= dev::p2p::c_protocolVersion - 1) + { + // r[0] = version + // r[1] = key + // r[2] = nodes + + for (auto i : r[2]) + { + // todo: ipv6 + if (i[0].itemCount() != 4 && i[0].size() != 4) + continue; + + if (i.itemCount() == 4 || i.itemCount() == 11) + { + Node n((NodeID)i[3], NodeIPEndpoint(i)); + if (i.itemCount() == 4 && n.endpoint.isAllowed()) + m_nodeTable->addNode(n); + else if (i.itemCount() == 11) + { + n.peerType = i[4].toInt() ? PeerType::Required : PeerType::Optional; + if (!n.endpoint.isAllowed() && n.peerType == PeerType::Optional) + continue; + shared_ptr p = make_shared(n); + p->m_lastConnected = chrono::system_clock::time_point(chrono::seconds(i[5].toInt())); + p->m_lastAttempted = chrono::system_clock::time_point(chrono::seconds(i[6].toInt())); + p->m_failedAttempts = i[7].toInt(); + p->m_lastDisconnect = (DisconnectReason)i[8].toInt(); + p->m_score = (int)i[9].toInt(); + p->m_rating = (int)i[10].toInt(); + m_peers[p->id] = p; + if (p->peerType == PeerType::Required) + requirePeer(p->id, n.endpoint); + else + m_nodeTable->addNode(*p.get(), NodeTable::NodeRelation::Known); + } + } + else if (i.itemCount() == 3 || i.itemCount() == 10) + { + Node n((NodeID)i[2], NodeIPEndpoint(bi::address_v4(i[0].toArray()), i[1].toInt(), i[1].toInt())); + if (i.itemCount() == 3 && n.endpoint.isAllowed()) + m_nodeTable->addNode(n); + else if (i.itemCount() == 10) + { + n.peerType = i[3].toInt() ? PeerType::Required : PeerType::Optional; + if (!n.endpoint.isAllowed() && n.peerType == PeerType::Optional) + continue; + shared_ptr p = make_shared(n); + p->m_lastConnected = chrono::system_clock::time_point(chrono::seconds(i[4].toInt())); + p->m_lastAttempted = chrono::system_clock::time_point(chrono::seconds(i[5].toInt())); + p->m_failedAttempts = i[6].toInt(); + p->m_lastDisconnect = (DisconnectReason)i[7].toInt(); + p->m_score = (int)i[8].toInt(); + p->m_rating = (int)i[9].toInt(); + m_peers[p->id] = p; + if (p->peerType == PeerType::Required) + requirePeer(p->id, n.endpoint); + else + m_nodeTable->addNode(*p.get(), NodeTable::NodeRelation::Known); + } + } + } + } + + addConnParamsToNodeTable(); +} + +KeyPair Host::networkAlias(bytesConstRef _b) +{ + RLP r(_b); + if (r.itemCount() == 3 && r[0].isInt() && r[0].toInt() >= 3) + return KeyPair(Secret(r[1].toBytes())); + else + { + KeyPair kp = KeyPair::create(); + RLPStream netData(3); + netData << dev::p2p::c_protocolVersion << kp.secret().ref(); + int count = 0; + netData.appendList(count); + + writeFile(getDataDir() + "/network.rlp", netData.out()); + return kp; + } +} + +void Host::addConnParamsToNodeTable() +{ + std::map mNodeConnParams; + NodeConnManagerSingleton::GetInstance().getAllNodeConnInfoContractAndConf(mNodeConnParams); + for (auto param : mNodeConnParams) + { + if (id().hex() == param.first) + { + continue; + } + p2p::NodeSpec ns = p2p::NodeSpec(param.second.toEnodeInfo()); + + std::cout << "addConnParamsToNodeTable id: " << ns.enode() << std::endl; + m_nodeTable->addNode(Node(ns.id(), ns.nodeIPEndpoint()), NodeTable::NodeRelation::Known); + } +} diff --git a/libp2p/Host.h b/libp2p/Host.h new file mode 100644 index 0000000000..0bb217f41d --- /dev/null +++ b/libp2p/Host.h @@ -0,0 +1,401 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Host.h + * @author Alex Leverington + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include "NodeTable.h" +#include "HostCapability.h" +#include "Network.h" +#include "Peer.h" +#include "RLPXSocket.h" +#include "RLPXFrameCoder.h" +#include "HandshakeCAData.h" +#include "Common.h" +namespace ba = boost::asio; +namespace bi = ba::ip; + +namespace std +{ + template<> struct hash> +{ + size_t operator()(pair const& _value) const + { + size_t ret = hash()(_value.first); + return ret ^ (hash()(_value.second) + 0x9e3779b9 + (ret << 6) + (ret >> 2)); + } +}; +} + +namespace dev +{ + + namespace p2p + { + + class Host; + + class HostNodeTableHandler: public NodeTableEventHandler + { + public: + HostNodeTableHandler(Host& _host); + + Host const& host() const { return m_host; } + + private: + virtual void processEvent(NodeID const& _n, NodeTableEventType const& _e); + + Host& m_host; + }; + + struct SubReputation + { + bool isRude = false; + int utility = 0; + bytes data; + }; + + struct Reputation + { + std::unordered_map subs; + }; + + class ReputationManager + { + public: + ReputationManager(); + + void noteRude(SessionFace const& _s, std::string const& _sub = std::string()); + bool isRude(SessionFace const& _s, std::string const& _sub = std::string()) const; + void setData(SessionFace const& _s, std::string const& _sub, bytes const& _data); + bytes data(SessionFace const& _s, std::string const& _subs) const; + + private: + std::unordered_map, Reputation> m_nodes; ///< Nodes that were impolite while syncing. We avoid syncing from these if possible. + SharedMutex mutable x_nodes; + }; + + struct NodeInfo + { + NodeInfo() = default; + NodeInfo(NodeID const& _id, std::string const& _address, unsigned _port, std::string const& _version): + id(_id), address(_address), port(_port), version(_version) {} + + std::string enode() const { return "enode://" + id.hex() + "@" + address + ":" + toString(port); } + + NodeID id; + std::string address; + unsigned port; + std::string version; + }; + +/** + * @brief The Host class + * Capabilities should be registered prior to startNetwork, since m_capabilities is not thread-safe. + * + * @todo determinePublic: ipv6, udp + * @todo per-session keepalive/ping instead of broadcast; set ping-timeout via median-latency + */ + class Host: public Worker + { + friend class HostNodeTableHandler; + friend class RLPXHandshake; + + friend class Session; + friend class HostCapabilityFace; + + public: + /// Start server, listening for connections on the given port. + Host( + std::string const& _clientVersion, + NetworkPreferences const& _n = NetworkPreferences(), + bytesConstRef _restoreNetwork = bytesConstRef() + ); + + /// Alternative constructor that allows providing the node key directly + /// without restoring the network. + Host( + std::string const& _clientVersion, + KeyPair const& _alias, + NetworkPreferences const& _n = NetworkPreferences() + ); + + /// Will block on network process events. + virtual ~Host(); + + /// Default hosts for current version of client. + static std::unordered_map pocHosts(); + + /// Register a peer-capability; all new peer connections will have this capability. + template std::shared_ptr registerCapability(std::shared_ptr const& _t) + { + _t->m_host = this; + m_capabilities[std::make_pair(T::staticName(), T::staticVersion())] = _t; + return _t; + } + template void addCapability(std::shared_ptr const & _p, std::string const& _name, u256 const& _version) { m_capabilities[std::make_pair(_name, _version)] = _p; } + + bool haveCapability(CapDesc const& _name) const { return m_capabilities.count(_name) != 0; } + CapDescs caps() const { CapDescs ret; for (auto const& i: m_capabilities) ret.push_back(i.first); return ret; } + template std::shared_ptr cap() const { try { return std::static_pointer_cast(m_capabilities.at(std::make_pair(T::staticName(), T::staticVersion()))); } catch (...) { return nullptr; } } + + /// Add a potential peer. + void addPeer(NodeSpec const& _s, PeerType _t); + + /// Add node as a peer candidate. Node is added if discovery ping is successful and table has capacity. + void addNode(NodeID const& _node, NodeIPEndpoint const& _endpoint); + + /// Create Peer and attempt keeping peer connected. + void requirePeer(NodeID const& _node, NodeIPEndpoint const& _endpoint); + + /// Create Peer and attempt keeping peer connected. + void requirePeer(NodeID const& _node, bi::address const& _addr, unsigned short _udpPort, unsigned short _tcpPort) { requirePeer(_node, NodeIPEndpoint(_addr, _udpPort, _tcpPort)); } + + /// Note peer as no longer being required. + void relinquishPeer(NodeID const& _node); + + /// Set ideal number of peers. + void setIdealPeerCount(unsigned _n) { m_idealPeerCount = _n; } + + /// Set multipier for max accepted connections. + void setPeerStretch(unsigned _n) { m_stretchPeers = _n; } + + /// Get peer information. + PeerSessionInfos peerSessionInfo() const; + + /// Get number of peers connected. + size_t peerCount() const; + + /// Get the address we're listening on currently. + std::string listenAddress() const { return m_tcpPublic.address().is_unspecified() ? "0.0.0.0" : m_tcpPublic.address().to_string(); } + + /// Get the port we're listening on currently. + unsigned short listenPort() const { return std::max(0, m_listenPort); } + + /// Serialise the set of known peers. + bytes saveNetwork() const; + + // TODO: P2P this should be combined with peers into a HostStat object of some kind; coalesce data, as it's only used for status information. + Peers getPeers() const { RecursiveGuard l(x_sessions); Peers ret; for (auto const& i: m_peers) ret.push_back(*i.second); return ret; } + + NetworkPreferences const& networkPreferences() const { return m_netPrefs; } + + void setNetworkPreferences(NetworkPreferences const& _p, bool _dropPeers = false) { m_dropPeers = _dropPeers; auto had = isStarted(); if (had) stop(); m_netPrefs = _p; if (had) start(); } + + /// Start network. @threadsafe + void start(); + + /// Stop network. @threadsafe + /// Resets acceptor, socket, and IO service. Called by deallocator. + void stop(); + + /// @returns if network has been started. + bool isStarted() const { return isWorking(); } + + /// @returns our reputation manager. + ReputationManager& repMan() { return m_repMan; } + + /// @returns if network is started and interactive. + bool haveNetwork() const { Guard l(x_runTimer); return m_run && !!m_nodeTable; } + + /// Validates and starts peer session, taking ownership of _io. Disconnects and returns false upon error. + void startPeerSession(Public const& _id, RLP const& _hello, std::unique_ptr&& _io, std::shared_ptr const& _s, RLPBaseData &rlpBaseData); + + /// Get session by id + std::shared_ptr peerSession(NodeID const& _id) { RecursiveGuard l(x_sessions); return m_sessions.count(_id) ? m_sessions[_id].lock() : std::shared_ptr(); } + + /// Get our current node ID. + NodeID id() const { return m_alias.pub(); } + Secret sec() const { return m_alias.sec(); } + KeyPair keyPair() const { return m_alias; } + + /// Get the public TCP endpoint. + bi::tcp::endpoint const& tcpPublic() const { return m_tcpPublic; } + + /// Get the public endpoint information. + std::string enode() const { return "enode://" + id().hex() + "@" + (networkPreferences().publicIPAddress.empty() ? m_tcpPublic.address().to_string() : networkPreferences().publicIPAddress) + ":" + toString(m_tcpPublic.port()); } + + /// Get the node information. + p2p::NodeInfo nodeInfo() const { return NodeInfo(id(), (networkPreferences().publicIPAddress.empty() ? m_tcpPublic.address().to_string() : networkPreferences().publicIPAddress), m_tcpPublic.port(), m_clientVersion); } + + //获取自己的签名数据 已经hash并签名 + bool getSelfSignData(Signature &_sign) const; + + /** + * 根据节点id 断掉连接 + * 存在即断掉对应的peer连接 + */ + void disconnectByNodeId(const std::string &sNodeId); + + /** + * 遍历所有的session,依据pub256来断开对应session + */ + void disconnectByPub256(const std::string &pub256); + + /** + * 遍历所有的session,当CA内容变更的时候,依据pub256重新检查签名的合法性 + */ + void recheckCAByPub256(const std::string &pub256); + + /** + * 遍历所有的session,当CAVerify改变的时候,重新检查所有链接节点的合法性 + */ + void recheckAllCA(); + + /** + * + */ + void saveCADataByNodeId(const std::string nodeId, CABaseData &baseData); + + bool onTick(unsigned _t, std::function _fun); + bool onInit(std::function _fun); + ba::io_service& ioService() { return m_ioService; } + protected: + void onNodeTableEvent(NodeID const& _n, NodeTableEventType const& _e); + + /// Deserialise the data and populate the set of known peers. + void restoreNetwork(bytesConstRef _b); + private: + enum PeerSlotType { Egress, Ingress }; + + unsigned peerSlots(PeerSlotType _type) { return _type == Egress ? m_idealPeerCount : m_idealPeerCount * m_stretchPeers; } + + bool havePeerSession(NodeID const& _id) { return !!peerSession(_id); } + + /// Determines and sets m_tcpPublic to publicly advertised address. + void determinePublic(); + + void connect(std::shared_ptr const& _p); + + /// Returns true if pending and connected peer count is less than maximum + bool peerSlotsAvailable(PeerSlotType _type = Ingress) { Guard l(x_pendingNodeConns); return peerCount() + m_pendingPeerConns.size() < peerSlots(_type); } + + /// Ping the peers to update the latency information and disconnect peers which have timed out. + void keepAlivePeers(); + + //看所有的节点是否已经连接 如果没有 则进行连接 + void reconnectAllNodes(); + + /// Disconnect peers which didn't respond to keepAlivePeers ping prior to c_keepAliveTimeOut. + void disconnectLatePeers(); + + /// Called only from startedWorking(). + void runAcceptor(); + + /// Called by Worker. Not thread-safe; to be called only by worker. + virtual void startedWorking(); + /// Called by startedWorking. Not thread-safe; to be called only be Worker. + void run(boost::system::error_code const& error); ///< Run network. Called serially via ASIO deadline timer. Manages connection state transitions. + + /// Run network. Not thread-safe; to be called only by worker. + virtual void doWork(); + + /// Shutdown network. Not thread-safe; to be called only by worker. + virtual void doneWorking(); + + /// Get or create host identifier (KeyPair). + static KeyPair networkAlias(bytesConstRef _b); + + //增加节点配置文件的节点信息到NodeTable中去 + void addConnParamsToNodeTable(); + + ////检查节点连接信息 + ////in - sEndPointNodeId 对端连接的nodeid + ////in - sSign 传入的加密数据 + //bool checkNodeConnInfo(const std::string &sEndPointNodeId, const Public &pub, const Signature &sSign) const; + + bytes m_restoreNetwork; ///< Set by constructor and used to set Host key and restore network peers & nodes. + + bool m_run = false; ///< Whether network is running. + + + mutable std::mutex x_runTimer; ///< Start/stop mutex. + + std::string m_clientVersion; ///< Our version string. + + NetworkPreferences m_netPrefs; ///< Network settings. + + /// Interface addresses (private, public) + std::set m_ifAddresses; ///< Interface addresses. + + int m_listenPort = -1; ///< What port are we listening on. -1 means binding failed or acceptor hasn't been initialized. + + ba::io_service m_ioService; ///< IOService for network stuff. + bi::tcp::acceptor m_tcp4Acceptor; ///< Listening acceptor. + + std::unique_ptr m_timer; ///< Timer which, when network is running, calls scheduler() every c_timerInterval ms. + static const unsigned c_timerInterval = 100; ///< Interval which m_timer is run when network is connected. + + std::set m_pendingPeerConns; /// Used only by connect(Peer&) to limit concurrently connecting to same node. See connect(shared_ptrconst&). + Mutex x_pendingNodeConns; + + bi::tcp::endpoint m_tcpPublic; ///< Our public listening endpoint. + KeyPair m_alias; ///< Alias for network communication. Network address is k*G. k is key material. TODO: Replace KeyPair. + std::shared_ptr m_nodeTable; ///< Node table (uses kademlia-like discovery). + + /// Shared storage of Peer objects. Peers are created or destroyed on demand by the Host. Active sessions maintain a shared_ptr to a Peer; + std::unordered_map> m_peers; + + /// Peers we try to connect regardless of p2p network. + std::set m_requiredPeers; + Mutex x_requiredPeers; + + /// The nodes to which we are currently connected. Used by host to service peer requests and keepAlivePeers and for shutdown. (see run()) + /// Mutable because we flush zombie entries (null-weakptrs) as regular maintenance from a const method. + mutable std::unordered_map> m_sessions; + mutable RecursiveMutex x_sessions; + + std::list> m_connecting; ///< Pending connections. + Mutex x_connecting; ///< Mutex for m_connecting. + + unsigned m_idealPeerCount = 11; ///< Ideal number of peers to be connected to. + unsigned m_stretchPeers = 7; ///< Accepted connection multiplier (max peers = ideal*stretch). + + std::map> m_capabilities; ///< Each of the capabilities we support. + + /// Deadline timers used for isolated network events. GC'd by run. + std::list> m_timers; + Mutex x_timers; + + std::chrono::steady_clock::time_point m_lastPing; ///< Time we sent the last ping to all peers. + std::chrono::steady_clock::time_point m_lastReconnect; ///< Time we sent the last ping to all peers. + + bool m_accepting = false; + bool m_dropPeers = false; + + ReputationManager m_repMan; + }; + + } +} \ No newline at end of file diff --git a/libp2p/HostCapability.cpp b/libp2p/HostCapability.cpp new file mode 100644 index 0000000000..0234f7fe9f --- /dev/null +++ b/libp2p/HostCapability.cpp @@ -0,0 +1,56 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file HostCapability.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "HostCapability.h" + +#include "Session.h" +#include "Host.h" +using namespace std; +using namespace dev; +using namespace dev::p2p; + +std::vector, std::shared_ptr>> HostCapabilityFace::peerSessions() const +{ + return peerSessions(version()); +} + +std::vector, std::shared_ptr>> HostCapabilityFace::peerSessions(u256 const& _version) const +{ + RecursiveGuard l(m_host->x_sessions); + std::vector, std::shared_ptr>> ret; + for (auto const& i : m_host->m_sessions) + if (std::shared_ptr s = i.second.lock()) + if (s->capabilities().count(std::make_pair(name(), _version))) + ret.push_back(make_pair(s, s->peer())); + return ret; +} + +bool HostCapabilityFace::isConnected(h512 const& _id) { + RecursiveGuard l(m_host->x_sessions); + for (auto const& i : m_host->m_sessions) { + if (std::shared_ptr s = i.second.lock()) { + if (s->id() == _id && s->isConnected()) { + return true; + } + } + } + return false; +} diff --git a/libp2p/HostCapability.h b/libp2p/HostCapability.h new file mode 100644 index 0000000000..5cf2eb76d5 --- /dev/null +++ b/libp2p/HostCapability.h @@ -0,0 +1,95 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file HostCapability.h + * @author Gav Wood + * @date 2014 + * + * Miscellanea required for the Host/Session classes. + */ + +#pragma once + +#include +#include "Peer.h" +#include "Common.h" +#include "Session.h" + +namespace dev +{ + +namespace p2p +{ + +class HostCapabilityFace +{ + friend class Host; + template friend class HostCapability; + friend class Capability; + friend class Session; + +public: + HostCapabilityFace() {} + virtual ~HostCapabilityFace() {} + + Host* host() const { return m_host; } + + std::vector, std::shared_ptr>> peerSessions() const; + std::vector, std::shared_ptr>> peerSessions(u256 const& _version) const; + bool isConnected(h512 const& _id); + +protected: + virtual std::string name() const = 0; + virtual u256 version() const = 0; + CapDesc capDesc() const { return std::make_pair(name(), version()); } + virtual unsigned messageCount() const = 0; + virtual std::shared_ptr newPeerCapability(std::shared_ptr const& _s, unsigned _idOffset, CapDesc const& _cap, uint16_t _capID) = 0; + + virtual void onStarting() {} + virtual void onStopping() {} + +private: + Host* m_host = nullptr; +}; + +template +class HostCapability: public HostCapabilityFace +{ +public: + HostCapability() {} + virtual ~HostCapability() {} + + static std::string staticName() { return PeerCap::name(); } + static u256 staticVersion() { return PeerCap::version(); } + static unsigned staticMessageCount() { return PeerCap::messageCount(); } + +protected: + virtual std::string name() const { return PeerCap::name(); } + virtual u256 version() const { return PeerCap::version(); } + virtual unsigned messageCount() const { return PeerCap::messageCount(); } + + virtual std::shared_ptr newPeerCapability(std::shared_ptr const& _s, unsigned _idOffset, CapDesc const& _cap, uint16_t _capID) + { + _s->registerFraming(_capID); + auto p = std::make_shared(_s, this, _idOffset, _cap, _capID); + _s->registerCapability(_cap, p); + return p; + } +}; + +} + +} diff --git a/libp2p/Network.cpp b/libp2p/Network.cpp new file mode 100644 index 0000000000..136f261269 --- /dev/null +++ b/libp2p/Network.cpp @@ -0,0 +1,251 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Network.cpp + * @author Alex Leverington + * @author Gav Wood + * @author Eric Lombrozo (Windows version of getInterfaceAddresses()) + * @date 2014 + */ + +#include +#ifndef _WIN32 +#include +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include "Common.h" +#include "UPnP.h" +#include "Network.h" + +using namespace std; +using namespace dev; +using namespace dev::p2p; + +std::set Network::getInterfaceAddresses() +{ + std::set addresses; + +#if defined(_WIN32) + WSAData wsaData; + if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0) + BOOST_THROW_EXCEPTION(NoNetworking()); + + char ac[80]; + if (gethostname(ac, sizeof(ac)) == SOCKET_ERROR) + { + clog(NetWarn) << "Error " << WSAGetLastError() << " when getting local host name."; + WSACleanup(); + BOOST_THROW_EXCEPTION(NoNetworking()); + } + + struct hostent* phe = gethostbyname(ac); + if (phe == 0) + { + clog(NetWarn) << "Bad host lookup."; + WSACleanup(); + BOOST_THROW_EXCEPTION(NoNetworking()); + } + + for (int i = 0; phe->h_addr_list[i] != 0; ++i) + { + struct in_addr addr; + memcpy(&addr, phe->h_addr_list[i], sizeof(struct in_addr)); + char *addrStr = inet_ntoa(addr); + bi::address address(bi::address::from_string(addrStr)); + if (!isLocalHostAddress(address)) + addresses.insert(address.to_v4()); + } + + WSACleanup(); +#else + ifaddrs* ifaddr; + if (getifaddrs(&ifaddr) == -1) + BOOST_THROW_EXCEPTION(NoNetworking()); + + for (auto ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) + { + if (!ifa->ifa_addr || string(ifa->ifa_name) == "lo0" || !(ifa->ifa_flags & IFF_UP)) + continue; + + if (ifa->ifa_addr->sa_family == AF_INET) + { + in_addr addr = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr; + boost::asio::ip::address_v4 address(boost::asio::detail::socket_ops::network_to_host_long(addr.s_addr)); + if (!isLocalHostAddress(address)) + addresses.insert(address); + } + else if (ifa->ifa_addr->sa_family == AF_INET6) + { + sockaddr_in6* sockaddr = ((struct sockaddr_in6 *)ifa->ifa_addr); + in6_addr addr = sockaddr->sin6_addr; + boost::asio::ip::address_v6::bytes_type bytes; + memcpy(&bytes[0], addr.s6_addr, 16); + boost::asio::ip::address_v6 address(bytes, sockaddr->sin6_scope_id); + if (!isLocalHostAddress(address)) + addresses.insert(address); + } + } + + if (ifaddr!=NULL) + freeifaddrs(ifaddr); + +#endif + + return addresses; +} + +int Network::tcp4Listen(bi::tcp::acceptor& _acceptor, NetworkPreferences const& _netPrefs) +{ + // Due to the complexities of NAT and network environments (multiple NICs, tunnels, etc) + // and security concerns automation is the enemy of network configuration. + // If a preference cannot be accommodate the network must fail to start. + // + // Preferred IP: Attempt if set, else, try 0.0.0.0 (all interfaces) + // Preferred Port: Attempt if set, else, try c_defaultListenPort or 0 (random) + // TODO: throw instead of returning -1 and rename NetworkPreferences to NetworkConfig + + bi::address listenIP; + try + { + listenIP = _netPrefs.listenIPAddress.empty() ? bi::address_v4() : bi::address::from_string(_netPrefs.listenIPAddress); + } + catch (...) + { + LOG(WARNING) << "Couldn't start accepting connections on host. Failed to accept socket on " << listenIP << ":" << _netPrefs.listenPort << ".\n" << boost::current_exception_diagnostic_information(); + return -1; + } + bool requirePort = (bool)_netPrefs.listenPort; + + for (unsigned i = 0; i < 2; ++i) + { + bi::tcp::endpoint endpoint(listenIP, requirePort ? _netPrefs.listenPort : (i ? 0 : c_defaultListenPort)); + try + { +#if defined(_WIN32) + bool reuse = false; +#else + bool reuse = true; +#endif + _acceptor.open(endpoint.protocol()); + _acceptor.set_option(ba::socket_base::reuse_address(reuse)); + _acceptor.bind(endpoint); + _acceptor.listen(); + return _acceptor.local_endpoint().port(); + } + catch (...) + { + // bail if this is first attempt && port was specificed, or second attempt failed (random port) + if (i || requirePort) + { + // both attempts failed + LOG(WARNING) << "Couldn't start accepting connections on host. Failed to accept socket on " << listenIP << ":" << _netPrefs.listenPort << ".\n" << boost::current_exception_diagnostic_information(); + _acceptor.close(); + return -1; + } + + _acceptor.close(); + continue; + } + } + + return -1; +} + +bi::tcp::endpoint Network::traverseNAT(std::set const& _ifAddresses, unsigned short _listenPort, bi::address& o_upnpInterfaceAddr) +{ + asserts(_listenPort != 0); + + unique_ptr upnp; + try + { + upnp.reset(new UPnP); + } + // let m_upnp continue as null - we handle it properly. + catch (...) {} + + bi::tcp::endpoint upnpEP; + if (upnp && upnp->isValid()) + { + bi::address pAddr; + int extPort = 0; + for (auto const& addr: _ifAddresses) + if (addr.is_v4() && isPrivateAddress(addr) && (extPort = upnp->addRedirect(addr.to_string().c_str(), _listenPort))) + { + pAddr = addr; + break; + } + + auto eIP = upnp->externalIP(); + bi::address eIPAddr(bi::address::from_string(eIP)); + if (extPort && eIP != string("0.0.0.0") && !isPrivateAddress(eIPAddr)) + { + clog(NetNote) << "Punched through NAT and mapped local port" << _listenPort << "onto external port" << extPort << "."; + clog(NetNote) << "External addr:" << eIP; + o_upnpInterfaceAddr = pAddr; + upnpEP = bi::tcp::endpoint(eIPAddr, (unsigned short)extPort); + } + else + clog(NetWarn) << "Couldn't punch through NAT (or no NAT in place)."; + } + + return upnpEP; +} + +bi::tcp::endpoint Network::resolveHost(string const& _addr) +{ + static boost::asio::io_service s_resolverIoService; + + vector split; + boost::split(split, _addr, boost::is_any_of(":")); + unsigned port = dev::p2p::c_defaultIPPort; + + try + { + if (split.size() > 1) + port = static_cast(stoi(split.at(1))); + } + catch(...) {} + + boost::system::error_code ec; + bi::address address = bi::address::from_string(split[0], ec); + bi::tcp::endpoint ep(bi::address(), port); + if (!ec) + ep.address(address); + else + { + boost::system::error_code ec; + // resolve returns an iterator (host can resolve to multiple addresses) + bi::tcp::resolver r(s_resolverIoService); + auto it = r.resolve({bi::tcp::v4(), split[0], toString(port)}, ec); + if (ec) + { + clog(NetWarn) << "Error resolving host address..." << LogTag::Url << _addr << ":" << LogTag::Error << ec.message(); + return bi::tcp::endpoint(); + } + else + ep = *it; + } + return ep; +} + diff --git a/libp2p/Network.h b/libp2p/Network.h new file mode 100644 index 0000000000..c3682357c1 --- /dev/null +++ b/libp2p/Network.h @@ -0,0 +1,88 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Network.h + * @author Alex Leverington + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include "Common.h" +namespace ba = boost::asio; +namespace bi = ba::ip; + +namespace dev +{ +namespace p2p +{ + +static unsigned short c_defaultListenPort = 16789; + +struct NetworkPreferences +{ + // Default Network Preferences + NetworkPreferences(unsigned short lp = c_defaultListenPort): listenPort(lp) {} + + // Network Preferences with specific Listen IP + NetworkPreferences(std::string const& l, unsigned short lp = c_defaultListenPort, bool u = true): publicIPAddress(), listenIPAddress(l), listenPort(lp), traverseNAT(u) {} + + // Network Preferences with intended Public IP + NetworkPreferences(std::string const& publicIP, std::string const& l = std::string(), unsigned short lp = c_defaultListenPort, bool u = true): publicIPAddress(publicIP), listenIPAddress(l), listenPort(lp), traverseNAT(u) { if (!publicIPAddress.empty() && !isPublicAddress(publicIPAddress)) BOOST_THROW_EXCEPTION(InvalidPublicIPAddress()); } + + /// Addressing + + std::string publicIPAddress; + std::string listenIPAddress; + unsigned short listenPort = c_defaultListenPort; + + + /// Preferences + + bool traverseNAT = true; + bool discovery = true; // Discovery is activated with network. + bool pin = false; // Only accept or connect to trusted peers. +}; + +/** + * @brief Network Class + * Static network operations and interface(s). + */ +class Network +{ +public: + /// @returns public and private interface addresses + static std::set getInterfaceAddresses(); + + /// Try to bind and listen on _listenPort, else attempt net-allocated port. + static int tcp4Listen(bi::tcp::acceptor& _acceptor, NetworkPreferences const& _netPrefs); + + /// Return public endpoint of upnp interface. If successful o_upnpifaddr will be a private interface address and endpoint will contain public address and port. + static bi::tcp::endpoint traverseNAT(std::set const& _ifAddresses, unsigned short _listenPort, bi::address& o_upnpInterfaceAddr); + + /// Resolve "host:port" string as TCP endpoint. Returns unspecified endpoint on failure. + static bi::tcp::endpoint resolveHost(std::string const& _host); +}; + +} +} diff --git a/libp2p/NodeTable.cpp b/libp2p/NodeTable.cpp new file mode 100644 index 0000000000..2a64b77902 --- /dev/null +++ b/libp2p/NodeTable.cpp @@ -0,0 +1,639 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . + */ +/** @file NodeTable.cpp + * @author Alex Leverington + * @date 2014 + */ + +#include "NodeTable.h" +#include +using namespace std; +using namespace dev; +using namespace dev::p2p; + +const char* NodeTableWarn::name() { return "!P!"; } +const char* NodeTableNote::name() { return "*P*"; } +const char* NodeTableMessageSummary::name() { return "-P-"; } +const char* NodeTableMessageDetail::name() { return "=P="; } +const char* NodeTableConnect::name() { return "+P+"; } +const char* NodeTableEvent::name() { return "+P+"; } +const char* NodeTableTimer::name() { return "+P+"; } +const char* NodeTableUpdate::name() { return "+P+"; } +const char* NodeTableTriviaSummary::name() { return "-P-"; } +const char* NodeTableTriviaDetail::name() { return "=P="; } +const char* NodeTableAllDetail::name() { return "=P="; } +const char* NodeTableEgress::name() { return ">>P"; } +const char* NodeTableIngress::name() { return "<(_io, *reinterpret_cast(this), (bi::udp::endpoint)m_node.endpoint)), + m_socketPointer(m_socket.get()), + m_timers(_io) +{ + for (unsigned i = 0; i < s_bins; i++) + m_state[i].distance = i; + + if (!_enabled) + return; + + try + { + m_socketPointer->connect(); + doDiscovery(); + } + catch (std::exception const& _e) + { + clog(NetWarn) << "Exception connecting NodeTable socket: " << _e.what(); + clog(NetWarn) << "Discovery disabled."; + } +} + +NodeTable::~NodeTable() +{ + m_socketPointer->disconnect(); + m_timers.stop(); +} + +void NodeTable::processEvents() +{ + if (m_nodeEventHandler) + m_nodeEventHandler->processEvents(); +} + +shared_ptr NodeTable::addNode(Node const& _node, NodeRelation _relation) +{ + LOG(TRACE)<<"NodeTable::addNode "<<_node.id<<","<<_relation; + if (_relation == Known) + { + auto ret = make_shared(m_node.id, _node.id, _node.endpoint); + ret->pending = false; + DEV_GUARDED(x_nodes) + m_nodes[_node.id] = ret; + noteActiveNode(_node.id, _node.endpoint); + return ret; + } + + if (!_node.endpoint) + return shared_ptr(); + + // ping address to recover nodeid if nodeid is empty + if (!_node.id) + { + DEV_GUARDED(x_nodes) + clog(NodeTableConnect) << "Sending public key discovery Ping to" << (bi::udp::endpoint)_node.endpoint << "(Advertising:" << (bi::udp::endpoint)m_node.endpoint << ")"; + DEV_GUARDED(x_pubkDiscoverPings) + m_pubkDiscoverPings[_node.endpoint.address] = std::chrono::steady_clock::now(); + ping(_node.endpoint); + return shared_ptr(); + } + + DEV_GUARDED(x_nodes) + if (m_nodes.count(_node.id)) + return m_nodes[_node.id]; + + auto ret = make_shared(m_node.id, _node.id, _node.endpoint); + DEV_GUARDED(x_nodes) + m_nodes[_node.id] = ret; + clog(NodeTableConnect) << "addNode pending for" << _node.endpoint; + ping(_node.endpoint); + return ret; +} + +list NodeTable::nodes() const +{ + list nodes; + DEV_GUARDED(x_nodes) + for (auto& i: m_nodes) + nodes.push_back(i.second->id); + return nodes; +} + +list NodeTable::snapshot() const +{ + list ret; + DEV_GUARDED(x_state) + for (auto const& s: m_state) + for (auto const& np: s.nodes) + if (auto n = np.lock()) + ret.push_back(*n); + return ret; +} + +Node NodeTable::node(NodeID const& _id) +{ + Guard l(x_nodes); + if (m_nodes.count(_id)) + { + auto entry = m_nodes[_id]; + return Node(_id, entry->endpoint, entry->peerType); + } + return UnspecifiedNode; +} + +shared_ptr NodeTable::nodeEntry(NodeID _id) +{ + Guard l(x_nodes); + return m_nodes.count(_id) ? m_nodes[_id] : shared_ptr(); +} + +void NodeTable::doDiscover(NodeID _node, unsigned _round, shared_ptr>> _tried) +{ + // NOTE: ONLY called by doDiscovery! + + if (!m_socketPointer->isOpen()) + return; + + if (_round == s_maxSteps) + { + clog(NodeTableEvent) << "Terminating discover after " << _round << " rounds."; + doDiscovery(); + return; + } + else if (!_round && !_tried) + // initialized _tried on first round + _tried = make_shared>>(); + + auto nearest = nearestNodeEntries(_node); + list> tried; + for (unsigned i = 0; i < nearest.size() && tried.size() < s_alpha; i++) + if (!_tried->count(nearest[i])) + { + auto r = nearest[i]; + tried.push_back(r); + FindNode p(r->endpoint, _node); + p.sign(m_secret); + DEV_GUARDED(x_findNodeTimeout) + m_findNodeTimeout.push_back(make_pair(r->id, chrono::steady_clock::now())); + m_socketPointer->send(p); + } + + if (tried.empty()) + { + clog(NodeTableEvent) << "Terminating discover after " << _round << " rounds."; + doDiscovery(); + return; + } + + while (!tried.empty()) + { + _tried->insert(tried.front()); + tried.pop_front(); + } + + m_timers.schedule(c_reqTimeout.count() * 2, [this, _node, _round, _tried](boost::system::error_code const& _ec) + { + if (_ec) + clog(NodeTableMessageDetail) << "Discovery timer was probably cancelled: " << _ec.value() << _ec.message(); + + if (_ec.value() == boost::asio::error::operation_aborted || m_timers.isStopped()) + return; + + // error::operation_aborted means that the timer was probably aborted. + // It usually happens when "this" object is deallocated, in which case + // subsequent call to doDiscover() would cause a crash. We can not rely on + // m_timers.isStopped(), because "this" pointer was captured by the lambda, + // and therefore, in case of deallocation m_timers object no longer exists. + + doDiscover(_node, _round + 1, _tried); + }); +} + +vector> NodeTable::nearestNodeEntries(NodeID _target) +{ + // send s_alpha FindNode packets to nodes we know, closest to target + static unsigned lastBin = s_bins - 1; + unsigned head = distance(m_node.id, _target); + unsigned tail = head == 0 ? lastBin : (head - 1) % s_bins; + + map>> found; + unsigned count = 0; + + // if d is 0, then we roll look forward, if last, we reverse, else, spread from d + if (head > 1 && tail != lastBin) + while (head != tail && head < s_bins && count < s_bucketSize) + { + Guard l(x_state); + for (auto const& n: m_state[head].nodes) + if (auto p = n.lock()) + { + if (count < s_bucketSize) + found[distance(_target, p->id)].push_back(p); + else + break; + } + + if (count < s_bucketSize && tail) + for (auto const& n: m_state[tail].nodes) + if (auto p = n.lock()) + { + if (count < s_bucketSize) + found[distance(_target, p->id)].push_back(p); + else + break; + } + + head++; + if (tail) + tail--; + } + else if (head < 2) + while (head < s_bins && count < s_bucketSize) + { + Guard l(x_state); + for (auto const& n: m_state[head].nodes) + if (auto p = n.lock()) + { + if (count < s_bucketSize) + found[distance(_target, p->id)].push_back(p); + else + break; + } + head++; + } + else + while (tail > 0 && count < s_bucketSize) + { + Guard l(x_state); + for (auto const& n: m_state[tail].nodes) + if (auto p = n.lock()) + { + if (count < s_bucketSize) + found[distance(_target, p->id)].push_back(p); + else + break; + } + tail--; + } + + vector> ret; + for (auto& nodes: found) + for (auto const& n: nodes.second) + if (ret.size() < s_bucketSize && !!n->endpoint && n->endpoint.isAllowed()) + ret.push_back(n); + return ret; +} + +void NodeTable::ping(NodeIPEndpoint _to) const +{ + NodeIPEndpoint src; + DEV_GUARDED(x_nodes) + src = m_node.endpoint; + PingNode p(src, _to); + p.sign(m_secret); + m_socketPointer->send(p); +} + +void NodeTable::ping(NodeEntry* _n) const +{ + if (_n) + ping(_n->endpoint); +} + +void NodeTable::evict(shared_ptr _leastSeen, shared_ptr _new) +{ + if (!m_socketPointer->isOpen()) + return; + + unsigned evicts = 0; + DEV_GUARDED(x_evictions) + { + m_evictions.push_back(EvictionTimeout(make_pair(_leastSeen->id,chrono::steady_clock::now()), _new->id)); + evicts = m_evictions.size(); + } + + if (evicts == 1) + doCheckEvictions(); + ping(_leastSeen.get()); +} + +void NodeTable::noteActiveNode(Public const& _pubk, bi::udp::endpoint const& _endpoint) +{ + LOG(TRACE)<<"NodeTable::noteActiveNode "<<_pubk<<","<<_endpoint; + + if (_pubk == m_node.address() ) + { + clog(NodeTableWarn) << "_pubk== m_node.address() "<< m_node.address() <<_pubk; + return; + } + if( !NodeIPEndpoint(_endpoint.address(), _endpoint.port(), _endpoint.port()).isAllowed()) + { + clog(NodeTableWarn) << "not allowed "<< m_node.address() <<_pubk<<","<<_endpoint.address()<<","<<_endpoint.port(); + return ; + } + + + shared_ptr node = nodeEntry(_pubk); + if (!!node && !node->pending) + { + clog(NodeTableConnect) << "Noting active node:" << _pubk << _endpoint.address().to_string() << ":" << _endpoint.port(); + node->endpoint.address = _endpoint.address(); + node->endpoint.udpPort = _endpoint.port(); + + shared_ptr contested; + { + Guard l(x_state); + NodeBucket& s = bucket_UNSAFE(node.get()); + bool removed = false; + s.nodes.remove_if([&node, &removed](weak_ptr const& n) + { + if (n.lock() == node) + removed = true; + return removed; + }); + + if (s.nodes.size() >= s_bucketSize) + { + if (removed) + clog(NodeTableWarn) << "DANGER: Bucket overflow when swapping node position."; + + // It's only contested iff nodeentry exists + contested = s.nodes.front().lock(); + if (!contested) + { + s.nodes.pop_front(); + s.nodes.push_back(node); + if (!removed && m_nodeEventHandler) + m_nodeEventHandler->appendEvent(node->id, NodeEntryAdded); + } + } + else + { + s.nodes.push_back(node); + if (!removed && m_nodeEventHandler) + m_nodeEventHandler->appendEvent(node->id, NodeEntryAdded); + } + } + + if (contested) + evict(contested, node); + } +} + +void NodeTable::dropNode(shared_ptr _n) +{ + // remove from nodetable + { + Guard l(x_state); + NodeBucket& s = bucket_UNSAFE(_n.get()); + s.nodes.remove_if([&_n](weak_ptr n) { return n.lock() == _n; }); + } + + // notify host + clog(NodeTableUpdate) << "p2p.nodes.drop " << _n->id; + if (m_nodeEventHandler) + m_nodeEventHandler->appendEvent(_n->id, NodeEntryDropped); +} + +NodeTable::NodeBucket& NodeTable::bucket_UNSAFE(NodeEntry const* _n) +{ + return m_state[_n->distance - 1]; +} + +void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytesConstRef _packet) +{ + try { + unique_ptr packet = DiscoveryDatagram::interpretUDP(_from, _packet); + if (!packet) + return; + if (packet->isExpired()) + { + clog(NodeTableWarn) << "Invalid packet (timestamp in the past) from " << _from.address().to_string() << ":" << _from.port(); + return; + } + + switch (packet->packetType()) + { + case Pong::type: + { + auto in = dynamic_cast(*packet); + // whenever a pong is received, check if it's in m_evictions + bool found = false; + EvictionTimeout evictionEntry; + DEV_GUARDED(x_evictions) + for (auto it = m_evictions.begin(); it != m_evictions.end(); ++it) + if (it->first.first == in.sourceid && it->first.second > std::chrono::steady_clock::now()) + { + found = true; + evictionEntry = *it; + m_evictions.erase(it); + break; + } + if (found) + { + if (auto n = nodeEntry(evictionEntry.second)) + dropNode(n); + if (auto n = nodeEntry(evictionEntry.first.first)) + n->pending = false; + } + else + { + // if not, check if it's known/pending or a pubk discovery ping + if (auto n = nodeEntry(in.sourceid)) + n->pending = false; + else + { + DEV_GUARDED(x_pubkDiscoverPings) + { + if (!m_pubkDiscoverPings.count(_from.address())) + return; // unsolicited pong; don't note node as active + m_pubkDiscoverPings.erase(_from.address()); + } + if (!haveNode(in.sourceid)) + addNode(Node(in.sourceid, NodeIPEndpoint(_from.address(), _from.port(), _from.port()))); + } + } + + // update our endpoint address and UDP port + DEV_GUARDED(x_nodes) + { + if ((!m_node.endpoint || !m_node.endpoint.isAllowed()) && isPublicAddress(in.destination.address)) + m_node.endpoint.address = in.destination.address; + m_node.endpoint.udpPort = in.destination.udpPort; + } + + clog(NodeTableConnect) << "PONG from " << in.sourceid << _from; + break; + } + + case Neighbours::type: + { + auto in = dynamic_cast(*packet); + bool expected = false; + auto now = chrono::steady_clock::now(); + DEV_GUARDED(x_findNodeTimeout) + m_findNodeTimeout.remove_if([&](NodeIdTimePoint const& t) + { + if (t.first == in.sourceid && now - t.second < c_reqTimeout) + expected = true; + else if (t.first == in.sourceid) + return true; + return false; + }); + if (!expected) + { + clog(NetConnect) << "Dropping unsolicited neighbours packet from " << _from.address(); + break; + } + + for (auto n: in.neighbours) + addNode(Node(n.node, n.endpoint)); + break; + } + + case FindNode::type: + { + auto in = dynamic_cast(*packet); + vector> nearest = nearestNodeEntries(in.target); + static unsigned const nlimit = (m_socketPointer->maxDatagramSize - 109) / 90; + for (unsigned offset = 0; offset < nearest.size(); offset += nlimit) + { + Neighbours out(_from, nearest, offset, nlimit); + out.sign(m_secret); + if (out.data.size() > 1280) + clog(NetWarn) << "Sending truncated datagram, size: " << out.data.size(); + m_socketPointer->send(out); + } + break; + } + + case PingNode::type: + { + auto in = dynamic_cast(*packet); + in.source.address = _from.address(); + in.source.udpPort = _from.port(); + addNode(Node(in.sourceid, in.source)); + + Pong p(in.source); + p.echo = sha3(in.echo); + p.sign(m_secret); + m_socketPointer->send(p); + break; + } + } + + noteActiveNode(packet->sourceid, _from); + } + catch (std::exception const& _e) + { + clog(NodeTableWarn) << "Exception processing message from " << _from.address().to_string() << ":" << _from.port() << ": " << _e.what(); + } + catch (...) + { + clog(NodeTableWarn) << "Exception processing message from " << _from.address().to_string() << ":" << _from.port(); + } +} + +void NodeTable::doCheckEvictions() +{ + m_timers.schedule(c_evictionCheckInterval.count(), [this](boost::system::error_code const& _ec) + { + if (_ec) + clog(NodeTableMessageDetail) << "Check Evictions timer was probably cancelled: " << _ec.value() << _ec.message(); + + if (_ec.value() == boost::asio::error::operation_aborted || m_timers.isStopped()) + return; + + bool evictionsRemain = false; + list> drop; + { + Guard le(x_evictions); + Guard ln(x_nodes); + for (auto& e: m_evictions) + if (chrono::steady_clock::now() - e.first.second > c_reqTimeout) + if (m_nodes.count(e.second)) + drop.push_back(m_nodes[e.second]); + evictionsRemain = (m_evictions.size() - drop.size() > 0); + } + + drop.unique(); + for (auto n: drop) + dropNode(n); + + if (evictionsRemain) + doCheckEvictions(); + }); +} + +void NodeTable::doDiscovery() +{ + m_timers.schedule(c_bucketRefresh.count(), [this](boost::system::error_code const& _ec) + { + if (_ec) + clog(NodeTableMessageDetail) << "Discovery timer was probably cancelled: " << _ec.value() << _ec.message(); + + if (_ec.value() == boost::asio::error::operation_aborted || m_timers.isStopped()) + return; + + clog(NodeTableEvent) << "performing random discovery"; + NodeID randNodeId; + crypto::Nonce::get().ref().copyTo(randNodeId.ref().cropped(0, h256::size)); + crypto::Nonce::get().ref().copyTo(randNodeId.ref().cropped(h256::size, h256::size)); + doDiscover(randNodeId); + }); +} + +unique_ptr DiscoveryDatagram::interpretUDP(bi::udp::endpoint const& _from, bytesConstRef _packet) +{ + unique_ptr decoded; + // h256 + Signature + type + RLP (smallest possible packet is empty neighbours packet which is 3 bytes) + if (_packet.size() < h256::size + Signature::size + 1 + 3) + { + clog(NodeTableWarn) << "Invalid packet (too small) from " << _from.address().to_string() << ":" << _from.port(); + return decoded; + } + bytesConstRef hashedBytes(_packet.cropped(h256::size, _packet.size() - h256::size)); + bytesConstRef signedBytes(hashedBytes.cropped(Signature::size, hashedBytes.size() - Signature::size)); + bytesConstRef signatureBytes(_packet.cropped(h256::size, Signature::size)); + bytesConstRef bodyBytes(_packet.cropped(h256::size + Signature::size + 1)); + + h256 echo(sha3(hashedBytes)); + if (!_packet.cropped(0, h256::size).contentsEqual(echo.asBytes())) + { + clog(NodeTableWarn) << "Invalid packet (bad hash) from " << _from.address().to_string() << ":" << _from.port(); + return decoded; + } + Public sourceid(dev::recover(*(Signature const*)signatureBytes.data(), sha3(signedBytes))); + if (!sourceid) + { + clog(NodeTableWarn) << "Invalid packet (bad signature) from " << _from.address().to_string() << ":" << _from.port(); + return decoded; + } + switch (signedBytes[0]) + { + case PingNode::type: + decoded.reset(new PingNode(_from, sourceid, echo)); + break; + case Pong::type: + decoded.reset(new Pong(_from, sourceid, echo)); + break; + case FindNode::type: + decoded.reset(new FindNode(_from, sourceid, echo)); + break; + case Neighbours::type: + decoded.reset(new Neighbours(_from, sourceid, echo)); + break; + default: + clog(NodeTableWarn) << "Invalid packet (unknown packet type) from " << _from.address().to_string() << ":" << _from.port(); + return decoded; + } + decoded->interpretRLP(bodyBytes); + return decoded; +} diff --git a/libp2p/NodeTable.h b/libp2p/NodeTable.h new file mode 100644 index 0000000000..c6394fded2 --- /dev/null +++ b/libp2p/NodeTable.h @@ -0,0 +1,463 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . + */ +/** @file NodeTable.h + * @author Alex Leverington + * @date 2014 + */ + +#pragma once + +#include +#include + +#include + +#include +#include "Common.h" + +namespace dev +{ +namespace p2p +{ + +/** + * NodeEntry + * @brief Entry in Node Table + */ +struct NodeEntry: public Node +{ + NodeEntry(NodeID const& _src, Public const& _pubk, NodeIPEndpoint const& _gw); + unsigned const distance; ///< Node's distance (xor of _src as integer). + bool pending = true; ///< Node will be ignored until Pong is received +}; + +enum NodeTableEventType +{ + NodeEntryAdded, + NodeEntryDropped +}; + +class NodeTable; +class NodeTableEventHandler +{ + friend class NodeTable; +public: + virtual void processEvent(NodeID const& _n, NodeTableEventType const& _e) = 0; + +protected: + /// Called by NodeTable on behalf of an implementation (Host) to process new events without blocking nodetable. + void processEvents() + { + std::list> events; + { + Guard l(x_events); + if (!m_nodeEventHandler.size()) + return; + m_nodeEventHandler.unique(); + for (auto const& n: m_nodeEventHandler) + events.push_back(std::make_pair(n,m_events[n])); + m_nodeEventHandler.clear(); + m_events.clear(); + } + for (auto const& e: events) + processEvent(e.first, e.second); + } + + /// Called by NodeTable to append event. + virtual void appendEvent(NodeID _n, NodeTableEventType _e) { Guard l(x_events); m_nodeEventHandler.push_back(_n); m_events[_n] = _e; } + + Mutex x_events; + std::list m_nodeEventHandler; + std::unordered_map m_events; +}; + +class NodeTable; +inline std::ostream& operator<<(std::ostream& _out, NodeTable const& _nodeTable); + +/** + * NodeTable using modified kademlia for node discovery and preference. + * Node table requires an IO service, creates a socket for incoming + * UDP messages and implements a kademlia-like protocol. Node requests and + * responses are used to build a node table which can be queried to + * obtain a list of potential nodes to connect to, and, passes events to + * Host whenever a node is added or removed to/from the table. + * + * Thread-safety is ensured by modifying NodeEntry details via + * shared_ptr replacement instead of mutating values. + * + * NodeTable accepts a port for UDP and will listen to the port on all available + * interfaces. + * + * [Optimization] + * @todo serialize evictions per-bucket + * @todo store evictions in map, unit-test eviction logic + * @todo store root node in table + * @todo encapsulate discover into NetworkAlgorithm (task) + * @todo expiration and sha3(id) 'to' for messages which are replies (prevents replay) + * @todo cache Ping and FindSelf + * + * [Networking] + * @todo eth/upnp/natpmp/stun/ice/etc for public-discovery + * @todo firewall + * + * [Protocol] + * @todo optimize knowledge at opposite edges; eg, s_bitsPerStep lookups. (Can be done via pointers to NodeBucket) + * @todo ^ s_bitsPerStep = 8; // Denoted by b in [Kademlia]. Bits by which address space is divided. + */ +class NodeTable: UDPSocketEvents, public std::enable_shared_from_this +{ + friend std::ostream& operator<<(std::ostream& _out, NodeTable const& _nodeTable); + using NodeSocket = UDPSocket; + using TimePoint = std::chrono::steady_clock::time_point; ///< Steady time point. + using NodeIdTimePoint = std::pair; + using EvictionTimeout = std::pair; ///< First NodeID (NodeIdTimePoint) may be evicted and replaced with second NodeID. + +public: + enum NodeRelation { Unknown = 0, Known }; + enum DiscoverType { Random = 0 }; + + /// Constructor requiring host for I/O, credentials, and IP Address and port to listen on. + NodeTable(ba::io_service& _io, KeyPair const& _alias, NodeIPEndpoint const& _endpoint, bool _enabled = true); + ~NodeTable(); + + /// Returns distance based on xor metric two node ids. Used by NodeEntry and NodeTable. + static unsigned distance(NodeID const& _a, NodeID const& _b) { u256 d = sha3(_a) ^ sha3(_b); unsigned ret; for (ret = 0; d >>= 1; ++ret) {}; return ret; } + + /// Set event handler for NodeEntryAdded and NodeEntryDropped events. + void setEventHandler(NodeTableEventHandler* _handler) { m_nodeEventHandler.reset(_handler); } + + /// Called by implementation which provided handler to process NodeEntryAdded/NodeEntryDropped events. Events are coalesced by type whereby old events are ignored. + void processEvents(); + + /// Add node. Node will be pinged and empty shared_ptr is returned if node has never been seen or NodeID is empty. + std::shared_ptr addNode(Node const& _node, NodeRelation _relation = NodeRelation::Unknown); + + /// Returns list of node ids active in node table. + std::list nodes() const; + + /// Returns node count. + unsigned count() const { return m_nodes.size(); } + + /// Returns snapshot of table. + std::list snapshot() const; + + /// Returns true if node id is in node table. + bool haveNode(NodeID const& _id) { Guard l(x_nodes); return m_nodes.count(_id) > 0; } + + /// Returns the Node to the corresponding node id or the empty Node if that id is not found. + Node node(NodeID const& _id); + +#if defined(BOOST_AUTO_TEST_SUITE) || defined(_MSC_VER) // MSVC includes access specifier in symbol name +protected: +#else +private: +#endif + + /// Constants for Kademlia, derived from address space. + + static unsigned const s_addressByteSize = h256::size; ///< Size of address type in bytes. + static unsigned const s_bits = 8 * s_addressByteSize; ///< Denoted by n in [Kademlia]. + static unsigned const s_bins = s_bits - 1; ///< Size of m_state (excludes root, which is us). + static unsigned const s_maxSteps = boost::static_log2::value; ///< Max iterations of discovery. (discover) + + /// Chosen constants + + static unsigned const s_bucketSize = 16; ///< Denoted by k in [Kademlia]. Number of nodes stored in each bucket. + static unsigned const s_alpha = 3; ///< Denoted by \alpha in [Kademlia]. Number of concurrent FindNode requests. + + /// Intervals + + /* todo: replace boost::posix_time; change constants to upper camelcase */ + std::chrono::milliseconds const c_evictionCheckInterval = std::chrono::milliseconds(75); ///< Interval at which eviction timeouts are checked. + std::chrono::milliseconds const c_reqTimeout = std::chrono::milliseconds(300); ///< How long to wait for requests (evict, find iterations). + std::chrono::milliseconds const c_bucketRefresh = std::chrono::milliseconds(7200); ///< Refresh interval prevents bucket from becoming stale. [Kademlia] + + struct NodeBucket + { + unsigned distance; + std::list> nodes; + }; + + /// Used to ping endpoint. + void ping(NodeIPEndpoint _to) const; + + /// Used ping known node. Used by node table when refreshing buckets and as part of eviction process (see evict). + void ping(NodeEntry* _n) const; + + /// Returns center node entry which describes this node and used with dist() to calculate xor metric for node table nodes. + NodeEntry center() const { return NodeEntry(m_node.id, m_node.publicKey(), m_node.endpoint); } + + /// Used by asynchronous operations to return NodeEntry which is active and managed by node table. + std::shared_ptr nodeEntry(NodeID _id); + + /// Used to discovery nodes on network which are close to the given target. + /// Sends s_alpha concurrent requests to nodes nearest to target, for nodes nearest to target, up to s_maxSteps rounds. + void doDiscover(NodeID _target, unsigned _round = 0, std::shared_ptr>> _tried = std::shared_ptr>>()); + + /// Returns nodes from node table which are closest to target. + std::vector> nearestNodeEntries(NodeID _target); + + /// Asynchronously drops _leastSeen node if it doesn't reply and adds _new node, otherwise _new node is thrown away. + void evict(std::shared_ptr _leastSeen, std::shared_ptr _new); + + /// Called whenever activity is received from a node in order to maintain node table. + void noteActiveNode(Public const& _pubk, bi::udp::endpoint const& _endpoint); + + /// Used to drop node when timeout occurs or when evict() result is to keep previous node. + void dropNode(std::shared_ptr _n); + + /// Returns references to bucket which corresponds to distance of node id. + /// @warning Only use the return reference locked x_state mutex. + // TODO p2p: Remove this method after removing offset-by-one functionality. + NodeBucket& bucket_UNSAFE(NodeEntry const* _n); + + /// General Network Events + + /// Called by m_socket when packet is received. + void onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytesConstRef _packet); + + /// Called by m_socket when socket is disconnected. + void onDisconnected(UDPSocketFace*) {} + + /// Tasks + + /// Called by evict() to ensure eviction check is scheduled to run and terminates when no evictions remain. Asynchronous. + void doCheckEvictions(); + + /// Looks up a random node at @c_bucketRefresh interval. + void doDiscovery(); + + std::unique_ptr m_nodeEventHandler; ///< Event handler for node events. + + Node m_node; ///< This node. LOCK x_state if endpoint access or mutation is required. Do not modify id. + Secret m_secret; ///< This nodes secret key. + + mutable Mutex x_nodes; ///< LOCK x_state first if both locks are required. Mutable for thread-safe copy in nodes() const. + std::unordered_map> m_nodes; ///< Known Node Endpoints + + mutable Mutex x_state; ///< LOCK x_state first if both x_nodes and x_state locks are required. + std::array m_state; ///< State of p2p node network. + + Mutex x_evictions; ///< LOCK x_evictions first if both x_nodes and x_evictions locks are required. + std::deque m_evictions; ///< Eviction timeouts. + + Mutex x_pubkDiscoverPings; ///< LOCK x_nodes first if both x_nodes and x_pubkDiscoverPings locks are required. + std::unordered_map m_pubkDiscoverPings; ///< List of pending pings where node entry wasn't created due to unkown pubk. + + Mutex x_findNodeTimeout; + std::list m_findNodeTimeout; ///< Timeouts for pending Ping and FindNode requests. + + std::shared_ptr m_socket; ///< Shared pointer for our UDPSocket; ASIO requires shared_ptr. + NodeSocket* m_socketPointer; ///< Set to m_socket.get(). Socket is created in constructor and disconnected in destructor to ensure access to pointer is safe. + + DeadlineOps m_timers; ///< this should be the last member - it must be destroyed first +}; + +inline std::ostream& operator<<(std::ostream& _out, NodeTable const& _nodeTable) +{ + _out << _nodeTable.center().address() << "\t" << "0\t" << _nodeTable.center().endpoint.address << ":" << _nodeTable.center().endpoint.udpPort << std::endl; + auto s = _nodeTable.snapshot(); + for (auto n: s) + _out << n.address() << "\t" << n.distance << "\t" << n.endpoint.address << ":" << n.endpoint.udpPort << std::endl; + return _out; +} + +struct DiscoveryDatagram: public RLPXDatagramFace +{ + /// Constructor used for sending. + DiscoveryDatagram(bi::udp::endpoint const& _to): RLPXDatagramFace(_to), ts(futureFromEpoch(std::chrono::seconds(60))) {} + + /// Constructor used for parsing inbound packets. + DiscoveryDatagram(bi::udp::endpoint const& _from, NodeID const& _fromid, h256 const& _echo): RLPXDatagramFace(_from), sourceid(_fromid), echo(_echo) {} + + // These two are set for inbound packets only. + NodeID sourceid; // sender public key (from signature) + h256 echo; // hash of encoded packet, for reply tracking + + // All discovery packets carry a timestamp, which must be greater + // than the current local time. This prevents replay attacks. + uint32_t ts = 0; + bool isExpired() const { return secondsSinceEpoch() > ts; } + + /// Decodes UDP packets. + static std::unique_ptr interpretUDP(bi::udp::endpoint const& _from, bytesConstRef _packet); +}; + +/** + * Ping packet: Sent to check if node is alive. + * PingNode is cached and regenerated after ts + t, where t is timeout. + * + * Ping is used to implement evict. When a new node is seen for + * a given bucket which is full, the least-responsive node is pinged. + * If the pinged node doesn't respond, then it is removed and the new + * node is inserted. + */ +struct PingNode: DiscoveryDatagram +{ + using DiscoveryDatagram::DiscoveryDatagram; + PingNode(NodeIPEndpoint const& _src, NodeIPEndpoint const& _dest): DiscoveryDatagram(_dest), source(_src), destination(_dest) {} + PingNode(bi::udp::endpoint const& _from, NodeID const& _fromid, h256 const& _echo): DiscoveryDatagram(_from, _fromid, _echo) {} + + static const uint8_t type = 1; + uint8_t packetType() const { return type; } + + unsigned version = 0; + NodeIPEndpoint source; + NodeIPEndpoint destination; + + void streamRLP(RLPStream& _s) const + { + _s.appendList(4); + _s << dev::p2p::c_protocolVersion; + source.streamRLP(_s); + destination.streamRLP(_s); + _s << ts; + } + void interpretRLP(bytesConstRef _bytes) + { + RLP r(_bytes, RLP::AllowNonCanon|RLP::ThrowOnFail); + version = r[0].toInt(); + source.interpretRLP(r[1]); + destination.interpretRLP(r[2]); + ts = r[3].toInt(); + } +}; + +/** + * Pong packet: Sent in response to ping + */ +struct Pong: DiscoveryDatagram +{ + Pong(NodeIPEndpoint const& _dest): DiscoveryDatagram((bi::udp::endpoint)_dest), destination(_dest) {} + Pong(bi::udp::endpoint const& _from, NodeID const& _fromid, h256 const& _echo): DiscoveryDatagram(_from, _fromid, _echo) {} + + static const uint8_t type = 2; + uint8_t packetType() const { return type; } + + NodeIPEndpoint destination; + + void streamRLP(RLPStream& _s) const + { + _s.appendList(3); + destination.streamRLP(_s); + _s << echo; + _s << ts; + } + void interpretRLP(bytesConstRef _bytes) + { + RLP r(_bytes, RLP::AllowNonCanon|RLP::ThrowOnFail); + destination.interpretRLP(r[0]); + echo = (h256)r[1]; + ts = r[2].toInt(); + } +}; + +/** + * FindNode Packet: Request k-nodes, closest to the target. + * FindNode is cached and regenerated after ts + t, where t is timeout. + * FindNode implicitly results in finding neighbours of a given node. + * + * RLP Encoded Items: 2 + * Minimum Encoded Size: 21 bytes + * Maximum Encoded Size: 30 bytes + * + * target: NodeID of node. The responding node will send back nodes closest to the target. + * + */ +struct FindNode: DiscoveryDatagram +{ + FindNode(bi::udp::endpoint _to, h512 _target): DiscoveryDatagram(_to), target(_target) {} + FindNode(bi::udp::endpoint const& _from, NodeID const& _fromid, h256 const& _echo): DiscoveryDatagram(_from, _fromid, _echo) {} + + static const uint8_t type = 3; + uint8_t packetType() const { return type; } + + h512 target; + + void streamRLP(RLPStream& _s) const + { + _s.appendList(2); _s << target << ts; + } + void interpretRLP(bytesConstRef _bytes) + { + RLP r(_bytes, RLP::AllowNonCanon|RLP::ThrowOnFail); + target = r[0].toHash(); + ts = r[1].toInt(); + } +}; + +/** + * Node Packet: One or more node packets are sent in response to FindNode. + */ +struct Neighbours: DiscoveryDatagram +{ + Neighbours(bi::udp::endpoint _to, std::vector> const& _nearest, unsigned _offset = 0, unsigned _limit = 0): DiscoveryDatagram(_to) + { + auto limit = _limit ? std::min(_nearest.size(), (size_t)(_offset + _limit)) : _nearest.size(); + for (auto i = _offset; i < limit; i++) + neighbours.push_back(Neighbour(*_nearest[i])); + } + Neighbours(bi::udp::endpoint const& _to): DiscoveryDatagram(_to) {} + Neighbours(bi::udp::endpoint const& _from, NodeID const& _fromid, h256 const& _echo): DiscoveryDatagram(_from, _fromid, _echo) {} + + struct Neighbour + { + Neighbour(Node const& _node): endpoint(_node.endpoint), node(_node.id) {} + Neighbour(RLP const& _r): endpoint(_r) { node = h512(_r[3].toBytes()); } + NodeIPEndpoint endpoint; + NodeID node; + void streamRLP(RLPStream& _s) const { _s.appendList(4); endpoint.streamRLP(_s, NodeIPEndpoint::StreamInline); _s << node; } + }; + + static const uint8_t type = 4; + uint8_t packetType() const { return type; } + + std::vector neighbours; + + void streamRLP(RLPStream& _s) const + { + _s.appendList(2); + _s.appendList(neighbours.size()); + for (auto const& n: neighbours) + n.streamRLP(_s); + _s << ts; + } + void interpretRLP(bytesConstRef _bytes) + { + RLP r(_bytes, RLP::AllowNonCanon|RLP::ThrowOnFail); + for (auto const& n: r[0]) + neighbours.emplace_back(n); + ts = r[1].toInt(); + } +}; + +struct NodeTableWarn: public LogChannel { static const char* name(); static const int verbosity = 0; }; +struct NodeTableNote: public LogChannel { static const char* name(); static const int verbosity = 1; }; +struct NodeTableMessageSummary: public LogChannel { static const char* name(); static const int verbosity = 2; }; +struct NodeTableMessageDetail: public LogChannel { static const char* name(); static const int verbosity = 5; }; +struct NodeTableConnect: public LogChannel { static const char* name(); static const int verbosity = 10; }; +struct NodeTableEvent: public LogChannel { static const char* name(); static const int verbosity = 10; }; +struct NodeTableTimer: public LogChannel { static const char* name(); static const int verbosity = 10; }; +struct NodeTableUpdate: public LogChannel { static const char* name(); static const int verbosity = 10; }; +struct NodeTableTriviaSummary: public LogChannel { static const char* name(); static const int verbosity = 10; }; +struct NodeTableTriviaDetail: public LogChannel { static const char* name(); static const int verbosity = 11; }; +struct NodeTableAllDetail: public LogChannel { static const char* name(); static const int verbosity = 13; }; +struct NodeTableEgress: public LogChannel { static const char* name(); static const int verbosity = 14; }; +struct NodeTableIngress: public LogChannel { static const char* name(); static const int verbosity = 15; }; + +} +} diff --git a/libp2p/Peer.cpp b/libp2p/Peer.cpp new file mode 100644 index 0000000000..871c2b8265 --- /dev/null +++ b/libp2p/Peer.cpp @@ -0,0 +1,86 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Peer.cpp + * @author Alex Leverington + * @author Gav Wood + * @date 2014 + */ + +#include "Peer.h" +using namespace std; +using namespace dev; +using namespace dev::p2p; + +namespace dev +{ + +namespace p2p +{ + +bool Peer::shouldReconnect() const +{ + return id && endpoint && chrono::system_clock::now() > m_lastAttempted + chrono::seconds(fallbackSeconds()); +} + +unsigned Peer::fallbackSeconds() const +{ + if (peerType == PeerType::Required) + return 5; + switch (m_lastDisconnect) + { + case BadProtocol: + return 30 * (m_failedAttempts + 1); + case UselessPeer: + case TooManyPeers: + return 25 * (m_failedAttempts + 1); + case ClientQuit: + return 15 * (m_failedAttempts + 1); + case NoDisconnect: + default: + if (m_failedAttempts < 5) + return m_failedAttempts ? m_failedAttempts * 5 : 5; + else if (m_failedAttempts < 15) + return 25 + (m_failedAttempts - 5) * 10; + else + return 25 + 100 + (m_failedAttempts - 15) * 20; + } +} + +bool Peer::operator<(Peer const& _p) const +{ + if (isOffline() != _p.isOffline()) + return isOffline(); + else if (isOffline()) + if (m_lastAttempted == _p.m_lastAttempted) + return m_failedAttempts < _p.m_failedAttempts; + else + return m_lastAttempted < _p.m_lastAttempted; + else + if (m_score == _p.m_score) + if (m_rating == _p.m_rating) + if (m_failedAttempts == _p.m_failedAttempts) + return id < _p.id; + else + return m_failedAttempts < _p.m_failedAttempts; + else + return m_rating < _p.m_rating; + else + return m_score < _p.m_score; +} + +} +} diff --git a/libp2p/Peer.h b/libp2p/Peer.h new file mode 100644 index 0000000000..eb3f220f08 --- /dev/null +++ b/libp2p/Peer.h @@ -0,0 +1,102 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Peer.h + * @author Alex Leverington + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include "Common.h" + +namespace dev +{ + +namespace p2p +{ + +/** + * @brief Representation of connectivity state and all other pertinent Peer metadata. + * A Peer represents connectivity between two nodes, which in this case, are the host + * and remote nodes. + * + * State information necessary for loading network topology is maintained by NodeTable. + * + * @todo Implement 'bool required' + * @todo reputation: Move score, rating to capability-specific map (&& remove friend class) + * @todo reputation: implement via origin-tagged events + * @todo Populate metadata upon construction; save when destroyed. + * @todo Metadata for peers needs to be handled via a storage backend. + * Specifically, peers can be utilized in a variety of + * many-to-many relationships while also needing to modify shared instances of + * those peers. Modifying these properties via a storage backend alleviates + * Host of the responsibility. (&& remove save/restoreNetwork) + * @todo reimplement recording of historical session information on per-transport basis + * @todo move attributes into protected + */ +class Peer: public Node +{ + friend class Session; /// Allows Session to update score and rating. + friend class Host; /// For Host: saveNetwork(), restoreNetwork() + + friend class RLPXHandshake; + +public: + /// Construct Peer from Node. + Peer(Node const& _node): Node(_node) {} + + bool isOffline() const { return !m_session.lock(); } + + virtual bool operator<(Peer const& _p) const; + + /// WIP: Returns current peer rating. + int rating() const { return m_rating; } + + /// Return true if connection attempt should be made to this peer or false if + bool shouldReconnect() const; + + /// Number of times connection has been attempted to peer. + int failedAttempts() const { return m_failedAttempts; } + + /// Reason peer was previously disconnected. + DisconnectReason lastDisconnect() const { return m_lastDisconnect; } + + /// Peer session is noted as useful. + void noteSessionGood() { m_failedAttempts = 0; } + +protected: + /// Returns number of seconds to wait until attempting connection, based on attempted connection history. + unsigned fallbackSeconds() const; + + int m_score = 0; ///< All time cumulative. + int m_rating = 0; ///< Trending. + + /// Network Availability + + std::chrono::system_clock::time_point m_lastConnected; + std::chrono::system_clock::time_point m_lastAttempted; + unsigned m_failedAttempts = 0; + DisconnectReason m_lastDisconnect = NoDisconnect; ///< Reason for disconnect that happened last. + + /// Used by isOffline() and (todo) for peer to emit session information. + std::weak_ptr m_session; +}; +using Peers = std::vector; + +} +} diff --git a/libp2p/RLPXFrameCoder.cpp b/libp2p/RLPXFrameCoder.cpp new file mode 100644 index 0000000000..7992dc25bb --- /dev/null +++ b/libp2p/RLPXFrameCoder.cpp @@ -0,0 +1,290 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . + */ +/** @file RLPXFrameCoder.cpp + * @author Alex Leverington + * @date 2015 + */ + +#include "RLPXFrameCoder.h" +#include +#include +#include +#include +#include +#include "RLPxHandshake.h" +#include "RLPXPacket.h" + +static_assert(CRYPTOPP_VERSION == 570, "Wrong Crypto++ version"); + +using namespace std; +using namespace dev; +using namespace dev::p2p; +using namespace CryptoPP; + +RLPXFrameInfo::RLPXFrameInfo(bytesConstRef _header): + length((_header[0] * 256 + _header[1]) * 256 + _header[2]), + padding((16 - (length % 16)) % 16), + data(_header.cropped(3).toBytes()), + header(RLP(data, RLP::ThrowOnFail | RLP::FailIfTooSmall)), + protocolId(header[0].toInt()), + multiFrame(header.itemCount() > 1), + sequenceId(multiFrame ? header[1].toInt() : 0), + totalLength(header.itemCount() == 3 ? header[2].toInt() : 0) +{} + +namespace dev +{ +namespace p2p +{ +class RLPXFrameCoderImpl +{ +public: + /// Update state of _mac. + void updateMAC(CryptoPP::Keccak_256& _mac, bytesConstRef _seed = {}); + + CryptoPP::SecByteBlock frameEncKey; ///< Key for m_frameEnc + CryptoPP::CTR_Mode::Encryption frameEnc; ///< Encoder for egress plaintext. + + CryptoPP::SecByteBlock frameDecKey; ///< Key for m_frameDec + CryptoPP::CTR_Mode::Encryption frameDec; ///< Decoder for egress plaintext. + + CryptoPP::SecByteBlock macEncKey; /// Key for m_macEnd + CryptoPP::ECB_Mode::Encryption macEnc; /// One-way coder used by updateMAC for ingress and egress MAC updates. + + CryptoPP::Keccak_256 egressMac; ///< State of MAC for egress ciphertext. + CryptoPP::Keccak_256 ingressMac; ///< State of MAC for ingress ciphertext. + +private: + Mutex x_macEnc; ///< Mutex. +}; +} +} + +RLPXFrameCoder::~RLPXFrameCoder() +{} + +RLPXFrameCoder::RLPXFrameCoder(RLPXHandshake const& _init): + m_impl(new RLPXFrameCoderImpl) +{ + setup(_init.m_originated, _init.m_remoteEphemeral, _init.m_remoteNonce, _init.m_ecdhe, _init.m_nonce, &_init.m_ackCipher, &_init.m_authCipher); +} + +RLPXFrameCoder::RLPXFrameCoder(bool _originated, h512 const& _remoteEphemeral, h256 const& _remoteNonce, crypto::ECDHE const& _ecdhe, h256 const& _nonce, bytesConstRef _ackCipher, bytesConstRef _authCipher): + m_impl(new RLPXFrameCoderImpl) +{ + setup(_originated, _remoteEphemeral, _remoteNonce, _ecdhe, _nonce, _ackCipher, _authCipher); +} + +void RLPXFrameCoder::setup(bool _originated, h512 const& _remoteEphemeral, h256 const& _remoteNonce, crypto::ECDHE const& _ecdhe, h256 const& _nonce, bytesConstRef _ackCipher, bytesConstRef _authCipher) +{ + bytes keyMaterialBytes(64); + bytesRef keyMaterial(&keyMaterialBytes); + + // shared-secret = sha3(ecdhe-shared-secret || sha3(nonce || initiator-nonce)) + Secret ephemeralShared; + _ecdhe.agree(_remoteEphemeral, ephemeralShared); + ephemeralShared.ref().copyTo(keyMaterial.cropped(0, h256::size)); + h512 nonceMaterial; + h256 const& leftNonce = _originated ? _remoteNonce : _nonce; + h256 const& rightNonce = _originated ? _nonce : _remoteNonce; + leftNonce.ref().copyTo(nonceMaterial.ref().cropped(0, h256::size)); + rightNonce.ref().copyTo(nonceMaterial.ref().cropped(h256::size, h256::size)); + auto outRef(keyMaterial.cropped(h256::size, h256::size)); + sha3(nonceMaterial.ref(), outRef); // output h(nonces) + + sha3(keyMaterial, outRef); // output shared-secret + // token: sha3(outRef, bytesRef(&token)); -> m_host (to be saved to disk) + + // aes-secret = sha3(ecdhe-shared-secret || shared-secret) + sha3(keyMaterial, outRef); // output aes-secret + m_impl->frameEncKey.resize(h256::size); + memcpy(m_impl->frameEncKey.data(), outRef.data(), h256::size); + m_impl->frameDecKey.resize(h256::size); + memcpy(m_impl->frameDecKey.data(), outRef.data(), h256::size); + h128 iv; + m_impl->frameEnc.SetKeyWithIV(m_impl->frameEncKey, h256::size, iv.data()); + m_impl->frameDec.SetKeyWithIV(m_impl->frameDecKey, h256::size, iv.data()); + + // mac-secret = sha3(ecdhe-shared-secret || aes-secret) + sha3(keyMaterial, outRef); // output mac-secret + m_impl->macEncKey.resize(h256::size); + memcpy(m_impl->macEncKey.data(), outRef.data(), h256::size); + m_impl->macEnc.SetKey(m_impl->macEncKey, h256::size); + + // Initiator egress-mac: sha3(mac-secret^recipient-nonce || auth-sent-init) + // ingress-mac: sha3(mac-secret^initiator-nonce || auth-recvd-ack) + // Recipient egress-mac: sha3(mac-secret^initiator-nonce || auth-sent-ack) + // ingress-mac: sha3(mac-secret^recipient-nonce || auth-recvd-init) + + (*(h256*)outRef.data() ^ _remoteNonce).ref().copyTo(keyMaterial); + bytesConstRef egressCipher = _originated ? _authCipher : _ackCipher; + keyMaterialBytes.resize(h256::size + egressCipher.size()); + keyMaterial.retarget(keyMaterialBytes.data(), keyMaterialBytes.size()); + egressCipher.copyTo(keyMaterial.cropped(h256::size, egressCipher.size())); + m_impl->egressMac.Update(keyMaterial.data(), keyMaterial.size()); + + // recover mac-secret by re-xoring remoteNonce + (*(h256*)keyMaterial.data() ^ _remoteNonce ^ _nonce).ref().copyTo(keyMaterial); + bytesConstRef ingressCipher = _originated ? _ackCipher : _authCipher; + keyMaterialBytes.resize(h256::size + ingressCipher.size()); + keyMaterial.retarget(keyMaterialBytes.data(), keyMaterialBytes.size()); + ingressCipher.copyTo(keyMaterial.cropped(h256::size, ingressCipher.size())); + m_impl->ingressMac.Update(keyMaterial.data(), keyMaterial.size()); +} + +void RLPXFrameCoder::writeFrame(uint16_t _protocolType, bytesConstRef _payload, bytes& o_bytes) +{ + RLPStream header; + uint32_t len = (uint32_t)_payload.size(); + header.appendRaw(bytes({byte((len >> 16) & 0xff), byte((len >> 8) & 0xff), byte(len & 0xff)})); + header.appendList(1) << _protocolType; + writeFrame(header, _payload, o_bytes); +} + +void RLPXFrameCoder::writeFrame(uint16_t _protocolType, uint16_t _seqId, bytesConstRef _payload, bytes& o_bytes) +{ + RLPStream header; + uint32_t len = (uint32_t)_payload.size(); + header.appendRaw(bytes({byte((len >> 16) & 0xff), byte((len >> 8) & 0xff), byte(len & 0xff)})); + header.appendList(2) << _protocolType << _seqId; + writeFrame(header, _payload, o_bytes); +} + +void RLPXFrameCoder::writeFrame(uint16_t _protocolType, uint16_t _seqId, uint32_t _totalSize, bytesConstRef _payload, bytes& o_bytes) +{ + RLPStream header; + uint32_t len = (uint32_t)_payload.size(); + header.appendRaw(bytes({byte((len >> 16) & 0xff), byte((len >> 8) & 0xff), byte(len & 0xff)})); + header.appendList(3) << _protocolType << _seqId << _totalSize; + writeFrame(header, _payload, o_bytes); +} + +void RLPXFrameCoder::writeFrame(RLPStream const& _header, bytesConstRef _payload, bytes& o_bytes) +{ + // TODO: SECURITY check header values && header <= 16 bytes + bytes headerWithMac(h256::size); + bytesConstRef(&_header.out()).copyTo(bytesRef(&headerWithMac)); + m_impl->frameEnc.ProcessData(headerWithMac.data(), headerWithMac.data(), 16); + updateEgressMACWithHeader(bytesConstRef(&headerWithMac).cropped(0, 16)); + egressDigest().ref().copyTo(bytesRef(&headerWithMac).cropped(h128::size,h128::size)); + + auto padding = (16 - (_payload.size() % 16)) % 16; + o_bytes.swap(headerWithMac); + o_bytes.resize(32 + _payload.size() + padding + h128::size); + bytesRef packetRef(o_bytes.data() + 32, _payload.size()); + m_impl->frameEnc.ProcessData(packetRef.data(), _payload.data(), _payload.size()); + bytesRef paddingRef(o_bytes.data() + 32 + _payload.size(), padding); + if (padding) + m_impl->frameEnc.ProcessData(paddingRef.data(), paddingRef.data(), padding); + bytesRef packetWithPaddingRef(o_bytes.data() + 32, _payload.size() + padding); + updateEgressMACWithFrame(packetWithPaddingRef); + bytesRef macRef(o_bytes.data() + 32 + _payload.size() + padding, h128::size); + egressDigest().ref().copyTo(macRef); +} + +void RLPXFrameCoder::writeSingleFramePacket(bytesConstRef _packet, bytes& o_bytes) +{ + RLPStream header; + uint32_t len = (uint32_t)_packet.size(); + header.appendRaw(bytes({byte((len >> 16) & 0xff), byte((len >> 8) & 0xff), byte(len & 0xff)})); + header.appendRaw(bytes({0xc2,0x80,0x80})); + writeFrame(header, _packet, o_bytes); +} + +bool RLPXFrameCoder::authAndDecryptHeader(bytesRef io) +{ + asserts(io.size() == h256::size); + updateIngressMACWithHeader(io); + bytesConstRef macRef = io.cropped(h128::size, h128::size); + h128 expected = ingressDigest(); + if (*(h128*)macRef.data() != expected) + return false; + m_impl->frameDec.ProcessData(io.data(), io.data(), h128::size); + return true; +} + +bool RLPXFrameCoder::authAndDecryptFrame(bytesRef io) +{ + bytesRef cipherText(io.cropped(0, io.size() - h128::size)); + updateIngressMACWithFrame(cipherText); + bytesConstRef frameMac(io.data() + io.size() - h128::size, h128::size); + if (*(h128*)frameMac.data() != ingressDigest()) + return false; + m_impl->frameDec.ProcessData(io.data(), io.data(), io.size() - h128::size); + return true; +} + +h128 RLPXFrameCoder::egressDigest() +{ + Keccak_256 h(m_impl->egressMac); + h128 digest; + h.TruncatedFinal(digest.data(), h128::size); + return digest; +} + +h128 RLPXFrameCoder::ingressDigest() +{ + Keccak_256 h(m_impl->ingressMac); + h128 digest; + h.TruncatedFinal(digest.data(), h128::size); + return digest; +} + +void RLPXFrameCoder::updateEgressMACWithHeader(bytesConstRef _headerCipher) +{ + m_impl->updateMAC(m_impl->egressMac, _headerCipher.cropped(0, 16)); +} + +void RLPXFrameCoder::updateEgressMACWithFrame(bytesConstRef _cipher) +{ + m_impl->egressMac.Update(_cipher.data(), _cipher.size()); + m_impl->updateMAC(m_impl->egressMac); +} + +void RLPXFrameCoder::updateIngressMACWithHeader(bytesConstRef _headerCipher) +{ + m_impl->updateMAC(m_impl->ingressMac, _headerCipher.cropped(0, 16)); +} + +void RLPXFrameCoder::updateIngressMACWithFrame(bytesConstRef _cipher) +{ + m_impl->ingressMac.Update(_cipher.data(), _cipher.size()); + m_impl->updateMAC(m_impl->ingressMac); +} + +void RLPXFrameCoderImpl::updateMAC(Keccak_256& _mac, bytesConstRef _seed) +{ + if (_seed.size() && _seed.size() != h128::size) + asserts(false); + + Keccak_256 prevDigest(_mac); + h128 encDigest(h128::size); + prevDigest.TruncatedFinal(encDigest.data(), h128::size); + h128 prevDigestOut = encDigest; + + { + Guard l(x_macEnc); + macEnc.ProcessData(encDigest.data(), encDigest.data(), 16); + } + if (_seed.size()) + encDigest ^= *(h128*)_seed.data(); + else + encDigest ^= *(h128*)prevDigestOut.data(); + + // update mac for final digest + _mac.Update(encDigest.data(), h128::size); +} diff --git a/libp2p/RLPXFrameCoder.h b/libp2p/RLPXFrameCoder.h new file mode 100644 index 0000000000..91008f0e4b --- /dev/null +++ b/libp2p/RLPXFrameCoder.h @@ -0,0 +1,133 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . + */ +/** @file RLPXFrameCoder.h + * @author Alex Leverington + * @date 2015 + */ + + +#pragma once + +#include +#include +#include +#include +#include "Common.h" + +namespace dev +{ +namespace p2p +{ + +struct RLPXFrameDecryptFailed: virtual dev::Exception {}; + +/** + * @brief Encapsulation of Frame + * @todo coder integration; padding derived from coder + */ +struct RLPXFrameInfo +{ + RLPXFrameInfo() = default; + /// Constructor. frame-size || protocol-type, [sequence-id[, total-packet-size]] + RLPXFrameInfo(bytesConstRef _frameHeader); + + uint32_t const length; ///< Size of frame (excludes padding). Max: 2**24 + uint8_t const padding; ///< Length of padding which follows @length. + + bytes const data; ///< Bytes of Header. + RLP const header; ///< Header RLP. + + uint16_t const protocolId; ///< Protocol ID as negotiated by handshake. + bool const multiFrame; ///< If this frame is part of a sequence + uint16_t const sequenceId; ///< Sequence ID of frame + uint32_t const totalLength; ///< Set to total length of packet in first frame of multiframe packet +}; + +class RLPXHandshake; + +/** + * @brief Encoder/decoder transport for RLPx connection established by RLPXHandshake. + * + * @todo rename to RLPXTranscoder + * @todo Remove 'Frame' nomenclature and expect caller to provide RLPXFrame + * @todo Remove handshake as friend, remove handshake-based constructor + * + * Thread Safety + * Distinct Objects: Unsafe. + * Shared objects: Unsafe. + */ +class RLPXFrameCoder +{ + friend class RLPXFrameIOMux; + friend class Session; +public: + /// Construct; requires instance of RLPXHandshake which has encrypted ECDH key exchange (first two phases of handshake). + RLPXFrameCoder(RLPXHandshake const& _init); + + /// Construct with external key material. + RLPXFrameCoder(bool _originated, h512 const& _remoteEphemeral, h256 const& _remoteNonce, crypto::ECDHE const& _ephemeral, h256 const& _nonce, bytesConstRef _ackCipher, bytesConstRef _authCipher); + + ~RLPXFrameCoder(); + + /// Establish shared secrets and setup AES and MAC states. + void setup(bool _originated, h512 const& _remoteEphemeral, h256 const& _remoteNonce, crypto::ECDHE const& _ephemeral, h256 const& _nonce, bytesConstRef _ackCipher, bytesConstRef _authCipher); + + /// Write single-frame payload of packet(s). + void writeFrame(uint16_t _protocolType, bytesConstRef _payload, bytes& o_bytes); + + /// Write continuation frame of segmented payload. + void writeFrame(uint16_t _protocolType, uint16_t _seqId, bytesConstRef _payload, bytes& o_bytes); + + /// Write first frame of segmented or sequence-tagged payload. + void writeFrame(uint16_t _protocolType, uint16_t _seqId, uint32_t _totalSize, bytesConstRef _payload, bytes& o_bytes); + + /// Legacy. Encrypt _packet as ill-defined legacy RLPx frame. + void writeSingleFramePacket(bytesConstRef _packet, bytes& o_bytes); + + /// Authenticate and decrypt header in-place. + bool authAndDecryptHeader(bytesRef io_cipherWithMac); + + /// Authenticate and decrypt frame in-place. + bool authAndDecryptFrame(bytesRef io_cipherWithMac); + + /// Return first 16 bytes of current digest from egress mac. + h128 egressDigest(); + + /// Return first 16 bytes of current digest from ingress mac. + h128 ingressDigest(); + +protected: + void writeFrame(RLPStream const& _header, bytesConstRef _payload, bytes& o_bytes); + + /// Update state of egress MAC with frame header. + void updateEgressMACWithHeader(bytesConstRef _headerCipher); + + /// Update state of egress MAC with frame. + void updateEgressMACWithFrame(bytesConstRef _cipher); + + /// Update state of ingress MAC with frame header. + void updateIngressMACWithHeader(bytesConstRef _headerCipher); + + /// Update state of ingress MAC with frame. + void updateIngressMACWithFrame(bytesConstRef _cipher); + +private: + std::unique_ptr m_impl; +}; + +} +} \ No newline at end of file diff --git a/libp2p/RLPXFrameReader.cpp b/libp2p/RLPXFrameReader.cpp new file mode 100644 index 0000000000..b398d51e86 --- /dev/null +++ b/libp2p/RLPXFrameReader.cpp @@ -0,0 +1,95 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . + */ +/** @file RLPXFrameReader.cpp + * @author Alex Leverington + * @date 2015 + */ + +#include "RLPXFrameReader.h" + +using namespace std; +using namespace dev; +using namespace dev::p2p; + +std::vector RLPXFrameReader::demux(RLPXFrameCoder& _coder, RLPXFrameInfo const& _info, bytesRef _frame) +{ + if (!_coder.authAndDecryptFrame(_frame)) + BOOST_THROW_EXCEPTION(RLPXFrameDecryptFailed()); + + std::vector ret; + if (_frame.empty()) + // drop: bad frame (empty) + return ret; + if (_info.multiFrame && _info.totalLength && (_frame.size() - (h128::size + _info.padding) > _info.totalLength)) + // drop: bad frame (too large) + return ret; + + // trim mac + bytesConstRef buffer = _frame.cropped(0, _frame.size() - (h128::size + _info.padding)); + // continue populating multiframe packets + if (_info.multiFrame && m_incomplete.count(_info.sequenceId)) + { + uint32_t& remaining = m_incomplete.at(_info.sequenceId).second; + if (!_info.totalLength && buffer.size() > 0 && buffer.size() <= remaining) + { + remaining -= buffer.size(); + + RLPXPacket& p = m_incomplete.at(_info.sequenceId).first; + if(p.append(buffer) && !remaining) + ret.push_back(std::move(p)); + + if (remaining) + { + if (!ret.empty()) + BOOST_THROW_EXCEPTION(RLPXInvalidPacket()); + } + else + { + m_incomplete.erase(_info.sequenceId); + if (ret.empty()) + BOOST_THROW_EXCEPTION(RLPXInvalidPacket()); + } + + return ret; + } + else + m_incomplete.erase(_info.sequenceId); + } + + while (!buffer.empty()) + { + auto type = nextRLP(buffer); + if (type.empty()) + break; + buffer = buffer.cropped(type.size()); + // consume entire buffer if packet has sequence + auto packet = _info.multiFrame ? buffer : nextRLP(buffer); + buffer = buffer.cropped(packet.size()); + RLPXPacket p(m_protocolType, type); + if (!packet.empty()) + p.append(packet); + + uint32_t remaining = _info.totalLength - type.size() - packet.size(); + if (p.isValid()) + ret.push_back(std::move(p)); + else if (_info.multiFrame && remaining) + m_incomplete.insert(std::make_pair(_info.sequenceId, std::make_pair(std::move(p), remaining))); + else + BOOST_THROW_EXCEPTION(RLPXInvalidPacket()); + } + return ret; +} diff --git a/libp2p/RLPXFrameReader.h b/libp2p/RLPXFrameReader.h new file mode 100644 index 0000000000..5356ba29a5 --- /dev/null +++ b/libp2p/RLPXFrameReader.h @@ -0,0 +1,55 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . + */ +/** @file RLPXFrameReader.h + * @author Alex Leverington + * @date 2015 + */ + + +#pragma once + +#include +#include "RLPXFrameCoder.h" +#include "RLPXPacket.h" +namespace ba = boost::asio; +namespace bi = boost::asio::ip; + +namespace dev +{ +namespace p2p +{ + +/** + * RLPFrameReader + * Reads and assembles RLPX frame byte buffers into RLPX packets. Additionally + * buffers incomplete packets which are pieced into multiple frames (has sequence). + */ +class RLPXFrameReader +{ +public: + RLPXFrameReader(uint16_t _protocolType): m_protocolType(_protocolType) {} + + /// Processes a single frame returning complete packets. + std::vector demux(RLPXFrameCoder& _coder, RLPXFrameInfo const& _info, bytesRef _frame); + +protected: + uint16_t m_protocolType; + std::map> m_incomplete; ///< Sequence: Incomplete packet and bytes remaining. +}; + +} +} \ No newline at end of file diff --git a/libp2p/RLPXFrameWriter.cpp b/libp2p/RLPXFrameWriter.cpp new file mode 100644 index 0000000000..111676a966 --- /dev/null +++ b/libp2p/RLPXFrameWriter.cpp @@ -0,0 +1,162 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . + */ +/** @file RLPXFrameWriter.cpp + * @author Alex Leverington + * @date 2015 + */ + +#include "RLPXFrameWriter.h" + +using namespace std; +using namespace dev; +using namespace dev::p2p; + +const uint16_t RLPXFrameWriter::EmptyFrameLength = h128::size * 3; // header + headerMAC + frameMAC +const uint16_t RLPXFrameWriter::MinFrameDequeLength = h128::size * 4; // header + headerMAC + padded-block + frameMAC + +void RLPXFrameWriter::enque(RLPXPacket&& _p, PacketPriority _priority) +{ + if (!_p.isValid()) + return; + WriterState& qs = _priority ? m_q.first : m_q.second; + DEV_GUARDED(qs.x) + qs.q.push_back(move(_p)); +} + +void RLPXFrameWriter::enque(uint8_t _packetType, RLPStream& _payload, PacketPriority _priority) +{ + enque(RLPXPacket(m_protocolId, (RLPStream() << _packetType), _payload), _priority); +} + +size_t RLPXFrameWriter::mux(RLPXFrameCoder& _coder, unsigned _size, deque& o_toWrite) +{ + static const size_t c_blockSize = h128::size; + static const size_t c_overhead = c_blockSize * 3; // header + headerMac + frameMAC + if (_size < c_overhead + c_blockSize) + return 0; + + size_t ret = 0; + size_t frameLen = _size / 16 * 16; + bytes payload(0); + bool swapQueues = false; + while (frameLen >= c_overhead + c_blockSize) + { + bool highPending = false; + bool lowPending = false; + DEV_GUARDED(m_q.first.x) + highPending = !!m_q.first.q.size(); + DEV_GUARDED(m_q.second.x) + lowPending = !!m_q.second.q.size(); + + if (!highPending && !lowPending) + return ret; + + // first run when !swapQueues, high > low, otherwise low > high + bool high = highPending && !swapQueues ? true : !lowPending; + WriterState &qs = high ? m_q.first : m_q.second; + size_t frameAllot = (!swapQueues && highPending && lowPending ? frameLen / 2 - (c_overhead + c_blockSize) > 0 ? frameLen / 2 : frameLen : frameLen) - c_overhead; + size_t offset = 0; + size_t length = 0; + while (frameAllot >= c_blockSize) + { + // Invariants: + // !qs.writing && payload.empty() initial entry + // !qs.writing && !payload.empty() continuation (multiple packets per frame) + // qs.writing && payload.empty() initial entry, continuation (multiple frames per packet) + // qs.writing && !payload.empty() INVALID + + // write packet-type + if (qs.writing == nullptr) + { + { + Guard l(qs.x); + if (!qs.q.empty()) + qs.writing = &qs.q[0]; + else + break; + } + + // break here if we can't write-out packet-type + // or payload is packed and next packet won't fit (implicit) + qs.multiFrame = qs.writing->size() > frameAllot; + assert(qs.writing->type().size()); + if (qs.writing->type().size() > frameAllot || (qs.multiFrame && !payload.empty())) + { + qs.writing = nullptr; + qs.remaining = 0; + qs.multiFrame = false; + break; + } + else if (qs.multiFrame) + qs.sequence = ++m_sequenceId; + + frameAllot -= qs.writing->type().size(); + payload += qs.writing->type(); + + qs.remaining = qs.writing->data().size(); + } + + // write payload w/remaining allotment + assert(qs.multiFrame || (!qs.multiFrame && frameAllot >= qs.remaining)); + if (frameAllot && qs.remaining) + { + offset = qs.writing->data().size() - qs.remaining; + length = qs.remaining <= frameAllot ? qs.remaining : frameAllot; + bytes portion = bytesConstRef(&qs.writing->data()).cropped(offset, length).toBytes(); + qs.remaining -= length; + frameAllot -= portion.size(); + payload += portion; + } + + assert((!qs.remaining && (offset > 0 || !qs.multiFrame)) || (qs.remaining && qs.multiFrame)); + if (!qs.remaining) + { + qs.writing = nullptr; + DEV_GUARDED(qs.x) + qs.q.pop_front(); + ret++; + } + // qs.writing is left alone for first frame of multi-frame packet + if (qs.multiFrame) + break; + } + + if (!payload.empty()) + { + if (qs.multiFrame) + if (offset == 0 && qs.writing) + // 1st frame of segmented packet writes total-size of packet + _coder.writeFrame(m_protocolId, qs.sequence, qs.writing->size(), &payload, payload); + else + _coder.writeFrame(m_protocolId, qs.sequence, &payload, payload); + else + _coder.writeFrame(m_protocolId, &payload, payload); + + assert(frameLen >= payload.size()); + frameLen -= payload.size(); + o_toWrite.push_back(payload); + payload.resize(0); + + if (!qs.remaining && qs.multiFrame) + qs.multiFrame = false; + } + else if (swapQueues) + break; + swapQueues = true; + } + return ret; +} diff --git a/libp2p/RLPXFrameWriter.h b/libp2p/RLPXFrameWriter.h new file mode 100644 index 0000000000..e92c139f46 --- /dev/null +++ b/libp2p/RLPXFrameWriter.h @@ -0,0 +1,90 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . + */ +/** @file RLPXperimental.h + * @author Alex Leverington + * @date 2015 + */ + + +#pragma once + +#include +#include +#include "RLPXFrameCoder.h" +#include "RLPXPacket.h" +namespace ba = boost::asio; +namespace bi = boost::asio::ip; + +namespace dev +{ +namespace p2p +{ + +/** + * @brief Multiplex packets into encrypted RLPX frames. + * @todo throw when enqueued packet is invalid + * @todo use RLPXFrameInfo + */ +class RLPXFrameWriter +{ + /** + * @brief Queue and state for Writer + * Properties are used independently; + * only valid packets should be added to q + * @todo implement as class + */ + struct WriterState + { + std::deque q; + mutable Mutex x; + + RLPXPacket* writing = nullptr; + size_t remaining = 0; + bool multiFrame = false; + uint16_t sequence = -1; + }; + +public: + enum PacketPriority { PriorityLow = 0, PriorityHigh }; + static const uint16_t EmptyFrameLength; + static const uint16_t MinFrameDequeLength; + + RLPXFrameWriter(uint16_t _protocolType): m_protocolId(_protocolType) {} + RLPXFrameWriter(RLPXFrameWriter const& _s): m_protocolId(_s.m_protocolId) {} + + /// Returns total number of queued packets. Thread-safe. + size_t size() const { size_t l = 0; size_t h = 0; DEV_GUARDED(m_q.first.x) h = m_q.first.q.size(); DEV_GUARDED(m_q.second.x) l = m_q.second.q.size(); return l + h; } + + /// Moves @_payload output to queue, to be muxed into frames by mux() when network buffer is ready for writing. Thread-safe. + void enque(uint8_t _packetType, RLPStream& _payload, PacketPriority _priority = PriorityLow); + + /// Returns number of packets framed and outputs frames to o_bytes. Not thread-safe. + size_t mux(RLPXFrameCoder& _coder, unsigned _size, std::deque& o_toWrite); + + /// Moves @_p to queue, to be muxed into frames by mux() when network buffer is ready for writing. Thread-safe. + void enque(RLPXPacket&& _p, PacketPriority _priority = PriorityLow); + + uint16_t protocolId() const { return m_protocolId; } + +private: + uint16_t const m_protocolId; + std::pair m_q; // High, Low frame queues + uint16_t m_sequenceId = 0; // Sequence ID +}; + +} +} diff --git a/libp2p/RLPXPacket.h b/libp2p/RLPXPacket.h new file mode 100644 index 0000000000..f68f70cfbd --- /dev/null +++ b/libp2p/RLPXPacket.h @@ -0,0 +1,71 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . + */ +/** @file RLPXPacket.h + * @author Alex Leverington + * @date 2015 + */ + +#pragma once + +#include +#include "Common.h" + +namespace dev +{ +namespace p2p +{ + +struct RLPXInvalidPacket: virtual dev::Exception {}; + +static bytesConstRef nextRLP(bytesConstRef _b) { try { RLP r(_b, RLP::AllowNonCanon); return _b.cropped(0, std::min((size_t)r.actualSize(), _b.size())); } catch(...) {} return bytesConstRef(); } + +/** + * RLPX Packet + */ +class RLPXPacket +{ +public: + /// Construct packet. RLPStream data is invalidated. + RLPXPacket(uint8_t _capId, RLPStream& _type, RLPStream& _data): m_cap(_capId), m_type(_type.out()), m_data(_data.out()) {} + + /// Construct packet from single bytestream. RLPStream data is invalidated. + RLPXPacket(uint8_t _capId, bytesConstRef _in): m_cap(_capId), m_type(nextRLP(_in).toBytes()) { if (_in.size() > m_type.size()) { m_data.resize(_in.size() - m_type.size()); _in.cropped(m_type.size()).copyTo(&m_data); } } + + RLPXPacket(RLPXPacket const& _p) = delete; + RLPXPacket(RLPXPacket&& _p): m_cap(_p.m_cap), m_type(_p.m_type), m_data(_p.m_data) {} + + bytes const& type() const { return m_type; } + + bytes const& data() const { return m_data; } + + uint8_t cap() const { return m_cap; } + + size_t size() const { try { return RLP(m_type).actualSize() + RLP(m_data, RLP::LaissezFaire).actualSize(); } catch(...) { return 0; } } + + /// Appends byte data and returns if packet is valid. + bool append(bytesConstRef _in) { auto offset = m_data.size(); m_data.resize(offset + _in.size()); _in.copyTo(bytesRef(&m_data).cropped(offset)); return isValid(); } + + virtual bool isValid() const noexcept { try { return !(m_type.empty() && m_data.empty()) && RLP(m_type).actualSize() == m_type.size() && RLP(m_data).actualSize() == m_data.size(); } catch (...) {} return false; } + +protected: + uint8_t m_cap; + bytes m_type; + bytes m_data; +}; + +} +} \ No newline at end of file diff --git a/libp2p/RLPXSocket.h b/libp2p/RLPXSocket.h new file mode 100644 index 0000000000..96464b1d34 --- /dev/null +++ b/libp2p/RLPXSocket.h @@ -0,0 +1,55 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . + */ +/** @file RLPXSocket.h + * @author Alex Leverington + * @date 2015 + */ + +#pragma once + +#include "Common.h" + +namespace dev +{ +namespace p2p +{ + +/** + * @brief Shared pointer wrapper for ASIO TCP socket. + * + * Thread Safety + * Distinct Objects: Safe. + * Shared objects: Unsafe. + * * an instance method must not be called concurrently + */ +class RLPXSocket: public std::enable_shared_from_this +{ +public: + RLPXSocket(ba::io_service& _ioService): m_socket(_ioService) {} + ~RLPXSocket() { close(); } + + bool isConnected() const { return m_socket.is_open(); } + void close() { try { boost::system::error_code ec; m_socket.shutdown(bi::tcp::socket::shutdown_both, ec); if (m_socket.is_open()) m_socket.close(); } catch (...){} } + bi::tcp::endpoint remoteEndpoint() { boost::system::error_code ec; return m_socket.remote_endpoint(ec); } + bi::tcp::socket& ref() { return m_socket; } + +protected: + bi::tcp::socket m_socket; +}; + +} +} diff --git a/libp2p/RLPXSocketIO.cpp b/libp2p/RLPXSocketIO.cpp new file mode 100644 index 0000000000..dfdf18ffe7 --- /dev/null +++ b/libp2p/RLPXSocketIO.cpp @@ -0,0 +1,115 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . + */ +/** @file RLPXSocketIO.cpp + * @author Alex Leverington + * @date 2015 + */ + +#include "RLPXSocketIO.h" + +#include +using namespace std; +using namespace dev; +using namespace dev::p2p; + +uint32_t const RLPXSocketIO::MinFrameSize = h128::size * 3; // header + block + mac +uint32_t const RLPXSocketIO::MaxPacketSize = 1 << 24; +uint16_t const RLPXSocketIO::DefaultInitialCapacity = 8 << 8; + +RLPXSocketIO::RLPXSocketIO(unsigned _protCount, RLPXFrameCoder& _coder, bi::tcp::socket& _socket, bool _flowControl, size_t _initialCapacity): + m_flowControl(_flowControl), + m_coder(_coder), + m_socket(_socket), + m_writers(writers(_protCount)), + m_egressCapacity(m_flowControl ? _initialCapacity : MaxPacketSize * m_writers.size()) +{} + +vector RLPXSocketIO::writers(unsigned _capacity) +{ + vector ret; + for (unsigned i = 0; i < _capacity; i++) + ret.push_back(RLPXFrameWriter(i)); + return ret; +} + +void RLPXSocketIO::send(unsigned _protocolType, unsigned _type, RLPStream& _payload) +{ + if (!m_socket.is_open()) + return; // TCPSocketNotOpen + m_writers.at(_protocolType).enque(_type, _payload); + bool wasEmtpy = false; + DEV_GUARDED(x_queued) + wasEmtpy = (++m_queued == 1); + if (wasEmtpy) + doWrite(); +} + +void RLPXSocketIO::doWrite() +{ + m_toSend.clear(); + + size_t capacity = 0; + DEV_GUARDED(x_queued) + capacity = min(m_egressCapacity, MaxPacketSize); + + size_t active = 0; + for (auto const& w: m_writers) + if (w.size()) + active += 1; + size_t dequed = 0; + size_t protFrameSize = capacity / active; + if (protFrameSize >= MinFrameSize) + for (auto& w: m_writers) + dequed += w.mux(m_coder, protFrameSize, m_toSend); + + if (dequed) + write(dequed); + else + deferWrite(); +} + +void RLPXSocketIO::deferWrite() +{ + auto self(shared_from_this()); + m_congestion.reset(new ba::deadline_timer(m_socket.get_io_service())); + m_congestion->expires_from_now(boost::posix_time::milliseconds(50)); + m_congestion->async_wait([=](boost::system::error_code const& _ec) { m_congestion.reset(); if (!_ec) doWrite(); }); +} + +void RLPXSocketIO::write(size_t _dequed) +{ + auto self(shared_from_this()); + if (m_toSend.empty()) + return; + + ba::async_write(m_socket, ba::buffer(m_toSend[0]), [this, self, _dequed](boost::system::error_code ec, size_t written) + { + if (ec) + return; // TCPSocketWriteError + + bool reschedule = false; + DEV_GUARDED(x_queued) + { + if (m_flowControl) + m_egressCapacity -= written; + m_queued -= _dequed; + reschedule = m_queued > 0; + } + if (reschedule) + doWrite(); + }); +} diff --git a/libp2p/RLPXSocketIO.h b/libp2p/RLPXSocketIO.h new file mode 100644 index 0000000000..2ecae23d78 --- /dev/null +++ b/libp2p/RLPXSocketIO.h @@ -0,0 +1,69 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . + */ +/** @file RLPXSocketIO.h + * @author Alex Leverington + * @date 2015 + */ + +#pragma once + +#include "RLPXFrameWriter.h" +namespace ba = boost::asio; +namespace bi = boost::asio::ip; + +namespace dev +{ +namespace p2p +{ + +class RLPXSocketIO: public std::enable_shared_from_this +{ +public: + static uint32_t const MinFrameSize; + static uint32_t const MaxPacketSize; + static uint16_t const DefaultInitialCapacity; + + RLPXSocketIO(unsigned _protCount, RLPXFrameCoder& _coder, bi::tcp::socket& _socket, bool _flowControl = true, size_t _initialCapacity = DefaultInitialCapacity); + + void send(unsigned _protocolType, unsigned _type, RLPStream& _payload); + + void doWrite(); + +private: + static std::vector writers(unsigned _capacity); + + void deferWrite(); + + void write(size_t _dequed); + + bool const m_flowControl; ///< True if flow control is enabled. + + RLPXFrameCoder& m_coder; ///< Encoder/decoder of frame payloads. + bi::tcp::socket& m_socket; + + std::deque m_toSend; ///< Reusable byte buffer for pending socket writes. + + std::vector m_writers; ///< Write queues for each protocol. TODO: map to bytes (of capability) + std::unique_ptr m_congestion; ///< Scheduled when writes are deferred due to congestion. + + Mutex x_queued; + unsigned m_queued = 0; ///< Track total queued packets to ensure single write loop + uint32_t m_egressCapacity; +}; + +} +} \ No newline at end of file diff --git a/libp2p/RLPxHandshake.cpp b/libp2p/RLPxHandshake.cpp new file mode 100644 index 0000000000..e55b9949fb --- /dev/null +++ b/libp2p/RLPxHandshake.cpp @@ -0,0 +1,453 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . + */ +/** @file RLPXHandshake.cpp + * @author Alex Leverington + * @date 2015 + */ + +#include "Host.h" +#include "Session.h" +#include "Peer.h" +#include "RLPxHandshake.h" +#include "libethereum/NodeConnParamsManager.h" +#include "libdevcrypto/Rsa.h" +#include "libdevcore/Hash.h" +#include + +using namespace std; +using namespace dev; +using namespace dev::p2p; +using namespace dev::crypto; + +void RLPXHandshake::writeAuth() +{ + clog(NetP2PConnect) << "p2p.connect.egress sending auth to " << m_socket->remoteEndpoint(); + m_auth.resize(Signature::size + h256::size + Public::size + h256::size + 1); + bytesRef sig(&m_auth[0], Signature::size); + bytesRef hepubk(&m_auth[Signature::size], h256::size); + bytesRef pubk(&m_auth[Signature::size + h256::size], Public::size); + bytesRef nonce(&m_auth[Signature::size + h256::size + Public::size], h256::size); + + // E(remote-pubk, S(ecdhe-random, ecdh-shared-secret^nonce) || H(ecdhe-random-pubk) || pubk || nonce || 0x0) + Secret staticShared; + crypto::ecdh::agree(m_host->m_alias.sec(), m_remote, staticShared); + sign(m_ecdhe.seckey(), staticShared.makeInsecure() ^ m_nonce).ref().copyTo(sig); + sha3(m_ecdhe.pubkey().ref(), hepubk); + m_host->m_alias.pub().ref().copyTo(pubk); + m_nonce.ref().copyTo(nonce); + m_auth[m_auth.size() - 1] = 0x0; + encryptECIES(m_remote, &m_auth, m_authCipher); + + auto self(shared_from_this()); + ba::async_write(m_socket->ref(), ba::buffer(m_authCipher), [this, self](boost::system::error_code ec, std::size_t) + { + transition(ec); + }); +} + +void RLPXHandshake::writeAck() +{ + clog(NetP2PConnect) << "p2p.connect.ingress sending ack to " << m_socket->remoteEndpoint(); + m_ack.resize(Public::size + h256::size + 1); + bytesRef epubk(&m_ack[0], Public::size); + bytesRef nonce(&m_ack[Public::size], h256::size); + m_ecdhe.pubkey().ref().copyTo(epubk); + m_nonce.ref().copyTo(nonce); + m_ack[m_ack.size() - 1] = 0x0; + encryptECIES(m_remote, &m_ack, m_ackCipher); + + auto self(shared_from_this()); + ba::async_write(m_socket->ref(), ba::buffer(m_ackCipher), [this, self](boost::system::error_code ec, std::size_t) + { + transition(ec); + }); +} + +void RLPXHandshake::writeAckEIP8() +{ + clog(NetP2PConnect) << "p2p.connect.ingress sending EIP-8 ack to " << m_socket->remoteEndpoint(); + + RLPStream rlp; + rlp.appendList(3) + << m_ecdhe.pubkey() + << m_nonce + << c_rlpxVersion; + m_ack = rlp.out(); + int padAmount(rand()%100 + 100); + m_ack.resize(m_ack.size() + padAmount, 0); + + bytes prefix(2); + toBigEndian(m_ack.size() + c_eciesOverhead, prefix); + encryptECIES(m_remote, bytesConstRef(&prefix), &m_ack, m_ackCipher); + m_ackCipher.insert(m_ackCipher.begin(), prefix.begin(), prefix.end()); + + auto self(shared_from_this()); + ba::async_write(m_socket->ref(), ba::buffer(m_ackCipher), [this, self](boost::system::error_code ec, std::size_t) + { + transition(ec); + }); +} + +void RLPXHandshake::setAuthValues(Signature const& _sig, Public const& _remotePubk, h256 const& _remoteNonce, uint64_t _remoteVersion) +{ + _remotePubk.ref().copyTo(m_remote.ref()); + _remoteNonce.ref().copyTo(m_remoteNonce.ref()); + m_remoteVersion = _remoteVersion; + Secret sharedSecret; + crypto::ecdh::agree(m_host->m_alias.sec(), _remotePubk, sharedSecret); + m_remoteEphemeral = recover(_sig, sharedSecret.makeInsecure() ^ _remoteNonce); +} + +void RLPXHandshake::readAuth() +{ + clog(NetP2PConnect) << "p2p.connect.ingress receiving auth from " << m_socket->remoteEndpoint(); + m_authCipher.resize(307); + auto self(shared_from_this()); + ba::async_read(m_socket->ref(), ba::buffer(m_authCipher, 307), [this, self](boost::system::error_code ec, std::size_t) + { + if (ec) + transition(ec); + else if (decryptECIES(m_host->m_alias.sec(), bytesConstRef(&m_authCipher), m_auth)) + { + bytesConstRef data(&m_auth); + Signature sig(data.cropped(0, Signature::size)); + Public pubk(data.cropped(Signature::size + h256::size, Public::size)); + h256 nonce(data.cropped(Signature::size + h256::size + Public::size, h256::size)); + setAuthValues(sig, pubk, nonce, 4); + transition(); + } + else + readAuthEIP8(); + }); +} + +void RLPXHandshake::readAuthEIP8() +{ + assert(m_authCipher.size() == 307); + uint16_t size(m_authCipher[0]<<8 | m_authCipher[1]); + clog(NetP2PConnect) << "p2p.connect.ingress receiving " << size << "bytes EIP-8 auth from " << m_socket->remoteEndpoint(); + m_authCipher.resize((size_t)size + 2); + auto rest = ba::buffer(ba::buffer(m_authCipher) + 307); + auto self(shared_from_this()); + ba::async_read(m_socket->ref(), rest, [this, self](boost::system::error_code ec, std::size_t) + { + bytesConstRef ct(&m_authCipher); + if (ec) + transition(ec); + else if (decryptECIES(m_host->m_alias.sec(), ct.cropped(0, 2), ct.cropped(2), m_auth)) + { + RLP rlp(m_auth, RLP::ThrowOnFail | RLP::FailIfTooSmall); + setAuthValues( + rlp[0].toHash(), + rlp[1].toHash(), + rlp[2].toHash(), + rlp[3].toInt() + ); + m_nextState = AckAuthEIP8; + transition(); + } + else + { + clog(NetP2PConnect) << "p2p.connect.ingress auth decrypt failed for" << m_socket->remoteEndpoint(); + m_nextState = Error; + transition(); + } + }); +} + +void RLPXHandshake::readAck() +{ + clog(NetP2PConnect) << "p2p.connect.egress receiving ack from " << m_socket->remoteEndpoint(); + m_ackCipher.resize(210); + auto self(shared_from_this()); + ba::async_read(m_socket->ref(), ba::buffer(m_ackCipher, 210), [this, self](boost::system::error_code ec, std::size_t) + { + if (ec) + transition(ec); + else if (decryptECIES(m_host->m_alias.sec(), bytesConstRef(&m_ackCipher), m_ack)) + { + bytesConstRef(&m_ack).cropped(0, Public::size).copyTo(m_remoteEphemeral.ref()); + bytesConstRef(&m_ack).cropped(Public::size, h256::size).copyTo(m_remoteNonce.ref()); + m_remoteVersion = 4; + transition(); + } + else + readAckEIP8(); + }); +} + +void RLPXHandshake::readAckEIP8() +{ + assert(m_ackCipher.size() == 210); + uint16_t size(m_ackCipher[0]<<8 | m_ackCipher[1]); + clog(NetP2PConnect) << "p2p.connect.egress receiving " << size << "bytes EIP-8 ack from " << m_socket->remoteEndpoint(); + m_ackCipher.resize((size_t)size + 2); + auto rest = ba::buffer(ba::buffer(m_ackCipher) + 210); + auto self(shared_from_this()); + ba::async_read(m_socket->ref(), rest, [this, self](boost::system::error_code ec, std::size_t) + { + bytesConstRef ct(&m_ackCipher); + if (ec) + transition(ec); + else if (decryptECIES(m_host->m_alias.sec(), ct.cropped(0, 2), ct.cropped(2), m_ack)) + { + RLP rlp(m_ack, RLP::ThrowOnFail | RLP::FailIfTooSmall); + m_remoteEphemeral = rlp[0].toHash(); + m_remoteNonce = rlp[1].toHash(); + m_remoteVersion = rlp[2].toInt(); + transition(); + } + else + { + clog(NetP2PConnect) << "p2p.connect.egress ack decrypt failed for " << m_socket->remoteEndpoint(); + m_nextState = Error; + transition(); + } + }); +} + +void RLPXHandshake::writeCASeed() +{ + clog(NetP2PConnect) << "p2p.connect.ingress sending CA to " << m_socket->remoteEndpoint(); + int seedKey = rand(); + if (seedKey < pow(10,7)) + { + //make sure 8 length bigger + seedKey += pow(10,7); + } + std::string str = std::to_string(seedKey).substr(0, 8); + auto self(shared_from_this()); + bytes bytesSeed(str.begin(), str.end()); + m_sendBaseData.setSeed(bytesSeed); + ba::async_write(m_socket->ref(), ba::buffer(bytesSeed), [this, self](boost::system::error_code ec, std::size_t) + { + if(ec) + { + transition(ec); + } + + }); +} + +void RLPXHandshake::readCASeed() +{ + clog(NetP2PConnect) << "p2p.connect.egress receiving CA from " << m_socket->remoteEndpoint(); + m_readBaseData.getSeed().resize(8); + auto self(shared_from_this()); + ba::async_read(m_socket->ref(), ba::buffer(m_readBaseData.getSeed()), [this, self](boost::system::error_code ec, std::size_t) + { + transition(ec); + }); +} + +void RLPXHandshake::cancel() +{ + m_cancel = true; + m_idleTimer.cancel(); + m_socket->close(); + m_io.reset(); +} + +void RLPXHandshake::error() +{ + auto connected = m_socket->isConnected(); + if (connected && !m_socket->remoteEndpoint().address().is_unspecified()) + clog(NetP2PConnect) << "Disconnecting " << m_socket->remoteEndpoint() << " (Handshake Failed)"; + else + clog(NetP2PConnect) << "Handshake Failed (Connection reset by peer)"; + + cancel(); +} + +void RLPXHandshake::transition(boost::system::error_code _ech) +{ + // reset timeout + m_idleTimer.cancel(); + + if (_ech || m_nextState == Error || m_cancel) + { + clog(NetP2PConnect) << "Handshake Failed (I/O Error:" << _ech.message() << ")"; + return error(); + } + + auto self(shared_from_this()); + assert(m_nextState != StartSession); + m_idleTimer.expires_from_now(c_timeout); + m_idleTimer.async_wait([this, self](boost::system::error_code const& _ec) + { + if (!_ec) + { + if (!m_socket->remoteEndpoint().address().is_unspecified()) + clog(NetP2PConnect) << "Disconnecting " << m_socket->remoteEndpoint() << " (Handshake Timeout)"; + cancel(); + } + }); + + if (m_nextState == New) + { + m_nextState = AckAuth; + if (m_originated) + writeAuth(); + else + readAuth(); + } + else if (m_nextState == AckAuth) + { + m_nextState = StartCA; + if (m_originated) + readAck(); + else + writeAck(); + } + else if (m_nextState == AckAuthEIP8) + { + m_nextState = StartCA; + if (m_originated) + readAck(); + else + writeAckEIP8(); + } + else if (m_nextState == StartCA) + { + m_nextState = WriteHello; + writeCASeed(); + readCASeed(); + } + else if (m_nextState == WriteHello) + { + m_nextState = ReadHello; + clog(NetP2PConnect) << (m_originated ? "p2p.connect.egress" : "p2p.connect.ingress") << "sending capabilities handshake"; + + /// This pointer will be freed if there is an error otherwise + /// it will be passed to Host which will take ownership. + m_io.reset(new RLPXFrameCoder(*this)); + + //协议进行修改,按需扩展字段 + RLPStream s; + NodeConnManagerSingleton::GetInstance().ConstructHandShakeRLP(s, m_readBaseData); + + bytes packet; + s.swapOut(packet); + m_io->writeSingleFramePacket(&packet, m_handshakeOutBuffer); + ba::async_write(m_socket->ref(), ba::buffer(m_handshakeOutBuffer), [this, self](boost::system::error_code ec, std::size_t) + { + transition(ec); + }); + } + else if (m_nextState == ReadHello) + { + // Authenticate and decrypt initial hello frame with initial RLPXFrameCoder + // and request m_host to start session. + m_nextState = StartSession; + + // read frame header + unsigned const handshakeSize = 32; + m_handshakeInBuffer.resize(handshakeSize); + ba::async_read(m_socket->ref(), boost::asio::buffer(m_handshakeInBuffer, handshakeSize), [this, self](boost::system::error_code ec, std::size_t) + { + if (ec) + transition(ec); + else + { + if (!m_io) + { + clog(NetP2PWarn) << "Internal error in handshake: RLPXFrameCoder disappeared."; + m_nextState = Error; + transition(); + return; + + } + /// authenticate and decrypt header + if (!m_io->authAndDecryptHeader(bytesRef(m_handshakeInBuffer.data(), m_handshakeInBuffer.size()))) + { + m_nextState = Error; + transition(); + return; + } + + clog(NetP2PNote) << (m_originated ? "p2p.connect.egress" : "p2p.connect.ingress") << "recvd hello header"; + + /// check frame size + bytes& header = m_handshakeInBuffer; + uint32_t frameSize = (uint32_t)(header[2]) | (uint32_t)(header[1])<<8 | (uint32_t)(header[0])<<16; + if (frameSize > 1024) + { + // all future frames: 16777216 + clog(NetP2PWarn) << (m_originated ? "p2p.connect.egress" : "p2p.connect.ingress") << "hello frame is too large" << frameSize; + m_nextState = Error; + transition(); + return; + } + + /// rlp of header has protocol-type, sequence-id[, total-packet-size] + bytes headerRLP(header.size() - 3 - h128::size); // this is always 32 - 3 - 16 = 13. wtf? + bytesConstRef(&header).cropped(3).copyTo(&headerRLP); + + /// read padded frame and mac + m_handshakeInBuffer.resize(frameSize + ((16 - (frameSize % 16)) % 16) + h128::size); + ba::async_read(m_socket->ref(), boost::asio::buffer(m_handshakeInBuffer, m_handshakeInBuffer.size()), [this, self, headerRLP](boost::system::error_code ec, std::size_t) + { + m_idleTimer.cancel(); + + if (ec) + transition(ec); + else + { + if (!m_io) + { + clog(NetP2PWarn) << "Internal error in handshake: RLPXFrameCoder disappeared."; + m_nextState = Error; + transition(); + return; + + } + bytesRef frame(&m_handshakeInBuffer); + if (!m_io->authAndDecryptFrame(frame)) + { + clog(NetTriviaSummary) << (m_originated ? "p2p.connect.egress" : "p2p.connect.ingress") << "hello frame: decrypt failed"; + m_nextState = Error; + transition(); + return; + } + + PacketType packetType = frame[0] == 0x80 ? HelloPacket : (PacketType)frame[0]; + if (packetType != HelloPacket) + { + clog(NetTriviaSummary) << (m_originated ? "p2p.connect.egress" : "p2p.connect.ingress") << "hello frame: invalid packet type"; + m_nextState = Error; + transition(); + return; + } + + clog(NetTriviaSummary) << (m_originated ? "p2p.connect.egress" : "p2p.connect.ingress") << "hello frame: success. starting session."; + try + { + RLP rlp(frame.cropped(1), RLP::ThrowOnFail | RLP::FailIfTooSmall); + m_host->startPeerSession(m_remote, rlp, move(m_io), m_socket, m_sendBaseData);// 回调 + } + catch (std::exception const& _e) + { + clog(NetWarn) << "Handshake causing an exception:" << _e.what(); + m_nextState = Error; + transition(); + } + } + }); + } + }); + } +} diff --git a/libp2p/RLPxHandshake.h b/libp2p/RLPxHandshake.h new file mode 100644 index 0000000000..9cd022413d --- /dev/null +++ b/libp2p/RLPxHandshake.h @@ -0,0 +1,162 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . + */ +/** @file RLPXHandshake.h + * @author Alex Leverington + * @date 2015 + */ + + +#pragma once + +#include +#include +#include +#include "RLPXSocket.h" +#include "RLPXFrameCoder.h" +#include "Common.h" + +#include "HandshakeCAData.h" + +namespace ba = boost::asio; +namespace bi = boost::asio::ip; + +namespace dev +{ +namespace p2p +{ + +static const unsigned c_rlpxVersion = 4; +/** + * @brief Setup inbound or outbound connection for communication over RLPXFrameCoder. + * RLPx Spec: https://github.com/ethereum/devp2p/blob/master/rlpx.md#encrypted-handshake + * + * @todo Implement StartSession transition via lambda which is passed to constructor. + * + * Thread Safety + * Distinct Objects: Safe. + * Shared objects: Unsafe. + */ +class RLPXHandshake: public std::enable_shared_from_this +{ + friend class RLPXFrameCoder; + +public: + /// Setup incoming connection. + RLPXHandshake(Host* _host, std::shared_ptr const& _socket): m_host(_host), m_originated(false), m_socket(_socket), m_idleTimer(m_socket->ref().get_io_service()) { crypto::Nonce::get().ref().copyTo(m_nonce.ref()); } + + /// Setup outbound connection. + RLPXHandshake(Host* _host, std::shared_ptr const& _socket, NodeID _remote): m_host(_host), m_remote(_remote), m_originated(true), m_socket(_socket), m_idleTimer(m_socket->ref().get_io_service()) { crypto::Nonce::get().ref().copyTo(m_nonce.ref()); } + + ~RLPXHandshake() {} + + /// Start handshake. + void start() { transition(); } + + /// Aborts the handshake. + void cancel(); + +protected: + /// Sequential states of handshake + enum State + { + Error = -1, + New, + AckAuth, + AckAuthEIP8, + WriteHello, + ReadHello, + StartSession, + StartCA + }; + + /// Write Auth message to socket and transitions to AckAuth. + void writeAuth(); + + /// Reads Auth message from socket and transitions to AckAuth. + void readAuth(); + + /// Continues reading Auth message in EIP-8 format and transitions to AckAuthEIP8. + void readAuthEIP8(); + + /// Derives ephemeral secret from signature and sets members after Auth has been decrypted. + void setAuthValues(Signature const& sig, Public const& remotePubk, h256 const& remoteNonce, uint64_t remoteVersion); + + /// Write Ack message to socket and transitions to WriteHello. + void writeAck(); + + /// Write Ack message in EIP-8 format to socket and transitions to WriteHello. + void writeAckEIP8(); + + /// Reads Auth message from socket and transitions to WriteHello. + void readAck(); + + ///Read CA seed message from socket + void readCASeed(); + + ///Write CA seed message to socket + void writeCASeed(); + + /// Continues reading Ack message in EIP-8 format and transitions to WriteHello. + void readAckEIP8(); + + /// Closes connection and ends transitions. + void error(); + + /// Performs transition for m_nextState. + virtual void transition(boost::system::error_code _ech = boost::system::error_code()); + + /// Timeout for remote to respond to transition events. Enforced by m_idleTimer and refreshed by transition(). + boost::posix_time::milliseconds const c_timeout = boost::posix_time::milliseconds(1800); + + State m_nextState = New; ///< Current or expected state of transition. + bool m_cancel = false; ///< Will be set to true if connection was canceled. + + Host* m_host; ///< Host which provides m_alias, protocolVersion(), m_clientVersion, caps(), and TCP listenPort(). + + /// Node id of remote host for socket. + NodeID m_remote; ///< Public address of remote host. + bool m_originated = false; ///< True if connection is outbound. + + /// Buffers for encoded and decoded handshake phases + bytes m_auth; ///< Plaintext of egress or ingress Auth message. + bytes m_authCipher; ///< Ciphertext of egress or ingress Auth message. + bytes m_ack; ///< Plaintext of egress or ingress Ack message. + bytes m_ackCipher; ///< Ciphertext of egress or ingress Ack message. + bytes m_handshakeOutBuffer; ///< Frame buffer for egress Hello packet. + bytes m_handshakeInBuffer; ///< Frame buffer for ingress Hello packet. + + ///CA + RLPBaseData m_readBaseData; + RLPBaseData m_sendBaseData; + + crypto::ECDHE m_ecdhe; ///< Ephemeral ECDH secret and agreement. + h256 m_nonce; ///< Nonce generated by this host for handshake. + + Public m_remoteEphemeral; ///< Remote ephemeral public key. + h256 m_remoteNonce; ///< Nonce generated by remote host for handshake. + uint64_t m_remoteVersion; + + /// Used to read and write RLPx encrypted frames for last step of handshake authentication. + /// Passed onto Host which will take ownership. + std::unique_ptr m_io; + + std::shared_ptr m_socket; ///< Socket. + boost::asio::deadline_timer m_idleTimer; ///< Timer which enforces c_timeout. +}; + +} +} diff --git a/libp2p/Session.cpp b/libp2p/Session.cpp new file mode 100644 index 0000000000..4613d76dcc --- /dev/null +++ b/libp2p/Session.cpp @@ -0,0 +1,626 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Session.cpp + * @author Gav Wood + * @author Alex Leverington + * @date 2014 + */ + +#include "Session.h" + +#include +#include +#include +#include +#include +#include "Host.h" +#include "Capability.h" +using namespace std; +using namespace dev; +using namespace dev::p2p; + +Session::Session(Host* _h, unique_ptr&& _io, std::shared_ptr const& _s, std::shared_ptr const& _n, PeerSessionInfo _info): + m_server(_h), + m_io(move(_io)), + m_socket(_s), + m_peer(_n), + m_info(_info), + m_ping(chrono::steady_clock::time_point::max()) +{ + registerFraming(0); + m_peer->m_lastDisconnect = NoDisconnect; + m_lastReceived = m_connect = chrono::steady_clock::now(); + DEV_GUARDED(x_info) + m_info.socketId = m_socket->ref().native_handle(); +} + +Session::~Session() +{ + ThreadContext tc(info().id.abridged()); + ThreadContext tc2(info().clientVersion); + clog(NetMessageSummary) << "Closing peer session :-("; + m_peer->m_lastConnected = m_peer->m_lastAttempted - chrono::seconds(1); + + // Read-chain finished for one reason or another. + for (auto& i : m_capabilities) + i.second.reset(); + + try + { + bi::tcp::socket& socket = m_socket->ref(); + if (socket.is_open()) + { + boost::system::error_code ec; + socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec); + socket.close(); + } + } + catch (...) {} + + if (m_CABaseData) + { + delete m_CABaseData; + m_CABaseData = nullptr; + } +} + +ReputationManager& Session::repMan() +{ + return m_server->repMan(); +} + +NodeID Session::id() const +{ + return m_peer ? m_peer->id : NodeID(); +} + +void Session::addRating(int _r) +{ + if (m_peer) + { + m_peer->m_rating += _r; + m_peer->m_score += _r; + if (_r >= 0) + m_peer->noteSessionGood(); + } +} + +int Session::rating() const +{ + return m_peer->m_rating; +} + +template vector randomSelection(vector const& _t, unsigned _n) +{ + if (_t.size() <= _n) + return _t; + vector ret = _t; + while (ret.size() > _n) + { + auto i = ret.begin(); + advance(i, rand() % ret.size()); + ret.erase(i); + } + return ret; +} + +// 收到数据包 +bool Session::readPacket(uint16_t _capId, PacketType _t, RLP const& _r) +{ + m_lastReceived = chrono::steady_clock::now(); + clog(NetRight) << _t << _r; + try // Generic try-catch block designed to capture RLP format errors - TODO: give decent diagnostics, make a bit more specific over what is caught. + { + // v4 frame headers are useless, offset packet type used + // v5 protocol type is in header, packet type not offset + if (_capId == 0 && _t < UserPacket) + return interpret(_t, _r); + + if (isFramingEnabled()) + { + for (auto const& i : m_capabilities) + if (i.second->c_protocolID == _capId) + return i.second->m_enabled ? i.second->interpret(_t, _r) : true; + } + else + { + for (auto const& i : m_capabilities) + if (_t >= (int)i.second->m_idOffset && _t - i.second->m_idOffset < i.second->hostCapability()->messageCount()) + return i.second->m_enabled ? i.second->interpret(_t - i.second->m_idOffset, _r) : true; + } + + return false; + } + catch (std::exception const& _e) + { + clog(NetWarn) << "Exception caught in p2p::Session::interpret(): " << _e.what() << ". PacketType: " << _t << ". RLP: " << _r; + disconnect(BadProtocol); + return true; + } + return true; +} + +bool Session::interpret(PacketType _t, RLP const& _r) +{ + switch (_t) + { + case DisconnectPacket: + { + string reason = "Unspecified"; + auto r = (DisconnectReason)_r[0].toInt(); + if (!_r[0].isInt()) + drop(BadProtocol); + else + { + reason = reasonOf(r); + clog(NetMessageSummary) << "Disconnect (reason: " << reason << ")"; + drop(DisconnectRequested); + } + break; + } + case PingPacket: + { + clog(NetTriviaSummary) << "Ping" << m_info.id; + RLPStream s; + sealAndSend(prep(s, PongPacket), 0); + break; + } + case PongPacket: + DEV_GUARDED(x_info) + { + m_info.lastPing = std::chrono::steady_clock::now() - m_ping; + clog(NetTriviaSummary) << "Latency: " << chrono::duration_cast(m_info.lastPing).count() << " ms"; + } + break; + case GetPeersPacket: + case PeersPacket: + break; + default: + return false; + } + return true; +} + +void Session::ping() +{ + RLPStream s; + sealAndSend(prep(s, PingPacket), 0); + m_ping = std::chrono::steady_clock::now(); +} + +RLPStream& Session::prep(RLPStream& _s, PacketType _id, unsigned _args) +{ + return _s.append((unsigned)_id).appendList(_args); +} + +void Session::sealAndSend(RLPStream& _s, uint16_t _protocolID) +{ + bytes b; + _s.swapOut(b); + send(move(b), _protocolID); +} + +bool Session::checkPacket(bytesConstRef _msg) +{ + if (_msg[0] > 0x7f || _msg.size() < 2) + return false; + if (RLP(_msg.cropped(1)).actualSize() + 1 != _msg.size()) + return false; + return true; +} + +void Session::send(bytes&& _msg, uint16_t _protocolID) +{ + bytesConstRef msg(&_msg); + clog(NetLeft) << RLP(msg.cropped(1)); + if (!checkPacket(msg)) + clog(NetWarn) << "INVALID PACKET CONSTRUCTED!"; + + if (!m_socket->ref().is_open()) + return; + + bool doWrite = false; + if (isFramingEnabled()) + { + DEV_GUARDED(x_framing) + { + doWrite = m_encFrames.empty(); + auto f = getFraming(_protocolID); + if (!f) + return; + + f->writer.enque(RLPXPacket(_protocolID, msg)); + multiplexAll(); + } + + if (doWrite) + writeFrames(); + } + else + { + DEV_GUARDED(x_framing) + { + m_writeQueue.push_back(std::move(_msg)); + m_writeTimeQueue.push_back(utcTime()); + doWrite = (m_writeQueue.size() == 1); + } + + if (doWrite) + write(); + } +} + +void Session::write() +{ + bytes const* out = nullptr; + u256 enter_time = 0; + DEV_GUARDED(x_framing) + { + m_io->writeSingleFramePacket(&m_writeQueue[0], m_writeQueue[0]); + out = &m_writeQueue[0]; + enter_time = m_writeTimeQueue[0]; + } + auto self(shared_from_this()); + m_start_t = utcTime(); + unsigned queue_elapsed = (unsigned)(m_start_t - enter_time); + if (queue_elapsed > 10) { + clog(NetWarn) << "Session::write queue-time=" << queue_elapsed; + } + ba::async_write(m_socket->ref(), ba::buffer(*out), [this, self](boost::system::error_code ec, std::size_t length) + { + + unsigned elapsed = (unsigned)(utcTime() - m_start_t); + if (elapsed >= 10) { + clog(NetWarn) << "ba::async_write write-time=" << elapsed << ",len=" << length << ",id=" << id(); + } + ThreadContext tc(info().id.abridged()); + ThreadContext tc2(info().clientVersion); + // must check queue, as write callback can occur following dropped() + if (ec) + { + clog(NetWarn) << "Error sending: " << ec.message(); + drop(TCPError); + return; + } + + DEV_GUARDED(x_framing) + { + m_writeQueue.pop_front(); + m_writeTimeQueue.pop_front(); + if (m_writeQueue.empty()) + return; + } + write(); + }); +} + +void Session::writeFrames() +{ + bytes const* out = nullptr; + DEV_GUARDED(x_framing) + { + if (m_encFrames.empty()) + return; + else + out = &m_encFrames[0]; + } + + m_start_t = utcTime(); + auto self(shared_from_this()); + ba::async_write(m_socket->ref(), ba::buffer(*out), [this, self](boost::system::error_code ec, std::size_t length) + { + unsigned elapsed = (unsigned)(utcTime() - m_start_t); + if (elapsed >= 10) { + clog(NetWarn) << "ba::async_write write-time=" << elapsed << ",len=" << length << ",id=" << id(); + } + ThreadContext tc(info().id.abridged()); + ThreadContext tc2(info().clientVersion); + // must check queue, as write callback can occur following dropped() + if (ec) + { + clog(NetWarn) << "Error sending: " << ec.message(); + drop(TCPError); + return; + } + + DEV_GUARDED(x_framing) + { + if (!m_encFrames.empty()) + m_encFrames.pop_front(); + + multiplexAll(); + if (m_encFrames.empty()) + return; + } + + writeFrames(); + }); +} + +void Session::drop(DisconnectReason _reason) +{ + if (m_dropped) + return; + bi::tcp::socket& socket = m_socket->ref(); + if (socket.is_open()) + try + { + boost::system::error_code ec; + clog(NetWarn) << "Closing " << socket.remote_endpoint(ec) << "(" << reasonOf(_reason) << ")"; + socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec); + socket.close(); + } + catch (...) {} + + m_peer->m_lastDisconnect = _reason; + if (_reason == BadProtocol) + { + m_peer->m_rating /= 2; + m_peer->m_score /= 2; + } + m_dropped = true; +} + +void Session::disconnect(DisconnectReason _reason) +{ + clog(NetWarn) << "Disconnecting (our reason:" << reasonOf(_reason) << ")"; + + if (m_socket->ref().is_open()) + { + RLPStream s; + prep(s, DisconnectPacket, 1) << (int)_reason; + sealAndSend(s, 0); + } + drop(_reason); +} + +void Session::start() +{ + ping(); + + if (isFramingEnabled()) + doReadFrames(); + else + doRead(); +} + +void Session::doRead() +{ + // ignore packets received while waiting to disconnect. + if (m_dropped) + return; + + auto self(shared_from_this()); + m_data.resize(h256::size); + ba::async_read(m_socket->ref(), boost::asio::buffer(m_data, h256::size), [this, self](boost::system::error_code ec, std::size_t length) + { + ThreadContext tc(info().id.abridged()); + ThreadContext tc2(info().clientVersion); + if (!checkRead(h256::size, ec, length)) + return; + else if (!m_io->authAndDecryptHeader(bytesRef(m_data.data(), length))) + { + clog(NetWarn) << "header decrypt failed"; + drop(BadProtocol); // todo: better error + return; + } + + uint16_t hProtocolId; + uint32_t hLength; + uint8_t hPadding; + try + { + RLPXFrameInfo header(bytesConstRef(m_data.data(), length)); + hProtocolId = header.protocolId; + hLength = header.length; + hPadding = header.padding; + } + catch (std::exception const& _e) + { + clog(NetWarn) << "Exception decoding frame header RLP:" << _e.what() << bytesConstRef(m_data.data(), h128::size).cropped(3); + drop(BadProtocol); + return; + } + + /// read padded frame and mac + auto tlen = hLength + hPadding + h128::size; + m_data.resize(tlen); + ba::async_read(m_socket->ref(), boost::asio::buffer(m_data, tlen), [this, self, hLength, hProtocolId, tlen](boost::system::error_code ec, std::size_t length) + { + ThreadContext tc(info().id.abridged()); + ThreadContext tc2(info().clientVersion); + if (!checkRead(tlen, ec, length)) + return; + else if (!m_io->authAndDecryptFrame(bytesRef(m_data.data(), tlen))) + { + clog(NetWarn) << "frame decrypt failed"; + drop(BadProtocol); // todo: better error + return; + } + + bytesConstRef frame(m_data.data(), hLength); + if (!checkPacket(frame)) + { + LOG(ERROR) << "Received " << frame.size() << ": " << toHex(frame) << endl; + clog(NetWarn) << "INVALID MESSAGE RECEIVED"; + disconnect(BadProtocol); + return; + } + else + { + auto packetType = (PacketType)RLP(frame.cropped(0, 1)).toInt(); + RLP r(frame.cropped(1)); + bool ok = readPacket(hProtocolId, packetType, r); + (void)ok; +#if ETH_DEBUG + if (!ok) + clog(NetWarn) << "Couldn't interpret packet." << RLP(r); +#endif + } + doRead(); + }); + }); +} + +bool Session::checkRead(std::size_t _expected, boost::system::error_code _ec, std::size_t _length) +{ + if (_ec && _ec.category() != boost::asio::error::get_misc_category() && _ec.value() != boost::asio::error::eof) + { + clog(NetConnect) << "Error reading: " << _ec.message(); + drop(TCPError); + return false; + } + else if (_ec && _length < _expected) + { + clog(NetWarn) << "Error reading - Abrupt peer disconnect: " << _ec.message(); + repMan().noteRude(*this); + drop(TCPError); + return false; + } + else if (_length != _expected) + { + // with static m_data-sized buffer this shouldn't happen unless there's a regression + // sec recommends checking anyways (instead of assert) + clog(NetWarn) << "Error reading - TCP read buffer length differs from expected frame size."; + disconnect(UserReason); + return false; + } + + return true; +} + +void Session::doReadFrames() +{ + if (m_dropped) + return; // ignore packets received while waiting to disconnect + + auto self(shared_from_this()); + m_data.resize(h256::size); + ba::async_read(m_socket->ref(), boost::asio::buffer(m_data, h256::size), [this, self](boost::system::error_code ec, std::size_t length) + { + ThreadContext tc(info().id.abridged()); + ThreadContext tc2(info().clientVersion); + if (!checkRead(h256::size, ec, length)) + return; + + DEV_GUARDED(x_framing) + { + if (!m_io->authAndDecryptHeader(bytesRef(m_data.data(), length))) + { + clog(NetWarn) << "header decrypt failed"; + drop(BadProtocol); // todo: better error + return; + } + } + + bytesConstRef rawHeader(m_data.data(), length); + try + { + RLPXFrameInfo tmpHeader(rawHeader); + } + catch (std::exception const& _e) + { + clog(NetWarn) << "Exception decoding frame header RLP:" << _e.what() << bytesConstRef(m_data.data(), h128::size).cropped(3); + drop(BadProtocol); + return; + } + + RLPXFrameInfo header(rawHeader); + auto tlen = header.length + header.padding + h128::size; // padded frame and mac + m_data.resize(tlen); + ba::async_read(m_socket->ref(), boost::asio::buffer(m_data, tlen), [this, self, tlen, header](boost::system::error_code ec, std::size_t length) + { + ThreadContext tc(info().id.abridged()); + ThreadContext tc2(info().clientVersion); + if (!checkRead(tlen, ec, length)) + return; + + bytesRef frame(m_data.data(), tlen); + vector px; + DEV_GUARDED(x_framing) + { + auto f = getFraming(header.protocolId); + if (!f) + { + clog(NetWarn) << "Unknown subprotocol " << header.protocolId; + drop(BadProtocol); + return; + } + + auto v = f->reader.demux(*m_io, header, frame); + px.swap(v); + } + + for (RLPXPacket& p : px) + { + PacketType packetType = (PacketType)RLP(p.type()).toInt(RLP::AllowNonCanon); + bool ok = readPacket(header.protocolId, packetType, RLP(p.data())); +#if ETH_DEBUG + if (!ok) + clog(NetWarn) << "Couldn't interpret packet." << RLP(p.data()); +#endif + ok = true; + (void)ok; + } + doReadFrames(); + }); + }); +} + +std::shared_ptr Session::getFraming(uint16_t _protocolID) +{ + if (m_framing.find(_protocolID) == m_framing.end()) + return nullptr; + else + return m_framing[_protocolID]; +} + +void Session::registerCapability(CapDesc const& _desc, std::shared_ptr _p) +{ + DEV_GUARDED(x_framing) + { + m_capabilities[_desc] = _p; + } +} + +void Session::registerFraming(uint16_t _id) +{ + DEV_GUARDED(x_framing) + { + if (m_framing.find(_id) == m_framing.end()) + { + std::shared_ptr f(new Session::Framing(_id)); + m_framing[_id] = f; + } + } +} + +void Session::multiplexAll() +{ + for (auto& f : m_framing) + f.second->writer.mux(*m_io, maxFrameSize(), m_encFrames); +} + +CABaseData* Session::getCABaseData() +{ + return m_CABaseData; +} + +void Session::saveCABaseData(CABaseData* baseData) +{ + m_CABaseData = baseData; +} diff --git a/libp2p/Session.h b/libp2p/Session.h new file mode 100644 index 0000000000..5c95ddf85c --- /dev/null +++ b/libp2p/Session.h @@ -0,0 +1,217 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Session.h + * @author Gav Wood + * @author Alex Leverington + * @date 2014 + */ + +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include "RLPXFrameCoder.h" +#include "RLPXSocket.h" +#include "Common.h" +#include "RLPXFrameWriter.h" +#include "RLPXFrameReader.h" +#include "SessionCAData.h" + +namespace dev +{ + +namespace p2p +{ + +class Peer; +class ReputationManager; +class SessionFace +{ +public: + virtual ~SessionFace() {} + + virtual void start() = 0; + virtual void disconnect(DisconnectReason _reason) = 0; + + virtual void ping() = 0; + + virtual bool isConnected() const = 0; + + virtual NodeID id() const = 0; + + virtual void sealAndSend(RLPStream& _s, uint16_t _protocolID) = 0; + + virtual int rating() const = 0; + virtual void addRating(int _r) = 0; + + virtual void addNote(std::string const& _k, std::string const& _v) = 0; + + virtual PeerSessionInfo info() const = 0; + virtual std::chrono::steady_clock::time_point connectionTime() = 0; + + virtual void registerCapability(CapDesc const& _desc, std::shared_ptr _p) = 0; + virtual void registerFraming(uint16_t _id) = 0; + + virtual std::map> const& capabilities() const = 0; + + virtual std::shared_ptr peer() const = 0; + + virtual std::chrono::steady_clock::time_point lastReceived() const = 0; + + virtual ReputationManager& repMan() = 0; + virtual CABaseData* getCABaseData() = 0; + virtual void saveCABaseData(CABaseData*) = 0; +}; + +/** + * @brief The Session class + * @todo Document fully. + */ +class Session: public SessionFace, public std::enable_shared_from_this +{ +public: + static bool isFramingAllowedForVersion(unsigned _version) { return _version > 4; } + + Session(Host* _server, std::unique_ptr&& _io, std::shared_ptr const& _s, std::shared_ptr const& _n, PeerSessionInfo _info); + virtual ~Session(); + + void start() override; + void disconnect(DisconnectReason _reason) override; + + void ping() override; + + bool isConnected() const override { return m_socket->ref().is_open(); } + + NodeID id() const override; + + void sealAndSend(RLPStream& _s, uint16_t _protocolID) override; + + int rating() const override; + void addRating(int _r) override; + + void addNote(std::string const& _k, std::string const& _v) override { Guard l(x_info); m_info.notes[_k] = _v; } + + PeerSessionInfo info() const override { Guard l(x_info); return m_info; } + std::chrono::steady_clock::time_point connectionTime() override { return m_connect; } + + void registerCapability(CapDesc const& _desc, std::shared_ptr _p) override; + void registerFraming(uint16_t _id) override; + + std::map> const& capabilities() const override { return m_capabilities; } + + std::shared_ptr peer() const override { return m_peer; } + + std::chrono::steady_clock::time_point lastReceived() const override { return m_lastReceived; } + + ReputationManager& repMan() override; + + CABaseData* getCABaseData(); + void saveCABaseData(CABaseData*); +private: + static RLPStream& prep(RLPStream& _s, PacketType _t, unsigned _args = 0); + + void send(bytes&& _msg, uint16_t _protocolID); + + /// Drop the connection for the reason @a _r. + void drop(DisconnectReason _r); + + /// Perform a read on the socket. + void doRead(); + void doReadFrames(); + + /// Check error code after reading and drop peer if error code. + bool checkRead(std::size_t _expected, boost::system::error_code _ec, std::size_t _length); + + /// Perform a single round of the write operation. This could end up calling itself asynchronously. + void write(); + void writeFrames(); + + /// Deliver RLPX packet to Session or Capability for interpretation. + bool readPacket(uint16_t _capId, PacketType _t, RLP const& _r); + + /// Interpret an incoming Session packet. + bool interpret(PacketType _t, RLP const& _r); + + /// @returns true iff the _msg forms a valid message for sending or receiving on the network. + static bool checkPacket(bytesConstRef _msg); + + Host* m_server; ///< The host that owns us. Never null. + + std::unique_ptr m_io; ///< Transport over which packets are sent. + std::shared_ptr m_socket; ///< Socket of peer's connection. + Mutex x_framing; ///< Mutex for the write queue. + std::deque m_writeQueue; ///< The write queue. + std::deque m_writeTimeQueue; ///< to stat queue time + std::vector m_data; ///< Buffer for ingress packet data. + bytes m_incoming; ///< Read buffer for ingress bytes. + + std::shared_ptr m_peer; ///< The Peer object. + bool m_dropped = false; ///< If true, we've already divested ourselves of this peer. We're just waiting for the reads & writes to fail before the shared_ptr goes OOS and the destructor kicks in. + + mutable Mutex x_info; + PeerSessionInfo m_info; ///< Dynamic information about this peer. + + std::chrono::steady_clock::time_point m_connect; ///< Time point of connection. + std::chrono::steady_clock::time_point m_ping; ///< Time point of last ping. + std::chrono::steady_clock::time_point m_lastReceived; ///< Time point of last message. + + std::map> m_capabilities; ///< The peer's capability set. + + // framing-related stuff (protected by x_writeQueue mutex) + struct Framing + { + Framing() = delete; + Framing(uint16_t _protocolID): writer(_protocolID), reader(_protocolID) {} + RLPXFrameWriter writer; + RLPXFrameReader reader; + }; + + std::map > m_framing; + std::deque m_encFrames; + + bool isFramingEnabled() const { return isFramingAllowedForVersion(m_info.protocolVersion); } + unsigned maxFrameSize() const { return 1024; } + std::shared_ptr getFraming(uint16_t _protocolID); + void multiplexAll(); + + CABaseData *m_CABaseData = nullptr; + unsigned m_start_t; +}; + +template +std::shared_ptr capabilityFromSession(SessionFace const& _session, u256 const& _version = PeerCap::version()) +{ + try + { + return std::static_pointer_cast(_session.capabilities().at(std::make_pair(PeerCap::name(), _version))); + } + catch (...) + { + return nullptr; + } +} + +} +} diff --git a/libp2p/SessionCAData.cpp b/libp2p/SessionCAData.cpp new file mode 100644 index 0000000000..fbd9a5bf70 --- /dev/null +++ b/libp2p/SessionCAData.cpp @@ -0,0 +1,43 @@ +#include "SessionCAData.h" + +using namespace dev::p2p; + +void CABaseData::setSign(std::string sign) +{ + m_sign = sign; +} +std::string CABaseData::getSign() +{ + return m_sign; +} + +void CABaseData::setSeed(std::string seed) +{ + m_seed = seed; +} + +std::string CABaseData::getSeed() +{ + return m_seed; +} + +std::string CABaseData::getPub256() +{ + return ""; +} + +void CABaseData::setPub256(std::string) +{ + +} + +Signature CABaseData::getNodeSign() +{ + Signature signature; + return signature; +} + +void CABaseData::setNodeSign(const Signature&) +{ + +} diff --git a/libp2p/SessionCAData.h b/libp2p/SessionCAData.h new file mode 100644 index 0000000000..15e088a584 --- /dev/null +++ b/libp2p/SessionCAData.h @@ -0,0 +1,36 @@ + +#pragma once + +#include +#include +#include "Common.h" + +using namespace dev; +namespace dev +{ + namespace p2p + { + + class CABaseData + { + public: + void setSign(std::string sign); + std::string getSign(); + void setSeed(std::string seed); + std::string getSeed(); + + virtual std::string getPub256(); + virtual void setPub256(std::string); + + virtual Signature getNodeSign(); + virtual void setNodeSign(const Signature&); + virtual ~CABaseData(){}; + private: + std::string m_seed; //随机数 + std::string m_sign; //对CA随机数信息的sign + + }; + + } + +} diff --git a/libp2p/SessionWBCAData.cpp b/libp2p/SessionWBCAData.cpp new file mode 100644 index 0000000000..03e6134552 --- /dev/null +++ b/libp2p/SessionWBCAData.cpp @@ -0,0 +1,23 @@ +#include "SessionWBCAData.h" + +using namespace dev::p2p; + +std::string WBCAData::getPub256() +{ + return m_pub256; +} + +void WBCAData::setPub256(std::string pub256) +{ + m_pub256 = pub256; +} + +Signature WBCAData::getNodeSign() +{ + return m_nodeSign; +} + +void WBCAData::setNodeSign(const Signature& _nodeSign) +{ + m_nodeSign = _nodeSign; +} diff --git a/libp2p/SessionWBCAData.h b/libp2p/SessionWBCAData.h new file mode 100644 index 0000000000..458be9ce79 --- /dev/null +++ b/libp2p/SessionWBCAData.h @@ -0,0 +1,20 @@ +#pragma once + +#include "SessionCAData.h" + +namespace dev { + + namespace p2p { + class WBCAData : public CABaseData + { + public: + virtual std::string getPub256(); + virtual void setPub256(std::string pub256); + Signature getNodeSign(); + void setNodeSign(const Signature& _nodeSign); + private: + std::string m_pub256; //CA证书内容的sha256 + Signature m_nodeSign; //对节点信息的sign + }; + } +} diff --git a/libp2p/UDP.cpp b/libp2p/UDP.cpp new file mode 100644 index 0000000000..85c85fd1ba --- /dev/null +++ b/libp2p/UDP.cpp @@ -0,0 +1,63 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . + */ +/** @file UDP.cpp + * @author Alex Leverington + * @date 2014 + */ + +#include "UDP.h" +using namespace std; +using namespace dev; +using namespace dev::p2p; + +const char* RLPXWarn::name() { return "!X!"; } +const char* RLPXNote::name() { return "-X-"; } + +h256 RLPXDatagramFace::sign(Secret const& _k) +{ + assert(packetType()); + + RLPStream rlpxstream; +// rlpxstream.appendRaw(toPublic(_k).asBytes()); // for mdc-based signature + rlpxstream.appendRaw(bytes(1, packetType())); // prefix by 1 byte for type + streamRLP(rlpxstream); + bytes rlpxBytes(rlpxstream.out()); + + bytesConstRef rlpx(&rlpxBytes); + h256 sighash(dev::sha3(rlpx)); // H(type||data) + Signature sig = dev::sign(_k, sighash); // S(H(type||data)) + + data.resize(h256::size + Signature::size + rlpx.size()); + bytesRef rlpxHash(&data[0], h256::size); + bytesRef rlpxSig(&data[h256::size], Signature::size); + bytesRef rlpxPayload(&data[h256::size + Signature::size], rlpx.size()); + + sig.ref().copyTo(rlpxSig); + rlpx.copyTo(rlpxPayload); + + bytesConstRef signedRLPx(&data[h256::size], data.size() - h256::size); + dev::sha3(signedRLPx).ref().copyTo(rlpxHash); + + return sighash; +} + +Public RLPXDatagramFace::authenticate(bytesConstRef _sig, bytesConstRef _rlp) +{ + Signature const& sig = *(Signature const*)_sig.data(); + return dev::recover(sig, sha3(_rlp)); +} + diff --git a/libp2p/UDP.h b/libp2p/UDP.h new file mode 100644 index 0000000000..d2e0200018 --- /dev/null +++ b/libp2p/UDP.h @@ -0,0 +1,279 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . + */ +/** @file UDP.h + * @author Alex Leverington + * @date 2014 + */ + +#pragma once + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include "Common.h" +namespace ba = boost::asio; +namespace bi = ba::ip; + +namespace dev +{ +namespace p2p +{ + +struct RLPXWarn: public LogChannel { static const char* name(); static const int verbosity = 0; }; +struct RLPXNote: public LogChannel { static const char* name(); static const int verbosity = 1; }; + +/** + * UDP Datagram + * @todo make data protected/functional + */ +class UDPDatagram +{ +public: + UDPDatagram(bi::udp::endpoint const& _ep): locus(_ep) {} + UDPDatagram(bi::udp::endpoint const& _ep, bytes _data): data(_data), locus(_ep) {} + bi::udp::endpoint const& endpoint() const { return locus; } + + bytes data; +protected: + bi::udp::endpoint locus; +}; + +/** + * @brief RLPX Datagram which can be signed. + */ +struct RLPXDatagramFace: public UDPDatagram +{ + static uint32_t futureFromEpoch(std::chrono::seconds _sec) { return static_cast(std::chrono::duration_cast((std::chrono::system_clock::now() + _sec).time_since_epoch()).count()); } + static uint32_t secondsSinceEpoch() { return static_cast(std::chrono::duration_cast((std::chrono::system_clock::now()).time_since_epoch()).count()); } + static Public authenticate(bytesConstRef _sig, bytesConstRef _rlp); + + RLPXDatagramFace(bi::udp::endpoint const& _ep): UDPDatagram(_ep) {} + + virtual h256 sign(Secret const& _from); + virtual uint8_t packetType() const = 0; + + virtual void streamRLP(RLPStream&) const = 0; + virtual void interpretRLP(bytesConstRef _bytes) = 0; +}; + +/** + * @brief Interface which UDPSocket will implement. + */ +struct UDPSocketFace +{ + virtual bool send(UDPDatagram const& _msg) = 0; + virtual void disconnect() = 0; +}; + +/** + * @brief Interface which a UDPSocket's owner must implement. + */ +struct UDPSocketEvents +{ + virtual void onDisconnected(UDPSocketFace*) {} + virtual void onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytesConstRef _packetData) = 0; +}; + +/** + * @brief UDP Interface + * Handler must implement UDPSocketEvents. + * + * @todo multiple endpoints (we cannot advertise 0.0.0.0) + * @todo decouple deque from UDPDatagram and add ref() to datagram for fire&forget + */ +template +class UDPSocket: UDPSocketFace, public std::enable_shared_from_this> +{ +public: + enum { maxDatagramSize = MaxDatagramSize }; + static_assert((unsigned)maxDatagramSize < 65507u, "UDP datagrams cannot be larger than 65507 bytes"); + + /// Create socket for specific endpoint. + UDPSocket(ba::io_service& _io, UDPSocketEvents& _host, bi::udp::endpoint _endpoint): m_host(_host), m_endpoint(_endpoint), m_socket(_io) { m_started.store(false); m_closed.store(true); }; + + /// Create socket which listens to all ports. + UDPSocket(ba::io_service& _io, UDPSocketEvents& _host, unsigned _port): m_host(_host), m_endpoint(bi::udp::v4(), _port), m_socket(_io) { m_started.store(false); m_closed.store(true); }; + virtual ~UDPSocket() { disconnect(); } + + /// Socket will begin listening for and delivering packets + void connect(); + + /// Send datagram. + bool send(UDPDatagram const& _datagram); + + /// Returns if socket is open. + bool isOpen() { return !m_closed; } + + /// Disconnect socket. + void disconnect() { disconnectWithError(boost::asio::error::connection_reset); } + +protected: + void doRead(); + + void doWrite(); + + void disconnectWithError(boost::system::error_code _ec); + + std::atomic m_started; ///< Atomically ensure connection is started once. Start cannot occur unless m_started is false. Managed by start and disconnectWithError. + std::atomic m_closed; ///< Connection availability. + + UDPSocketEvents& m_host; ///< Interface which owns this socket. + bi::udp::endpoint m_endpoint; ///< Endpoint which we listen to. + + Mutex x_sendQ; + std::deque m_sendQ; ///< Queue for egress data. + std::array m_recvData; ///< Buffer for ingress data. + bi::udp::endpoint m_recvEndpoint; ///< Endpoint data was received from. + bi::udp::socket m_socket; ///< Boost asio udp socket. + + Mutex x_socketError; ///< Mutex for error which can be set from host or IO thread. + boost::system::error_code m_socketError; ///< Set when shut down due to error. +}; + +template +void UDPSocket::connect() +{ + bool expect = false; + if (!m_started.compare_exchange_strong(expect, true)) + return; + + m_socket.open(bi::udp::v4()); + try + { + m_socket.bind(m_endpoint); + } + catch (...) + { + m_socket.bind(bi::udp::endpoint(bi::udp::v4(), m_endpoint.port())); + } + + // clear write queue so reconnect doesn't send stale messages + Guard l(x_sendQ); + m_sendQ.clear(); + + m_closed = false; + doRead(); +} + +template +bool UDPSocket::send(UDPDatagram const& _datagram) +{ + if (m_closed) + return false; + + Guard l(x_sendQ); + m_sendQ.push_back(_datagram); + if (m_sendQ.size() == 1) + doWrite(); + + return true; +} + +template +void UDPSocket::doRead() +{ + if (m_closed) + return; + + auto self(UDPSocket::shared_from_this()); + m_socket.async_receive_from(boost::asio::buffer(m_recvData), m_recvEndpoint, [this, self](boost::system::error_code _ec, size_t _len) + { + if (m_closed) + return disconnectWithError(_ec); + + if (_ec != boost::system::errc::success) + clog(NetWarn) << "Receiving UDP message failed. " << _ec.value() << ":" << _ec.message(); + + if (_len) + m_host.onReceived(this, m_recvEndpoint, bytesConstRef(m_recvData.data(), _len)); + doRead(); + }); +} + +template +void UDPSocket::doWrite() +{ + if (m_closed) + return; + + const UDPDatagram& datagram = m_sendQ[0]; + auto self(UDPSocket::shared_from_this()); + bi::udp::endpoint endpoint(datagram.endpoint()); + m_socket.async_send_to(boost::asio::buffer(datagram.data), endpoint, [this, self, endpoint](boost::system::error_code _ec, std::size_t) + { + if (m_closed) + return disconnectWithError(_ec); + + if (_ec != boost::system::errc::success) + clog(NetWarn) << "Failed delivering UDP message. " << _ec.value() << ":" << _ec.message(); + + Guard l(x_sendQ); + m_sendQ.pop_front(); + if (m_sendQ.empty()) + return; + doWrite(); + }); +} + +template +void UDPSocket::disconnectWithError(boost::system::error_code _ec) +{ + // If !started and already stopped, shutdown has already occured. (EOF or Operation canceled) + if (!m_started && m_closed && !m_socket.is_open() /* todo: veirfy this logic*/) + return; + + assert(_ec); + { + // disconnect-operation following prior non-zero errors are ignored + Guard l(x_socketError); + if (m_socketError != boost::system::error_code()) + return; + m_socketError = _ec; + } + // TODO: (if non-zero error) schedule high-priority writes + + // prevent concurrent disconnect + bool expected = true; + if (!m_started.compare_exchange_strong(expected, false)) + return; + + // set m_closed to true to prevent undeliverable egress messages + bool wasClosed = m_closed; + m_closed = true; + + // close sockets + boost::system::error_code ec; + m_socket.shutdown(bi::udp::socket::shutdown_both, ec); + m_socket.close(); + + // socket never started if it never left stopped-state (pre-handshake) + if (wasClosed) + return; + + m_host.onDisconnected(this); +} + +} +} diff --git a/libp2p/UPnP.cpp b/libp2p/UPnP.cpp new file mode 100644 index 0000000000..78984253a4 --- /dev/null +++ b/libp2p/UPnP.cpp @@ -0,0 +1,196 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file UPnP.cpp + * @authors: + * Gav Wood + * Lefteris Karapetsas + * @date 2014, 2015 + */ + +#include "UPnP.h" + +#include +#include +#if ETH_MINIUPNPC +#include +#include +#include +#endif +#include +#include +#include +#include +#include +using namespace std; +using namespace dev; +using namespace dev::p2p; + +UPnP::UPnP() +{ +#if ETH_MINIUPNPC + m_urls = make_shared(); + m_data = make_shared(); + + m_ok = false; + + struct UPNPDev* devlist; + struct UPNPDev* dev; + char* descXML; + int descXMLsize = 0; + int upnperror = 0; + memset(m_urls.get(), 0, sizeof(struct UPNPUrls)); + memset(m_data.get(), 0, sizeof(struct IGDdatas)); +#if MINIUPNPC_API_VERSION >= 14 + devlist = upnpDiscover(2000, NULL/*multicast interface*/, NULL/*minissdpd socket path*/, 0/*sameport*/, 0/*ipv6*/, 2/*ttl*/, &upnperror); +#else + devlist = upnpDiscover(2000, NULL/*multicast interface*/, NULL/*minissdpd socket path*/, 0/*sameport*/, 0/*ipv6*/, &upnperror); +#endif + if (devlist) + { + dev = devlist; + while (dev) + { + if (strstr (dev->st, "InternetGatewayDevice")) + break; + dev = dev->pNext; + } + if (!dev) + dev = devlist; /* defaulting to first device */ + + cnote << "UPnP device:" << dev->descURL << "[st:" << dev->st << "]"; +#if MINIUPNPC_API_VERSION >= 16 + int responsecode = 200; + descXML = (char*)miniwget(dev->descURL, &descXMLsize, 0, &responsecode); +#elif MINIUPNPC_API_VERSION >= 9 + descXML = (char*)miniwget(dev->descURL, &descXMLsize, 0); +#else + descXML = (char*)miniwget(dev->descURL, &descXMLsize); +#endif + if (descXML) + { + parserootdesc (descXML, descXMLsize, m_data.get()); + free (descXML); descXML = 0; +#if MINIUPNPC_API_VERSION >= 9 + GetUPNPUrls (m_urls.get(), m_data.get(), dev->descURL, 0); +#else + GetUPNPUrls (m_urls.get(), m_data.get(), dev->descURL); +#endif + m_ok = true; + } + freeUPNPDevlist(devlist); + } + else +#endif + { + cnote << "UPnP device not found."; + BOOST_THROW_EXCEPTION(NoUPnPDevice()); + } +} + +UPnP::~UPnP() +{ + auto r = m_reg; + for (auto i: r) + removeRedirect(i); +} + +string UPnP::externalIP() +{ +#if ETH_MINIUPNPC + char addr[16]; + if (!UPNP_GetExternalIPAddress(m_urls->controlURL, m_data->first.servicetype, addr)) + return addr; + else +#endif + return "0.0.0.0"; +} + +int UPnP::addRedirect(char const* _addr, int _port) +{ + (void)_addr; + (void)_port; +#if ETH_MINIUPNPC + if (m_urls->controlURL[0] == '\0') + { + LOG(WARNING) << "UPnP::addRedirect() called without proper initialisation?"; + return -1; + } + + // Try direct mapping first (port external, port internal). + char port_str[16]; + char ext_port_str[16]; + sprintf(port_str, "%d", _port); + if (!UPNP_AddPortMapping(m_urls->controlURL, m_data->first.servicetype, port_str, port_str, _addr, "ethereum", "TCP", NULL, NULL)) + return _port; + + // Failed - now try (random external, port internal) and cycle up to 10 times. + srand(time(NULL)); + for (unsigned i = 0; i < 10; ++i) + { + _port = rand() % (32768 - 1024) + 1024; + sprintf(ext_port_str, "%d", _port); + if (!UPNP_AddPortMapping(m_urls->controlURL, m_data->first.servicetype, ext_port_str, port_str, _addr, "ethereum", "TCP", NULL, NULL)) + return _port; + } + + // Failed. Try asking the router to give us a free external port. + if (UPNP_AddPortMapping(m_urls->controlURL, m_data->first.servicetype, port_str, NULL, _addr, "ethereum", "TCP", NULL, NULL)) + // Failed. Exit. + return 0; + + // We got mapped, but we don't know which ports we got mapped to. Now to find... + unsigned num = 0; + UPNP_GetPortMappingNumberOfEntries(m_urls->controlURL, m_data->first.servicetype, &num); + for (unsigned i = 0; i < num; ++i) + { + char extPort[16]; + char intClient[16]; + char intPort[6]; + char protocol[4]; + char desc[80]; + char enabled[4]; + char rHost[64]; + char duration[16]; + UPNP_GetGenericPortMappingEntry(m_urls->controlURL, m_data->first.servicetype, toString(i).c_str(), extPort, intClient, intPort, protocol, desc, enabled, rHost, duration); + if (string("ethereum") == desc) + { + m_reg.insert(atoi(extPort)); + return atoi(extPort); + } + } + LOG(ERROR) << "ERROR: Mapped port not found." << endl; +#endif + return 0; +} + +void UPnP::removeRedirect(int _port) +{ + (void)_port; +#if ETH_MINIUPNPC + char port_str[16]; +// int t; + printf("TB : upnp_rem_redir (%d)\n", _port); + if (m_urls->controlURL[0] == '\0') + { + printf("TB : the init was not done !\n"); + return; + } + sprintf(port_str, "%d", _port); + UPNP_DeletePortMapping(m_urls->controlURL, m_data->first.servicetype, port_str, "TCP", NULL); + m_reg.erase(_port); +#endif +} diff --git a/libp2p/UPnP.h b/libp2p/UPnP.h new file mode 100644 index 0000000000..803aa5a098 --- /dev/null +++ b/libp2p/UPnP.h @@ -0,0 +1,58 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file UPnP.h + * @authors: + * Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include +#include +#include + +struct UPNPUrls; +struct IGDdatas; + +namespace dev +{ +namespace p2p +{ + +class UPnP +{ +public: + UPnP(); + ~UPnP(); + + std::string externalIP(); + int addRedirect(char const* addr, int port); + void removeRedirect(int port); + + bool isValid() const { return m_ok; } + +private: + std::set m_reg; + bool m_ok; + std::shared_ptr m_urls; + std::shared_ptr m_data; +}; + +} +} diff --git a/libpailler/CMakeLists.txt b/libpailler/CMakeLists.txt new file mode 100644 index 0000000000..6afaf48e6a --- /dev/null +++ b/libpailler/CMakeLists.txt @@ -0,0 +1,7 @@ +aux_source_directory(. SRC_LIST) + +file(GLOB HEADERS "*.h") + +add_library(pailler ${SRC_LIST} ${HEADERS}) + +install(TARGETS pailler RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib) \ No newline at end of file diff --git a/libpailler/bn.c b/libpailler/bn.c new file mode 100644 index 0000000000..4d2110c7a7 --- /dev/null +++ b/libpailler/bn.c @@ -0,0 +1,226 @@ +#include "bn.h" + +void BN_Print(U32 *pwBN, S32 iBNWordLen) +{ + for (S32 i = iBNWordLen - 1; i >= 0; i--) + { + printf("%08X", pwBN[i]); + } + + printf("\n"); +} + +void BN_Reset(U32 *pwBN,S32 iBNWordLen) +{ + for (S32 i = 0; i < iBNWordLen; i++) + pwBN[i] = 0x0; +} + +void BN_Assign(U32 *pwDest, U32 *pwSource, S32 iBNWordLen) +{ + for (S32 i = 0; i < iBNWordLen; i++) + pwDest[i] = pwSource[i]; +} + +S32 BN_JA(U32 *pwX, U32 *pwY, S32 iBNWordLen) +{ + for (S32 i = iBNWordLen - 1; i >= 0; i--) + { + if (pwX[i] > pwY[i]) + { + return 1; + } + else + { + if (pwX[i] < pwY[i]) + { + return 0; + } + } + } + + return 0; +} + +U32 BN_Add( U32 *pwSum, U32 *pwX, U32 *pwY,S32 iBNWordLen) +{ + U64 carry = 0; + + for (S32 i = 0; i < iBNWordLen; i++) + { + carry = (U64)pwX[i] + (U64)pwY[i] + carry; + pwSum[i] = (U32)carry; + carry = carry >> 32; + } + + return (U32)carry; +} + +U32 BN_Sub(U32 *pwDiff, U32 *pwX, U32 *pwY, S32 iBNWordLen) +{ + U64 borrow = 0; + + for (S32 i = 0; i < iBNWordLen; i++) + { + borrow = (U64)pwX[i] - (U64)pwY[i] + borrow; + pwDiff[i] = (U32)borrow; + borrow = (U64)(((S64)borrow) >> 32); + } + + return (U32)borrow; +} + +void BN_Mul(U32 *pwPro, U32 *pwX, U32 *pwY, S32 iBNWordLen) +{ + U64 carry = 0; + + S32 i = iBNWordLen << 1; + BN_Reset(pwPro, i); + + for (i = 0; i < iBNWordLen; i++) + { + carry = 0; + for (S32 j = 0; j < iBNWordLen; j++) + { + carry = (U64)pwPro[i + j] + (U64)pwX[j] * (U64)pwY[i] + carry; + pwPro[i + j] = (U32)carry; + carry >>= WordLen;; + } + pwPro[i + iBNWordLen] = (U32)(carry); + } +} + +void BN_ModAdd(U32 *pwResult, U32 *pwX, U32 *pwY, U32 *pwModule, S32 iBNWordLen) +{ + U32 c = BN_Add(pwResult, pwX, pwY,iBNWordLen); + if (c == 0) + return; + + do + { + c = BN_Sub(pwResult, pwResult, pwModule,iBNWordLen); + } while (c==0); +} + +void BN_ModSub(U32 *pwResult, U32 *pwX, U32 *pwY, U32 *pwModule, S32 iBNWordLen) +{ + U32 c = BN_Sub(pwResult, pwX, pwY,iBNWordLen); + if (c == 0) + return; + + do + { + c = BN_Add(pwResult, pwResult, pwModule,iBNWordLen); + } while (c == 0); +} + +U32 BN_GetMontConst(U32 nLastU32, S32 nRadix) +{ + U64 y = 1; + U64 flag_2_i = 1; + U64 flag_last_i = 1; + + for (S32 i = 2; i <= nRadix; i++ ) + { + flag_2_i = flag_2_i << 1; + flag_last_i = (flag_last_i << 1) | 0x01; + + U64 tmp = nLastU32 * y; + tmp = tmp & flag_last_i; + if ( tmp > flag_2_i) + { + y = y + flag_2_i; + } + } + flag_2_i = flag_2_i << 1; + + return (U32)(flag_2_i - y); +} + +void BN_ModMul_Mont(U32 *pwResult, U32 *pwX, U32 *pwY, U32 *pwModule, U32 wModuleConst, S32 iBNWordLen) +{ + U32 D[BNMAXWordLen + 2]; + BN_Reset(D, BNMAXWordLen + 2); + + for (int i = 0; i < iBNWordLen; i++) + { + U64 carry = 0; + for (int j = 0; j < iBNWordLen; j++) + { + carry = (U64)D[j] + (U64)pwX[j] * (U64)pwY[i] + carry; + D[j] = (U32)carry; + carry = carry >> 32; + } + + carry = (U64)D[iBNWordLen] + carry; + D[iBNWordLen] = (U32)carry; + D[iBNWordLen + 1] = (U32)(carry >> 32); + + carry = (U64)D[0] * (U64)wModuleConst; + U32 U = (U32)carry; + carry = (U64)D[0] + (U64)U * (U64)pwModule[0]; + carry = carry >> 32; + for (int j = 1; j < iBNWordLen; j++) + { + carry = (U64)D[j] + (U64)U * (U64)pwModule[j] + carry; + D[j - 1] = (U32)carry; + carry = carry >> 32; + } + carry = (U64)D[iBNWordLen] + carry; + D[iBNWordLen - 1] = (U32)carry; + D[iBNWordLen] = D[iBNWordLen + 1] + (U32)(carry >> 32); + } + + if (D[iBNWordLen] == 0) + BN_Assign(pwResult,D, iBNWordLen); + else + BN_Sub(pwResult, D, pwModule, iBNWordLen); +} + +void BN_Random(U32 *pwBN, S32 iBNWordLen) +{ + for (S32 i = 0; i < iBNWordLen; i++) + { + U8 B0 = (U8)rand(); + U8 B1 = (U8)rand(); + U8 B2 = (U8)rand(); + U8 B3 = (U8)rand(); + pwBN[i] = ((U32)B3 << 24) | ((U32)B3 << 16) | ((U32)B3 << 8) | ((U32)B3); + } +} + +void BN_GetLastRes(U32 *pwBN, U32 *pwMod, S32 iBNWordLen) +{ + if ( BN_JA(pwMod, pwBN, iBNWordLen) == 0) + { + BN_Sub(pwBN, pwBN, pwMod, iBNWordLen); + } +} + +void BN_GetR(U32 *pwR, U32 *pwModule, S32 iBNWordLen) +{ + U32 BNT[BNMAXWordLen]; + + BN_Reset(BNT, BNMAXWordLen); + + BN_Sub(pwR, BNT, pwModule, iBNWordLen);//R = 0-N; +} + +void BN_GetR2(U32 *pwR2, U32 *pwR, U32 *pwModule, U32 wModuleConst, S32 iBNWordLen, S32 iLogLogBNWordLen) +{ + U32 BN_T1[BNMAXWordLen]; + U32 BN_T2[BNMAXWordLen]; + + BN_Reset(BN_T1, BNMAXWordLen); + BN_Reset(BN_T2, BNMAXWordLen); + + BN_ModAdd(BN_T1, pwR, pwR, pwModule, iBNWordLen);//BN_T1 = 2*R + + for (S32 i = 0; i < iLogLogBNWordLen; i ++ ) + { + BN_ModMul_Mont(BN_T2, BN_T1, BN_T1, pwModule, wModuleConst, iBNWordLen);// + BN_Assign(BN_T1, BN_T2, iBNWordLen); + } + + BN_Assign(pwR2, BN_T2, iBNWordLen); +} diff --git a/libpailler/bn.h b/libpailler/bn.h new file mode 100644 index 0000000000..84df06a692 --- /dev/null +++ b/libpailler/bn.h @@ -0,0 +1,41 @@ +#ifndef __HEADER_BN_H__ +#define __HEADER_BN_H__ + +#include "typedef.h" +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void BN_Print(U32 *pwBN,S32 iBNWordLen); +void BN_Reset(U32 *pwBN,S32 iBNWordLen); +void BN_Assign(U32 *pwDest, U32 *pwSource, S32 iBNWordLen); + +S32 BN_JE(U32 *pwX, U32 *pwY, S32 iBNWordLen); +S32 BN_JA(U32 *pwX, U32 *pwY, S32 iBNWordLen); + +U32 BN_Add( U32 *pwSum, U32 *pwX, U32 *pwY,S32 iBNWordLen); +U32 BN_Sub(U32 *pwDiff, U32 *pwX, U32 *pwY, S32 iBNWordLen); +void BN_Mul(U32 *pwPro, U32 *pwX, U32 *pwY, S32 iBNWordLen); + +void BN_ModAdd(U32 *pwResult, U32 *pwX, U32 *pwY, U32 *pwModule, S32 iBNWordLen); +void BN_ModSub(U32 *pwResult, U32 *pwX, U32 *pwY, U32 *pwModule, S32 iBNWordLen); +void BN_ModMul_Mont(U32 *pwResult, U32 *pwX, U32 *pwY, U32 *pwModule,U32 wModuleConst,S32 iBNWordLen); + +U32 BN_GetMontConst(U32 nLastWord, S32 nRadix); +void BN_GetR(U32 *pwR, U32 *pwX, S32 iBNWordLen); +void BN_GetR2(U32 *pwR2, U32 *pwR, U32 *pwModule, U32 wModuleConst, S32 iBNWordLen, S32 iLogLogBNWordLen); + +void BN_Random(U32 *pwBN, S32 iBNWordLen); +void BN_GetLastRes(U32 *pwBN, U32 *pwMod, S32 iBNWordLen); + + +#ifdef __cplusplus +} +#endif + + +#endif + diff --git a/libpailler/common.c b/libpailler/common.c new file mode 100644 index 0000000000..195b32ac49 --- /dev/null +++ b/libpailler/common.c @@ -0,0 +1,162 @@ +#include "common.h" + +S32 CharToByte(const S8 *pCharBuf, S32 charlen, U8 *pByteBuf, S32 *bytelen) +{ + S32 i = 0; + U8 hdata = 0; + U8 ldata = 0; + + S32 charlen_tmp = charlen; + if (charlen_tmp & LSBOfWord) + { + charlen_tmp += 1; + *bytelen = charlen_tmp >> 1; + if (ConvertHexChar(pCharBuf[0], &ldata) == 1) + { + pByteBuf[0] = ldata; + } + for (i = 1; i < *bytelen; i++) + { + if (ConvertHexChar(pCharBuf[2 * i - 1], &hdata) == 1) + { + if (ConvertHexChar(pCharBuf[2 * i], &ldata) == 1) + { + pByteBuf[i] = (hdata << 4) | ldata; + } + else + { + return 0; + } + } + else + { + return 0; + } + } + } + else + { + *bytelen = charlen_tmp >> 1; + for (i = 0; i < *bytelen; i++) + { + if (ConvertHexChar(pCharBuf[2 * i], &hdata) == 1) + { + if (ConvertHexChar(pCharBuf[2 * i + 1], &ldata) == 1) + { + pByteBuf[i] = (hdata << 4) | ldata; + } + else + { + return 0; + } + } + else + { + return 0; + } + } + } + + return 1; +} + +S32 ConvertHexChar(S8 ch, U8 *ch_byte) +{ + if ((ch >= '0') && (ch <= '9')) + { + + *ch_byte = (U8)(ch - 0x30); + return 1; + + } + else + { + if ((ch >= 'A') && (ch <= 'F')) + { + *ch_byte = (U8)(ch - 'A' + 0x0a); + return 1; + } + else + { + if ((ch >= 'a') && (ch <= 'f')) + { + *ch_byte = (U8)(ch - 'a' + 0x0a); + return 1; + } + } + } + + return 0; +} + +S32 ByteToBN(U8 *pByteBuf, S32 bytelen, U32 *pwBN, S32 iBNWordLen) +{ + S32 ExpLen = bytelen >> 2; + S32 Rem = bytelen & 0x00000003; + + if (Rem != 0) + { + ExpLen += 1; + } + + if (ExpLen > iBNWordLen) + { + return 0; + } + + S32 i = bytelen - 1; + S32 j = 0; + while (i >= Rem) + { + pwBN[j] = ((U32)pByteBuf[i]) | ((U32)pByteBuf[i - 1] << 8) | ((U32)pByteBuf[i - 2] << 16) | ((U32)pByteBuf[i - 3] << 24); + i -= 4; + j++; + } + + i = 0; + while (i < Rem) + { + pwBN[j] = (pwBN[j] << 8) | ((U32)pByteBuf[i]); + i++; + } + + return 1; +} + +S32 BNToByte(U32 *pwBN,S32 iBNWordLen,U8 *pByteBuf,S32 *bytelen) +{ + U8 * P = pByteBuf; + + for(S32 i = iBNWordLen - 1; i >= 0; i--) + { + U32 W = pwBN[i]; + *P++=(U8) ((W & 0xFF000000) >> 24); + *P++=(U8) ((W & 0x00FF0000) >> 16); + *P++=(U8) ((W & 0x0000FF00) >> 8); + *P++=(U8) (W & 0x000000FF) ; + } + *bytelen = iBNWordLen << 2; + + return 1; +} + +void U8_Print(U8* pwSource,S32 len) +{ + for(S32 i = 0;i> 24 ); \ + (b)[(i) + 1] = (U8) ( (n) >> 16 ); \ + (b)[(i) + 2] = (U8) ( (n) >> 8 ); \ + (b)[(i) + 3] = (U8) ( (n) ); \ +} + +#ifdef __cplusplus +extern "C" { +#endif + +S32 ConvertHexChar(S8 ch, U8 *ch_byte); +S32 CharToByte(const S8 *pCharBuf, S32 charlen, U8 *pByteBuf, S32 *bytelen); +S32 ByteToBN(U8 *pByteBuf, S32 bytelen, U32 *pwBN, S32 iBNWordLen); +S32 BNToByte(U32 *pwBN,S32 iBNWordLen,U8 *pByteBuf,S32 *bytelen); + +void U8_Print(U8* pwSource,S32 len); +S32 U8_JE(U8* pwX,U8* pwY,S32 len); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libpailler/macro.h b/libpailler/macro.h new file mode 100644 index 0000000000..f807c68ec2 --- /dev/null +++ b/libpailler/macro.h @@ -0,0 +1,35 @@ +#ifndef __HEADER_MACRO_H__ +#define __HEADER_MACRO_H__ + +#ifdef __cplusplus +extern "C"{ +#endif + +#define WRONG 0 +#define RIGHT 1 + +//macro for common bn +#define WordLen 32 +#define ByteLen 8 +#define WordByteLen (WordLen/ByteLen) +#define LSBOfWord 0x00000001 +#define MSBOfWord 0x80000000 +#define Plus 0x00000000 +#define Minus 0x00000001 + +//macro for BN in pailler +#define PaiBNBitLen 1024 +#define PaiBNWordLen 32 +#define PaiPrimeWordLen 16 +#define MAXPrimeWordLen 32 +#define Ext_PaiBNWordLen (PaiBNWordLen + 2) +#define BNMAXWordLen (2 * PaiBNWordLen + 2) +#define LogPaiBNBitLen 10 +#define LogPaiBN2BitLen 11 + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libpailler/pailler.c b/libpailler/pailler.c new file mode 100644 index 0000000000..0a831051f8 --- /dev/null +++ b/libpailler/pailler.c @@ -0,0 +1,51 @@ +#include "pailler.h" + +void PAI_HomAdd(U8 *pbBN_Result, U8 *pbBN_c1, U8 *pbBN_c2, U8 *pbBN_n, S32 iBNWordLen) +{ + /****************************/ + U32 BN_N2[BNMAXWordLen]; + U32 BN_N[BNMAXWordLen]; + U32 BN_R[BNMAXWordLen]; + U32 BN_R2[BNMAXWordLen]; + U32 BN_C1[BNMAXWordLen]; + U32 BN_C2[BNMAXWordLen]; + U32 BN_C3[BNMAXWordLen]; + U32 BN_One[BNMAXWordLen]; + U32 wModuleConst = 0; + + U8 bBN_T[8*BNMAXWordLen] = {0}; + S32 i = 0; + S32 len = 0; + /****************************/ + + BN_Reset(BN_N2, BNMAXWordLen); + BN_Reset(BN_N, BNMAXWordLen); + BN_Reset(BN_R, BNMAXWordLen); + BN_Reset(BN_R2, BNMAXWordLen); + BN_Reset(BN_C1, BNMAXWordLen); + BN_Reset(BN_C2, BNMAXWordLen); + BN_Reset(BN_C3, BNMAXWordLen); + BN_Reset(BN_One, BNMAXWordLen); + BN_One[0] = LSBOfWord; + + ByteToBN(pbBN_n, 4*iBNWordLen, BN_N, iBNWordLen); + ByteToBN(pbBN_c1, 8*iBNWordLen, BN_C1, 2*iBNWordLen); + ByteToBN(pbBN_c2, 8*iBNWordLen, BN_C2, 2*iBNWordLen); + + //n^2 + BN_Mul(BN_N2, BN_N, BN_N, iBNWordLen); + + wModuleConst = BN_GetMontConst(BN_N2[0], 32); + BN_GetR(BN_R, BN_N2, 2*iBNWordLen); + + BN_GetR2(BN_R2, BN_R, BN_N2, wModuleConst, 2*iBNWordLen, LogPaiBN2BitLen); + BN_GetLastRes(BN_R2, BN_N2, 2*iBNWordLen); + + BN_ModMul_Mont(BN_C1, BN_C1, BN_R2, BN_N2, wModuleConst, 2*iBNWordLen); + BN_ModMul_Mont(BN_C2, BN_C2, BN_R2, BN_N2, wModuleConst, 2*iBNWordLen); + BN_ModMul_Mont(BN_C3, BN_C1, BN_C2, BN_N2, wModuleConst, 2*iBNWordLen); + BN_ModMul_Mont(BN_C3, BN_C3, BN_One, BN_N2, wModuleConst, 2*iBNWordLen); + BN_GetLastRes(BN_C3, BN_N2, 2*iBNWordLen); + + BNToByte(BN_C3, 2*iBNWordLen, pbBN_Result, &len); +} \ No newline at end of file diff --git a/libpailler/pailler.h b/libpailler/pailler.h new file mode 100644 index 0000000000..d82a748d0c --- /dev/null +++ b/libpailler/pailler.h @@ -0,0 +1,20 @@ +#ifndef __HEADER_PAILLER_H__ +#define __HEADER_PAILLER_H__ + +#include "bn.h" +#include "common.h" +#include "macro.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void PAI_HomAdd(U8 *pbBN_Result, U8 *pbBN_c1, U8 *pbBN_c2, U8 *pbBN_n, S32 iBNWordLen); + +#ifdef __cplusplus +} +#endif + + +#endif + diff --git a/libpailler/typedef.h b/libpailler/typedef.h new file mode 100644 index 0000000000..30001a21f1 --- /dev/null +++ b/libpailler/typedef.h @@ -0,0 +1,27 @@ +#ifndef __HEADER_TYPEDEF_H__ +#define __HEADER_TYPEDEF_H__ + +#include +#include "macro.h" + +#ifdef __cplusplus +extern "C"{ +#endif + + typedef unsigned char U8; + typedef unsigned short U16; + typedef uint32_t U32; + typedef uint64_t U64; + + typedef char S8; + typedef short S16; + typedef int32_t S32; + typedef int64_t S64; + +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/libpbftseal/CMakeLists.txt b/libpbftseal/CMakeLists.txt new file mode 100644 index 0000000000..561424ebf5 --- /dev/null +++ b/libpbftseal/CMakeLists.txt @@ -0,0 +1,29 @@ +aux_source_directory(. SRC_LIST) + +file(GLOB HEADERS "*.h") + +add_library(pbftseal ${SRC_LIST} ${HEADERS}) + +find_package(Eth) +find_package(Dev) + +target_include_directories(pbftseal PRIVATE ..) + +include_directories(../libodbc/include + ../libodbc/include/db2_linux + ../libodbc/include/ibase + ../libodbc/include/infomix + ../libodbc/include/mysql + ../libodbc/include/odbc_linux + ../libodbc/include/pgsql + ../libodbc/include/sqlbase + ../libodbc/include/sqllite + ../libodbc/include/ss_linux + ../libodbc/include/sybase) + +target_link_libraries(pbftseal ${Dev_DEVCORE_LIBRARIES}) +target_link_libraries(pbftseal ${Dev_DEVCRYPTO_LIBRARIES}) +target_link_libraries(pbftseal ${Eth_ETHCORE_LIBRARIES}) +target_link_libraries(pbftseal ${Eth_ETHEREUM_LIBRARIES}) + +install(TARGETS pbftseal RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib) diff --git a/libpbftseal/Common.cpp b/libpbftseal/Common.cpp new file mode 100644 index 0000000000..db15c187ab --- /dev/null +++ b/libpbftseal/Common.cpp @@ -0,0 +1,22 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ + + +#include "Common.h" +using namespace std; +using namespace dev; +using namespace eth; diff --git a/libpbftseal/Common.h b/libpbftseal/Common.h new file mode 100644 index 0000000000..5dca1d85f8 --- /dev/null +++ b/libpbftseal/Common.h @@ -0,0 +1,110 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ + + +#pragma once + +#include +#include +#include +#include +#include + +namespace dev +{ + +namespace eth +{ + +enum PBFTPacketType : byte +{ + PrepareReqPacket = 0x00, + SignReqPacket = 0x01, + ViewChangeReqPacket = 0x02, + + PBFTPacketCount +}; + +// for pbft +struct PBFTMsgPacket { + u256 node_idx; + h512 node_id; + unsigned packet_id; + bytes data; // rlp data + u256 timestamp; + + PBFTMsgPacket(): node_idx(h256(0)), node_id(h512(0)), packet_id(0), timestamp(utcTime()) {} + PBFTMsgPacket(u256 _idx, h512 _id, unsigned _pid, bytesConstRef _data) + : node_idx(_idx), node_id(_id), packet_id(_pid), data(_data.toBytes()), timestamp(utcTime()) {} +}; +using PBFTMsgQueue = dev::concurrent_queue; + +struct PBFTMsg { + u256 height = Invalid256; + u256 view = Invalid256; + u256 idx = Invalid256; + u256 timestamp = Invalid256; + h256 block_hash; + Signature sig; + + virtual void streamRLPFields(RLPStream& _s) const { + _s << height << view << idx << timestamp << block_hash << sig.asBytes(); + } + virtual void populate(RLP const& _rlp) { + int field = 0; + try { + height = _rlp[field = 0].toInt(); + view = _rlp[field = 1].toInt(); + idx = _rlp[field = 2].toInt(); + timestamp = _rlp[field = 3].toInt(); + block_hash = _rlp[field = 4].toHash(RLP::VeryStrict); + sig = dev::Signature(_rlp[field = 5].toBytesConstRef()); + } catch (Exception const& _e) { + _e << errinfo_name("invalid msg format") << BadFieldError(field, toHex(_rlp[field].data().toBytes())); + throw; + } + } + + void clear() { + height = Invalid256; + view = Invalid256; + idx = Invalid256; + timestamp = Invalid256; + block_hash = h256(); + sig = Signature(); + } +}; + +struct PrepareReq : public PBFTMsg { + bytes block; + virtual void streamRLPFields(RLPStream& _s) const { PBFTMsg::streamRLPFields(_s); _s << block; } + virtual void populate(RLP const& _rlp) { + PBFTMsg::populate(_rlp); + int field = 0; + try { + block = _rlp[field = 6].toBytes(); + } catch (Exception const& _e) { + _e << errinfo_name("invalid msg format") << BadFieldError(field, toHex(_rlp[field].data().toBytes())); + throw; + } + } +}; +struct SignReq : public PBFTMsg {}; +struct ViewChangeReq : public PBFTMsg {}; + +} +} diff --git a/libpbftseal/PBFT.cpp b/libpbftseal/PBFT.cpp new file mode 100644 index 0000000000..6eec584129 --- /dev/null +++ b/libpbftseal/PBFT.cpp @@ -0,0 +1,896 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ + + +#include +#include +#include +#include +#include +#include +#include +#include "PBFT.h" +#include +using namespace std; +using namespace dev; +using namespace eth; + +static const unsigned kCollectInterval = 60; // second + +void PBFT::init() +{ + ETH_REGISTER_SEAL_ENGINE(PBFT); +} + +PBFT::PBFT() +{ +} + +void PBFT::initEnv(std::weak_ptr _host, BlockChain* _bc, OverlayDB* _db, BlockQueue *bq, KeyPair const& _key_pair, unsigned _view_timeout) +{ + Guard l(m_mutex); + + m_host = _host; + m_bc.reset(_bc); + m_stateDB.reset(_db); + m_bq.reset(bq); + + m_bc->setSignChecker([this](BlockHeader const & _header, std::vector> _sign_list) { + return checkBlockSign(_header, _sign_list); + }); + + m_key_pair = _key_pair; + + resetConfig(); + + m_view_timeout = _view_timeout; + m_consensus_block_number = 0; + m_last_consensus_time = utcTime(); //std::chrono::system_clock::now(); + m_change_cycle = 0; + m_to_view = 0; + m_leader_failed = false; + + m_last_sign_time = 0; + + m_last_collect_time = std::chrono::system_clock::now(); + + m_future_prepare_cache = std::make_pair(Invalid256, PrepareReq()); + + LOG(INFO) << "PBFT initEnv success"; +} + +void PBFT::resetConfig() { + if (!NodeConnManagerSingleton::GetInstance().getAccountType(m_key_pair.pub(), m_account_type)) { + LOG(ERROR) << "resetConfig: can't find myself id, stop sealing"; + m_cfg_err = true; + return; + } + + auto node_num = NodeConnManagerSingleton::GetInstance().getMinerNum(); + if (node_num == 0) { + LOG(ERROR) << "resetConfig: miner_num = 0, stop sealing"; + m_cfg_err = true; + return; + } + + u256 node_idx; + if (!NodeConnManagerSingleton::GetInstance().getIdx(m_key_pair.pub(), node_idx)) { + //BOOST_THROW_EXCEPTION(PbftInitFailed() << errinfo_comment("NodeID not in cfg")); + LOG(ERROR) << "resetConfig: can't find myself id, stop sealing"; + m_cfg_err = true; + return; + } + + if (node_num != m_node_num || node_idx != m_node_idx) { + m_node_num = node_num; + m_node_idx = node_idx; + m_f = (m_node_num - 1 ) / 3; + + m_prepare_cache.clear(); + m_sign_cache.clear(); + m_recv_view_change_req.clear(); + + if (!getMinerList(-1, m_miner_list)) { + LOG(ERROR) << "resetConfig: getMinerList return false"; + m_cfg_err = true; + return; + } + + if (m_miner_list.size() != m_node_num) { + LOG(ERROR) << "resetConfig: m_miner_list.size=" << m_miner_list.size() << ",m_node_num=" << m_node_num; + m_cfg_err = true; + return; + } + LOG(INFO) << "resetConfig: m_node_idx=" << m_node_idx << ", m_node_num=" << m_node_num; + } + + m_cfg_err = false; +} + +StringHashMap PBFT::jsInfo(BlockHeader const& _bi) const +{ + return { { "number", toJS(_bi.number()) }, { "timestamp", toJS(_bi.timestamp()) } }; +} + +void PBFT::generateSeal(BlockHeader const& _bi, bytes const& _block_data) +{ + Timer t; + Guard l(m_mutex); + if (!broadcastPrepareReq(_bi, _block_data)) { + LOG(ERROR) << "broadcastPrepareReq failed, " << _bi.number() << _bi.hash(WithoutSeal); + return; + } + + LOG(DEBUG) << "generateSeal, blk=" << _bi.number() << ", timecost=" << 1000 * t.elapsed(); +} + +bool PBFT::shouldSeal(Interface*) +{ + Guard l(m_mutex); + + if (m_cfg_err || m_account_type != EN_ACCOUNT_TYPE_MINER) { // 配置中找不到自己或非记账节点就不出块, + return false; + } + + std::pair ret = getLeader(); + + if (!ret.first) { + return ret.first; + } + if (ret.second != m_node_idx) { + if (auto h = m_host.lock()) { + h512 node_id = h512(0); + if (NodeConnManagerSingleton::GetInstance().getPublicKey(ret.second, node_id) && !h->isConnected(node_id)) { + LOG(ERROR) << "getLeader ret:<" << ret.first << "," << ret.second << ">" << ", need viewchange for disconnected"; + m_last_consensus_time = 0; + m_signalled.notify_all(); + } + } + return false; + } + return true; +} + +std::pair PBFT::getLeader() const { + if (m_leader_failed || m_highest_block.number() == Invalid256) { + return std::make_pair(false, Invalid256); + } + + return std::make_pair(true, (m_view + m_highest_block.number()) % m_node_num); +} + +void PBFT::reportBlock(BlockHeader const & _b, u256 const &) { + Guard l(m_mutex); + + m_highest_block = _b; + + if (m_highest_block.number() >= m_consensus_block_number) { + m_view = m_to_view = m_change_cycle = 0; + m_leader_failed = false; + m_last_consensus_time = utcTime(); + m_consensus_block_number = m_highest_block.number() + 1; + m_recv_view_change_req.clear(); + } + + resetConfig(); + + LOG(INFO) << "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Report: blk=" << m_highest_block.number() << ",hash=" << _b.hash(WithoutSeal).abridged() << ",idx=" << m_highest_block.genIndex() << ", Next: blk=" << m_consensus_block_number; +} + +void PBFT::onPBFTMsg(unsigned _id, std::shared_ptr _peer, RLP const & _r) { + if (_id <= ViewChangeReqPacket) { + //LOG(INFO) << "onPBFTMsg: id=" << _id; + u256 idx = u256(0); + if (!NodeConnManagerSingleton::GetInstance().getIdx(_peer->session()->id(), idx)) { + LOG(ERROR) << "Recv an pbft msg from unknown peer id=" << _id; + return; + } + handleMsg(_id, idx, _peer->session()->id(), _r[0]); + } else { + LOG(ERROR) << "Recv an illegal msg, id=" << _id; + } +} + +void PBFT::workLoop() { + while (isWorking()) { + try + { + checkTimeout(); + handleFutureBlock(); + collectGarbage(); + + std::unique_lock l(x_signalled); + m_signalled.wait_for(l, chrono::milliseconds(10)); + } catch (Exception &_e) { + LOG(ERROR) << _e.what(); + } + } +} + +void PBFT::handleMsg(unsigned _id, u256 const& _from, h512 const& _node, RLP const& _r) { + Guard l(m_mutex); + + auto now_time = utcTime(); + std::string key; + PBFTMsg pbft_msg; + switch (_id) { + case PrepareReqPacket: { + PrepareReq req; + req.populate(_r); + handlePrepareMsg(_from, req); + key = req.block_hash.hex(); + pbft_msg = req; + break; + } + case SignReqPacket: { + SignReq req; + req.populate(_r); + handleSignMsg(_from, req); + key = req.sig.hex(); + pbft_msg = req; + break; + } + case ViewChangeReqPacket: { + ViewChangeReq req; + req.populate(_r); + handleViewChangeMsg(_from, req); + key = req.sig.hex() + toJS(req.view); + pbft_msg = req; + break; + } + default: { + LOG(ERROR) << "Recv error msg, id=" << _id; + return; + } + } + + bool time_flag = (pbft_msg.timestamp >= now_time) || (now_time - pbft_msg.timestamp < m_view_timeout); + bool height_flag = (pbft_msg.height > m_highest_block.number()) || (m_highest_block.number() - pbft_msg.height < 10); + LOG(TRACE) << "key=" << key << ",time_flag=" << time_flag << ",height_flag=" << height_flag; + if (key.size() > 0 && time_flag && height_flag) { + std::unordered_set filter; + filter.insert(_node); + h512 gen_node_id = h512(0); + if (NodeConnManagerSingleton::GetInstance().getPublicKey(pbft_msg.idx, gen_node_id)) { + filter.insert(gen_node_id); + } + broadcastMsg(key, _id, _r.toBytes(), filter); + } +} + +void PBFT::checkTimeout() { + Timer t; + bool flag = false; + { + Guard l(m_mutex); + + auto now_time = utcTime(); + auto last_time = std::max(m_last_consensus_time, m_last_sign_time); + unsigned interval = m_view_timeout * std::pow(1.5, m_change_cycle); + if (now_time - last_time >= interval) { + m_leader_failed = true; + m_to_view += 1; + m_change_cycle += 1; + m_last_consensus_time = now_time; + flag = true; + // 曾经收到的viewchange消息中跟我当前要的不一致就清空 + for (auto iter = m_recv_view_change_req[m_to_view].begin(); iter != m_recv_view_change_req[m_to_view].end();) { + if (iter->second.height < m_highest_block.number()) { + iter = m_recv_view_change_req[m_to_view].erase(iter); + } else { + ++iter; + } + } + if (!broadcastViewChangeReq()) { + LOG(ERROR) << "broadcastViewChangeReq failed"; + return; + } + checkAndChangeView(); + LOG(TRACE) << "checkTimeout timecost=" << t.elapsed(); + } + } + + if (flag && m_onViewChange) { + m_onViewChange(); + } +} + +void PBFT::handleFutureBlock() { + Guard l(m_mutex); + + if (m_future_prepare_cache.second.height == m_consensus_block_number) { + auto bi = BlockHeader(m_future_prepare_cache.second.block); + if (bi.parentHash() == m_highest_block.hash(WithoutSeal)) { + LOG(INFO) << "handleFurtureBlock, blk=" << m_future_prepare_cache.second.height; + handlePrepareMsg(m_future_prepare_cache.first, m_future_prepare_cache.second); + } + m_future_prepare_cache = std::make_pair(Invalid256, PrepareReq()); + } +} + +void PBFT::recvFutureBlock(u256 const& _from, PrepareReq const& _req) { + if (m_future_prepare_cache.second.block_hash != _req.block_hash) { + auto bi = BlockHeader(_req.block); + auto status = m_bq->blockStatus(bi.parentHash()); + bool waitting = bi.parentHash() == m_prepare_cache.block_hash || m_sign_cache.find(bi.parentHash()) != m_sign_cache.end(); + LOG(DEBUG) << "status=" << (unsigned)status << ",waitting=" << waitting; + if (status == QueueStatus::Importing || status == QueueStatus::Ready || waitting) { + m_future_prepare_cache = std::make_pair(_from, _req); + LOG(INFO) << "Recv an future block prepare, cache it, blk=" << _req.height << ",hash=" << _req.block_hash << ",idx=" << _req.idx; + } + } +} + +Signature PBFT::signBlock(h256 const & _hash) { + return dev::sign(m_key_pair.sec(), _hash); +} + +bool PBFT::checkSign(u256 const & _idx, h256 const & _hash, Signature const & _sig) { + Public pub_id; + if (!NodeConnManagerSingleton::GetInstance().getPublicKey(_idx, pub_id)) { + LOG(ERROR) << "Can't find node, idx=" << _idx; + return false; + } + return dev::verify(pub_id, _sig, _hash); +} + +bool PBFT::broadcastViewChangeReq() { + if (m_account_type != EN_ACCOUNT_TYPE_MINER) { + LOG(INFO) << "Ready to broadcastViewChangeReq, blk=" << m_highest_block.number() << ",to_view=" << m_to_view << ", give up for not miner"; + return true; + } + ViewChangeReq req; + req.height = m_highest_block.number(); + req.view = m_to_view; + req.idx = m_node_idx; + req.timestamp = u256(utcTime()); + req.block_hash = m_highest_block.hash(WithoutSeal); + req.sig = signBlock(req.block_hash); + + RLPStream ts; + req.streamRLPFields(ts); + bool ret = broadcastMsg(req.sig.hex() + toJS(req.view), ViewChangeReqPacket, ts.out()); + return ret; +} + +bool PBFT::broadcastSignReq(PrepareReq const & _req) { + SignReq sign_req; + sign_req.height = _req.height; + sign_req.view = _req.view; + sign_req.idx = m_node_idx; + sign_req.timestamp = u256(utcTime()); + sign_req.block_hash = _req.block_hash; + sign_req.sig = signBlock(sign_req.block_hash); + DEV_BLOCK_STAT_LOG(_req.block_hash, _req.height, utcTime(), "broadcastSignReq"); + RLPStream ts; + sign_req.streamRLPFields(ts); + if (broadcastMsg(sign_req.sig.hex(), SignReqPacket, ts.out())) { + addSignReq(sign_req); + // 重置倒计时,给出足够的时间收集签名 + m_last_sign_time = utcTime(); + return true; + } + return false; +} + +bool PBFT::broadcastPrepareReq(BlockHeader const & _bi, bytes const & _block_data) { + PrepareReq req; + req.height = _bi.number(); + req.view = m_view; + req.idx = m_node_idx; + req.timestamp = u256(utcTime()); + req.block_hash = _bi.hash(WithoutSeal); + req.sig = signBlock(req.block_hash); + req.block = _block_data; + DEV_BLOCK_STAT_LOG(req.block_hash, req.height, utcTime(), "broadcastPrepareReq"); + RLPStream ts; + req.streamRLPFields(ts); + if (broadcastMsg(req.block_hash.hex(), PrepareReqPacket, ts.out()) && addPrepareReq(req)) { + m_last_exec_finish_time = static_cast(req.timestamp); + checkAndCommit(); // 支持单节点可出块 + return true; + } + return false; +} + +bool PBFT::broadcastMsg(std::string const & _key, unsigned _id, bytes const & _data, std::unordered_set const & _filter) { + + if (auto h = m_host.lock()) { + h->foreachPeer([&](shared_ptr _p) + { + unsigned account_type = 0; + if (!NodeConnManagerSingleton::GetInstance().getAccountType(_p->session()->id(), account_type)) { + LOG(ERROR) << "Cannot get account type for peer" << _p->session()->id(); + return true; + } + if (account_type != EN_ACCOUNT_TYPE_MINER && !m_bc->chainParams().broadcastToNormalNode) { + return true; + } + + if (_filter.count(_p->session()->id())) { // 转发广播 + this->broadcastMark(_key, _id, _p); + return true; + } + if (this->broadcastFilter(_key, _id, _p)) { + return true; + } + + RLPStream ts; + _p->prep(ts, _id, 1).append(_data); + _p->sealAndSend(ts); + this->broadcastMark(_key, _id, _p); + return true; + }); + return true; + } + return false; +} + +bool PBFT::broadcastFilter(std::string const & _key, unsigned _id, shared_ptr _p) { + if (_id == PrepareReqPacket) { + DEV_GUARDED(_p->x_knownPrepare) + return _p->m_knownPrepare.exist(_key); + } else if (_id == SignReqPacket) { + DEV_GUARDED(_p->x_knownSign) + return _p->m_knownSign.exist(_key); + } else if (_id == ViewChangeReqPacket) { + DEV_GUARDED(_p->x_knownViewChange) + return _p->m_knownViewChange.exist(_key); + } else { + return true; + } + return true; +} + +void PBFT::broadcastMark(std::string const & _key, unsigned _id, shared_ptr _p) { + if (_id == PrepareReqPacket) { + DEV_GUARDED(_p->x_knownPrepare) + { + if (_p->m_knownPrepare.size() > kKnownPrepare) { + _p->m_knownPrepare.pop(); + } + _p->m_knownPrepare.push(_key); + } + } else if (_id == SignReqPacket) { + DEV_GUARDED(_p->x_knownSign) + { + if (_p->m_knownSign.size() > kKnownSign) { + _p->m_knownSign.pop(); + } + _p->m_knownSign.push(_key); + } + } else if (_id == ViewChangeReqPacket) { + DEV_GUARDED(_p->x_knownViewChange) + { + if (_p->m_knownViewChange.size() > kKnownViewChange) { + _p->m_knownViewChange.pop(); + } + _p->m_knownViewChange.push(_key); + } + } else { + // do nothing + } +} + +bool PBFT::isExistPrepare(PrepareReq const & _req) { + return m_prepare_cache.block_hash == _req.block_hash; +} + +bool PBFT::isExistSign(SignReq const & _req) { + auto iter = m_sign_cache.find(_req.block_hash); + if (iter == m_sign_cache.end()) { + return false; + } + return iter->second.find(_req.sig.hex()) != iter->second.end(); +} + +bool PBFT::isExistViewChange(ViewChangeReq const & _req) { + auto iter = m_recv_view_change_req.find(_req.view); + if (iter == m_recv_view_change_req.end()) { + return false; + } + return iter->second.find(_req.idx) != iter->second.end(); +} + +void PBFT::handlePrepareMsg(u256 const & _from, PrepareReq const & _req) { + u256 t2 = u256(utcTime()) - _req.timestamp; + Timer t; + ostringstream oss; + oss << "handlePrepareMsg: idx=" << _req.idx << ",view=" << _req.view << ",blk=" << _req.height << ",hash=" << _req.block_hash.abridged() << ",from=" << _from; + LOG(TRACE) << oss.str(); + + if (isExistPrepare(_req)) { + LOG(TRACE) << oss.str() << "Discard an illegal prepare, duplicated"; + return; + } + + if (_req.idx == m_node_idx) { + LOG(ERROR) << oss.str() << "Discard an illegal prepare, your own req"; + return; + } + + if (_req.view != m_view) { + LOG(DEBUG) << oss.str() << "Recv an illegal prepare, m_view=" << m_view << ",m_to_view=" << m_to_view; + if (_req.view == m_to_view) { + recvFutureBlock(_from, _req); + LOG(DEBUG) << oss.str() << " wait to be handled later"; + } + return; + } + + auto leader = getLeader(); + if (!leader.first || _req.idx != leader.second) { + LOG(ERROR) << oss.str() << "Recv an illegal prepare, err leader"; + return; + } + + if (_req.height != m_consensus_block_number) { + LOG(DEBUG) << oss.str() << "Discard an illegal prepare req, need_height=" << m_consensus_block_number; + } + + + if (!checkSign(_req.idx, _req.block_hash, _req.sig)) { + LOG(ERROR) << oss.str() << "CheckSign failed"; + return; + } + + try { + m_bc->checkBlockValid(_req.block_hash, _req.block, *m_stateDB); + } + catch (dev::eth::InvalidParentHash) + { + recvFutureBlock(_from, _req); + return; + } + catch (dev::eth::UnknownParent) + { + recvFutureBlock(_from, _req); + return; + } + catch (Exception &ex) { + LOG(ERROR) << oss.str() << "CheckBlockValid failed" << ex.what(); + return; + } + + if (!addPrepareReq(_req)) { + LOG(ERROR) << oss.str() << "addPrepare failed"; + return; + } + + if (m_account_type == EN_ACCOUNT_TYPE_MINER && !broadcastSignReq(_req)) { + LOG(ERROR) << oss.str() << "broadcastSignReq failed"; + return; + } + + // TODO: 保存交易 + + LOG(INFO) << oss.str() << ", success"; + m_last_exec_finish_time = static_cast(_req.timestamp); + checkAndCommit(); + + LOG(TRACE) << "handlePrepareMsg, timecost=" << 1000 * t.elapsed() << ",net-time=" << t2; + return; +} + +void PBFT::handleSignMsg(u256 const & _from, SignReq const & _req) { + u256 t2 = u256(utcTime()) - _req.timestamp; + Timer t; + ostringstream oss; + oss << "handleSignMsg: idx=" << _req.idx << ",view=" << _req.view << ",blk=" << _req.height << ",hash=" << _req.block_hash.abridged() << ", from=" << _from; + LOG(TRACE) << oss.str(); + + if (isExistSign(_req)) { + LOG(TRACE) << oss.str() << "Discard an illegal sign, duplicated"; + return; + } + + if (_req.idx == m_node_idx) { + LOG(ERROR) << oss.str() << "Discard an illegal sign, your own req"; + return; + } + + if (m_prepare_cache.block_hash != _req.block_hash) { + LOG(DEBUG) << oss.str() << "Recv a sign_req for block which not in prepareCache, preq=" << m_prepare_cache.block_hash.abridged(); + + if (_req.height == m_consensus_block_number && checkSign(_req.idx, _req.block_hash, _req.sig)) { + addSignReq(_req); + LOG(DEBUG) << oss.str() << "Cache this sign_req"; + } + return; + } + + if (m_prepare_cache.view != _req.view) { + LOG(INFO) << oss.str() << "Discard a sign_req which view is not equal, preq.v=" << m_prepare_cache.view; + return; + } + + if (!checkSign(_req.idx, _req.block_hash, _req.sig)) { + LOG(ERROR) << oss.str() << "CheckSign failed"; + return; + } + + LOG(INFO) << oss.str() << ", success"; + + addSignReq(_req); + + checkAndCommit(); + + LOG(TRACE) << "handleSignMsg, timecost=" << 1000 * t.elapsed() << ",net-time=" << t2; + return; +} + +void PBFT::handleViewChangeMsg(u256 const & _from, ViewChangeReq const & _req) { + u256 t2 = u256(utcTime()) - _req.timestamp; + Timer t; + ostringstream oss; + oss << "handleViewChangeMsg: idx=" << _req.idx << ",view=" << _req.view << ",blk=" << _req.height << ",hash=" << _req.block_hash.abridged() << ",from=" << _from; + LOG(TRACE) << oss.str(); + + if (isExistViewChange(_req)) { + LOG(TRACE) << oss.str() << "Discard an illegal viewchange, duplicated"; + return; + } + + + if (_req.idx == m_node_idx) { + LOG(ERROR) << oss.str() << "Discard an illegal viewchange, your own req"; + return; + } + + if (_req.height < m_highest_block.number() || _req.view <= m_view) { + LOG(TRACE) << oss.str() << "Discard an illegal viewchange, m_highest_block=" << m_highest_block.number() << ",m_view=" << m_view; + return; + } + if (_req.height == m_highest_block.number() && _req.block_hash != m_highest_block.hash(WithoutSeal) && m_bc->block(_req.block_hash).size() == 0) { + LOG(DEBUG) << oss.str() << "Discard an illegal viewchange, same height but not hash, chain has been forked, my=" << m_highest_block.hash(WithoutSeal) << ",req=" << _req.block_hash; + return; + } + + if (!checkSign(_req.idx, _req.block_hash, _req.sig)) { + LOG(ERROR) << oss.str() << "CheckSign failed"; + return; + } + + LOG(INFO) << oss.str() << ", success"; + + m_recv_view_change_req[_req.view][_req.idx] = _req; + + if (_req.view == m_to_view) { + checkAndChangeView(); + } else { + u256 count = u256(0); + u256 min_view = Invalid256; + for (auto iter = m_recv_view_change_req.begin(); iter != m_recv_view_change_req.end(); ++iter) { + if (iter->first > m_to_view) { + count += iter->second.size(); + if (min_view > iter->first) { + min_view = iter->first; + } + } + } + + if (count > m_f + 1) { + LOG(INFO) << "Fast start viewchange, m_to_view=" << m_to_view << ",req.view=" << _req.view; + m_last_consensus_time = 0; + m_to_view = min_view - 1; // it will be setted equal to min_view when viewchange happened. + m_signalled.notify_all(); + } + } + + LOG(TRACE) << "handleViewChangeMsg, timecost=" << 1000 * t.elapsed() << ",net-time=" << t2; + return; +} + +void PBFT::checkAndCommit() { + u256 need_sign = m_node_num - m_f; + u256 have_sign = m_sign_cache[m_prepare_cache.block_hash].size() + 1; + if (have_sign >= need_sign) { + LOG(INFO) << "######### Reach enough sign for block=" << m_prepare_cache.height << ",hash=" << m_prepare_cache.block_hash.abridged() << ",have_sign=" << have_sign << ",need_sign=" << need_sign; + if (m_prepare_cache.view != m_view) { + LOG(INFO) << "view has changed, discard this block, preq.view=" << m_prepare_cache.view << ",m_view=" << m_view; + return; + } + if (m_prepare_cache.height > m_highest_block.number()) { + // 把签名加上 + std::vector> sig_list; + sig_list.reserve(static_cast(have_sign)); + sig_list.push_back(std::make_pair(m_prepare_cache.idx, m_prepare_cache.sig)); + for (auto item : m_sign_cache[m_prepare_cache.block_hash]) { + sig_list.push_back(std::make_pair(item.second.idx, Signature(item.first.c_str()))); + } + RLP r(m_prepare_cache.block); + RLPStream rs; + rs.appendList(5); + rs.appendRaw(r[0].data()); // header + rs.appendRaw(r[1].data()); // tx + rs.appendRaw(r[2].data()); // uncles + rs.appendRaw(r[3].data()); // hash + rs.appendVector(sig_list); // sign_list + + m_onSealGenerated(rs.out(), m_prepare_cache.idx == m_node_idx); + //m_commited_block = BlockHeader(m_prepare_cache.block); + delCache(m_prepare_cache.block_hash); + } else { + LOG(INFO) << "Discard this block, blk_no=" << m_prepare_cache.height << ",highest_block=" << m_highest_block.number(); + delCache(m_prepare_cache.block_hash); + } + } +} + +void PBFT::checkAndChangeView() { + u256 count = m_recv_view_change_req[m_to_view].size(); + if (count >= m_node_num - m_f - 1) { + LOG(INFO) << "######### Reach consensus, to_view=" << m_to_view; + + m_leader_failed = false; + m_view = m_to_view; + + for (auto iter = m_recv_view_change_req.begin(); iter != m_recv_view_change_req.end();) { + if (iter->first <= m_view) { + iter = m_recv_view_change_req.erase(iter); + } else { + ++iter; + } + } + } +} + +bool PBFT::addPrepareReq(PrepareReq const & _req) { + if (m_prepare_cache.block_hash == _req.block_hash) { + LOG(INFO) << "Discard duplicated prepare block"; + return false; + } + + if (m_prepare_cache.height == _req.height) { + if (m_prepare_cache.view < _req.view) { + LOG(INFO) << "Replace prepare block which has same H but bigger V, req.view=" << _req.view << ",cache.view=" << m_prepare_cache.view; + m_prepare_cache = _req; + return true; + } else { + LOG(INFO) << "Discard prepare block, req.view=" << _req.view << ",cache.view=" << m_prepare_cache.view; + return false; + } + } else { + m_prepare_cache = _req; + return true; + } + + return false; // can't be here +} + +void PBFT::addSignReq(SignReq const & _req) { + m_sign_cache[_req.block_hash][_req.sig.hex()] = _req; +} + +void PBFT::delCache(h256 const & _block_hash) { + auto iter2 = m_sign_cache.find(_block_hash); + if (iter2 == m_sign_cache.end()) { + LOG(INFO) << "Try to delete not-exist, hash=" << _block_hash; + //BOOST_THROW_EXCEPTION(UnexpectError()); + } else { + m_sign_cache.erase(iter2); + } + + m_prepare_cache.clear(); +} + +void PBFT::collectGarbage() { + Timer t; + Guard l(m_mutex); + if (!m_highest_block) return; + + std::chrono::system_clock::time_point now_time = std::chrono::system_clock::now(); + if (now_time - m_last_collect_time >= std::chrono::seconds(kCollectInterval)) { + for (auto iter = m_sign_cache.begin(); iter != m_sign_cache.end();) { + for (auto iter2 = iter->second.begin(); iter2 != iter->second.end();) { + if (iter2->second.height < m_highest_block.number()) { + iter2 = iter->second.erase(iter2); + } else { + ++iter2; + } + } + if (iter->second.size() == 0) { + iter = m_sign_cache.erase(iter); + } else { + ++iter; + } + } + m_last_collect_time = now_time; + + LOG(INFO) << "collectGarbage timecost(ms)=" << 1000 * t.elapsed(); + } +} + + +bool PBFT::getMinerList(int _blk_no, h512s &_miner_list) const { + std::map all_node; + NodeConnManagerSingleton::GetInstance().getAllNodeConnInfo(_blk_no, all_node); + + unsigned miner_num = 0; + for (auto iter = all_node.begin(); iter != all_node.end(); ++iter) { + if (iter->second._iIdentityType == EN_ACCOUNT_TYPE_MINER) { + ++miner_num; + } + } + _miner_list.resize(miner_num); + for (auto iter = all_node.begin(); iter != all_node.end(); ++iter) { + if (iter->second._iIdentityType == EN_ACCOUNT_TYPE_MINER) { + auto idx = static_cast(iter->second._iIdx); + if (idx >= miner_num) { + LOG(ERROR) << "getMinerList return false cause for idx=" << idx << ",miner_num=" << miner_num; + return false; + } + _miner_list[idx] = jsToPublic(toJS(iter->second._sNodeId)); + } + } + + return true; + +} + +bool PBFT::checkBlockSign(BlockHeader const& _header, std::vector> _sign_list) { + Timer t; + + LOG(TRACE) << "PBFT::checkBlockSign " << _header.number(); + + + h512s miner_list; + if (!getMinerList(static_cast(_header.number() - 1), miner_list)) { + LOG(ERROR) << "checkBlockSign failed for getMinerList return false, blk=" << _header.number() - 1; + return false; + } + + LOG(DEBUG) << "checkBlockSign call getAllNodeConnInfo: blk=" << _header.number() - 1 << ", miner_num=" << miner_list.size(); + + // 检查公钥列表 + if (_header.nodeList() != miner_list) { + ostringstream oss; + for (size_t i = 0; i < miner_list.size(); ++i) { + oss << miner_list[i] << ","; + } + LOG(ERROR) << "checkBlockSign failed, chain_block=" << _header.number() << ",miner_list size=" << miner_list.size() << ",value=" << oss.str(); + oss.clear(); + for (size_t i = 0; i < _header.nodeList().size(); ++i) { + oss << _header.nodeList()[i] << ","; + } + LOG(ERROR) << "checkBlockSign failed, down_block=" << _header.number() << ",miner_list size=" << _header.nodeList().size() << ",value=" << oss.str(); + return false; + } + + // 检查签名数量 + if (_sign_list.size() < (miner_list.size() - (miner_list.size() - 1) / 3)) { + LOG(ERROR) << "checkBlockSign failed, blk=" << _header.number() << " not enough sign, sign_num=" << _sign_list.size() << ",miner_num" << miner_list.size(); + return false; + } + + // 检查签名是否有效 + for (auto item : _sign_list) { + if (item.first >= miner_list.size()) { + LOG(ERROR) << "checkBlockSign failed, block=" << _header.number() << "sig idx=" << item.first << ", out of bound, miner_list size=" << miner_list.size(); + return false; + } + + if (!dev::verify(miner_list[static_cast(item.first)], item.second, _header.hash(WithoutSeal))) { + LOG(ERROR) << "checkBlockSign failed, verify false, blk=" << _header.number() << ",hash=" << _header.hash(WithoutSeal); + return false; + } + } + + LOG(INFO) << "checkBlockSign success, blk=" << _header.number() << ",hash=" << _header.hash(WithoutSeal) << ",timecost=" << t.elapsed() / 1000 << "ms"; + + return true; +} diff --git a/libpbftseal/PBFT.h b/libpbftseal/PBFT.h new file mode 100644 index 0000000000..d55d8fe295 --- /dev/null +++ b/libpbftseal/PBFT.h @@ -0,0 +1,180 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ + + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include "Common.h" +#include "PBFTHost.h" + +namespace dev +{ + +namespace eth +{ + +DEV_SIMPLE_EXCEPTION(PbftInitFailed); +DEV_SIMPLE_EXCEPTION(UnexpectError); + +class PBFT: public SealEngineFace, Worker +{ +public: + PBFT(); + + static void init(); + + std::string name() const override { return "PBFT"; } + StringHashMap jsInfo(BlockHeader const& _bi) const override; + + strings sealers() const override { return {m_sealer}; } + std::string sealer() const override { return m_sealer; } + void setSealer(std::string const& _sealer) override { m_sealer = _sealer; } + u256 nodeIdx() const { /*Guard l(m_mutex);*/ return m_node_idx; } + uint64_t lastConsensusTime() const { /*Guard l(m_mutex);*/ return m_last_consensus_time;} + unsigned accountType() const { return m_account_type; } + + void startGeneration() { setName("PBFT"); m_last_consensus_time = utcTime(); resetConfig(); startWorking(); } + void cancelGeneration() override { stopWorking(); } + + void generateSeal(BlockHeader const& _bi, bytes const& _block_data) override; + void onSealGenerated(std::function const&) override {} + void onSealGenerated(std::function const& _f) { m_onSealGenerated = _f;} + void onViewChange(std::function const& _f) { m_onViewChange = _f; } + bool shouldSeal(Interface* _i) override; + + // should be called before start + void initEnv(std::weak_ptr _host, BlockChain* _bc, OverlayDB* _db, BlockQueue *bq, KeyPair const& _key_pair, unsigned _view_timeout); + + // 上报最新块 + void reportBlock(BlockHeader const& _b, u256 const& td); + + void onPBFTMsg(unsigned _id, std::shared_ptr _peer, RLP const& _r); + + h512s getMinerNodeList() const { /*Guard l(m_mutex);*/ return m_miner_list; } + uint64_t lastExecFinishTime() const { return m_last_exec_finish_time; } +private: + void resetConfig(); + // 线程:处理各种消息的响应,超时主动发送viewchange消息 + void workLoop() override; + + //检测是否超时,超时切换视图 + void checkTimeout(); + + void collectGarbage(); + + + bool getMinerList(int _blk_no, h512s & _miner_list) const; + + std::pair getLeader() const; + + Signature signBlock(h256 const& _hash); + bool checkSign(u256 const& _idx, h256 const& _hash, Signature const& _sign); + + // 广播消息 + bool broadcastPrepareReq(BlockHeader const& _bi, bytes const& _block_data); + bool broadcastSignReq(PrepareReq const& _req); + bool broadcastViewChangeReq(); + bool broadcastMsg(std::string const& _key, unsigned _id, bytes const& _data, std::unordered_set const& _filter = std::unordered_set()); + bool broadcastFilter(std::string const& _key, unsigned _id, shared_ptr _p); + void broadcastMark(std::string const& _key, unsigned _id, shared_ptr _p); + + // 处理响应消息 + void handleMsg(unsigned _id, u256 const& _from, h512 const& _node, RLP const& _r); + void handlePrepareMsg(u256 const& _from, PrepareReq const& _req); + void handleSignMsg(u256 const& _from, SignReq const& _req); + void handleViewChangeMsg(u256 const& _from, ViewChangeReq const& _req); + + // cache访问(未加锁,外层要加锁保护) + bool addPrepareReq(PrepareReq const& _req); + void addSignReq(SignReq const& _req); + void delCache(h256 const& _block_hash); + + bool isExistPrepare(PrepareReq const& _req); + bool isExistSign(SignReq const& _req); + bool isExistViewChange(ViewChangeReq const& _req); + + void checkAndChangeView(); + void checkAndCommit(); + + void handleFutureBlock(); + void recvFutureBlock(u256 const& _from, PrepareReq const& _req); + + bool checkBlockSign(BlockHeader const& _header, std::vector> _sign_list); + +private: + mutable Mutex m_mutex; + + unsigned m_account_type; + KeyPair m_key_pair; + std::string m_sealer = "pbft"; + + std::function m_onSealGenerated; + std::function m_onViewChange; + + std::weak_ptr m_host; + std::shared_ptr m_bc; + std::shared_ptr m_stateDB; + std::shared_ptr m_bq; + + u256 m_node_idx = 0; + u256 m_view = 0; + u256 m_node_num = 0; + u256 m_f = 0; + + unsigned m_view_timeout; + uint64_t m_last_consensus_time; + unsigned m_change_cycle; + u256 m_to_view; + bool m_leader_failed; + uint64_t m_last_sign_time; + + //std::unordered_map m_raw_prepare_cache; + PrepareReq m_raw_prepare_cache; + //std::unordered_map m_prepare_cache; + PrepareReq m_prepare_cache; + std::pair m_future_prepare_cache; + std::unordered_map> m_sign_cache; + std::unordered_map> m_recv_view_change_req; + + std::chrono::system_clock::time_point m_last_collect_time; + + BlockHeader m_highest_block; + u256 m_consensus_block_number; // 在等待共识的块 + //BlockHeader m_commited_block; // 已经共识提交的块 + + h512s m_miner_list; + + bool m_cfg_err = false; + + uint64_t m_last_exec_finish_time; + std::condition_variable m_signalled; + Mutex x_signalled; + + static const size_t kKnownPrepare = 1024; + static const size_t kKnownSign = 1024; + static const size_t kKnownViewChange = 1024; +}; + +} +} diff --git a/libpbftseal/PBFTClient.cpp b/libpbftseal/PBFTClient.cpp new file mode 100644 index 0000000000..560dc7ac10 --- /dev/null +++ b/libpbftseal/PBFTClient.cpp @@ -0,0 +1,300 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ + + +#include +#include +#include +#include "PBFTClient.h" +#include "PBFT.h" +#include "PBFTHost.h" +#include +using namespace std; +using namespace dev; +using namespace dev::eth; +using namespace p2p; + +PBFTClient& dev::eth::asPBFTClient(Interface& _c) +{ + if (dynamic_cast(_c.sealEngine())) + return dynamic_cast(_c); + throw NotPBFTSealEngine(); +} + +PBFTClient* dev::eth::asPBFTClient(Interface* _c) +{ + if (dynamic_cast(_c->sealEngine())) + return &dynamic_cast(*_c); + throw NotPBFTSealEngine(); +} + +PBFTClient::PBFTClient( + ChainParams const& _params, + int _networkID, + p2p::Host* _host, + std::shared_ptr _gpForAdoption, + std::string const& _dbPath, + WithExisting _forceAction, + TransactionQueue::Limits const& _limits +): + Client(_params, _networkID, _host, _gpForAdoption, _dbPath, _forceAction, _limits) +{ + // will throw if we're not an PBFT seal engine. + asPBFTClient(*this); + + init(_params, _host); +} + +PBFTClient::~PBFTClient() { + pbft()->cancelGeneration(); + stopWorking(); +} + +void PBFTClient::init(ChainParams const& _params, p2p::Host *_host) { + m_params = _params; + m_working.setEvmCoverLog(m_params.evmCoverLog); + m_working.setEvmEventLog(m_params.evmEventLog); + + + // register PBFTHost + auto pbft_host = _host->registerCapability(make_shared([this](unsigned _id, std::shared_ptr _peer, RLP const & _r) { + pbft()->onPBFTMsg(_id, _peer, _r); + })); + + pbft()->initEnv(pbft_host, &m_bc, &m_stateDB, &m_bq, _host->keyPair(), static_cast(sealEngine()->getIntervalBlockTime()) * 3); + + pbft()->reportBlock(bc().info(), bc().details().totalDifficulty); + + pbft()->onSealGenerated([ this ](bytes const & _block, bool _isOurs) { + if (!submitSealed(_block, _isOurs)) + LOG(ERROR) << "Submitting block failed..."; + }); + + pbft()->onViewChange([this]() { + DEV_WRITE_GUARDED(x_working) + { + if (m_working.isSealed()) { + m_working.resetCurrent(); + } + } + }); + + LOG(INFO) << "Init PBFTClient success"; +} + +PBFT* PBFTClient::pbft() const +{ + return dynamic_cast(Client::sealEngine()); +} + +void PBFTClient::startSealing() { + setName("Client"); + pbft()->reportBlock(bc().info(), bc().details().totalDifficulty); + pbft()->startGeneration(); + Client::startSealing(); +} + +void PBFTClient::stopSealing() { + Client::stopSealing(); + pbft()->cancelGeneration(); +} + +void PBFTClient::syncBlockQueue() { + Client::syncBlockQueue(); + + pbft()->reportBlock(bc().info(), bc().details().totalDifficulty); + + DEV_WRITE_GUARDED(x_working) + { + if (m_working.isSealed() && m_working.info().number() <= bc().info().number()) { + m_working.resetCurrent(); + } + } +} + +void PBFTClient::onTransactionQueueReady() { + m_syncTransactionQueue = true; + m_signalled.notify_all(); + // 通知EthereumHost去广播交易 + if (auto h = m_host.lock()) { + h->noteNewTransactions(); + } +} + +void PBFTClient::syncTransactionQueue() +{ + Timer timer; + + h256Hash changeds; + TransactionReceipts newPendingReceipts; + + DEV_WRITE_GUARDED(x_working) + { + if (m_working.isSealed()) + { + LOG(TRACE) << "Skipping txq sync for a sealed block."; + return; + } + if ( m_working.pending().size() >= m_maxBlockTranscations ) + { + LOG(TRACE) << "Skipping txq sync for Full block ."; + return; + } + + tie(newPendingReceipts, m_syncTransactionQueue) = m_working.sync(bc(), m_tq, *m_gp); + } + + if (newPendingReceipts.empty()) + { + auto s = m_tq.status(); + LOG(TRACE) << "No transactions to process. " << m_working.pending().size() << " pending, " << s.current << " queued, " << s.future << " future, " << s.unverified << " unverified"; + return; + } + + DEV_READ_GUARDED(x_working) + DEV_WRITE_GUARDED(x_postSeal) + m_postSeal = m_working; + + DEV_READ_GUARDED(x_postSeal) + for (size_t i = 0; i < newPendingReceipts.size(); i++) + appendFromNewPending(newPendingReceipts[i], changeds, m_postSeal.pending()[i].sha3()); + + // Tell farm about new transaction (i.e. restart mining). + onPostStateChanged(); + + // Tell watches about the new transactions. + noteChanged(changeds); + + LOG(TRACE) << "Processed " << newPendingReceipts.size() << " transactions in" << (timer.elapsed() * 1000) << "(" << (bool)m_syncTransactionQueue << ")"; + + cblockstat << m_working.info().number() << ",trans=" << newPendingReceipts.size() << " 交易处理速度=" << ((1000 * newPendingReceipts.size()) / ((timer.elapsed() * 1000000) / 1000)) << "/S"; + +} + +void PBFTClient::doWork(bool _doWait) +{ + bool t = true; + if (m_syncBlockQueue.compare_exchange_strong(t, false)) + syncBlockQueue(); + + if (m_needStateReset) + { + resetState(); + m_needStateReset = false; + } + + tick(); + + rejigSealing(); + + callQueuedFunctions(); + + if (!m_syncBlockQueue && _doWait) + { + std::unique_lock l(x_signalled); + m_signalled.wait_for(l, chrono::milliseconds(10)); + } +} + +void PBFTClient::rejigSealing() { + bool would_seal = m_wouldSeal && (pbft()->accountType() == EN_ACCOUNT_TYPE_MINER); + bool is_major_syncing = isMajorSyncing(); + if (would_seal && !is_major_syncing) + { + if (pbft()->shouldSeal(this)) // 自己是不是leader? + { + DEV_READ_GUARDED(x_working) + { + if (m_working.isSealed()) { + LOG(TRACE) << "Tried to seal sealed block..."; + return; + } + } + + // 被选为leader之后才开始打包 + bool t = true; + if (!isSyncing() && !m_remoteWorking && m_syncTransactionQueue.compare_exchange_strong(t, false)) { + syncTransactionQueue(); + } + + DEV_READ_GUARDED(x_working) + { + // 判断是否已够 + size_t tx_num = m_working.pending().size(); + //auto last_consensus_time = pbft()->lastConsensusTime(); + auto last_exec_finish_time = pbft()->lastExecFinishTime(); + auto now_time = utcTime(); + //auto proc_time = last_consensus_time - static_cast(bc().info().timestamp()); + auto max_interval = static_cast(sealEngine()->getIntervalBlockTime()); + /*if (proc_time > max_interval) { + max_interval = 0; + } else { + max_interval -= proc_time; + }*/ + + if (tx_num < m_maxBlockTranscations && now_time - last_exec_finish_time < max_interval) { + //LOG(TRACE) << "Wait for next interval, tx:" << tx_num; + return; + } + } + + DEV_WRITE_GUARDED(x_working) + { + // 出块 + DEV_BLOCK_STAT_LOG("", m_working.info().number(), utcTime(), "commitToSeal"); + //m_working.resetCurrentTime(); + m_working.setIndex(pbft()->nodeIdx()); + m_working.setNodeList(pbft()->getMinerNodeList()); + m_working.commitToSeal(bc(), m_extraData); + + m_sealingInfo = m_working.info(); + RLPStream ts; + m_sealingInfo.streamRLP(ts, WithoutSeal); + + + m_working.setEvmCoverLog(m_params.evmCoverLog); + m_working.setEvmEventLog(m_params.evmEventLog); + + //增加cache + bc().addBlockCache(m_working, m_working.info().difficulty()); + + if (!m_working.sealBlock(m_sealingInfo, &ts.out())) { + LOG(INFO) << "Error: sealBlock failed"; + return; + } + } + + DEV_READ_GUARDED(x_working) + { + DEV_WRITE_GUARDED(x_postSeal) + m_postSeal = m_working; + + if (would_seal) + { + LOG(INFO) << "+++++++++++++++++++++++++++ Generating seal on " << m_sealingInfo.hash(WithoutSeal).abridged() << "#" << m_sealingInfo.number() << "tx:" << m_working.pending().size(); + pbft()->generateSeal(m_sealingInfo, m_working.blockData()); + } + } + } + } +} + +bool PBFTClient::submitSealed(bytes const & _block, bool _isOurs) { + auto ret = m_bq.import(&_block, _isOurs); + LOG(TRACE) << "PBFTClient::submitSealed m_bq.import return " << (unsigned)ret; + return ret == ImportResult::Success; +} diff --git a/libpbftseal/PBFTClient.h b/libpbftseal/PBFTClient.h new file mode 100644 index 0000000000..a8a9b2c33d --- /dev/null +++ b/libpbftseal/PBFTClient.h @@ -0,0 +1,74 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ + + +#pragma once + +#include + +namespace dev +{ +namespace eth +{ + +class PBFT; + +DEV_SIMPLE_EXCEPTION(NotPBFTSealEngine); +DEV_SIMPLE_EXCEPTION(ChainParamsNotPBFT); +DEV_SIMPLE_EXCEPTION(InitFailed); + +class PBFTClient: public Client +{ +public: + /// Trivial forwarding constructor. + PBFTClient( + ChainParams const& _params, + int _networkID, + p2p::Host* _host, + std::shared_ptr _gpForAdoption, + std::string const& _dbPath = std::string(), + WithExisting _forceAction = WithExisting::Trust, + TransactionQueue::Limits const& _l = TransactionQueue::Limits {102400, 102400} + ); + + virtual ~PBFTClient(); + + void startSealing() override; + void stopSealing() override; + //bool isMining() const override { return isWorking(); } + + PBFT* pbft() const; + +protected: + void init(ChainParams const& _params, p2p::Host *_host); + void doWork(bool _doWait) override; + void rejigSealing() override; + void syncBlockQueue() override; + void syncTransactionQueue() override; + void onTransactionQueueReady() override; + + bool submitSealed(bytes const & _block, bool _isOurs); + +private: + ChainParams m_params; +}; + +PBFTClient& asPBFTClient(Interface& _c); +PBFTClient* asPBFTClient(Interface* _c); + +} +} diff --git a/libpbftseal/PBFTHost.cpp b/libpbftseal/PBFTHost.cpp new file mode 100644 index 0000000000..a5dd39c63a --- /dev/null +++ b/libpbftseal/PBFTHost.cpp @@ -0,0 +1,45 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ + + +#include "PBFTHost.h" +using namespace std; +using namespace dev; +using namespace dev::eth; +using namespace p2p; + +void PBFTHost::foreachPeer(std::function)> const& _f) const +{ + //order peers by protocol, rating, connection age + auto sessions = peerSessions(); + auto sessionLess = [](std::pair, std::shared_ptr> const & _left, std::pair, std::shared_ptr> const & _right) + { return _left.first->rating() == _right.first->rating() ? _left.first->connectionTime() < _right.first->connectionTime() : _left.first->rating() > _right.first->rating(); }; + + std::sort(sessions.begin(), sessions.end(), sessionLess); + for (auto s : sessions) + if (!_f(capabilityFromSession(*s.first))) + return; + + static const unsigned c_oldProtocolVersion = 62; + sessions = peerSessions(c_oldProtocolVersion); //TODO: remove once v61+ is common + std::sort(sessions.begin(), sessions.end(), sessionLess); + for (auto s : sessions) + if (!_f(capabilityFromSession(*s.first, c_oldProtocolVersion))) + return; +} + + diff --git a/libpbftseal/PBFTHost.h b/libpbftseal/PBFTHost.h new file mode 100644 index 0000000000..439751a9bc --- /dev/null +++ b/libpbftseal/PBFTHost.h @@ -0,0 +1,51 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ + + +#pragma once +#include +#include +#include +#include +#include "Common.h" +#include "PBFTPeer.h" + +namespace dev +{ +namespace eth +{ + +class PBFTHost: public p2p::HostCapability +{ +public: + typedef std::function, RLP const&)> MsgHandler; + + PBFTHost(MsgHandler h): m_msg_handler(h) {} + virtual ~PBFTHost() {} + + void onMsg(unsigned _id, std::shared_ptr _peer, RLP const& _r) { + m_msg_handler(_id, _peer, _r); + } + + void foreachPeer(std::function)> const& _f) const; + +private: + MsgHandler m_msg_handler; +}; + +} +} diff --git a/libpbftseal/PBFTPeer.cpp b/libpbftseal/PBFTPeer.cpp new file mode 100644 index 0000000000..3c544bb830 --- /dev/null +++ b/libpbftseal/PBFTPeer.cpp @@ -0,0 +1,43 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ + +#include +#include +#include "PBFTPeer.h" +#include "PBFTHost.h" +using namespace std; +using namespace dev; +using namespace eth; +using namespace p2p; + +PBFTPeer::PBFTPeer(std::shared_ptr _s, HostCapabilityFace* _h, unsigned _i, CapDesc const& _cap, uint16_t _capID): + Capability(_s, _h, _i, _capID), + m_peerCapabilityVersion(_cap.second) +{ + //session()->addNote("manners", isRude() ? "RUDE" : "nice"); +} + +PBFTPeer::~PBFTPeer() +{ +} + +bool PBFTPeer::interpret(unsigned _id, RLP const& _r) +{ + //clog(PBFTTrace) << "PBFTPeer::interpret id=" << _id; + dynamic_cast(*hostCapability()).onMsg(_id, dynamic_pointer_cast(shared_from_this()), _r); + return true; +} \ No newline at end of file diff --git a/libpbftseal/PBFTPeer.h b/libpbftseal/PBFTPeer.h new file mode 100644 index 0000000000..52f9709b27 --- /dev/null +++ b/libpbftseal/PBFTPeer.h @@ -0,0 +1,66 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ + + +#pragma once + +#include +#include +#include +#include +#include +#include "Common.h" + +namespace dev +{ + +namespace eth +{ +class PBFTPeer : public p2p::Capability +{ + friend class PBFT; +public: + PBFTPeer(std::shared_ptr _s, p2p::HostCapabilityFace* _h, unsigned _i, p2p::CapDesc const& _cap, uint16_t _capID); + + /// Basic destructor. + virtual ~PBFTPeer(); + + /// What is our name? + static std::string name() { return "pbft"; } + /// What is our version? + static u256 version() { return c_protocolVersion; } + /// How many message types do we have? + static unsigned messageCount() { return PBFTPacketCount; } + + p2p::NodeID id() const { return session()->id(); } + +protected: + virtual bool interpret(unsigned _id, RLP const& _r); + +private: + u256 const m_peerCapabilityVersion; + + Mutex x_knownPrepare; + QueueSet m_knownPrepare; + Mutex x_knownSign; + QueueSet m_knownSign; + Mutex x_knownViewChange; + QueueSet m_knownViewChange; +}; + +} +} diff --git a/libraftseal/CMakeLists.txt b/libraftseal/CMakeLists.txt new file mode 100644 index 0000000000..00040aeee0 --- /dev/null +++ b/libraftseal/CMakeLists.txt @@ -0,0 +1,19 @@ +aux_source_directory(. SRC_LIST) + +file(GLOB HEADERS "*.h") + +add_library(raftseal ${SRC_LIST} ${HEADERS}) + +find_package(Eth) +find_package(Dev) + +target_include_directories(raftseal PRIVATE ..) +target_include_directories(raftseal PRIVATE .) + +target_link_libraries(raftseal ${Dev_DEVCORE_LIBRARIES}) +target_link_libraries(raftseal ${Dev_DEVCRYPTO_LIBRARIES}) +target_link_libraries(raftseal ${Eth_ETHCORE_LIBRARIES}) +target_link_libraries(raftseal ${Eth_ETHEREUM_LIBRARIES}) + +install(TARGETS raftseal RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib) + diff --git a/libraftseal/Common.h b/libraftseal/Common.h new file mode 100644 index 0000000000..7d79404223 --- /dev/null +++ b/libraftseal/Common.h @@ -0,0 +1,44 @@ + +#pragma once + +#include +#include +#include +#include + +#define craft LOG(TRACE) + +enum RaftMsgType +{ + RaftMsgRaft = 0x01, + + RaftMsgCount +}; + +enum RaftPacketType +{ + raftBlockVote = 0x01, + raftBlockVoteEcho, + RaftTestPacket, + + raftPacketCount +}; + +struct AutoLock +{ + AutoLock(boost::recursive_mutex & _lock): m_lock(_lock) + { + //m_lock.lock(); + } + + ~AutoLock() + { + //m_lock.unlock(); + } + + boost::recursive_mutex & m_lock; +}; + +#define AUTO_LOCK(x) AutoLock autoLock(x) + + diff --git a/libraftseal/Raft.cpp b/libraftseal/Raft.cpp new file mode 100644 index 0000000000..2ca9bb46f7 --- /dev/null +++ b/libraftseal/Raft.cpp @@ -0,0 +1,448 @@ + +#include + + +#include "Common.h" +#include "Raft.h" + +#include + +#define gettidv1() syscall(__NR_gettid) +#define gettidv2() syscall(SYS_gettid) + +#define RAFT_SIGNAL SIGUSR1 +#define RAFT_SIGNAL_REPORT SIGUSR2 + +using namespace dev; +using namespace dev::eth; + +using namespace boost::asio; +using namespace ba::ip; + +void Raft::tick() +{ + if(m_account_type != EN_ACCOUNT_TYPE_MINER) + return; + + uint64_t now = utcTime(); + if(raftInitial == m_consensusState){ + bool have; + bytes blockBytes; + tie(have, blockBytes) = m_blocks.tryPop(0); + + if(have && !blockBytes.empty()) + generateSealBegin(blockBytes); + }else if(raftPrePrepare == m_consensusState){ + if(now > m_consensusTimeOut){ + LOG(TRACE) << "raftPrePrepare: m_account_type=" << m_account_type << ",now=" << now; + voteBlockBegin(); + } + }else if(raftWaitingVote == m_consensusState){ + LOG(TRACE) << "raftWaitingVote: m_account_type=" << m_account_type << ",now=" << now << ",m_consensusTimeOut=" << m_consensusTimeOut; + voteBlockEnd(); + }else if(raftFinished == m_consensusState){ + if(now > m_consensusTimeOut){ + LOG(TRACE) << "raftInitial: m_account_type=" << m_account_type << ",now=" << now; + m_consensusState = raftInitial; + } + } +} + +bool Raft::interpret(RaftPeer* _p, unsigned _id, RLP const& _r) +{ + if(m_account_type != EN_ACCOUNT_TYPE_MINER){ + LOG(TRACE) << "_id= " << _id << ",m_account_type=" << m_account_type << ",_p->id()=" << _p->id(); + return true; + } + + unsigned msgType; + try{ + msgType = _r[0][0].toInt(); + }catch(...){ + LOG(TRACE) << "msgType err _id= " << _id << ",m_account_type=" << m_account_type << ",_p->id()=" << _p->id(); + return true; + } + + bool contain = (find(m_miner_list.begin(), m_miner_list.end(), _p->id()) != m_miner_list.end()); + if(!contain){ + LOG(TRACE) << "interpret _p->id()=" << _p->id() << ",_id=" << _id << ",msgType=" << msgType; + return true; + } + + LOG(TRACE) << "interpret _p->id()=" << _p->id() << ",_id=" << _id << ",msgType=" << msgType; + try{ + switch(msgType){ + case raftBlockVote: + onBlockVote(_p, _r); + break; + case raftBlockVoteEcho: + onBlockVoteAck(_p, _r); + break; + default: + break; + } + }catch(...){ + LOG(ERROR) << "catchErrinterpret _p->id()=" << _p->id() << ",_id=" << _id << ",msgType=" << msgType; + } + + return true; +} + +void Raft::reportBlock(BlockHeader const& _b) +{ + unsigned long long blockNumber = _b.number().convert_to(); + m_blockReport = blockNumber; + kill(m_hostTid, RAFT_SIGNAL_REPORT); + + LOG(TRACE) << "blockNumber=" << blockNumber << ",m_blockNumber=" << m_blockNumber; +} + +void Raft::reportBlockSelf() +{ + unsigned long long blockNumber = m_blockReport; + + LOG(TRACE) << "blockNumber=" << blockNumber << ",m_blockNumber=" << m_blockNumber; + + if(m_blockNumber >= blockNumber) + return; + + m_blockNumber = blockNumber; + m_blockNumberRecv = blockNumber; + + resetConfig(); + reSet(); + m_currentView = 0; +} + +void Raft::resetConfig() +{ + if(!getMinerList(m_miner_list)){ + LOG(ERROR) << "resetConfig: getMinerList return false"; + } + + auto ourIt = find(m_miner_list.begin(), m_miner_list.end(), id()); + bool contain = (ourIt != m_miner_list.end()); + m_account_type = contain ? EN_ACCOUNT_TYPE_MINER : EN_ACCOUNT_TYPE_NORMAL; + if(contain){ + m_node_idx = ourIt - m_miner_list.begin(); + }else{ + m_node_idx = 0; + } + + LOG(TRACE) << "m_account_type=" << m_account_type << ",id()=" << id() << ",m_node_idx=" << (unsigned)m_node_idx; +} + +void Raft::signalHandler(const boost::system::error_code& err, int signal) +{ + LOG(TRACE) << "_host.onTick err = " << err << ",signal = " << signal << ",m_hostTid=" << m_hostTid; + + if(RAFT_SIGNAL == signal){ + tick(); + }else if(RAFT_SIGNAL_REPORT == signal){ + reportBlockSelf(); + } + m_sigset->async_wait(boost::bind(&Raft::signalHandler, this, _1, _2)); +} + +void Raft::initEnv(class Client *_c, p2p::Host *_host, BlockChain* _bc) +{ + srand(utcTime()); + RaftSealEngine::initEnv(_c, _host, _bc); + + resetConfig(); + + _host->onTick(1000, [=]() { + this->tick(); + }); + + _host->onInit([=]() { + m_hostTid = gettidv1(); + LOG(TRACE) << "_host.onTick**************************************************************************************** m_hostTid =" << m_hostTid; + }); + + m_sigset = new signal_set(_host->ioService(), RAFT_SIGNAL, RAFT_SIGNAL_REPORT); + m_sigset->async_wait(boost::bind(&Raft::signalHandler, this, _1, _2)); +} + +uint64_t Raft::nodeCount() const +{ + return m_miner_list.size(); +} + +bool Raft::msgVerify(const NodeID &_nodeID, bytes const& _msg, h520 _msgSign) +{ + BlockHeader header(_msg); + //h256 hash = sha3(_msg); + h256 hash = header.hash(WithoutSeal); + + LOG(TRACE) << "_nodeID=" << _nodeID << ",hash=" << hash << ",_msgSign=" << _msgSign; + return dev::verify(_nodeID, _msgSign, hash); +} + +bytes Raft::authBytes() +{ + bytes ret; + RLPStream authListStream; + authListStream.appendList(m_idVoted.size()*2); + + for(auto it : m_idVoted){ + authListStream << it.first; + authListStream << it.second; + } + + authListStream.swapOut(ret); + return ret; +} + +void Raft::reSet() +{ + m_blockBytes = bytes(); + //m_currentView = 0; + m_consensusTimeOut = 0; + m_idVoted.clear(); + m_idUnVoted.clear(); + m_votedId = NodeID(); + m_recvedBlock = false; + m_last_consensus_time = utcTime(); + + bool have; + bytes blockBytes; + + while(1){ + tie(have, blockBytes) = m_blocks.tryPop(0); + if(!have) + break; + + LOG(TRACE) << "reSet too much block:m_consensusState=" << m_consensusState << ",nodeCount()=" << nodeCount(); + } + + m_consensusState = raftInitial; + + LOG(TRACE) << "m_consensusState=" << m_consensusState << ",nodeCount()=" << nodeCount(); +} + +void Raft::voteBlockEnd() +{ + uint64_t now = utcTime(); + if(m_idUnVoted.size() >= (nodeCount()+1)/2 || now > m_consensusTimeOut){ + LOG(TRACE) << "m_idUnVoted.size()=" << m_idUnVoted.size() << ",m_idVoted.size()=" << m_idVoted.size() << ",nodeCount()=" << nodeCount(); + + reSet(); + return; + } + + if(raftFinished != m_consensusState && m_idVoted.size() > nodeCount()/2){ + LOG(TRACE) << "Vote succed, m_blockBytes.size() = " << m_blockBytes.size(); + + try{ + if(m_onSealGenerated){ + std::vector> sig_list; + + for(size_t i = 0; i < m_miner_list.size(); i++){ + if(m_idVoted.count(m_miner_list[i])){ + sig_list.push_back(std::make_pair(u256(i), m_idVoted[m_miner_list[i]])); + } + } + + BlockHeader header(m_blockBytes); + RLP r(m_blockBytes); + RLPStream rs; + rs.appendList(5); + rs.appendRaw(r[0].data()); // header + rs.appendRaw(r[1].data()); // tx + rs.appendRaw(r[2].data()); // uncles + rs.append(header.hash()); // hash + rs.appendVector(sig_list); // sign_list + + bytes blockBytes; + rs.swapOut(blockBytes); + + LOG(TRACE) << "Vote_succed: idx.count blockBytes.size() = " << blockBytes.size() << ",header.number()=" << header.number() << ",header.hash()=" << header.hash(WithoutSeal) << ",generl_id = " << (m_votedId == NodeID() ? id() : m_votedId) << ",m_node_idx=" << static_cast(m_node_idx); + + m_onSealGenerated(blockBytes, m_votedId == NodeID()); + } + }catch(...){ + LOG(ERROR) << "m_consensusFinishedFunc run err"; + } + + m_consensusState = raftFinished; + m_consensusTimeOut = utcTime() + m_consensusTimeInterval; + return; + } +} + +void Raft::onBlockVoteAck(RaftPeer* _p, RLP const& _r) +{ + bool vote = _r[0][1].toInt(); + uint64_t currentView = _r[0][2].toInt(); + Signature mySign = h520(_r[0][3].toBytes()); + NodeID idrecv(_r[0][4].toBytes()); + + bool v = msgVerify(_p->id(), m_blockBytes, mySign); + bool voteMatch = true; + if(m_votedId != NodeID()){ + voteMatch = (idrecv == m_votedId); + }else{ + voteMatch = (id() == idrecv); + } + + LOG(TRACE) << ",v=" << v << ",voteMatch=" << voteMatch << ",currentView=" << currentView << ",nodeCount()=" << nodeCount() << ",vote=" << vote << ",m_currentView=" << m_currentView << ",m_blockNumber=" << m_blockNumber << ",idrecv=" << idrecv << ",m_consensusState=" << static_cast(m_consensusState); + if(!v || currentView != m_currentView || !voteMatch || raftFinished == m_consensusState) + return; + + if(vote){ + m_idVoted[_p->id()] = mySign; + }else{ + m_idUnVoted.insert(_p->id()); + } + + LOG(TRACE) << ",m_idUnVoted.size()=" << m_idUnVoted.size() << ",m_votedId=" << m_votedId << ",m_idVoted.size()=" << m_idVoted.size() << ",nodeCount()=" << nodeCount(); + voteBlockEnd(); +} + +void Raft::onBlockVote(RaftPeer* _p, RLP const& _r) +{ + uint64_t currentView = _r[0][1].toInt(); + Signature mySign = h520(_r[0][2].toBytes()); + bytes blockBytes = _r[0][3].toBytes(); + BlockHeader header(blockBytes); + uint64_t blockNumber = header.number().convert_to(); + bool vote = false; + uint64_t now = utcTime(); + + bool verify = msgVerify(_p->id(), blockBytes, mySign); + bool verifyblock = true; + verifyblock = verifyBlock(blockBytes); + + LOG(TRACE) << "verify =" << verify << ",verifyblock=" << verifyblock << ",nodeCount()=" << nodeCount() << ",currentView=" << currentView << ",m_currentView=" << m_currentView << ",blockNumber=" << blockNumber << ",m_blockNumber=" << m_blockNumber; + if(verify && verifyblock && m_blockNumber + 1 == blockNumber && currentView > m_currentView){ + vote = true; + m_idVoted.clear(); + m_idUnVoted.clear(); + m_currentView = currentView; + m_consensusState = raftWaitingVote; + m_consensusTimeOut = utcTime() + m_consensusTimeInterval; + m_votedId = _p->id(); + m_blockBytes = blockBytes; + m_idVoted[_p->id()] = mySign; + LOG(TRACE) << "m_currentView =" << m_currentView << ",m_votedId=" << m_votedId << ",m_blockBytes.size()=" << m_blockBytes.size(); + } + + h256 hash = sha3(blockBytes); + mySign = sign(header.hash(WithoutSeal)); + + if(vote) + m_idVoted[id()] = mySign; + + RLPStream data; + data << raftBlockVoteEcho; + data << (uint8_t)vote; + data << m_currentView; + data << mySign; + data << _p->id(); + + multicast(m_miner_list, data); + LOG(TRACE) << "hash=" << hash << ",mySign=" << mySign << ",blockBytes.size()=" << blockBytes.size() << ",vote=" << vote << ",_p->id()=" << _p->id(); + + voteBlockEnd(); +} + +void Raft::voteBlockBegin() +{ + BlockHeader header(m_blockBytes); + Signature mySign = sign(header.hash(WithoutSeal)); + RLPStream msg; + msg << raftBlockVote; + msg << ++m_currentView; + msg << mySign; + msg << m_blockBytes; + + m_idVoted[id()] = mySign; + + m_consensusTimeOut = utcTime() + m_consensusTimeInterval; + m_consensusState = raftWaitingVote; + + multicast(m_miner_list, msg); + LOG(TRACE) << ",header.hash(WithoutSeal)=" << header.hash(WithoutSeal) << ",mySign=" << mySign << ",m_blockBytes.size()=" << m_blockBytes.size(); +} + +void Raft::generateSealBegin(bytes const& _block) +{ + if(m_account_type != EN_ACCOUNT_TYPE_MINER || m_consensusState != raftInitial) + return; + + m_blockBytes = _block; + + LOG(TRACE) << "m_miner_list.size()=" << m_miner_list.size() << ",m_consensusState=" << m_consensusState << ",m_consensusRandTimeInterval=" << m_consensusRandTimeInterval << ",m_blockBytes.size()=" << m_blockBytes.size(); + assert(m_miner_list.size() >= 1); + + if(1 == m_miner_list.size() || 0 == m_consensusRandTimeInterval){ + voteBlockBegin(); + }else{ + m_consensusState = raftPrePrepare; + m_consensusTimeOut = utcTime() + rand()%m_consensusRandTimeInterval; + } +} + +void Raft::generateSeal(BlockHeader const& _bi, bytes const& _block) +{ + (void)_bi; + + if(m_account_type != EN_ACCOUNT_TYPE_MINER) + return; + + m_blocks.push(_block); + kill(m_hostTid, RAFT_SIGNAL); + m_recvedBlock = true; +} + +bool Raft::shouldSeal(Interface * _client) +{ + unsigned long long number = m_blockNumberRecv; + uint64_t blockNumber = _client->number(); + bool recvedBlock = m_recvedBlock; + + LOG(TRACE) << "blockNumber = " << blockNumber << ",m_blockNumberRecv=" << number << ",m_consensusState=" << m_consensusState << ",recvedBlock=" << recvedBlock; + return m_consensusState == raftInitial && !recvedBlock; +} + +h512s Raft::getMinerNodeList() +{ + h512s ret; + for(auto i : m_miner_list) + ret.push_back(i); + + return ret; +} + +bool Raft::checkBlockSign(BlockHeader const& _header, std::vector> _sign_list) +{ + Timer t; + LOG(TRACE) << "PBFT::checkBlockSign " << _header.number(); + + h512s miner_list; + if (!getMinerList(miner_list, static_cast(_header.number() - 1))) { + LOG(ERROR) << "checkBlockSign failed for getMinerList return false, blk=" << _header.number() - 1; + return false; + } + + LOG(DEBUG) << "checkBlockSign call getAllNodeConnInfo: blk=" << _header.number() - 1 << ", miner_list.size()=" << miner_list.size(); + + unsigned singCount = 0; + for (auto item : _sign_list) { + unsigned idx = item.first.convert_to(); + if (idx >= miner_list.size() || !dev::verify(miner_list[idx], item.second, _header.hash(WithoutSeal))) { + LOG(ERROR) << "checkBlockSign failed, verify false, blk=" << _header.number() << ",hash=" << _header.hash(WithoutSeal); + continue; + } + + singCount++; + if(singCount >= (miner_list.size()+1)/2) + return true; + } + + LOG(INFO) << "checkBlockSign success, blk=" << _header.number() << ",hash=" << _header.hash(WithoutSeal) << ",timecost=" << t.elapsed() / 1000 << "ms"; + return false; +} + + diff --git a/libraftseal/Raft.h b/libraftseal/Raft.h new file mode 100644 index 0000000000..6fa72542e7 --- /dev/null +++ b/libraftseal/Raft.h @@ -0,0 +1,110 @@ + +#pragma once + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + + +#include "RaftSealEngine.h" + +using namespace std; +using namespace dev; +using namespace eth; + +namespace dev +{ +namespace eth +{ + +enum raftState +{ + raftInitial, + raftPrePrepare, + raftWaitingVote, + raftFinished +}; + +class Raft:public RaftSealEngine +{ +public: + virtual bool interpret(RaftPeer*, unsigned _id, RLP const& _r); + + virtual bool shouldSeal(Interface*); + + virtual void initEnv(class Client *_c, p2p::Host *_host, BlockChain* _bc) override; + virtual void generateSeal(BlockHeader const& _bi, bytes const& _block) override; + void generateSealBegin(bytes const& _block); + + unsigned accountType() const { return m_account_type; } + + //void generateSeal(BlockHeader const& _bi, bytes const& _block_data) override; + void onSealGenerated(std::function const& _f) { m_onSealGenerated = _f;} + + void reportBlock(BlockHeader const& _b); + h512s getMinerNodeList(); + uint64_t lastConsensusTime() const { /*Guard l(m_mutex);*/ return m_last_consensus_time;}; + + u256 nodeIdx() const { /*Guard l(m_mutex);*/ return u256(static_cast(m_node_idx)); } +protected: + virtual void tick(); + void reportBlockSelf(); + + void resetConfig(); + + void onBlockVoteAck(RaftPeer* _p, RLP const& _r); + void onBlockVote(RaftPeer* _p, RLP const& _r); + bytes authBytes(); + void reSet(); + void voteBlockEnd(); + void voteBlockBegin(); + bool msgVerify(const NodeID &_nodeID, bytes const& _msg, h520 _msgSign); + void addNodes(const std::string &_nodes); + uint64_t nodeCount() const; + void signalHandler(const boost::system::error_code& err, int signal); + bool checkBlockSign(BlockHeader const& _header, std::vector> _sign_list); +private: + unsigned m_consensusTimeInterval = 20000; + unsigned m_consensusRandTimeInterval = 0; + + std::function m_onSealGenerated; + + std::atomic m_blockReport = {0}; + uint64_t m_blockNumber = 0; + uint64_t m_blockNumberRecv = 0; + unsigned m_account_type; + + NodeID m_votedId; + h512s m_miner_list; + + bytes m_blockBytes; + uint64_t m_currentView; + uint64_t m_consensusTimeOut = 0; + set m_idUnVoted; + map m_idVoted; + //unsigned m_consensusState = raftInitial; + std::atomic m_consensusState = { raftInitial }; + std::atomic m_recvedBlock = { false }; + std::atomic m_node_idx = {0}; + std::atomic m_last_consensus_time = {0}; + + concurrent_queue m_blocks; + + std::atomic m_hostTid = {0}; + boost::asio::signal_set *m_sigset; +}; + + +} +} + diff --git a/libraftseal/RaftClient.cpp b/libraftseal/RaftClient.cpp new file mode 100644 index 0000000000..b6d2a05bb9 --- /dev/null +++ b/libraftseal/RaftClient.cpp @@ -0,0 +1,193 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ + +#include +#include +#include +#include "RaftClient.h" +#include "Common.h" +#include "Raft.h" +#include "RaftHost.h" +using namespace std; +using namespace dev; +using namespace dev::eth; +using namespace p2p; + +RaftClient& dev::eth::asRaftClient(Interface& _c) +{ + if (dynamic_cast(_c.sealEngine())) + return dynamic_cast(_c); + throw NotRaftSealEngine(); +} + +RaftClient* dev::eth::asRaftClient(Interface* _c) +{ + if (dynamic_cast(_c->sealEngine())) + return &dynamic_cast(*_c); + throw NotRaftSealEngine(); +} + +RaftClient::RaftClient( + ChainParams const& _params, + int _networkID, + p2p::Host* _host, + std::shared_ptr _gpForAdoption, + std::string const& _dbPath, + WithExisting _forceAction, + TransactionQueue::Limits const& _limits +): + Client(_params, _networkID, _host, _gpForAdoption, _dbPath, _forceAction, _limits) +{ + // will throw if we're not an Raft seal engine. + asRaftClient(*this); + + init(_params, _host); + m_last_import_time = utcTime(); +} + +RaftClient::~RaftClient() { + raft()->cancelGeneration(); + stopWorking(); +} + +void RaftClient::init(ChainParams const&, p2p::Host *_host) { + raft()->initEnv(this, _host, &m_bc); + + raft()->onSealGenerated([ = ](bytes const & _block, bool _isOurs) { + if (!this->submitSealed(_block, _isOurs)) { + clog(ClientNote) << "Submitting block failed..."; + } else { + //Guard l(x_last_block); + //m_last_commited_block = BlockHeader(header, HeaderData); + //u256 time = m_last_commited_block.timestamp(); + + SetLastTime(); + } + }); + + clog(ClientNote) << "Init RaftClient success"; +} + +Raft* RaftClient::raft() const +{ + return dynamic_cast(Client::sealEngine()); +} + +void RaftClient::startSealing() { + setName("Client"); + raft()->reportBlock(bc().info()); + raft()->startGeneration(); + Client::startSealing(); +} + +void RaftClient::stopSealing() { + Client::stopSealing(); + raft()->cancelGeneration(); +} + +void RaftClient::SetLastTime() +{ + uint64_t time = bc().info().timestamp().convert_to(); + + if (time > m_last_block_time) { + m_last_block_time = time; + } + +} + +void RaftClient::syncBlockQueue() { + Client::syncBlockQueue(); + raft()->reportBlock(bc().info()); + + SetLastTime(); +} + +bool RaftClient::submitSealed(bytes const& _block, bool _isOurs) +{ + uint64_t now = utcTime(); + uint64_t interval = now - m_last_import_time; + m_last_import_time = now; + LOG(TRACE) << "Client_submitSealed: _block.size() = " << _block.size() << ",_isOurs=" << _isOurs << ",interval=" << interval; + + // OPTIMISE: very inefficient to not utilise the existing OverlayDB in m_postSeal that contains all trie changes. + return m_bq.import(&_block, _isOurs) == ImportResult::Success; +} + +void RaftClient::rejigSealing() +{ + bytes blockBytes; + bool would_seal = m_wouldSeal && wouldSeal() && (raft()->accountType() == EN_ACCOUNT_TYPE_MINER); + bool is_major_syncing = isMajorSyncing(); + if (would_seal && !is_major_syncing) + { + if (sealEngine()->shouldSeal(this)) + { + + m_wouldButShouldnot = false; + + LOG(TRACE) << "Rejigging seal engine... m_maxBlockTranscations = " << m_maxBlockTranscations; + DEV_WRITE_GUARDED(x_working) + { + if (m_working.isSealed()) + { + clog(ClientTrace) << "Tried to seal sealed block..."; + return; + } + + u256 now_time = u256(utcTime()); + auto last_exec_finish_time = raft()->lastConsensusTime(); + size_t tx_num = m_working.pending().size(); + if (tx_num < m_maxBlockTranscations && now_time - last_exec_finish_time < sealEngine()->getIntervalBlockTime()) { + clog(ClientTrace) << "Wait for next interval, tx:" << tx_num << ", last_exec_finish_time:" << last_exec_finish_time << ",now:" << now_time << ", interval=" << now_time - last_exec_finish_time << "ms" << ",sealEngine()->getIntervalBlockTime()=" << sealEngine()->getIntervalBlockTime(); + return; + } + + if (m_working.empty()) + m_working.resetCurrentTime(); + m_working.setIndex(raft()->nodeIdx()); + //m_working.setNodeList(raft()->getMinerNodeList()); + m_working.commitToSeal(bc(), m_extraData); + } + DEV_READ_GUARDED(x_working) + { + DEV_WRITE_GUARDED(x_postSeal) + m_postSeal = m_working; + m_sealingInfo = m_working.info(); + blockBytes = m_working.blockBytes(); + } + + if (wouldSeal()) + { + clog(ClientNote) << "-------------------------Generating seal on" << m_sealingInfo.hash(WithoutSeal) << "#" << m_sealingInfo.number() << ",m_working.empty()=" << m_working.empty(); + raft()->generateSeal(BlockHeader(), blockBytes); + } + } + else { + m_wouldButShouldnot = true; + LOG(TRACE) << "m_wouldButShouldnot=" << m_wouldButShouldnot; + //this_thread::sleep_for(std::chrono::milliseconds(1000)); + } + }/* else { + clog(ClientTrace) << "would_seal=" << would_seal << ",is_major_syncing=" << is_major_syncing; + if (is_major_syncing) { + if (auto h = m_host.lock()) { + clog(ClientTrace) << "state=" << EthereumHost::stateName(h->status().state); + } + } + }*/ +} + diff --git a/libraftseal/RaftClient.h b/libraftseal/RaftClient.h new file mode 100644 index 0000000000..f51ba14f39 --- /dev/null +++ b/libraftseal/RaftClient.h @@ -0,0 +1,71 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ + +#pragma once + +#include + +namespace dev +{ +namespace eth +{ + +class Raft; + +DEV_SIMPLE_EXCEPTION(NotRaftSealEngine); +DEV_SIMPLE_EXCEPTION(ChainParamsNotRaft); +DEV_SIMPLE_EXCEPTION(InitRaftFailed); + +class RaftClient: public Client +{ +public: + /// Trivial forwarding constructor. + RaftClient( + ChainParams const& _params, + int _networkID, + p2p::Host* _host, + std::shared_ptr _gpForAdoption, + std::string const& _dbPath = std::string(), + WithExisting _forceAction = WithExisting::Trust, + TransactionQueue::Limits const& _l = TransactionQueue::Limits {1024, 1024} + ); + + virtual ~RaftClient(); + + void startSealing() override; + void stopSealing() override; + //bool isMining() const override { return isWorking(); } + + Raft* raft() const; +protected: + void init(ChainParams const& _params, p2p::Host *_host); + void rejigSealing() override; + void syncBlockQueue() override; + bool submitSealed(bytes const& _block, bool _isOurs); + void SetLastTime(); + + std::atomic m_last_block_time = { 0 }; + + uint64_t m_last_import_time = 0; + BlockHeader m_last_commited_block; +}; + +RaftClient& asRaftClient(Interface& _c); +RaftClient* asRaftClient(Interface* _c); + +} +} diff --git a/libraftseal/RaftHost.cpp b/libraftseal/RaftHost.cpp new file mode 100644 index 0000000000..7c31de4f38 --- /dev/null +++ b/libraftseal/RaftHost.cpp @@ -0,0 +1,65 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file RaftHost.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "RaftPeer.h" +#include "RaftHost.h" + +#include +#include +#include + +using namespace std; +using namespace dev; +using namespace dev::p2p; +using namespace dev::eth; + +RaftHost::RaftHost(RaftSealEngine* leader) +{ + m_leader = leader; +} + +RaftHost::~RaftHost() +{ +} + + +void RaftHost::foreachPeer(std::function)> const& _f) const +{ + auto sessions = peerSessions(); + auto sessionLess = [](std::pair, std::shared_ptr> const & _left, std::pair, std::shared_ptr> const & _right) + { return _left.first->rating() == _right.first->rating() ? _left.first->connectionTime() < _right.first->connectionTime() : _left.first->rating() > _right.first->rating(); }; + + std::sort(sessions.begin(), sessions.end(), sessionLess); + for (auto s : sessions) + if (!_f(capabilityFromSession(*s.first))) + return; + + static const unsigned c_oldProtocolVersion = 62; + sessions = peerSessions(c_oldProtocolVersion); //TODO: remove once v61+ is common + std::sort(sessions.begin(), sessions.end(), sessionLess); + for (auto s : sessions) + if (!_f(capabilityFromSession(*s.first, c_oldProtocolVersion))) + return; + +} + + + diff --git a/libraftseal/RaftHost.h b/libraftseal/RaftHost.h new file mode 100644 index 0000000000..dd99270e5c --- /dev/null +++ b/libraftseal/RaftHost.h @@ -0,0 +1,64 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file RaftHost.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "RaftPeer.h" +#include "RaftSealEngine.h" + +namespace dev +{ +namespace eth +{ + +class RaftSealEngine; + +class RaftHost: public HostCapability +{ + friend class RaftPeer; + +public: + RaftHost(RaftSealEngine* leader); + virtual ~RaftHost(); + + void foreachPeer(std::function)> const&) const; + + RaftSealEngine* Leader() {return m_leader;} +protected: + + +private: + RaftSealEngine* m_leader = 0; +}; + +} +} diff --git a/libraftseal/RaftPeer.cpp b/libraftseal/RaftPeer.cpp new file mode 100644 index 0000000000..702a32f774 --- /dev/null +++ b/libraftseal/RaftPeer.cpp @@ -0,0 +1,84 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file RaftPeer.cpp + * @author Gav Wood + * @date 2014 + */ + +#include +#include +#include "RaftHost.h" +#include "Common.h" + +using namespace std; +using namespace dev; +using namespace dev::p2p; +using namespace dev::eth; + +RaftPeer::RaftPeer(std::shared_ptr _s, p2p::HostCapabilityFace* _h, unsigned _i, p2p::CapDesc const& _cap, uint16_t _capID): + Capability(_s, _h, _i, _capID) +{ + RaftHost* host = (RaftHost*)_h; + m_leader = host->Leader(); +} + +RaftPeer::~RaftPeer() +{ +} + +RaftHost* RaftPeer::host() const +{ + return static_cast(Capability::hostCapability()); +} + +bytes RaftPeer::toBytes(RLP const& _r) +{ + try{ + return _r.toBytes(); + }catch(...){ + return bytes(); + } + + return bytes(); +} + +bool RaftPeer::interpret(unsigned _id, RLP const& _r) +{ + bool ret = m_leader && m_leader->interpret(this, _id, _r); + + return ret; +} + +bool RaftPeer::sendBytes(unsigned _t, const bytes &_b) +{ + RLPStream s; + prep(s, _t, 1) << _b; + + sealAndSend(s); + return true; +} + +NodeID RaftPeer::id() +{ + std::shared_ptr s = session(); + if(s) + return s->id(); + + return NodeID(); +} + + diff --git a/libraftseal/RaftPeer.h b/libraftseal/RaftPeer.h new file mode 100644 index 0000000000..fe9fe89594 --- /dev/null +++ b/libraftseal/RaftPeer.h @@ -0,0 +1,90 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file RaftPeer.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "RaftHost.h" +#include "Common.h" +#include "RaftSealEngine.h" + +namespace dev +{ + +using namespace p2p; + +/* +using namespace p2p::Session; +using namespace p2p::HostCapabilityFace; +using namespace p2p::HostCapability; +using namespace p2p::Capability; +using namespace p2p::CapDesc; +*/ + +namespace eth +{ + + + +class RaftSealEngine; +class RaftHost; + +class RaftPeer: public Capability +{ + friend class RaftHost; + +public: + RaftPeer(std::shared_ptr _s, p2p::HostCapabilityFace* _h, unsigned _i, p2p::CapDesc const& _cap, uint16_t _capID); + + virtual ~RaftPeer(); + RaftHost* host() const; + + bool sendBytes(unsigned _t, const bytes &_b); + static std::string name() { return "Raft"; } + static u256 version() { return c_protocolVersion; } + static unsigned messageCount() { return RaftMsgCount; } + + NodeID id(); +protected: + bytes toBytes(RLP const& _r); +private: + virtual bool interpret(unsigned _id, RLP const&) override; + + RaftSealEngine* m_leader = 0; +}; + +} +} diff --git a/libraftseal/RaftSealEngine.cpp b/libraftseal/RaftSealEngine.cpp new file mode 100644 index 0000000000..67c08840a4 --- /dev/null +++ b/libraftseal/RaftSealEngine.cpp @@ -0,0 +1,201 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Ethash.cpp + * @author Gav Wood + * @date 2014 + */ + +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "RaftSealEngine.h" +#include "Common.h" +#include "Raft.h" + +using namespace std; +using namespace dev; +using namespace eth; +//using namespace p2p; + +RaftSealEngine::RaftSealEngine() +{ +} + +void RaftSealEngine::initEnv(class Client *_c, p2p::Host *_host, BlockChain* _bc) +{ + m_client = _c; + m_host = _host; + m_pair = _host->keyPair(); + m_bc = _bc; + + m_LeaderHost = new RaftHost(this); + std::shared_ptr ptr(m_LeaderHost);// = std::make_shared(); + m_host->registerCapability(ptr); +} + +void RaftSealEngine::init() +{ + static SealEngineFactory __eth_registerSealEngineFactoryRaft = SealEngineRegistrar::registerSealEngine("RAFT"); +} + +void RaftSealEngine::populateFromParent(BlockHeader& _bi, BlockHeader const& _parent) const +{ + SealEngineFace::populateFromParent(_bi, _parent); + _bi.setGasLimit(chainParams().u256Param("maxGasLimit")); +} + +void RaftSealEngine::multicast(const set &_id, RLPStream& _msg) +{ + if(_id.empty()) + return; + + m_LeaderHost->foreachPeer([&](std::shared_ptr _p) + { + if(_id.count(_p->id())){ + RLPStream s; + _p->prep(s, RaftMsgRaft, 1); + s.appendList(_msg); + _p->sealAndSend(s); + } + return true; + }); +} + +void RaftSealEngine::multicast(const h512s &miner_list, RLPStream& _msg) +{ + set id; + id.insert(miner_list.begin(), miner_list.end()); + + multicast(id, _msg); +} + +bool RaftSealEngine::verifyBlock(const bytes& _block, ImportRequirements::value _ir) const +{ + try{ + m_bc->verifyBlock(&_block, nullptr, _ir); + }catch(...){ + return false; + } + + return true; +} + +void RaftSealEngine::tick() +{ +} + +void RaftSealEngine::workLoop() +{/* + while (isWorking()){ + this->tick(); + + this_thread::sleep_for(std::chrono::milliseconds(100)); + }*/ +} + +bool RaftSealEngine::getMinerList(set &_nodes, int _blk_no) const +{ + std::map all_node; + NodeConnManagerSingleton::GetInstance().getAllNodeConnInfo(_blk_no, all_node); + + for (auto iter = all_node.begin(); iter != all_node.end(); ++iter) { + if (iter->second._iIdentityType == EN_ACCOUNT_TYPE_MINER) { + _nodes.insert(jsToPublic(toJS(iter->second._sNodeId))); + } + } + + LOG(TRACE) << "_nodes=" << _nodes; + return true; +} + +bool RaftSealEngine::getMinerList(h512s &_miner_list, int _blk_no) const +{ + std::map all_node; + NodeConnManagerSingleton::GetInstance().getAllNodeConnInfo(_blk_no, all_node); + + unsigned miner_num = 0; + for (auto iter = all_node.begin(); iter != all_node.end(); ++iter) { + if (iter->second._iIdentityType == EN_ACCOUNT_TYPE_MINER) { + ++miner_num; + } + } + _miner_list.resize(miner_num); + for (auto iter = all_node.begin(); iter != all_node.end(); ++iter) { + if (iter->second._iIdentityType == EN_ACCOUNT_TYPE_MINER) { + auto idx = static_cast(iter->second._iIdx); + if (idx >= miner_num) { + LOG(ERROR) << "getMinerList return false cause for idx=" << idx << ",miner_num=" << miner_num; + return false; + } + _miner_list[idx] = jsToPublic(toJS(iter->second._sNodeId)); + } + } + + return true; + +} + +bool RaftSealEngine::getIdx(map &_idx, int _blk_no) const +{ + std::map all_node; + NodeConnManagerSingleton::GetInstance().getAllNodeConnInfo(_blk_no, all_node); + + unsigned miner_num = 0; + for (auto iter = all_node.begin(); iter != all_node.end(); ++iter) { + if (iter->second._iIdentityType == EN_ACCOUNT_TYPE_MINER) { + ++miner_num; + } + } + + for (auto iter = all_node.begin(); iter != all_node.end(); ++iter) { + if (iter->second._iIdentityType == EN_ACCOUNT_TYPE_MINER) { + auto idx = static_cast(iter->second._iIdx); + if (idx >= miner_num) { + LOG(ERROR) << "getMinerList return false cause for idx=" << idx << ",miner_num=" << miner_num; + return false; + } + + _idx[jsToPublic(toJS(iter->second._sNodeId))] = idx; + } + } + + return true; +} + +bool RaftSealEngine::interpret(RaftPeer* _peer, unsigned _id, RLP const& _r) +{ + (void)_peer; + (void)_id; + (void)_r; + + return true; +} + +EVMSchedule const& RaftSealEngine::evmSchedule(EnvInfo const& _envInfo) const +{ + (void)_envInfo; + return DefaultSchedule; +} + diff --git a/libraftseal/RaftSealEngine.h b/libraftseal/RaftSealEngine.h new file mode 100644 index 0000000000..bdd7731e96 --- /dev/null +++ b/libraftseal/RaftSealEngine.h @@ -0,0 +1,106 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Ethash.h + * @author Gav Wood + * @date 2014 + * + * A proof of work algorithm. + */ + +#pragma once + +#include + +#include +#include +#include +#include +#include +#include + +#include "RaftHost.h" +#include "RaftPeer.h" + +#include +#include +#include +#include +#include + +using namespace std; +using namespace dev; +using namespace eth; + +namespace dev +{ + +using namespace p2p; + +namespace eth +{ + +class RaftHost; +class RaftPeer; + +class RaftSealEngine: public eth::SealEngineBase//, Worker +{ +public: + RaftSealEngine(); + std::string name() const override { return "RAFT"; } + static void init(); + + virtual void initEnv(class Client *_c, p2p::Host *_host, BlockChain* _bc); + + void startGeneration() {/* startWorking(); */} + //void cancelGeneration() override { stopWorking(); } + + virtual bool shouldSeal(Interface*){return true;}; + void populateFromParent(BlockHeader& _bi, BlockHeader const& _parent) const; + virtual bool interpret(RaftPeer*, unsigned _id, RLP const& _r); + + EVMSchedule const& evmSchedule(EnvInfo const&) const override; + + +protected: + virtual void tick(); + bool getMinerList(set &_nodes, int _blk_no = -1) const; + bool getMinerList(h512s &_miner_list, int _blk_no = -1) const; + bool getIdx(map &_idx, int _blk_no = -1) const; + + + Signature sign(h256 const& _hash){return dev::sign(m_pair.secret(), _hash);}; + bool verify(Signature const& _s, h256 const& _hash){return dev::verify(m_pair.pub(), _s, _hash);}; + + void multicast(const set &_id, RLPStream& _msg); + void multicast(const h512s &_miner_list, RLPStream& _msg); + + bool verifyBlock(const bytes& _block, ImportRequirements::value _ir = ImportRequirements::OutOfOrderChecks) const; + + NodeID id() const{ return m_pair.pub();}; + +private: + virtual void workLoop(); +private: + class Client *m_client = 0; + RaftHost* m_LeaderHost = 0; + p2p::Host* m_host = 0; + KeyPair m_pair; + BlockChain *m_bc; +}; + +} +} diff --git a/libsinglepoint/CMakeLists.txt b/libsinglepoint/CMakeLists.txt new file mode 100644 index 0000000000..f706b9cf5b --- /dev/null +++ b/libsinglepoint/CMakeLists.txt @@ -0,0 +1,27 @@ +aux_source_directory(. SRC_LIST) + +file(GLOB HEADERS "*.h") + + +set(SRC_LIST ${SRC_LIST} ${SRCS}) + +add_library(singlepoint ${SRC_LIST} ${HEADERS}) +eth_use(singlepoint OPTIONAL Eth::singlepoint-cl Cpuid) + +find_package(Eth) + +include_directories(../libodbc/include + ../libodbc/include/db2_linux + ../libodbc/include/ibase + ../libodbc/include/infomix + ../libodbc/include/mysql + ../libodbc/include/odbc_linux + ../libodbc/include/pgsql + ../libodbc/include/sqlbase + ../libodbc/include/sqllite + ../libodbc/include/ss_linux + ../libodbc/include/sybase) +target_include_directories(singlepoint PRIVATE ..) +target_link_libraries(singlepoint ${Eth_ETHEREUM_LIBRARIES}) + +install(TARGETS singlepoint RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib) diff --git a/libsinglepoint/SinglePoint.cpp b/libsinglepoint/SinglePoint.cpp new file mode 100644 index 0000000000..6e6dc7b9af --- /dev/null +++ b/libsinglepoint/SinglePoint.cpp @@ -0,0 +1,97 @@ + + +#include "SinglePoint.h" + +#include +#include +#include +#include +using namespace std; +using namespace dev; +using namespace eth; + + + +void SinglePoint::init() +{ + ETH_REGISTER_SEAL_ENGINE(SinglePoint); +} + +SinglePoint::SinglePoint() +{ + +} + +strings SinglePoint::sealers() const +{ + return {"cpu"}; +} + + + + + +void SinglePoint::verify(Strictness , BlockHeader const& , BlockHeader const& , bytesConstRef ) const +{ + +} + +void SinglePoint::verifyTransaction(ImportRequirements::value , TransactionBase const& , BlockHeader const& ) const +{ + +} + +u256 SinglePoint::childGasLimit(BlockHeader const& , u256 const& ) const +{ + return 0; +} + + + +u256 SinglePoint::calculateDifficulty(BlockHeader const& , BlockHeader const& ) const +{ + return 1; +} + +void SinglePoint::populateFromParent(BlockHeader& _bi, BlockHeader const& _parent) const +{ + SealEngineFace::populateFromParent(_bi, _parent);//自动调blockheader里面的 + +} + +bool SinglePoint::quickVerifySeal(BlockHeader const& ) const +{ + return true; +} + +bool SinglePoint::verifySeal(BlockHeader const& ) const +{ + return true; +} +void SinglePoint::setIntervalBlockTime(u256 _intervalBlockTime) +{ + if ( _intervalBlockTime < 1000 ) + _intervalBlockTime = 1000; + + m_intervalBlockTime = _intervalBlockTime; +} + +void SinglePoint::generateSeal(BlockHeader const& bi, bytes const& _data) +{ + auto d = chrono::duration_cast(chrono::high_resolution_clock::now() - m_lasttimesubmit); + + if ( d.count() >= getIntervalBlockTime() ) + { + SealEngineBase::generateSeal(bi, _data);//执行回调 + m_lasttimesubmit = chrono::high_resolution_clock::now(); + + LOG(TRACE) << "SinglePoint::generateSeal Suc!!!!!!!" << bi.hash(WithoutSeal) << "#" << bi.number(); + } +} + +bool SinglePoint::shouldSeal(Interface*) +{ + return true; +} + + diff --git a/libsinglepoint/SinglePoint.h b/libsinglepoint/SinglePoint.h new file mode 100644 index 0000000000..3398f4ece0 --- /dev/null +++ b/libsinglepoint/SinglePoint.h @@ -0,0 +1,51 @@ + + +#pragma once + +#include + + + +namespace dev +{ + +namespace eth +{ + +class SinglePoint: public SealEngineBase +{ +public: + SinglePoint(); + + std::string name() const override { return "SinglePoint"; } + unsigned revision() const override { return 1; } + + + + void verify(Strictness _s, BlockHeader const& _bi, BlockHeader const& _parent, bytesConstRef _block) const override; + void verifyTransaction(ImportRequirements::value _ir, TransactionBase const& _t, BlockHeader const& _bi) const override; + void populateFromParent(BlockHeader& _bi, BlockHeader const& _parent) const override; + + strings sealers() const override; + + void generateSeal(BlockHeader const& _bi, bytes const& _data) override; + bool shouldSeal(Interface* _i) override; + + + void setIntervalBlockTime(u256 _intervalBlockTime) override; + + u256 calculateDifficulty(BlockHeader const& _bi, BlockHeader const& _parent) const; + u256 childGasLimit(BlockHeader const& _bi, u256 const& _gasFloorTarget = Invalid256) const; + + static void init(); + +private: + bool verifySeal(BlockHeader const& _bi) const; + bool quickVerifySeal(BlockHeader const& _bi) const; + + std::chrono::high_resolution_clock::time_point m_lasttimesubmit; + +}; + +} +} diff --git a/libsinglepoint/SinglePointClient.cpp b/libsinglepoint/SinglePointClient.cpp new file mode 100644 index 0000000000..99b4329447 --- /dev/null +++ b/libsinglepoint/SinglePointClient.cpp @@ -0,0 +1,47 @@ + + +#include "SinglePointClient.h" +#include "SinglePoint.h" + +using namespace std; +using namespace dev; +using namespace dev::eth; +using namespace p2p; + +DEV_SIMPLE_EXCEPTION(ChainParamsNotSinglePoint); + +SinglePointClient::SinglePointClient( + ChainParams const& _params, + int _networkID, + p2p::Host* _host, + std::shared_ptr _gpForAdoption, + std::string const& _dbPath, + WithExisting _forceAction, + TransactionQueue::Limits const& _limits +): + Client(_params, _networkID, _host, _gpForAdoption, _dbPath, _forceAction, _limits) +{ +} + + +bool SinglePointClient::isMining() const +{ + return true; +} + + + +u256 SinglePointClient::hashrate() const +{ + return 1; +} + +std::tuple SinglePointClient::getEthashWork() +{ + + return std::tuple(h256(1), h256(1), h256(1)); +} + + + + diff --git a/libsinglepoint/SinglePointClient.h b/libsinglepoint/SinglePointClient.h new file mode 100644 index 0000000000..844b1e9452 --- /dev/null +++ b/libsinglepoint/SinglePointClient.h @@ -0,0 +1,53 @@ + + +#pragma once + +#include +#include +#include "SinglePoint.h" + +namespace dev +{ +namespace eth +{ + +class SinglePoint; + +DEV_SIMPLE_EXCEPTION(InvalidSealEngine); + +class SinglePointClient: public Client +{ +public: + /// Trivial forwarding constructor. + SinglePointClient( + ChainParams const& _params, + int _networkID, + p2p::Host* _host, + std::shared_ptr _gpForAdoption, + std::string const& _dbPath = std::string(), + WithExisting _forceAction = WithExisting::Trust, + TransactionQueue::Limits const& _l = TransactionQueue::Limits {2048, 2048} + ); + + + + + + /// Are we mining now? + bool isMining() const; + + /// The hashrate... + u256 hashrate() const; + + std::tuple getEthashWork(); + + + + +}; +/* +SinglePointClient& asEthashClient(Interface& _c); +SinglePointClient* asEthashClient(Interface* _c);*/ + +} +} diff --git a/libweb3jsonrpc/AccountHolder.cpp b/libweb3jsonrpc/AccountHolder.cpp new file mode 100644 index 0000000000..a3fb0fbece --- /dev/null +++ b/libweb3jsonrpc/AccountHolder.cpp @@ -0,0 +1,222 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file AccountHolder.cpp + * @authors: + * Christian R + * Lefteris Karapetsas + * @date 2015 + */ + +#include "AccountHolder.h" +#include +#include +#include +#include + + +using namespace std; +using namespace dev; +using namespace dev::eth; + +vector g_emptyQueue; +static std::mt19937 g_randomNumberGenerator(utcTime()); +static Mutex x_rngMutex; + +vector
AccountHolder::allAccounts() const +{ + vector
accounts; + accounts += realAccounts(); + for (auto const& pair: m_proxyAccounts) + if (!isRealAccount(pair.first)) + accounts.push_back(pair.first); + return accounts; +} + +Address const& AccountHolder::defaultTransactAccount() const +{ + auto accounts = realAccounts(); + if (accounts.empty()) + return ZeroAddress; + Address const* bestMatch = &*accounts.begin(); + for (auto const& account: accounts) + if (m_client()->balanceAt(account) > m_client()->balanceAt(*bestMatch)) + bestMatch = &account; + return *bestMatch; +} + +int AccountHolder::addProxyAccount(const Address& _account) +{ + Guard g(x_rngMutex); + int id = std::uniform_int_distribution(1)(g_randomNumberGenerator); + id = int(u256(FixedHash<32>(sha3(bytesConstRef((byte*)(&id), sizeof(int) / sizeof(byte)))))); + if (isProxyAccount(_account) || id == 0 || m_transactionQueues.count(id)) + return 0; + m_proxyAccounts.insert(make_pair(_account, id)); + m_transactionQueues[id].first = _account; + return id; +} + +bool AccountHolder::removeProxyAccount(unsigned _id) +{ + if (!m_transactionQueues.count(_id)) + return false; + m_proxyAccounts.erase(m_transactionQueues[_id].first); + m_transactionQueues.erase(_id); + return true; +} + +void AccountHolder::queueTransaction(TransactionSkeleton const& _transaction) +{ + if (!m_proxyAccounts.count(_transaction.from)) + return; + int id = m_proxyAccounts[_transaction.from]; + m_transactionQueues[id].second.push_back(_transaction); +} + +vector const& AccountHolder::queuedTransactions(int _id) const +{ + if (!m_transactionQueues.count(_id)) + return g_emptyQueue; + return m_transactionQueues.at(_id).second; +} + +void AccountHolder::clearQueue(int _id) +{ + if (m_transactionQueues.count(_id)) + m_transactionQueues.at(_id).second.clear(); +} + +AddressHash SimpleAccountHolder::realAccounts() const +{ + return m_keyManager.accountsHash(); +} + +TransactionNotification SimpleAccountHolder::authenticate(dev::eth::TransactionSkeleton const& _t) +{ + TransactionNotification ret; + bool locked = true; + if (m_unlockedAccounts.count(_t.from)) + { + chrono::steady_clock::time_point start = m_unlockedAccounts[_t.from].first; + chrono::seconds duration(m_unlockedAccounts[_t.from].second); + auto end = start + duration; + if (start < end && chrono::steady_clock::now() < end) + locked = false; + } + ret.r = TransactionRepercussion::Locked; + if (locked && m_getAuthorisation) + { + if (m_getAuthorisation(_t, isProxyAccount(_t.from))) + locked = false; + else + ret.r = TransactionRepercussion::Refused; + } + if (locked) + return ret; + if (isRealAccount(_t.from)) + { + if (Secret s = m_keyManager.secret(_t.from, [&](){ return m_getPassword(_t.from); })) + { + + //tie 解开tuple + tie(ret.hash, ret.created) = m_client()->submitTransaction(_t, s); + //LOG(TRACE)<<"SimpleAccountHolder::authenticate"<submitTransaction(_t, m_accounts[_t.from]); + + if( ret.created == Address(1) ) //nonceCheck + ret.r = TransactionRepercussion::NonceError; + else if( ret.created == Address(2) ) //blocklimit 检查失败 + ret.r = TransactionRepercussion::BlockLimitError; + else if( ret.created == Address(3) ) //blocklimit 检查失败 + ret.r = TransactionRepercussion::TxPermissionError; + else if( ret.created == Address(4)) + ret.r= TransactionRepercussion::DeployPermissionError; + else + ret.r = TransactionRepercussion::Success; + } + else + ret.r = TransactionRepercussion::Locked; + } + else if (isProxyAccount(_t.from)) + { + ret.r = TransactionRepercussion::ProxySuccess; + queueTransaction(_t); + } + else + ret.r = TransactionRepercussion::UnknownAccount; + return ret; +} + + + diff --git a/libweb3jsonrpc/AccountHolder.h b/libweb3jsonrpc/AccountHolder.h new file mode 100644 index 0000000000..aa64bd6847 --- /dev/null +++ b/libweb3jsonrpc/AccountHolder.h @@ -0,0 +1,168 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file AccountHolder.h + * @authors: + * Christian R + * Lefteris Karapetsas + * @date 2015 + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace dev +{ +namespace eth +{ + +class KeyManager; +class Interface; + +enum class TransactionRepercussion +{ + Unknown, + UnknownAccount, + Locked, + Refused, + ProxySuccess, + Success, + NonceError, + BlockLimitError, + DeployPermissionError, + TxPermissionError, + CallPermissionError +}; + +struct TransactionNotification +{ + TransactionRepercussion r; + h256 hash; + Address created; +}; + +/** + * Manages real accounts (where we know the secret key) and proxy accounts (where transactions + * to be sent from these accounts are forwarded to a proxy on the other side). + */ +class AccountHolder +{ +public: + explicit AccountHolder(std::function const& _client): m_client(_client) {} + + virtual AddressHash realAccounts() const = 0; + // use m_web3's submitTransaction + // or use AccountHolder::queueTransaction(_t) to accept + virtual TransactionNotification authenticate(dev::eth::TransactionSkeleton const& _t) = 0; + + Addresses allAccounts() const; + bool isRealAccount(Address const& _account) const { return realAccounts().count(_account) > 0; } + bool isProxyAccount(Address const& _account) const { return m_proxyAccounts.count(_account) > 0; } + Address const& defaultTransactAccount() const; + + /// Automatically authenticate all transactions for the given account for the next @a _duration + /// seconds. Decrypt the key with @a _password if needed. @returns true on success. + /// Only works for direct accounts. + virtual bool unlockAccount( + Address const& /*_account*/, + std::string const& /*_password*/, + unsigned /*_duration*/ + ) + { + return false; + } + + int addProxyAccount(Address const& _account); + bool removeProxyAccount(unsigned _id); + void queueTransaction(eth::TransactionSkeleton const& _transaction); + + std::vector const& queuedTransactions(int _id) const; + void clearQueue(int _id); + +protected: + std::function m_client; + +private: + using TransactionQueue = std::vector; + + std::unordered_map m_proxyAccounts; + std::unordered_map> m_transactionQueues; +}; + +class SimpleAccountHolder: public AccountHolder +{ +public: + SimpleAccountHolder(std::function const& _client, std::function const& _getPassword, KeyManager& _keyman, std::function _getAuthorisation = std::function()): + AccountHolder(_client), + m_getPassword(_getPassword), + m_getAuthorisation(_getAuthorisation), + m_keyManager(_keyman) + {} + + AddressHash realAccounts() const override; + TransactionNotification authenticate(dev::eth::TransactionSkeleton const& _t) override; + + virtual bool unlockAccount(Address const& _account, std::string const& _password, unsigned _duration) override; + +private: + std::function m_getPassword; + std::function m_getAuthorisation; + KeyManager& m_keyManager; + std::map> m_unlockedAccounts; +}; + +class FixedAccountHolder: public AccountHolder +{ +public: + FixedAccountHolder(std::function const& _client, std::vector const& _accounts): + AccountHolder(_client) + { + setAccounts(_accounts); + } + + void setAccounts(std::vector const& _accounts) + { + for (auto const& i: _accounts) + m_accounts[i.address()] = i.secret(); + } + + dev::AddressHash realAccounts() const override + { + dev::AddressHash ret; + for (auto const& i: m_accounts) + ret.insert(i.first); + return ret; + } + + // use m_web3's submitTransaction + // or use AccountHolder::queueTransaction(_t) to accept + TransactionNotification authenticate(dev::eth::TransactionSkeleton const& _t) override; + +private: + std::unordered_map m_accounts; +}; + + +} +} diff --git a/libweb3jsonrpc/AdminEth.cpp b/libweb3jsonrpc/AdminEth.cpp new file mode 100644 index 0000000000..02d41bb9ef --- /dev/null +++ b/libweb3jsonrpc/AdminEth.cpp @@ -0,0 +1,298 @@ +#include +#include +#include +#include +#include +#include +//#include +#include "AdminEth.h" +#include "SessionManager.h" +#include "JsonHelper.h" +using namespace std; +using namespace dev; +using namespace dev::rpc; +using namespace dev::eth; + +AdminEth::AdminEth(eth::Client& _eth, eth::TrivialGasPricer& _gp, eth::KeyManager& _keyManager, SessionManager& _sm): + m_eth(_eth), + m_gp(_gp), + m_keyManager(_keyManager), + m_sm(_sm) +{} + +bool AdminEth::admin_eth_setMining(bool _on, string const& _session) +{ + RPC_ADMIN; + if (_on) + m_eth.startSealing(); + else + m_eth.stopSealing(); + return true; +} + +Json::Value AdminEth::admin_eth_blockQueueStatus(string const& _session) +{ + RPC_ADMIN; + Json::Value ret; + BlockQueueStatus bqs = m_eth.blockQueue().status(); + ret["importing"] = (int)bqs.importing; + ret["verified"] = (int)bqs.verified; + ret["verifying"] = (int)bqs.verifying; + ret["unverified"] = (int)bqs.unverified; + ret["future"] = (int)bqs.future; + ret["unknown"] = (int)bqs.unknown; + ret["bad"] = (int)bqs.bad; + return ret; +} + +bool AdminEth::admin_eth_setAskPrice(string const& _wei, string const& _session) +{ + RPC_ADMIN; + m_gp.setAsk(jsToU256(_wei)); + return true; +} + +bool AdminEth::admin_eth_setBidPrice(string const& _wei, string const& _session) +{ + RPC_ADMIN; + m_gp.setBid(jsToU256(_wei)); + return true; +} + +Json::Value AdminEth::admin_eth_findBlock(string const& _blockHash, string const& _session) +{ + RPC_ADMIN; + h256 h(_blockHash); + if (m_eth.blockChain().isKnown(h)) + return toJson(m_eth.blockChain().info(h)); + switch(m_eth.blockQueue().blockStatus(h)) + { + case QueueStatus::Ready: + return "ready"; + case QueueStatus::Importing: + return "importing"; + case QueueStatus::UnknownParent: + return "unknown parent"; + case QueueStatus::Bad: + return "bad"; + default: + return "unknown"; + } +} + +string AdminEth::admin_eth_blockQueueFirstUnknown(string const& _session) +{ + RPC_ADMIN; + return m_eth.blockQueue().firstUnknown().hex(); +} + +bool AdminEth::admin_eth_blockQueueRetryUnknown(string const& _session) +{ + RPC_ADMIN; + m_eth.retryUnknown(); + return true; +} + +Json::Value AdminEth::admin_eth_allAccounts(string const& _session) +{ + RPC_ADMIN; + Json::Value ret; + u256 total = 0; + u256 pendingtotal = 0; + Address beneficiary; + for (auto const& address: m_keyManager.accounts()) + { + auto pending = m_eth.balanceAt(address, PendingBlock); + auto latest = m_eth.balanceAt(address, LatestBlock); + Json::Value a; + if (address == beneficiary) + a["beneficiary"] = true; + a["address"] = toJS(address); + a["balance"] = toJS(latest); + a["nicebalance"] = formatBalance(latest); + a["pending"] = toJS(pending); + a["nicepending"] = formatBalance(pending); + ret["accounts"][m_keyManager.accountName(address)] = a; + total += latest; + pendingtotal += pending; + } + ret["total"] = toJS(total); + ret["nicetotal"] = formatBalance(total); + ret["pendingtotal"] = toJS(pendingtotal); + ret["nicependingtotal"] = formatBalance(pendingtotal); + return ret; +} + +Json::Value AdminEth::admin_eth_newAccount(Json::Value const& _info, string const& _session) +{ + RPC_ADMIN; + if (!_info.isMember("name")) + throw jsonrpc::JsonRpcException("No member found: name"); + string name = _info["name"].asString(); + auto s = ICAP::createDirect(); + h128 uuid; + if (_info.isMember("password")) + { + string password = _info["password"].asString(); + string hint = _info["passwordHint"].asString(); + uuid = m_keyManager.import(s, name, password, hint); + } + else + uuid = m_keyManager.import(s, name); + Json::Value ret; + ret["account"] = toJS(toAddress(s)); + ret["uuid"] = toUUID(uuid); + return ret; +} + +bool AdminEth::admin_eth_setMiningBenefactor(string const& _uuidOrAddress, string const& _session) +{ + RPC_ADMIN; + return miner_setEtherbase(_uuidOrAddress); +} + +Json::Value AdminEth::admin_eth_inspect(string const& _address, string const& _session) +{ + RPC_ADMIN; + if (!isHash
(_address)) + throw jsonrpc::JsonRpcException("Invalid address given."); + + Json::Value ret; + auto h = Address(fromHex(_address)); + ret["storage"] = toJson(m_eth.storageAt(h, PendingBlock)); + ret["balance"] = toJS(m_eth.balanceAt(h, PendingBlock)); + ret["nonce"] = toJS(m_eth.countAt(h, PendingBlock)); + ret["code"] = toJS(m_eth.codeAt(h, PendingBlock)); + return ret; +} + +h256 AdminEth::blockHash(string const& _blockNumberOrHash) const +{ + if (isHash(_blockNumberOrHash)) + return h256(_blockNumberOrHash.substr(_blockNumberOrHash.size() - 64, 64)); + try + { + return m_eth.blockChain().numberHash(stoul(_blockNumberOrHash)); + } + catch (...) + { + throw jsonrpc::JsonRpcException("Invalid argument"); + } +} + +Json::Value AdminEth::admin_eth_reprocess(string const& _blockNumberOrHash, string const& _session) +{ + RPC_ADMIN; + Json::Value ret; + PopulationStatistics ps; + m_eth.block(blockHash(_blockNumberOrHash), &ps); + ret["enact"] = ps.enact; + ret["verify"] = ps.verify; + ret["total"] = ps.verify + ps.enact; + return ret; +} + +Json::Value AdminEth::admin_eth_vmTrace(string const& _blockNumberOrHash, int _txIndex, string const& _session) +{ + RPC_ADMIN; + + Json::Value ret; + + if (_txIndex < 0) + throw jsonrpc::JsonRpcException("Negative index"); + Block block = m_eth.block(blockHash(_blockNumberOrHash)); + if ((unsigned)_txIndex < block.pending().size()) + { + Transaction t = block.pending()[_txIndex]; + State s(State::Null); + Executive e(s, block, _txIndex, m_eth.blockChain()); + try + { + StandardTrace st; + st.setShowMnemonics(); + e.initialize(t); + if (!e.execute()) + e.go(st.onOp()); + e.finalize(); + Json::Reader().parse(st.json(), ret); + } + catch(Exception const& _e) + { + LOG(WARNING) << diagnostic_information(_e); + } + } + + return ret; +} + +Json::Value AdminEth::admin_eth_getReceiptByHashAndIndex(string const& _blockNumberOrHash, int _txIndex, string const& _session) +{ + RPC_ADMIN; + if (_txIndex < 0) + throw jsonrpc::JsonRpcException("Negative index"); + auto h = blockHash(_blockNumberOrHash); + if (!m_eth.blockChain().isKnown(h)) + throw jsonrpc::JsonRpcException("Invalid/unknown block."); + auto rs = m_eth.blockChain().receipts(h); + if ((unsigned)_txIndex >= rs.receipts.size()) + throw jsonrpc::JsonRpcException("Index too large."); + return toJson(rs.receipts[_txIndex]); +} + +bool AdminEth::miner_start(int) +{ + m_eth.startSealing(); + return true; +} + +bool AdminEth::miner_stop() +{ + m_eth.stopSealing(); + return true; +} + +bool AdminEth::miner_setEtherbase(string const& _uuidOrAddress) +{ + Address a; + h128 uuid = fromUUID(_uuidOrAddress); + if (uuid) + a = m_keyManager.address(uuid); + else if (isHash
(_uuidOrAddress)) + a = Address(_uuidOrAddress); + else + throw jsonrpc::JsonRpcException("Invalid UUID or address"); + + if (m_setMiningBenefactor) + m_setMiningBenefactor(a); + else + m_eth.setAuthor(a); + return true; +} + +bool AdminEth::miner_setExtra(string const& _extraData) +{ + m_eth.setExtraData(asBytes(_extraData)); + return true; +} + +bool AdminEth::miner_setGasPrice(string const& _gasPrice) +{ + m_gp.setAsk(jsToU256(_gasPrice)); + return true; +} + +string AdminEth::miner_hashrate() +{ + return "1"; + /* + EthashClient const* client = nullptr; + try + { + client = asEthashClient(&m_eth); + } + catch (...) + { + throw jsonrpc::JsonRpcException("Hashrate not available - blockchain does not support mining."); + } + return toJS(client->hashrate());*/ +} diff --git a/libweb3jsonrpc/AdminEth.h b/libweb3jsonrpc/AdminEth.h new file mode 100644 index 0000000000..d66b738632 --- /dev/null +++ b/libweb3jsonrpc/AdminEth.h @@ -0,0 +1,62 @@ +#pragma once +#include "AdminEthFace.h" + +namespace dev +{ + +namespace eth +{ +class Client; +class TrivialGasPricer; +class KeyManager; +} + +namespace rpc +{ + +class SessionManager; + +class AdminEth: public AdminEthFace +{ +public: + AdminEth(eth::Client& _eth, eth::TrivialGasPricer& _gp, eth::KeyManager& _keyManager, SessionManager& _sm); + + virtual RPCModules implementedModules() const override + { + return RPCModules{RPCModule{"admin", "1.0"}, RPCModule{"miner", "1.0"}}; + } + + virtual bool admin_eth_setMining(bool _on, std::string const& _session) override; + virtual Json::Value admin_eth_blockQueueStatus(std::string const& _session) override; + virtual bool admin_eth_setAskPrice(std::string const& _wei, std::string const& _session) override; + virtual bool admin_eth_setBidPrice(std::string const& _wei, std::string const& _session) override; + virtual Json::Value admin_eth_findBlock(std::string const& _blockHash, std::string const& _session) override; + virtual std::string admin_eth_blockQueueFirstUnknown(std::string const& _session) override; + virtual bool admin_eth_blockQueueRetryUnknown(std::string const& _session) override; + virtual Json::Value admin_eth_allAccounts(std::string const& _session) override; + virtual Json::Value admin_eth_newAccount(const Json::Value& _info, std::string const& _session) override; + virtual bool admin_eth_setMiningBenefactor(std::string const& _uuidOrAddress, std::string const& _session) override; + virtual Json::Value admin_eth_inspect(std::string const& _address, std::string const& _session) override; + virtual Json::Value admin_eth_reprocess(std::string const& _blockNumberOrHash, std::string const& _session) override; + virtual Json::Value admin_eth_vmTrace(std::string const& _blockNumberOrHash, int _txIndex, std::string const& _session) override; + virtual Json::Value admin_eth_getReceiptByHashAndIndex(std::string const& _blockNumberOrHash, int _txIndex, std::string const& _session) override; + virtual bool miner_start(int _threads) override; + virtual bool miner_stop() override; + virtual bool miner_setEtherbase(std::string const& _uuidOrAddress) override; + virtual bool miner_setExtra(std::string const& _extraData) override; + virtual bool miner_setGasPrice(std::string const& _gasPrice) override; + virtual std::string miner_hashrate() override; + + virtual void setMiningBenefactorChanger(std::function const& _f) { m_setMiningBenefactor = _f; } +private: + eth::Client& m_eth; + eth::TrivialGasPricer& m_gp; + eth::KeyManager& m_keyManager; + SessionManager& m_sm; + std::function m_setMiningBenefactor; + + h256 blockHash(std::string const& _blockNumberOrHash) const; +}; + +} +} diff --git a/libweb3jsonrpc/AdminEthFace.h b/libweb3jsonrpc/AdminEthFace.h new file mode 100644 index 0000000000..dcda6e7ffe --- /dev/null +++ b/libweb3jsonrpc/AdminEthFace.h @@ -0,0 +1,145 @@ +/** + * This file is generated by jsonrpcstub, DO NOT CHANGE IT MANUALLY! + */ + +#ifndef JSONRPC_CPP_STUB_DEV_RPC_ADMINETHFACE_H_ +#define JSONRPC_CPP_STUB_DEV_RPC_ADMINETHFACE_H_ + +#include "ModularServer.h" + +namespace dev { + namespace rpc { + class AdminEthFace : public ServerInterface + { + public: + AdminEthFace() + { + this->bindAndAddMethod(jsonrpc::Procedure("admin_eth_blockQueueStatus", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING, NULL), &dev::rpc::AdminEthFace::admin_eth_blockQueueStatusI); + this->bindAndAddMethod(jsonrpc::Procedure("admin_eth_setAskPrice", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &dev::rpc::AdminEthFace::admin_eth_setAskPriceI); + this->bindAndAddMethod(jsonrpc::Procedure("admin_eth_setBidPrice", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &dev::rpc::AdminEthFace::admin_eth_setBidPriceI); + this->bindAndAddMethod(jsonrpc::Procedure("admin_eth_setMining", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_BOOLEAN,"param2",jsonrpc::JSON_STRING, NULL), &dev::rpc::AdminEthFace::admin_eth_setMiningI); + this->bindAndAddMethod(jsonrpc::Procedure("admin_eth_findBlock", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &dev::rpc::AdminEthFace::admin_eth_findBlockI); + this->bindAndAddMethod(jsonrpc::Procedure("admin_eth_blockQueueFirstUnknown", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &dev::rpc::AdminEthFace::admin_eth_blockQueueFirstUnknownI); + this->bindAndAddMethod(jsonrpc::Procedure("admin_eth_blockQueueRetryUnknown", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING, NULL), &dev::rpc::AdminEthFace::admin_eth_blockQueueRetryUnknownI); + this->bindAndAddMethod(jsonrpc::Procedure("admin_eth_allAccounts", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, "param1",jsonrpc::JSON_STRING, NULL), &dev::rpc::AdminEthFace::admin_eth_allAccountsI); + this->bindAndAddMethod(jsonrpc::Procedure("admin_eth_newAccount", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_OBJECT,"param2",jsonrpc::JSON_STRING, NULL), &dev::rpc::AdminEthFace::admin_eth_newAccountI); + this->bindAndAddMethod(jsonrpc::Procedure("admin_eth_setMiningBenefactor", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &dev::rpc::AdminEthFace::admin_eth_setMiningBenefactorI); + this->bindAndAddMethod(jsonrpc::Procedure("admin_eth_inspect", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &dev::rpc::AdminEthFace::admin_eth_inspectI); + this->bindAndAddMethod(jsonrpc::Procedure("admin_eth_reprocess", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &dev::rpc::AdminEthFace::admin_eth_reprocessI); + this->bindAndAddMethod(jsonrpc::Procedure("admin_eth_vmTrace", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_INTEGER,"param3",jsonrpc::JSON_STRING, NULL), &dev::rpc::AdminEthFace::admin_eth_vmTraceI); + this->bindAndAddMethod(jsonrpc::Procedure("admin_eth_getReceiptByHashAndIndex", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_INTEGER,"param3",jsonrpc::JSON_STRING, NULL), &dev::rpc::AdminEthFace::admin_eth_getReceiptByHashAndIndexI); + this->bindAndAddMethod(jsonrpc::Procedure("miner_start", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_INTEGER, NULL), &dev::rpc::AdminEthFace::miner_startI); + this->bindAndAddMethod(jsonrpc::Procedure("miner_stop", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, NULL), &dev::rpc::AdminEthFace::miner_stopI); + this->bindAndAddMethod(jsonrpc::Procedure("miner_setEtherbase", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING, NULL), &dev::rpc::AdminEthFace::miner_setEtherbaseI); + this->bindAndAddMethod(jsonrpc::Procedure("miner_setExtra", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING, NULL), &dev::rpc::AdminEthFace::miner_setExtraI); + this->bindAndAddMethod(jsonrpc::Procedure("miner_setGasPrice", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING, NULL), &dev::rpc::AdminEthFace::miner_setGasPriceI); + this->bindAndAddMethod(jsonrpc::Procedure("miner_hashrate", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, NULL), &dev::rpc::AdminEthFace::miner_hashrateI); + } + + inline virtual void admin_eth_blockQueueStatusI(const Json::Value &request, Json::Value &response) + { + response = this->admin_eth_blockQueueStatus(request[0u].asString()); + } + inline virtual void admin_eth_setAskPriceI(const Json::Value &request, Json::Value &response) + { + response = this->admin_eth_setAskPrice(request[0u].asString(), request[1u].asString()); + } + inline virtual void admin_eth_setBidPriceI(const Json::Value &request, Json::Value &response) + { + response = this->admin_eth_setBidPrice(request[0u].asString(), request[1u].asString()); + } + inline virtual void admin_eth_setMiningI(const Json::Value &request, Json::Value &response) + { + response = this->admin_eth_setMining(request[0u].asBool(), request[1u].asString()); + } + inline virtual void admin_eth_findBlockI(const Json::Value &request, Json::Value &response) + { + response = this->admin_eth_findBlock(request[0u].asString(), request[1u].asString()); + } + inline virtual void admin_eth_blockQueueFirstUnknownI(const Json::Value &request, Json::Value &response) + { + response = this->admin_eth_blockQueueFirstUnknown(request[0u].asString()); + } + inline virtual void admin_eth_blockQueueRetryUnknownI(const Json::Value &request, Json::Value &response) + { + response = this->admin_eth_blockQueueRetryUnknown(request[0u].asString()); + } + inline virtual void admin_eth_allAccountsI(const Json::Value &request, Json::Value &response) + { + response = this->admin_eth_allAccounts(request[0u].asString()); + } + inline virtual void admin_eth_newAccountI(const Json::Value &request, Json::Value &response) + { + response = this->admin_eth_newAccount(request[0u], request[1u].asString()); + } + inline virtual void admin_eth_setMiningBenefactorI(const Json::Value &request, Json::Value &response) + { + response = this->admin_eth_setMiningBenefactor(request[0u].asString(), request[1u].asString()); + } + inline virtual void admin_eth_inspectI(const Json::Value &request, Json::Value &response) + { + response = this->admin_eth_inspect(request[0u].asString(), request[1u].asString()); + } + inline virtual void admin_eth_reprocessI(const Json::Value &request, Json::Value &response) + { + response = this->admin_eth_reprocess(request[0u].asString(), request[1u].asString()); + } + inline virtual void admin_eth_vmTraceI(const Json::Value &request, Json::Value &response) + { + response = this->admin_eth_vmTrace(request[0u].asString(), request[1u].asInt(), request[2u].asString()); + } + inline virtual void admin_eth_getReceiptByHashAndIndexI(const Json::Value &request, Json::Value &response) + { + response = this->admin_eth_getReceiptByHashAndIndex(request[0u].asString(), request[1u].asInt(), request[2u].asString()); + } + inline virtual void miner_startI(const Json::Value &request, Json::Value &response) + { + response = this->miner_start(request[0u].asInt()); + } + inline virtual void miner_stopI(const Json::Value &request, Json::Value &response) + { + (void)request; + response = this->miner_stop(); + } + inline virtual void miner_setEtherbaseI(const Json::Value &request, Json::Value &response) + { + response = this->miner_setEtherbase(request[0u].asString()); + } + inline virtual void miner_setExtraI(const Json::Value &request, Json::Value &response) + { + response = this->miner_setExtra(request[0u].asString()); + } + inline virtual void miner_setGasPriceI(const Json::Value &request, Json::Value &response) + { + response = this->miner_setGasPrice(request[0u].asString()); + } + inline virtual void miner_hashrateI(const Json::Value &request, Json::Value &response) + { + (void)request; + response = this->miner_hashrate(); + } + virtual Json::Value admin_eth_blockQueueStatus(const std::string& param1) = 0; + virtual bool admin_eth_setAskPrice(const std::string& param1, const std::string& param2) = 0; + virtual bool admin_eth_setBidPrice(const std::string& param1, const std::string& param2) = 0; + virtual bool admin_eth_setMining(bool param1, const std::string& param2) = 0; + virtual Json::Value admin_eth_findBlock(const std::string& param1, const std::string& param2) = 0; + virtual std::string admin_eth_blockQueueFirstUnknown(const std::string& param1) = 0; + virtual bool admin_eth_blockQueueRetryUnknown(const std::string& param1) = 0; + virtual Json::Value admin_eth_allAccounts(const std::string& param1) = 0; + virtual Json::Value admin_eth_newAccount(const Json::Value& param1, const std::string& param2) = 0; + virtual bool admin_eth_setMiningBenefactor(const std::string& param1, const std::string& param2) = 0; + virtual Json::Value admin_eth_inspect(const std::string& param1, const std::string& param2) = 0; + virtual Json::Value admin_eth_reprocess(const std::string& param1, const std::string& param2) = 0; + virtual Json::Value admin_eth_vmTrace(const std::string& param1, int param2, const std::string& param3) = 0; + virtual Json::Value admin_eth_getReceiptByHashAndIndex(const std::string& param1, int param2, const std::string& param3) = 0; + virtual bool miner_start(int param1) = 0; + virtual bool miner_stop() = 0; + virtual bool miner_setEtherbase(const std::string& param1) = 0; + virtual bool miner_setExtra(const std::string& param1) = 0; + virtual bool miner_setGasPrice(const std::string& param1) = 0; + virtual std::string miner_hashrate() = 0; + }; + + } +} +#endif //JSONRPC_CPP_STUB_DEV_RPC_ADMINETHFACE_H_ diff --git a/libweb3jsonrpc/AdminNet.cpp b/libweb3jsonrpc/AdminNet.cpp new file mode 100644 index 0000000000..2e55316588 --- /dev/null +++ b/libweb3jsonrpc/AdminNet.cpp @@ -0,0 +1,175 @@ +#include +#include +#include +#include +#include +#include "AdminNet.h" +#include "SessionManager.h" +#include "JsonHelper.h" + +using namespace std; +using namespace dev; +using namespace dev::rpc; +using namespace dev::eth; + +AdminNet::AdminNet(NetworkFace& _network, SessionManager& _sm): m_network(_network), m_sm(_sm) {} + +bool AdminNet::admin_net_start(std::string const& _session) +{ + RPC_ADMIN; + m_network.startNetwork(); + return true; +} + +bool AdminNet::admin_net_stop(std::string const& _session) +{ + RPC_ADMIN; + m_network.stopNetwork(); + return true; +} + +bool AdminNet::admin_net_connect(std::string const& _node, std::string const& _session) +{ + RPC_ADMIN; + return admin_addPeer(_node); +} + +Json::Value AdminNet::admin_net_peers(std::string const& _session) +{ + RPC_ADMIN; + return admin_peers(); +} + +Json::Value AdminNet::admin_net_nodeInfo(std::string const& _session) +{ + RPC_ADMIN; + Json::Value ret; + p2p::NodeInfo i = m_network.nodeInfo(); + ret["name"] = i.version; + ret["port"] = i.port; + ret["address"] = i.address; + ret["listenAddr"] = i.address + ":" + toString(i.port); + ret["id"] = i.id.hex(); + ret["enode"] = i.enode(); + return ret; +} + +Json::Value AdminNet::admin_nodeInfo() +{ + Json::Value ret; + p2p::NodeInfo i = m_network.nodeInfo(); + ret["name"] = i.version; + ret["ports"] = Json::objectValue; + // Both ports are equal as of 2016-02-04, migt change later + ret["ports"]["discovery"] = i.port; + ret["ports"]["listener"] = i.port; + ret["ip"] = i.address; + ret["listenAddr"] = i.address + ":" + toString(i.port); + ret["id"] = i.id.hex(); + ret["enode"] = i.enode(); + ret["protocols"] = Json::objectValue; + ret["protocols"]["eth"] = Json::objectValue; //@todo fill with information + return ret; +} + +Json::Value AdminNet::admin_peers() +{ + Json::Value ret; + for (p2p::PeerSessionInfo const& peer: m_network.peers()) + ret.append(toJson(peer)); + return ret; +} + +bool AdminNet::admin_addPeer(string const& _node) +{ + m_network.addPeer(p2p::NodeSpec(_node), p2p::PeerType::Required); + return true; +} + +//增加新的节点信息 +bool AdminNet::admin_addNodePubKeyInfo(string const& _node) +{ + bool bRet = false; + std::cout << "AdminNet::admin_addNodePubKeyInfo |" << _node << std::endl; + NodeConnParams nodeParam(_node); + if (!nodeParam.Valid()) + { + std::cout << "AdminNet::admin_addNodePubKeyInfo reserialize error : " << _node << std::endl; + return bRet; + } + bRet = NodeConnManagerSingleton::GetInstance().addNewNodeConnInfo(nodeParam); + if (!bRet) + { + std::cout << "admin_addNodePubKeyInfo node existed." << std::endl; + } + + //发起广播 增加新的协议 + vector vParams; + vParams.push_back(nodeParam); + NodeConnManagerSingleton::GetInstance().sendNodeInfoSync(vParams); + + std::cout << "admin_addNodePubKeyInfo sendNodeInfoSync.node id is " << nodeParam._sNodeId << std::endl; + + //不进行连接,连接以合约中的为主 + //进行连接 需要序列化出他的enode信息 +// NodeConnManagerSingleton::GetInstance().connNode(nodeParam); + return true; +} + +//删除配置中的节点信息 +//_node则为nodeid即可 +bool AdminNet::admin_delNodePubKeyInfo(string const& _node) +{ + bool bExisted = false; + std::cout << "AdminNet::admin_addNodePubKeyInfo |" << _node << std::endl; + + + NodeConnManagerSingleton::GetInstance().delNodeConnInfo(_node, bExisted); + if (bExisted) + { + //发起广播 增加新的协议 + NodeConnManagerSingleton::GetInstance().sendDelNodeInfoSync(_node); + + //断掉连接以合约为主,这里主要做配置的同步落地 + ////需要断掉连接 + //NodeConnManagerSingleton::GetInstance().disconnNode(_node); + //std::cout << "delNodeconninfo node exiteds. node id is : " << _node << endl; + } + else + { + std::cout << "delNodeconninfo node not exiteds. node id is : " << _node << endl; + } + + + return true; +} + +//展示所有的节点信息 +Json::Value AdminNet::admin_NodePubKeyInfos() +{ + Json::Value ret; + std::map mNodeConnParams; + NodeConnManagerSingleton::GetInstance().getAllNodeConnInfoContract(mNodeConnParams); + + for (auto const & param : mNodeConnParams) + { + ret.append(toJson(param.second)); + } + + return ret; +} + +//展示所有的节点信息 +Json::Value AdminNet::admin_ConfNodePubKeyInfos() +{ + Json::Value ret; + std::map mNodeConnParams; + NodeConnManagerSingleton::GetInstance().getAllConfNodeConnInfo(mNodeConnParams); + + for (auto const & param : mNodeConnParams) + { + ret.append(toJson(param.second)); + } + + return ret; +} \ No newline at end of file diff --git a/libweb3jsonrpc/AdminNet.h b/libweb3jsonrpc/AdminNet.h new file mode 100644 index 0000000000..359bd0641f --- /dev/null +++ b/libweb3jsonrpc/AdminNet.h @@ -0,0 +1,41 @@ +#pragma once +#include "AdminNetFace.h" + +namespace dev +{ + +class NetworkFace; + +namespace rpc +{ + +class SessionManager; + +class AdminNet: public dev::rpc::AdminNetFace +{ +public: + AdminNet(NetworkFace& _network, SessionManager& _sm); + virtual RPCModules implementedModules() const override + { + return RPCModules{RPCModule{"admin", "1.0"}}; + } + virtual bool admin_net_start(std::string const& _session) override; + virtual bool admin_net_stop(std::string const& _session) override; + virtual bool admin_net_connect(std::string const& _node, std::string const& _session) override; + virtual Json::Value admin_net_peers(std::string const& _session) override; + virtual Json::Value admin_net_nodeInfo(std::string const& _session) override; + virtual Json::Value admin_nodeInfo() override; + virtual Json::Value admin_peers() override; + virtual bool admin_addPeer(std::string const& _node) override; + virtual bool admin_addNodePubKeyInfo(string const& _node) override; + virtual Json::Value admin_NodePubKeyInfos() override; + virtual Json::Value admin_ConfNodePubKeyInfos() override; + virtual bool admin_delNodePubKeyInfo(string const& _node) override; + +private: + NetworkFace& m_network; + SessionManager& m_sm; +}; + +} +} diff --git a/libweb3jsonrpc/AdminNetFace.h b/libweb3jsonrpc/AdminNetFace.h new file mode 100644 index 0000000000..c275a387b2 --- /dev/null +++ b/libweb3jsonrpc/AdminNetFace.h @@ -0,0 +1,104 @@ +/** + * This file is generated by jsonrpcstub, DO NOT CHANGE IT MANUALLY! + */ + +#ifndef JSONRPC_CPP_STUB_DEV_RPC_ADMINNETFACE_H_ +#define JSONRPC_CPP_STUB_DEV_RPC_ADMINNETFACE_H_ + +#include "ModularServer.h" + +namespace dev { + namespace rpc { + class AdminNetFace : public ServerInterface + { + public: + AdminNetFace() + { + this->bindAndAddMethod(jsonrpc::Procedure("admin_net_start", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING, NULL), &dev::rpc::AdminNetFace::admin_net_startI); + this->bindAndAddMethod(jsonrpc::Procedure("admin_net_stop", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING, NULL), &dev::rpc::AdminNetFace::admin_net_stopI); + this->bindAndAddMethod(jsonrpc::Procedure("admin_net_connect", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &dev::rpc::AdminNetFace::admin_net_connectI); + this->bindAndAddMethod(jsonrpc::Procedure("admin_net_peers", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, "param1",jsonrpc::JSON_STRING, NULL), &dev::rpc::AdminNetFace::admin_net_peersI); + this->bindAndAddMethod(jsonrpc::Procedure("admin_net_nodeInfo", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING, NULL), &dev::rpc::AdminNetFace::admin_net_nodeInfoI); + this->bindAndAddMethod(jsonrpc::Procedure("admin_nodeInfo", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, NULL), &dev::rpc::AdminNetFace::admin_nodeInfoI); + this->bindAndAddMethod(jsonrpc::Procedure("admin_peers", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, NULL), &dev::rpc::AdminNetFace::admin_peersI); + this->bindAndAddMethod(jsonrpc::Procedure("admin_addPeer", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING, NULL), &dev::rpc::AdminNetFace::admin_addPeerI); + this->bindAndAddMethod(jsonrpc::Procedure("admin_NodePubKeyInfos", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, NULL), &dev::rpc::AdminNetFace::admin_NodePubKeyInfosI); + this->bindAndAddMethod(jsonrpc::Procedure("admin_ConfNodePubKeyInfos", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, NULL), &dev::rpc::AdminNetFace::admin_ConfNodePubKeyInfosI); + this->bindAndAddMethod(jsonrpc::Procedure("admin_addNodePubKeyInfo", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1", jsonrpc::JSON_STRING, NULL), &dev::rpc::AdminNetFace::admin_addNodePubKeyInfoI); + this->bindAndAddMethod(jsonrpc::Procedure("admin_delNodePubKeyInfo", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1", jsonrpc::JSON_STRING, NULL), &dev::rpc::AdminNetFace::admin_delNodePubKeyInfoI); + + } + + inline virtual void admin_net_startI(const Json::Value &request, Json::Value &response) + { + response = this->admin_net_start(request[0u].asString()); + } + inline virtual void admin_net_stopI(const Json::Value &request, Json::Value &response) + { + response = this->admin_net_stop(request[0u].asString()); + } + inline virtual void admin_net_connectI(const Json::Value &request, Json::Value &response) + { + response = this->admin_net_connect(request[0u].asString(), request[1u].asString()); + } + inline virtual void admin_net_peersI(const Json::Value &request, Json::Value &response) + { + response = this->admin_net_peers(request[0u].asString()); + } + inline virtual void admin_net_nodeInfoI(const Json::Value &request, Json::Value &response) + { + response = this->admin_net_nodeInfo(request[0u].asString()); + } + inline virtual void admin_nodeInfoI(const Json::Value &request, Json::Value &response) + { + (void)request; + response = this->admin_nodeInfo(); + } + inline virtual void admin_peersI(const Json::Value &request, Json::Value &response) + { + (void)request; + response = this->admin_peers(); + } + inline virtual void admin_addPeerI(const Json::Value &request, Json::Value &response) + { + response = this->admin_addPeer(request[0u].asString()); + } + inline virtual void admin_addNodePubKeyInfoI(const Json::Value &request, Json::Value &response) + { + response = this->admin_addNodePubKeyInfo(request[0u].asString()); + } + inline virtual void admin_delNodePubKeyInfoI(const Json::Value &request, Json::Value &response) + { + response = this->admin_delNodePubKeyInfo(request[0u].asString()); + } + inline virtual void admin_NodePubKeyInfosI(const Json::Value &request, Json::Value &response) + { + (void)request; + response = this->admin_NodePubKeyInfos(); + } + inline virtual void admin_ConfNodePubKeyInfosI(const Json::Value &request, Json::Value &response) + { + (void)request; + response = this->admin_ConfNodePubKeyInfos(); + } + + + + + virtual bool admin_net_start(const std::string& param1) = 0; + virtual bool admin_net_stop(const std::string& param1) = 0; + virtual bool admin_net_connect(const std::string& param1, const std::string& param2) = 0; + virtual Json::Value admin_net_peers(const std::string& param1) = 0; + virtual Json::Value admin_net_nodeInfo(const std::string& param1) = 0; + virtual Json::Value admin_nodeInfo() = 0; + virtual Json::Value admin_peers() = 0; + virtual bool admin_addPeer(const std::string& param1) = 0; + virtual bool admin_addNodePubKeyInfo(const std::string& param1) = 0; + virtual bool admin_delNodePubKeyInfo(const std::string& param1) = 0; + virtual Json::Value admin_NodePubKeyInfos() = 0; + virtual Json::Value admin_ConfNodePubKeyInfos() = 0; + }; + + } +} +#endif //JSONRPC_CPP_STUB_DEV_RPC_ADMINNETFACE_H_ diff --git a/libweb3jsonrpc/AdminUtils.cpp b/libweb3jsonrpc/AdminUtils.cpp new file mode 100644 index 0000000000..e6217a465d --- /dev/null +++ b/libweb3jsonrpc/AdminUtils.cpp @@ -0,0 +1,38 @@ +#include +#include +#include +#include "SessionManager.h" +#include "AdminUtils.h" + +using namespace std; +using namespace dev; +using namespace dev::eth; +using namespace dev::rpc; + +AdminUtils::AdminUtils(SessionManager& _sm, SystemManager* _systemManager): + m_sm(_sm), + m_systemManager(_systemManager) +{} + +bool AdminUtils::admin_setVerbosity(int _v, std::string const& _session) +{ + RPC_ADMIN; + return admin_verbosity(_v); +} + +bool AdminUtils::admin_verbosity(int _v) +{ + g_logVerbosity = _v; + return true; +} + +bool AdminUtils::admin_exit(std::string const& _session) +{ + RPC_ADMIN; + if (m_systemManager) + { + m_systemManager->exit(); + return true; + } + return false; +} diff --git a/libweb3jsonrpc/AdminUtils.h b/libweb3jsonrpc/AdminUtils.h new file mode 100644 index 0000000000..dbcc319b49 --- /dev/null +++ b/libweb3jsonrpc/AdminUtils.h @@ -0,0 +1,30 @@ +#pragma once +#include +#include "AdminUtilsFace.h" + +namespace dev +{ +namespace rpc +{ + +class SessionManager; + +class AdminUtils: public dev::rpc::AdminUtilsFace +{ +public: + AdminUtils(SessionManager& _sm, SystemManager* _systemManager = nullptr); + virtual RPCModules implementedModules() const override + { + return RPCModules{RPCModule{"admin", "1.0"}}; + } + virtual bool admin_setVerbosity(int _v, std::string const& _session) override; + virtual bool admin_verbosity(int _v) override; + virtual bool admin_exit(std::string const& _session) override; + +private: + SessionManager& m_sm; + SystemManager* m_systemManager = nullptr; +}; + +} +} diff --git a/libweb3jsonrpc/AdminUtilsFace.h b/libweb3jsonrpc/AdminUtilsFace.h new file mode 100644 index 0000000000..85b32508e8 --- /dev/null +++ b/libweb3jsonrpc/AdminUtilsFace.h @@ -0,0 +1,41 @@ +/** + * This file is generated by jsonrpcstub, DO NOT CHANGE IT MANUALLY! + */ + +#ifndef JSONRPC_CPP_STUB_DEV_RPC_ADMINUTILSFACE_H_ +#define JSONRPC_CPP_STUB_DEV_RPC_ADMINUTILSFACE_H_ + +#include "ModularServer.h" + +namespace dev { + namespace rpc { + class AdminUtilsFace : public ServerInterface + { + public: + AdminUtilsFace() + { + this->bindAndAddMethod(jsonrpc::Procedure("admin_setVerbosity", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_INTEGER,"param2",jsonrpc::JSON_STRING, NULL), &dev::rpc::AdminUtilsFace::admin_setVerbosityI); + this->bindAndAddMethod(jsonrpc::Procedure("admin_verbosity", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_INTEGER, NULL), &dev::rpc::AdminUtilsFace::admin_verbosityI); + this->bindAndAddMethod(jsonrpc::Procedure("admin_exit", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING, NULL), &dev::rpc::AdminUtilsFace::admin_exitI); + } + + inline virtual void admin_setVerbosityI(const Json::Value &request, Json::Value &response) + { + response = this->admin_setVerbosity(request[0u].asInt(), request[1u].asString()); + } + inline virtual void admin_verbosityI(const Json::Value &request, Json::Value &response) + { + response = this->admin_verbosity(request[0u].asInt()); + } + inline virtual void admin_exitI(const Json::Value &request, Json::Value &response) + { + response = this->admin_exit(request[0u].asString()); + } + virtual bool admin_setVerbosity(int param1, const std::string& param2) = 0; + virtual bool admin_verbosity(int param1) = 0; + virtual bool admin_exit(const std::string& param1) = 0; + }; + + } +} +#endif //JSONRPC_CPP_STUB_DEV_RPC_ADMINUTILSFACE_H_ diff --git a/libweb3jsonrpc/Bzz.cpp b/libweb3jsonrpc/Bzz.cpp new file mode 100644 index 0000000000..edf807f794 --- /dev/null +++ b/libweb3jsonrpc/Bzz.cpp @@ -0,0 +1,48 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Bzz.cpp + * @authors: + * Gav Wood + * Marek Kotewicz + * @date 2015 + */ + +#include +#include +#include +#include +#include +#include // TODO: bytes ostream operator doesn't work without this import +#include "Bzz.h" + +using namespace std; +using namespace dev; +using namespace dev::rpc; + +Bzz::Bzz(dev::bzz::Interface& _bzz): m_bzz(_bzz){} + +std::string Bzz::bzz_put(std::string const& _data) +{ + bytes b = jsToBytes(_data); + m_bzz.put(b); + return toJS(sha3(b)); +} + +std::string Bzz::bzz_get(std::string const& _hash) +{ + return toJS(static_cast(m_bzz.get(jsToFixed<32>(_hash)))); +} \ No newline at end of file diff --git a/libweb3jsonrpc/Bzz.h b/libweb3jsonrpc/Bzz.h new file mode 100644 index 0000000000..7defd35d69 --- /dev/null +++ b/libweb3jsonrpc/Bzz.h @@ -0,0 +1,54 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Bzz.h + * @authors: + * Gav Wood + * Marek Kotewicz + * @date 2015 + */ + +#pragma once +#include "BzzFace.h" + +namespace dev +{ + +namespace bzz +{ +class Interface; +} + +namespace rpc +{ + +class Bzz: public BzzFace +{ +public: + Bzz(dev::bzz::Interface& _bzz); + virtual RPCModules implementedModules() const override + { + return RPCModules{RPCModule{"bzz", "1.0"}}; + } + virtual std::string bzz_put(std::string const& _data) override; + virtual std::string bzz_get(std::string const& _hash) override; + +private: + dev::bzz::Interface& m_bzz; +}; + +} +} diff --git a/libweb3jsonrpc/BzzFace.h b/libweb3jsonrpc/BzzFace.h new file mode 100644 index 0000000000..a0b59ea45c --- /dev/null +++ b/libweb3jsonrpc/BzzFace.h @@ -0,0 +1,35 @@ +/** + * This file is generated by jsonrpcstub, DO NOT CHANGE IT MANUALLY! + */ + +#ifndef JSONRPC_CPP_STUB_DEV_RPC_BZZFACE_H_ +#define JSONRPC_CPP_STUB_DEV_RPC_BZZFACE_H_ + +#include "ModularServer.h" + +namespace dev { + namespace rpc { + class BzzFace : public ServerInterface + { + public: + BzzFace() + { + this->bindAndAddMethod(jsonrpc::Procedure("bzz_put", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &dev::rpc::BzzFace::bzz_putI); + this->bindAndAddMethod(jsonrpc::Procedure("bzz_get", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &dev::rpc::BzzFace::bzz_getI); + } + + inline virtual void bzz_putI(const Json::Value &request, Json::Value &response) + { + response = this->bzz_put(request[0u].asString()); + } + inline virtual void bzz_getI(const Json::Value &request, Json::Value &response) + { + response = this->bzz_get(request[0u].asString()); + } + virtual std::string bzz_put(const std::string& param1) = 0; + virtual std::string bzz_get(const std::string& param1) = 0; + }; + + } +} +#endif //JSONRPC_CPP_STUB_DEV_RPC_BZZFACE_H_ diff --git a/libweb3jsonrpc/CMakeLists.txt b/libweb3jsonrpc/CMakeLists.txt new file mode 100644 index 0000000000..a071bad9fc --- /dev/null +++ b/libweb3jsonrpc/CMakeLists.txt @@ -0,0 +1,81 @@ +aux_source_directory(. SRC_LIST) +aux_source_directory(./dfs SRC_LIST) + +file(GLOB HEADERS "*.h") +include_directories(./dfs) + +add_library(web3jsonrpc ${SRC_LIST} ${HEADERS}) + +jsonrpcstub_create(web3jsonrpc eth.json + dev::rpc::EthFace ${CMAKE_CURRENT_SOURCE_DIR} EthFace + EthClient ${CMAKE_CURRENT_BINARY_DIR} EthClient +) + +jsonrpcstub_create(web3jsonrpc db.json + dev::rpc::DBFace ${CMAKE_CURRENT_SOURCE_DIR} DBFace + DBClient ${CMAKE_CURRENT_BINARY_DIR} DBClient +) + +jsonrpcstub_create(web3jsonrpc debug.json + dev::rpc::DebugFace ${CMAKE_CURRENT_SOURCE_DIR} DebugFace + DebugClient ${CMAKE_CURRENT_BINARY_DIR} DebugClient +) + +jsonrpcstub_create(web3jsonrpc whisper.json + dev::rpc::WhisperFace ${CMAKE_CURRENT_SOURCE_DIR} WhisperFace + WhisperClient ${CMAKE_CURRENT_BINARY_DIR} WhisperClient +) + +jsonrpcstub_create(web3jsonrpc net.json + dev::rpc::NetFace ${CMAKE_CURRENT_SOURCE_DIR} NetFace + NetClient ${CMAKE_CURRENT_BINARY_DIR} NetClient +) + +jsonrpcstub_create(web3jsonrpc web3.json + dev::rpc::Web3Face ${CMAKE_CURRENT_SOURCE_DIR} Web3Face + Web3Client ${CMAKE_CURRENT_BINARY_DIR} Web3Client +) + +jsonrpcstub_create(web3jsonrpc admin_net.json + dev::rpc::AdminNetFace ${CMAKE_CURRENT_SOURCE_DIR} AdminNetFace + AdminNetClient ${CMAKE_CURRENT_BINARY_DIR} AdminNetClient +) + +jsonrpcstub_create(web3jsonrpc admin_eth.json + dev::rpc::AdminEthFace ${CMAKE_CURRENT_SOURCE_DIR} AdminEthFace + AdminEthClient ${CMAKE_CURRENT_BINARY_DIR} AdminEthClient +) + +jsonrpcstub_create(web3jsonrpc admin_utils.json + dev::rpc::AdminUtilsFace ${CMAKE_CURRENT_SOURCE_DIR} AdminUtilsFace + AdminUtilsClient ${CMAKE_CURRENT_BINARY_DIR} AdminUtilsClient +) + +jsonrpcstub_create(web3jsonrpc personal.json + dev::rpc::PersonalFace ${CMAKE_CURRENT_SOURCE_DIR} PersonalFace + PersonalClient ${CMAKE_CURRENT_BINARY_DIR} PersonalClient +) + +jsonrpcstub_create(web3jsonrpc test.json + dev::rpc::TestFace ${CMAKE_CURRENT_SOURCE_DIR} TestFace + TestClient ${CMAKE_CURRENT_BINARY_DIR} TestClient +) + +find_package(Web3) + +include_directories(../libodbc/include + ../libodbc/include/db2_linux + ../libodbc/include/ibase + ../libodbc/include/infomix + ../libodbc/include/mysql + ../libodbc/include/odbc_linux + ../libodbc/include/pgsql + ../libodbc/include/sqlbase + ../libodbc/include/sqllite + ../libodbc/include/ss_linux + ../libodbc/include/sybase) + +target_include_directories(web3jsonrpc PRIVATE ..) +target_link_libraries(web3jsonrpc ${Web3_WEBTHREE_LIBRARIES} + ${Web3_WHISPER_LIBRARIES} + JsonRpcCpp::Server) diff --git a/libweb3jsonrpc/DBFace.h b/libweb3jsonrpc/DBFace.h new file mode 100644 index 0000000000..09f2abae6f --- /dev/null +++ b/libweb3jsonrpc/DBFace.h @@ -0,0 +1,35 @@ +/** + * This file is generated by jsonrpcstub, DO NOT CHANGE IT MANUALLY! + */ + +#ifndef JSONRPC_CPP_STUB_DEV_RPC_DBFACE_H_ +#define JSONRPC_CPP_STUB_DEV_RPC_DBFACE_H_ + +#include "ModularServer.h" + +namespace dev { + namespace rpc { + class DBFace : public ServerInterface + { + public: + DBFace() + { + this->bindAndAddMethod(jsonrpc::Procedure("db_put", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING,"param3",jsonrpc::JSON_STRING, NULL), &dev::rpc::DBFace::db_putI); + this->bindAndAddMethod(jsonrpc::Procedure("db_get", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &dev::rpc::DBFace::db_getI); + } + + inline virtual void db_putI(const Json::Value &request, Json::Value &response) + { + response = this->db_put(request[0u].asString(), request[1u].asString(), request[2u].asString()); + } + inline virtual void db_getI(const Json::Value &request, Json::Value &response) + { + response = this->db_get(request[0u].asString(), request[1u].asString()); + } + virtual bool db_put(const std::string& param1, const std::string& param2, const std::string& param3) = 0; + virtual std::string db_get(const std::string& param1, const std::string& param2) = 0; + }; + + } +} +#endif //JSONRPC_CPP_STUB_DEV_RPC_DBFACE_H_ diff --git a/libweb3jsonrpc/Debug.cpp b/libweb3jsonrpc/Debug.cpp new file mode 100644 index 0000000000..ba62259ae2 --- /dev/null +++ b/libweb3jsonrpc/Debug.cpp @@ -0,0 +1,208 @@ +#include +#include +#include +#include +#include +#include +#include "Debug.h" +#include "JsonHelper.h" +using namespace std; +using namespace dev; +using namespace dev::rpc; +using namespace dev::eth; + +Debug::Debug(eth::Client const& _eth): + m_eth(_eth) +{} + +StandardTrace::DebugOptions debugOptions(Json::Value const& _json) +{ + StandardTrace::DebugOptions op; + if (!_json.isObject() || _json.empty()) + return op; + if (!_json["disableStorage"].empty()) + op.disableStorage = _json["disableStorage"].asBool(); + if (!_json["disableMemory"].empty()) + op.disableMemory = _json["disableMemory"].asBool(); + if (!_json["disableStack"].empty()) + op.disableStack =_json["disableStack"].asBool(); + if (!_json["fullStorage"].empty()) + op.fullStorage = _json["fullStorage"].asBool(); + return op; +} + +h256 Debug::blockHash(string const& _blockNumberOrHash) const +{ + if (isHash(_blockNumberOrHash)) + return h256(_blockNumberOrHash.substr(_blockNumberOrHash.size() - 64, 64)); + try + { + return m_eth.blockChain().numberHash(stoul(_blockNumberOrHash)); + } + catch (...) + { + throw jsonrpc::JsonRpcException("Invalid argument"); + } +} + +Json::Value Debug::traceTransaction(Executive& _e, Transaction const& _t, Json::Value const& _json) +{ + Json::Value trace; + StandardTrace st; + st.setShowMnemonics(); + st.setOptions(debugOptions(_json)); + _e.initialize(_t); + if (!_e.execute()) + _e.go(st.onOp()); + _e.finalize(); + Json::Reader().parse(st.json(), trace); + return trace; +} + +Json::Value Debug::traceBlock(Block const& _block, Json::Value const& _json) +{ + Json::Value traces(Json::arrayValue); + for (unsigned k = 0; k < _block.pending().size(); k++) + { + Transaction t = _block.pending()[k]; + State s(State::Null); + eth::ExecutionResult er; + Executive e(s, _block, k, m_eth.blockChain()); + e.setResultRecipient(er); + traces.append(traceTransaction(e, t, _json)); + } + return traces; +} + +Json::Value Debug::debug_traceTransaction(string const& _txHash, Json::Value const& _json) +{ + Json::Value ret; + try + { + LocalisedTransaction t = m_eth.localisedTransaction(h256(_txHash)); + Block block = m_eth.block(t.blockHash()); + State s(State::Null); + eth::ExecutionResult er; + Executive e(s, block, t.transactionIndex(), m_eth.blockChain()); + e.setResultRecipient(er); + Json::Value trace = traceTransaction(e, t, _json); + ret["gas"] = toHex(t.gas(), HexPrefix::Add); + ret["return"] = toHex(er.output, 2, HexPrefix::Add); + ret["structLogs"] = trace; + } + catch(Exception const& _e) + { + LOG(WARNING) << diagnostic_information(_e); + } + return ret; +} + +Json::Value Debug::debug_traceBlock(string const& _blockRLP, Json::Value const& _json) +{ + bytes bytes = fromHex(_blockRLP); + BlockHeader blockHeader(bytes); + return debug_traceBlockByHash(blockHeader.hash().hex(), _json); +} + +Json::Value Debug::debug_traceBlockByHash(string const& _blockHash, Json::Value const& _json) +{ + Json::Value ret; + Block block = m_eth.block(h256(_blockHash)); + ret["structLogs"] = traceBlock(block, _json); + return ret; +} + +Json::Value Debug::debug_traceBlockByNumber(int _blockNumber, Json::Value const& _json) +{ + Json::Value ret; + Block block = m_eth.block(blockHash(std::to_string(_blockNumber))); + ret["structLogs"] = traceBlock(block, _json); + return ret; +} + +Json::Value Debug::debug_storageRangeAt(string const& _blockHashOrNumber, int _txIndex, string const& _address, string const& _begin, int _maxResults) +{ + Json::Value ret(Json::objectValue); + ret["complete"] = true; + ret["storage"] = Json::Value(Json::arrayValue); + + if (_txIndex < 0) + throw jsonrpc::JsonRpcException("Negative index"); + if (_maxResults <= 0) + throw jsonrpc::JsonRpcException("Nonpositive maxResults"); + + try + { + Block block = m_eth.block(blockHash(_blockHashOrNumber)); + + unsigned const i = ((unsigned)_txIndex < block.pending().size()) ? (unsigned)_txIndex : block.pending().size(); + State state = block.fromPending(i); + + map> const storage(state.storage(Address(_address))); + + // begin is inclusive + auto itBegin = storage.lower_bound(h256fromHex(_begin)); + + for (auto it = itBegin; it != storage.end(); ++it) + { + if (ret["storage"].size() == static_cast(_maxResults)) + { + ret["complete"] = false; + break; + } + + Json::Value keyValue(Json::objectValue); + keyValue["hashedKey"] = toCompactHex(it->first, HexPrefix::Add, 1); + keyValue["key"] = toCompactHex(it->second.first, HexPrefix::Add, 1); + keyValue["value"] = toCompactHex(it->second.second, HexPrefix::Add, 1); + + ret["storage"].append(keyValue); + } + } + catch (Exception const& _e) + { + LOG(WARNING) << diagnostic_information(_e); + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_RPC_INVALID_PARAMS); + } + + return ret; +} + +std::string Debug::debug_preimage(std::string const& _hashedKey) +{ + h256 const hashedKey(h256fromHex(_hashedKey)); + bytes const key = m_eth.stateDB().lookupAux(hashedKey); + + return key.empty() ? std::string() : toCompactHex(u256(h256(key)), HexPrefix::Add, 1); +} + +Json::Value Debug::debug_traceCall(Json::Value const& _call, std::string const& _blockNumber, Json::Value const& _options) +{ + Json::Value ret; + try + { + Block temp = m_eth.block(jsToBlockNumber(_blockNumber)); + TransactionSkeleton ts = toTransactionSkeleton(_call); + if (!ts.from) { + ts.from = Address(); + } + u256 nonce = temp.transactionsFrom(ts.from); + u256 gas = ts.gas == Invalid256 ? m_eth.gasLimitRemaining() : ts.gas; + u256 gasPrice = ts.gasPrice == Invalid256 ? m_eth.gasBidPrice() : ts.gasPrice; + temp.mutableState().addBalance(ts.from, gas * gasPrice + ts.value); + Transaction transaction(ts.value, gasPrice, gas, ts.to, ts.data, nonce); + transaction.forceSender(ts.from); + eth::ExecutionResult er; + Executive e(temp); + e.setResultRecipient(er); + Json::Value trace = traceTransaction(e, transaction, _options); + ret["gas"] = toHex(transaction.gas(), HexPrefix::Add); + ret["return"] = toHex(er.output, 2, HexPrefix::Add); + ret["structLogs"] = trace; + } + catch(Exception const& _e) + { + LOG(WARNING) << diagnostic_information(_e); + } + return ret; +} diff --git a/libweb3jsonrpc/Debug.h b/libweb3jsonrpc/Debug.h new file mode 100644 index 0000000000..13c271b634 --- /dev/null +++ b/libweb3jsonrpc/Debug.h @@ -0,0 +1,46 @@ +#pragma once +#include +#include "DebugFace.h" + +namespace dev +{ + +namespace eth +{ +class Client; +} + +namespace rpc +{ + +class SessionManager; + +class Debug: public DebugFace +{ +public: + explicit Debug(eth::Client const& _eth); + + virtual RPCModules implementedModules() const override + { + return RPCModules{RPCModule{"debug", "1.0"}}; + } + + + virtual Json::Value debug_traceTransaction(std::string const& _txHash, Json::Value const& _json) override; + virtual Json::Value debug_traceCall(Json::Value const& _call, std::string const& _blockNumber, Json::Value const& _options) override; + virtual Json::Value debug_traceBlockByNumber(int _blockNumber, Json::Value const& _json) override; + virtual Json::Value debug_traceBlockByHash(std::string const& _blockHash, Json::Value const& _json) override; + virtual Json::Value debug_storageRangeAt(std::string const& _blockHashOrNumber, int _txIndex, std::string const& _address, std::string const& _begin, int _maxResults) override; + virtual std::string debug_preimage(std::string const& _hashedKey) override; + virtual Json::Value debug_traceBlock(std::string const& _blockRlp, Json::Value const& _json); + +private: + + eth::Client const& m_eth; + h256 blockHash(std::string const& _blockHashOrNumber) const; + Json::Value traceTransaction(dev::eth::Executive& _e, dev::eth::Transaction const& _t, Json::Value const& _json); + Json::Value traceBlock(dev::eth::Block const& _block, Json::Value const& _json); +}; + +} +} diff --git a/libweb3jsonrpc/DebugFace.h b/libweb3jsonrpc/DebugFace.h new file mode 100644 index 0000000000..e88120f367 --- /dev/null +++ b/libweb3jsonrpc/DebugFace.h @@ -0,0 +1,59 @@ +/** + * This file is generated by jsonrpcstub, DO NOT CHANGE IT MANUALLY! + */ + +#ifndef JSONRPC_CPP_STUB_DEV_RPC_DEBUGFACE_H_ +#define JSONRPC_CPP_STUB_DEV_RPC_DEBUGFACE_H_ + +#include "ModularServer.h" + +namespace dev { + namespace rpc { + class DebugFace : public ServerInterface + { + public: + DebugFace() + { + this->bindAndAddMethod(jsonrpc::Procedure("debug_traceTransaction", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_OBJECT, NULL), &dev::rpc::DebugFace::debug_traceTransactionI); + this->bindAndAddMethod(jsonrpc::Procedure("debug_storageRangeAt", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_INTEGER,"param3",jsonrpc::JSON_STRING,"param4",jsonrpc::JSON_STRING,"param5",jsonrpc::JSON_INTEGER, NULL), &dev::rpc::DebugFace::debug_storageRangeAtI); + this->bindAndAddMethod(jsonrpc::Procedure("debug_preimage", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING, NULL), &dev::rpc::DebugFace::debug_preimageI); + this->bindAndAddMethod(jsonrpc::Procedure("debug_traceBlockByNumber", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_INTEGER,"param2",jsonrpc::JSON_OBJECT, NULL), &dev::rpc::DebugFace::debug_traceBlockByNumberI); + this->bindAndAddMethod(jsonrpc::Procedure("debug_traceBlockByHash", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_OBJECT, NULL), &dev::rpc::DebugFace::debug_traceBlockByHashI); + this->bindAndAddMethod(jsonrpc::Procedure("debug_traceCall", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_OBJECT,"param2",jsonrpc::JSON_STRING,"param3",jsonrpc::JSON_OBJECT, NULL), &dev::rpc::DebugFace::debug_traceCallI); + } + + inline virtual void debug_traceTransactionI(const Json::Value &request, Json::Value &response) + { + response = this->debug_traceTransaction(request[0u].asString(), request[1u]); + } + inline virtual void debug_storageRangeAtI(const Json::Value &request, Json::Value &response) + { + response = this->debug_storageRangeAt(request[0u].asString(), request[1u].asInt(), request[2u].asString(), request[3u].asString(), request[4u].asInt()); + } + inline virtual void debug_preimageI(const Json::Value &request, Json::Value &response) + { + response = this->debug_preimage(request[0u].asString()); + } + inline virtual void debug_traceBlockByNumberI(const Json::Value &request, Json::Value &response) + { + response = this->debug_traceBlockByNumber(request[0u].asInt(), request[1u]); + } + inline virtual void debug_traceBlockByHashI(const Json::Value &request, Json::Value &response) + { + response = this->debug_traceBlockByHash(request[0u].asString(), request[1u]); + } + inline virtual void debug_traceCallI(const Json::Value &request, Json::Value &response) + { + response = this->debug_traceCall(request[0u], request[1u].asString(), request[2u]); + } + virtual Json::Value debug_traceTransaction(const std::string& param1, const Json::Value& param2) = 0; + virtual Json::Value debug_storageRangeAt(const std::string& param1, int param2, const std::string& param3, const std::string& param4, int param5) = 0; + virtual std::string debug_preimage(const std::string& param1) = 0; + virtual Json::Value debug_traceBlockByNumber(int param1, const Json::Value& param2) = 0; + virtual Json::Value debug_traceBlockByHash(const std::string& param1, const Json::Value& param2) = 0; + virtual Json::Value debug_traceCall(const Json::Value& param1, const std::string& param2, const Json::Value& param3) = 0; + }; + + } +} +#endif //JSONRPC_CPP_STUB_DEV_RPC_DEBUGFACE_H_ diff --git a/libweb3jsonrpc/Eth.cpp b/libweb3jsonrpc/Eth.cpp new file mode 100644 index 0000000000..30889c5670 --- /dev/null +++ b/libweb3jsonrpc/Eth.cpp @@ -0,0 +1,821 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Eth.cpp + * @authors: + * Gav Wood + * Marek Kotewicz + * @date 2014 + */ + +#include +#include +#include +#include +#include +//#include +#include +#include +#include +#include "Eth.h" +#include "AccountHolder.h" +#include "JsonHelper.h" + +using namespace std; +using namespace jsonrpc; +using namespace dev; +using namespace eth; +using namespace shh; +using namespace dev::rpc; + +#if ETH_DEBUG +const unsigned dev::SensibleHttpThreads = 8; +#else +const unsigned dev::SensibleHttpThreads = 8; +#endif +const unsigned dev::SensibleHttpPort = 6789; + +Eth::Eth(eth::Interface& _eth, eth::AccountHolder& _ethAccounts): + m_eth(_eth), + m_ethAccounts(_ethAccounts) +{ +} + +string Eth::eth_protocolVersion() +{ + return toJS(eth::c_protocolVersion); +} + +string Eth::eth_coinbase() +{ + return toJS(client()->author()); +} + +string Eth::eth_hashrate() +{ + return "1"; + /* + try + { + return toJS(asEthashClient(client())->hashrate()); + } + catch (InvalidSealEngine&) + { + BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); + }*/ +} + +bool Eth::eth_mining() +{ + return false; + /* + try + { + return asEthashClient(client())->isMining(); + } + catch (InvalidSealEngine&) + { + BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); + }*/ +} + +string Eth::eth_gasPrice() +{ + return toJS(client()->gasBidPrice()); +} + +Json::Value Eth::eth_accounts() +{ + return toJson(m_ethAccounts.allAccounts()); +} + +string Eth::eth_blockNumber() +{ + return toJS(client()->number()); +} + + +string Eth::eth_getBalance(string const& _address, string const& _blockNumber) +{ + try + { + return toJS(client()->balanceAt(jsToAddress(_address), jsToBlockNumber(_blockNumber))); + } + catch (...) + { + BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); + } +} + +string Eth::eth_getStorageAt(string const& _address, string const& _position, string const& _blockNumber) +{ + try + { + return toJS(toCompactBigEndian(client()->stateAt(jsToAddress(_address), jsToU256(_position), jsToBlockNumber(_blockNumber)), 32)); + } + catch (...) + { + BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); + } +} + +string Eth::eth_getStorageRoot(string const& _address, string const& _blockNumber) +{ + try + { + return toString(client()->stateRootAt(jsToAddress(_address), jsToBlockNumber(_blockNumber))); + } + catch (...) + { + BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); + } +} + +string Eth::eth_pendingTransactions() +{ + //Return list of transaction that being sent by local accounts + Transactions ours; + for (Transaction const& pending : client()->pending()) + { + for (Address const& account : m_ethAccounts.allAccounts()) + { + if (pending.sender() == account) + { + ours.push_back(pending); + break; + } + } + } + + return toJS(ours); +} + +string Eth::eth_getTransactionCount(string const& _address, string const& _blockNumber) +{ + try + { + return toJS(client()->countAt(jsToAddress(_address), jsToBlockNumber(_blockNumber))); + } + catch (...) + { + BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); + } +} + +Json::Value Eth::eth_getBlockTransactionCountByHash(string const& _blockHash) +{ + try + { + h256 blockHash = jsToFixed<32>(_blockHash); + if (!client()->isKnown(blockHash)) + return Json::Value(Json::nullValue); + + return toJS(client()->transactionCount(blockHash)); + } + catch (...) + { + BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); + } +} + +Json::Value Eth::eth_getBlockTransactionCountByNumber(string const& _blockNumber) +{ + try + { + BlockNumber blockNumber = jsToBlockNumber(_blockNumber); + if (!client()->isKnown(blockNumber)) + return Json::Value(Json::nullValue); + + return toJS(client()->transactionCount(jsToBlockNumber(_blockNumber))); + } + catch (...) + { + BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); + } +} + +Json::Value Eth::eth_getUncleCountByBlockHash(string const& _blockHash) +{ + try + { + h256 blockHash = jsToFixed<32>(_blockHash); + if (!client()->isKnown(blockHash)) + return Json::Value(Json::nullValue); + + return toJS(client()->uncleCount(blockHash)); + } + catch (...) + { + BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); + } +} + +Json::Value Eth::eth_getUncleCountByBlockNumber(string const& _blockNumber) +{ + try + { + BlockNumber blockNumber = jsToBlockNumber(_blockNumber); + if (!client()->isKnown(blockNumber)) + return Json::Value(Json::nullValue); + + return toJS(client()->uncleCount(blockNumber)); + } + catch (...) + { + BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); + } +} + +string Eth::eth_getCode(string const& _address, string const& _blockNumber) +{ + try + { + return toJS(client()->codeAt(jsToAddress(_address), jsToBlockNumber(_blockNumber))); + } + catch (...) + { + BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); + } +} + +void Eth::setTransactionDefaults(TransactionSkeleton& _t) +{ + if (!_t.from) + _t.from = m_ethAccounts.defaultTransactAccount(); +} + +string Eth::eth_sendTransaction(Json::Value const& _json) +{ + try + { + //std::cout << "eth_sendTransaction " << _json << std::endl; + + TransactionSkeleton t = toTransactionSkeleton(_json); + setTransactionDefaults(t); + +#ifdef ETH_DEBUG + if(t.randomid == Invalid256) + t.randomid = u256(h256::random()); +#endif + + if ( t.blockLimit == Invalid256 ) //默认帮忙设置个 + t.blockLimit = client()->number() + 100; + + + TransactionNotification n = m_ethAccounts.authenticate(t); + LOG(TRACE) << "Eth::eth_sendTransaction " << n.hash << "," << (unsigned)n.r; + ctxstat<<"eth_sendTransaction Hash="<<(n.hash)<<",Randid="<injectTransaction(jsToBytes(_rlp, OnFailed::Throw));//里面到import的时候会CheckTransaction::Everything 要求校验 + + if ( ImportResult::Success == ir) + { + Transaction tx(jsToBytes(_rlp, OnFailed::Throw), CheckTransaction::None); + ctxstat<<"eth_sendRawTransaction Hash="<<(tx.sha3())<<",Randid="<estimateGas(t.from, t.value, t.to, t.data, t.gas, t.gasPrice, PendingBlock).first); + } + catch (...) + { + BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); + } +} + +bool Eth::eth_flush() +{ + client()->flushTransactions(); + return true; +} + +Json::Value Eth::eth_getBlockByHash(string const& _blockHash, bool _includeTransactions) +{ + try + { + h256 h = jsToFixed<32>(_blockHash); + if (!client()->isKnown(h)) + return Json::Value(Json::nullValue); + + if (_includeTransactions) + return toJson(client()->blockInfo(h), client()->blockDetails(h), client()->uncleHashes(h), client()->transactions(h), client()->sealEngine()); + else + return toJson(client()->blockInfo(h), client()->blockDetails(h), client()->uncleHashes(h), client()->transactionHashes(h), client()->sealEngine()); + } + catch (...) + { + BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); + } +} + +Json::Value Eth::eth_getBlockByNumber(string const& _blockNumber, bool _includeTransactions) +{ + try + { + BlockNumber h = jsToBlockNumber(_blockNumber); + if (!client()->isKnown(h)) + return Json::Value(Json::nullValue); + + if (_includeTransactions) + return toJson(client()->blockInfo(h), client()->blockDetails(h), client()->uncleHashes(h), client()->transactions(h), client()->sealEngine()); + else + return toJson(client()->blockInfo(h), client()->blockDetails(h), client()->uncleHashes(h), client()->transactionHashes(h), client()->sealEngine()); + } + catch (...) + { + BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); + } +} + +Json::Value Eth::eth_getTransactionByHash(string const& _transactionHash) +{ + try + { + h256 h = jsToFixed<32>(_transactionHash); + if (!client()->isKnownTransaction(h)) + return Json::Value(Json::nullValue); + + return toJson(client()->localisedTransaction(h)); + } + catch (...) + { + BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); + } +} + +Json::Value Eth::eth_getTransactionByBlockHashAndIndex(string const& _blockHash, string const& _transactionIndex) +{ + try + { + h256 bh = jsToFixed<32>(_blockHash); + unsigned ti = jsToInt(_transactionIndex); + if (!client()->isKnownTransaction(bh, ti)) + return Json::Value(Json::nullValue); + + return toJson(client()->localisedTransaction(bh, ti)); + } + catch (...) + { + BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); + } +} + +Json::Value Eth::eth_getTransactionByBlockNumberAndIndex(string const& _blockNumber, string const& _transactionIndex) +{ + try + { + BlockNumber bn = jsToBlockNumber(_blockNumber); + h256 bh = client()->hashFromNumber(bn); + unsigned ti = jsToInt(_transactionIndex); + if (!client()->isKnownTransaction(bh, ti)) + return Json::Value(Json::nullValue); + + return toJson(client()->localisedTransaction(bh, ti)); + } + catch (...) + { + BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); + } +} + +Json::Value Eth::eth_getTransactionReceipt(string const& _transactionHash) +{ + try + { + h256 h = jsToFixed<32>(_transactionHash); + if (!client()->isKnownTransaction(h)) + return Json::Value(Json::nullValue); + + return toJson(client()->localisedTransactionReceipt(h)); + } + catch (...) + { + BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); + } +} + +Json::Value Eth::eth_getUncleByBlockHashAndIndex(string const& _blockHash, string const& _uncleIndex) +{ + try + { + return toJson(client()->uncle(jsToFixed<32>(_blockHash), jsToInt(_uncleIndex)), client()->sealEngine()); + } + catch (...) + { + BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); + } +} + +Json::Value Eth::eth_getUncleByBlockNumberAndIndex(string const& _blockNumber, string const& _uncleIndex) +{ + try + { + return toJson(client()->uncle(jsToBlockNumber(_blockNumber), jsToInt(_uncleIndex)), client()->sealEngine()); + } + catch (...) + { + BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); + } +} + +string Eth::eth_newFilter(Json::Value const& _json) +{ + try + { + return toJS(client()->installWatch(toLogFilter(_json, *client()))); + } + catch (...) + { + BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); + } +} + +string Eth::eth_newFilterEx(Json::Value const& _json) +{ + try + { + return toJS(client()->installWatch(toLogFilter(_json))); + } + catch (...) + { + BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); + } +} + +string Eth::eth_newBlockFilter() +{ + h256 filter = dev::eth::ChainChangedFilter; + return toJS(client()->installWatch(filter)); +} + +string Eth::eth_newPendingTransactionFilter() +{ + h256 filter = dev::eth::PendingChangedFilter; + return toJS(client()->installWatch(filter)); +} + +bool Eth::eth_uninstallFilter(string const& _filterId) +{ + try + { + return client()->uninstallWatch(jsToInt(_filterId)); + } + catch (...) + { + BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); + } +} + +Json::Value Eth::eth_getFilterChanges(string const& _filterId) +{ + try + { + int id = jsToInt(_filterId); + auto entries = client()->checkWatch(id); +// if (entries.size()) +// cnote << "FIRING WATCH" << id << entries.size(); + return toJson(entries); + } + catch (...) + { + BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); + } +} + +Json::Value Eth::eth_getFilterChangesEx(string const& _filterId) +{ + try + { + int id = jsToInt(_filterId); + auto entries = client()->checkWatch(id); +// if (entries.size()) +// cnote << "FIRING WATCH" << id << entries.size(); + return toJsonByBlock(entries); + } + catch (...) + { + BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); + } +} + +Json::Value Eth::eth_getFilterLogs(string const& _filterId) +{ + try + { + return toJson(client()->logs(jsToInt(_filterId))); + } + catch (...) + { + BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); + } +} + +Json::Value Eth::eth_getFilterLogsEx(string const& _filterId) +{ + try + { + return toJsonByBlock(client()->logs(jsToInt(_filterId))); + } + catch (...) + { + BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); + } +} + +Json::Value Eth::eth_getLogs(Json::Value const& _json) +{ + try + { + return toJson(client()->logs(toLogFilter(_json, *client()))); + } + catch (...) + { + BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); + } +} + +Json::Value Eth::eth_getLogsEx(Json::Value const& _json) +{ + try + { + return toJsonByBlock(client()->logs(toLogFilter(_json))); + } + catch (...) + { + BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); + } +} + +Json::Value Eth::eth_getWork() +{ + Json::Value ret(Json::arrayValue); + return ret; + /* + try + { + Json::Value ret(Json::arrayValue); + auto r = asEthashClient(client())->getEthashWork(); + ret.append(toJS(get<0>(r))); + ret.append(toJS(get<1>(r))); + ret.append(toJS(get<2>(r))); + return ret; + } + catch (...) + { + BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); + }*/ +} + +Json::Value Eth::eth_syncing() +{ + dev::eth::SyncStatus sync = client()->syncStatus(); + if (sync.state == SyncState::Idle || !sync.majorSyncing) + return Json::Value(false); + + Json::Value info(Json::objectValue); + info["startingBlock"] = sync.startBlockNumber; + info["highestBlock"] = sync.highestBlockNumber; + info["currentBlock"] = sync.currentBlockNumber; + return info; +} + +bool Eth::eth_submitWork(string const& , string const&, string const& ) +{ + return false; + /* + try + { + return asEthashClient(client())->submitEthashWork(jsToFixed<32>(_mixHash), jsToFixed(_nonce)); + } + catch (...) + { + BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); + }*/ +} + +bool Eth::eth_submitHashrate(string const& , string const& ) +{ + return false; + /* + try + { + asEthashClient(client())->submitExternalHashrate(jsToInt<32>(_hashes), jsToFixed<32>(_id)); + return true; + } + catch (...) + { + BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); + }*/ +} + +string Eth::eth_register(string const& _address) +{ + try + { + return toJS(m_ethAccounts.addProxyAccount(jsToAddress(_address))); + } + catch (...) + { + BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); + } +} + +bool Eth::eth_unregister(string const& _accountId) +{ + try + { + return m_ethAccounts.removeProxyAccount(jsToInt(_accountId)); + } + catch (...) + { + BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); + } +} + +Json::Value Eth::eth_fetchQueuedTransactions(string const& _accountId) +{ + try + { + auto id = jsToInt(_accountId); + Json::Value ret(Json::arrayValue); + // TODO: throw an error on no account with given id + for (TransactionSkeleton const& t : m_ethAccounts.queuedTransactions(id)) + ret.append(toJson(t)); + m_ethAccounts.clearQueue(id); + return ret; + } + catch (...) + { + BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); + } +} diff --git a/libweb3jsonrpc/Eth.h b/libweb3jsonrpc/Eth.h new file mode 100644 index 0000000000..bbf48bfc5a --- /dev/null +++ b/libweb3jsonrpc/Eth.h @@ -0,0 +1,139 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Eth.h + * @authors: + * Gav Wood + * Marek Kotewicz + * @date 2014 + */ + +#pragma once + +#include +#include +#include +#include +#include +#include "SessionManager.h" +#include "EthFace.h" + + +namespace dev +{ +class NetworkFace; +class KeyPair; +namespace eth +{ +class AccountHolder; +struct TransactionSkeleton; +class Interface; +} +namespace shh +{ +class Interface; +} + +extern const unsigned SensibleHttpThreads; +extern const unsigned SensibleHttpPort; + +} + +namespace dev +{ + +namespace rpc +{ + +/** + * @brief JSON-RPC api implementation + */ +class Eth: public dev::rpc::EthFace +{ +public: + Eth(eth::Interface& _eth, eth::AccountHolder& _ethAccounts); + + virtual RPCModules implementedModules() const override + { + return RPCModules{RPCModule{"eth", "1.0"}}; + } + + eth::AccountHolder const& ethAccounts() const { return m_ethAccounts; } + + virtual std::string eth_protocolVersion() override; + virtual std::string eth_hashrate() override; + virtual std::string eth_coinbase() override; + virtual bool eth_mining() override; + virtual std::string eth_gasPrice() override; + virtual Json::Value eth_accounts() override; + virtual std::string eth_blockNumber()override; + virtual std::string eth_getBalance(std::string const& _address, std::string const& _blockNumber) override; + virtual std::string eth_getStorageAt(std::string const& _address, std::string const& _position, std::string const& _blockNumber) override; + virtual std::string eth_getStorageRoot(std::string const& _address, std::string const& _blockNumber) override; + virtual std::string eth_getTransactionCount(std::string const& _address, std::string const& _blockNumber) override; + virtual std::string eth_pendingTransactions() override; + virtual Json::Value eth_getBlockTransactionCountByHash(std::string const& _blockHash) override; + virtual Json::Value eth_getBlockTransactionCountByNumber(std::string const& _blockNumber) override; + virtual Json::Value eth_getUncleCountByBlockHash(std::string const& _blockHash) override; + virtual Json::Value eth_getUncleCountByBlockNumber(std::string const& _blockNumber) override; + virtual std::string eth_getCode(std::string const& _address, std::string const& _blockNumber) override; + virtual std::string eth_sendTransaction(Json::Value const& _json) override; + virtual std::string eth_call(Json::Value const& _json, std::string const& _blockNumber) override; + virtual std::string eth_estimateGas(Json::Value const& _json) override; + virtual bool eth_flush() override; + virtual Json::Value eth_getBlockByHash(std::string const& _blockHash, bool _includeTransactions) override; + virtual Json::Value eth_getBlockByNumber(std::string const& _blockNumber, bool _includeTransactions) override; + virtual Json::Value eth_getTransactionByHash(std::string const& _transactionHash) override; + virtual Json::Value eth_getTransactionByBlockHashAndIndex(std::string const& _blockHash, std::string const& _transactionIndex) override; + virtual Json::Value eth_getTransactionByBlockNumberAndIndex(std::string const& _blockNumber, std::string const& _transactionIndex) override; + virtual Json::Value eth_getTransactionReceipt(std::string const& _transactionHash) override; + virtual Json::Value eth_getUncleByBlockHashAndIndex(std::string const& _blockHash, std::string const& _uncleIndex) override; + virtual Json::Value eth_getUncleByBlockNumberAndIndex(std::string const& _blockNumber, std::string const& _uncleIndex) override; + virtual std::string eth_newFilter(Json::Value const& _json) override; + virtual std::string eth_newFilterEx(Json::Value const& _json) override; + virtual std::string eth_newBlockFilter() override; + virtual std::string eth_newPendingTransactionFilter() override; + virtual bool eth_uninstallFilter(std::string const& _filterId) override; + virtual Json::Value eth_getFilterChanges(std::string const& _filterId) override; + virtual Json::Value eth_getFilterChangesEx(std::string const& _filterId) override; + virtual Json::Value eth_getFilterLogs(std::string const& _filterId) override; + virtual Json::Value eth_getFilterLogsEx(std::string const& _filterId) override; + virtual Json::Value eth_getLogs(Json::Value const& _json) override; + virtual Json::Value eth_getLogsEx(Json::Value const& _json) override; + virtual Json::Value eth_getWork() override; + virtual bool eth_submitWork(std::string const& _nonce, std::string const&, std::string const& _mixHash) override; + virtual bool eth_submitHashrate(std::string const& _hashes, std::string const& _id) override; + virtual std::string eth_register(std::string const& _address) override; + virtual bool eth_unregister(std::string const& _accountId) override; + virtual Json::Value eth_fetchQueuedTransactions(std::string const& _accountId) override; + virtual std::string eth_signTransaction(Json::Value const& _transaction) override; + virtual Json::Value eth_inspectTransaction(std::string const& _rlp) override; + virtual std::string eth_sendRawTransaction(std::string const& _rlp) override; + virtual bool eth_notePassword(std::string const&) override { return false; } + virtual Json::Value eth_syncing() override; + + void setTransactionDefaults(eth::TransactionSkeleton& _t); +protected: + + eth::Interface* client() { return &m_eth; } + + eth::Interface& m_eth; + eth::AccountHolder& m_ethAccounts; + +}; + +} +} //namespace dev diff --git a/libweb3jsonrpc/EthFace.h b/libweb3jsonrpc/EthFace.h new file mode 100644 index 0000000000..2d0a44b414 --- /dev/null +++ b/libweb3jsonrpc/EthFace.h @@ -0,0 +1,342 @@ +/** + * This file is generated by jsonrpcstub, DO NOT CHANGE IT MANUALLY! + */ + +#ifndef JSONRPC_CPP_STUB_DEV_RPC_ETHFACE_H_ +#define JSONRPC_CPP_STUB_DEV_RPC_ETHFACE_H_ + +#include "ModularServer.h" + +namespace dev { + namespace rpc { + class EthFace : public ServerInterface + { + public: + EthFace() + { + this->bindAndAddMethod(jsonrpc::Procedure("eth_protocolVersion", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, NULL), &dev::rpc::EthFace::eth_protocolVersionI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_hashrate", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, NULL), &dev::rpc::EthFace::eth_hashrateI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_coinbase", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, NULL), &dev::rpc::EthFace::eth_coinbaseI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_mining", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, NULL), &dev::rpc::EthFace::eth_miningI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_gasPrice", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, NULL), &dev::rpc::EthFace::eth_gasPriceI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_accounts", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, NULL), &dev::rpc::EthFace::eth_accountsI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_blockNumber", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, NULL), &dev::rpc::EthFace::eth_blockNumberI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_getBalance", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &dev::rpc::EthFace::eth_getBalanceI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_getStorageAt", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING,"param3",jsonrpc::JSON_STRING, NULL), &dev::rpc::EthFace::eth_getStorageAtI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_getStorageRoot", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &dev::rpc::EthFace::eth_getStorageRootI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_getTransactionCount", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &dev::rpc::EthFace::eth_getTransactionCountI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_pendingTransactions", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, NULL), &dev::rpc::EthFace::eth_pendingTransactionsI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_getBlockTransactionCountByHash", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING, NULL), &dev::rpc::EthFace::eth_getBlockTransactionCountByHashI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_getBlockTransactionCountByNumber", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING, NULL), &dev::rpc::EthFace::eth_getBlockTransactionCountByNumberI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_getUncleCountByBlockHash", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING, NULL), &dev::rpc::EthFace::eth_getUncleCountByBlockHashI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_getUncleCountByBlockNumber", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING, NULL), &dev::rpc::EthFace::eth_getUncleCountByBlockNumberI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_getCode", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &dev::rpc::EthFace::eth_getCodeI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_sendTransaction", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_OBJECT, NULL), &dev::rpc::EthFace::eth_sendTransactionI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_call", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_OBJECT,"param2",jsonrpc::JSON_STRING, NULL), &dev::rpc::EthFace::eth_callI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_flush", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, NULL), &dev::rpc::EthFace::eth_flushI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_getBlockByHash", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_BOOLEAN, NULL), &dev::rpc::EthFace::eth_getBlockByHashI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_getBlockByNumber", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_BOOLEAN, NULL), &dev::rpc::EthFace::eth_getBlockByNumberI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_getTransactionByHash", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING, NULL), &dev::rpc::EthFace::eth_getTransactionByHashI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_getTransactionByBlockHashAndIndex", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &dev::rpc::EthFace::eth_getTransactionByBlockHashAndIndexI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_getTransactionByBlockNumberAndIndex", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &dev::rpc::EthFace::eth_getTransactionByBlockNumberAndIndexI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_getTransactionReceipt", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING, NULL), &dev::rpc::EthFace::eth_getTransactionReceiptI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_getUncleByBlockHashAndIndex", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &dev::rpc::EthFace::eth_getUncleByBlockHashAndIndexI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_getUncleByBlockNumberAndIndex", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &dev::rpc::EthFace::eth_getUncleByBlockNumberAndIndexI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_newFilter", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_OBJECT, NULL), &dev::rpc::EthFace::eth_newFilterI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_newFilterEx", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_OBJECT, NULL), &dev::rpc::EthFace::eth_newFilterExI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_newBlockFilter", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, NULL), &dev::rpc::EthFace::eth_newBlockFilterI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_newPendingTransactionFilter", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, NULL), &dev::rpc::EthFace::eth_newPendingTransactionFilterI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_uninstallFilter", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING, NULL), &dev::rpc::EthFace::eth_uninstallFilterI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_getFilterChanges", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, "param1",jsonrpc::JSON_STRING, NULL), &dev::rpc::EthFace::eth_getFilterChangesI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_getFilterChangesEx", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, "param1",jsonrpc::JSON_STRING, NULL), &dev::rpc::EthFace::eth_getFilterChangesExI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_getFilterLogs", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, "param1",jsonrpc::JSON_STRING, NULL), &dev::rpc::EthFace::eth_getFilterLogsI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_getFilterLogsEx", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, "param1",jsonrpc::JSON_STRING, NULL), &dev::rpc::EthFace::eth_getFilterLogsExI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_getLogs", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, "param1",jsonrpc::JSON_OBJECT, NULL), &dev::rpc::EthFace::eth_getLogsI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_getLogsEx", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, "param1",jsonrpc::JSON_OBJECT, NULL), &dev::rpc::EthFace::eth_getLogsExI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_getWork", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, NULL), &dev::rpc::EthFace::eth_getWorkI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_submitWork", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING,"param3",jsonrpc::JSON_STRING, NULL), &dev::rpc::EthFace::eth_submitWorkI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_submitHashrate", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &dev::rpc::EthFace::eth_submitHashrateI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_register", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &dev::rpc::EthFace::eth_registerI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_unregister", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING, NULL), &dev::rpc::EthFace::eth_unregisterI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_fetchQueuedTransactions", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, "param1",jsonrpc::JSON_STRING, NULL), &dev::rpc::EthFace::eth_fetchQueuedTransactionsI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_signTransaction", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_OBJECT, NULL), &dev::rpc::EthFace::eth_signTransactionI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_inspectTransaction", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING, NULL), &dev::rpc::EthFace::eth_inspectTransactionI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_sendRawTransaction", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &dev::rpc::EthFace::eth_sendRawTransactionI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_notePassword", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING, NULL), &dev::rpc::EthFace::eth_notePasswordI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_syncing", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, NULL), &dev::rpc::EthFace::eth_syncingI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_estimateGas", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_OBJECT, NULL), &dev::rpc::EthFace::eth_estimateGasI); + } + + inline virtual void eth_protocolVersionI(const Json::Value &request, Json::Value &response) + { + (void)request; + response = this->eth_protocolVersion(); + } + inline virtual void eth_hashrateI(const Json::Value &request, Json::Value &response) + { + (void)request; + response = this->eth_hashrate(); + } + inline virtual void eth_coinbaseI(const Json::Value &request, Json::Value &response) + { + (void)request; + response = this->eth_coinbase(); + } + inline virtual void eth_miningI(const Json::Value &request, Json::Value &response) + { + (void)request; + response = this->eth_mining(); + } + inline virtual void eth_gasPriceI(const Json::Value &request, Json::Value &response) + { + (void)request; + response = this->eth_gasPrice(); + } + inline virtual void eth_accountsI(const Json::Value &request, Json::Value &response) + { + (void)request; + response = this->eth_accounts(); + } + inline virtual void eth_blockNumberI(const Json::Value &request, Json::Value &response) + { + (void)request; + response = this->eth_blockNumber(); + } + inline virtual void eth_getBalanceI(const Json::Value &request, Json::Value &response) + { + response = this->eth_getBalance(request[0u].asString(), request[1u].asString()); + } + inline virtual void eth_getStorageAtI(const Json::Value &request, Json::Value &response) + { + response = this->eth_getStorageAt(request[0u].asString(), request[1u].asString(), request[2u].asString()); + } + inline virtual void eth_getStorageRootI(const Json::Value &request, Json::Value &response) + { + response = this->eth_getStorageRoot(request[0u].asString(), request[1u].asString()); + } + inline virtual void eth_getTransactionCountI(const Json::Value &request, Json::Value &response) + { + response = this->eth_getTransactionCount(request[0u].asString(), request[1u].asString()); + } + inline virtual void eth_pendingTransactionsI(const Json::Value &request, Json::Value &response) + { + (void)request; + response = this->eth_pendingTransactions(); + } + inline virtual void eth_getBlockTransactionCountByHashI(const Json::Value &request, Json::Value &response) + { + response = this->eth_getBlockTransactionCountByHash(request[0u].asString()); + } + inline virtual void eth_getBlockTransactionCountByNumberI(const Json::Value &request, Json::Value &response) + { + response = this->eth_getBlockTransactionCountByNumber(request[0u].asString()); + } + inline virtual void eth_getUncleCountByBlockHashI(const Json::Value &request, Json::Value &response) + { + response = this->eth_getUncleCountByBlockHash(request[0u].asString()); + } + inline virtual void eth_getUncleCountByBlockNumberI(const Json::Value &request, Json::Value &response) + { + response = this->eth_getUncleCountByBlockNumber(request[0u].asString()); + } + inline virtual void eth_getCodeI(const Json::Value &request, Json::Value &response) + { + response = this->eth_getCode(request[0u].asString(), request[1u].asString()); + } + inline virtual void eth_sendTransactionI(const Json::Value &request, Json::Value &response) + { + response = this->eth_sendTransaction(request[0u]); + } + inline virtual void eth_callI(const Json::Value &request, Json::Value &response) + { + response = this->eth_call(request[0u], request[1u].asString()); + } + inline virtual void eth_flushI(const Json::Value &request, Json::Value &response) + { + (void)request; + response = this->eth_flush(); + } + inline virtual void eth_getBlockByHashI(const Json::Value &request, Json::Value &response) + { + response = this->eth_getBlockByHash(request[0u].asString(), request[1u].asBool()); + } + inline virtual void eth_getBlockByNumberI(const Json::Value &request, Json::Value &response) + { + response = this->eth_getBlockByNumber(request[0u].asString(), request[1u].asBool()); + } + inline virtual void eth_getTransactionByHashI(const Json::Value &request, Json::Value &response) + { + response = this->eth_getTransactionByHash(request[0u].asString()); + } + inline virtual void eth_getTransactionByBlockHashAndIndexI(const Json::Value &request, Json::Value &response) + { + response = this->eth_getTransactionByBlockHashAndIndex(request[0u].asString(), request[1u].asString()); + } + inline virtual void eth_getTransactionByBlockNumberAndIndexI(const Json::Value &request, Json::Value &response) + { + response = this->eth_getTransactionByBlockNumberAndIndex(request[0u].asString(), request[1u].asString()); + } + inline virtual void eth_getTransactionReceiptI(const Json::Value &request, Json::Value &response) + { + response = this->eth_getTransactionReceipt(request[0u].asString()); + } + inline virtual void eth_getUncleByBlockHashAndIndexI(const Json::Value &request, Json::Value &response) + { + response = this->eth_getUncleByBlockHashAndIndex(request[0u].asString(), request[1u].asString()); + } + inline virtual void eth_getUncleByBlockNumberAndIndexI(const Json::Value &request, Json::Value &response) + { + response = this->eth_getUncleByBlockNumberAndIndex(request[0u].asString(), request[1u].asString()); + } + inline virtual void eth_newFilterI(const Json::Value &request, Json::Value &response) + { + response = this->eth_newFilter(request[0u]); + } + inline virtual void eth_newFilterExI(const Json::Value &request, Json::Value &response) + { + response = this->eth_newFilterEx(request[0u]); + } + inline virtual void eth_newBlockFilterI(const Json::Value &request, Json::Value &response) + { + (void)request; + response = this->eth_newBlockFilter(); + } + inline virtual void eth_newPendingTransactionFilterI(const Json::Value &request, Json::Value &response) + { + (void)request; + response = this->eth_newPendingTransactionFilter(); + } + inline virtual void eth_uninstallFilterI(const Json::Value &request, Json::Value &response) + { + response = this->eth_uninstallFilter(request[0u].asString()); + } + inline virtual void eth_getFilterChangesI(const Json::Value &request, Json::Value &response) + { + response = this->eth_getFilterChanges(request[0u].asString()); + } + inline virtual void eth_getFilterChangesExI(const Json::Value &request, Json::Value &response) + { + response = this->eth_getFilterChangesEx(request[0u].asString()); + } + inline virtual void eth_getFilterLogsI(const Json::Value &request, Json::Value &response) + { + response = this->eth_getFilterLogs(request[0u].asString()); + } + inline virtual void eth_getFilterLogsExI(const Json::Value &request, Json::Value &response) + { + response = this->eth_getFilterLogsEx(request[0u].asString()); + } + inline virtual void eth_getLogsI(const Json::Value &request, Json::Value &response) + { + response = this->eth_getLogs(request[0u]); + } + inline virtual void eth_getLogsExI(const Json::Value &request, Json::Value &response) + { + response = this->eth_getLogsEx(request[0u]); + } + inline virtual void eth_getWorkI(const Json::Value &request, Json::Value &response) + { + (void)request; + response = this->eth_getWork(); + } + inline virtual void eth_submitWorkI(const Json::Value &request, Json::Value &response) + { + response = this->eth_submitWork(request[0u].asString(), request[1u].asString(), request[2u].asString()); + } + inline virtual void eth_submitHashrateI(const Json::Value &request, Json::Value &response) + { + response = this->eth_submitHashrate(request[0u].asString(), request[1u].asString()); + } + inline virtual void eth_registerI(const Json::Value &request, Json::Value &response) + { + response = this->eth_register(request[0u].asString()); + } + inline virtual void eth_unregisterI(const Json::Value &request, Json::Value &response) + { + response = this->eth_unregister(request[0u].asString()); + } + inline virtual void eth_fetchQueuedTransactionsI(const Json::Value &request, Json::Value &response) + { + response = this->eth_fetchQueuedTransactions(request[0u].asString()); + } + inline virtual void eth_signTransactionI(const Json::Value &request, Json::Value &response) + { + response = this->eth_signTransaction(request[0u]); + } + inline virtual void eth_inspectTransactionI(const Json::Value &request, Json::Value &response) + { + response = this->eth_inspectTransaction(request[0u].asString()); + } + inline virtual void eth_sendRawTransactionI(const Json::Value &request, Json::Value &response) + { + response = this->eth_sendRawTransaction(request[0u].asString()); + } + inline virtual void eth_notePasswordI(const Json::Value &request, Json::Value &response) + { + response = this->eth_notePassword(request[0u].asString()); + } + inline virtual void eth_syncingI(const Json::Value &request, Json::Value &response) + { + (void)request; + response = this->eth_syncing(); + } + inline virtual void eth_estimateGasI(const Json::Value &request, Json::Value &response) + { + response = this->eth_estimateGas(request[0u]); + } + virtual std::string eth_protocolVersion() = 0; + virtual std::string eth_hashrate() = 0; + virtual std::string eth_coinbase() = 0; + virtual bool eth_mining() = 0; + virtual std::string eth_gasPrice() = 0; + virtual Json::Value eth_accounts() = 0; + virtual std::string eth_blockNumber() = 0; + virtual std::string eth_getBalance(const std::string& param1, const std::string& param2) = 0; + virtual std::string eth_getStorageAt(const std::string& param1, const std::string& param2, const std::string& param3) = 0; + virtual std::string eth_getStorageRoot(const std::string& param1, const std::string& param2) = 0; + virtual std::string eth_getTransactionCount(const std::string& param1, const std::string& param2) = 0; + virtual std::string eth_pendingTransactions() = 0; + virtual Json::Value eth_getBlockTransactionCountByHash(const std::string& param1) = 0; + virtual Json::Value eth_getBlockTransactionCountByNumber(const std::string& param1) = 0; + virtual Json::Value eth_getUncleCountByBlockHash(const std::string& param1) = 0; + virtual Json::Value eth_getUncleCountByBlockNumber(const std::string& param1) = 0; + virtual std::string eth_getCode(const std::string& param1, const std::string& param2) = 0; + virtual std::string eth_sendTransaction(const Json::Value& param1) = 0; + virtual std::string eth_call(const Json::Value& param1, const std::string& param2) = 0; + virtual bool eth_flush() = 0; + virtual Json::Value eth_getBlockByHash(const std::string& param1, bool param2) = 0; + virtual Json::Value eth_getBlockByNumber(const std::string& param1, bool param2) = 0; + virtual Json::Value eth_getTransactionByHash(const std::string& param1) = 0; + virtual Json::Value eth_getTransactionByBlockHashAndIndex(const std::string& param1, const std::string& param2) = 0; + virtual Json::Value eth_getTransactionByBlockNumberAndIndex(const std::string& param1, const std::string& param2) = 0; + virtual Json::Value eth_getTransactionReceipt(const std::string& param1) = 0; + virtual Json::Value eth_getUncleByBlockHashAndIndex(const std::string& param1, const std::string& param2) = 0; + virtual Json::Value eth_getUncleByBlockNumberAndIndex(const std::string& param1, const std::string& param2) = 0; + virtual std::string eth_newFilter(const Json::Value& param1) = 0; + virtual std::string eth_newFilterEx(const Json::Value& param1) = 0; + virtual std::string eth_newBlockFilter() = 0; + virtual std::string eth_newPendingTransactionFilter() = 0; + virtual bool eth_uninstallFilter(const std::string& param1) = 0; + virtual Json::Value eth_getFilterChanges(const std::string& param1) = 0; + virtual Json::Value eth_getFilterChangesEx(const std::string& param1) = 0; + virtual Json::Value eth_getFilterLogs(const std::string& param1) = 0; + virtual Json::Value eth_getFilterLogsEx(const std::string& param1) = 0; + virtual Json::Value eth_getLogs(const Json::Value& param1) = 0; + virtual Json::Value eth_getLogsEx(const Json::Value& param1) = 0; + virtual Json::Value eth_getWork() = 0; + virtual bool eth_submitWork(const std::string& param1, const std::string& param2, const std::string& param3) = 0; + virtual bool eth_submitHashrate(const std::string& param1, const std::string& param2) = 0; + virtual std::string eth_register(const std::string& param1) = 0; + virtual bool eth_unregister(const std::string& param1) = 0; + virtual Json::Value eth_fetchQueuedTransactions(const std::string& param1) = 0; + virtual std::string eth_signTransaction(const Json::Value& param1) = 0; + virtual Json::Value eth_inspectTransaction(const std::string& param1) = 0; + virtual std::string eth_sendRawTransaction(const std::string& param1) = 0; + virtual bool eth_notePassword(const std::string& param1) = 0; + virtual Json::Value eth_syncing() = 0; + virtual std::string eth_estimateGas(const Json::Value& param1) = 0; + }; + + } +} +#endif //JSONRPC_CPP_STUB_DEV_RPC_ETHFACE_H_ diff --git a/libweb3jsonrpc/IpcServer.h b/libweb3jsonrpc/IpcServer.h new file mode 100644 index 0000000000..1a585d4fce --- /dev/null +++ b/libweb3jsonrpc/IpcServer.h @@ -0,0 +1,34 @@ +/* +This file is part of cpp-ethereum. + +cpp-ethereum is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +cpp-ethereum 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with cpp-ethereum. If not, see . +*/ +/** @file IpcServer.h +* @authors: +* Arkadiy Paronyan +* @date 2015 +*/ +#pragma once + +#include "UnixSocketServer.h" +#include "WinPipeServer.h" + +namespace dev +{ +#if defined(_WIN32) + using IpcServer = WindowsPipeServer; +#else + using IpcServer = UnixDomainSocketServer; +#endif +} // namespace dev diff --git a/libweb3jsonrpc/IpcServerBase.cpp b/libweb3jsonrpc/IpcServerBase.cpp new file mode 100644 index 0000000000..6105d1baff --- /dev/null +++ b/libweb3jsonrpc/IpcServerBase.cpp @@ -0,0 +1,162 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file IpcServerBase.cpp + * @authors: + * Arkadiy Paronyan + * @date 2015 + */ + +#include "IpcServerBase.h" +#include +#include +#include +#include +#include + +using namespace std; +using namespace jsonrpc; +using namespace dev; + +int const c_bufferSize = 1024; + +struct IpcSendChannel: public LogChannel { static const char* name() { return "I>"; } static const int verbosity = 10; }; +struct IpcReceiveChannel: public LogChannel { static const char* name() { return "I<"; } static const int verbosity = 10; }; +#define cipcs dev::LogOutputStream() +#define cipcr dev::LogOutputStream() + +template IpcServerBase::IpcServerBase(string const& _path): + m_path(_path) +{ +} + +template bool IpcServerBase::StartListening() +{ + if (!m_running) + { + m_running = true; + m_listeningThread = std::thread([this](){ Listen(); }); + return true; + } + return false; +} + +template bool IpcServerBase::StopListening() +{ + if (m_running) + { + m_running = false; + DEV_GUARDED(x_sockets) + { + for (S s : m_sockets) + CloseConnection(s); + m_sockets.clear(); + } + m_listeningThread.join(); + return true; + } + return false; +} + +template bool IpcServerBase::SendResponse(string const& _response, void* _addInfo) +{ + bool fullyWritten = false; + bool errorOccured = false; + S socket = (S)(reinterpret_cast(_addInfo)); + string toSend = _response; + do + { + size_t bytesWritten = Write(socket, toSend); + if (bytesWritten == 0) + errorOccured = true; + else if (bytesWritten < toSend.size()) + { + int len = toSend.size() - bytesWritten; + toSend = toSend.substr(bytesWritten + sizeof(char), len); + } + else + fullyWritten = true; + } while (!fullyWritten && !errorOccured); + cipcs << _response; + return fullyWritten && !errorOccured; +} + +template void IpcServerBase::GenerateResponse(S _connection) +{ + char buffer[c_bufferSize]; + string request; + bool escape = false; + bool inString = false; + size_t i = 0; + int depth = 0; + size_t nbytes = 0; + do + { + nbytes = Read(_connection, buffer, c_bufferSize); + if (nbytes <= 0) + break; + request.append(buffer, nbytes); + while (i < request.size()) + { + char c = request[i]; + if (c == '\"' && !inString) + { + inString = true; + escape = false; + } + else if (c == '\"' && inString && !escape) + { + inString = false; + escape = false; + } + else if (inString && c == '\\' && !escape) + { + escape = true; + } + else if (inString) + { + escape = false; + } + else if (!inString && (c == '{' || c == '[')) + { + depth++; + } + else if (!inString && (c == '}' || c == ']')) + { + depth--; + if (depth == 0) + { + std::string r = request.substr(0, i + 1); + request.erase(0, i + 1); + cipcr << r; + OnRequest(r, reinterpret_cast((intptr_t)_connection)); + i = 0; + continue; + } + } + i++; + } + } while (true); + DEV_GUARDED(x_sockets) + m_sockets.erase(_connection); +} + +namespace dev +{ +template class IpcServerBase; +template class IpcServerBase; +} + diff --git a/libweb3jsonrpc/IpcServerBase.h b/libweb3jsonrpc/IpcServerBase.h new file mode 100644 index 0000000000..9b69399e81 --- /dev/null +++ b/libweb3jsonrpc/IpcServerBase.h @@ -0,0 +1,55 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file IpcServerBase.h + * @authors: + * Arkadiy Paronyan + * @date 2015 + */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace dev +{ +template class IpcServerBase: public jsonrpc::AbstractServerConnector +{ +public: + IpcServerBase(std::string const& _path); + virtual bool StartListening(); + virtual bool StopListening(); + virtual bool SendResponse(std::string const& _response, void* _addInfo = nullptr); + +protected: + virtual void Listen() = 0; + virtual void CloseConnection(S _socket) = 0; + virtual size_t Write(S _connection, std::string const& _data) = 0; + virtual size_t Read(S _connection, void* _data, size_t _size) = 0; + void GenerateResponse(S _connection); + +protected: + bool m_running = false; + std::string m_path; + std::unordered_set m_sockets; + std::mutex x_sockets; + std::thread m_listeningThread; //TODO use asio for parallel request processing +}; +} // namespace dev diff --git a/libweb3jsonrpc/JsonHelper.cpp b/libweb3jsonrpc/JsonHelper.cpp new file mode 100644 index 0000000000..d06f4ef288 --- /dev/null +++ b/libweb3jsonrpc/JsonHelper.cpp @@ -0,0 +1,577 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file JsonHelper.cpp + * @authors: + * Gav Wood + * @date 2014 + */ + +#include "JsonHelper.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +using namespace std; +using namespace dev; +using namespace eth; + +namespace dev +{ + +Json::Value toJson(unordered_map const& _storage) +{ + Json::Value res(Json::objectValue); + for (auto i: _storage) + res[toJS(i.first)] = toJS(i.second); + return res; +} + +Json::Value toJson(map> const& _storage) +{ + Json::Value res(Json::objectValue); + for (auto i: _storage) + res[toJS(u256(i.second.first))] = toJS(i.second.second); + return res; +} + +Json::Value toJson(Address const& _address) +{ + return toJS(_address); +} + +// //////////////////////////////////////////////////////////////////////////////// +// p2p +// //////////////////////////////////////////////////////////////////////////////// +namespace p2p +{ + +Json::Value toJson(p2p::PeerSessionInfo const& _p) +{ + //@todo localAddress + //@todo protocols + Json::Value ret; + ret["id"] = _p.id.hex(); + ret["name"] = _p.clientVersion; + ret["network"]["remoteAddress"] = _p.host + ":" + toString(_p.port); + ret["lastPing"] = (int)chrono::duration_cast(_p.lastPing).count(); + for (auto const& i: _p.notes) + ret["notes"][i.first] = i.second; + for (auto const& i: _p.caps) + ret["caps"].append(i.first + "/" + toString((unsigned)i.second)); + return ret; +} + +} + +// //////////////////////////////////////////////////////////////////////////////// +// eth +// //////////////////////////////////////////////////////////////////////////////// + +namespace eth +{ + +Json::Value toJson(dev::eth::BlockHeader const& _bi, SealEngineFace* _sealer) +{ + Json::Value res; + if (_bi) + { + DEV_IGNORE_EXCEPTIONS(res["hash"] = toJS(_bi.hash())); + res["parentHash"] = toJS(_bi.parentHash()); + res["sha3Uncles"] = toJS(_bi.sha3Uncles()); + res["author"] = toJS(_bi.author()); + res["stateRoot"] = toJS(_bi.stateRoot()); + res["transactionsRoot"] = toJS(_bi.transactionsRoot()); + res["receiptsRoot"] = toJS(_bi.receiptsRoot()); + res["number"] = toJS(_bi.number()); + res["gasUsed"] = toJS(_bi.gasUsed()); + res["gasLimit"] = toJS(_bi.gasLimit()); + res["extraData"] = toJS(_bi.extraData()); + res["logsBloom"] = toJS(_bi.logBloom()); + res["timestamp"] = toJS(_bi.timestamp()); + res["difficulty"] = toJS(_bi.difficulty()); + // TODO: remove once JSONRPC spec is updated to use "author" over "miner". + res["miner"] = toJS(_bi.author()); + if (_sealer) + for (auto const& i: _sealer->jsInfo(_bi)) + res[i.first] = i.second; + + } + return res; +} + +Json::Value toJson(dev::eth::Transaction const& _t, std::pair _location, BlockNumber _blockNumber) +{ + Json::Value res; + if (_t) + { + res["hash"] = toJS(_t.sha3()); + res["input"] = toJS(_t.data()); + res["to"] = _t.isCreation() ? Json::Value() : toJS(_t.receiveAddress()); + res["from"] = toJS(_t.safeSender()); + res["gas"] = toJS(_t.gas()); + res["gasPrice"] = toJS(_t.gasPrice()); + res["nonce"] = toJS(_t.randomid()); + res["value"] = toJS(_t.value()); + res["blockHash"] = toJS(_location.first); + res["transactionIndex"] = toJS(_location.second); + res["blockNumber"] = toJS(_blockNumber); + } + return res; +} + +Json::Value toJson(dev::eth::BlockHeader const& _bi, BlockDetails const& _bd, UncleHashes const& _us, Transactions const& _ts, SealEngineFace* _face) +{ + Json::Value res = toJson(_bi, _face); + if (_bi) + { + res["totalDifficulty"] = toJS(_bd.totalDifficulty); + res["uncles"] = Json::Value(Json::arrayValue); + for (h256 h: _us) + res["uncles"].append(toJS(h)); + res["transactions"] = Json::Value(Json::arrayValue); + for (unsigned i = 0; i < _ts.size(); i++) + res["transactions"].append(toJson(_ts[i], std::make_pair(_bi.hash(), i), (BlockNumber)_bi.number())); + } + return res; +} + +Json::Value toJson(dev::eth::BlockHeader const& _bi, BlockDetails const& _bd, UncleHashes const& _us, TransactionHashes const& _ts, SealEngineFace* _face) +{ + Json::Value res = toJson(_bi, _face); + if (_bi) + { + res["totalDifficulty"] = toJS(_bd.totalDifficulty); + res["uncles"] = Json::Value(Json::arrayValue); + for (h256 h: _us) + res["uncles"].append(toJS(h)); + res["transactions"] = Json::Value(Json::arrayValue); + for (h256 const& t: _ts) + res["transactions"].append(toJS(t)); + } + return res; +} + +Json::Value toJson(dev::eth::TransactionSkeleton const& _t) +{ + Json::Value res; + res["to"] = _t.creation ? Json::Value() : toJS(_t.to); + res["from"] = toJS(_t.from); + res["gas"] = toJS(_t.gas); + res["gasPrice"] = toJS(_t.gasPrice); + res["value"] = toJS(_t.value); + res["data"] = toJS(_t.data, 32); + return res; +} + +Json::Value toJson(dev::eth::TransactionReceipt const& _t) +{ + Json::Value res; + res["stateRoot"] = toJS(_t.stateRoot()); + res["gasUsed"] = toJS(_t.gasUsed()); + res["contractAddress"] = toJS(_t.contractAddress());//新增的 + res["bloom"] = toJS(_t.bloom()); + res["log"] = dev::toJson(_t.log()); + return res; +} + +Json::Value toJson(dev::eth::LocalisedTransactionReceipt const& _t) +{ + Json::Value res; + res["transactionHash"] = toJS(_t.hash()); + res["transactionIndex"] = _t.transactionIndex(); + res["blockHash"] = toJS(_t.blockHash()); + res["blockNumber"] = _t.blockNumber(); + res["cumulativeGasUsed"] = toJS(_t.gasUsed()); // TODO: check if this is fine + res["gasUsed"] = toJS(_t.gasUsed()); + res["contractAddress"] = toJS(_t.contractAddress()); + res["logs"] = dev::toJson(_t.localisedLogs()); + return res; +} + +Json::Value toJson(dev::eth::Transaction const& _t) +{ + Json::Value res; + res["to"] = _t.isCreation() ? Json::Value() : toJS(_t.to()); + res["from"] = toJS(_t.from()); + res["gas"] = toJS(_t.gas()); + res["gasPrice"] = toJS(_t.gasPrice()); + res["value"] = toJS(_t.value()); + res["data"] = toJS(_t.data(), 32); + res["nonce"] = toJS(_t.randomid()); + res["hash"] = toJS(_t.sha3(WithSignature)); + res["sighash"] = toJS(_t.sha3(WithoutSignature)); + res["r"] = toJS(_t.signature().r); + res["s"] = toJS(_t.signature().s); + res["v"] = toJS(_t.signature().v); + return res; +} + +Json::Value toJson(dev::eth::LocalisedTransaction const& _t) +{ + Json::Value res; + if (_t) + { + res["hash"] = toJS(_t.sha3()); + res["input"] = toJS(_t.data()); + res["to"] = _t.isCreation() ? Json::Value() : toJS(_t.receiveAddress()); + res["from"] = toJS(_t.safeSender()); + res["gas"] = toJS(_t.gas()); + res["gasPrice"] = toJS(_t.gasPrice()); + res["nonce"] = toJS(_t.randomid()); + res["value"] = toJS(_t.value()); + res["blockHash"] = toJS(_t.blockHash()); + res["transactionIndex"] = toJS(_t.transactionIndex()); + res["blockNumber"] = toJS(_t.blockNumber()); + } + return res; +} + +Json::Value toJson(dev::eth::NodeConnParams const& _t) +{ + Json::Value res; + res["NodeId"] = _t._sNodeId; + res["AgencyInfo"] = _t._sAgencyInfo; + res["IP"] = _t._sIP; + res["Port"] = _t._iPort; + res["IdentityType"] = _t._iIdentityType; + res["AgencyDesc"] = _t._sAgencyDesc; + return res; +} + +Json::Value toJson(dev::eth::LocalisedLogEntry const& _e) +{ + Json::Value res; + + if (_e.isSpecial) + res = toJS(_e.special); + else + { + res = toJson(static_cast(_e)); + res["polarity"] = _e.polarity == BlockPolarity::Live ? true : false; + if (_e.mined) + { + res["type"] = "mined"; + res["blockNumber"] = _e.blockNumber; + res["blockHash"] = toJS(_e.blockHash); + res["logIndex"] = _e.logIndex; + res["transactionHash"] = toJS(_e.transactionHash); + res["transactionIndex"] = _e.transactionIndex; + } + else + { + res["type"] = "pending"; + res["blockNumber"] = Json::Value(Json::nullValue); + res["blockHash"] = Json::Value(Json::nullValue); + res["logIndex"] = Json::Value(Json::nullValue); + res["transactionHash"] = Json::Value(Json::nullValue); + res["transactionIndex"] = Json::Value(Json::nullValue); + } + } + return res; +} + +Json::Value toJson(dev::eth::LogEntry const& _e) +{ + Json::Value res; + res["data"] = toJS(_e.data); + res["address"] = toJS(_e.address); + res["topics"] = Json::Value(Json::arrayValue); + for (auto const& t: _e.topics) + res["topics"].append(toJS(t)); + return res; +} + +Json::Value toJson(std::unordered_map const& _entriesByBlock, vector const& _order) +{ + Json::Value res(Json::arrayValue); + for (auto const& i: _order) + { + auto entries = _entriesByBlock.at(i); + Json::Value currentBlock(Json::objectValue); + LocalisedLogEntry entry = entries[0]; + if (entry.mined) + { + + currentBlock["blockNumber"] = entry.blockNumber; + currentBlock["blockHash"] = toJS(entry.blockHash); + currentBlock["type"] = "mined"; + } + else + currentBlock["type"] = "pending"; + + currentBlock["polarity"] = entry.polarity == BlockPolarity::Live ? true : false; + currentBlock["logs"] = Json::Value(Json::arrayValue); + + for (LocalisedLogEntry const& e: entries) + { + Json::Value log(Json::objectValue); + log["logIndex"] = e.logIndex; + log["transactionIndex"] = e.transactionIndex; + log["transactionHash"] = toJS(e.transactionHash); + log["address"] = toJS(e.address); + log["data"] = toJS(e.data); + log["topics"] = Json::Value(Json::arrayValue); + for (auto const& t: e.topics) + log["topics"].append(toJS(t)); + + currentBlock["logs"].append(log); + } + + res.append(currentBlock); + } + + return res; +} + +Json::Value toJsonByBlock(LocalisedLogEntries const& _entries) +{ + vector order; + unordered_map entriesByBlock; + + for (dev::eth::LocalisedLogEntry const& e: _entries) + { + if (e.isSpecial) // skip special log + continue; + + if (entriesByBlock.count(e.blockHash) == 0) + { + entriesByBlock[e.blockHash] = LocalisedLogEntries(); + order.push_back(e.blockHash); + } + + entriesByBlock[e.blockHash].push_back(e); + } + + return toJson(entriesByBlock, order); +} + +TransactionSkeleton toTransactionSkeleton(Json::Value const& _json) +{ + TransactionSkeleton ret; + if (!_json.isObject() || _json.empty()) + return ret; + + if (!_json["from"].empty()) + ret.from = jsToAddress(_json["from"].asString()); + if ((!_json["to"].empty())&& (!_json["to"].asString().empty()) && _json["to"].asString() != "0x") + ret.to = jsToAddress(_json["to"].asString()); + else + ret.creation = true; + + if (!_json["value"].empty()) + ret.value = jsToU256(_json["value"].asString()); + + if (!_json["gas"].empty()) + ret.gas = jsToU256(_json["gas"].asString()); + + if (!_json["gasPrice"].empty()) + ret.gasPrice = jsToU256(_json["gasPrice"].asString()); + + if (!_json["data"].empty()) // ethereum.js has preconstructed the data array + ret.data = jsToBytes(_json["data"].asString(), OnFailed::Throw); + + if (!_json["code"].empty()) + ret.data = jsToBytes(_json["code"].asString(), OnFailed::Throw); + + if (!_json["randomid"].empty()) + ret.randomid = jsToU256(_json["randomid"].asString()); + + //增加blocklimit 参数 + if (!_json["blockLimit"].empty()) + ret.blockLimit = jsToU256(_json["blockLimit"].asString()); + return ret; +} + +dev::eth::LogFilter toLogFilter(Json::Value const& _json) +{ + dev::eth::LogFilter filter; + if (!_json.isObject() || _json.empty()) + return filter; + + // check only !empty. it should throw exceptions if input params are incorrect + if (!_json["fromBlock"].empty()) + filter.withEarliest(jsToFixed<32>(_json["fromBlock"].asString())); + if (!_json["toBlock"].empty()) + filter.withLatest(jsToFixed<32>(_json["toBlock"].asString())); + if (!_json["address"].empty()) + { + if (_json["address"].isArray()) + for (auto i : _json["address"]) + filter.address(jsToAddress(i.asString())); + else + filter.address(jsToAddress(_json["address"].asString())); + } + if (!_json["topics"].empty()) + for (unsigned i = 0; i < _json["topics"].size(); i++) + { + if (_json["topics"][i].isArray()) + { + for (auto t: _json["topics"][i]) + if (!t.isNull()) + filter.topic(i, jsToFixed<32>(t.asString())); + } + else if (!_json["topics"][i].isNull()) // if it is anything else then string, it should and will fail + filter.topic(i, jsToFixed<32>(_json["topics"][i].asString())); + } + return filter; +} + +// TODO: this should be removed once we decide to remove backward compatibility with old log filters +dev::eth::LogFilter toLogFilter(Json::Value const& _json, Interface const& _client) // commented to avoid warning. Uncomment once in use @ PoC-7. +{ + dev::eth::LogFilter filter; + if (!_json.isObject() || _json.empty()) + return filter; + + // check only !empty. it should throw exceptions if input params are incorrect + if (!_json["fromBlock"].empty()) + filter.withEarliest(_client.hashFromNumber(jsToBlockNumber(_json["fromBlock"].asString()))); + if (!_json["toBlock"].empty()) + filter.withLatest(_client.hashFromNumber(jsToBlockNumber(_json["toBlock"].asString()))); + if (!_json["address"].empty()) + { + if (_json["address"].isArray()) + for (auto i : _json["address"]) + filter.address(jsToAddress(i.asString())); + else + filter.address(jsToAddress(_json["address"].asString())); + } + if (!_json["topics"].empty()) + for (unsigned i = 0; i < _json["topics"].size(); i++) + { + if (_json["topics"][i].isArray()) + { + for (auto t: _json["topics"][i]) + if (!t.isNull()) + filter.topic(i, jsToFixed<32>(t.asString())); + } + else if (!_json["topics"][i].isNull()) // if it is anything else then string, it should and will fail + filter.topic(i, jsToFixed<32>(_json["topics"][i].asString())); + } + return filter; +} + +} + +// //////////////////////////////////////////////////////////////////////////////////// +// shh +// //////////////////////////////////////////////////////////////////////////////////// + +namespace shh +{ + +Json::Value toJson(h256 const& _h, shh::Envelope const& _e, shh::Message const& _m) +{ + Json::Value res; + res["hash"] = toJS(_h); + res["expiry"] = toJS(_e.expiry()); + res["sent"] = toJS(_e.sent()); + res["ttl"] = toJS(_e.ttl()); + res["workProved"] = toJS(_e.workProved()); + res["topics"] = Json::Value(Json::arrayValue); + for (auto const& t: _e.topic()) + res["topics"].append(toJS(t)); + res["payload"] = toJS(_m.payload()); + res["from"] = toJS(_m.from()); + res["to"] = toJS(_m.to()); + return res; +} + +shh::Message toMessage(Json::Value const& _json) +{ + shh::Message ret; + if (!_json["from"].empty()) + ret.setFrom(jsToPublic(_json["from"].asString())); + if (!_json["to"].empty()) + ret.setTo(jsToPublic(_json["to"].asString())); + if (!_json["payload"].empty()) + ret.setPayload(jsToBytes(_json["payload"].asString())); + return ret; +} + +shh::Envelope toSealed(Json::Value const& _json, shh::Message const& _m, Secret const& _from) +{ + unsigned ttl = 50; + unsigned workToProve = 50; + shh::BuildTopic bt; + + if (!_json["ttl"].empty()) + ttl = jsToInt(_json["ttl"].asString()); + + if (!_json["workToProve"].empty()) + workToProve = jsToInt(_json["workToProve"].asString()); + + if (!_json["topics"].empty()) + for (auto i: _json["topics"]) + { + if (i.isArray()) + { + for (auto j: i) + if (!j.isNull()) + bt.shift(jsToBytes(j.asString())); + } + else if (!i.isNull()) // if it is anything else then string, it should and will fail + bt.shift(jsToBytes(i.asString())); + } + + return _m.seal(_from, bt, ttl, workToProve); +} + +pair toWatch(Json::Value const& _json) +{ + shh::BuildTopic bt; + Public to; + + if (!_json["to"].empty()) + to = jsToPublic(_json["to"].asString()); + + if (!_json["topics"].empty()) + for (auto i: _json["topics"]) + bt.shift(jsToBytes(i.asString())); + + return make_pair(bt, to); +} + +} + +// //////////////////////////////////////////////////////////////////////////////////// +// rpc +// //////////////////////////////////////////////////////////////////////////////////// + +namespace rpc +{ +h256 h256fromHex(string const& _s) +{ + try + { + return h256(_s); + } + catch (boost::exception const&) + { + throw jsonrpc::JsonRpcException("Invalid hex-encoded string: " + _s); + } +} +} + +} diff --git a/libweb3jsonrpc/JsonHelper.h b/libweb3jsonrpc/JsonHelper.h new file mode 100644 index 0000000000..d1e98bf0b9 --- /dev/null +++ b/libweb3jsonrpc/JsonHelper.h @@ -0,0 +1,126 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file JsonHelper.h + * @authors: + * Gav Wood + * @date 2015 + */ +#pragma once + +#include +#include +#include +#include +#include + +namespace dev +{ + +Json::Value toJson(std::map> const& _storage); +Json::Value toJson(std::unordered_map const& _storage); +Json::Value toJson(Address const& _address); + +namespace p2p +{ + +Json::Value toJson(PeerSessionInfo const& _p); + +} + +namespace eth +{ + +class Transaction; +class LocalisedTransaction; +class SealEngineFace; +class NodeConnParams; +struct BlockDetails; +class Interface; +using Transactions = std::vector; +using UncleHashes = h256s; +using TransactionHashes = h256s; + +Json::Value toJson(BlockHeader const& _bi, SealEngineFace* _face = nullptr); +//TODO: wrap these params into one structure eg. "LocalisedTransaction" +Json::Value toJson(Transaction const& _t, std::pair _location, BlockNumber _blockNumber); +Json::Value toJson(BlockHeader const& _bi, BlockDetails const& _bd, UncleHashes const& _us, Transactions const& _ts, SealEngineFace* _face = nullptr); +Json::Value toJson(BlockHeader const& _bi, BlockDetails const& _bd, UncleHashes const& _us, TransactionHashes const& _ts, SealEngineFace* _face = nullptr); +Json::Value toJson(TransactionSkeleton const& _t); +Json::Value toJson(Transaction const& _t); +Json::Value toJson(LocalisedTransaction const& _t); +Json::Value toJson(NodeConnParams const& _t); +Json::Value toJson(TransactionReceipt const& _t); +Json::Value toJson(LocalisedTransactionReceipt const& _t); +Json::Value toJson(LocalisedLogEntry const& _e); +Json::Value toJson(LogEntry const& _e); +Json::Value toJson(std::unordered_map const& _entriesByBlock); +Json::Value toJsonByBlock(LocalisedLogEntries const& _entries); +TransactionSkeleton toTransactionSkeleton(Json::Value const& _json); +LogFilter toLogFilter(Json::Value const& _json); +LogFilter toLogFilter(Json::Value const& _json, Interface const& _client); // commented to avoid warning. Uncomment once in use @ PoC-7. + +class AddressResolver +{ +public: + static Address fromJS(std::string const& _address); +}; + +} + +namespace shh +{ + +Json::Value toJson(h256 const& _h, Envelope const& _e, Message const& _m); +Message toMessage(Json::Value const& _json); +Envelope toSealed(Json::Value const& _json, Message const& _m, Secret const& _from); +std::pair toWatch(Json::Value const& _json); + +} + +namespace rpc +{ +h256 h256fromHex(std::string const& _s); +} + +template +Json::Value toJson(std::vector const& _es) +{ + Json::Value res(Json::arrayValue); + for (auto const& e: _es) + res.append(toJson(e)); + return res; +} + +template +Json::Value toJson(std::unordered_set const& _es) +{ + Json::Value res(Json::arrayValue); + for (auto const& e: _es) + res.append(toJson(e)); + return res; +} + +template +Json::Value toJson(std::set const& _es) +{ + Json::Value res(Json::arrayValue); + for (auto const& e: _es) + res.append(toJson(e)); + return res; +} + +} diff --git a/libweb3jsonrpc/LevelDB.cpp b/libweb3jsonrpc/LevelDB.cpp new file mode 100644 index 0000000000..2689108f22 --- /dev/null +++ b/libweb3jsonrpc/LevelDB.cpp @@ -0,0 +1,61 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file LevelDB.cpp + * @authors: + * Gav Wood + * Marek Kotewicz + * @date 2015 + */ + +#include "LevelDB.h" +#include +#include +#include +#include + +using namespace std; +using namespace dev; +using namespace dev::rpc; +namespace fs = boost::filesystem; +namespace ldb = leveldb; + +LevelDB::LevelDB() +{ + auto path = getDataDir() + "/.web3"; + fs::create_directories(path); + DEV_IGNORE_EXCEPTIONS(fs::permissions(path, fs::owner_all)); + ldb::Options o; + o.create_if_missing = true; + ldb::DB::Open(o, path, &m_db); +} + +bool LevelDB::db_put(std::string const& _name, std::string const& _key, std::string const& _value) +{ + bytes k = sha3(_name).asBytes() + sha3(_key).asBytes(); + auto status = m_db->Put(ldb::WriteOptions(), + ldb::Slice((char const*)k.data(), k.size()), + ldb::Slice((char const*)_value.data(), _value.size())); + return status.ok(); +} + +std::string LevelDB::db_get(std::string const& _name, std::string const& _key) +{ + bytes k = sha3(_name).asBytes() + sha3(_key).asBytes(); + string ret; + m_db->Get(ldb::ReadOptions(), ldb::Slice((char const*)k.data(), k.size()), &ret); + return ret; +} \ No newline at end of file diff --git a/libweb3jsonrpc/LevelDB.h b/libweb3jsonrpc/LevelDB.h new file mode 100644 index 0000000000..344535c46b --- /dev/null +++ b/libweb3jsonrpc/LevelDB.h @@ -0,0 +1,53 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file LevelDB.h + * @authors: + * Gav Wood + * Marek Kotewicz + * @date 2015 + */ + +#pragma once +#include "DBFace.h" + +namespace leveldb +{ + class DB; +} + +namespace dev +{ +namespace rpc +{ + +class LevelDB: public dev::rpc::DBFace +{ +public: + LevelDB(); + virtual RPCModules implementedModules() const override + { + return RPCModules{RPCModule{"db", "1.0"}}; + } + virtual bool db_put(std::string const& _name, std::string const& _key, std::string const& _value) override; + virtual std::string db_get(std::string const& _name, std::string const& _key) override; + +private: + leveldb::DB* m_db; +}; + +} +} diff --git a/libweb3jsonrpc/MemoryDB.cpp b/libweb3jsonrpc/MemoryDB.cpp new file mode 100644 index 0000000000..d7dfca21fc --- /dev/null +++ b/libweb3jsonrpc/MemoryDB.cpp @@ -0,0 +1,39 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file MemoryDB.cpp + * @authors: + * Gav Wood + * Marek Kotewicz + * @date 2015 + */ + +#include "MemoryDB.h" + +using namespace dev::rpc; + +bool MemoryDB::db_put(std::string const& _name, std::string const& _key, std::string const& _value) +{ + std::string k(_name + "/" + _key); + m_db[k] = _value; + return true; +} + +std::string MemoryDB::db_get(std::string const& _name, std::string const& _key) +{ + std::string k(_name + "/" + _key); + return m_db[k]; +} diff --git a/libweb3jsonrpc/MemoryDB.h b/libweb3jsonrpc/MemoryDB.h new file mode 100644 index 0000000000..894f756ca0 --- /dev/null +++ b/libweb3jsonrpc/MemoryDB.h @@ -0,0 +1,47 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file MemoryDB.h + * @authors: + * Gav Wood + * Marek Kotewicz + * @date 2015 + */ + +#pragma once +#include "DBFace.h" + +namespace dev +{ +namespace rpc +{ + +class MemoryDB: public dev::rpc::DBFace +{ +public: + virtual RPCModules implementedModules() const override + { + return RPCModules{RPCModule{"db", "1.0"}}; + } + virtual bool db_put(std::string const& _name, std::string const& _key, std::string const& _value) override; + virtual std::string db_get(std::string const& _name, std::string const& _key) override; + +private: + std::map m_db; +}; + +} +} diff --git a/libweb3jsonrpc/ModularServer.h b/libweb3jsonrpc/ModularServer.h new file mode 100644 index 0000000000..bed6c8d03d --- /dev/null +++ b/libweb3jsonrpc/ModularServer.h @@ -0,0 +1,184 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file ModularServer.h + * @author Marek Kotewicz + * @date 2015 + */ + +#pragma once + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +template using AbstractMethodPointer = void(I::*)(Json::Value const& _parameter, Json::Value& _result); +template using AbstractNotificationPointer = void(I::*)(Json::Value const& _parameter); + +template +class ServerInterface +{ +public: + using MethodPointer = AbstractMethodPointer; + using NotificationPointer = AbstractNotificationPointer; + + using MethodBinding = std::tuple>; + using NotificationBinding = std::tuple>; + using Methods = std::vector; + using Notifications = std::vector; + struct RPCModule { std::string name; std::string version; }; + using RPCModules = std::vector; + + virtual ~ServerInterface() {} + Methods const& methods() const { return m_methods; } + Notifications const& notifications() const { return m_notifications; } + /// @returns which interfaces (eth, admin, db, ...) this class implements in which version. + virtual RPCModules implementedModules() const = 0; + +protected: + void bindAndAddMethod(jsonrpc::Procedure const& _proc, MethodPointer _pointer) { m_methods.emplace_back(_proc, _pointer); } + void bindAndAddNotification(jsonrpc::Procedure const& _proc, NotificationPointer _pointer) { m_notifications.emplace_back(_proc, _pointer); } + +private: + Methods m_methods; + Notifications m_notifications; +}; + +template +class ModularServer: public jsonrpc::IProcedureInvokationHandler +{ +public: + ModularServer() + : m_handler(jsonrpc::RequestHandlerFactory::createProtocolHandler(jsonrpc::JSONRPC_SERVER_V2, *this)) + { + m_handler->AddProcedure(jsonrpc::Procedure("rpc_modules", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, NULL)); + m_implementedModules = Json::objectValue; + } + inline virtual void modules(const Json::Value &request, Json::Value &response) + { + (void)request; + response = m_implementedModules; + } + + virtual ~ModularServer() { StopListening(); } + + virtual bool StartListening() + { + + for (auto const& connector: m_connectors) + { + if( false == connector->StartListening() ) + return false;//启动失败 + } + + return true; + } + + virtual void StopListening() + { + for (auto const& connector: m_connectors) + connector->StopListening(); + } + + virtual void HandleMethodCall(jsonrpc::Procedure& _proc, Json::Value const& _input, Json::Value& _output) override + { + if (_proc.GetProcedureName() == "rpc_modules") + modules(_input, _output); + } + + virtual void HandleNotificationCall(jsonrpc::Procedure& _proc, Json::Value const& _input) override + { + (void)_proc; + (void)_input; + } + + /// server takes ownership of the connector + unsigned addConnector(jsonrpc::AbstractServerConnector* _connector) + { + m_connectors.emplace_back(_connector); + _connector->SetHandler(m_handler.get()); + return m_connectors.size() - 1; + } + + jsonrpc::AbstractServerConnector* connector(unsigned _i) const + { + return m_connectors.at(_i).get(); + } + +protected: + std::vector> m_connectors; + std::unique_ptr m_handler; + /// Mapping for implemented modules, to be filled by subclasses during construction. + Json::Value m_implementedModules; +}; + +template +class ModularServer : public ModularServer +{ +public: + using MethodPointer = AbstractMethodPointer; + using NotificationPointer = AbstractNotificationPointer; + + ModularServer(I* _i, Is*... _is): ModularServer(_is...), m_interface(_i) + { + if (!m_interface) + return; + for (auto const& method: m_interface->methods()) + { + m_methods[std::get<0>(method).GetProcedureName()] = std::get<1>(method); + this->m_handler->AddProcedure(std::get<0>(method)); + } + + for (auto const& notification: m_interface->notifications()) + { + m_notifications[std::get<0>(notification).GetProcedureName()] = std::get<1>(notification); + this->m_handler->AddProcedure(std::get<0>(notification)); + } + // Store module with version. + for (auto const& module: m_interface->implementedModules()) + this->m_implementedModules[module.name] = module.version; + } + + virtual void HandleMethodCall(jsonrpc::Procedure& _proc, Json::Value const& _input, Json::Value& _output) override + { + auto pointer = m_methods.find(_proc.GetProcedureName()); + if (pointer != m_methods.end()) + (m_interface.get()->*(pointer->second))(_input, _output); + else + ModularServer::HandleMethodCall(_proc, _input, _output); + } + + virtual void HandleNotificationCall(jsonrpc::Procedure& _proc, Json::Value const& _input) override + { + auto pointer = m_notifications.find(_proc.GetProcedureName()); + if (pointer != m_notifications.end()) + (m_interface.get()->*(pointer->second))(_input); + else + ModularServer::HandleNotificationCall(_proc, _input); + } + +private: + std::unique_ptr m_interface; + std::map m_methods; + std::map m_notifications; +}; diff --git a/libweb3jsonrpc/Net.cpp b/libweb3jsonrpc/Net.cpp new file mode 100644 index 0000000000..b3ff3e4d51 --- /dev/null +++ b/libweb3jsonrpc/Net.cpp @@ -0,0 +1,47 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Net.cpp + * @authors: + * Gav Wood + * Marek Kotewicz + * @date 2015 + */ + +#include +#include +#include +#include "Net.h" + +using namespace dev; +using namespace dev::rpc; + +Net::Net(NetworkFace& _network): m_network(_network) {} + +std::string Net::net_version() +{ + return toString(m_network.networkId()); +} + +std::string Net::net_peerCount() +{ + return toJS(m_network.peerCount()); +} + +bool Net::net_listening() +{ + return m_network.isNetworkStarted(); +} diff --git a/libweb3jsonrpc/Net.h b/libweb3jsonrpc/Net.h new file mode 100644 index 0000000000..00a32a7a12 --- /dev/null +++ b/libweb3jsonrpc/Net.h @@ -0,0 +1,52 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Net.h + * @authors: + * Gav Wood + * Marek Kotewicz + * @date 2015 + */ + +#pragma once +#include "NetFace.h" + +namespace dev +{ + +class NetworkFace; + +namespace rpc +{ + +class Net: public NetFace +{ +public: + Net(NetworkFace& _network); + virtual RPCModules implementedModules() const override + { + return RPCModules{RPCModule{"net", "1.0"}}; + } + virtual std::string net_version() override; + virtual std::string net_peerCount() override; + virtual bool net_listening() override; + +private: + NetworkFace& m_network; +}; + +} +} diff --git a/libweb3jsonrpc/NetFace.h b/libweb3jsonrpc/NetFace.h new file mode 100644 index 0000000000..a1f889ecc5 --- /dev/null +++ b/libweb3jsonrpc/NetFace.h @@ -0,0 +1,44 @@ +/** + * This file is generated by jsonrpcstub, DO NOT CHANGE IT MANUALLY! + */ + +#ifndef JSONRPC_CPP_STUB_DEV_RPC_NETFACE_H_ +#define JSONRPC_CPP_STUB_DEV_RPC_NETFACE_H_ + +#include "ModularServer.h" + +namespace dev { + namespace rpc { + class NetFace : public ServerInterface + { + public: + NetFace() + { + this->bindAndAddMethod(jsonrpc::Procedure("net_version", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, NULL), &dev::rpc::NetFace::net_versionI); + this->bindAndAddMethod(jsonrpc::Procedure("net_peerCount", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, NULL), &dev::rpc::NetFace::net_peerCountI); + this->bindAndAddMethod(jsonrpc::Procedure("net_listening", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, NULL), &dev::rpc::NetFace::net_listeningI); + } + + inline virtual void net_versionI(const Json::Value &request, Json::Value &response) + { + (void)request; + response = this->net_version(); + } + inline virtual void net_peerCountI(const Json::Value &request, Json::Value &response) + { + (void)request; + response = this->net_peerCount(); + } + inline virtual void net_listeningI(const Json::Value &request, Json::Value &response) + { + (void)request; + response = this->net_listening(); + } + virtual std::string net_version() = 0; + virtual std::string net_peerCount() = 0; + virtual bool net_listening() = 0; + }; + + } +} +#endif //JSONRPC_CPP_STUB_DEV_RPC_NETFACE_H_ diff --git a/libweb3jsonrpc/Personal.cpp b/libweb3jsonrpc/Personal.cpp new file mode 100644 index 0000000000..26b44c8f59 --- /dev/null +++ b/libweb3jsonrpc/Personal.cpp @@ -0,0 +1,66 @@ +#include +#include +#include +#include +#include +#include + +#include "Personal.h" + +using namespace std; +using namespace dev; +using namespace dev::rpc; +using namespace dev::eth; +using namespace jsonrpc; + +Personal::Personal(KeyManager& _keyManager, AccountHolder& _accountHolder, eth::Interface& _eth): + m_keyManager(_keyManager), + m_accountHolder(_accountHolder), + m_eth(_eth) +{ +} + +std::string Personal::personal_newAccount(std::string const& _password) +{ + KeyPair p = KeyManager::newKeyPair(KeyManager::NewKeyType::NoVanity); + m_keyManager.import(p.secret(), std::string(), _password, std::string()); + return toJS(p.address()); +} + +string Personal::personal_sendTransaction(Json::Value const& _transaction, string const& _password) +{ + TransactionSkeleton t; + try + { + t = toTransactionSkeleton(_transaction); + } + catch (...) + { + BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); + return string(); + } + + if (Secret s = m_keyManager.secret(t.from, [&](){ return _password; }, false)) + { + // return the tx hash + return toJS(m_eth.submitTransaction(t, s).first); + } + else + BOOST_THROW_EXCEPTION(JsonRpcException("Invalid password or account.")); + return string(); +} + +string Personal::personal_signAndSendTransaction(Json::Value const& _transaction, string const& _password) +{ + return personal_sendTransaction(_transaction, _password); +} + +bool Personal::personal_unlockAccount(std::string const& _address, std::string const& _password, int _duration) +{ + return m_accountHolder.unlockAccount(Address(fromHex(_address, WhenError::Throw)), _password, _duration); +} + +Json::Value Personal::personal_listAccounts() +{ + return toJson(m_keyManager.accounts()); +} diff --git a/libweb3jsonrpc/Personal.h b/libweb3jsonrpc/Personal.h new file mode 100644 index 0000000000..65d7fdf34e --- /dev/null +++ b/libweb3jsonrpc/Personal.h @@ -0,0 +1,38 @@ +#pragma once +#include "PersonalFace.h" + +namespace dev +{ + +namespace eth +{ +class KeyManager; +class AccountHolder; +class Interface; +} + +namespace rpc +{ + +class Personal: public dev::rpc::PersonalFace +{ +public: + Personal(dev::eth::KeyManager& _keyManager, dev::eth::AccountHolder& _accountHolder, eth::Interface& _eth); + virtual RPCModules implementedModules() const override + { + return RPCModules{RPCModule{"personal", "1.0"}}; + } + virtual std::string personal_newAccount(std::string const& _password) override; + virtual bool personal_unlockAccount(std::string const& _address, std::string const& _password, int _duration) override; + virtual std::string personal_signAndSendTransaction(Json::Value const& _transaction, std::string const& _password) override; + virtual std::string personal_sendTransaction(Json::Value const& _transaction, std::string const& _password) override; + virtual Json::Value personal_listAccounts() override; + +private: + dev::eth::KeyManager& m_keyManager; + dev::eth::AccountHolder& m_accountHolder; + dev::eth::Interface& m_eth; +}; + +} +} diff --git a/libweb3jsonrpc/PersonalFace.h b/libweb3jsonrpc/PersonalFace.h new file mode 100644 index 0000000000..54f2842f18 --- /dev/null +++ b/libweb3jsonrpc/PersonalFace.h @@ -0,0 +1,54 @@ +/** + * This file is generated by jsonrpcstub, DO NOT CHANGE IT MANUALLY! + */ + +#ifndef JSONRPC_CPP_STUB_DEV_RPC_PERSONALFACE_H_ +#define JSONRPC_CPP_STUB_DEV_RPC_PERSONALFACE_H_ + +#include "ModularServer.h" + +namespace dev { + namespace rpc { + class PersonalFace : public ServerInterface + { + public: + PersonalFace() + { + this->bindAndAddMethod(jsonrpc::Procedure("personal_newAccount", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &dev::rpc::PersonalFace::personal_newAccountI); + this->bindAndAddMethod(jsonrpc::Procedure("personal_unlockAccount", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING,"param3",jsonrpc::JSON_INTEGER, NULL), &dev::rpc::PersonalFace::personal_unlockAccountI); + this->bindAndAddMethod(jsonrpc::Procedure("personal_signAndSendTransaction", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_OBJECT,"param2",jsonrpc::JSON_STRING, NULL), &dev::rpc::PersonalFace::personal_signAndSendTransactionI); + this->bindAndAddMethod(jsonrpc::Procedure("personal_sendTransaction", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_OBJECT,"param2",jsonrpc::JSON_STRING, NULL), &dev::rpc::PersonalFace::personal_sendTransactionI); + this->bindAndAddMethod(jsonrpc::Procedure("personal_listAccounts", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, NULL), &dev::rpc::PersonalFace::personal_listAccountsI); + } + + inline virtual void personal_newAccountI(const Json::Value &request, Json::Value &response) + { + response = this->personal_newAccount(request[0u].asString()); + } + inline virtual void personal_unlockAccountI(const Json::Value &request, Json::Value &response) + { + response = this->personal_unlockAccount(request[0u].asString(), request[1u].asString(), request[2u].asInt()); + } + inline virtual void personal_signAndSendTransactionI(const Json::Value &request, Json::Value &response) + { + response = this->personal_signAndSendTransaction(request[0u], request[1u].asString()); + } + inline virtual void personal_sendTransactionI(const Json::Value &request, Json::Value &response) + { + response = this->personal_sendTransaction(request[0u], request[1u].asString()); + } + inline virtual void personal_listAccountsI(const Json::Value &request, Json::Value &response) + { + (void)request; + response = this->personal_listAccounts(); + } + virtual std::string personal_newAccount(const std::string& param1) = 0; + virtual bool personal_unlockAccount(const std::string& param1, const std::string& param2, int param3) = 0; + virtual std::string personal_signAndSendTransaction(const Json::Value& param1, const std::string& param2) = 0; + virtual std::string personal_sendTransaction(const Json::Value& param1, const std::string& param2) = 0; + virtual Json::Value personal_listAccounts() = 0; + }; + + } +} +#endif //JSONRPC_CPP_STUB_DEV_RPC_PERSONALFACE_H_ diff --git a/libweb3jsonrpc/SafeHttpServer.cpp b/libweb3jsonrpc/SafeHttpServer.cpp new file mode 100644 index 0000000000..340c1c95fe --- /dev/null +++ b/libweb3jsonrpc/SafeHttpServer.cpp @@ -0,0 +1,278 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file SafeHttpServer.cpp + * @authors: + * Marek + * @date 2015 + */ + +#include +#include +#include +#include +#include "SafeHttpServer.h" +#include "DfsFileServer.h" + + +using namespace std; +using namespace dev; +using namespace dev::rpc::fs; + + +/// structure copied from libjson-rpc-cpp httpserver version 0.6.0 +struct mhd_coninfo +{ + struct MHD_PostProcessor *postprocessor; + MHD_Connection* connection; + stringstream request; + TrustHttpServer* server; + int code; +}; + +TrustHttpServer::TrustHttpServer(eth::Client* _eth, int _port, const std::string& _sslrootca, const std::string& _sslcert, const std::string& _sslkey, int _threads) : + AbstractServerConnector(), + m_port(_port), + m_threads(_threads), + m_running(false), + m_path_sslcert(_sslcert), + m_path_sslkey(_sslkey), + m_path_sslrootca(_sslrootca), + m_eth(_eth), + daemon(NULL), + m_DfsNodeGroupId(""), + m_DfsNodeId(""), + m_DfsStoragePath("") +{ +} + +jsonrpc::IClientConnectionHandler *TrustHttpServer::GetHandler(const std::string &_url) +{ + if (AbstractServerConnector::GetHandler() != NULL) + return AbstractServerConnector::GetHandler(); + map::iterator it = this->m_urlhandler.find(_url); + if (it != this->m_urlhandler.end()) + return it->second; + return NULL; +} + +bool TrustHttpServer::StartListening() +{ + if(!this->m_running) + { + //start the fileserver + if (0 != DfsFileServer::getInstance()->init(m_DfsStoragePath, m_DfsNodeGroupId, m_DfsNodeId, m_eth)) + { + LOG(ERROR) << "init DfsFileServer failed !"; + //return false; + } + + if (this->m_path_sslcert != "" && this->m_path_sslkey != "" && this->m_path_sslrootca != "") + { + LOG(TRACE) << "*****#### HTTPS / SSL start, but not support ###******"; + } + + LOG(TRACE) << "*****#### HTTP start ###******"; + this->daemon = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY, this->m_port, NULL, NULL, \ + TrustHttpServer::callback, this, \ + MHD_OPTION_THREAD_POOL_SIZE, this->m_threads, \ + MHD_OPTION_NOTIFY_COMPLETED, DfsFileServer::request_completed, NULL, \ + MHD_OPTION_END); + if (this->daemon != NULL) + this->m_running = true; + } + + return this->m_running; +} + +bool TrustHttpServer::StopListening() +{ + if(this->m_running) + { + MHD_stop_daemon(this->daemon); + DfsFileServer::getInstance()->destory(); + this->m_running = false; + } + + return true; +} + +bool TrustHttpServer::SendResponse(const string& _response, void* _addInfo) +{ + struct mhd_coninfo* client_connection = static_cast(_addInfo); + struct MHD_Response *result = MHD_create_response_from_buffer(_response.size(),(void *) _response.c_str(), MHD_RESPMEM_MUST_COPY); + + MHD_add_response_header(result, "Content-Type", "application/json"); + MHD_add_response_header(result, "Access-Control-Allow-Origin", "*"); + + int ret = MHD_queue_response(client_connection->connection, client_connection->code, result); + MHD_destroy_response(result); + return ret == MHD_YES; +} + +bool TrustHttpServer::SendOptionsResponse(void* _addInfo) +{ + struct mhd_coninfo* client_connection = static_cast(_addInfo); + struct MHD_Response *result = MHD_create_response_from_buffer(0, NULL, MHD_RESPMEM_MUST_COPY); + + MHD_add_response_header(result, "Allow", "POST, OPTIONS"); + MHD_add_response_header(result, "Access-Control-Allow-Origin", "*"); + MHD_add_response_header(result, "Access-Control-Allow-Headers", "origin, content-type, accept"); + MHD_add_response_header(result, "DAV", "1"); + + int ret = MHD_queue_response(client_connection->connection, client_connection->code, result); + MHD_destroy_response(result); + return ret == MHD_YES; +} + +void TrustHttpServer::SetUrlHandler(const string &_url, jsonrpc::IClientConnectionHandler *_handler) +{ + this->m_urlhandler[_url] = _handler; + this->SetHandler(NULL); +} + +void TrustHttpServer::setGroup(const std::string& group) +{ + m_DfsNodeGroupId = group; +} + +void TrustHttpServer::setNode(const std::string& node) +{ + m_DfsNodeId = node; +} + +void TrustHttpServer::setStoragePath(const std::string& storage) +{ + m_DfsStoragePath = storage; +} + +int TrustHttpServer::callback(void *_cls, MHD_Connection *_connection, const char *_url, const char *_method, const char *_version, const char *_upload_data, size_t *_upload_data_size, void **_con_cls) +{ + (void)_version; + std::string account = ""; + string strUrl(_url); + string strMethod(_method); + + bool isFileProcess = DfsFileServer::getInstance()->filter(strUrl, strMethod) == 0; + //huanggaofeng: filter file process request + if (isFileProcess) + { + DfsHttpInfo objHttpInfo; + objHttpInfo.cls = _cls; + objHttpInfo.connection = _connection; + objHttpInfo.url = (char*)_url; + objHttpInfo.method = (char*)_method; + objHttpInfo.version = (char*)_version; + objHttpInfo.upload_data = (char*)_upload_data; + objHttpInfo.upload_data_size = _upload_data_size; + objHttpInfo.ptr = _con_cls; + int ret = DfsFileServer::getInstance()->handle(&objHttpInfo); + *_upload_data_size = 0; + return ret; + } + + //not file process http request + if (*_con_cls == NULL)//request first comes to here + { + struct mhd_coninfo* client_connection = new mhd_coninfo; + client_connection->connection = _connection; + client_connection->server = static_cast(_cls); + *_con_cls = client_connection; + + return MHD_YES; + } + struct mhd_coninfo* client_connection = static_cast(*_con_cls); + + if (string("POST") == _method) + { + if (*_upload_data_size != 0) + { + client_connection->request.write(_upload_data, *_upload_data_size); + *_upload_data_size = 0; + return MHD_YES; + } + else + { + string response; + jsonrpc::IClientConnectionHandler* handler = client_connection->server->GetHandler(string(_url)); + if (handler == NULL) + { + //debug print + LOG(TRACE) << "***** http get null handler *******"; + client_connection->code = MHD_HTTP_INTERNAL_SERVER_ERROR; + client_connection->server->SendResponse("No client conneciton handler found", client_connection); + } + else + { + //debug print + //LOG(TRACE) << "***** http get handler and response *******"; + client_connection->code = MHD_HTTP_OK; + handler->HandleRequest(client_connection->request.str(), response); + client_connection->server->SendResponse(response, client_connection); + } + } + } + else if (string("OPTIONS") == _method) { + //debug print + //LOG(TRACE) << "***** http option process ******"; + client_connection->code = MHD_HTTP_OK; + client_connection->server->SendOptionsResponse(client_connection); + } + else + { + //debug print + //LOG(TRACE) << "***** http else method: " << _method << " *******"; + client_connection->code = MHD_HTTP_METHOD_NOT_ALLOWED; + client_connection->server->SendResponse("Not allowed HTTP Method", client_connection); + } + delete client_connection; + *_con_cls = NULL; + + return MHD_YES; +} + + +bool SafeHttpServer::SendResponse(string const& _response, void* _addInfo) +{ + struct mhd_coninfo* client_connection = static_cast(_addInfo); + struct MHD_Response *result = MHD_create_response_from_buffer( + _response.size(), + static_cast(const_cast(_response.c_str())), + MHD_RESPMEM_MUST_COPY + ); + + MHD_add_response_header(result, "Content-Type", "application/json"); + MHD_add_response_header(result, "Access-Control-Allow-Origin", m_allowedOrigin.c_str()); + + int ret = MHD_queue_response(client_connection->connection, client_connection->code, result); + MHD_destroy_response(result); + return ret == MHD_YES; +} + +bool SafeHttpServer::SendOptionsResponse(void* _addInfo) +{ + struct mhd_coninfo* client_connection = static_cast(_addInfo); + struct MHD_Response *result = MHD_create_response_from_buffer(0, nullptr, MHD_RESPMEM_MUST_COPY); + + MHD_add_response_header(result, "Allow", "POST, OPTIONS"); + MHD_add_response_header(result, "Access-Control-Allow-Origin", m_allowedOrigin.c_str()); + MHD_add_response_header(result, "Access-Control-Allow-Headers", "origin, content-type, accept"); + MHD_add_response_header(result, "DAV", "1"); + + int ret = MHD_queue_response(client_connection->connection, client_connection->code, result); + MHD_destroy_response(result); + return ret == MHD_YES; +} diff --git a/libweb3jsonrpc/SafeHttpServer.h b/libweb3jsonrpc/SafeHttpServer.h new file mode 100644 index 0000000000..5f968c1e6e --- /dev/null +++ b/libweb3jsonrpc/SafeHttpServer.h @@ -0,0 +1,107 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file SafeHttpServer.h + * @authors: + * Marek + * @date 2015 + */ +#pragma once + +#include +#include +#include +#include +#include + +namespace dev +{ +/** + * This class provides an embedded HTTP Server, based on libmicrohttpd, to handle incoming Requests and send HTTP 1.1 + * valid responses. + * Note that this class will always send HTTP-Status 200, even though an JSON-RPC Error might have occurred. Please + * always check for the JSON-RPC Error Header. + */ +class TrustHttpServer: public jsonrpc::AbstractServerConnector +{ +public: + + /** + * @brief TrustHttpServer, constructor for the included TrustHttpServer + * @param port on which the server is listening + * @param enableSpecification - defines if the specification is returned in case of a GET request + * @param sslcert - defines the path to a SSL certificate, if this path is != "", then SSL/HTTPS is used with the given certificate. + */ + TrustHttpServer(eth::Client* _eth, int _port, const std::string& _sslrootca = "", const std::string& _sslcert = "", const std::string& _sslkey = "", int _threads = 50); + + virtual bool StartListening(); + virtual bool StopListening(); + + bool virtual SendResponse(std::string const& _response, void* _addInfo = NULL) ; + bool virtual SendOptionsResponse(void* _addInfo); + + void SetUrlHandler(const std::string &_url, jsonrpc::IClientConnectionHandler *_handler); + + void setGroup(const std::string& group); + void setNode(const std::string& node); + void setStoragePath(const std::string& storage); + +private: + int m_port; + int m_threads; + bool m_running; + std::string m_path_sslcert; + std::string m_path_sslkey; + std::string m_path_sslrootca; + std::string m_sslcert; + std::string m_sslkey; + std::string m_sslrootca; + eth::Client* m_eth; + + struct MHD_Daemon *daemon; + + std::map m_urlhandler; + + static int callback(void *_cls, struct MHD_Connection *_connection, const char *_url, const char *_method, const char *_version, const char *_upload_data, size_t *_upload_data_size, void **_con_cls); + + jsonrpc::IClientConnectionHandler* GetHandler(const std::string &_url); + +protected: + std::string m_DfsNodeGroupId; + std::string m_DfsNodeId; + std::string m_DfsStoragePath; + +}; + +class SafeHttpServer: public TrustHttpServer +{ +public: + /// "using HttpServer" won't work with msvc 2013, so we need to copy'n'paste constructor + SafeHttpServer(eth::Client* _eth, int _port, std::string const& _sslrootca = std::string(), std::string const& _sslcert = std::string(), std::string const& _sslkey = std::string(), int _threads = 50): + TrustHttpServer(_eth, _port, _sslrootca, _sslcert, _sslkey, _threads) {} + + /// override HttpServer implementation + bool virtual SendResponse(std::string const& _response, void* _addInfo = nullptr) override; + bool virtual SendOptionsResponse(void* _addInfo) override; + + void setAllowedOrigin(std::string const& _origin) { m_allowedOrigin = _origin; } + std::string const& allowedOrigin() const { return m_allowedOrigin; } + +private: + std::string m_allowedOrigin; +}; + +} diff --git a/libweb3jsonrpc/SessionManager.cpp b/libweb3jsonrpc/SessionManager.cpp new file mode 100644 index 0000000000..03bfd502dd --- /dev/null +++ b/libweb3jsonrpc/SessionManager.cpp @@ -0,0 +1,24 @@ +#include +#include "SessionManager.h" + +using namespace std; +using namespace dev; +using namespace dev::rpc; + +std::string SessionManager::newSession(SessionPermissions const& _p) +{ + std::string s = toBase64(h64::random().ref()); + m_sessions[s] = _p; + return s; +} + +void SessionManager::addSession(std::string const& _session, SessionPermissions const& _p) +{ + m_sessions[_session] = _p; +} + +bool SessionManager::hasPrivilegeLevel(std::string const& _session, Privilege _l) const +{ + auto it = m_sessions.find(_session); + return it != m_sessions.end() && it->second.privileges.count(_l); +} diff --git a/libweb3jsonrpc/SessionManager.h b/libweb3jsonrpc/SessionManager.h new file mode 100644 index 0000000000..16fadffac3 --- /dev/null +++ b/libweb3jsonrpc/SessionManager.h @@ -0,0 +1,50 @@ +#pragma once +#include +#include + +#define RPC_ADMIN if (!m_sm.hasPrivilegeLevel(_session, Privilege::Admin)) throw jsonrpc::JsonRpcException("Invalid privileges"); + +namespace dev +{ +namespace rpc +{ + +enum class Privilege +{ + Admin +}; + +} +} + +namespace std +{ + template<> struct hash + { + size_t operator()(dev::rpc::Privilege _value) const { return (size_t)_value; } + }; +} + +namespace dev +{ +namespace rpc +{ + +struct SessionPermissions +{ + std::unordered_set privileges; +}; + +class SessionManager +{ +public: + std::string newSession(SessionPermissions const& _p); + void addSession(std::string const& _session, SessionPermissions const& _p); + bool hasPrivilegeLevel(std::string const& _session, Privilege _l) const; + +private: + std::unordered_map m_sessions; +}; + +} +} diff --git a/libweb3jsonrpc/Test.cpp b/libweb3jsonrpc/Test.cpp new file mode 100644 index 0000000000..7f351aeb3a --- /dev/null +++ b/libweb3jsonrpc/Test.cpp @@ -0,0 +1,103 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Test.cpp + * @authors: + * Dimitry Khokhlov + * @date 2016 + */ + +#include "Test.h" +#include +#include +#include +#include + +using namespace std; +using namespace dev; +using namespace dev::rpc; +using namespace jsonrpc; + +Test::Test(eth::Client& _eth): m_eth(_eth) {} + +bool Test::test_setChainParams(Json::Value const& param1) +{ + try + { + Json::FastWriter fastWriter; + std::string output = fastWriter.write(param1); + asClientTest(m_eth).setChainParams(output); + } + catch (std::exception const&) + { + BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INTERNAL_ERROR)); + } + + return true; +} + +bool Test::test_mineBlocks(int _number) +{ + try + { + asClientTest(m_eth).mineBlocks(_number); + } + catch (std::exception const&) + { + BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INTERNAL_ERROR)); + } + + return true; +} + +bool Test::test_modifyTimestamp(int _timestamp) +{ + try + { + asClientTest(m_eth).modifyTimestamp(u256(_timestamp)); + } + catch (std::exception const&) + { + BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INTERNAL_ERROR)); + } + return true; +} + +bool Test::test_addBlock(std::string const& _rlp) +{ + try + { + asClientTest(m_eth).addBlock(_rlp); + } + catch (std::exception const&) + { + BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INTERNAL_ERROR)); + } + return true; +} + +bool Test::test_rewindToBlock(int _number) +{ + try + { + m_eth.rewind(_number); + } + catch (std::exception const&) + { + BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INTERNAL_ERROR)); + } + return true; +} diff --git a/libweb3jsonrpc/Test.h b/libweb3jsonrpc/Test.h new file mode 100644 index 0000000000..c841bf3d59 --- /dev/null +++ b/libweb3jsonrpc/Test.h @@ -0,0 +1,57 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Test.h + * @authors: + * Dimitry Khokhlov + * @date 2016 + */ + +#pragma once +#include "TestFace.h" + +namespace dev +{ + +namespace eth +{ +class Client; +} + +namespace rpc +{ + +class Test: public TestFace +{ +public: + Test(eth::Client& _eth); + virtual RPCModules implementedModules() const override + { + return RPCModules{RPCModule{"test", "1.0"}}; + } + + virtual bool test_setChainParams(const Json::Value ¶m1) override; + virtual bool test_mineBlocks(int _number) override; + virtual bool test_modifyTimestamp(int _timestamp) override; + virtual bool test_addBlock(std::string const& _rlp) override; + virtual bool test_rewindToBlock(int _number) override; + +private: + eth::Client& m_eth; +}; + +} +} diff --git a/libweb3jsonrpc/TestFace.h b/libweb3jsonrpc/TestFace.h new file mode 100644 index 0000000000..f6b3fd5f9c --- /dev/null +++ b/libweb3jsonrpc/TestFace.h @@ -0,0 +1,53 @@ +/** + * This file is generated by jsonrpcstub, DO NOT CHANGE IT MANUALLY! + */ + +#ifndef JSONRPC_CPP_STUB_DEV_RPC_TESTFACE_H_ +#define JSONRPC_CPP_STUB_DEV_RPC_TESTFACE_H_ + +#include "ModularServer.h" + +namespace dev { + namespace rpc { + class TestFace : public ServerInterface + { + public: + TestFace() + { + this->bindAndAddMethod(jsonrpc::Procedure("test_setChainParams", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_OBJECT, NULL), &dev::rpc::TestFace::test_setChainParamsI); + this->bindAndAddMethod(jsonrpc::Procedure("test_mineBlocks", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_INTEGER, NULL), &dev::rpc::TestFace::test_mineBlocksI); + this->bindAndAddMethod(jsonrpc::Procedure("test_modifyTimestamp", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_INTEGER, NULL), &dev::rpc::TestFace::test_modifyTimestampI); + this->bindAndAddMethod(jsonrpc::Procedure("test_addBlock", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING, NULL), &dev::rpc::TestFace::test_addBlockI); + this->bindAndAddMethod(jsonrpc::Procedure("test_rewindToBlock", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_INTEGER, NULL), &dev::rpc::TestFace::test_rewindToBlockI); + } + + inline virtual void test_setChainParamsI(const Json::Value &request, Json::Value &response) + { + response = this->test_setChainParams(request[0u]); + } + inline virtual void test_mineBlocksI(const Json::Value &request, Json::Value &response) + { + response = this->test_mineBlocks(request[0u].asInt()); + } + inline virtual void test_modifyTimestampI(const Json::Value &request, Json::Value &response) + { + response = this->test_modifyTimestamp(request[0u].asInt()); + } + inline virtual void test_addBlockI(const Json::Value &request, Json::Value &response) + { + response = this->test_addBlock(request[0u].asString()); + } + inline virtual void test_rewindToBlockI(const Json::Value &request, Json::Value &response) + { + response = this->test_rewindToBlock(request[0u].asInt()); + } + virtual bool test_setChainParams(const Json::Value& param1) = 0; + virtual bool test_mineBlocks(int param1) = 0; + virtual bool test_modifyTimestamp(int param1) = 0; + virtual bool test_addBlock(const std::string& param1) = 0; + virtual bool test_rewindToBlock(int param1) = 0; + }; + + } +} +#endif //JSONRPC_CPP_STUB_DEV_RPC_TESTFACE_H_ diff --git a/libweb3jsonrpc/UnixSocketServer.cpp b/libweb3jsonrpc/UnixSocketServer.cpp new file mode 100644 index 0000000000..3b5e37bd7c --- /dev/null +++ b/libweb3jsonrpc/UnixSocketServer.cpp @@ -0,0 +1,148 @@ +/* +This file is part of cpp-ethereum. + +cpp-ethereum is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +cpp-ethereum 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with cpp-ethereum. If not, see . +*/ +/** @file UnixSocketServer.cpp +* @authors: +* Arkadiy Paronyan +* @date 2015 +*/ +#if !defined(_WIN32) + +#include "UnixSocketServer.h" +#include +#include +#include +#include +#include +#include +#include +#include + +// "Mac OS X does not support the flag MSG_NOSIGNAL but we have an equivalent." +// See http://lists.apple.com/archives/macnetworkprog/2002/Dec/msg00091.html +#if defined(__APPLE__) + #if !defined(MSG_NOSIGNAL) + #define MSG_NOSIGNAL SO_NOSIGPIPE + #endif +#endif + +using namespace std; +using namespace jsonrpc; +using namespace dev; + +int const c_pathMaxSize = sizeof(sockaddr_un::sun_path)/sizeof(sockaddr_un::sun_path[0]); + +string ipcSocketPath() +{ +#ifdef __APPLE__ + // A bit hacky, but backwards compatible: If we did not change the default data dir, + // put the socket in ~/Library/Ethereum, otherwise in the set data dir. + string path = getIpcPath(); + if (path == getDefaultDataDir()) + return getenv("HOME") + string("/Library/Ethereum"); + else + return path; +#else + return getIpcPath(); +#endif +} + +UnixDomainSocketServer::UnixDomainSocketServer(string const& _appId): + IpcServerBase(string(getIpcPath() + "/" + _appId + ".ipc").substr(0, c_pathMaxSize)) +{ +} + +UnixDomainSocketServer::~UnixDomainSocketServer() +{ + StopListening(); +} + +bool UnixDomainSocketServer::StartListening() +{ + if (!m_running) + { + if (access(m_path.c_str(), F_OK) != -1) + unlink(m_path.c_str()); + + if (access(m_path.c_str(), F_OK) != -1) + return false; + + m_socket = socket(PF_UNIX, SOCK_STREAM, 0); + memset(&(m_address), 0, sizeof(sockaddr_un)); + m_address.sun_family = AF_UNIX; +#ifdef __APPLE__ + m_address.sun_len = m_path.size() + 1; +#endif + strncpy(m_address.sun_path, m_path.c_str(), c_pathMaxSize); + ::bind(m_socket, reinterpret_cast(&m_address), sizeof(sockaddr_un)); + listen(m_socket, 128); + } + return IpcServerBase::StartListening(); +} + +bool UnixDomainSocketServer::StopListening() +{ + shutdown(m_socket, SHUT_RDWR); + close(m_socket); + m_socket = -1; + if (IpcServerBase::StopListening()) + { + unlink(m_path.c_str()); + return true; + } + return false; +} + +void UnixDomainSocketServer::Listen() +{ + socklen_t addressLen = sizeof(m_address); + while (m_running) + { + int connection = accept(m_socket, (sockaddr*) &(m_address), &addressLen); + if (connection > 0) + { + DEV_GUARDED(x_sockets) + m_sockets.insert(connection); + + std::thread handler([this, connection](){ GenerateResponse(connection); }); + handler.detach(); + } + } +} + +void UnixDomainSocketServer::CloseConnection(int _socket) +{ + close(_socket); +} + + +size_t UnixDomainSocketServer::Write(int _connection, string const& _data) +{ + int r = send(_connection, _data.data(), _data.size(), MSG_NOSIGNAL); + if (r > 0) + return r; + return 0; +} + +size_t UnixDomainSocketServer::Read(int _connection, void* _data, size_t _size) +{ + int r = read(_connection, _data, _size); + if (r > 0) + return r; + return 0; +} + +#endif diff --git a/libweb3jsonrpc/UnixSocketServer.h b/libweb3jsonrpc/UnixSocketServer.h new file mode 100644 index 0000000000..44981ddac2 --- /dev/null +++ b/libweb3jsonrpc/UnixSocketServer.h @@ -0,0 +1,53 @@ +/* +This file is part of cpp-ethereum. + +cpp-ethereum is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +cpp-ethereum 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with cpp-ethereum. If not, see . +*/ +/** @file UnixSocketServer.h +* @authors: +* Arkadiy Paronyan +* @date 2015 +*/ +#pragma once + +#if !defined(_WIN32) + +#include +#include +#include +#include "IpcServerBase.h" + +namespace dev +{ +class UnixDomainSocketServer: public IpcServerBase +{ +public: + UnixDomainSocketServer(std::string const& _appId); + ~UnixDomainSocketServer(); + bool StartListening() override; + bool StopListening() override; + +protected: + void Listen() override; + void CloseConnection(int _socket) override; + size_t Write(int _connection, std::string const& _data) override; + size_t Read(int _connection, void* _data, size_t _size) override; + + sockaddr_un m_address; + int m_socket = 0; +}; + +} // namespace dev + +#endif diff --git a/libweb3jsonrpc/Web3.cpp b/libweb3jsonrpc/Web3.cpp new file mode 100644 index 0000000000..2af5fe9649 --- /dev/null +++ b/libweb3jsonrpc/Web3.cpp @@ -0,0 +1,11 @@ +#include +#include +#include "Web3.h" + +using namespace std; +using namespace dev; + +std::string rpc::Web3::web3_sha3(std::string const& _param1) +{ + return toJS(sha3(jsToBytes(_param1))); +} \ No newline at end of file diff --git a/libweb3jsonrpc/Web3.h b/libweb3jsonrpc/Web3.h new file mode 100644 index 0000000000..c0ca2df22b --- /dev/null +++ b/libweb3jsonrpc/Web3.h @@ -0,0 +1,25 @@ +#pragma once +#include "Web3Face.h" + +namespace dev +{ +namespace rpc +{ + +class Web3: public Web3Face +{ +public: + Web3(std::string _clientVersion = "C++ (ethereum-cpp)"): m_clientVersion(_clientVersion) {} + virtual RPCModules implementedModules() const override + { + return RPCModules{RPCModule{"web3", "1.0"}}; + } + virtual std::string web3_sha3(std::string const& _param1) override; + virtual std::string web3_clientVersion() override { return m_clientVersion; } + +private: + std::string m_clientVersion; +}; + +} +} diff --git a/libweb3jsonrpc/Web3Face.h b/libweb3jsonrpc/Web3Face.h new file mode 100644 index 0000000000..a374df3699 --- /dev/null +++ b/libweb3jsonrpc/Web3Face.h @@ -0,0 +1,36 @@ +/** + * This file is generated by jsonrpcstub, DO NOT CHANGE IT MANUALLY! + */ + +#ifndef JSONRPC_CPP_STUB_DEV_RPC_WEB3FACE_H_ +#define JSONRPC_CPP_STUB_DEV_RPC_WEB3FACE_H_ + +#include "ModularServer.h" + +namespace dev { + namespace rpc { + class Web3Face : public ServerInterface + { + public: + Web3Face() + { + this->bindAndAddMethod(jsonrpc::Procedure("web3_sha3", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &dev::rpc::Web3Face::web3_sha3I); + this->bindAndAddMethod(jsonrpc::Procedure("web3_clientVersion", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, NULL), &dev::rpc::Web3Face::web3_clientVersionI); + } + + inline virtual void web3_sha3I(const Json::Value &request, Json::Value &response) + { + response = this->web3_sha3(request[0u].asString()); + } + inline virtual void web3_clientVersionI(const Json::Value &request, Json::Value &response) + { + (void)request; + response = this->web3_clientVersion(); + } + virtual std::string web3_sha3(const std::string& param1) = 0; + virtual std::string web3_clientVersion() = 0; + }; + + } +} +#endif //JSONRPC_CPP_STUB_DEV_RPC_WEB3FACE_H_ diff --git a/libweb3jsonrpc/Whisper.cpp b/libweb3jsonrpc/Whisper.cpp new file mode 100644 index 0000000000..b9a75740ca --- /dev/null +++ b/libweb3jsonrpc/Whisper.cpp @@ -0,0 +1,202 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Whisper.cpp + * @authors: + * Gav Wood + * Marek Kotewicz + * @date 2015 + */ + +#include +#include +#include +#include +#include +#include +#include "Whisper.h" +#include "JsonHelper.h" + +using namespace std; +using namespace jsonrpc; +using namespace dev; +using namespace dev::rpc; + + +Whisper::Whisper(WebThreeDirect& _web3, std::vector const& _accounts): m_web3(_web3) +{ + setIdentities(_accounts); +} + +void Whisper::setIdentities(std::vector const& _ids) +{ + m_ids.clear(); + for (auto i: _ids) + m_ids[i.pub()] = i.secret(); +} + +shh::Interface* Whisper::shh() const +{ + return m_web3.whisper().get(); +} + +bool Whisper::shh_post(Json::Value const& _json) +{ + try + { + shh::Message m = shh::toMessage(_json); + Secret from; + if (m.from() && m_ids.count(m.from())) + { + LOG(WARNING) << "Silently signing message from identity" << m.from() << ": User validation hook goes here."; + // TODO: insert validification hook here. + from = m_ids[m.from()]; + } + + shh()->inject(toSealed(_json, m, from)); + return true; + } + catch (...) + { + BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); + } +} + +std::string Whisper::shh_newIdentity() +{ + KeyPair kp = KeyPair::create(); + m_ids[kp.pub()] = kp.secret(); + return toJS(kp.pub()); +} + +bool Whisper::shh_hasIdentity(std::string const& _identity) +{ + try + { + return m_ids.count(jsToPublic(_identity)) > 0; + } + catch (...) + { + BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); + } +} + +std::string Whisper::shh_newGroup(std::string const& _id, std::string const& _who) +{ + (void)_id; + (void)_who; + return ""; +} + +std::string Whisper::shh_addToGroup(std::string const& _group, std::string const& _who) +{ + (void)_group; + (void)_who; + return ""; +} + +std::string Whisper::shh_newFilter(Json::Value const& _json) +{ + try + { + pair w = shh::toWatch(_json); + auto ret = shh()->installWatch(w.first); + m_watches.insert(make_pair(ret, w.second)); + return toJS(ret); + } + catch (...) + { + BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); + } +} + +bool Whisper::shh_uninstallFilter(std::string const& _filterId) +{ + try + { + shh()->uninstallWatch(jsToInt(_filterId)); + return true; + } + catch (...) + { + BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); + } +} + +Json::Value Whisper::shh_getFilterChanges(std::string const& _filterId) +{ + try + { + Json::Value ret(Json::arrayValue); + + int id = jsToInt(_filterId); + auto pub = m_watches[id]; + if (!pub || m_ids.count(pub)) + for (h256 const& h: shh()->checkWatch(id)) + { + auto e = shh()->envelope(h); + shh::Message m; + if (pub) + { + LOG(WARNING) << "Silently decrypting message from identity" << pub << ": User validation hook goes here."; + m = e.open(shh()->fullTopics(id), m_ids[pub]); + } + else + m = e.open(shh()->fullTopics(id)); + if (!m) + continue; + ret.append(toJson(h, e, m)); + } + + return ret; + } + catch (...) + { + BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); + } +} + +Json::Value Whisper::shh_getMessages(std::string const& _filterId) +{ + try + { + Json::Value ret(Json::arrayValue); + + int id = jsToInt(_filterId); + auto pub = m_watches[id]; + if (!pub || m_ids.count(pub)) + for (h256 const& h: shh()->watchMessages(id)) + { + auto e = shh()->envelope(h); + shh::Message m; + if (pub) + { + LOG(WARNING) << "Silently decrypting message from identity" << pub << ": User validation hook goes here."; + m = e.open(shh()->fullTopics(id), m_ids[pub]); + } + else + m = e.open(shh()->fullTopics(id)); + if (!m) + continue; + ret.append(toJson(h, e, m)); + } + return ret; + } + catch (...) + { + BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); + } +} diff --git a/libweb3jsonrpc/Whisper.h b/libweb3jsonrpc/Whisper.h new file mode 100644 index 0000000000..a00cb9b4d1 --- /dev/null +++ b/libweb3jsonrpc/Whisper.h @@ -0,0 +1,73 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Whisper.h + * @authors: + * Gav Wood + * Marek Kotewicz + * @date 2015 + */ + +#pragma once +#include +#include "WhisperFace.h" + +namespace dev +{ + +class WebThreeDirect; + +namespace shh +{ +class Interface; +} + +namespace rpc +{ + +class Whisper: public WhisperFace +{ +public: + // TODO: init with whisper interface instead of webthreedirect + Whisper(WebThreeDirect& _web3, std::vector const& _accounts); + virtual RPCModules implementedModules() const override + { + return RPCModules{RPCModule{"shh", "1.0"}}; + } + + virtual void setIdentities(std::vector const& _ids); + std::map const& ids() const { return m_ids; } + + virtual bool shh_post(Json::Value const& _json) override; + virtual std::string shh_newIdentity() override; + virtual bool shh_hasIdentity(std::string const& _identity) override; + virtual std::string shh_newGroup(std::string const& _id, std::string const& _who) override; + virtual std::string shh_addToGroup(std::string const& _group, std::string const& _who) override; + virtual std::string shh_newFilter(Json::Value const& _json) override; + virtual bool shh_uninstallFilter(std::string const& _filterId) override; + virtual Json::Value shh_getFilterChanges(std::string const& _filterId) override; + virtual Json::Value shh_getMessages(std::string const& _filterId) override; + +private: + shh::Interface* shh() const; + + WebThreeDirect& m_web3; + std::map m_ids; + std::map m_watches; +}; + +} +} diff --git a/libweb3jsonrpc/WhisperFace.h b/libweb3jsonrpc/WhisperFace.h new file mode 100644 index 0000000000..3a46a35af3 --- /dev/null +++ b/libweb3jsonrpc/WhisperFace.h @@ -0,0 +1,78 @@ +/** + * This file is generated by jsonrpcstub, DO NOT CHANGE IT MANUALLY! + */ + +#ifndef JSONRPC_CPP_STUB_DEV_RPC_WHISPERFACE_H_ +#define JSONRPC_CPP_STUB_DEV_RPC_WHISPERFACE_H_ + +#include "ModularServer.h" + +namespace dev { + namespace rpc { + class WhisperFace : public ServerInterface + { + public: + WhisperFace() + { + this->bindAndAddMethod(jsonrpc::Procedure("shh_post", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_OBJECT, NULL), &dev::rpc::WhisperFace::shh_postI); + this->bindAndAddMethod(jsonrpc::Procedure("shh_newIdentity", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, NULL), &dev::rpc::WhisperFace::shh_newIdentityI); + this->bindAndAddMethod(jsonrpc::Procedure("shh_hasIdentity", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING, NULL), &dev::rpc::WhisperFace::shh_hasIdentityI); + this->bindAndAddMethod(jsonrpc::Procedure("shh_newGroup", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &dev::rpc::WhisperFace::shh_newGroupI); + this->bindAndAddMethod(jsonrpc::Procedure("shh_addToGroup", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &dev::rpc::WhisperFace::shh_addToGroupI); + this->bindAndAddMethod(jsonrpc::Procedure("shh_newFilter", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_OBJECT, NULL), &dev::rpc::WhisperFace::shh_newFilterI); + this->bindAndAddMethod(jsonrpc::Procedure("shh_uninstallFilter", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING, NULL), &dev::rpc::WhisperFace::shh_uninstallFilterI); + this->bindAndAddMethod(jsonrpc::Procedure("shh_getFilterChanges", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, "param1",jsonrpc::JSON_STRING, NULL), &dev::rpc::WhisperFace::shh_getFilterChangesI); + this->bindAndAddMethod(jsonrpc::Procedure("shh_getMessages", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, "param1",jsonrpc::JSON_STRING, NULL), &dev::rpc::WhisperFace::shh_getMessagesI); + } + + inline virtual void shh_postI(const Json::Value &request, Json::Value &response) + { + response = this->shh_post(request[0u]); + } + inline virtual void shh_newIdentityI(const Json::Value &request, Json::Value &response) + { + (void)request; + response = this->shh_newIdentity(); + } + inline virtual void shh_hasIdentityI(const Json::Value &request, Json::Value &response) + { + response = this->shh_hasIdentity(request[0u].asString()); + } + inline virtual void shh_newGroupI(const Json::Value &request, Json::Value &response) + { + response = this->shh_newGroup(request[0u].asString(), request[1u].asString()); + } + inline virtual void shh_addToGroupI(const Json::Value &request, Json::Value &response) + { + response = this->shh_addToGroup(request[0u].asString(), request[1u].asString()); + } + inline virtual void shh_newFilterI(const Json::Value &request, Json::Value &response) + { + response = this->shh_newFilter(request[0u]); + } + inline virtual void shh_uninstallFilterI(const Json::Value &request, Json::Value &response) + { + response = this->shh_uninstallFilter(request[0u].asString()); + } + inline virtual void shh_getFilterChangesI(const Json::Value &request, Json::Value &response) + { + response = this->shh_getFilterChanges(request[0u].asString()); + } + inline virtual void shh_getMessagesI(const Json::Value &request, Json::Value &response) + { + response = this->shh_getMessages(request[0u].asString()); + } + virtual bool shh_post(const Json::Value& param1) = 0; + virtual std::string shh_newIdentity() = 0; + virtual bool shh_hasIdentity(const std::string& param1) = 0; + virtual std::string shh_newGroup(const std::string& param1, const std::string& param2) = 0; + virtual std::string shh_addToGroup(const std::string& param1, const std::string& param2) = 0; + virtual std::string shh_newFilter(const Json::Value& param1) = 0; + virtual bool shh_uninstallFilter(const std::string& param1) = 0; + virtual Json::Value shh_getFilterChanges(const std::string& param1) = 0; + virtual Json::Value shh_getMessages(const std::string& param1) = 0; + }; + + } +} +#endif //JSONRPC_CPP_STUB_DEV_RPC_WHISPERFACE_H_ diff --git a/libweb3jsonrpc/WinPipeServer.cpp b/libweb3jsonrpc/WinPipeServer.cpp new file mode 100644 index 0000000000..3156e98ae7 --- /dev/null +++ b/libweb3jsonrpc/WinPipeServer.cpp @@ -0,0 +1,89 @@ +/* +This file is part of cpp-ethereum. + +cpp-ethereum is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +cpp-ethereum 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with cpp-ethereum. If not, see . +*/ +/** @file WinPipeServer.cpp +* @authors: +* Arkadiy Paronyan +* @date 2015 +*/ +#if defined(_WIN32) + +#include "WinPipeServer.h" +#include +#include + +using namespace std; +using namespace jsonrpc; +using namespace dev; + +int const c_bufferSize = 1024; + +WindowsPipeServer::WindowsPipeServer(string const& _appId): + IpcServerBase("\\\\.\\pipe\\" + _appId + ".ipc") +{ +} + +void WindowsPipeServer::CloseConnection(HANDLE _socket) +{ + ::CloseHandle(_socket); +} + +size_t WindowsPipeServer::Write(HANDLE _connection, std::string const& _data) +{ + DWORD written = 0; + ::WriteFile(_connection, _data.data(), _data.size(), &written , nullptr); + return written; +} + +size_t WindowsPipeServer::Read(HANDLE _connection, void* _data, size_t _size) +{ + DWORD read; + ::ReadFile(_connection, _data, _size, &read, nullptr); + return read; +} + +void WindowsPipeServer::Listen() +{ + while (m_running) + { + HANDLE socket = CreateNamedPipe( + m_path.c_str(), + PIPE_ACCESS_DUPLEX, + PIPE_READMODE_BYTE | + PIPE_WAIT, + PIPE_UNLIMITED_INSTANCES, + c_bufferSize, + c_bufferSize, + 0, + nullptr); + + DEV_GUARDED(x_sockets) + m_sockets.insert(socket); + + if (ConnectNamedPipe(socket, nullptr) != 0) + { + std::thread handler([this, socket](){ GenerateResponse(socket); }); + handler.detach(); + } + else + { + DEV_GUARDED(x_sockets) + m_sockets.erase(socket); + } + } +} + +#endif \ No newline at end of file diff --git a/libweb3jsonrpc/WinPipeServer.h b/libweb3jsonrpc/WinPipeServer.h new file mode 100644 index 0000000000..f148bda1d2 --- /dev/null +++ b/libweb3jsonrpc/WinPipeServer.h @@ -0,0 +1,49 @@ +/* +This file is part of cpp-ethereum. + +cpp-ethereum is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +cpp-ethereum 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with cpp-ethereum. If not, see . +*/ +/** @file WinPipeServer.h +* @authors: +* Arkadiy Paronyan +* @date 2015 +*/ +#pragma once + +#if defined(_WIN32) + +#include +#include +#include +#include +#include +#include "IpcServerBase.h" + +namespace dev +{ +class WindowsPipeServer: public IpcServerBase +{ +public: + WindowsPipeServer(std::string const& _appId); + +protected: + void Listen() override; + void CloseConnection(HANDLE _socket) override; + size_t Write(HANDLE _connection, std::string const& _data) override; + size_t Read(HANDLE _connection, void* _data, size_t _size) override; +}; + +} // namespace dev + +#endif \ No newline at end of file diff --git a/libweb3jsonrpc/admin_eth.json b/libweb3jsonrpc/admin_eth.json new file mode 100644 index 0000000000..1522fdbade --- /dev/null +++ b/libweb3jsonrpc/admin_eth.json @@ -0,0 +1,22 @@ +[ +{ "name": "admin_eth_blockQueueStatus", "params": [""], "returns": {}}, +{ "name": "admin_eth_setAskPrice", "params": ["", ""], "returns": true }, +{ "name": "admin_eth_setBidPrice", "params": ["", ""], "returns": true }, +{ "name": "admin_eth_setMining", "params": [true, ""], "returns": true }, +{ "name": "admin_eth_findBlock", "params": ["", ""], "returns": {} }, +{ "name": "admin_eth_blockQueueFirstUnknown", "params": [""], "returns": "" }, +{ "name": "admin_eth_blockQueueRetryUnknown", "params": [""], "returns": true }, +{ "name": "admin_eth_allAccounts", "params": [""], "returns": [] }, +{ "name": "admin_eth_newAccount", "params": [{}, ""], "returns": {} }, +{ "name": "admin_eth_setMiningBenefactor", "params": ["", ""], "returns": true }, +{ "name": "admin_eth_inspect", "params": ["", ""], "returns": {} }, +{ "name": "admin_eth_reprocess", "params": ["", ""], "returns": {} }, +{ "name": "admin_eth_vmTrace", "params": ["", 0, ""], "returns": {} }, +{ "name": "admin_eth_getReceiptByHashAndIndex", "params": ["", 0, ""], "returns": {} }, +{ "name": "miner_start", "params": [0], "returns": true }, +{ "name": "miner_stop", "params": [], "returns": true }, +{ "name": "miner_setEtherbase", "params": [""], "returns": true }, +{ "name": "miner_setExtra", "params": [""], "returns": true }, +{ "name": "miner_setGasPrice", "params": [""], "returns": true }, +{ "name": "miner_hashrate", "params": [], "returns": "" } +] diff --git a/libweb3jsonrpc/admin_net.json b/libweb3jsonrpc/admin_net.json new file mode 100644 index 0000000000..ae437517cb --- /dev/null +++ b/libweb3jsonrpc/admin_net.json @@ -0,0 +1,10 @@ +[ +{ "name": "admin_net_start", "params": [""], "returns": true }, +{ "name": "admin_net_stop", "params": [""], "returns": true }, +{ "name": "admin_net_connect", "params": ["", ""], "returns": true }, +{ "name": "admin_net_peers", "params": [""], "returns": [] }, +{ "name": "admin_net_nodeInfo", "params": [""], "returns": {}}, +{ "name": "admin_nodeInfo", "params": [], "returns": {}}, +{ "name": "admin_peers", "params": [], "returns": {}}, +{ "name": "admin_addPeer", "params": [""], "returns": true} +] diff --git a/libweb3jsonrpc/admin_utils.json b/libweb3jsonrpc/admin_utils.json new file mode 100644 index 0000000000..8b7d22e008 --- /dev/null +++ b/libweb3jsonrpc/admin_utils.json @@ -0,0 +1,5 @@ +[ +{ "name": "admin_setVerbosity", "params": [0, ""], "returns": true }, +{ "name": "admin_verbosity", "params": [0], "returns": true }, +{ "name": "admin_exit", "params": [""], "returns": true} +] diff --git a/libweb3jsonrpc/bzz.json b/libweb3jsonrpc/bzz.json new file mode 100644 index 0000000000..114c626c62 --- /dev/null +++ b/libweb3jsonrpc/bzz.json @@ -0,0 +1,4 @@ +[ +{ "name": "bzz_put", "params": [""], "returns": ""}, +{ "name": "bzz_get", "params": [""], "returns": ""} +] diff --git a/libweb3jsonrpc/db.json b/libweb3jsonrpc/db.json new file mode 100644 index 0000000000..7e6dfca8cd --- /dev/null +++ b/libweb3jsonrpc/db.json @@ -0,0 +1,4 @@ +[ +{ "name": "db_put", "params": ["", "", ""], "order": [], "returns": true}, +{ "name": "db_get", "params": ["", ""], "order": [], "returns": ""} +] diff --git a/libweb3jsonrpc/debug.json b/libweb3jsonrpc/debug.json new file mode 100644 index 0000000000..3c78fb9fd3 --- /dev/null +++ b/libweb3jsonrpc/debug.json @@ -0,0 +1,8 @@ +[ +{ "name": "debug_traceTransaction", "params": ["", {}], "returns": {}}, +{ "name": "debug_storageRangeAt", "params": ["", 0, "", "", 0], "returns": {}}, +{ "name": "debug_preimage", "params": [""], "returns": ""}, +{ "name": "debug_traceBlockByNumber", "params": [0, {}], "returns": {}}, +{ "name": "debug_traceBlockByHash", "params": ["", {}], "returns": {}}, +{ "name": "debug_traceCall", "params": [{}, "", {}], "returns": {}} +] diff --git a/libweb3jsonrpc/dfs/DfsBase.h b/libweb3jsonrpc/dfs/DfsBase.h new file mode 100644 index 0000000000..7165db5ad5 --- /dev/null +++ b/libweb3jsonrpc/dfs/DfsBase.h @@ -0,0 +1,133 @@ +#pragma once + +#include +#include +#include "microhttpd.h" +#include + +#define dfs_debug (LOG(DEBUG)) +#define dfs_warn (LOG(ERROR)) +#define dfs_trace (LOG(TRACE)) +#define dfs_error (LOG(ERROR)) + + +using std::string; + +namespace dev +{ + +namespace rpc +{ + +namespace fs +{ + +typedef struct DfsHttpInfo +{ + void *cls; + struct MHD_Connection *connection; + char *url; + char *method; + char *version; + char *upload_data; + size_t *upload_data_size; + void **ptr; +} DfsHttpInfo; + +typedef struct DfsUrlInfo { + string method; + string module;//must be "fs" now + string version; + string container_id; + string file_id; +} DfsUrlInfo; + +typedef struct DfsFileInfo { + string id; + string container; + string filename; + string filehash; + string owner; + string src_node;//server node id + string node_group; + int Type; + string priviliges; + string info; + int store_flag; + + DfsFileInfo() : \ + id(""),container(""),filename(""),filehash(""),\ + owner(""),src_node(""),node_group(""),\ + Type(0),priviliges(""),info(""),store_flag(0) + {}; + +} DfsFileInfo; + + +typedef struct DfsFileTask { + enum TaskOperation + { + UPLOAD_START = 0, + UPLOAD = 1, + DELETE = 2, + MODIFY = 3, + DOWNLOAD_START = 4, + DOWNLOAD = 5, + DOWNLOAD_FAIL = 6 + }; + + string id; + string container; + string filename; + string filehash; + string owner; + string src_node;//server node id + string node_group; + string host; + int port; + string directory; + int operation;//TaskOperation +} DfsFileTask; + +typedef struct DfsDownRecord { + string id; + string container; + string filename; + string directory; + string src_node;//server node id + string node_group; +} DfsDownRecord; + +typedef struct DfsConnectionInfo +{ + struct MHD_PostProcessor *postprocessor; + string method; + string version; + FILE *fp; + string fp_path; + int recv_bytes; + string file_id; + string filename; + string container; + + char *data; + int length; + + DfsConnectionInfo(){ + postprocessor = NULL; + method = ""; + version = ""; + fp = NULL; + fp_path = ""; + recv_bytes = 0; + file_id = ""; + filename = ""; + container = ""; + data = NULL; + length = 0; + }; +} DfsConnectionInfo; + +} +} +} \ No newline at end of file diff --git a/libweb3jsonrpc/dfs/DfsCommon.cpp b/libweb3jsonrpc/dfs/DfsCommon.cpp new file mode 100644 index 0000000000..bf69cc799e --- /dev/null +++ b/libweb3jsonrpc/dfs/DfsCommon.cpp @@ -0,0 +1,257 @@ +/** +* @Filename DfsCommon.cpp +* @Author huanggaofeng +* @Date 2017-01-31 +* @brief utils functions +*/ + +#include "DfsCommon.h" +#include "DfsBase.h" + +#include +#include +#include +#include +#include +#include +#include "DfsMd5.h" + + +using namespace dev::rpc::fs; + + +namespace dev +{ + +namespace rpc +{ + +namespace fs +{ + + +/// check if the specific directory exists +bool ChkDirExists(const string &pm_sDir) +{ + struct stat stDir; + + if (stat(pm_sDir.c_str(), &stDir) != 0) + { + return false; + } + + return S_ISDIR(stDir.st_mode); +} + +/// check if the specific directory has write permission +bool ChkDirWritePerm(const string &pm_sDir) +{ + return (0 == access(pm_sDir.data(), W_OK)); +} + +/// check if the specific file exists +bool ChkFileExists(const string &pm_sFile) +{ + struct stat stFile; + + if (stat(pm_sFile.c_str(), &stFile) != 0) + { + return false; + } + + return S_ISREG(stFile.st_mode); +} + +/// get the file size +long GetFileSize(const string &pm_sFile) +{ + struct stat stFile; + + if (stat(pm_sFile.c_str(), &stFile) != 0) + { + return -1; + } + + return stFile.st_size; +} + +/// simple copy file function +int FileCpy(const string &pm_sSrc, const string &pm_sDest) +{ + FILE* fp = NULL; + FILE* fp_dst = NULL; + fp = fopen(pm_sSrc.c_str(), "rb"); + if (fp == NULL) + { + return -1; + } + + fp_dst = fopen(pm_sDest.c_str(), "wb"); + char szBuffer[4096]; + size_t bytes = 0; + size_t bytes_write = 0; + size_t bytes_read = 0; + while((bytes=fread(szBuffer, 1, 4096, fp)) > 0) { + bytes_read += bytes; + int ret = fwrite(szBuffer, 1, bytes, fp_dst); + if (ret) + { + bytes_write += ret; + } + } + + fclose(fp); + fclose(fp_dst); + if (bytes_write != bytes_read) + { + return -1; + } + + return 0; +} + +/// simply move file function +int FileMv(const string &pm_sSrc, const string &pm_sDest) +{ + if (rename(pm_sSrc.c_str(), pm_sDest.c_str()) != 0) + { + return -1; + } + + return 0; +} + +/// remove a file +int FileRm(const string &pm_sFileName) +{ + if (unlink(pm_sFileName.c_str()) != 0) + { + return -1; + } + + return 0; +} + +// create a specific directory +bool createFileDir(const string &dirPath) +{ + if (dirPath.size() <= 0) + return false; + + if (0 != mkdir(dirPath.c_str(), 0755)) + return false; + + return true; +} + +//get the date string with the pattern: YYYYMMDD_HHMMSS +string currentTimestamp() +{ + struct timeval objTime; + gettimeofday(&objTime, NULL); + + char szTime[256]; + memset(szTime, 0, 256); + snprintf(szTime, 256, "%ld", objTime.tv_sec); + + return szTime; +} + +void createDfsFileNames(const string& path, const string &fileID, const string &fileName, string &filename, string &filename_bak) +{ + filename = path; + filename += "/"; + filename += fileID; + filename += "_"; + filename += fileName; + + filename_bak = filename; + filename_bak += "_"; + filename_bak += currentTimestamp(); + //strFileBak += ".bak"; +} + +void listAllFiles(const std::string &dirPath, vector &files, bool fullPath) +{ + if (!ChkDirExists(dirPath)) + { + return; + } + + files.clear(); + DIR *d; + struct dirent *dir; + d = opendir(dirPath.data()); + if (d) + { + while ((dir = readdir(d)) != NULL) + { + if (strcmp(dir->d_name, ".") == 0 || strcmp(dir->d_name, "..") == 0) + { + continue; + } + + if (!fullPath) + { + files.push_back(dir->d_name); + } + else + { + string strFile = dirPath; + strFile += "/"; + strFile += dir->d_name; + files.push_back(strFile); + } + } + + closedir(d); + } + + return; +} + + +void SplitString(const string &pm_sExpression, char pm_cDelimiter, vector &pm_vecArray) +{ + size_t iPosBegin = 0; + size_t iPosEnd; + while ((iPosEnd = pm_sExpression.find(pm_cDelimiter, iPosBegin)) != string::npos) + { + pm_vecArray.push_back(pm_sExpression.substr(iPosBegin, iPosEnd - iPosBegin)); + iPosBegin = iPosEnd + 1; + } + pm_vecArray.push_back(pm_sExpression.substr(iPosBegin)); +} + +// create the directory path by container +void createDirectoryByContainer(const string& base, const string &container, string &directory) +{ + directory.clear(); + if (container.empty()) + { + dfs_warn << "the container is null \n"; + return; + } + + MD5_CTX ctx; + unsigned char szResult[16] = {0}; + memset(szResult, 0, 16); + ms_MD5_Init(&ctx); + ms_MD5_Update(&ctx, container.data(), container.size()); + ms_MD5_Final(szResult, &ctx); + unsigned char lowPart = szResult[0]; + unsigned char hignPart = szResult[8]; + + char szDirAppend[256] = {0}; + memset(szDirAppend, 0, 256); + snprintf(szDirAppend, 256, "%02X/%02X/%s", lowPart, hignPart, container.data()); + + directory = base; + directory += "/"; + directory += szDirAppend; +} + +} +} +} + diff --git a/libweb3jsonrpc/dfs/DfsCommon.h b/libweb3jsonrpc/dfs/DfsCommon.h new file mode 100644 index 0000000000..341c5eb10e --- /dev/null +++ b/libweb3jsonrpc/dfs/DfsCommon.h @@ -0,0 +1,160 @@ +/** +* @Filename Common.h +* @Date 2017-01-31 +* @brief utils functions +*/ +#pragma once + +#ifndef _COMMON_H +#define _COMMON_H + +#include +#include + +using std::string; +using std::vector; + + +#ifdef DEBUG + #define DBMSG(x) x +#else + #define DBMSG(x) +#endif + + +// RET +const int RET_RANGE = -2; +const int RET_SYN = -3; + +const int DB_RETRY_TIME = 3; + +/// CODE +const int DB_SUCCESS = 0; +const int DB_CONNECT_ERR = -1000; +const int ATTACH_CONN_ERR = -1001; +const int DB_NO_RECORD = -1002; +const int RET_DB_ERR = -1003; + +//// ERROR +const int DEFAULT_CODE = 0; +const int CFGFILE_ERR = -1; +const int DBPASS_ERR = -2; +const int APP_ERR = -3; +const int INPUT_PARAM_ERR = -4; +const int RET_DATA_ERR = -5; +const int RET_ABORT = -6; +const int IO_ERR = -7; +const int TIME_ERR = -8; +const int FILE_DUP = -9; + +namespace dev +{ + +namespace rpc +{ + +namespace fs +{ + +/** + *@brief check if the directory exists + *@param pm_sDir Ŀ¼ + *@return true/false + */ +bool ChkDirExists(const string &pm_sDir); + +/** + *@brief check if write is allowed with the the directory + *@param pm_sDir Ŀ¼ + *@return true/false + */ +bool ChkDirWritePerm(const string &pm_sDir); + +/** + *@brief check if the specific file exists + *@param pm_sFile the file + *@return true/false + */ +bool ChkFileExists(const string &pm_sFile); + +/** + *@brief get the content size of a file + *@param pm_sFile the file + *@return the size of a file + */ +long GetFileSize(const string &pm_sFile); + +/** + *@brief copy a file + *@param pm_sSrc source file + *@param pm_sDest destination file + *@return -1 fail + * 0 success + */ +int FileCpy(const string &pm_sSrc, const string &pm_sDest); + +/** + *@brief move a file + *@param pm_sSrc source file + *@param pm_sDest destination file + *@return -1 fail + * 0 success + */ +int FileMv(const string& pm_sSrc, const string& pm_sDest); + +/** + *@brief simply move file function + *@param pm_sFileName file path + *@return -1 fail + * 0 success + */ +int FileRm(const string& pm_sFileName); + +/** + *@brief create a specific directory + *@param dirPath the specific directory + *@return false success + * true failure + */ +bool createFileDir(const string& dirPath); + +/** +*@desc list all the filepath or filename in the specific directory +*@param dirPath the search directory +*@param files the output filepath or filename containers +*@param fullPath if the output result is full file path with filename +*/ +void listAllFiles(const std::string& dirPath, vector& files, bool fullPath=false); + +/** + *@brief get the date string with the pattern: YYYYMMDD_HHMMSS + *@return time string + */ +string currentTimestamp(); + +/** + *@brief get the full path of stored file + *@param path the base directory of the file + *@param fileID the file id + *@param fileName the file name + *@param filename the output full file path + *@param filename_bak the output full backup file path + */ +void createDfsFileNames(const string& path, const string& fileID, const string& fileName, string& filename, string& filename_bak); + + +/** + *@desc splite string by the dilimiter character + *@param pm_sExpression string to splite + *@param pm_cDelimiter the dilimiter + *@param pm_vecArray the splited substrings + */ +void SplitString(const string &pm_sExpression, char pm_cDelimiter, vector &pm_vecArray); + +void createDirectoryByContainer(const string& base, const string &container, string &directory); + +} +} +} + +#endif // _COMMON_H diff --git a/libweb3jsonrpc/dfs/DfsCommonClient.cpp b/libweb3jsonrpc/dfs/DfsCommonClient.cpp new file mode 100644 index 0000000000..778aea65aa --- /dev/null +++ b/libweb3jsonrpc/dfs/DfsCommonClient.cpp @@ -0,0 +1,99 @@ +#include "DfsCommonClient.h" +#include "DfsFileServer.h" +#include "DfsCommon.h" +#include "DfsConst.h" + + +using namespace dev::rpc::fs; + + + +DfsCommonClient::DfsCommonClient() : DfsHttpClient() +{ + +} + +DfsCommonClient::~DfsCommonClient() +{ + +} + +int DfsCommonClient::fillUserData(JzRequestInfo& req_info) +{ + JzBuffer *pBuffer = new JzBuffer(); + pBuffer->data = (char*)new char[JZ_FIX_BUFFER_SIZE]; + pBuffer->compacity = JZ_FIX_BUFFER_SIZE; + pBuffer->size = 0; + req_info.user_data = pBuffer; + + return 0; +} + +int DfsCommonClient::endRequest() +{ + if (m_ReqInfo.user_data) + { + //parse json + JzBuffer* pBuffer = (JzBuffer*)m_ReqInfo.user_data; + string strjson(pBuffer->data, pBuffer->size); + parseRspJson(strjson); + + //free user data + delete []pBuffer->data; + delete pBuffer; + m_ReqInfo.user_data = NULL; + } + + return 0; +} + + +size_t DfsCommonClient::handle_recv_data(void *ptr, size_t size, size_t nmemb, void *cls) +{ + if (cls == NULL) + return -1; + + DfsHttpClient *pClient = (DfsHttpClient*)cls; + if (!pClient->m_ReqInfo.curl) + { + dfs_warn << "NULL curl found\n"; + return -1; + } + + CURLcode res; + long response_code; + res = curl_easy_getinfo(pClient->m_ReqInfo.curl, CURLINFO_RESPONSE_CODE, &response_code); + if (res != CURLE_OK || (response_code != 0 && response_code != 200) ) + { + dfs_warn << "bad response: " << (char*)ptr << "\n"; + string strjson((char*)ptr, size*nmemb); + parseRspJson(strjson); + return size*nmemb; + } + + //content recv + JzBuffer* pBuff = (JzBuffer*)pClient->m_ReqInfo.user_data; + if (pBuff == NULL || !pBuff->data) + { + dfs_warn << "null pointer for recv buffer\n"; + return -1; + } + + if ((int)(pBuff->compacity - pBuff->size - nmemb*size) < 0) + { + int compacity = pBuff->compacity + nmemb*size + 1; + char *pData = (char*)malloc(compacity); + + memcpy(pData, pBuff->data, pBuff->size); + memset(pData + pBuff->size, 0, pBuff->compacity - pBuff->size); + + free(pBuff->data); + pBuff->data = pData; + pBuff->compacity = compacity; + } + + memcpy(pBuff->data + pBuff->size, ptr, nmemb*size); + pBuff->size = pBuff->size + nmemb * size; + return size*nmemb; +} + diff --git a/libweb3jsonrpc/dfs/DfsCommonClient.h b/libweb3jsonrpc/dfs/DfsCommonClient.h new file mode 100644 index 0000000000..2668f4ad4f --- /dev/null +++ b/libweb3jsonrpc/dfs/DfsCommonClient.h @@ -0,0 +1,31 @@ +#pragma once + + +#include "DfsBase.h" +#include "DfsHttpClient.h" + +namespace dev +{ + +namespace rpc +{ + +namespace fs +{ + +class DfsCommonClient : public DfsHttpClient +{ +public: + DfsCommonClient(); + virtual ~DfsCommonClient(); + + + virtual int fillUserData(JzRequestInfo& req_info); + virtual int endRequest(); + virtual size_t handle_recv_data(void *ptr, size_t size, size_t nmemb, void *cls); + +}; + +} +} +} \ No newline at end of file diff --git a/libweb3jsonrpc/dfs/DfsConst.h b/libweb3jsonrpc/dfs/DfsConst.h new file mode 100644 index 0000000000..1573ef12af --- /dev/null +++ b/libweb3jsonrpc/dfs/DfsConst.h @@ -0,0 +1,37 @@ +/** +*@file DfsConst.h +*@desc const file of file process module +*/ + +#pragma once + +//basic info +#define JZ_MODULE_VERSION_V1 "v1" +#define JZ_MODULE_FS "fs" +#define JZ_HTTP_DEFAULT_HOST_PORT 6789 + +//http method +#define JZ_HTTP_METHOD_GET "GET" +#define JZ_HTTP_METHOD_POST "POST" +#define JZ_HTTP_METHOD_DELETE "DELETE" +#define JZ_HTTP_METHOD_OPTIONS "OPTIONS" +#define JZ_HTTP_METHOD_HEAD "HEAD" +#define JZ_HTTP_METHOD_PUT "PUT" + +//container definition +#define JZ_CONTAINER_FILES "files" + + +#define JZ_FIX_BUFFER_SIZE 1024 + +#define JZ_FIX_SLEEP_TIME 3000//milliseconds + +#define JZ_2000_FIRST_DAY_TIMESTAMP 946713600 + +#define JZ_UPLOAD_FILE_INFO_FIELD "fileinfo" + +#define JZ_FILE_RECORD_FILE "DfsFileUpdate.data" + + + + diff --git a/libweb3jsonrpc/dfs/DfsContractCaller.cpp b/libweb3jsonrpc/dfs/DfsContractCaller.cpp new file mode 100644 index 0000000000..fdd82324ec --- /dev/null +++ b/libweb3jsonrpc/dfs/DfsContractCaller.cpp @@ -0,0 +1,225 @@ +#include "DfsContractCaller.h" +#include "libcontract/FileInfoManagerContract.h" +#include "libcontract/FileServerManagerContract.h" +#include "libdevcore/Log.h" + +using namespace contract; + +namespace dev +{ + +namespace rpc +{ + +namespace fs +{ + +static dev::eth::Client* psClient = NULL; +static FileInfoManagerContract* pFileInfoContract = NULL; +static FileServerManagerContract* pFileServerContract = NULL; + +static void updateFileContracts() +{ + if (pFileInfoContract && pFileServerContract) + return; + + //get the file info contract address, the fileserver contract address + Address addrFileInfo = psClient->findContract("FileInfoManager"); + Address addrFileServer = psClient->findContract("FileServerManager"); + + if (addrFileInfo == h160() || addrFileServer == h160()) + { + LOG(ERROR) << "Client not ready or cannot find the system contract !"; + return; + } + + pFileInfoContract = new FileInfoManagerContract(psClient, addrFileInfo); + pFileServerContract = new FileServerManagerContract(psClient, addrFileServer); + LOG(TRACE) << "update the file contracts and DFS is prepared ! OK"; + return; +} + +int init_caller_client(dev::eth::Client* client) +{ + psClient = client; + { + updateFileContracts(); + } + + return 0; +} + +int uninit_caller_client() +{ + psClient = NULL; + if (pFileInfoContract) + { + delete pFileInfoContract; + pFileInfoContract = NULL; + } + + if (pFileServerContract) + { + delete pFileServerContract; + pFileServerContract = NULL; + } + + return 0; +} + + +int listFileInfo(string& result) +{ + updateFileContracts(); + if (!pFileInfoContract || !psClient) + { + return -1; + } + + result.clear(); + if (0 != pFileInfoContract->listFileinfo(result)) + { + return -1; + } + + return 0; +} + +int listGroupFileInfo(const string& group, string& result) +{ + updateFileContracts(); + if (!pFileInfoContract || !psClient) + { + return -1; + } + + result.clear(); + if (0 != pFileInfoContract->listFileinfoByGroup(group, result)) + { + return -1; + } + + if (result.size() <= 0) + { + return -2; + } + + return 0; +} + +int findFileInfo(const string& fileid, string& result) +{ + updateFileContracts(); + if (!pFileInfoContract || !psClient) + { + return -1; + } + + if (0 != pFileInfoContract->findFileInfo(fileid, result)) + { + return -1; + } + + return 0; +} + +int listServerInfo(string& result) +{ + updateFileContracts(); + if (!psClient || !pFileServerContract) + { + return -1; + } + + if (0 != pFileServerContract->listFileServer(result)) + { + return -1; + } + + return 0; +} + +int findServerInfo(const string& serverid, string& result) +{ + updateFileContracts(); + if (!psClient || !pFileServerContract) + { + return -1; + } + + if (0 != pFileServerContract->findServerInfo(serverid, result)) + { + return -1; + } + + return 0; +} + +int pageByGroup(string _group, int _pageNo, string& result) +{ + updateFileContracts(); + if (!pFileInfoContract || !psClient) + { + return -1; + } + + if (0 != pFileInfoContract->pageByGroup(_group, _pageNo, result)) + { + return -1; + } + + return 0; +} + +int getGroupPageCount(const std::string& group, int& result) +{ + updateFileContracts(); + if (!pFileInfoContract || !psClient) + { + return -1; + } + + if (0 != pFileInfoContract->getGroupPageCount(group, result)) + { + return -1; + } + + return 0; +} + +int getPageCount(int& result) +{ + updateFileContracts(); + if (!pFileInfoContract || !psClient) + { + return -1; + } + + if (0 != pFileInfoContract->getPageCount(result)) + { + return -1; + } + + return 0; +} + +int checkServiceNode(const std::string& nodeid, bool& enable) +{ + updateFileContracts(); + if (!psClient || !pFileServerContract) + { + return -1; + } + + if (0 != pFileServerContract->isServerEnable(nodeid, enable)) + { + return -1; + } + + return 0; +} + + +} +} +} diff --git a/libweb3jsonrpc/dfs/DfsContractCaller.h b/libweb3jsonrpc/dfs/DfsContractCaller.h new file mode 100644 index 0000000000..7d38d24dcb --- /dev/null +++ b/libweb3jsonrpc/dfs/DfsContractCaller.h @@ -0,0 +1,81 @@ +#pragma once + + +#include +#include + +using std::string; + + +namespace dev +{ + +namespace rpc +{ + +namespace fs +{ + + + +/** +*@desc initiate the caller +*/ +int init_caller_client(dev::eth::Client* client); + +/** +*@desc list all the file info +*/ +int listFileInfo(string& result); + +/** +*@desc list all the file info by group +*/ +int listGroupFileInfo(const string& group, string& result); + +/** +*@desc find the specific file info by fileid +*/ +int findFileInfo(const string& fileid, string& result); + +/** +*@desc list all the file server info +*/ +int listServerInfo(string& result); + +/** +*@desc find the specific server info by serverid +*/ +int findServerInfo(const string& serverid, string& result); + +/** +*@desc add file info +*/ +int insertFileInfo(const string& fileinfo); + + +/** +*@desc fetch file info by group and page number +*/ +int pageByGroup(string _group, int _pageNo, string& result); + +/** +*@desc get page count of a group file info +*/ +int getGroupPageCount(const std::string& group, int& result); + +/** +*@desc get file info page count +*/ +int getPageCount(int& result); + +/** +*@desc check if the service node is enabled +*/ +int checkServiceNode(const std::string& nodeid, bool& enable); + +} + +} +} + diff --git a/libweb3jsonrpc/dfs/DfsDeleteFileHandler.cpp b/libweb3jsonrpc/dfs/DfsDeleteFileHandler.cpp new file mode 100644 index 0000000000..d84a606332 --- /dev/null +++ b/libweb3jsonrpc/dfs/DfsDeleteFileHandler.cpp @@ -0,0 +1,107 @@ +#include "DfsDeleteFileHandler.h" +#include +#include +#include +#include "DfsCommon.h" +#include "DfsConst.h" +#include "DfsJsonUtils.h" +#include "DfsFileServer.h" +#include "DfsFileOperationManager.h" +#include "DfsBase.h" +#include "DfsFileRecorder.h" + + +using namespace dev::rpc::fs; + +void DfsDeleteFileHandler::handle_request_completed (void *cls, struct MHD_Connection *connection, + void **con_cls, enum MHD_RequestTerminationCode toe) +{ + (void)cls; + (void)connection; + (void)con_cls; + (void)toe; + printf("the delete request of delete completed\n"); +} + +DfsDeleteFileHandler::DfsDeleteFileHandler(const string& version, const string &method) +: IUrlHandler(version, method) +{ + +} + +DfsDeleteFileHandler::~DfsDeleteFileHandler() +{ + +} + +//only modify filename +int DfsDeleteFileHandler::handle(DfsHttpInfo* http_info, DfsUrlInfo* url_info) +{ + //PUT, container_id, file_id + if (0 != strcmp(http_info->method, JZ_HTTP_METHOD_DELETE) \ + || url_info->container_id.empty() \ + || url_info->file_id.empty()) + { + printf("bad request url: %s, method: %s\n", http_info->url, http_info->method); + string strjson = DfsJsonUtils::createCommonRsp(MHD_HTTP_BAD_REQUEST, -1, "bad request, check url"); + return IUrlHandler::send_page(http_info->connection, strjson.c_str(), MHD_HTTP_BAD_REQUEST); + } + + dfs_debug << "delete file, url: " << http_info->url << ", method: " << http_info->method << "\n"; + if (*(http_info->ptr) == NULL) + { + DfsConnectionInfo *con_info = new DfsConnectionInfo; + con_info->method = JZ_HTTP_METHOD_POST; + con_info->version = JZ_MODULE_VERSION_V1; + *(http_info->ptr) = con_info; + } + + //consume data + *(http_info->upload_data_size) = 0; + + //process delete file + int http_code = MHD_HTTP_OK; + string strRspJson = ""; + if (0 != deleteFile(url_info)) + { + http_code = MHD_HTTP_INTERNAL_SERVER_ERROR; + strRspJson = DfsJsonUtils::createCommonRsp(http_code, -1, "delete file failed, maybe not exist or not allowed!"); + return IUrlHandler::send_page(http_info->connection, strRspJson.data(), http_code); + } + + http_code = MHD_HTTP_OK; + strRspJson = DfsJsonUtils::createCommonRsp(http_code, 0, "OK"); + return IUrlHandler::send_page(http_info->connection, strRspJson.data(), http_code); +} + + +//revise the file info +int DfsDeleteFileHandler::deleteFile(const DfsUrlInfo* url_info) +{ + DfsFileInfo fileinfo; + fileinfo.id = url_info->file_id; + fileinfo.container = url_info->container_id; + string strFilePath; + if (0 != DfsFileOperationManager::getInstance()->delFile(fileinfo, strFilePath)) + { + dfs_warn << "### failed in del file: " << url_info->file_id.data() << "\n"; + return -1; + } + + dfs_debug << "del file: " << url_info->file_id.data() << "\n"; + //write modify file record + string strUpDir; + createDirectoryByContainer(DfsFileServer::getInstance()->m_StoreRootPath, url_info->container_id, strUpDir); + + DfsFileTask objTask; + objTask.id = url_info->file_id; + objTask.filename = strFilePath.substr(strFilePath.find_last_of("/")+1); + objTask.operation = DfsFileTask::DELETE; + objTask.directory = strUpDir; + if (0 != DfsFileRecorder::writeRecord(objTask)) + { + dfs_warn << "## write file update record failed !!"; + } + + return 0; +} \ No newline at end of file diff --git a/libweb3jsonrpc/dfs/DfsDeleteFileHandler.h b/libweb3jsonrpc/dfs/DfsDeleteFileHandler.h new file mode 100644 index 0000000000..0daefbb4b9 --- /dev/null +++ b/libweb3jsonrpc/dfs/DfsDeleteFileHandler.h @@ -0,0 +1,37 @@ +#pragma once + +#include "IUrlHandler.h" + +namespace dev +{ + +namespace rpc +{ + +namespace fs +{ + +class DfsDeleteFileHandler : public IUrlHandler +{ +public: + DfsDeleteFileHandler(const string& version, const string &method); + virtual ~DfsDeleteFileHandler(); + +public: + virtual int handle(DfsHttpInfo* http_info, DfsUrlInfo* url_info); + virtual void handle_request_completed (void *cls, struct MHD_Connection *connection, + void **con_cls, enum MHD_RequestTerminationCode toe); + + //parse file info json: eg. file info json: {\"fileid\\":\"file_1111\",\"filename\":\"file_name_111\"} + int parseFileInfo(const string& json, DfsFileInfo& fileInfo); + + //revise the file info + int reviseFileInfo(const DfsFileInfo& fileInfo); + + int deleteFile(const DfsUrlInfo* url_info); + +}; + +} +} +} diff --git a/libweb3jsonrpc/dfs/DfsDownloadClient.cpp b/libweb3jsonrpc/dfs/DfsDownloadClient.cpp new file mode 100644 index 0000000000..c205a1dae2 --- /dev/null +++ b/libweb3jsonrpc/dfs/DfsDownloadClient.cpp @@ -0,0 +1,116 @@ +#include "DfsDownloadClient.h" +#include "DfsFileServer.h" +#include "DfsCommon.h" +#include "DfsConst.h" +#include "DfsMd5.h" + + +using namespace dev::rpc::fs; + + +DfsDownloadClient::DfsDownloadClient() : DfsHttpClient() +{ + +} + +DfsDownloadClient::~DfsDownloadClient() +{ + +} + +int DfsDownloadClient::fillUserData(JzRequestInfo& req_info) +{ + (void)req_info; + return 0; +} + +int DfsDownloadClient::endRequest() +{ + //close file + if (m_ReqInfo.user_data) + { + fclose((FILE*)m_ReqInfo.user_data); + //get file full path to store + string strFile; + string strFileBak; + string strFileDir; + string strFirst; + string strSecond; + DfsFileServer::getInstance()->createDirectoryStringByContainer(m_ReqInfo.container_id, strFileDir, strFirst, strSecond); + createDfsFileNames(strFileDir, m_ReqInfo.file_id, m_ReqInfo.filename, strFile, strFileBak); + + dfs_debug << "** end of the download request, save temp file " << m_ReqInfo.filepath.data() << "to " << strFile.data(); + FileCpy(m_ReqInfo.filepath, strFile); + FileRm(m_ReqInfo.filepath); + + std::string strHash; + if(0 != ms_md5(strFile, strHash)) + { + dfs_warn << "** cannot calculate md5 hash of file: " << strFile; + } + + if (m_ReqInfo.filehash == strHash) + { + dfs_debug << "the calculate hash check success "; + m_error_code = 0; + } + else + { + dfs_warn << "the calculate hash not equal, srcHash: " << m_ReqInfo.filehash.data() << ", dstHash: " << strHash.data(); + m_error_code = -1; + } + + m_ReqInfo.user_data = NULL; + } + + return 0; +} + +size_t DfsDownloadClient::handle_recv_data(void *ptr, size_t size, size_t nmemb, void *cls) +{ + dfs_debug << "### recv data: " << (int)size << " bytes ******"; + if (cls == NULL) + return -1; + + DfsHttpClient *pClient = (DfsHttpClient*)cls; + if (!pClient->m_ReqInfo.curl) + { + dfs_debug << "NULL curl found\n"; + return -1; + } + + CURLcode res; + long response_code; + res = curl_easy_getinfo(pClient->m_ReqInfo.curl, CURLINFO_RESPONSE_CODE, &response_code); + if (res != CURLE_OK || (response_code != 0 && response_code != 200) ) + { + dfs_debug << "bad response: " << (char*)ptr << "\n"; + string strjson((char*)ptr, size*nmemb); + parseRspJson(strjson); + return size*nmemb; + } + + //file recv + if (!pClient->m_ReqInfo.user_data) + { + m_ReqInfo.filepath = DfsFileServer::getInstance()->m_TempStorePath; + m_ReqInfo.filepath += "/"; + m_ReqInfo.filepath += m_ReqInfo.file_id; + m_ReqInfo.filepath += "_"; + m_ReqInfo.filepath += m_ReqInfo.filename; + + FILE* fp = fopen(m_ReqInfo.filepath.c_str(), "wb"); + if (fp == NULL) + { + dfs_warn << "cannot open file for download : " << m_ReqInfo.filepath.c_str(); + return -1; + } + + pClient->m_ReqInfo.user_data = fp; + } + + size_t written = fwrite(ptr, size, nmemb, (FILE*)pClient->m_ReqInfo.user_data); + dfs_debug << "#####**** download, recv " << size << ", and write " << (int)written << " bytes to fileid: " << pClient->m_ReqInfo.file_id.data() << ", filename: " << pClient->m_ReqInfo.filename.data() << "\n"; + return written; +} + diff --git a/libweb3jsonrpc/dfs/DfsDownloadClient.h b/libweb3jsonrpc/dfs/DfsDownloadClient.h new file mode 100644 index 0000000000..5dfeca86ea --- /dev/null +++ b/libweb3jsonrpc/dfs/DfsDownloadClient.h @@ -0,0 +1,31 @@ +#pragma once + + +#include "DfsBase.h" +#include "DfsHttpClient.h" + +namespace dev +{ + +namespace rpc +{ + +namespace fs +{ + +class DfsDownloadClient : public DfsHttpClient +{ +public: + DfsDownloadClient(); + virtual ~DfsDownloadClient(); + + + virtual int fillUserData(JzRequestInfo& req_info); + virtual int endRequest(); + virtual size_t handle_recv_data(void *ptr, size_t size, size_t nmemb, void *cls); + +}; + +} +} +} \ No newline at end of file diff --git a/libweb3jsonrpc/dfs/DfsDownloadHandler.cpp b/libweb3jsonrpc/dfs/DfsDownloadHandler.cpp new file mode 100644 index 0000000000..914ac1bc31 --- /dev/null +++ b/libweb3jsonrpc/dfs/DfsDownloadHandler.cpp @@ -0,0 +1,199 @@ +#include "DfsDownloadHandler.h" +#include +#include +#include +#include +#include +#include + +#include "DfsJsonUtils.h" +#include "DfsCommon.h" +#include "DfsConst.h" +#include "DfsFileServer.h" +#include "DfsFileOperationManager.h" +#include "DfsContractCaller.h" + + + +using namespace dev::rpc::fs; + + + +void DfsDownloadHandler::handle_request_completed (void *cls, struct MHD_Connection *connection, + void **con_cls, enum MHD_RequestTerminationCode toe) +{ + (void)cls; + (void)connection; + (void)con_cls; + (void)toe; + dfs_debug << "download request of download completed \n"; +} + + +DfsDownloadHandler::DfsDownloadHandler(const string &version, const string &method) : + IUrlHandler(version, method) +{ +} + +DfsDownloadHandler::~DfsDownloadHandler() +{ +} + + +static ssize_t +file_reader (void *cls, + uint64_t pos, + char *buf, + size_t max); + + +static void free_callback (void *cls); + + +//handle request and setup download +int DfsDownloadHandler::handle(DfsHttpInfo *http_info, DfsUrlInfo *url_info) +{ + struct stat buf; + + dfs_debug << "the url: " << http_info->url << "\n"; + if ((0 != strcmp(http_info->method, MHD_HTTP_METHOD_GET)) + || url_info->container_id.empty() \ + || url_info->file_id.empty()) + { + dfs_warn << "bad request method: " << http_info->method << "\n"; + string strjson = DfsJsonUtils::createCommonRsp(MHD_HTTP_BAD_REQUEST, -1, "bad request, check url"); + return IUrlHandler::send_page(http_info->connection, strjson.c_str(), MHD_HTTP_BAD_REQUEST); + } + + if (*(http_info->ptr) == NULL) + { + DfsConnectionInfo *con_info = new DfsConnectionInfo; + con_info->method = JZ_HTTP_METHOD_GET; + con_info->version = JZ_MODULE_VERSION_V1; + con_info->fp = NULL; + con_info->fp_path = ""; + con_info->data = (char*)http_info->connection; + *(http_info->ptr) = con_info; + } + + DfsConnectionInfo *down_con_info = (DfsConnectionInfo*)(*(http_info->ptr)); + int http_response_code = MHD_HTTP_OK; + if (NULL == down_con_info->fp) + { + string strFileDir; + string strFirst; + string strSecond; + DfsFileServer::getInstance()->createDirectoryStringByContainer(url_info->container_id, strFileDir, strFirst, strSecond); + + if (url_info->file_id.empty()) + { + dfs_warn << "bad request, url: " << http_info->url << " without file_id\n"; + string strjson = DfsJsonUtils::createCommonRsp(MHD_HTTP_BAD_REQUEST, -1, "bad request no fileid"); + return IUrlHandler::send_page(http_info->connection, strjson.c_str(), MHD_HTTP_BAD_REQUEST); + } + + //get short fileid_xxx as the filepath + //find the file + string strFullFileFound = ""; + if (!findShortestAsFile(strFileDir, url_info->file_id, strFullFileFound)) + { + dfs_warn << "download, cannot find fileid: " << url_info->file_id.c_str() << " corresponding file \n"; + string strjson = DfsJsonUtils::createCommonRsp(MHD_HTTP_NOT_FOUND, -1, "file id not found"); + return IUrlHandler::send_page(http_info->connection, strjson.c_str(), MHD_HTTP_NOT_FOUND); + } + + down_con_info->fp = fopen (strFullFileFound.c_str(), "rb"); + if (down_con_info->fp == NULL) + { + http_response_code = MHD_HTTP_NOT_FOUND; + + dfs_warn << "**** open file failed! file: " << strFullFileFound.data(); + string strPage = DfsJsonUtils::createCommonRsp(MHD_HTTP_NOT_FOUND, -1, "file not found"); + return IUrlHandler::send_page(http_info->connection, strPage.data(), http_response_code); + } + else + { + int fd = fileno (down_con_info->fp); + int result = 0; + if (-1 == fd) + { + result = -1; + } + + if ((result == 0) && ((0 != fstat (fd, &buf)) || (! S_ISREG (buf.st_mode))) ) + { + result = -1; + } + + if (result != 0) + { + (void) fclose (down_con_info->fp); + down_con_info->fp = NULL; + http_response_code = MHD_HTTP_BAD_REQUEST; + + dfs_warn << "**** bad file cannot down, file: " << strFullFileFound.data(); + string strPage = DfsJsonUtils::createCommonRsp(MHD_HTTP_BAD_REQUEST, -1, "bad file"); + return IUrlHandler::send_page(http_info->connection, strPage.data(), http_response_code); + } + } + } + + int ret = MHD_YES; + struct MHD_Response *response; + //do downloading... + response = MHD_create_response_from_callback (buf.st_size, 4 * 1024, /* 32k page size */ + &file_reader, + down_con_info, + &free_callback); + if (NULL == response) + { + fclose (down_con_info->fp); + down_con_info->fp = NULL; + http_response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; + + dfs_warn << "**** download file, MHD_create_response_from_callback, url: " << http_info->url; + string strPage = DfsJsonUtils::createCommonRsp(http_response_code, -1, "create reader failed"); + return IUrlHandler::send_page(http_info->connection, strPage.data(), http_response_code); + } + + dfs_debug << "download request commit ok! url: " << http_info->url << "\n"; + ret = MHD_queue_response(http_info->connection, MHD_HTTP_OK, response); + MHD_destroy_response(response); + return ret; +} + +static ssize_t +file_reader (void *cls, + uint64_t pos, + char *buf, + size_t max) +{ + DfsConnectionInfo *down_con_info = (DfsConnectionInfo*)cls; + + FILE *file = (FILE*)down_con_info->fp; + + fseek (file, pos, SEEK_SET); + int ret = fread (buf, 1, max, file); + dfs_debug << "download, read " << ret << " bytes from file\n"; + return ret; +} + + +static void +free_callback (void *cls) +{ + DfsConnectionInfo *down_con_info = (DfsConnectionInfo*)cls; + + FILE *file = (FILE*)down_con_info->fp; + if (file) + { + fclose (down_con_info->fp); + down_con_info->fp = NULL; + dfs_debug << "**** download down and free, url: " << down_con_info->file_id.data(); + down_con_info->data = NULL; + down_con_info->fp_path = ""; + } + + dfs_debug << "file read done, fileid: " << down_con_info->file_id.data() << "\n"; +} + diff --git a/libweb3jsonrpc/dfs/DfsDownloadHandler.h b/libweb3jsonrpc/dfs/DfsDownloadHandler.h new file mode 100644 index 0000000000..8ab1d30eb4 --- /dev/null +++ b/libweb3jsonrpc/dfs/DfsDownloadHandler.h @@ -0,0 +1,28 @@ +#pragma once + +#include "IUrlHandler.h" + +namespace dev +{ + +namespace rpc +{ + +namespace fs +{ + +class DfsDownloadHandler : public IUrlHandler +{ +public: + DfsDownloadHandler(const string& version, const string &method); + virtual ~DfsDownloadHandler(); + +public: + virtual int handle(DfsHttpInfo* http_info, DfsUrlInfo* url_info); + virtual void handle_request_completed (void *cls, struct MHD_Connection *connection, + void **con_cls, enum MHD_RequestTerminationCode toe); +}; + +} +} +} diff --git a/libweb3jsonrpc/dfs/DfsFileInfoScanner.cpp b/libweb3jsonrpc/dfs/DfsFileInfoScanner.cpp new file mode 100644 index 0000000000..bcc70f5674 --- /dev/null +++ b/libweb3jsonrpc/dfs/DfsFileInfoScanner.cpp @@ -0,0 +1,601 @@ +#include "DfsFileInfoScanner.h" +#include +#include +#include +#include "json/json.h" +#include "DfsContractCaller.h" +#include "DfsCommon.h" +#include "DfsMd5.h" +#include "DfsFileServer.h" +#include "DfsFileOperationManager.h" +#include "DfsConst.h" +#include "DfsDownloadClient.h" +#include "DfsCommonClient.h" +#include "DfsFileRecorder.h" +#include "libethereum/Client.h" + + + +using namespace dev; +using namespace dev::eth; +using namespace dev::rpc::fs; + +static Client* psClient = NULL; + +DfsFileInfoScanner::DfsFileInfoScanner(): Worker("filesync", 0) +{ + m_BasePath = ""; + + m_SrcNode = ""; + m_GroupId = ""; + m_SyncState = FileSyncState::SYNC_NOT_INITED; + m_InitBlockNum = 0; + + struct timeval nowTime; + gettimeofday(&nowTime, NULL); + m_TimeLastCheck = nowTime.tv_sec * 1000000 + nowTime.tv_usec; +} + +DfsFileInfoScanner::~DfsFileInfoScanner() +{ + stop(); +} + +//init +int DfsFileInfoScanner::init(const vector &containers, void* client) +{ + m_BasePath = DfsFileServer::getInstance()->m_StoreRootPath; + m_SrcNode = DfsFileServer::getInstance()->m_NodeId; + m_GroupId = DfsFileServer::getInstance()->m_NodeGroup; + m_Containers = containers; + + //get all file info from contract + map fileinfos; + getContractFileInfos(fileinfos); + + //get all file info from local dfs + map localFileinfos; + getLocalFileInfos(localFileinfos); + + //check all the file infos and create file operation task + processFileinfoInit(localFileinfos, fileinfos); + + //start the running thread + m_SyncState = FileSyncState::SYNC_WAIT_INIT; + m_InitBlockNum = 0; + psClient = (Client*)client; + + startWorking(); + + dfs_debug << "DfsFileInfoScanner (file sync module) has been inited !\n"; + return 0; +} + +/// Called after thread is started from startWorking(). +void DfsFileInfoScanner::startedWorking() +{ + dfs_debug << "the file info sanner is started... running\n"; +} + +/// Called continuously following sleep for m_idleWaitMs. +void DfsFileInfoScanner::doWork() +{ + if (m_SyncState == FileSyncState::SYNC_INIT_OK) + { + doTask(); + } + else + { + if (checkBlockInit()) + { + dfs_debug << "init state is OK, start real file working !!"; + m_SyncState = FileSyncState::SYNC_INIT_OK; + if (!DfsFileServer::getInstance()->checkServiceAvailable()) + { + dfs_warn << "the file service of node: " << m_SrcNode << "is not open !"; + } + else + { + dfs_debug << "the file service of node: " << m_SrcNode << "is open !"; + } + } + else + { + static int tag = 0; + if (tag == 0) + dfs_debug << "init state is NOT OK, waiting... !!"; + + usleep(1000);//1ms + } + } +} + +bool DfsFileInfoScanner::checkBlockInit() +{ + if (!psClient->checkWorking()) + return false; + + return true; + //as there has empty block, the code block is commented now + /*int blockNum = psClient->number(); + struct timeval nowTime; + gettimeofday(&nowTime, NULL); + + int utimeNow = nowTime.tv_sec * 1000000 + nowTime.tv_usec; + if (blockNum > 0 && blockNum == m_InitBlockNum && utimeNow > m_TimeLastCheck + 3000000) + return true; + + if (blockNum > m_InitBlockNum) + { + m_InitBlockNum = blockNum; + m_TimeLastCheck = utimeNow; + } + + return false;*/ +} + +void DfsFileInfoScanner::stop() +{ + stopWorking(); +} + +//thread cycle +void DfsFileInfoScanner::doTask() +{ + //1. process all tasks for the first + if (!DfsFileServer::getInstance()->checkServiceAvailable() || m_DownloadFileInfos.size() <= 0) + { + //dfs_debug << "**** no files to process ***\n"; + for (int i = 0 ; i < 5; ++i)//sleep (5s) + { + + if (!shouldStop()) + usleep(1000000);//1s + else + return; + } + } + + //execute all the download tasks + DfsHttpClient* pClient = new DfsDownloadClient(); + + for(auto &file : m_DownloadFileInfos) + { + if (m_SrcNode == file.second.src_node) + { + dfs_debug << "get a file download task, but the src_node is self ###****\n"; + continue; + } + + if (shouldStop()) + return; + + JzRequestInfo objReq; + objReq.method = JZ_HTTP_METHOD_GET; + objReq.host = file.second.host; + objReq.port = file.second.port; + objReq.module = JZ_MODULE_FS; + objReq.container_id = file.second.container; + objReq.version = JZ_MODULE_VERSION_V1; + objReq.file_id = file.second.id; + objReq.filename = file.second.filename; + objReq.filehash = file.second.filehash; + objReq.user_data = NULL; + objReq.curl = NULL; + + dfs_debug << "to down file: " << file.first.c_str() << ", from src_node: " << file.second.src_node.c_str() <<"\n"; + pClient->init(objReq); + + DfsFileTask objTaskStart = file.second; + file.second.operation = DfsFileTask::DOWNLOAD_START; + if (0 != DfsFileRecorder::writeRecord(file.second)) + { + dfs_warn << "write down_start file update record failed !!"; + } + + pClient->request(""); + pClient->endRequest(); + + dfs_debug << "down file done: " << file.first.c_str() << ", from src_node: " << file.second.src_node.c_str() <<"\n"; + file.second.operation = pClient->getErrorCode() == 0 ? DfsFileTask::DOWNLOAD : DfsFileTask::DOWNLOAD_FAIL; + if (0 != DfsFileRecorder::writeRecord(file.second)) + { + dfs_warn << "write down file update record failed !!"; + } + } + + m_DownloadFileInfos.clear(); + delete pClient; + + //dfs_debug << "**** to fetch info and generateTasks ..."; + //2. get all file info from contract + map fileInfos; + getContractFileInfos(fileInfos); + + if (shouldStop()) + return; + //3. calculate the files info changes + generateTasks(fileInfos); + +} + +int DfsFileInfoScanner::queryGroupFileInfo(const std::string& group, vector& result) +{ + int pageSize = 0; + if (0 != getGroupPageCount(group, pageSize)) + { + dfs_debug << "getGroupPageCount failed !"; + return -1; + } + + for (int i = 0; i < pageSize; ++i) + { + string json; + if (0 != pageByGroup(group, i, json)) + { + dfs_debug << "pageByGroup failed, in call !"; + return -1; + } + + result.push_back(json); + } + + return 0; +} + +int DfsFileInfoScanner::getContractFileInfos(map& fileInfos) +{ + vector vecFileInfos; + if (0 != queryGroupFileInfo(m_GroupId, vecFileInfos)) + { + dfs_warn << "*** listGroupFileInfo failed ***\n"; + return -1; + } + + //parse the file info list + //dfs_debug << "*** listByGroup(" << m_GroupId.data() << ") pages ==> "<< vecFileInfos.size() <<"\n"; + if(0 != parseFileInfoList(vecFileInfos, fileInfos)) + { + dfs_warn << "parseFileInfoList faield, size: " << vecFileInfos.size() << "\n"; + return -1; + } + + //dfs_debug << "**** fs has "<< (int)fileInfos.size() << " fileinfo objects for group: " << m_GroupId.data() << "\n"; + return 0; +} + + + +int DfsFileInfoScanner::parseFileInfoList(const vector& vecJson, map& fileInfos) +{ + + + /* {"ret":0, + "data":{"; + "total":0,"items": + [{"id", + "container":"files", + "filename":"filename001", + "updateTime":"147899899", + "size":1, + "file_hash":"afsfsd33wrsdf", + "type":1, + "priviliges":"rwx", + "src_node":"node_id_001", + "node_group":"group001", + "info":"" + }] + } + } + */ + + for (auto && strjson : vecJson) + { + Json::Reader reader; + Json::Value root; + string strRet; + if (strjson.size() <= 0 || !reader.parse(strjson, root)) + { + dfs_debug << "parse json: " << strjson.c_str() << "failed\n"; + return -1; + } + + if (root["ret"].isNull() || root["data"].isNull()) + { + dfs_debug << "bad json: " << strjson.c_str() << "\n"; + return -1; + } + + strRet = root["ret"].asString(); + Json::Value &data = root["data"]; + if (data["items"].isNull() || data["total"].isNull()) + { + dfs_debug << "the data node is invalid \n"; + return -1; + } + + Json::Value &items = data["items"]; + //parse items to fileinfos + //MUST: id, filename, file_hash, src_node, node_group + string id; + string filename; + string file_hash; + string src_node; + string node_group; + int count = items.size(); + for(int i = 0; i < count; ++i) + { + if (items[i]["id"].isNull() || + items[i]["filename"].isNull() || + items[i]["file_hash"].isNull() || + items[i]["src_node"].isNull() || + items[i]["node_group"].isNull()) + { + dfs_debug << "bad item, not complete json cannot parse"; + return -1; + } + + //id,container,filename,node_group,src_node + DfsFileInfo objFileInfo; + objFileInfo.id = items[i]["id"].asString(); + objFileInfo.container = items[i]["container"].asString(); + objFileInfo.src_node = items[i]["src_node"].asString(); + objFileInfo.filename = items[i]["filename"].asString(); + objFileInfo.node_group = items[i]["node_group"].asString(); + objFileInfo.filehash = items[i]["file_hash"].asString(); + + fileInfos.insert(std::pair(objFileInfo.id, objFileInfo)); + } + } + + return 0; +} + +int DfsFileInfoScanner::getLocalFileInfos(map& fileInfos) +{ + //get all files by container ids + for (auto & container : m_Containers) + { + //all full file path + vector fullFiles; + + string strBasePath = DfsFileServer::getInstance()->m_StoreRootPath; + string strDir; + createDirectoryByContainer(strBasePath, container, strDir); + + listAllFiles(strDir, fullFiles, false); + dfs_debug << "*****#### the local fs has: " << (int)fullFiles.size() << "files\n"; + + for (auto & file : fullFiles) + { + //fill the info: id,container,filename,node_group,src_node + vector vecStr; + SplitString(file, '_', vecStr);//to-do: '_'转义需要做 + + if (vecStr.size() == 2)//fileid0001_filename0001 + { + DfsFileInfo objFileInfo; + objFileInfo.id = vecStr[0]; + objFileInfo.filename = vecStr[1]; + objFileInfo.container = container; + objFileInfo.node_group = DfsFileServer::getInstance()->m_NodeGroup; + + string strFile = strDir; + strFile += "/"; + strFile += file; + // string strMd5 = ""; + // if(md5(strFile, strMd5, objFileInfo.file_hash) != 0) + // { + // printf("the file: %s access error !\n", strFile.c_str()); + // return -1; + // } + + fileInfos.insert(std::pair(objFileInfo.id, objFileInfo)); + } + } + } + + for (auto & f : fileInfos) + { + dfs_debug << "********** the local file: " << f.first.data() << "\n"; + } + dfs_debug << "****** getLocalFileInfos done, total="<< (int)fileInfos.size() << "\n"; + return 0; +} + +int DfsFileInfoScanner::md5(const string& filepath, string& md5) +{ + MD5_CTX ctx; + ms_MD5_Init(&ctx); + + char szBuf[4096]; + int bytes = 0; + FILE* fp = fopen(filepath.data(), "rb"); + if (!fp) + return -1; + + md5.clear(); + while((bytes=fread(szBuf, 1, sizeof(szBuf), fp)) > 0) + { + ms_MD5_Update(&ctx, szBuf, bytes); + } + fclose(fp); + + unsigned char szResult[16] = {0}; + memset(szResult, 0, 16); + ms_MD5_Final(szResult, &ctx); + + char szTmp[32]; + memset(szTmp, 0, sizeof(szTmp)); + for (size_t i = 0; i < 16; ++i) + { + snprintf(szTmp, sizeof(szTmp), "%02X", szResult[i]); + md5.append(szTmp, strlen(szTmp)); + } + + return 0; +} + +int DfsFileInfoScanner::processFileinfoInit(map& localFileInfos, \ + map& fileInfos) +{ + //create delete, modify tasks + for (auto &info : localFileInfos) + { + //1. file not exists + if (fileInfos.find(info.first) == fileInfos.end())//not exists, delete file + { + //it is delete file task + //id, container, filename, owner, src_node, node_group, operation;//TaskOperation + dfs_debug << "***** to delete a file id: %s" << info.first.data() << "\n"; + + string strFilePath; + DfsFileOperationManager::getInstance()->delFile(info.second, strFilePath); + continue; + } + + //2. file exist + //if modify filename + if (info.second.filename != fileInfos[info.first].filename) + { + dfs_debug << "***** to modify a file id: %s " << info.first.data() << "***** \n"; + DfsFileOperationManager::getInstance()->modifyFile(info.second); + continue; + } + } + + //download task + for(auto & file : fileInfos) + { + if (localFileInfos.find(file.first) == localFileInfos.end()) + { + //检查文件是否存在 + string strDownDir; + createDirectoryByContainer(m_BasePath, file.second.container, strDownDir); + + string strFullFile; + string strFullFileBak; + createDfsFileNames(strDownDir, file.second.id, file.second.filename, strFullFile, strFullFileBak); + + string strHost; + int port = 0; + if (!ChkFileExists(strFullFile) && validateSourceNode(file.second.src_node, strHost, port)) + { + dfs_debug << "*** add a download task, fileid: " << file.first.data() << "src node: " << file.second.src_node.data() << "\n"; + DfsFileTask objTask; + objTask.id = file.second.id; + objTask.container = file.second.container; + objTask.filename = file.second.filename; + objTask.filehash = file.second.filehash; + objTask.owner = file.second.owner; + objTask.src_node = file.second.src_node; + objTask.node_group = file.second.node_group; + objTask.host = strHost; + objTask.port = port; + objTask.operation = DfsFileTask::DOWNLOAD; + objTask.directory = strDownDir; + m_DownloadFileInfos.insert(std::pair(file.first, objTask)); + } + else + { + dfs_debug << "*** no need to down file fileid: " << file.first.data() << "src node: " << file.second.src_node.data() << ", filepath: "<< strFullFile.data() << "\n"; + } + } + } + + m_CacheFileInfos = fileInfos; + return 0; +} + +int DfsFileInfoScanner::generateTasks(map& fileInfos) +{ + //m_FileInfoMap + processFileinfoInit(m_CacheFileInfos, fileInfos); + return 0; +} + +bool DfsFileInfoScanner::validateSourceNode(const string& src_node, string& fileHost, int& filePort) +{ + //fetch src node info + string fileSeverJson; + if (0 != findServerInfo(src_node, fileSeverJson)) + { + dfs_warn << "**** cannot retrieve the src node : " << src_node.data() <<"info\n"; + return false; + } + + //parse the json + dfs_debug << "find the src node: " << fileSeverJson; + Json::Reader reader; + Json::Value root; + string strRet; + if (fileSeverJson.size() <= 0 || !reader.parse(fileSeverJson, root)) + { + dfs_warn << "parse json: " << fileSeverJson.c_str() << " failed\n"; + return false; + } + + if (root["ret"].isNull() || root["data"].isNull()) + { + dfs_warn << "bad json: " << fileSeverJson.c_str() << " not complete\n"; + return false; + } + + strRet = root["ret"].asString(); + Json::Value &data = root["data"]; + if (data["items"].isNull() || !data["items"].isArray()) + { + dfs_warn << "the data node is invalid \n"; + return false; + } + + Json::Value &items = data["items"]; + //parse items to fileinfos + //MUST: id; host; port; updateTime; organization; position; group; info; + string id; + string group; + string host; + int port; + int enable = 0; + int count = items.size(); + if (count <= 0) + { + dfs_warn << "cannot find the src node: " << src_node.data() << "\n"; + return false; + } + + const int i = 0; + if (items[i]["id"].isNull() || + items[i]["host"].isNull() || + items[i]["port"].isNull() || + items[i]["group"].isNull() || + items[i]["enable"].isNull()) + { + dfs_warn << "bad item, not complete json cannot parse"; + return false; + } + + //id; host; port; updateTime; organization; position; group; info; + id = items[i]["id"].asString(); + group = items[i]["group"].asString(); + port = items[i]["port"].asInt(); + host = items[i]["host"].asString(); + enable = items[i]["enable"].asInt(); + + //check group + if (group != m_GroupId) + { + dfs_warn << "the src node group in blockchains is : "<< group.data() << " current group: " << m_GroupId.data() << "\n"; + return false; + } + + if (enable == 0) + { + dfs_warn << "the src node: " << id << " is not on service !"; + return false; + } + + fileHost = host; + filePort = port; + return true; +} diff --git a/libweb3jsonrpc/dfs/DfsFileInfoScanner.h b/libweb3jsonrpc/dfs/DfsFileInfoScanner.h new file mode 100644 index 0000000000..f74164e30c --- /dev/null +++ b/libweb3jsonrpc/dfs/DfsFileInfoScanner.h @@ -0,0 +1,100 @@ +#pragma once + +#include +#include +#include +#include +#include "DfsBase.h" +#include + + +using std::string; +using std::map; +using std::vector; + + + +namespace dev +{ + +namespace rpc +{ + +namespace fs +{ + +enum class FileSyncState : short +{ + SYNC_NOT_INITED = 0, + SYNC_WAIT_INIT = 1, + SYNC_INIT_OK = 2 +}; + +class DfsFileInfoScanner : public Worker +{ +public: + DfsFileInfoScanner(); + ~DfsFileInfoScanner(); + + +public: + //init + int init(const vector &containers, void* client); + + //stop + void stop(); + + +protected: + //thread every cycle + void doTask(); + + /// Called after thread is started from startWorking(). + virtual void startedWorking() override; + + /// Called continuously following sleep for m_idleWaitMs. + virtual void doWork() override; + + +private: + int getContractFileInfos(map& fileInfos); + + //int parseFileInfoList(const string& strjson, map& fileInfos); + int parseFileInfoList(const vector& vecJson, map& fileInfos); + + int getLocalFileInfos(map& fileInfos); + + int md5(const string& filepath, string& md5); + + int processFileinfoInit(map& localFileInfos, map& fileInfos); + + int generateTasks(map& fileInfos); + + bool validateSourceNode(const string& src_node, string& fileHost, int& filePort); + + bool checkBlockInit(); + + int queryGroupFileInfo(const std::string& group, vector& result); + + +private: + FileSyncState m_SyncState; + string m_BasePath; + string m_SrcNode; + string m_GroupId; + + vector m_Containers; + + pthread_mutex_t m_Mutex; + map m_DownloadFileInfos; + map m_CacheFileInfos; + + int m_InitBlockNum; + int m_TimeLastCheck; + +}; + +} + +} +} \ No newline at end of file diff --git a/libweb3jsonrpc/dfs/DfsFileOperationManager.cpp b/libweb3jsonrpc/dfs/DfsFileOperationManager.cpp new file mode 100644 index 0000000000..0eea1725c9 --- /dev/null +++ b/libweb3jsonrpc/dfs/DfsFileOperationManager.cpp @@ -0,0 +1,132 @@ +#include "DfsFileOperationManager.h" +#include "DfsCommon.h" +#include "DfsFileServer.h" +#include "DfsConst.h" +#include "string.h" + + +using namespace dev::rpc::fs; + + + +DfsFileOperationManager::DfsFileOperationManager() +{ + pthread_mutexattr_t Attr; + + pthread_mutexattr_init(&Attr); + pthread_mutexattr_settype(&Attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&m_Mutex, &Attr); +} + +DfsFileOperationManager::~DfsFileOperationManager() +{ + pthread_mutex_destroy(&m_Mutex); +} + +DfsFileOperationManager* DfsFileOperationManager::getInstance() +{ + static DfsFileOperationManager sInstance; + return &sInstance; +} + +int DfsFileOperationManager::delFile(const DfsFileInfo& fileinfo, string& deleteFilePath) +{ + string strBasePath = DfsFileServer::getInstance()->m_StoreRootPath; + string strDir; + createDirectoryByContainer(strBasePath, fileinfo.container, strDir); + + //find the file shortest + if(!findShortestAsFile(strDir, fileinfo.id, deleteFilePath)) + { + dfs_warn << "cannot find the file_id: " << fileinfo.id.c_str() << "\n"; + return -1; + } + + string strBakFile = deleteFilePath; + strBakFile += "_"; + strBakFile += currentTimestamp(); + + pthread_mutex_lock(&m_Mutex); + //rename the file + FileMv(deleteFilePath, strBakFile); + pthread_mutex_unlock(&m_Mutex); + + dfs_debug << "delete file, use rename file " << deleteFilePath.data() << " to " << strBakFile.data() << "\n"; + return 0; +} + + +int DfsFileOperationManager::modifyFile(const DfsFileInfo& fileinfo) +{ + string strBasePath = DfsFileServer::getInstance()->m_StoreRootPath; + string strDir; + createDirectoryByContainer(strBasePath, fileinfo.container, strDir); + + //find the file shortest + string strFullFileFound; + if(!findShortestAsFile(strDir, fileinfo.id, strFullFileFound)) + { + dfs_warn << "cannot find the file_id: "<< fileinfo.id.c_str(); + return -1; + } + + string strNewFile = strDir; + strNewFile += "/"; + char szFile[256]; + memset(szFile, 0, 256); + snprintf(szFile, sizeof(szFile), "%s_%s", fileinfo.id.c_str(), fileinfo.filename.c_str()); + strNewFile += szFile; + + pthread_mutex_lock(&m_Mutex); + //rename the file + FileMv(strFullFileFound, strNewFile); + pthread_mutex_unlock(&m_Mutex); + + return 0; +} + +bool DfsFileOperationManager::findShortestAsFile(const string& dir, const string& file_id, string& full_file) +{ + //find the file + vector files; + vector filesFound; + listAllFiles(dir, files); + for (std::vector::iterator file = files.begin(); file != files.end(); ++file) + { + size_t pos = file->find(file_id); + if (pos != string::npos && pos == 0)//begin with fileid + { + filesFound.push_back(*file); + } + } + + if (filesFound.empty()) + { + dfs_warn << "file id: "<< file_id.c_str() << "not found\n"; + return false; + } + + string strFileFound = filesFound.front(); + size_t length = filesFound.front().size(); + for (std::vector::iterator f = filesFound.begin(); f != filesFound.end(); ++f) + { + if (length > f->size())//get the shortest one + { + length = f->size(); + strFileFound = *f; + } + } + + vector vecStr; + SplitString(strFileFound, '_', vecStr); + if (vecStr.size() != 2) + { + dfs_warn << "cannot find the existing file, shortest file: "< +#include +#include + +#include "DfsBase.h" + +using std::string; + + +namespace dev +{ + +namespace rpc +{ + +namespace fs +{ + +class DfsFileOperationManager +{ +public: + DfsFileOperationManager(); + virtual ~DfsFileOperationManager(); + + static DfsFileOperationManager* getInstance(); + + +public: + int delFile(const DfsFileInfo& fileinfo, string& deleteFilePath); + + int modifyFile(const DfsFileInfo& fileinfo); + + +private: + bool findShortestAsFile(const string& dir, const string& file_id, string& full_file); + +private: + pthread_mutex_t m_Mutex; + // + +}; + +} +} +} \ No newline at end of file diff --git a/libweb3jsonrpc/dfs/DfsFileRecorder.cpp b/libweb3jsonrpc/dfs/DfsFileRecorder.cpp new file mode 100644 index 0000000000..ba705ed08b --- /dev/null +++ b/libweb3jsonrpc/dfs/DfsFileRecorder.cpp @@ -0,0 +1,91 @@ +#include "DfsFileRecorder.h" +#include "DfsCommon.h" +#include "DfsConst.h" +#include +#include "DfsBase.h" + + +using std::string; +using namespace dev::rpc::fs; + + +DfsFileRecorder::DfsFileRecorder() +{} + + +DfsFileRecorder::~DfsFileRecorder() +{} + + +static string convertOperation(int operation); + +int DfsFileRecorder::writeRecord(const DfsFileTask& task) +{ + string strFile = task.directory; + strFile += "/"; + strFile += JZ_FILE_RECORD_FILE; + FILE* file = NULL; + if (!ChkFileExists(strFile)) + { + file = fopen(strFile.data(), "wb"); + } + else + { + file = fopen(strFile.data(), "ab"); + } + + if (file == NULL) + { + dfs_warn << "**** error ==> open file: " << strFile.data(); + return -1; + } + + struct timeval objTime; + gettimeofday(&objTime, NULL); + fprintf(file, "%s, %s, %s, %ld\n", task.id.data(), task.filename.data(), convertOperation(task.operation).data(), (objTime.tv_sec * 1000000 + objTime.tv_usec)/1000); + fclose(file); + return 0; +} + + + static string convertOperation(int operation) +{ + /** + enum TaskOperation + { + UPLOAD = 0, + DELETE = 1, + MODIFY = 2, + DOWNLOAD = 3 + }; + */ + string op = "UNKOWN"; + switch(operation) + { + case DfsFileTask::UPLOAD_START: + op = "UPLOAD_START"; + break; + case DfsFileTask::UPLOAD: + op = "UPLOAD"; + break; + case DfsFileTask::DELETE: + op = "DELETE"; + break; + case DfsFileTask::MODIFY: + op = "MODIFY"; + break; + case DfsFileTask::DOWNLOAD_START: + op = "DOWNLOAD_START"; + break; + case DfsFileTask::DOWNLOAD_FAIL: + op = "DOWNLOAD_FAIL"; + break; + case DfsFileTask::DOWNLOAD: + op = "DOWNLOAD"; + break; + default: + break; + } + + return op; +} \ No newline at end of file diff --git a/libweb3jsonrpc/dfs/DfsFileRecorder.h b/libweb3jsonrpc/dfs/DfsFileRecorder.h new file mode 100644 index 0000000000..9a95b9d764 --- /dev/null +++ b/libweb3jsonrpc/dfs/DfsFileRecorder.h @@ -0,0 +1,31 @@ +#pragma once + +#include "DfsBase.h" + + +namespace dev +{ + +namespace rpc +{ + +namespace fs +{ + +class DfsFileRecorder +{ +public: + DfsFileRecorder(); + ~DfsFileRecorder(); + + +public: + //write the directory, save to the "fileRecrod.dat" + static int writeRecord(const DfsFileTask& task); + + +}; + +} +} +} diff --git a/libweb3jsonrpc/dfs/DfsFileServer.cpp b/libweb3jsonrpc/dfs/DfsFileServer.cpp new file mode 100644 index 0000000000..2dd863a557 --- /dev/null +++ b/libweb3jsonrpc/dfs/DfsFileServer.cpp @@ -0,0 +1,501 @@ +#include "DfsFileServer.h" +#include +#include +#include "DfsConst.h" +#include "DfsCommon.h" +#include "DfsJsonUtils.h" +#include "DfsUploadHandler.h" +#include "DfsDownloadHandler.h" +#include "DfsDeleteFileHandler.h" +#include "DfsModifyFileHandler.h" +#include "DfsMd5.h" +#include + + + +using namespace dev::rpc::fs; + + +DfsFileServer::DfsFileServer() +{ + m_StoreRootPath = ""; + m_NodeGroup = ""; + m_NodeId = ""; + m_Inited = false; +} + +DfsFileServer::~DfsFileServer() +{ + if (m_Inited) + { + destory(); + } +} + +static DfsFileServer *pInstance = NULL; +DfsFileServer *DfsFileServer::getInstance() +{ + if (pInstance == NULL) + { + static DfsFileServer objInstance; + pInstance = &objInstance; + } + + return pInstance; +} + +void DfsFileServer::destory() +{ + m_DfsFileInfoScanner.stop(); + + map >::iterator iter = m_HandlerMap.begin(); + for (; iter != m_HandlerMap.end(); ++iter) + { + map::iterator iter_handler = iter->second.begin(); + for (; iter_handler != iter->second.end(); ++iter_handler) + { + delete iter_handler->second; + } + } + + m_HandlerMap.clear(); + m_Containers.clear(); + m_Inited = false; +} + +//initiate file storage repository tree +int DfsFileServer::init(const string& store_root, const string& group, const string& node, dev::eth::Client* ethClient) +{ + if (m_Inited) + { + LOG(ERROR) << "dfs already inited !"; + return 0; + } + + if (store_root.empty() || group.empty() || node.empty()) + { + LOG(ERROR) << "dfs init param invalid, null param exists !"; + return -1; + } + + //relative path + char szDir[4096] = {0}; + if (NULL == getcwd(szDir, 4096)) + { + LOG(ERROR) << "cannot getcwd, system error "; + return -1; + } + + if (store_root.empty() || group.empty() || node.empty()) + { + LOG(ERROR) << "dfs storagePath, group, node is invalid !"; + return -1; + } + + if (store_root[0] == '.' && store_root[1] == '/') + { + m_StoreRootPath = szDir; + m_StoreRootPath += "/"; + m_StoreRootPath += store_root.substr(2); + } + else if (store_root[0] == '/') + { + m_StoreRootPath = store_root; + } + else + { + m_StoreRootPath = szDir; + m_StoreRootPath += "/"; + m_StoreRootPath += store_root; + } + + if (m_StoreRootPath[m_StoreRootPath.size()-1] == '/') + { + m_StoreRootPath.erase(m_StoreRootPath.size()-1);//caus we will add "/" later + } + + m_NodeGroup = group; + m_NodeId = node; + + m_Containers.clear(); + m_Containers.push_back(JZ_CONTAINER_FILES); + + dfs_debug << "****#### hey, init the fileserver! base: " << m_StoreRootPath.data() <<" group: " < >::iterator iter = m_HandlerMap.find(version); + if (iter == m_HandlerMap.end()) + { + map URL_Handlers; + m_HandlerMap.insert(std::pair >(version, URL_Handlers)); + + iter = m_HandlerMap.find(version); + } + + map::iterator iter_handler = iter->second.find(method); + if (iter_handler != iter->second.end()) + { + LOG(ERROR) << "http handler already exists, method: " <second.insert(std::pair(method, handler)); + return 0; +} + +//filter ilegal request of file process request +int DfsFileServer::filter(const string &url, const string &method) +{ + DfsUrlInfo url_info; + + //parse the url line + //module, version, container_id, file_id + if (0 != parserURL(url, url_info)) + { + return -1; + } + + if (m_HandlerMap.find(url_info.version) == m_HandlerMap.end()) + { + LOG(ERROR) << "cannot find the version:" < 1 && strUrl[0] == '/') + { + strUrl = strUrl.substr(1); + } + else + { + LOG(ERROR) << "url not enough for version\n"; + return -1; + } + + //version + if (strUrl.find("/") == string::npos) + { + LOG(ERROR) << "url not enough, just has version\n"; + return -1; + } + version = strUrl.substr(0, strUrl.find("/")); + if (m_HandlerMap.find(version) == m_HandlerMap.end()) + { + LOG(ERROR) << "version:" << version.data() <<" not register, not support !\n"; + return -1; + } + + //container_id [optional] + strUrl = strUrl.substr(strUrl.find("/") + 1); + if (strUrl.find("/") == string::npos) + { + url_info.module = module; + url_info.version = version; + LOG(ERROR) << "not find container: "<< url_info.container_id.data(); + return 0; + } + + if (strUrl.find("/") == string::npos) + { + url_info.module = module; + url_info.version = version; + container_id = strUrl; + url_info.container_id = container_id; + return 0; + } + else + { + container_id = strUrl.substr(0, strUrl.find("/")); + } + + + //file_id [optional] + file_id = strUrl.substr(strUrl.find("/") + 1); + + url_info.module = module; + url_info.version = version; + url_info.file_id = file_id; + url_info.container_id = container_id; + return 0; +} + +//find the specfic handler +IUrlHandler * DfsFileServer::getHandler(const string &version, const string &method) +{ + if (m_HandlerMap.find(version) == m_HandlerMap.end()) + { + LOG(ERROR) << "cannot find the version: " << version.data(); + return NULL; + } + + if (m_HandlerMap[version].find(method) == m_HandlerMap[version].end()) + { + LOG(ERROR) << "not support the method: " << method.data(); + return NULL; + } + + return m_HandlerMap[version][method]; +} + +bool DfsFileServer::checkServiceAvailable() +{ + //check service enable state + bool enable = false; + if (0 != checkServiceNode(m_NodeId, enable)) + { + LOG(ERROR) << "check service enable state failed ! nodeid : " << m_NodeId; + return false; + } + + return enable; +} + +//handle upload, download, revise file, delete file +int DfsFileServer::handle(DfsHttpInfo *http_info)//http_info有内部handler释放 +{ + //check if file service is enable for the server + if (!checkServiceAvailable()) + { + LOG(ERROR) << "###!!! file service of the nodeid: " << m_NodeId << " is disable !"; + string strJson = DfsJsonUtils::createCommonRsp(MHD_HTTP_SERVICE_UNAVAILABLE, MHD_HTTP_SERVICE_UNAVAILABLE, "service not available"); + return IUrlHandler::send_page(http_info->connection, strJson.data(), MHD_HTTP_SERVICE_UNAVAILABLE); + } + + DfsUrlInfo url_info; + if (0 != parserURL(string(http_info->url), url_info)) + { + LOG(ERROR) << "bad request, url: " <url <<" method:" <method << "\n"; + + string strJson = DfsJsonUtils::createCommonRsp(MHD_HTTP_BAD_REQUEST, MHD_HTTP_BAD_REQUEST, "bad request, check url or parameters"); + return IUrlHandler::send_page(http_info->connection, strJson.data(), MHD_HTTP_BAD_REQUEST); + } + + map::iterator iterFind = m_HandlerMap[url_info.version].find(http_info->method); + if (iterFind == m_HandlerMap[url_info.version].end()) + { + LOG(ERROR) << "cannot find the handle for method: " <method; + + string strJson = DfsJsonUtils::createCommonRsp(MHD_HTTP_METHOD_NOT_ALLOWED, MHD_HTTP_METHOD_NOT_ALLOWED, "bad method or request"); + return IUrlHandler::send_page(http_info->connection, strJson.data(), MHD_HTTP_METHOD_NOT_ALLOWED); + } + + return iterFind->second->handle(http_info, &url_info); +} + + +//iniatate the storage +int DfsFileServer::init_storage(const string &store_root) +{ + dfs_debug << "##@@@ init_storage ###"; + m_TempStorePath = store_root; + m_TempStorePath += "/"; + m_TempStorePath += "temp"; + + if(!ChkDirExists(store_root.c_str())) + { + //create store_root directory + if (!createFileDir(store_root)) + { + LOG(ERROR) << "create base directory: " << store_root.data() << " failed !\n"; + return -1; + } + + //create temp file store path + if (!createFileDir(m_TempStorePath)) + { + LOG(ERROR) << "create Temp file store directory: " << store_root.data() << " failed !\n"; + return -1; + } + } + else + { + if(ChkDirExists(m_TempStorePath.c_str())) + { + //clean all temp files + std::vector vecFiles; + listAllFiles(m_TempStorePath, vecFiles, true); + for (auto &file : vecFiles) + { + FileRm(file); + } + + } + else + { + //create temp file store path + if (!createFileDir(m_TempStorePath)) + { + LOG(ERROR) << "create Temp file store directory: " << store_root.data() << " failed !\n"; + return -1; + } + } + } + + //calculate the result of "files" + for (std::vector::const_iterator container = m_Containers.begin(); container != m_Containers.end(); ++container) + { + dfs_debug << "#### create directory for container_id: " << container->data() <<"\n"; + string strDirFiles; + string firstDir; + string secondDir; + createDirectoryStringByContainer(*container, strDirFiles, firstDir, secondDir); + + dfs_debug << "#### create directory for container_id: " << container->data() <<", full directory: " << strDirFiles.data(); + + //first + if (!ChkDirExists(firstDir)) + { + if (!createFileDir(firstDir)) + { + LOG(ERROR) << "create directory: " << firstDir.c_str() <<" failed\n"; + return -1; + } + + dfs_debug << "create first storage files directory: " << firstDir.data(); + } + + //second/////////////// + if (!ChkDirExists(secondDir)) + { + if (!createFileDir(secondDir)) + { + LOG(ERROR) << "create directory: " << secondDir.c_str() <<" failed\n"; + return -1; + } + + dfs_debug << "create second storage files directory: " << secondDir.data(); + } + + if (!ChkDirExists(strDirFiles)) + { + if (!createFileDir(strDirFiles)) + { + LOG(ERROR) << "create directory: " << strDirFiles.c_str() <<" failed\n"; + return -1; + } + + dfs_debug << "create storage files directory: " << strDirFiles.data(); + } + } + + + return 0; +} + + +//create directory string by container id +void DfsFileServer::createDirectoryStringByContainer(const string &container, string &directory, string& first, string& second) +{ + directory.clear(); + if (container.empty()) + { + LOG(ERROR) << "the container is null \n"; + return; + } + + MD5_CTX ctx; + unsigned char szResult[16] = {0}; + memset(szResult, 0, 16); + ms_MD5_Init(&ctx); + ms_MD5_Update(&ctx, container.data(), container.size()); + ms_MD5_Final(szResult, &ctx); + unsigned char lowPart = szResult[0]; + unsigned char hignPart = szResult[8]; + + char szDirAppend[256] = {0}; + char szFirst[256] = {0}; + char szSecond[256] = {0}; + memset(szDirAppend, 0, 256); + snprintf(szDirAppend, 256, "%02X/%02X/%s", lowPart, hignPart, container.data()); + snprintf(szFirst, 256, "%02X", lowPart); + snprintf(szSecond, 256, "%02X/%02X", lowPart, hignPart); + + + directory = m_StoreRootPath; + directory += "/"; + directory += szDirAppend; + + first = m_StoreRootPath; + first += "/"; + first += szFirst; + + second = m_StoreRootPath; + second += "/"; + second += szSecond; +} + + +void DfsFileServer::request_completed (void *cls, + struct MHD_Connection *connection, + void **con_cls, + enum MHD_RequestTerminationCode toe) +{ + DfsConnectionInfo *con_info = (DfsConnectionInfo*)(*con_cls); + if (NULL == con_info) + { + return; + } + + IUrlHandler *pHandler = DfsFileServer::getInstance()->getHandler(con_info->version, con_info->method); + if (pHandler == NULL) + { + LOG(ERROR) << "cannot get dfs request handler !"; + return; + } + + pHandler->handle_request_completed(cls, connection, con_cls, toe); + + delete con_info; + *con_cls = NULL; +} diff --git a/libweb3jsonrpc/dfs/DfsFileServer.h b/libweb3jsonrpc/dfs/DfsFileServer.h new file mode 100644 index 0000000000..eb8c49bb16 --- /dev/null +++ b/libweb3jsonrpc/dfs/DfsFileServer.h @@ -0,0 +1,100 @@ +/** +**@file 文件处理服务模块 +*/ + +#pragma once + +#include +#include +#include +#include +#include "microhttpd.h" +#include "IUrlHandler.h" +#include "DfsContractCaller.h" +#include "DfsFileInfoScanner.h" + + + +using std::string; +using std::map; +using std::vector; + + +namespace dev +{ + +namespace rpc +{ + +namespace fs +{ + +class DfsFileServer +{ +private: + DfsFileServer(); + ~DfsFileServer(); + +public: + static DfsFileServer* getInstance(); + + +public: + //initiate file storage repository tree + int init(const string& store_root, const string& group, const string& node, dev::eth::Client* ethClient); + + //destory + void destory(); + + //filter ilegal file process request + int filter(const string &url, const string &method); + + //handle upload, download, revise file, delete file + int handle(DfsHttpInfo* http_info);//http_info有内部handler释放 + + //create directory string by container id + void createDirectoryStringByContainer(const string &container, string &directory, string& first, string& second); + + + static void request_completed (void *cls, + struct MHD_Connection *connection, + void **con_cls, + enum MHD_RequestTerminationCode toe); + + bool isInited() const{return m_Inited;}; + + //check if service node avaiable + bool checkServiceAvailable(); + +private: + //register request handler, module now is : "fs" + int registerHandler(const string& version, const string& method, IUrlHandler* handler); + + //find the specfic handler + IUrlHandler* getHandler(const string& version, const string& method); + + //parse url + int parserURL(const string& url, DfsUrlInfo& url_info); + + //iniatate the storage + int init_storage(const string& store_root); + + + +public: + string m_StoreRootPath; + string m_TempStorePath; + string m_NodeGroup; + string m_NodeId; + DfsFileInfoScanner m_DfsFileInfoScanner; + vector m_Containers; + +private: + map > m_HandlerMap;// > + bool m_Inited; + +}; + +} +} +} \ No newline at end of file diff --git a/libweb3jsonrpc/dfs/DfsHttpClient.cpp b/libweb3jsonrpc/dfs/DfsHttpClient.cpp new file mode 100644 index 0000000000..722da9066e --- /dev/null +++ b/libweb3jsonrpc/dfs/DfsHttpClient.cpp @@ -0,0 +1,121 @@ +#include "DfsHttpClient.h" +#include +#include +#include "DfsBase.h" + + +using namespace dev::rpc::fs; + + +DfsHttpClient::DfsHttpClient() +{ + m_Inited = false; + m_resp_code = 404; + m_error_code = -1; + m_strError = ""; +} + +DfsHttpClient::~DfsHttpClient() +{ + +} + +static size_t recv_response(void *ptr, size_t size, size_t nmemb, void *cls) +{ + if (cls == NULL) + return -1; + + DfsHttpClient *pClient = (DfsHttpClient*)cls; + return pClient->handle_recv_data(ptr, size, nmemb, cls); +} + +//init the curl components +void DfsHttpClient::init(const JzRequestInfo& req_info) +{ + m_Inited = true; + m_ReqInfo = req_info; +} + +//fill upload data and request to URL +int DfsHttpClient::request(const string& upload_data) +{ + if (m_ReqInfo.host.empty() || !m_Inited) + return -1; + + string strUrl = m_ReqInfo.host; + char szUrl[256]; + memset(szUrl, 0, sizeof(szUrl)); + snprintf(szUrl, sizeof(szUrl), ":%d/fs/%s/files/%s", m_ReqInfo.port, m_ReqInfo.version.c_str(), m_ReqInfo.file_id.c_str()); + strUrl += szUrl; + + CURL *curl; + CURLcode res; + + curl = curl_easy_init(); + if (!curl) + { + dfs_debug << "curl_easy_init() failed\n"; + return -1; + } + + curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str()); + curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, m_ReqInfo.method.c_str()); + + dfs_debug << "###1 do http client request: " << strUrl.data() << ", method: " << m_ReqInfo.method.c_str() << " start ###"; + //for reading data from response + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, recv_response); + m_ReqInfo.curl = curl; + fillUserData(m_ReqInfo); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, this); + + //for sending data to server + if (!upload_data.empty()) + { + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, upload_data.data()); + curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, upload_data.size()); + } + + //do request + res = curl_easy_perform(curl); + if(res != CURLE_OK) + { + dfs_debug << "URL: " << strUrl.data() << ", curl_easy_perform() failed: " << curl_easy_strerror(res); + curl_easy_cleanup(curl); + return -1; + } + + curl_easy_cleanup(curl); + dfs_debug << "###2 do http client request: " << strUrl.data() << ", method: " << m_ReqInfo.method.c_str() << " end ###"; + return 0; +} + + +int DfsHttpClient::parseRspJson(const string& json) +{ + //file info json: {\"fileid\\":\"file_1111\",\"filename\":\"file_name_111\"} + printf("input json: %s\n", json.c_str()); + Json::Reader reader; + Json::Value objValue; + if ( (json.size() <= 0) || !(reader.parse(json, objValue)) ) + { + dfs_warn << "parse json: " << json.c_str() <<"failed\n"; + return -1; + } + + if ( (!objValue["ret"].isNull()) && (!objValue["code"].isNull()) && (!objValue["info"].isNull()) ) + { + m_strError = objValue["info"].asString(); + m_resp_code = objValue["ret"].asInt(); + m_error_code = objValue["code"].asInt(); + } + else + { + dfs_warn << "bad json: " << json.c_str() <<"not complete\n"; + m_resp_code = -1; + m_error_code = -1; + m_strError = ""; + return -1; + } + + return 0; +} diff --git a/libweb3jsonrpc/dfs/DfsHttpClient.h b/libweb3jsonrpc/dfs/DfsHttpClient.h new file mode 100644 index 0000000000..d5c89692e9 --- /dev/null +++ b/libweb3jsonrpc/dfs/DfsHttpClient.h @@ -0,0 +1,100 @@ +#pragma once + +#include +#include +#include +#include + + +using std::string; + +namespace dev +{ + +namespace rpc +{ + +namespace fs +{ + +//eg. size_t write_data(void *ptr, size_t size, size_t nmemb, void *cls) +typedef size_t (*Callback_write_data)(void*, size_t, size_t, void *cls); + +typedef struct JzBuffer{ + int compacity; + int size; + char* data; +} JzBuffer; + +typedef struct JzRequestInfo { + string method; + string module;//must be "fs" now + string version; + string container_id; + string file_id; + string filename; + string filepath; + string filehash; + string host;//host:port + int port; + void *user_data; + CURL *curl; + JzRequestInfo(){ + filepath = ""; + filehash = ""; + method = ""; + module = "fs"; + version = "v1"; + container_id = "files"; + file_id = ""; + filename = ""; + host = ""; + port = 0; + user_data = NULL; + curl = NULL; + } +} JzRequestInfo; + + +class DfsHttpClient +{ +public: + DfsHttpClient(); + virtual ~DfsHttpClient(); + + +public: + //init the curl components + void init(const JzRequestInfo& req_info); + + //fill upload data and request to URL + int request(const string& upload_data); + + int getRespCode() const {return m_resp_code;}; + int getErrorCode() const {return m_error_code;}; + + const string& getMethod() const {return m_ReqInfo.method;} + + int parseRspJson(const string& json); + +public: + virtual int fillUserData(JzRequestInfo& req_info)=0; + virtual int endRequest()=0; + virtual size_t handle_recv_data(void *ptr, size_t size, size_t nmemb, void *cls)=0; + +protected: + bool m_Inited; + + int m_resp_code; + int m_error_code; + string m_strError; + + +public: + JzRequestInfo m_ReqInfo; + +}; + +} +} +} \ No newline at end of file diff --git a/libweb3jsonrpc/dfs/DfsJsonUtils.cpp b/libweb3jsonrpc/dfs/DfsJsonUtils.cpp new file mode 100644 index 0000000000..a27bf1e35c --- /dev/null +++ b/libweb3jsonrpc/dfs/DfsJsonUtils.cpp @@ -0,0 +1,32 @@ +#include "DfsJsonUtils.h" +#include +#include + + +using namespace dev::rpc::fs; + + +DfsJsonUtils::DfsJsonUtils() +{} + +DfsJsonUtils::~DfsJsonUtils() +{} + + +string DfsJsonUtils::createCommonRsp(int ret, int code, const string& info) +{ + char szTemp[1024] = {0}; + memset(szTemp, 0, 1024); + + snprintf(szTemp, sizeof(szTemp), "{\"ret\":%d,\"code\":%d,\"info\":\"%s\"}", ret, code, info.c_str()); + return szTemp; +} + +string DfsJsonUtils::createCommonRsp(int ret, int code, const string& info, const string& hash) +{ + char szTemp[1024] = {0}; + memset(szTemp, 0, 1024); + + snprintf(szTemp, sizeof(szTemp), "{\"ret\":%d,\"code\":%d,\"hash\":\"%s\",\"info\":\"%s\"}", ret, code, hash.data(), info.c_str()); + return szTemp; +} diff --git a/libweb3jsonrpc/dfs/DfsJsonUtils.h b/libweb3jsonrpc/dfs/DfsJsonUtils.h new file mode 100644 index 0000000000..e1493ffcc8 --- /dev/null +++ b/libweb3jsonrpc/dfs/DfsJsonUtils.h @@ -0,0 +1,32 @@ +#pragma once + +#include +#include + +using namespace std; + +namespace dev +{ + +namespace rpc +{ + +namespace fs +{ + +class DfsJsonUtils +{ +public: + DfsJsonUtils(); + ~DfsJsonUtils(); + + +public: + static string createCommonRsp(int ret, int code, const string& info); + static string createCommonRsp(int ret, int code, const string& info, const string& hash); +}; + +} +} +} + diff --git a/libweb3jsonrpc/dfs/DfsMd5.cpp b/libweb3jsonrpc/dfs/DfsMd5.cpp new file mode 100644 index 0000000000..7530faf245 --- /dev/null +++ b/libweb3jsonrpc/dfs/DfsMd5.cpp @@ -0,0 +1,334 @@ +/* + * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc. + * MD5 Message-Digest Algorithm (RFC 1321). + * + * Homepage: + * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5 + * + * Author: + * Alexander Peslyak, better known as Solar Designer + * + * This software was written by Alexander Peslyak in 2001. No copyright is + * claimed, and the software is hereby placed in the public domain. + * In case this attempt to disclaim copyright and place the software in the + * public domain is deemed null and void, then the software is + * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the + * general public under the following terms: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted. + * + * There's ABSOLUTELY NO WARRANTY, express or implied. + * + * (This is a heavily cut-down "BSD license".) + * + * This differs from Colin Plumb's older public domain implementation in that + * no exactly 32-bit integer data type is required (any 32-bit or wider + * unsigned integer data type will do), there's no compile-time endianness + * configuration, and the function prototypes match OpenSSL's. No code from + * Colin Plumb's implementation has been reused; this comment merely compares + * the properties of the two independent implementations. + * + * The primary goals of this implementation are portability and ease of use. + * It is meant to be fast, but not as fast as possible. Some known + * optimizations are not included to reduce source code size and avoid + * compile-time configuration. + */ + +#include +#include "DfsMd5.h" + +using namespace dev::rpc::fs; + +/* + * The basic MD5 functions. + * + * F and G are optimized compared to their RFC 1321 definitions for + * architectures that lack an AND-NOT instruction, just like in Colin Plumb's + * implementation. + */ +#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) +#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y)))) +#define H(x, y, z) (((x) ^ (y)) ^ (z)) +#define H2(x, y, z) ((x) ^ ((y) ^ (z))) +#define I(x, y, z) ((y) ^ ((x) | ~(z))) + +/* + * The MD5 transformation for all four rounds. + */ +#define STEP(f, a, b, c, d, x, t, s) \ + (a) += f((b), (c), (d)) + (x) + (t); \ + (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \ + (a) += (b); + +/* + * SET reads 4 input bytes in little-endian byte order and stores them in a + * properly aligned word in host byte order. + * + * The check for little-endian architectures that tolerate unaligned memory + * accesses is just an optimization. Nothing will break if it fails to detect + * a suitable architecture. + * + * Unfortunately, this optimization may be a C strict aliasing rules violation + * if the caller's data buffer has effective type that cannot be aliased by + * MD5_u32plus. In practice, this problem may occur if these MD5 routines are + * inlined into a calling function, or with future and dangerously advanced + * link-time optimizations. For the time being, keeping these MD5 routines in + * their own translation unit avoids the problem. + */ +#if defined(__i386__) || defined(__x86_64__) || defined(__vax__) +#define SET(n) \ + (*(MD5_u32plus *)&ptr[(n) * 4]) +#define GET(n) \ + SET(n) +#else +#define SET(n) \ + (ctx->block[(n)] = \ + (MD5_u32plus)ptr[(n) * 4] | \ + ((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \ + ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \ + ((MD5_u32plus)ptr[(n) * 4 + 3] << 24)) +#define GET(n) \ + (ctx->block[(n)]) +#endif + +/* + * This processes one or more 64-byte data blocks, but does NOT update the bit + * counters. There are no alignment requirements. + */ +static const void *body(MD5_CTX *ctx, const void *data, unsigned long size) +{ + const unsigned char *ptr; + MD5_u32plus a, b, c, d; + MD5_u32plus saved_a, saved_b, saved_c, saved_d; + + ptr = (const unsigned char *)data; + + a = ctx->a; + b = ctx->b; + c = ctx->c; + d = ctx->d; + + do { + saved_a = a; + saved_b = b; + saved_c = c; + saved_d = d; + +/* Round 1 */ + STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7) + STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12) + STEP(F, c, d, a, b, SET(2), 0x242070db, 17) + STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22) + STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7) + STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12) + STEP(F, c, d, a, b, SET(6), 0xa8304613, 17) + STEP(F, b, c, d, a, SET(7), 0xfd469501, 22) + STEP(F, a, b, c, d, SET(8), 0x698098d8, 7) + STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12) + STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17) + STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22) + STEP(F, a, b, c, d, SET(12), 0x6b901122, 7) + STEP(F, d, a, b, c, SET(13), 0xfd987193, 12) + STEP(F, c, d, a, b, SET(14), 0xa679438e, 17) + STEP(F, b, c, d, a, SET(15), 0x49b40821, 22) + +/* Round 2 */ + STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5) + STEP(G, d, a, b, c, GET(6), 0xc040b340, 9) + STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14) + STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20) + STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5) + STEP(G, d, a, b, c, GET(10), 0x02441453, 9) + STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14) + STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20) + STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5) + STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9) + STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14) + STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20) + STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5) + STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9) + STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14) + STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20) + +/* Round 3 */ + STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4) + STEP(H2, d, a, b, c, GET(8), 0x8771f681, 11) + STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16) + STEP(H2, b, c, d, a, GET(14), 0xfde5380c, 23) + STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4) + STEP(H2, d, a, b, c, GET(4), 0x4bdecfa9, 11) + STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16) + STEP(H2, b, c, d, a, GET(10), 0xbebfbc70, 23) + STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4) + STEP(H2, d, a, b, c, GET(0), 0xeaa127fa, 11) + STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16) + STEP(H2, b, c, d, a, GET(6), 0x04881d05, 23) + STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4) + STEP(H2, d, a, b, c, GET(12), 0xe6db99e5, 11) + STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16) + STEP(H2, b, c, d, a, GET(2), 0xc4ac5665, 23) + +/* Round 4 */ + STEP(I, a, b, c, d, GET(0), 0xf4292244, 6) + STEP(I, d, a, b, c, GET(7), 0x432aff97, 10) + STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15) + STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21) + STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6) + STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10) + STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15) + STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21) + STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6) + STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10) + STEP(I, c, d, a, b, GET(6), 0xa3014314, 15) + STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21) + STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6) + STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10) + STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15) + STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21) + + a += saved_a; + b += saved_b; + c += saved_c; + d += saved_d; + + ptr += 64; + } while (size -= 64); + + ctx->a = a; + ctx->b = b; + ctx->c = c; + ctx->d = d; + + return ptr; +} + +namespace dev +{ + +namespace rpc +{ + +namespace fs +{ + +void ms_MD5_Init(MD5_CTX *ctx) +{ + ctx->a = 0x67452301; + ctx->b = 0xefcdab89; + ctx->c = 0x98badcfe; + ctx->d = 0x10325476; + + ctx->lo = 0; + ctx->hi = 0; +} + +void ms_MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size) +{ + MD5_u32plus saved_lo; + unsigned long used, available; + + saved_lo = ctx->lo; + if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo) + ctx->hi++; + ctx->hi += size >> 29; + + used = saved_lo & 0x3f; + + if (used) { + available = 64 - used; + + if (size < available) { + memcpy(&ctx->buffer[used], data, size); + return; + } + + memcpy(&ctx->buffer[used], data, available); + data = (const unsigned char *)data + available; + size -= available; + body(ctx, ctx->buffer, 64); + } + + if (size >= 64) { + data = body(ctx, data, size & ~(unsigned long)0x3f); + size &= 0x3f; + } + + memcpy(ctx->buffer, data, size); +} + +#define OUT(dst, src) \ + (dst)[0] = (unsigned char)(src); \ + (dst)[1] = (unsigned char)((src) >> 8); \ + (dst)[2] = (unsigned char)((src) >> 16); \ + (dst)[3] = (unsigned char)((src) >> 24); + +void ms_MD5_Final(unsigned char *result, MD5_CTX *ctx) +{ + unsigned long used, available; + + used = ctx->lo & 0x3f; + + ctx->buffer[used++] = 0x80; + + available = 64 - used; + + if (available < 8) { + memset(&ctx->buffer[used], 0, available); + body(ctx, ctx->buffer, 64); + used = 0; + available = 64; + } + + memset(&ctx->buffer[used], 0, available - 8); + + ctx->lo <<= 3; + OUT(&ctx->buffer[56], ctx->lo) + OUT(&ctx->buffer[60], ctx->hi) + + body(ctx, ctx->buffer, 64); + + OUT(&result[0], ctx->a) + OUT(&result[4], ctx->b) + OUT(&result[8], ctx->c) + OUT(&result[12], ctx->d) + + memset(ctx, 0, sizeof(*ctx)); +} + +int ms_md5(const string& filepath, string& md5) +{ + MD5_CTX ctx; + ms_MD5_Init(&ctx); + + char szBuf[4096]; + int bytes = 0; + FILE* fp = fopen(filepath.data(), "rb"); + if (!fp) + return -1; + + md5.clear(); + while((bytes=fread(szBuf, 1, sizeof(szBuf), fp)) > 0) + { + ms_MD5_Update(&ctx, szBuf, bytes); + } + fclose(fp); + + unsigned char szResult[16] = {0}; + memset(szResult, 0, 16); + ms_MD5_Final(szResult, &ctx); + + char szTmp[32]; + memset(szTmp, 0, sizeof(szTmp)); + for (size_t i = 0; i < 16; ++i) + { + snprintf(szTmp, sizeof(szTmp), "%02x", szResult[i]); + md5.append(szTmp, strlen(szTmp)); + } + + return 0; +} + +} +} +} \ No newline at end of file diff --git a/libweb3jsonrpc/dfs/DfsMd5.h b/libweb3jsonrpc/dfs/DfsMd5.h new file mode 100644 index 0000000000..fd4c16f669 --- /dev/null +++ b/libweb3jsonrpc/dfs/DfsMd5.h @@ -0,0 +1,72 @@ +/* + * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc. + * MD5 Message-Digest Algorithm (RFC 1321). + * + * Homepage: + * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5 + * + * Author: + * Alexander Peslyak, better known as Solar Designer + * + * This software was written by Alexander Peslyak in 2001. No copyright is + * claimed, and the software is hereby placed in the public domain. + * In case this attempt to disclaim copyright and place the software in the + * public domain is deemed null and void, then the software is + * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the + * general public under the following terms: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted. + * + * There's ABSOLUTELY NO WARRANTY, express or implied. + * + * See md5.c for more information. + */ + +#pragma once + + +#include +using std::string; + +namespace dev +{ + +namespace rpc +{ + +namespace fs +{ + + +/* Any 32-bit or wider unsigned integer data type will do */ +typedef unsigned int MD5_u32plus; + +typedef struct MD5_CTX { + MD5_u32plus lo, hi; + MD5_u32plus a, b, c, d; + unsigned char buffer[64]; + MD5_u32plus block[16]; +} MD5_CTX; + +#define MD5_DIGEST_LENGTH 16 + +#ifdef __cplusplus +extern "C" +{ +#endif// + + void ms_MD5_Init(MD5_CTX *ctx); + void ms_MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size); + void ms_MD5_Final(unsigned char *result, MD5_CTX *ctx); + +#ifdef __cplusplus +} +#endif// + +int ms_md5(const string& filepath, string& md5); + +} +} +} + diff --git a/libweb3jsonrpc/dfs/DfsModifyFileHandler.cpp b/libweb3jsonrpc/dfs/DfsModifyFileHandler.cpp new file mode 100644 index 0000000000..d4083ecbb7 --- /dev/null +++ b/libweb3jsonrpc/dfs/DfsModifyFileHandler.cpp @@ -0,0 +1,193 @@ +#include "DfsModifyFileHandler.h" +#include +#include +#include +#include "DfsCommon.h" +#include "DfsConst.h" +#include "DfsJsonUtils.h" +#include "DfsFileOperationManager.h" +#include "DfsFileServer.h" +#include "DfsFileRecorder.h" + + +using namespace dev::rpc::fs; + + +void DfsModifyFileHandler::handle_request_completed(void *cls, \ + struct MHD_Connection *connection, + void **con_cls, enum MHD_RequestTerminationCode toe) +{ + DfsConnectionInfo *con_info = (DfsConnectionInfo*)*con_cls; + (void)cls; + (void)connection; + (void)toe; + if (NULL == con_info) + return; + + dfs_debug << "the the request completed, data_len: "<< con_info->length; + + if (con_info->data) + { + dfs_debug << "**** the all recv json data: " << con_info->data; + delete [](con_info->data); + con_info->data = NULL; + con_info->length = 0; + } + + dfs_debug << "the modify request completed\n"; +} + +DfsModifyFileHandler::DfsModifyFileHandler(const string& version, const string &method) +: IUrlHandler(version, method) +{ + +} + +DfsModifyFileHandler::~DfsModifyFileHandler() +{ + +} + +//only modify filename +int DfsModifyFileHandler::handle(DfsHttpInfo* http_info, DfsUrlInfo* url_info) +{ + //PUT, container_id, file_id + if (0 != strcmp(http_info->method, JZ_HTTP_METHOD_PUT) \ + || url_info->container_id.empty() \ + || url_info->file_id.empty()) + { + dfs_warn << "bad request url: "<< http_info->url <<", method: " << http_info->method; + string strjson = DfsJsonUtils::createCommonRsp(MHD_HTTP_BAD_REQUEST, -1, "bad request, check url"); + return IUrlHandler::send_page(http_info->connection, strjson.c_str(), MHD_HTTP_BAD_REQUEST); + } + + DfsConnectionInfo *con_info = NULL; + dfs_debug << "request url: "<< http_info->url <<", method: " << http_info->method; + //file info json: {\"fileid\\":\"file_1111\",\"filename\":\"file_name_111\"} + if (*(http_info->ptr) == NULL)// + { + con_info = new DfsConnectionInfo; + con_info->method = JZ_HTTP_METHOD_PUT; + con_info->version = JZ_MODULE_VERSION_V1; + + if (*(http_info->upload_data_size) > 0) + { + con_info->length = *(http_info->upload_data_size); + con_info->data = new char[(*(http_info->upload_data_size))]; + memcpy(con_info->data, http_info->upload_data, *(http_info->upload_data_size)); + } + else + { + con_info->length = 0; + con_info->data = NULL; + } + + *(http_info->ptr) = con_info; + return MHD_YES; + } + + con_info = (DfsConnectionInfo*)*(http_info->ptr); + //recv data and append to buffer + if (*(http_info->upload_data_size) != 0) + { + char *pData = new char[(*(http_info->upload_data_size) + con_info->length)]; + memcpy(pData, con_info->data, con_info->length); + memcpy(pData + con_info->length, http_info->upload_data, *(http_info->upload_data_size)); + + con_info->length += *(http_info->upload_data_size); + delete []con_info->data; + con_info->data = pData; + + //consume data + *(http_info->upload_data_size) = 0; + + return MHD_YES; + } + else//recv done + { + dfs_debug << "recv request url: " <url <<" total: " << con_info->length <<"bytes \n"; + + //parse the json + string strjson(con_info->data, con_info->length); + DfsFileInfo objFileInfo; + objFileInfo.container = url_info->container_id; + string strRspJson; + int http_code = MHD_HTTP_OK; + if (0 != parseFileInfo(strjson, objFileInfo)) + { + http_code = MHD_HTTP_BAD_REQUEST; + strRspJson = DfsJsonUtils::createCommonRsp(http_code, -1, "bad input json cannot verify !"); + return IUrlHandler::send_page(http_info->connection, strRspJson.data(), http_code); + } + + if(!(objFileInfo.id == url_info->file_id)) + { + http_code = MHD_HTTP_BAD_REQUEST; + strRspJson = DfsJsonUtils::createCommonRsp(http_code, -1, "input fileid not consistent!"); + return IUrlHandler::send_page(http_info->connection, strRspJson.data(), http_code); + } + + //process rename file + if (0 != reviseFileInfo(objFileInfo)) + { + http_code = MHD_HTTP_INTERNAL_SERVER_ERROR; + strRspJson = DfsJsonUtils::createCommonRsp(http_code, -1, "input parameter not valid!"); + return IUrlHandler::send_page(http_info->connection, strRspJson.data(), http_code); + } + + //write modify file record + string strUpDir; + createDirectoryByContainer(DfsFileServer::getInstance()->m_StoreRootPath, con_info->container, strUpDir); + + + DfsFileTask objTask; + objTask.id = con_info->file_id; + objTask.filename = con_info->filename; + objTask.filename += " => "; + objTask.filename += objFileInfo.filename; + objTask.operation = DfsFileTask::MODIFY; + objTask.directory = strUpDir; + if (0 != DfsFileRecorder::writeRecord(objTask)) + { + dfs_warn << "## write file update record failed !!"; + } + + dfs_debug << "## modify file has completed ! "; + http_code = MHD_HTTP_OK; + strRspJson = DfsJsonUtils::createCommonRsp(http_code, 0, "OK"); + return IUrlHandler::send_page(http_info->connection, strRspJson.data(), http_code); + } +} + +int DfsModifyFileHandler::parseFileInfo(const string& json, DfsFileInfo& fileInfo) +{ + //file info json: {\"fileid\\":\"file_1111\",\"filename\":\"file_name_111\"} + dfs_debug << "input json: " << json.c_str(); + Json::Reader reader; + Json::Value objValue; + if (json.size() <= 0 || !reader.parse(json, objValue)) + { + dfs_warn << "bad parse json: " << json.c_str(); + return -1; + } + + if (!objValue["fileid"].isNull() && !objValue["filename"].isNull()) + { + fileInfo.id = objValue["fileid"].asString(); + fileInfo.filename = objValue["filename"].asString(); + } + else + { + dfs_warn << "bad parse json: " << json.c_str() << "not complete\n"; + return -1; + } + + return 0; +} + +//revise the file info +int DfsModifyFileHandler::reviseFileInfo(const DfsFileInfo& fileInfo) +{ + return DfsFileOperationManager::getInstance()->modifyFile(fileInfo); +} + diff --git a/libweb3jsonrpc/dfs/DfsModifyFileHandler.h b/libweb3jsonrpc/dfs/DfsModifyFileHandler.h new file mode 100644 index 0000000000..9645befd5c --- /dev/null +++ b/libweb3jsonrpc/dfs/DfsModifyFileHandler.h @@ -0,0 +1,38 @@ +#pragma once + +#include "IUrlHandler.h" + + +namespace dev +{ + +namespace rpc +{ + +namespace fs +{ + + +class DfsModifyFileHandler : public IUrlHandler +{ +public: + DfsModifyFileHandler(const string& version, const string &method); + virtual ~DfsModifyFileHandler(); + +public: + virtual int handle(DfsHttpInfo* http_info, DfsUrlInfo* url_info); + + virtual void handle_request_completed(void *cls, struct MHD_Connection *connection, + void **con_cls, enum MHD_RequestTerminationCode toe); + + //parse file info json: eg. file info json: {\"fileid\\":\"file_1111\",\"filename\":\"file_name_111\"} + int parseFileInfo(const string& json, DfsFileInfo& fileInfo); + + //revise the file info + int reviseFileInfo(const DfsFileInfo& fileInfo); + +}; + +} +} +} diff --git a/libweb3jsonrpc/dfs/DfsUploadHandler.cpp b/libweb3jsonrpc/dfs/DfsUploadHandler.cpp new file mode 100644 index 0000000000..50b173efd5 --- /dev/null +++ b/libweb3jsonrpc/dfs/DfsUploadHandler.cpp @@ -0,0 +1,363 @@ +#include "DfsUploadHandler.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "DfsMd5.h" +#include "DfsCommon.h" +#include "DfsConst.h" +#include "DfsJsonUtils.h" +#include "DfsFileServer.h" +#include "DfsFileRecorder.h" +#include "DfsMd5.h" + + + +#define POSTBUFFERSIZE 1024 +#define MAXCLIENTS 100 + + +using namespace dev::rpc::fs; + + + +static unsigned int nr_of_uploading_clients = 0; + +static int +iterate_post (void *coninfo_cls, + enum MHD_ValueKind kind, + const char *key, + const char *filename, + const char *content_type, + const char *transfer_encoding, + const char *data, + uint64_t off, + size_t size); + +void DfsUploadHandler::handle_request_completed(void *cls, + struct MHD_Connection *connection, + void **con_cls, + enum MHD_RequestTerminationCode toe) +{ + (void)cls; + (void)toe; + DfsConnectionInfo *con_info = (DfsConnectionInfo*)*con_cls; + + if (NULL == con_info) + return; + + if (0 == strcmp(con_info->method.data(), JZ_HTTP_METHOD_POST)) + { + if (NULL != con_info->postprocessor) + { + MHD_destroy_post_processor (con_info->postprocessor); + nr_of_uploading_clients--; + } + + if (con_info->fp) + { + fclose(con_info->fp); + con_info->fp = NULL; + + string strFile; + string strFileBak; + string strFileDir; + string strFirst; + string strSecond; + DfsFileServer::getInstance()->createDirectoryStringByContainer(con_info->container, strFileDir, strFirst, strSecond); + createDfsFileNames(strFileDir, con_info->file_id, con_info->filename, strFile, strFileBak); + + //file copy from temp to real store path + dfs_debug << "***** file copy, src: " << con_info->fp_path.data() <<", dst: " <fp_path, strFile); + FileRm(con_info->fp_path); + } + + if (con_info->data) + { + delete []con_info->data; + con_info->data = NULL; + } + } + + if (con_info->recv_bytes == 0) + { + dfs_debug << "upload interupt, response error, may already exist fileid: " << con_info->file_id.data(); + string strjson = DfsJsonUtils::createCommonRsp(MHD_HTTP_BAD_REQUEST, \ + -1, "request handle error"); + send_page (connection, + strjson.data(), + MHD_HTTP_BAD_REQUEST); + } + else + { + //检查文件是否存在 + string strUpDir; + createDirectoryByContainer(DfsFileServer::getInstance()->m_StoreRootPath, con_info->container, strUpDir); + + dfs_debug << "## upload has completed ! recv bytes: " << con_info->recv_bytes; + DfsFileTask objTask; + objTask.id = con_info->file_id; + objTask.filename = con_info->filename; + objTask.operation = DfsFileTask::UPLOAD; + objTask.directory = strUpDir; + if (0 != DfsFileRecorder::writeRecord(objTask)) + { + dfs_warn << "## write file update record failed !!"; + } + } +} + + +DfsUploadHandler::DfsUploadHandler(const string &version, const string &method) : + IUrlHandler(version, method) +{ +} + +DfsUploadHandler::~DfsUploadHandler() +{ +} + +int DfsUploadHandler::handle(DfsHttpInfo *http_info, DfsUrlInfo *url_info) +{ + string strjson; + if (0 != strcmp(http_info->method, MHD_HTTP_METHOD_POST) \ + || url_info->container_id.empty() || url_info->file_id.empty()) + { + dfs_warn << "bad method (" << http_info->method <<") or url: " << http_info->url << ", should be with container and fileId\n"; + strjson = DfsJsonUtils::createCommonRsp(MHD_HTTP_BAD_REQUEST, \ + MHD_HTTP_BAD_REQUEST, "bad method or url request without fileid"); + + //consume data + *(http_info->upload_data_size) = 0; + + return send_page (http_info->connection, + strjson.data(), + MHD_HTTP_BAD_REQUEST); + } + + dfs_debug << "connection request comes... url=" << http_info->url << ", upload_data_size=" << *(http_info->upload_data_size); + + MHD_Connection* connection = http_info->connection; + + DfsConnectionInfo *con_info = NULL; + + if (NULL == *(http_info->ptr))//first time a request is null for ptr + { + if (nr_of_uploading_clients > MAXCLIENTS) + { + strjson = DfsJsonUtils::createCommonRsp(MHD_HTTP_SERVICE_UNAVAILABLE, \ + -1, "too many upload request"); + return send_page (connection, + strjson.data(), + MHD_HTTP_SERVICE_UNAVAILABLE); + } + + con_info = new DfsConnectionInfo; + con_info->method = JZ_HTTP_METHOD_POST; + con_info->version = JZ_MODULE_VERSION_V1; + con_info->fp = NULL; + con_info->fp_path = ""; + con_info->postprocessor = MHD_create_post_processor(connection, + POSTBUFFERSIZE, + &iterate_post, + (void *) con_info); + if (NULL == con_info->postprocessor) + { + dfs_warn << "cannot create the postprocessor, method= " << http_info->method; + delete (con_info); + strjson = DfsJsonUtils::createCommonRsp(MHD_HTTP_BAD_REQUEST, \ + -1, "request handle error"); + return send_page (connection, + strjson.data(), + MHD_HTTP_BAD_REQUEST); + } + + nr_of_uploading_clients++; + con_info->recv_bytes = 0; + con_info->file_id = url_info->file_id; + con_info->container = url_info->container_id; + con_info->data = NULL; + con_info->length = 0; + + *(http_info->ptr) = (void *) con_info; + + //consume data + *(http_info->upload_data_size) = 0; + + return MHD_YES; + } + + + con_info = (DfsConnectionInfo*)(*(http_info->ptr)); + + if (0 != *(http_info->upload_data_size)) + { + dfs_warn << "********* do post process *******\n"; + //do post process + if (MHD_post_process (con_info->postprocessor, + http_info->upload_data, + *(http_info->upload_data_size)) != MHD_YES) + { + dfs_warn << "cannot DO POST process " << http_info->url; + strjson = DfsJsonUtils::createCommonRsp(MHD_HTTP_BAD_REQUEST, -1, "Error processing POST data"); + return send_page (connection, + strjson.data(), + MHD_HTTP_BAD_REQUEST); + } + *(http_info->upload_data_size) = 0; + + return MHD_YES; + } + + dfs_debug << "a request of upload file just done, url: " << http_info->url; + //get the uploaded file md5 hash + string strHash; + string strFile; + string strFileBak; + string strFileDir; + string strFirst; + string strSecond; + DfsFileServer::getInstance()->createDirectoryStringByContainer(con_info->container, strFileDir, strFirst, strSecond); + createDfsFileNames(strFileDir, con_info->file_id, con_info->filename, strFile, strFileBak); + if (0 != ms_md5(strFile, strHash)) + { + dfs_warn << "file: " << strFile.data() << " md5 failed, inner error"; + strjson = DfsJsonUtils::createCommonRsp(MHD_HTTP_BAD_REQUEST, -1, "the upload has error with file"); + return IUrlHandler::send_page(http_info->connection, strjson.data(), MHD_HTTP_BAD_REQUEST); + } + + dfs_debug << "upload file OK ! fileid: " << con_info->file_id << ", hash: " << strHash; + strjson = DfsJsonUtils::createCommonRsp(MHD_HTTP_OK, 0, "the upload has been completed", strHash); + return IUrlHandler::send_page(http_info->connection, strjson.data(), MHD_HTTP_OK); +} + + +static int +iterate_post (void *coninfo_cls, + enum MHD_ValueKind kind, + const char *key, + const char *filename, + const char *content_type, + const char *transfer_encoding, + const char *data, + uint64_t off, + size_t size) +{ + (void)kind; + (void)content_type; + (void)transfer_encoding; + (void)off; + + //TODO: (void)transfer_encoding; + DfsConnectionInfo *con_info = (DfsConnectionInfo*)coninfo_cls; + + dfs_debug << "*****== recv file: " << filename << ", key: " << key << ", size: " << size; + + if (filename == NULL) + { + //NOTE: if we upload file with file info [not used now] + if (strcmp(key, JZ_UPLOAD_FILE_INFO_FIELD) == 0)//get the json + { + dfs_debug << "*** recv fileinfo json: "<< data; + con_info->data = new char[size+1]; + con_info->length = size; + memcpy(con_info->data, data, size); + return MHD_YES; + } + else + { + dfs_debug << "****** ERROR: the filename is null\n"; + return MHD_NO; + } + } + + con_info->filename = filename; + if (!con_info->fp) + { + string strFile; + string strFileBak; + string strFileDir; + string strFirst; + string strSecond; + DfsFileServer::getInstance()->createDirectoryStringByContainer(con_info->container, strFileDir, strFirst, strSecond); + createDfsFileNames(strFileDir, con_info->file_id, con_info->filename, strFile, strFileBak); + if (ChkFileExists(strFile)) + { + dfs_debug << "*** file already exists, file: " << strFile.c_str(); + con_info->recv_bytes = 0; + return MHD_NO; + + /* + //当前文件存在则中断文件上传 + printf("**** file exist : %s\n", strFile.data()); + printf("== alter file or dup upload file id: %s, name: %s, but ok \n", \ + con_info->file_id.data(), con_info->filename.data()); + //mv file + FileMv(strFile, strFileBak); + + time_t theTime = time(NULL); + theTime += 2; + char szTemp[256]; + snprintf(szTemp, 256, "%ld", theTime); + strFileBak = strFile; + strFileBak += "_"; + strFileBak += szTemp;*/ + + } + + //temp download the file + con_info->fp_path = DfsFileServer::getInstance()->m_TempStorePath; + con_info->fp_path += "/"; + con_info->fp_path += con_info->file_id; + con_info->fp_path += "_"; + con_info->fp_path += con_info->filename; + dfs_debug << "to save files: " << strFile.c_str() << ", temp: " << con_info->fp_path.c_str(); + con_info->fp = fopen (strFile.c_str(), "wb"); + if (!con_info->fp) + { + dfs_debug << "upload file, to save temp file failed, file: " << strFileBak.c_str(); + return MHD_NO; + } + + //记录文件开始上传时间 + string strUpDir; + createDirectoryByContainer(DfsFileServer::getInstance()->m_StoreRootPath, con_info->container, strUpDir); + + DfsFileTask objTask; + objTask.id = con_info->file_id; + objTask.filename = con_info->filename; + objTask.operation = DfsFileTask::UPLOAD_START; + objTask.directory = strUpDir; + if (0 != DfsFileRecorder::writeRecord(objTask)) + { + dfs_warn << "## write file update record failed !!"; + } + } + + if (size > 0) + { + size_t ret = 0; + if (!(ret = fwrite(data, sizeof(char), size, con_info->fp))) + { + dfs_warn << "write to disk failed, fileid: " << con_info->file_id.data(); + return MHD_NO; + } + + con_info->recv_bytes += size; + } + else + { + dfs_debug << "****** post iterator, size: " << (int)size; + } + + return MHD_YES; +} + + diff --git a/libweb3jsonrpc/dfs/DfsUploadHandler.h b/libweb3jsonrpc/dfs/DfsUploadHandler.h new file mode 100644 index 0000000000..9b818c9a4b --- /dev/null +++ b/libweb3jsonrpc/dfs/DfsUploadHandler.h @@ -0,0 +1,32 @@ +#pragma once + +#include "IUrlHandler.h" + + +namespace dev +{ + +namespace rpc +{ + +namespace fs +{ + + +class DfsUploadHandler : public IUrlHandler +{ +public: + DfsUploadHandler(const string& version, const string &method); + virtual ~DfsUploadHandler(); + +public: + virtual int handle(DfsHttpInfo* http_info, DfsUrlInfo* url_info); + + virtual void handle_request_completed (void *cls, struct MHD_Connection *connection, + void **con_cls, enum MHD_RequestTerminationCode toe); +}; + +} +} +} + diff --git a/libweb3jsonrpc/dfs/IUrlHandler.cpp b/libweb3jsonrpc/dfs/IUrlHandler.cpp new file mode 100644 index 0000000000..712afedace --- /dev/null +++ b/libweb3jsonrpc/dfs/IUrlHandler.cpp @@ -0,0 +1,74 @@ +#include "IUrlHandler.h" +#include "microhttpd.h" +#include +#include "DfsCommon.h" +#include + +using namespace dev::rpc::fs; + + +int IUrlHandler::send_page(struct MHD_Connection *connection, + const char *json, + int status_code) +{ + int ret; + struct MHD_Response *response; + + response = MHD_create_response_from_buffer(strlen (json), + (void *) json, + MHD_RESPMEM_MUST_COPY); + if (!response) + { + dfs_warn << "cannot create valid response !"; + return MHD_NO; + } + + MHD_add_response_header(response, + MHD_HTTP_HEADER_CONTENT_TYPE, + "application/json"); + ret = MHD_queue_response(connection, + status_code, + response); + MHD_destroy_response(response); + + return ret; +} + + +bool IUrlHandler::findShortestAsFile(const string& dir, const string& file_id, string& full_file) +{ + //find the file + vector files; + vector filesFound; + listAllFiles(dir, files); + for (std::vector::iterator file = files.begin(); file != files.end(); ++file) + { + size_t pos = file->find(file_id); + if (pos != string::npos && pos == 0)//begin with fileid + { + filesFound.push_back(*file); + } + } + + if (filesFound.empty()) + { + dfs_warn << "file id: " << file_id.data() << " not found \n"; + return false; + } + + string strFileFound = filesFound.front(); + size_t length = filesFound.front().size(); + for (std::vector::iterator f = filesFound.begin(); f != filesFound.end(); ++f) + { + if (length > f->size())//get the shortest one + { + length = f->size(); + strFileFound = *f; + } + } + + full_file = dir; + full_file += "/"; + full_file += strFileFound; + return true; +} diff --git a/libweb3jsonrpc/dfs/IUrlHandler.h b/libweb3jsonrpc/dfs/IUrlHandler.h new file mode 100644 index 0000000000..678d196402 --- /dev/null +++ b/libweb3jsonrpc/dfs/IUrlHandler.h @@ -0,0 +1,48 @@ +/** +* @file IUrlHandler.h +* @time 2017-02-15 +**@desc URL handler interface class +*/ + +#pragma once + +#include "DfsBase.h" + + +using std::string; + +namespace dev +{ + +namespace rpc +{ + +namespace fs +{ + +class IUrlHandler +{ +public: + IUrlHandler(const string& version, const string &method){m_Version = version; m_Method = method;}; + virtual ~IUrlHandler(){}; + +public: + virtual int handle(DfsHttpInfo* http_info, DfsUrlInfo* url_info)=0; + virtual void handle_request_completed(void *cls,struct MHD_Connection *connection, + void **con_cls, enum MHD_RequestTerminationCode toe)=0; + + static int send_page (struct MHD_Connection *connection, + const char *page, + int status_code); + + static bool findShortestAsFile(const string& dir, const string& file_id, string& full_file); + + +protected: + string m_Version; + string m_Method; +}; + +} +} +} \ No newline at end of file diff --git a/libweb3jsonrpc/dfs/json_format.txt b/libweb3jsonrpc/dfs/json_format.txt new file mode 100644 index 0000000000..5123ffa0a8 --- /dev/null +++ b/libweb3jsonrpc/dfs/json_format.txt @@ -0,0 +1,6 @@ +json format of the http response: +{ + "ret":200, //http response code + "code":0, //busi return code + "info":"bad parameters" //infomation of response +} diff --git a/libweb3jsonrpc/eth.json b/libweb3jsonrpc/eth.json new file mode 100644 index 0000000000..5b13bc7e12 --- /dev/null +++ b/libweb3jsonrpc/eth.json @@ -0,0 +1,55 @@ +[ +{ "name": "eth_protocolVersion", "params": [], "order": [], "returns" : "" }, +{ "name": "eth_hashrate", "params": [], "order": [], "returns" : "" }, +{ "name": "eth_coinbase", "params": [], "order": [], "returns" : "" }, +{ "name": "eth_mining", "params": [], "order": [], "returns" : false }, +{ "name": "eth_gasPrice", "params": [], "order": [], "returns" : "" }, +{ "name": "eth_accounts", "params": [], "order": [], "returns" : [] }, +{ "name": "eth_blockNumber", "params": [], "order": [], "returns" : ""}, +{ "name": "eth_getBalance", "params": ["", ""], "order": [], "returns" : ""}, +{ "name": "eth_getStorageAt", "params": ["", "", ""], "order": [], "returns": ""}, +{ "name": "eth_getStorageRoot", "params": ["", ""], "order": [], "returns": ""}, +{ "name": "eth_getTransactionCount", "params": ["", ""], "order": [], "returns" : ""}, +{ "name": "eth_pendingTransactions", "params": [], "order": [], "returns" : ""}, +{ "name": "eth_getBlockTransactionCountByHash", "params": [""], "order": [], "returns" : {}}, +{ "name": "eth_getBlockTransactionCountByNumber", "params": [""], "order": [], "returns" : {}}, +{ "name": "eth_getUncleCountByBlockHash", "params": [""], "order": [], "returns" : {}}, +{ "name": "eth_getUncleCountByBlockNumber", "params": [""], "order": [], "returns" : {}}, +{ "name": "eth_getCode", "params": ["", ""], "order": [], "returns": ""}, +{ "name": "eth_sendTransaction", "params": [{}], "order": [], "returns": ""}, +{ "name": "eth_call", "params": [{}, ""], "order": [], "returns": ""}, +{ "name": "eth_flush", "params": [], "order": [], "returns" : true}, +{ "name": "eth_getBlockByHash", "params": ["", false],"order": [], "returns": {}}, +{ "name": "eth_getBlockByNumber", "params": ["", false],"order": [], "returns": {}}, +{ "name": "eth_getTransactionByHash", "params": [""], "order": [], "returns": {}}, +{ "name": "eth_getTransactionByBlockHashAndIndex", "params": ["", ""], "order": [], "returns": {}}, +{ "name": "eth_getTransactionByBlockNumberAndIndex", "params": ["", ""], "order": [], "returns": {}}, +{ "name": "eth_getTransactionReceipt", "params": [""], "order": [], "returns": {}}, +{ "name": "eth_getUncleByBlockHashAndIndex", "params": ["", ""], "order": [], "returns": {}}, +{ "name": "eth_getUncleByBlockNumberAndIndex", "params": ["", ""], "order": [], "returns": {}}, +{ "name": "eth_newFilter", "params": [{}], "order": [], "returns": ""}, +{ "name": "eth_newFilterEx", "params": [{}], "order": [], "returns": ""}, +{ "name": "eth_newBlockFilter", "params": [], "order": [], "returns": ""}, +{ "name": "eth_newPendingTransactionFilter", "params": [], "order": [], "returns": ""}, +{ "name": "eth_uninstallFilter", "params": [""], "order": [], "returns": true}, +{ "name": "eth_getFilterChanges", "params": [""], "order": [], "returns": []}, +{ "name": "eth_getFilterChangesEx", "params": [""], "order": [], "returns": []}, +{ "name": "eth_getFilterLogs", "params": [""], "order": [], "returns": []}, +{ "name": "eth_getFilterLogsEx", "params": [""], "order": [], "returns": []}, +{ "name": "eth_getLogs", "params": [{}], "order": [], "returns": []}, +{ "name": "eth_getLogsEx", "params": [{}], "order": [], "returns": []}, +{ "name": "eth_getWork", "params": [], "order": [], "returns": []}, +{ "name": "eth_submitWork", "params": ["", "", ""], "order": [], "returns": true}, +{ "name": "eth_submitHashrate", "params": ["", ""], "order": [], "returns": true}, +{ "name": "eth_register", "params": [""], "order": [], "returns": ""}, +{ "name": "eth_unregister", "params": [""], "order": [], "returns": true}, +{ "name": "eth_fetchQueuedTransactions", "params": [""], "order": [], "returns": []}, +{ "name": "eth_signTransaction", "params": [{}], "order": [], "returns": ""}, +{ "name": "eth_inspectTransaction", "params": [""], "order": [], "returns": {}}, +{ "name": "eth_sendRawTransaction", "params": [""], "order": [], "returns": ""}, +{ "name": "eth_notePassword", "params": [""], "order": [], "returns": true}, +{ "name": "eth_syncing", "params": [], "order": [], "returns": {}}, +{ "name": "eth_estimateGas", "params": [{}], "order": [], "returns": ""} + +] + diff --git a/libweb3jsonrpc/net.json b/libweb3jsonrpc/net.json new file mode 100644 index 0000000000..6b4b402ce5 --- /dev/null +++ b/libweb3jsonrpc/net.json @@ -0,0 +1,5 @@ +[ +{ "name": "net_version", "params": [], "order": [], "returns" : "" }, +{ "name": "net_peerCount", "params": [], "order": [], "returns" : "" }, +{ "name": "net_listening", "params": [], "order": [], "returns" : false } +] diff --git a/libweb3jsonrpc/personal.json b/libweb3jsonrpc/personal.json new file mode 100644 index 0000000000..8df137bb25 --- /dev/null +++ b/libweb3jsonrpc/personal.json @@ -0,0 +1,7 @@ +[ +{ "name": "personal_newAccount", "params": [""], "returns": "" }, +{ "name": "personal_unlockAccount", "params": ["", "", 0], "returns": true }, +{ "name": "personal_signAndSendTransaction", "params": [{}, ""], "returns": "" }, +{ "name": "personal_sendTransaction", "params": [{}, ""], "returns": "" }, +{ "name": "personal_listAccounts", "params": [], "returns": [] } +] diff --git a/libweb3jsonrpc/test.json b/libweb3jsonrpc/test.json new file mode 100644 index 0000000000..6ea0dc3e1a --- /dev/null +++ b/libweb3jsonrpc/test.json @@ -0,0 +1,7 @@ +[ +{ "name": "test_setChainParams", "params": [{}], "order": [], "returns": false}, +{ "name": "test_mineBlocks", "params": [0], "returns": false }, +{ "name": "test_modifyTimestamp", "params": [0], "returns": false }, +{ "name": "test_addBlock", "params": [""], "returns": false }, +{ "name": "test_rewindToBlock", "params": [0], "returns": false } +] diff --git a/libweb3jsonrpc/web3.json b/libweb3jsonrpc/web3.json new file mode 100644 index 0000000000..e261bc7fd4 --- /dev/null +++ b/libweb3jsonrpc/web3.json @@ -0,0 +1,4 @@ +[ +{ "name": "web3_sha3", "params": [""], "returns" : "" }, +{ "name": "web3_clientVersion", "params": [], "returns" : "" } +] diff --git a/libweb3jsonrpc/whisper.json b/libweb3jsonrpc/whisper.json new file mode 100644 index 0000000000..d171490404 --- /dev/null +++ b/libweb3jsonrpc/whisper.json @@ -0,0 +1,11 @@ +[ +{ "name": "shh_post", "params": [{}], "order": [], "returns": true}, +{ "name": "shh_newIdentity", "params": [], "order": [], "returns": ""}, +{ "name": "shh_hasIdentity", "params": [""], "order": [], "returns": false}, +{ "name": "shh_newGroup", "params": ["", ""], "order": [], "returns": ""}, +{ "name": "shh_addToGroup", "params": ["", ""], "order": [], "returns": ""}, +{ "name": "shh_newFilter", "params": [{}], "order": [], "returns": ""}, +{ "name": "shh_uninstallFilter", "params": [""], "order": [], "returns": true}, +{ "name": "shh_getFilterChanges", "params": [""], "order": [], "returns": []}, +{ "name": "shh_getMessages", "params": [""], "order": [], "returns": []} +] diff --git a/libwebthree/CMakeLists.txt b/libwebthree/CMakeLists.txt new file mode 100644 index 0000000000..89f5d021cb --- /dev/null +++ b/libwebthree/CMakeLists.txt @@ -0,0 +1,34 @@ +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") + +aux_source_directory(. SRC_LIST) + +file(GLOB HEADERS "*.h") +list(APPEND SRC_LIST libexecstream/exec-stream.cpp) + +add_library(webthree ${SRC_LIST} ${HEADERS}) + +eth_use(webthree REQUIRED Web3::whisper) + +find_package(Eth) +find_package(Web3) +include_directories(../libodbc/include + ../libodbc/include/db2_linux + ../libodbc/include/ibase + ../libodbc/include/infomix + ../libodbc/include/mysql + ../libodbc/include/odbc_linux + ../libodbc/include/pgsql + ../libodbc/include/sqlbase + ../libodbc/include/sqllite + ../libodbc/include/ss_linux + ../libodbc/include/sybase) + +target_include_directories(webthree PRIVATE ..) +#target_link_libraries(webthree ${Eth_ETHASH_LIBRARIES}) +#target_link_libraries(webthree ${Eth_ETHASHSEAL_LIBRARIES}) +target_link_libraries(webthree ${Eth_SINGLEPOINT_LIBRARIES}) +target_link_libraries(webthree ${Eth_PBFTSEAL_LIBRARIES}) +target_link_libraries(webthree ${Eth_RAFTSEAL_LIBRARIES}) +target_link_libraries(webthree ${Web3_WHISPER_LIBRARIES}) + +install(TARGETS webthree RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib) diff --git a/libwebthree/IPFS.cpp b/libwebthree/IPFS.cpp new file mode 100644 index 0000000000..595b22a394 --- /dev/null +++ b/libwebthree/IPFS.cpp @@ -0,0 +1,81 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file IPFS.cpp + * @author Gav Wood + * @date 2015 + */ + +#include "IPFS.h" +#include +#include +using namespace std; +using namespace dev; +#include "libexecstream/exec-stream.h" + +static bytes exec(string const& _args) +{ + string output; + try + { + exec_stream_t es("ipfs", _args); + do + { + string s; + getline(es.out(), s); + output += s; + } while(es.out().good()); + } + catch (exception const &e) + { + throw IPFSCommunicationError(e.what()); + } + return bytes(output.begin(), output.end()); +} +static void exec(string const& _args, bytesConstRef _in) +{ + try + { + exec_stream_t es("ipfs", _args); + es.in() << string(_in.begin(), _in.end()); + } + catch (exception const &e) + { + throw IPFSCommunicationError(e.what()); + } +} + +h256 IPFS::putBlockForSHA256(bytesConstRef _data) +{ + exec("block put", _data); + return sha256(_data); +} + +bytes IPFS::putBlock(bytesConstRef _data) +{ + return sha256AsMultihash(putBlockForSHA256(_data)); +} + +bytes IPFS::getBlockForSHA256(h256 const& _sha256) +{ + auto b = sha256AsMultihash(_sha256); + return getBlock(&b); +} + +bytes IPFS::getBlock(bytesConstRef _multihash) +{ + return exec("block get " + toBase58(_multihash)); +} diff --git a/libwebthree/IPFS.h b/libwebthree/IPFS.h new file mode 100644 index 0000000000..1e000e4ddf --- /dev/null +++ b/libwebthree/IPFS.h @@ -0,0 +1,60 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file IPFS.h + * @author Gav Wood + * @date 2015 + */ +#pragma once + +#include +#include +#include + + +namespace dev +{ + +DEV_SIMPLE_EXCEPTION(IPFSExecutableNotFound); +struct IPFSCommunicationError: virtual Exception { public: IPFSCommunicationError(std::string _s): Exception("Communication with ipfs executable failed: " + _s + ".") {} }; + +class IPFS +{ +public: + /// Places data into IPFS and @returns SHA2-256 hash of the data. + h256 putBlockForSHA256(bytesConstRef _data); + /// Places data into IPFS and @returns multihash of the data. + bytes putBlock(bytesConstRef _data); + + /// Retrieves data from IPFS SHA2-256 hash is given. + bytes getBlockForSHA256(h256 const& _sha256); + /// Retrieves data from IPFS whose multihash is given. + bytes getBlock(bytesConstRef _multihash); + + static h256 multihashAsSHA256(bytesConstRef _b) + { + if (_b.size() == 34 && _b[0] == 0x12 && _b[1] == 0x20) + return h256(_b.cropped(2)); + throw std::invalid_argument("Given data is not a SHA2-256 multihash"); + } + + static bytes sha256AsMultihash(h256 const& _h) + { + return bytes{0x12, 0x20} + _h.asBytes(); + } +}; + +} diff --git a/libwebthree/Support.cpp b/libwebthree/Support.cpp new file mode 100644 index 0000000000..5840379336 --- /dev/null +++ b/libwebthree/Support.cpp @@ -0,0 +1,120 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Support.h + * @author Gav Wood + * @date 2015 + */ + +#include "Support.h" +#include +#include +#include +#include +#include "WebThree.h" +using namespace std; +using namespace dev; +using namespace eth; + +Support::Support(WebThreeDirect* _web3): + m_web3(_web3) +{ +} + +Support::~Support() +{ +} + +strings Support::decomposed(std::string const& _name) +{ + size_t i = _name.find_first_of('/'); + strings parts; + string ts = _name.substr(0, i); + boost::algorithm::split(parts, ts, boost::algorithm::is_any_of(".")); + std::reverse(parts.begin(), parts.end()); + if (i != string::npos) + { + strings pathParts; + boost::algorithm::split(pathParts, ts = _name.substr(i + 1), boost::is_any_of("/")); + parts += pathParts; + } + return parts; +} + +bytes Support::call(Address const& _to, bytes const& _data) const +{ + return m_web3->ethereum()->call(_to, _data).output; +} + +bytes Support::auxLookup(strings const& _path, std::string const& _query) const +{ + Address address = registrar(); + for (unsigned i = 0; i < _path.size() - 1; ++i) + address = abiOut
(call(address, abiIn("subRegistrar(string)", _path[i]))); + return call(address, abiIn(_query + "(string)", _path.back())); +} + +Address Support::registrar() const +{ + return Address(m_web3->ethereum()->chainParams().otherParams.at("registrar")); +} + +Address Support::urlHint() const +{ + return lookup
({"urlhinter"}, "addr"); +} + +Address Support::sha256Hint() const +{ + return lookup
({"sha256hinter"}, "addr"); +} + +std::string Support::urlHint(h256 const& _content) const +{ + return toString(abiOut(call(urlHint(), abiIn("url(bytes32)", _content)))); +} + +h256 Support::sha256Hint(h256 const& _content) const +{ + return abiOut(call(sha256Hint(), abiIn("data(bytes32)", _content))); +} + +void Support::hintURL(h256 const& _content, std::string const& _url, Secret const& _s) const +{ + TransactionSkeleton t; + t.data = abiIn("suggestUrl(bytes32,bytes32)", _content, toString32(_url)); + t.to = urlHint(); + m_web3->ethereum()->submitTransaction(t, _s); +} + +void Support::hintSHA256(h256 const& _content, h256 const& _sha256, Secret const& _s) const +{ + TransactionSkeleton t; + t.data = abiIn("setData(bytes32,bytes32)", _content, _sha256); + t.to = sha256Hint(); + m_web3->ethereum()->submitTransaction(t, _s); +} + +Address Support::icapRegistrar() const +{ + return Address("a1a111bc074c9cfa781f0c38e63bd51c91b8af00"); + return lookup
({"icapregistrar"}, "addr"); +} + +std::pair Support::decodeICAP(std::string const& _icap) const +{ + return ICAP::decoded(_icap).address([&](Address a, bytes b){ return call(a, b); }, icapRegistrar()); +} diff --git a/libwebthree/Support.h b/libwebthree/Support.h new file mode 100644 index 0000000000..0688ee8384 --- /dev/null +++ b/libwebthree/Support.h @@ -0,0 +1,76 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Support.h + * @author Gav Wood + * @date 2015 + */ + +#pragma once + +#include +#include +#include + +namespace dev +{ + +class WebThreeDirect; + +/// Utilities supporting typical use of the Ethereum network. +class Support +{ +public: + Support(WebThreeDirect* _web3); + ~Support(); + + // URI managment + static strings decomposed(std::string const& _name); + + // Registrar + Address registrar() const; + h256 content(std::string const& _url) const { return lookup(decomposed(_url), "content"); } + Address address(std::string const& _url) const { return lookup
(decomposed(_url), "addr"); } + Address subRegistrar(std::string const& _url) const { return lookup
(decomposed(_url), "subRegistrar"); } + Address owner(std::string const& _url) const { return lookup
(decomposed(_url), "owner"); } + + // URL Hinter + Address urlHint() const; + std::string urlHint(h256 const& _content) const; + void hintURL(h256 const& _content, std::string const& _url, Secret const& _s) const; + + // SHA256 Hinter + Address sha256Hint() const; + h256 sha256Hint(h256 const& _content) const; + void hintSHA256(h256 const& _content, h256 const& _sha256, Secret const& _s) const; + + // ICAP + Address icapRegistrar() const; + std::pair decodeICAP(std::string const& _icap) const; + +private: + bytes call(Address const& _to, bytes const& _data) const; + + template T lookup(strings const& _path, std::string const& _query) const + { + return eth::abiOut(auxLookup(_path, _query)); + } + bytes auxLookup(strings const& _path, std::string const& _query) const; + + WebThreeDirect* m_web3; +}; + +} diff --git a/libwebthree/Swarm.cpp b/libwebthree/Swarm.cpp new file mode 100644 index 0000000000..0bd195b41c --- /dev/null +++ b/libwebthree/Swarm.cpp @@ -0,0 +1,112 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Swarm.cpp + * @author Gav Wood + * @date 2015 + */ + +#include "Swarm.h" + +#include +#include +#include +#include +#include +#include "WebThree.h" +#include "Support.h" +#include "IPFS.h" +using namespace std; +using namespace dev; +using namespace bzz; +using namespace eth; + +struct SwarmChannel: public LogChannel { static const char* name(); static const int verbosity = 3; }; +const char* SwarmChannel::name() { return EthYellow "bzz"; } +#define cbzz clog(SwarmChannel) + +bzz::Interface::~Interface() +{ +} + +bzz::Client::Client(WebThreeDirect* _web3): + m_ipfs(new IPFS) +{ + m_owner = _web3; +} + +Pinneds bzz::Client::insertBundle(bytesConstRef _bundle) +{ + cbzz << "Bundle insert" << sha3(_bundle); + + Pinneds ret; + RLP rlp(_bundle); + bool first = true; + for (auto const& r: rlp) + if (first) + first = false; + else + { + cbzz << " inserting slice" << sha3(r.toBytesConstRef()); + ret.push_back(Pinned(m_cache[sha3(r.toBytesConstRef())] = make_shared(r.toBytes()))); + } + return ret; +} + +Pinned bzz::Client::put(bytes const& _data) +{ + h256 ret = sha3(_data); + cbzz << "Inserting" << ret; + + if (!m_cache.count(ret)) + m_cache[ret] = make_shared(_data); + + if (m_putAccount) + { + // send to IPFS... + h256 sha256hash = sha256(&_data); + cbzz << "IPFS-inserting" << sha256hash; + + // set in blockchain + try + { + m_owner->support()->hintSHA256(ret, sha256hash, m_putAccount); + m_ipfs->putBlockForSHA256(&_data); + } + catch (InterfaceNotSupported&) {} + } + + return Pinned(m_cache[ret]); +} + +Pinned bzz::Client::get(h256 const& _hash) +{ + cbzz << "Looking up" << _hash; + auto it = m_cache.find(_hash); + if (it != m_cache.end()) + return it->second; + + if (u256 sha256hash = m_owner->support()->sha256Hint(_hash)) + { + cbzz << "IPFS Searching" << sha256hash; + auto b = m_ipfs->getBlockForSHA256(sha256hash); + if (!b.empty()) + return (m_cache[_hash] = make_shared(b)); + } + + cbzz << "Not found" << _hash; + throw ResourceNotAvailable(); +} diff --git a/libwebthree/Swarm.h b/libwebthree/Swarm.h new file mode 100644 index 0000000000..41bc6eced3 --- /dev/null +++ b/libwebthree/Swarm.h @@ -0,0 +1,98 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Swarm.h + * @author Gav Wood + * @date 2015 + */ + +#pragma once + +#include +#include +#include +#include + +namespace dev +{ + +class WebThreeDirect; +class IPFS; + +namespace bzz +{ + +DEV_SIMPLE_EXCEPTION(ResourceNotAvailable); + +/// Pinned, read-only, content. +class Pinned +{ + friend class Client; + +public: + Pinned() = default; + + explicit operator bool() const { return !!m_content; } + + operator bytes const&() const { return *m_content; } + operator bytesConstRef() const { return bytesConstRef(&*m_content); } + +private: + Pinned(std::shared_ptr const& _d): m_content(_d) {} + + std::shared_ptr m_content; +}; + +using Pinneds = std::vector; + +/// Basic interface for Swarm. +class Interface +{ +public: + virtual ~Interface(); + + virtual Pinned put(bytes const& _data) = 0; + virtual Pinned get(h256 const& _hash) = 0; + + virtual Pinneds insertBundle(bytesConstRef _bundle) = 0; +}; + +class Client; + +/// Placeholder for Swarm. +class Client: public Interface +{ +public: + Client(WebThreeDirect* _web3); + + void setPutAccount(Secret const& _s) { m_putAccount = _s; } + + Pinned put(bytes const& _data) override; + Pinned get(h256 const& _hash) override; + + Pinneds insertBundle(bytesConstRef _bundle) override; + +private: + std::unordered_map> m_cache; + + WebThreeDirect* m_owner; + std::shared_ptr m_ipfs; + + Secret m_putAccount; +}; + +} +} diff --git a/libwebthree/SystemManager.cpp b/libwebthree/SystemManager.cpp new file mode 100644 index 0000000000..2573179e20 --- /dev/null +++ b/libwebthree/SystemManager.cpp @@ -0,0 +1,25 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file SystemManager.cpp + * @author Gav Wood + * @date 2015 + */ + +#include "SystemManager.h" +#include +using namespace std; +using namespace dev; diff --git a/libwebthree/SystemManager.h b/libwebthree/SystemManager.h new file mode 100644 index 0000000000..2897868cfc --- /dev/null +++ b/libwebthree/SystemManager.h @@ -0,0 +1,35 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file SystemManager.h + * @author Gav Wood + * @date 2015 + */ + +#pragma once + +#include + +namespace dev +{ + +class SystemManager +{ +public: + virtual void exit() = 0; +}; + +} diff --git a/libwebthree/WebThree.cpp b/libwebthree/WebThree.cpp new file mode 100644 index 0000000000..5be5d9858c --- /dev/null +++ b/libwebthree/WebThree.cpp @@ -0,0 +1,203 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file WebThree.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "WebThree.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "BuildInfo.h" +#include +#include +#include +#include +#include "Swarm.h" +#include "Support.h" +using namespace std; +using namespace dev; +using namespace dev::p2p; +using namespace dev::eth; +using namespace dev::shh; + +WebThreeDirect::WebThreeDirect( + std::string const& _clientVersion, + std::string const& _dbPath, + eth::ChainParams const& _params, + WithExisting _we, + std::set const& _interfaces, + NetworkPreferences const& _n, + bytesConstRef _network, + bool _testing +): + m_clientVersion(_clientVersion), + m_net(_clientVersion, _n, _network) +{ + cout << "&m_net=" << &m_net << ",My enode:" << enode(); + //设置NodeConnParamsManager中的NetworkFace指针 + NodeConnManagerSingleton::GetInstance().setNetworkFace(this); + if (_dbPath.size()) + Defaults::setDBPath(_dbPath); + if (_interfaces.count("eth")) + { + PBFT::init(); + NoProof::init(); + SinglePoint::init(); + + if (_params.sealEngineName == "SinglePoint") + { + LOG(TRACE) << "WebThreeDirect::WebThreeDirect SinglePoint"; + m_ethereum.reset(new eth::SinglePointClient(_params, (int)_params.u256Param("networkID"), &m_net, shared_ptr(), _dbPath, _we)); + } + else if (_params.sealEngineName == "PBFT") { + m_ethereum.reset(new eth::PBFTClient(_params, (int)_params.u256Param("networkID"), &m_net, shared_ptr(), _dbPath, _we)); + } + else if (!strcasecmp(_params.sealEngineName.c_str(), "RAFT")) { + m_ethereum.reset(new eth::RaftClient(_params, (int)_params.u256Param("networkID"), &m_net, shared_ptr(), _dbPath, _we)); + } + else if (_params.sealEngineName == "NoProof" && _testing) + { + LOG(TRACE) << "WebThreeDirect::WebThreeDirect NoProof"; + m_ethereum.reset(new eth::ClientTest(_params, (int)_params.u256Param("networkID"), &m_net, shared_ptr(), _dbPath, _we)); + } + else + { + LOG(TRACE) << "WebThreeDirect::WebThreeDirect Default "; + m_ethereum.reset(new eth::Client(_params, (int)_params.u256Param("networkID"), &m_net, shared_ptr(), _dbPath, _we)); + } + string bp = DEV_QUOTED(ETH_BUILD_PLATFORM); + vector bps; + boost::split(bps, bp, boost::is_any_of("/")); + bps[0] = bps[0].substr(0, 5); + bps[1] = bps[1].substr(0, 3); + bps.back() = bps.back().substr(0, 3); + m_ethereum->setExtraData(rlpList(0, string(dev::Version) + "++" + string(DEV_QUOTED(ETH_COMMIT_HASH)).substr(0, 4) + (ETH_CLEAN_REPO ? "-" : "*") + string(DEV_QUOTED(ETH_BUILD_TYPE)).substr(0, 1) + boost::join(bps, "/"))); + } + + if (_interfaces.count("shh")) + m_whisper = m_net.registerCapability(make_shared()); + + if (_interfaces.count("bzz")) + { + m_swarm.reset(new bzz::Client(this)); + } + + m_support = make_shared(this); +} + +WebThreeDirect::~WebThreeDirect() +{ + // Utterly horrible right now - WebThree owns everything (good), but: + // m_net (Host) owns the eth::EthereumHost via a shared_ptr. + // The eth::EthereumHost depends on eth::Client (it maintains a reference to the BlockChain field of Client). + // eth::Client (owned by us via a unique_ptr) uses eth::EthereumHost (via a weak_ptr). + // Really need to work out a clean way of organising ownership and guaranteeing startup/shutdown is perfect. + + // Have to call stop here to get the Host to kill its io_service otherwise we end up with left-over reads, + // still referencing Sessions getting deleted *after* m_ethereum is reset, causing bad things to happen, since + // the guarantee is that m_ethereum is only reset *after* all sessions have ended (sessions are allowed to + // use bits of data owned by m_ethereum). + m_net.stop(); + m_ethereum.reset(); +} + +bzz::Interface* WebThreeDirect::swarm() const +{ + if (!m_swarm) + BOOST_THROW_EXCEPTION(InterfaceNotSupported("bzz")); + return m_swarm.get(); +} + +std::string WebThreeDirect::composeClientVersion(std::string const& _client) +{ + return _client + "/" + \ + "v" + dev::Version + "/" + \ + DEV_QUOTED(ETH_BUILD_OS) + "/" + \ + DEV_QUOTED(ETH_BUILD_COMPILER) + "/" + \ + DEV_QUOTED(ETH_BUILD_JIT_MODE) + "/" + \ + DEV_QUOTED(ETH_BUILD_TYPE) + "/" + \ + string(DEV_QUOTED(ETH_COMMIT_HASH)).substr(0, 8) + \ + (ETH_CLEAN_REPO ? "" : "*") + "/"; +} + +p2p::NetworkPreferences const& WebThreeDirect::networkPreferences() const +{ + return m_net.networkPreferences(); +} + +void WebThreeDirect::setNetworkPreferences(p2p::NetworkPreferences const& _n, bool _dropPeers) +{ + auto had = isNetworkStarted(); + if (had) + stopNetwork(); + m_net.setNetworkPreferences(_n, _dropPeers); + if (had) + startNetwork(); +} + +std::vector WebThreeDirect::peers() +{ + return m_net.peerSessionInfo(); +} + +size_t WebThreeDirect::peerCount() const +{ + return m_net.peerCount(); +} + +void WebThreeDirect::setIdealPeerCount(size_t _n) +{ + return m_net.setIdealPeerCount(_n); +} + +void WebThreeDirect::setPeerStretch(size_t _n) +{ + return m_net.setPeerStretch(_n); +} + +bytes WebThreeDirect::saveNetwork() +{ + return m_net.saveNetwork(); +} + +void WebThreeDirect::addNode(NodeID const& _node, bi::tcp::endpoint const& _host) +{ + m_net.addNode(_node, NodeIPEndpoint(_host.address(), _host.port(), _host.port())); +} + +void WebThreeDirect::requirePeer(NodeID const& _node, bi::tcp::endpoint const& _host) +{ + m_net.requirePeer(_node, NodeIPEndpoint(_host.address(), _host.port(), _host.port())); +} + +void WebThreeDirect::addPeer(NodeSpec const& _s, PeerType _t) +{ + LOG(TRACE) << "WebThreeDirect::addPeer "; + m_net.addPeer(_s, _t); +} + diff --git a/libwebthree/WebThree.h b/libwebthree/WebThree.h new file mode 100644 index 0000000000..ab4cfacd46 --- /dev/null +++ b/libwebthree/WebThree.h @@ -0,0 +1,324 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file WebThree.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include +#include +#include +#include // Make sure boost/asio.hpp is included before windows.h. +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace dev +{ + +enum WorkState +{ + Active = 0, + Deleting, + Deleted +}; + +namespace eth { class Interface; } +namespace shh { class Interface; } +namespace bzz { class Interface; class Client; } + +class Support; + +class NetworkFace +{ +public: + /// Get information concerning this node. + virtual p2p::NodeInfo nodeInfo() const = 0; + + /// Get information on the current peer set. + virtual std::vector peers() = 0; + + /// Same as peers().size(), but more efficient. + virtual size_t peerCount() const = 0; + + /// Generalised peer addition. + virtual void addPeer(p2p::NodeSpec const& _node, p2p::PeerType _t) = 0; + + /// Add node to connect to. + virtual void addNode(p2p::NodeID const& _node, bi::tcp::endpoint const& _hostEndpoint) = 0; + + /// Require connection to peer. + virtual void requirePeer(p2p::NodeID const& _node, bi::tcp::endpoint const& _endpoint) = 0; + + /// Save peers + virtual dev::bytes saveNetwork() = 0; + + /// Sets the ideal number of peers. + virtual void setIdealPeerCount(size_t _n) = 0; + + virtual bool haveNetwork() const = 0; + + virtual p2p::NetworkPreferences const& networkPreferences() const = 0; + virtual void setNetworkPreferences(p2p::NetworkPreferences const& _n, bool _dropPeers) = 0; + + virtual p2p::NodeID id() const = 0; + + /// Get network id + virtual u256 networkId() const = 0; + + /// Gets the nodes. + virtual p2p::Peers nodes() const = 0; + + /// Start the network subsystem. + virtual void startNetwork() = 0; + + /// Stop the network subsystem. + virtual void stopNetwork() = 0; + + /// Is network working? there may not be any peers yet. + virtual bool isNetworkStarted() const = 0; + + /// Get enode string. + virtual std::string enode() const = 0; + + virtual void disconnectByNodeId(const std::string &sNodeId) = 0; +}; + + +/** + * @brief Main API hub for interfacing with Web 3 components. This doesn't do any local multiplexing, so you can only have one + * running on any given machine for the provided DB path. + * + * Keeps a libp2p Host going (administering the work thread with m_workNet). + * + * Encapsulates a bunch of P2P protocols (interfaces), each using the same underlying libp2p Host. + * + * Provides a baseline for the multiplexed multi-protocol session class, WebThree. + */ +class WebThreeDirect: public NetworkFace +{ +public: + /// Constructor for private instance. If there is already another process on the machine using @a _dbPath, then this will throw an exception. + /// ethereum() may be safely static_cast()ed to a eth::Client*. + WebThreeDirect( + std::string const& _clientVersion, + std::string const& _dbPath, + eth::ChainParams const& _params, + WithExisting _we = WithExisting::Trust, + std::set const& _interfaces = {"eth", "shh", "bzz"}, + p2p::NetworkPreferences const& _n = p2p::NetworkPreferences(), + bytesConstRef _network = bytesConstRef(), + bool _testing = false + ); + + /// Destructor. + ~WebThreeDirect(); + + // The mainline interfaces: + + eth::Client* ethereum() const { if (!m_ethereum) BOOST_THROW_EXCEPTION(InterfaceNotSupported("eth")); return m_ethereum.get(); } + std::shared_ptr whisper() const { auto w = m_whisper.lock(); if (!w) BOOST_THROW_EXCEPTION(InterfaceNotSupported("shh")); return w; } + bzz::Interface* swarm() const; + + Support* support() const { return m_support.get(); } + + // Misc stuff: + + static std::string composeClientVersion(std::string const& _client); + std::string const& clientVersion() const { return m_clientVersion; } + void setClientVersion(std::string const& _name) { m_clientVersion = _name; } + + // Network stuff: + + /// Get information on the current peer set. + std::vector peers() override; + + /// Same as peers().size(), but more efficient. + size_t peerCount() const override; + + /// Generalised peer addition. + virtual void addPeer(p2p::NodeSpec const& _node, p2p::PeerType _t) override; + + /// Add node to connect to. + virtual void addNode(p2p::NodeID const& _node, bi::tcp::endpoint const& _hostEndpoint) override; + + /// Add node to connect to. + void addNode(p2p::NodeID const& _node, std::string const& _hostString) { addNode(_node, p2p::Network::resolveHost(_hostString)); } + + /// Add node to connect to. + void addNode(bi::tcp::endpoint const& _endpoint) { addNode(p2p::NodeID(), _endpoint); } + + /// Add node to connect to. + void addNode(std::string const& _hostString) { addNode(p2p::NodeID(), _hostString); } + + /// Require connection to peer. + void requirePeer(p2p::NodeID const& _node, bi::tcp::endpoint const& _endpoint) override; + + /// Require connection to peer. + void requirePeer(p2p::NodeID const& _node, std::string const& _hostString) { requirePeer(_node, p2p::Network::resolveHost(_hostString)); } + + /// Save peers + dev::bytes saveNetwork() override; + + /// Sets the ideal number of peers. + void setIdealPeerCount(size_t _n) override; + + /// Experimental. Sets ceiling for incoming connections to multiple of ideal peer count. + void setPeerStretch(size_t _n); + + bool haveNetwork() const override { return m_net.haveNetwork(); } + + p2p::NetworkPreferences const& networkPreferences() const override; + + void setNetworkPreferences(p2p::NetworkPreferences const& _n, bool _dropPeers = false) override; + + p2p::NodeInfo nodeInfo() const override { return m_net.nodeInfo(); } + + p2p::NodeID id() const override { return m_net.id(); } + + u256 networkId() const override { return m_ethereum.get()->networkId(); } + + std::string enode() const override { return m_net.enode(); } + + bool getSelfSignData(Signature &_sign) const { return m_net.getSelfSignData(_sign); } + + void disconnectByNodeId(const std::string &sNodeId) { return m_net.disconnectByNodeId(sNodeId); } + + /// Gets the nodes. + p2p::Peers nodes() const override { return m_net.getPeers(); } + + /// Start the network subsystem. + void startNetwork() override { m_net.start(); } + + /// Stop the network subsystem. + void stopNetwork() override { m_net.stop(); } + + /// Is network working? there may not be any peers yet. + bool isNetworkStarted() const override { return m_net.isStarted(); } + +private: + std::string m_clientVersion; ///< Our end-application client's name/version. + + p2p::Host m_net; ///< Should run in background and send us events when blocks found and allow us to send blocks as required. + + std::unique_ptr m_ethereum; ///< Client for Ethereum ("eth") protocol. + std::weak_ptr m_whisper; ///< Client for Whisper ("shh") protocol. + std::shared_ptr m_swarm; ///< Client for Swarm ("bzz") protocol. + + std::shared_ptr m_support; +}; + +// TODO, probably move into libdevrpc: + +class RPCSlave {}; +class RPCMaster {}; + +// TODO, probably move into eth: + +class EthereumSlave: public eth::Interface +{ +public: + EthereumSlave(RPCSlave*) {} + + // TODO: implement all of the virtuals with the RLPClient link. +}; + +class EthereumMaster +{ +public: + EthereumMaster(RPCMaster*) {} + + // TODO: implement the master-end of whatever the RLPClient link will send over. +}; + +// TODO, probably move into shh: + +class WhisperSlave: public shh::Interface +{ +public: + WhisperSlave(RPCSlave*) {} + + // TODO: implement all of the virtuals with the RLPClient link. +}; + +class WhisperMaster +{ +public: + WhisperMaster(RPCMaster*) {} + + // TODO: implement the master-end of whatever the RLPClient link will send over. +}; + +/** + * @brief Main API hub for interfacing with Web 3 components. + * + * This does transparent local multiplexing, so you can have as many running on the + * same machine all working from a single DB path. + */ +class WebThree +{ +public: + /// Constructor for public instance. This will be shared across the local machine. + WebThree(); + + /// Destructor. + ~WebThree(); + + // The mainline interfaces. + + eth::Interface* ethereum() const { if (!m_ethereum) BOOST_THROW_EXCEPTION(InterfaceNotSupported("eth")); return m_ethereum; } + shh::Interface* whisper() const { if (!m_whisper) BOOST_THROW_EXCEPTION(InterfaceNotSupported("shh")); return m_whisper; } + bzz::Interface* swarm() const { BOOST_THROW_EXCEPTION(InterfaceNotSupported("bzz")); } + + // Peer network stuff - forward through RPCSlave, probably with P2PNetworkSlave/Master classes like Whisper & Ethereum. + + /// Get information on the current peer set. + std::vector peers(); + + /// Same as peers().size(), but more efficient. + size_t peerCount() const; + + /// Connect to a particular peer. + void connect(std::string const& _seedHost, unsigned short _port = 30303); + + /// Is the network subsystem up? + bool haveNetwork(); + + /// Save peers + dev::bytes savePeers(); + + /// Restore peers + void restorePeers(bytesConstRef _saved); + +private: + EthereumSlave* m_ethereum = nullptr; + WhisperSlave* m_whisper = nullptr; + + // TODO: + RPCSlave m_rpcSlave; +}; + +} diff --git a/libwebthree/libexecstream/README b/libwebthree/libexecstream/README new file mode 100644 index 0000000000..e07773e9a1 --- /dev/null +++ b/libwebthree/libexecstream/README @@ -0,0 +1,42 @@ +This is version 0.3 of libexecstream, a C++ library +that allows you to run a child process and have its input, +output and error avaliable as standard C++ streams. + +Copyright (c) 2004 Artem Khodush +Libexecstream is distributed under the BSD-style license, +see doc/license.html for the details. + +Documentation: + doc/index.html + http://libexecstream/sourceforge.net/ + +Features: + Works on Linux and Windows + Uses threads + Does not depend on any other non-standard library + Distributed as source code only, requires you to compile and link + one file into your program + +Installaion: + +Libexecstream is provided in source code form only. +In order to use it, you need to compile and link one file, exec-stream.cpp, +into your program. + +Header file exec-stream.h defines interface of the library and uses +only standard C++. It does not include any platform-specific header files. + +On Linux, libexecstream was tested on Red Hat 9 with gcc compiler. +Versions of gcc prior to 3.0 will not work. Make sure that exec-stream.h +is found somewhere on the include path, compile exec-stream.cpp as usual, +link your program with -lpthread. GCC must be configured with --enable-threads, +which is by default on most Linux distributions. + +On Windows, libexecstream was tested on XP and 95 flavors with VC++ 7 compiler. +VC++ 6 will not work. Make sure that exec-stream.h is found somewhere +on the include path, compile exec-stream.cpp as usual, link you program +with multi-threaded runtime. + +Example makefiles for Windows and Linux (used to build the testsute) +are provided in the test subdirectory. + diff --git a/libwebthree/libexecstream/exec-stream.cpp b/libwebthree/libexecstream/exec-stream.cpp new file mode 100644 index 0000000000..26c74d8a46 --- /dev/null +++ b/libwebthree/libexecstream/exec-stream.cpp @@ -0,0 +1,465 @@ +/* +Copyright (C) 2004 Artem Khodush + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +3. The name of the author may not be used to endorse or promote products +derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "exec-stream.h" + +#include +#include +#include +#include + +#if defined(_WIN32) + +#ifndef NOMINMAX +#define NOMINMAX +#endif + +#include + +#define HELPERS_H "win/exec-stream-helpers.h" +#define HELPERS_CPP "win/exec-stream-helpers.cpp" +#define IMPL_CPP "win/exec-stream-impl.cpp" + +#else + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define HELPERS_H "posix/exec-stream-helpers.h" +#define HELPERS_CPP "posix/exec-stream-helpers.cpp" +#define IMPL_CPP "posix/exec-stream-impl.cpp" + +#endif + +// helper classes +namespace helpers { + +class buffer_list_t { +public: + struct buffer_t { + std::size_t size; + char * data; + }; + + buffer_list_t(); + ~buffer_list_t(); + + void get( char * dst, std::size_t & size ); + void get_translate_crlf( char * dst, std::size_t & size ); + void put( char * const src, std::size_t size ); + void put_translate_crlf( char * const src, std::size_t size ); + buffer_t detach(); + + bool empty(); + bool full( std::size_t limit ); // limit==0 -> no limit + + void clear(); + +private: + typedef std::list< buffer_t > buffers_t; + buffers_t m_buffers; + std::size_t m_read_offset; // offset into the first buffer + std::size_t m_total_size; +}; + +buffer_list_t::buffer_list_t() +{ + m_total_size=0; + m_read_offset=0; +} + +buffer_list_t::~buffer_list_t() +{ + clear(); +} + +void buffer_list_t::get( char * dst, std::size_t & size ) +{ + std::size_t written_size=0; + while( size>0 && m_total_size>0 ) { + std::size_t portion_size=std::min( size, m_buffers.front().size-m_read_offset ); + std::char_traits< char >::copy( dst, m_buffers.front().data+m_read_offset, portion_size ); + dst+=portion_size; + size-=portion_size; + m_total_size-=portion_size; + m_read_offset+=portion_size; + written_size+=portion_size; + if( m_read_offset==m_buffers.front().size ) { + delete[] m_buffers.front().data; + m_buffers.pop_front(); + m_read_offset=0; + } + } + size=written_size; +} + +void buffer_list_t::get_translate_crlf( char * dst, std::size_t & size ) +{ + std::size_t written_size=0; + while( written_size!=size && m_total_size>0 ) { + while( written_size!=size && m_read_offset!=m_buffers.front().size ) { + char c=m_buffers.front().data[m_read_offset]; + if( c!='\r' ) { // MISFEATURE: single \r in the buffer will cause end of file + *dst++=c; + ++written_size; + } + --m_total_size; + ++m_read_offset; + } + if( m_read_offset==m_buffers.front().size ) { + delete[] m_buffers.front().data; + m_buffers.pop_front(); + m_read_offset=0; + } + } + size=written_size; +} + +void buffer_list_t::put( char * const src, std::size_t size ) +{ + buffer_t buffer; + buffer.data=new char[size]; + buffer.size=size; + std::char_traits< char >::copy( buffer.data, src, size ); + m_buffers.push_back( buffer ); + m_total_size+=buffer.size; +} + +void buffer_list_t::put_translate_crlf( char * const src, std::size_t size ) +{ + char const * p=src; + std::size_t lf_count=0; + while( p!=src+size ) { + if( *p=='\n' ) { + ++lf_count; + } + ++p; + } + buffer_t buffer; + buffer.data=new char[size+lf_count]; + buffer.size=size+lf_count; + p=src; + char * dst=buffer.data; + while( p!=src+size ) { + if( *p=='\n' ) { + *dst++='\r'; + } + *dst++=*p; + ++p; + } + m_buffers.push_back( buffer ); + m_total_size+=buffer.size; +} + +buffer_list_t::buffer_t buffer_list_t::detach() +{ + buffer_t buffer=m_buffers.front(); + m_buffers.pop_front(); + m_total_size-=buffer.size; + return buffer; +} + +bool buffer_list_t::empty() +{ + return m_total_size==0; +} + +bool buffer_list_t::full( std::size_t limit ) +{ + return limit!=0 && m_total_size>=limit; +} + +void buffer_list_t::clear() +{ + for( buffers_t::iterator i=m_buffers.begin(); i!=m_buffers.end(); ++i ) { + delete[] i->data; + } + m_buffers.clear(); + m_read_offset=0; + m_total_size=0; +} + +} + +// platform-dependent helpers + +namespace helpers { + +#include HELPERS_H +#include HELPERS_CPP + +} + +// stream buffer class +namespace helpers { + +class exec_stream_buffer_t : public std::streambuf { +public: + exec_stream_buffer_t( exec_stream_t::stream_kind_t kind, thread_buffer_t & thread_buffer ); + virtual ~exec_stream_buffer_t(); + + void clear(); + +protected: + virtual int_type underflow(); + virtual int_type overflow( int_type c ); + virtual int sync(); + +private: + bool send_buffer(); + bool send_char( char c ); + + exec_stream_t::stream_kind_t m_kind; + thread_buffer_t & m_thread_buffer; + char * m_stream_buffer; +}; + +const std::size_t STREAM_BUFFER_SIZE=4096; + +exec_stream_buffer_t::exec_stream_buffer_t( exec_stream_t::stream_kind_t kind, thread_buffer_t & thread_buffer ) +: m_kind( kind ), m_thread_buffer( thread_buffer ) +{ + m_stream_buffer=new char[STREAM_BUFFER_SIZE]; + clear(); +} + +exec_stream_buffer_t::~exec_stream_buffer_t() +{ + delete[] m_stream_buffer; +} + +void exec_stream_buffer_t::clear() +{ + if( m_kind==exec_stream_t::s_in ) { + setp( m_stream_buffer, m_stream_buffer+STREAM_BUFFER_SIZE ); + }else { + setg( m_stream_buffer, m_stream_buffer+STREAM_BUFFER_SIZE, m_stream_buffer+STREAM_BUFFER_SIZE ); + } +} + +exec_stream_buffer_t::int_type exec_stream_buffer_t::underflow() +{ + if( gptr()==egptr() ) { + std::size_t read_size=STREAM_BUFFER_SIZE; + bool no_more; + m_thread_buffer.get( m_kind, m_stream_buffer, read_size, no_more ); + if( no_more || read_size==0 ) { // there is no way for underflow to return something other than eof when 0 bytes are read + return traits_type::eof(); + }else { + setg( m_stream_buffer, m_stream_buffer, m_stream_buffer+read_size ); + } + } + return traits_type::to_int_type( *eback() ); +} + +bool exec_stream_buffer_t::send_buffer() +{ + if( pbase()!=pptr() ) { + std::size_t write_size=pptr()-pbase(); + std::size_t n=write_size; + bool no_more; + m_thread_buffer.put( pbase(), n, no_more ); + if( no_more || n!=write_size ) { + return false; + }else { + setp( m_stream_buffer, m_stream_buffer+STREAM_BUFFER_SIZE ); + } + } + return true; +} + +bool exec_stream_buffer_t::send_char( char c ) +{ + std::size_t write_size=1; + bool no_more; + m_thread_buffer.put( &c, write_size, no_more ); + return write_size==1 && !no_more; +} + +exec_stream_buffer_t::int_type exec_stream_buffer_t::overflow( exec_stream_buffer_t::int_type c ) +{ + if( !send_buffer() ) { + return traits_type::eof(); + } + if( c!=traits_type::eof() ) { + if( pbase()==epptr() ) { + if( !send_char( c ) ) { + return traits_type::eof(); + } + }else { + sputc( c ); + } + } + return traits_type::not_eof( c ); +} + +int exec_stream_buffer_t::sync() +{ + if( !send_buffer() ) { + return -1; + } + return 0; +} + +// stream classes + +class exec_istream_t : public std::istream { +public: + exec_istream_t( exec_stream_buffer_t & buf ) + : std::istream( &buf ) { + } +}; + + +class exec_ostream_t : public std::ostream { +public: + exec_ostream_t( exec_stream_buffer_t & buf ) + : std::ostream( &buf ){ + } +}; + +} + +// platform-dependent implementation +#include IMPL_CPP + + +//platform-independent exec_stream_t member functions +exec_stream_t::exec_stream_t() +{ + m_impl=new impl_t; + exceptions( true ); +} + +exec_stream_t::exec_stream_t( std::string const & program, std::string const & arguments ) +{ + m_impl=new impl_t; + exceptions( true ); + start( program, arguments ); +} + +void exec_stream_t::new_impl() +{ + m_impl=new impl_t; +} + +exec_stream_t::~exec_stream_t() +{ + try { + close(); + }catch( ... ) { + } + delete m_impl; +} + +std::ostream & exec_stream_t::in() +{ + return m_impl->m_in; +} + +std::istream & exec_stream_t::out() +{ + return m_impl->m_out; +} + +std::istream & exec_stream_t::err() +{ + return m_impl->m_err; +} + +void exec_stream_t::exceptions( bool enable ) +{ + if( enable ) { + // getline sets failbit on eof, so we should enable badbit and badbit _only_ to propagate our exceptions through iostream code. + m_impl->m_in.exceptions( std::ios_base::badbit ); + m_impl->m_out.exceptions( std::ios_base::badbit ); + m_impl->m_err.exceptions( std::ios_base::badbit ); + }else { + m_impl->m_in.exceptions( std::ios_base::goodbit ); + m_impl->m_out.exceptions( std::ios_base::goodbit ); + m_impl->m_err.exceptions( std::ios_base::goodbit ); + } +} + +// exec_stream_t::error_t +namespace { + +std::string int2str( unsigned long i, int base, std::size_t width ) +{ + std::string s; + s.reserve(4); + while( i!=0 ) { + s="0123456789abcdef"[i%base]+s; + i/=base; + } + if( width!=0 ) { + while( s.size() +#include +#include +#include +#include + +class exec_stream_t { +public: + exec_stream_t(); + exec_stream_t( std::string const & program, std::string const & arguments ); + template< class iterator > exec_stream_t( std::string const & program, iterator args_begin, iterator args_end ); + + ~exec_stream_t(); + + enum stream_kind_t { s_in=1, s_out=2, s_err=4, s_all=s_in|s_out|s_err, s_child=8 }; + + void set_buffer_limit( int stream_kind, std::size_t size ); + + typedef unsigned long timeout_t; + void set_wait_timeout( int stream_kind, timeout_t milliseconds ); + + void set_binary_mode( int stream_kind ); + void set_text_mode( int stream_kind ); + + void start( std::string const & program, std::string const & arguments ); + template< class iterator > void start( std::string const & program, iterator args_begin, iterator args_end ); + void start( std::string const & program, char const * arg1, char const * arg2 ); // to compensate for damage from the previous one + void start( std::string const & program, char * arg1, char * arg2 ); + + bool close_in(); + bool close(); + void kill(); + int exit_code(); + + std::ostream & in(); + std::istream & out(); + std::istream & err(); + + typedef unsigned long error_code_t; + + class error_t : public std::exception { + public: + error_t( std::string const & msg ); + error_t( std::string const & msg, error_code_t code ); + ~error_t() throw(); + virtual char const * what() const throw(); + protected: + error_t(); + void compose( std::string const & msg, error_code_t code ); + + std::string m_msg; + }; + +private: + exec_stream_t( exec_stream_t const & ); + exec_stream_t & operator=( exec_stream_t const & ); + + struct impl_t; + friend struct impl_t; + impl_t * m_impl; + + void exceptions( bool enable ); + +// helpers for template member functions + void new_impl(); + + class next_arg_t { + public: + virtual ~next_arg_t() + { + } + + virtual std::string const * next()=0; + }; + + template< class iterator > class next_arg_impl_t : public next_arg_t { + public: + next_arg_impl_t( iterator args_begin, iterator args_end ) + : m_args_i( args_begin ), m_args_end( args_end ) + { + } + + virtual std::string const * next() + { + if( m_args_i==m_args_end ) { + return 0; + }else { + m_arg=*m_args_i; + ++m_args_i; + return &m_arg; + } + } + + private: + iterator m_args_i; + iterator m_args_end; + std::string m_arg; + }; + + void start( std::string const & program, next_arg_t & next_arg ); +}; + +template< class iterator > inline exec_stream_t::exec_stream_t( std::string const & program, iterator args_begin, iterator args_end ) +{ + new_impl(); + exceptions( true ); + start( program, args_begin, args_end ); +} + +template< class iterator > inline void exec_stream_t::start( std::string const & program, iterator args_begin, iterator args_end ) +{ + exec_stream_t::next_arg_impl_t< iterator > next_arg( args_begin, args_end ); + start( program, next_arg ); +} + +inline void exec_stream_t::start( std::string const & program, char const * arg1, char const * arg2 ) +{ + std::vector< std::string > args; + args.push_back( std::string( arg1 ) ); + args.push_back( std::string( arg2 ) ); + start( program, args.begin(), args.end() ); +} + +inline void exec_stream_t::start( std::string const & program, char * arg1, char * arg2 ) +{ + std::vector< std::string > args; + args.push_back( std::string( arg1 ) ); + args.push_back( std::string( arg2 ) ); + start( program, args.begin(), args.end() ); +} + +#endif diff --git a/libwebthree/libexecstream/posix/exec-stream-helpers.cpp b/libwebthree/libexecstream/posix/exec-stream-helpers.cpp new file mode 100644 index 0000000000..03233c7370 --- /dev/null +++ b/libwebthree/libexecstream/posix/exec-stream-helpers.cpp @@ -0,0 +1,844 @@ +/* +Copyright (C) 2004 Artem Khodush + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +3. The name of the author may not be used to endorse or promote products +derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +// os_error_t +os_error_t::os_error_t( std::string const & msg ) +{ + compose( msg, errno ); +} + +os_error_t::os_error_t( std::string const & msg, exec_stream_t::error_code_t code ) +{ + compose( msg, code ); +} + +void os_error_t::compose( std::string const & msg, exec_stream_t::error_code_t code ) +{ + std::string s( msg ); + s+='\n'; + errno=0; + char const * x=strerror( code ); + if( errno!=0 ) { + s+="[unable to retrieve error description]"; + }else { + s+=x; + } + exec_stream_t::error_t::compose( s, code ); +} + +// pipe_t +pipe_t::pipe_t() +: m_direction( closed ) +{ + m_fds[0]=-1; + m_fds[1]=-1; +} + +pipe_t::~pipe_t() +{ + try { + close(); + }catch(...) { + } +} + +int pipe_t::r() const +{ + return m_fds[0]; +} + +int pipe_t::w() const +{ + return m_fds[1]; +} + +void pipe_t::close_r() +{ + if( m_direction==both || m_direction==read ) { + if( ::close( m_fds[0] )==-1 ) { + throw os_error_t( "pipe_t::close_r: close failed" ); + } + m_direction= m_direction==both ? write : closed; + } +} + +void pipe_t::close_w() +{ + if( m_direction==both || m_direction==write ) { + if( ::close( m_fds[1] )==-1 ) { + throw os_error_t( "pipe_t::close_w: close failed" ); + } + m_direction= m_direction==both ? read : closed; + } +} + +void pipe_t::close() +{ + close_r(); + close_w(); +} + +void pipe_t::open() +{ + close(); + if( pipe( m_fds )==-1 ) { + throw os_error_t( "pipe_t::open(): pipe() failed" ); + } + m_direction=both; +} + + +// mutex_t +mutex_t::mutex_t() +{ + if( int code=pthread_mutex_init( &m_mutex, 0 ) ) { + throw os_error_t( "mutex_t::mutex_t: pthread_mutex_init failed", code ); + } +} + +mutex_t::~mutex_t() +{ + pthread_mutex_destroy( &m_mutex ); +} + + +// grab_mutex_t +grab_mutex_t::grab_mutex_t( mutex_t & mutex, mutex_registrator_t * mutex_registrator ) +{ + m_mutex=&mutex.m_mutex; + m_error_code=pthread_mutex_lock( m_mutex ); + m_grabbed=ok(); + m_mutex_registrator=mutex_registrator; + if( m_mutex_registrator ) { + m_mutex_registrator->add( this ); + } +} + +grab_mutex_t::~grab_mutex_t() +{ + release(); + if( m_mutex_registrator ) { + m_mutex_registrator->remove( this ); + } +} + +int grab_mutex_t::release() +{ + int code=0; + if( m_grabbed ) { + code=pthread_mutex_unlock( m_mutex ); + m_grabbed=false; + } + return code; +} + +bool grab_mutex_t::ok() +{ + return m_error_code==0; +} + +int grab_mutex_t::error_code() +{ + return m_error_code; +} + +// mutex_registrator_t +mutex_registrator_t::~mutex_registrator_t() +{ + for( mutexes_t::iterator i=m_mutexes.begin(); i!=m_mutexes.end(); ++i ) { + (*i)->m_mutex_registrator=0; + } +} + +void mutex_registrator_t::add( grab_mutex_t * g ) +{ + m_mutexes.insert( m_mutexes.end(), g ); +} + +void mutex_registrator_t::remove( grab_mutex_t * g ) +{ + m_mutexes.erase( std::find( m_mutexes.begin(), m_mutexes.end(), g ) ); +} + +void mutex_registrator_t::release_all() +{ + for( mutexes_t::iterator i=m_mutexes.begin(); i!=m_mutexes.end(); ++i ) { + (*i)->release(); + } +} + +// wait_result_t +wait_result_t::wait_result_t( unsigned signaled_state, int error_code, bool timed_out ) +{ + m_timed_out=timed_out; + m_error_code=error_code; + m_signaled_state= error_code==0 ? signaled_state : 0; +} + +bool wait_result_t::ok() +{ + return m_error_code==0; +} + +bool wait_result_t::is_signaled( int state ) +{ + return m_signaled_state&state; +} + +int wait_result_t::error_code() +{ + return m_error_code; +} + +bool wait_result_t::timed_out() +{ + return m_timed_out; +} + + +// event_t +event_t::event_t() +{ + if( int code=pthread_cond_init( &m_cond, 0 ) ) { + throw os_error_t( "event_t::event_t: pthread_cond_init failed", code ); + } + m_state=0; +} + +event_t::~event_t() +{ + pthread_cond_destroy( &m_cond ); +} + +int event_t::set( unsigned bits, mutex_registrator_t * mutex_registrator ) +{ + grab_mutex_t grab_mutex( m_mutex, mutex_registrator ); + if( !grab_mutex.ok() ) { + return grab_mutex.error_code(); + } + + int code=0; + if( bits&~m_state ) { + m_state|=bits; + code=pthread_cond_broadcast( &m_cond ); + } + + int release_code=grab_mutex.release(); + if( code==0 ) { + code=release_code; + } + return code; +} + +int event_t::reset( unsigned bits, mutex_registrator_t * mutex_registrator ) +{ + grab_mutex_t grab_mutex( m_mutex, mutex_registrator ); + if( !grab_mutex.ok() ) { + return grab_mutex.error_code(); + } + m_state&=~bits; + return grab_mutex.release(); +} + +wait_result_t event_t::wait( unsigned any_bits, unsigned long timeout, mutex_registrator_t * mutex_registrator ) +{ + if( any_bits==0 ) { + // we ain't waiting for anything + return wait_result_t( 0, 0, false ); + } + + grab_mutex_t grab_mutex( m_mutex, mutex_registrator ); + if( !grab_mutex.ok() ) { + return wait_result_t( 0, grab_mutex.error_code(), false ); + } + + struct timeval time_val_limit; + gettimeofday( &time_val_limit, 0 ); + struct timespec time_limit; + time_limit.tv_sec=time_val_limit.tv_sec+timeout/1000; + time_limit.tv_nsec=1000*(time_val_limit.tv_usec+1000*(timeout%1000)); + int code=0; + while( code==0 && (m_state&any_bits)==0 ) { + code=pthread_cond_timedwait( &m_cond, &m_mutex.m_mutex, &time_limit ); + } + + unsigned state=m_state; + int release_code=grab_mutex.release(); + if( code==0 ) { + code=release_code; + } + return wait_result_t( state, code, code==ETIMEDOUT ); +} + +// thread_buffer_t +thread_buffer_t::thread_buffer_t( pipe_t & in_pipe, pipe_t & out_pipe, pipe_t & err_pipe, std::ostream & in ) +: m_in_pipe( in_pipe ), m_out_pipe( out_pipe ), m_err_pipe( err_pipe ), m_in( in ) +{ + m_in_bad=false; + m_error_prefix=""; + m_error_code=0; + m_in_wait_timeout=2000; + m_out_wait_timeout=2000; + m_err_wait_timeout=2000; + m_thread_termination_timeout=1000; + m_in_buffer_limit=0; + m_out_buffer_limit=0; + m_err_buffer_limit=0; + m_out_read_buffer_size=4096; + m_err_read_buffer_size=4096; + m_thread_started=false; + m_in_closed=false; +} + +thread_buffer_t::~thread_buffer_t() +{ + bool stopped=false; + try { + stopped=stop_thread(); + }catch( ... ) { + } + if( !stopped ) { + try { + stopped=abort_thread(); + }catch( ... ) { + } + } + if( !stopped ) { + std::terminate(); + } +} + +void thread_buffer_t::set_wait_timeout( int stream_kind, unsigned long milliseconds ) +{ + if( m_thread_started ) { + throw exec_stream_t::error_t( "thread_buffer_t::set_wait_timeout: thread already started" ); + } + if( stream_kind&exec_stream_t::s_in ) { + m_in_wait_timeout=milliseconds; + } + if( stream_kind&exec_stream_t::s_out ) { + m_out_wait_timeout=milliseconds; + } + if( stream_kind&exec_stream_t::s_err ) { + m_err_wait_timeout=milliseconds; + } + if( stream_kind&exec_stream_t::s_child ) { + m_thread_termination_timeout=milliseconds; + } +} + +void thread_buffer_t::set_buffer_limit( int stream_kind, std::size_t limit ) +{ + if( m_thread_started ) { + throw exec_stream_t::error_t( "thread_buffer_t::set_buffer_limit: thread already started" ); + } + if( stream_kind&exec_stream_t::s_in ) { + m_in_buffer_limit=limit; + } + if( stream_kind&exec_stream_t::s_out ) { + m_out_buffer_limit=limit; + } + if( stream_kind&exec_stream_t::s_err ) { + m_err_buffer_limit=limit; + } +} + +void thread_buffer_t::set_read_buffer_size( int stream_kind, std::size_t size ) +{ + if( m_thread_started ) { + throw exec_stream_t::error_t( "thread_buffer_t::set_read_buffer_size: thread already started" ); + } + if( stream_kind&exec_stream_t::s_out ) { + m_out_read_buffer_size=size; + } + if( stream_kind&exec_stream_t::s_err ) { + m_err_read_buffer_size=size; + } +} + +void thread_buffer_t::start() +{ + if( m_thread_started ) { + throw exec_stream_t::error_t( "thread_buffer_t::start: thread already started" ); + } + m_in_buffer.clear(); + m_out_buffer.clear(); + m_err_buffer.clear(); + + int code; + if( (code=m_thread_control.reset( ~0u, 0 )) || (code=m_thread_control.set( exec_stream_t::s_out|exec_stream_t::s_err, 0 ) ) ) { + throw os_error_t( "thread_buffer_t::start: unable to initialize m_thread_control event", code ); + } + if( (code=m_thread_responce.reset( ~0u, 0 )) || (code=m_thread_responce.set( exec_stream_t::s_in, 0 )) ) { + throw os_error_t( "thread_buffer_t::start: unable to initialize m_thread_responce event", code ); + } + + m_error_prefix=""; + m_error_code=0; + + if( int code=pthread_create( &m_thread, 0, &thread_func, this ) ) { + throw os_error_t( "exec_stream_therad_t::start: pthread_create failed", code ); + } + m_thread_started=true; + m_in_closed=false; + m_in_bad=false; +} + +bool thread_buffer_t::stop_thread() +{ + if( m_thread_started ) { + if( int code=m_thread_control.set( exec_stream_t::s_child, 0 ) ) { + throw os_error_t( "thread_buffer_t::stop_thread: unable to set thread termination event", code ); + } + wait_result_t wait_result=m_thread_responce.wait( exec_stream_t::s_child, m_thread_termination_timeout, 0 ); + if( !wait_result.ok() && !wait_result.timed_out() ) { + throw os_error_t( "thread_buffer_t::stop_thread: wait for m_thread_stopped failed", wait_result.error_code() ); + } + if( wait_result.ok() ) { + void * thread_result; + if( int code=pthread_join( m_thread, &thread_result ) ) { + throw os_error_t( "thread_buffer_t::stop_thread: pthread_join failed", code ); + } + m_thread_started=false; + // check for any errors encountered in the thread + if( m_error_code!=0 ) { + throw os_error_t( m_error_prefix, m_error_code ); + } + return true; + }else { + return false; + } + } + return true; +} + +bool thread_buffer_t::abort_thread() +{ + if( m_thread_started ) { + if( int code=pthread_cancel( m_thread ) ) { + throw os_error_t( "thread_buffer_t::abort_thread: pthread_cancel failed", code ); + } + void * thread_result; + if( int code=pthread_join( m_thread, &thread_result ) ) { + throw os_error_t( "thread_buffer_t::stop_thread: pthread_join failed", code ); + } + m_thread_started=false; + } + return true; +} + +const int s_in_eof=16; +const int s_out_eof=32; +const int s_err_eof=64; + +void thread_buffer_t::get( exec_stream_t::stream_kind_t kind, char * dst, std::size_t & size, bool & no_more ) +{ + if( !m_thread_started ) { + throw exec_stream_t::error_t( "thread_buffer_t::get: thread was not started" ); + } + unsigned long timeout= kind==exec_stream_t::s_out ? m_out_wait_timeout : m_err_wait_timeout; + int eof_kind= kind==exec_stream_t::s_out ? s_out_eof : s_err_eof; + buffer_list_t & buffer= kind==exec_stream_t::s_out ? m_out_buffer : m_err_buffer; + + wait_result_t wait_result=m_thread_responce.wait( kind|exec_stream_t::s_child|eof_kind, timeout, 0 ); + if( !wait_result.ok() ) { + throw os_error_t( "thread_buffer_t::get: wait for got_data failed", wait_result.error_code() ); + } + + if( wait_result.is_signaled( exec_stream_t::s_child ) ) { + // thread stopped - no need to synchronize + if( !buffer.empty() ) { + // we have data - deliver it first + // when thread terminated, there is no need to synchronize + buffer.get( dst, size ); + no_more=false; + }else { + // thread terminated and we have no more data to return - report errors, if any + if( m_error_code!=0 ) { + throw os_error_t( m_error_prefix, m_error_code ); + } + // if terminated without error - signal eof + size=0; + no_more=true; + } + }else if( wait_result.is_signaled( kind|eof_kind ) ) { + // thread got some data for us - grab them + grab_mutex_t grab_mutex( m_mutex, 0 ); + if( !grab_mutex.ok() ) { + throw os_error_t( "thread_buffer_t::get: wait for mutex failed", grab_mutex.error_code() ); + } + + if( !buffer.empty() ) { + buffer.get( dst, size ); + no_more=false; + }else { + size=0; + no_more=wait_result.is_signaled( eof_kind ); + } + // if no data left - make the next get() wait until it arrives + if( buffer.empty() ) { + if( int code=m_thread_responce.reset( kind, 0 ) ) { + throw os_error_t( "thread_buffer_t::get: unable to reset got_data event", code ); + } + } + // if buffer is not too long tell the thread we want more data + std::size_t buffer_limit= kind==exec_stream_t::s_out ? m_out_buffer_limit : m_err_buffer_limit; + if( !buffer.full( buffer_limit ) ) { + if( int code=m_thread_control.set( kind, 0 ) ) { + throw os_error_t( "thread_buffer_t::get: unable to set want_data event", code ); + } + } + } + no_more=false; +} + +void thread_buffer_t::put( char * src, std::size_t & size, bool & no_more ) +{ + if( !m_thread_started ) { + throw exec_stream_t::error_t( "thread_buffer_t::put: thread was not started" ); + } + if( m_in_closed || m_in_bad ) { + size=0; + no_more=true; + return; + } + // wait for both m_want_data and m_mutex + wait_result_t wait_result=m_thread_responce.wait( exec_stream_t::s_in|exec_stream_t::s_child, m_in_wait_timeout, 0 ); + if( !wait_result.ok() ) { + // workaround for versions of libstdc++ (at least in gcc 3.1 pre) that do not intercept exceptions in operator<<( std::ostream, std::string ) + m_in_bad=true; + if( m_in.exceptions()&std::ios_base::badbit ) { + throw os_error_t( "thread_buffer_t::put: wait for want_data failed", wait_result.error_code() ); + }else { + m_in.setstate( std::ios_base::badbit ); + size=0; + no_more=true; + return; + } + } + if( wait_result.is_signaled( exec_stream_t::s_child ) ) { + // thread stopped - check for errors + if( m_error_code!=0 ) { + throw os_error_t( m_error_prefix, m_error_code ); + } + // if terminated without error - signal eof, since no one will ever write our data + size=0; + no_more=true; + }else if( wait_result.is_signaled( exec_stream_t::s_in ) ) { + // thread wants some data from us - stuff them + grab_mutex_t grab_mutex( m_mutex, 0 ); + if( !grab_mutex.ok() ) { + throw os_error_t( "thread_buffer_t::put: wait for mutex failed", grab_mutex.error_code() ); + } + + no_more=false; + m_in_buffer.put( src, size ); + + // if the buffer is too long - make the next put() wait until it shrinks + if( m_in_buffer.full( m_in_buffer_limit ) ) { + if( int code=m_thread_responce.reset( exec_stream_t::s_in, 0 ) ) { + throw os_error_t( "thread_buffer_t::put: unable to reset want_data event", code ); + } + } + // tell the thread we got data + if( !m_in_buffer.empty() ) { + if( int code=m_thread_control.set( exec_stream_t::s_in, 0 ) ) { + throw os_error_t( "thread_buffer_t::put: unable to set got_data event", code ); + } + } + } + no_more=false; +} + +void thread_buffer_t::close_in() +{ + if( !m_in_bad ) { + m_in.flush(); + } + if( m_thread_started ) { + if( int code=m_thread_control.set( s_in_eof, 0 ) ) { + throw os_error_t( "thread_buffer_t::close_in: unable to set in_got_data event", code ); + } + m_in_closed=true; + } +} + +void mutex_cleanup( void * p ) +{ + static_cast< mutex_registrator_t * >( p )->release_all(); +} + +void * thread_buffer_t::thread_func( void * param ) +{ + thread_buffer_t * p=static_cast< thread_buffer_t * >( param ); + // accessing p anywhere here is safe because thread_buffer_t destructor + // ensures the thread is terminated before p get destroyed + char * out_read_buffer=0; + char * err_read_buffer=0; + bool in_eof=false; + bool in_closed=false; + bool out_eof=false; + bool err_eof=false; + + mutex_registrator_t mutex_registrator; + pthread_cleanup_push( mutex_cleanup, &mutex_registrator ); + + try { + out_read_buffer=new char[p->m_out_read_buffer_size]; + err_read_buffer=new char[p->m_err_read_buffer_size]; + + buffer_list_t::buffer_t write_buffer; + write_buffer.data=0; + write_buffer.size=0; + std::size_t write_buffer_offset=0; + + unsigned long timeout=std::max( p->m_in_wait_timeout, std::max( p->m_out_wait_timeout, p->m_err_wait_timeout ) ); + + fd_set read_fds; + FD_ZERO( &read_fds ); + fd_set write_fds; + FD_ZERO( &write_fds ); + + while( true ) { + unsigned wait_for=exec_stream_t::s_child; + if( !in_eof && write_buffer.data==0 ) { + wait_for|=exec_stream_t::s_in|s_in_eof; + } + if( !out_eof ) { + wait_for|=exec_stream_t::s_out; + } + if( !err_eof ) { + wait_for|=exec_stream_t::s_err; + } + + wait_result_t wait_result=p->m_thread_control.wait( wait_for, timeout, &mutex_registrator ); + if( !wait_result.ok() && !wait_result.timed_out() ) { + p->m_error_code=wait_result.error_code(); + p->m_error_prefix="thread_buffer_t::thread_func: wait for thread_event failed"; + break; + } + + // we need more data - get from p->m_buffers + if( write_buffer.data==0 && wait_result.is_signaled( exec_stream_t::s_in|s_in_eof ) ) { + grab_mutex_t grab_mutex( p->m_mutex, &mutex_registrator ); + if( !grab_mutex.ok() ) { + p->m_error_code=grab_mutex.error_code(); + p->m_error_prefix="thread_buffer_t::thread_func: wait for mutex failed"; + break; + } + + if( p->m_in_buffer.empty() ) { + // we have empty write_buffer, empty p->m_in_buffer and we are told it will stay so - time to close child's stdin + if( wait_result.is_signaled( s_in_eof ) ) { + in_eof=true; + } + } + if( !p->m_in_buffer.empty() ) { + // we've got buffer - detach it + write_buffer=p->m_in_buffer.detach(); + write_buffer_offset=0; + } + // if no data left in p->m_in_buffer - wait until it arrives + if( p->m_in_buffer.empty() ) { + // if no data for us - stop trying to get it until we are told it arrived + if( int code=p->m_thread_control.reset( exec_stream_t::s_in, &mutex_registrator ) ) { + p->m_error_code=code; + p->m_error_prefix="thread_buffer_t::thread_func: unable to reset thread_event (s_in)"; + break; + } + } + + // if buffer is not too long - tell put() it can proceed + if( !p->m_in_buffer.full( p->m_in_buffer_limit ) ) { + if( int code=p->m_thread_responce.set( exec_stream_t::s_in, &mutex_registrator ) ) { + p->m_error_code=code; + p->m_error_prefix="thread_buffer_t::thread_func: unable to set in_want_data event"; + break; + } + } + } + + if( in_eof && write_buffer.data==0 ) { + p->m_in_pipe.close(); + in_closed=true; + } + + // see if they want us to stop, but only when there is nothing more to write + if( write_buffer.data==0 && wait_result.is_signaled( exec_stream_t::s_child ) ) { + break; + } + + // determine whether we want something + if( write_buffer.data!=0 ) { + FD_SET( p->m_in_pipe.w(), &write_fds ); + }else { + FD_CLR( p->m_in_pipe.w(), &write_fds ); + } + if( !out_eof && wait_result.is_signaled( exec_stream_t::s_out ) ) { + FD_SET( p->m_out_pipe.r(), &read_fds ); + }else { + FD_CLR( p->m_out_pipe.r(), &read_fds ); + } + if( !err_eof && wait_result.is_signaled( exec_stream_t::s_err ) ) { + FD_SET( p->m_err_pipe.r(), &read_fds ); + }else { + FD_CLR( p->m_err_pipe.r(), &read_fds ); + } + + if( FD_ISSET( p->m_in_pipe.w(), &write_fds ) || FD_ISSET( p->m_out_pipe.r(), &read_fds ) || FD_ISSET( p->m_err_pipe.r(), &read_fds ) ) { + // we want something - get it + struct timeval select_timeout; + select_timeout.tv_sec=0; + select_timeout.tv_usec=100000; + int nfds=std::max( p->m_in_pipe.w(), std::max( p->m_out_pipe.r(), p->m_err_pipe.r() ) )+1; + if( select( nfds, &read_fds, &write_fds, 0, &select_timeout )==-1 ) { + p->m_error_code=errno; + p->m_error_prefix="thread_buffer_t::thread_func: select failed"; + break; + } + } + + // determine what we got + + if( FD_ISSET( p->m_in_pipe.w(), &write_fds ) ) { + // it seems we may write to child's stdin + int n_written=write( p->m_in_pipe.w(), write_buffer.data+write_buffer_offset, write_buffer.size-write_buffer_offset ); + if( n_written==-1 ) { + if( errno!=EAGAIN ) { + p->m_error_code=errno; + p->m_error_prefix="thread_buffer_t::thread_func: write to child stdin failed"; + break; + } + }else { + write_buffer_offset+=n_written; + if( write_buffer_offset==write_buffer.size ) { + delete[] write_buffer.data; + write_buffer.data=0; + write_buffer.size=0; + } + } + } + + if( FD_ISSET( p->m_out_pipe.r(), &read_fds ) ) { + // it seems we may read child's stdout + int n_out_read=read( p->m_out_pipe.r(), out_read_buffer, p->m_out_read_buffer_size ); + if( n_out_read==-1 ) { + if( errno!=EAGAIN ) { + p->m_error_code=errno; + p->m_error_prefix="exec_stream_t::thread_func: read from child stdout failed"; + break; + } + }else { + grab_mutex_t grab_mutex( p->m_mutex, &mutex_registrator ); + if( n_out_read!=0 ) { + p->m_out_buffer.put( out_read_buffer, n_out_read ); + // if buffer is full - stop reading + if( p->m_out_buffer.full( p->m_out_buffer_limit ) ) { + if( int code=p->m_thread_control.reset( exec_stream_t::s_out, &mutex_registrator ) ) { + p->m_error_code=code; + p->m_error_prefix="exec_stream_t::thread_func: unable to reset m_out_want_data event"; + break; + } + } + } + unsigned responce=exec_stream_t::s_out; + if( n_out_read==0 ) { // EOF when read 0 bytes while select told that it's ready + out_eof=true; + responce|=s_out_eof; + } + // we got either data or eof - tell always + if( int code=p->m_thread_responce.set( responce, &mutex_registrator ) ) { + p->m_error_code=code; + p->m_error_prefix="exec_stream_t::thread_func: unable to set out_got_data event"; + break; + } + } + } + + if( FD_ISSET( p->m_err_pipe.r(), &read_fds ) ) { + // it seemds we may read child's stderr + int n_err_read=read( p->m_err_pipe.r(), err_read_buffer, p->m_err_read_buffer_size ); + if( n_err_read==-1 ) { + if( errno!=EAGAIN ) { + p->m_error_code=errno; + p->m_error_prefix="exec_stream_t::thread_func: read from child stderr failed"; + break; + } + }else { + grab_mutex_t grab_mutex( p->m_mutex, &mutex_registrator ); + if( n_err_read!=0 ) { + p->m_err_buffer.put( err_read_buffer, n_err_read ); + // if buffer is full - stop reading + if( p->m_err_buffer.full( p->m_err_buffer_limit ) ) { + if( int code=p->m_thread_control.reset( exec_stream_t::s_err, &mutex_registrator ) ) { + p->m_error_code=code; + p->m_error_prefix="exec_stream_t::thread_func: unable to reset m_err_want_data event"; + break; + } + } + } + unsigned responce=exec_stream_t::s_err; + if( n_err_read==0 ) { + err_eof=true; + responce|=s_err_eof; + } + // we got either data or eof - tell always + if( int code=p->m_thread_responce.set( responce, &mutex_registrator ) ) { + p->m_error_code=code; + p->m_error_prefix="exec_stream_t::thread_func: unable to set err_got_data event"; + break; + } + } + } + + if( in_closed && out_eof && err_eof ) { + // have nothing more to do + break; + } + } + + delete[] write_buffer.data; + + }catch( ... ) { + // might only be std::bad_alloc + p->m_error_code=0; + p->m_error_prefix="thread_buffer_t::writer_thread: exception caught"; + } + + delete[] out_read_buffer; + delete[] err_read_buffer; + + // tell everyone that we've stopped, so that get() and put() will be unblocked + if( int code=p->m_thread_responce.set( exec_stream_t::s_child, &mutex_registrator ) ) { + p->m_error_code=code; + p->m_error_prefix="exec_stream_t::thread_func: unable to set thread_stopped event"; + } + + pthread_cleanup_pop( 0 ); + return 0; +} diff --git a/libwebthree/libexecstream/posix/exec-stream-helpers.h b/libwebthree/libexecstream/posix/exec-stream-helpers.h new file mode 100644 index 0000000000..99be3b6ca9 --- /dev/null +++ b/libwebthree/libexecstream/posix/exec-stream-helpers.h @@ -0,0 +1,239 @@ +/* +Copyright (C) 2004 Artem Khodush + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +3. The name of the author may not be used to endorse or promote products +derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +class os_error_t : public exec_stream_t::error_t { +public: + os_error_t( std::string const & msg ); + os_error_t( std::string const & msg, exec_stream_t::error_code_t code ); +private: + void compose( std::string const & msg, exec_stream_t::error_code_t code ); +}; + + +template< class T > class buf_t { +public: + typedef T data_t; + + buf_t() + { + m_buf=0; + m_size=0; + } + + ~buf_t() + { + delete [] m_buf; + } + + data_t * new_data( std::size_t size ) + { + m_buf=new T[size]; + m_size=size; + return m_buf; + } + + void append_data( data_t const * data, std::size_t size ) + { + buf_t new_buf; + new_buf.new_data( m_size+size ); + std::char_traits< data_t >::copy( new_buf.m_buf, m_buf, m_size ); + std::char_traits< data_t >::copy( new_buf.m_buf+m_size, data, size ); + std::swap( this->m_buf, new_buf.m_buf ); + std::swap( this->m_size, new_buf.m_size ); + } + + data_t * data() + { + return m_buf; + } + + std::size_t size() + { + return m_size; + } + +private: + buf_t( buf_t const & ); + buf_t & operator=( buf_t const & ); + + data_t * m_buf; + std::size_t m_size; +}; + + +class pipe_t { +public: + pipe_t(); + ~pipe_t(); + int r() const; + int w() const; + void close_r(); + void close_w(); + void close(); + void open(); +private: + enum direction_t{ closed, read, write, both }; + direction_t m_direction; + int m_fds[2]; +}; + + +class mutex_t { +public: + mutex_t(); + ~mutex_t(); + +private: + pthread_mutex_t m_mutex; + + friend class event_t; + friend class grab_mutex_t; +}; + + +class grab_mutex_t { +public: + grab_mutex_t( mutex_t & mutex, class mutex_registrator_t * mutex_registrator ); + ~grab_mutex_t(); + + int release(); + bool ok(); + int error_code(); + +private: + pthread_mutex_t * m_mutex; + int m_error_code; + bool m_grabbed; + class mutex_registrator_t * m_mutex_registrator; + + friend class mutex_registrator_t; +}; + +class mutex_registrator_t { +public: + ~mutex_registrator_t(); + void add( grab_mutex_t * g ); + void remove( grab_mutex_t * g ); + void release_all(); +private: + typedef std::list< grab_mutex_t * > mutexes_t; + mutexes_t m_mutexes; +}; + + +class wait_result_t { +public: + wait_result_t( unsigned signaled_state, int error_code, bool timed_out ); + + bool ok(); + bool is_signaled( int state ); + int error_code(); + bool timed_out(); + +private: + unsigned m_signaled_state; + int m_error_code; + bool m_timed_out; +}; + + +class event_t { +public: + event_t(); + ~event_t(); + + int set( unsigned bits, mutex_registrator_t * mutex_registrator ); + int reset( unsigned bits, mutex_registrator_t * mutex_registrator ); + + wait_result_t wait( unsigned any_bits, unsigned long timeout, mutex_registrator_t * mutex_registrator ); + +private: + mutex_t m_mutex; + pthread_cond_t m_cond; + unsigned volatile m_state; +}; + + +class thread_buffer_t { +public: + thread_buffer_t( pipe_t & in_pipe, pipe_t & out_pipe, pipe_t & err_pipe, std::ostream & in ); + ~thread_buffer_t(); + + void set_wait_timeout( int stream_kind, unsigned long milliseconds ); + void set_buffer_limit( int stream_kind, std::size_t limit ); + void set_read_buffer_size( int stream_kind, std::size_t size ); + + void start(); + + void get( exec_stream_t::stream_kind_t kind, char * dst, std::size_t & size, bool & no_more ); + void put( char * src, std::size_t & size, bool & no_more ); + + void close_in(); + bool stop_thread(); + bool abort_thread(); + +private: + static void * thread_func( void * param ); + + pthread_t m_thread; + mutex_t m_mutex; // protecting m_in_buffer, m_out_buffer, m_err_buffer + + buffer_list_t m_in_buffer; + buffer_list_t m_out_buffer; + buffer_list_t m_err_buffer; + + event_t m_thread_control; // s_in : in got_data; s_out: out want data; s_err: err want data; s_child: stop thread + event_t m_thread_responce; // s_in : in want data; s_out: out got data; s_err: err got data; s_child: thread stopped + + char const * m_error_prefix; + int m_error_code; + + bool m_thread_started; // set in start(), checked in set_xxx(), get() and put() + bool m_in_closed; // set in close_in(), checked in put() + + pipe_t & m_in_pipe; + pipe_t & m_out_pipe; + pipe_t & m_err_pipe; + + unsigned long m_in_wait_timeout; + unsigned long m_out_wait_timeout; + unsigned long m_err_wait_timeout; + + unsigned long m_thread_termination_timeout; + + std::size_t m_in_buffer_limit; + std::size_t m_out_buffer_limit; + std::size_t m_err_buffer_limit; + + std::size_t m_out_read_buffer_size; + std::size_t m_err_read_buffer_size; + + // workaround for not-quite-conformant libstdc++ (see put()) + std::ostream & m_in; + bool m_in_bad; +}; diff --git a/libwebthree/libexecstream/posix/exec-stream-impl.cpp b/libwebthree/libexecstream/posix/exec-stream-impl.cpp new file mode 100644 index 0000000000..8a861d9b0c --- /dev/null +++ b/libwebthree/libexecstream/posix/exec-stream-impl.cpp @@ -0,0 +1,395 @@ +/* +Copyright (C) 2004 Artem Khodush + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +3. The name of the author may not be used to endorse or promote products +derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +using namespace helpers; + +// exec_stream_t::impl_t +struct exec_stream_t::impl_t { + impl_t(); + ~impl_t(); + + void split_args( std::string const & program, std::string const & arguments ); + void split_args( std::string const & program, exec_stream_t::next_arg_t & next_arg ); + void start( std::string const & program ); + + pid_t m_child_pid; + int m_exit_code; + unsigned long m_child_timeout; + + buf_t< char > m_child_args; + buf_t< char * > m_child_argp; + + pipe_t m_in_pipe; + pipe_t m_out_pipe; + pipe_t m_err_pipe; + + thread_buffer_t m_thread; + + exec_stream_buffer_t m_in_buffer; + exec_stream_buffer_t m_out_buffer; + exec_stream_buffer_t m_err_buffer; + + exec_ostream_t m_in; + exec_istream_t m_out; + exec_istream_t m_err; + + void (*m_old_sigpipe_handler)(int); +}; + +exec_stream_t::impl_t::impl_t() +: m_thread( m_in_pipe, m_out_pipe, m_err_pipe, m_in ), /* m_in here is not initialized, but its ok */ + m_in_buffer( exec_stream_t::s_in, m_thread ), m_out_buffer( exec_stream_t::s_out, m_thread ), m_err_buffer( exec_stream_t::s_err, m_thread ), + m_in( m_in_buffer ), m_out( m_out_buffer ), m_err( m_err_buffer ) +{ + m_out.tie( &m_in ); + m_err.tie( &m_in ); + m_child_timeout=1000; + m_child_pid=-1; + m_old_sigpipe_handler=signal( SIGPIPE, SIG_IGN ); +} + +exec_stream_t::impl_t::~impl_t() +{ + signal( SIGPIPE, m_old_sigpipe_handler ); +} + +void exec_stream_t::impl_t::split_args( std::string const & program, std::string const & arguments ) +{ + char * args_end=m_child_args.new_data( program.size()+1+arguments.size()+1 ); + int argc=1; + + std::string::traits_type::copy( args_end, program.data(), program.size() ); + args_end+=program.size(); + *args_end++=0; + + std::string whitespace=" \t\r\n\v"; + + std::string::size_type arg_start=arguments.find_first_not_of( whitespace ); + while( arg_start!=std::string::npos ) { + ++argc; + std::string::size_type arg_stop; + if( arguments[arg_start]!='"' ) { + arg_stop=arguments.find_first_of( whitespace, arg_start ); + if( arg_stop==std::string::npos ) { + arg_stop=arguments.size(); + } + std::string::traits_type::copy( args_end, arguments.data()+arg_start, arg_stop-arg_start ); + args_end+=arg_stop-arg_start; + }else { + std::string::size_type cur=arg_start+1; + while( true ) { + std::string::size_type next=arguments.find( '"', cur ); + if( next==std::string::npos || arguments[next-1]!='\\' ) { + if( next==std::string::npos ) { + next=arguments.size(); + arg_stop=next; + }else { + arg_stop=next+1; + } + std::string::traits_type::copy( args_end, arguments.data()+cur, next-cur ); + args_end+=next-cur; + break; + }else { + std::string::traits_type::copy( args_end, arguments.data()+cur, next-1-cur ); + args_end+=next-1-cur; + *args_end++='"'; + cur=next+1; + } + } + } + *args_end++=0; + arg_start=arguments.find_first_not_of( whitespace, arg_stop ); + } + + char ** argp_end=m_child_argp.new_data( argc+1 ); + char * args=m_child_args.data(); + while( args!=args_end ) { + *argp_end=args; + args+=std::string::traits_type::length( args )+1; + ++argp_end; + } + *argp_end=0; +} + +void exec_stream_t::impl_t::split_args( std::string const & program, exec_stream_t::next_arg_t & next_arg ) +{ + typedef std::vector< std::size_t > arg_sizes_t; + arg_sizes_t arg_sizes; + + m_child_args.new_data( program.size()+1 ); + std::string::traits_type::copy( m_child_args.data(), program.c_str(), program.size()+1 ); + arg_sizes.push_back( program.size()+1 ); + + while( std::string const * s=next_arg.next() ) { + m_child_args.append_data( s->c_str(), s->size()+1 ); + arg_sizes.push_back( s->size()+1 ); + } + + char ** argp_end=m_child_argp.new_data( arg_sizes.size()+1 ); + char * argp=m_child_args.data(); + for( arg_sizes_t::iterator i=arg_sizes.begin(); i!=arg_sizes.end(); ++i ) { + *argp_end=argp; + argp+=*i; + ++argp_end; + } + *argp_end=0; +} + +void exec_stream_t::set_buffer_limit( int stream_kind, std::size_t size ) +{ + m_impl->m_thread.set_buffer_limit( stream_kind, size ); +} + +void exec_stream_t::set_wait_timeout( int stream_kind, timeout_t milliseconds ) +{ + m_impl->m_thread.set_wait_timeout( stream_kind, milliseconds ); + if( stream_kind&exec_stream_t::s_child ) { + m_impl->m_child_timeout=milliseconds; + } +} + +void exec_stream_t::start( std::string const & program, std::string const & arguments ) +{ + if( !close() ) { + throw exec_stream_t::error_t( "exec_stream_t::start: previous child process has not yet terminated" ); + } + + m_impl->split_args( program, arguments ); + m_impl->start( program ); +} + +void exec_stream_t::start( std::string const & program, exec_stream_t::next_arg_t & next_arg ) +{ + if( !close() ) { + throw exec_stream_t::error_t( "exec_stream_t::start: previous child process has not yet terminated" ); + } + + m_impl->split_args( program, next_arg ); + m_impl->start( program ); +} + +void exec_stream_t::impl_t::start( std::string const & program ) +{ + m_in_pipe.open(); + m_out_pipe.open(); + m_err_pipe.open(); + + pipe_t status_pipe; + status_pipe.open(); + + pid_t pid=fork(); + if( pid==-1 ) { + throw os_error_t( "exec_stream_t::start: fork failed" ); + }else if( pid==0 ) { + try { + status_pipe.close_r(); + if( fcntl( status_pipe.w(), F_SETFD, FD_CLOEXEC )==-1 ) { + throw os_error_t( "exec_stream_t::start: unable to fcnth( status_pipe, F_SETFD, FD_CLOEXEC ) in child process" ); + } + m_in_pipe.close_w(); + m_out_pipe.close_r(); + m_err_pipe.close_r(); + if( ::close( 0 )==-1 ) { + throw os_error_t( "exec_stream_t::start: unable to close( 0 ) in child process" ); + } + if( fcntl( m_in_pipe.r(), F_DUPFD, 0 )==-1 ) { + throw os_error_t( "exec_stream_t::start: unable to fcntl( .., F_DUPFD, 0 ) in child process" ); + } + if( ::close( 1 )==-1 ) { + throw os_error_t( "exec_stream_t::start: unable to close( 1 ) in child process" ); + } + if( fcntl( m_out_pipe.w(), F_DUPFD, 1 )==-1 ) { + throw os_error_t( "exec_stream_t::start: unable to fcntl( .., F_DUPFD, 1 ) in child process" ); + } + if( ::close( 2 )==-1 ) { + throw os_error_t( "exec_stream_t::start: unable to close( 2 ) in child process" ); + } + if( fcntl( m_err_pipe.w(), F_DUPFD, 2 )==-1 ) { + throw os_error_t( "exec_stream_t::start: unable to fcntl( .., F_DUPFD, 2 ) in child process" ); + } + m_in_pipe.close_r(); + m_out_pipe.close_w(); + m_err_pipe.close_w(); + if( execvp( m_child_args.data(), m_child_argp.data() )==-1 ) { + throw os_error_t( "exec_stream_t::start: exec in child process failed. "+program ); + } + throw exec_stream_t::error_t( "exec_stream_t::start: exec in child process returned" ); + }catch( std::exception const & e ) { + const char * msg=e.what(); + std::size_t len=strlen( msg ); + // no sense in checking return of write here, but gcc has a long standing but + // which would generate warnings if we did not: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25509 + if (-1 == write( status_pipe.w(), &len, sizeof( len ) )) + _exit( -1 ); + if (-1 == write( status_pipe.w(), msg, len )) + _exit( -1 ); + _exit( -1 ); + }catch( ... ) { + const char* msg = "exec_stream_t::start: unknown exception in child process"; + std::size_t len=strlen( msg ); + // no sense in checking return of write here, but gcc has a long standing but + // which would generate warnings if we did not: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25509 + if (-1 == write( status_pipe.w(), &len, sizeof( len ) )) + _exit( 1 ); + if (-1 == write( status_pipe.w(), msg, len )) + _exit ( 1 ); + _exit( 1 ); + } + }else { + m_child_pid=pid; + status_pipe.close_w(); + fd_set status_fds; + FD_ZERO( &status_fds ); + FD_SET( status_pipe.r(), &status_fds ); + struct timeval timeout; + timeout.tv_sec=3; + timeout.tv_usec=0; + if( select( status_pipe.r()+1, &status_fds, 0, 0, &timeout )==-1 ) { + throw os_error_t( "exec_stream_t::start: select on status_pipe failed" ); + } + if( !FD_ISSET( status_pipe.r(), &status_fds ) ) { + throw os_error_t( "exec_stream_t::start: timeout while waiting for child to report via status_pipe" ); + } + std::size_t status_len; + int status_nread=read( status_pipe.r(), &status_len, sizeof( status_len ) ); + // when all ok, status_pipe is closed on child's exec, and nothing is written to it + if( status_nread!=0 ) { + // otherwize, check what went wrong. + if( status_nread==-1 ) { + throw os_error_t( "exec_stream_t::start: read from status pipe failed" ); + }else if( status_nread!=sizeof( status_len ) ) { + throw os_error_t( "exec_stream_t::start: unable to read length of status message from status_pipe" ); + } + std::string status_msg; + if( status_len!=0 ) { + buf_t< char > status_buf; + status_buf.new_data( status_len ); + status_nread=read( status_pipe.r(), status_buf.data(), status_len ); + if( status_nread==-1 ) { + throw os_error_t( "exec_stream_t::start: readof status message from status pipe failed" ); + } + status_msg.assign( status_buf.data(), status_len ); + } + throw exec_stream_t::error_t( "exec_stream_t::start: error in child process."+status_msg ); + } + status_pipe.close_r(); + + m_in_pipe.close_r(); + m_out_pipe.close_w(); + m_err_pipe.close_w(); + + if( fcntl( m_in_pipe.w(), F_SETFL, O_NONBLOCK )==-1 ) { + throw os_error_t( "exec_stream_t::start: fcntl( in_pipe, F_SETFL, O_NONBLOCK ) failed" ); + } + + m_in_buffer.clear(); + m_out_buffer.clear(); + m_err_buffer.clear(); + + m_in.clear(); + m_out.clear(); + m_err.clear(); + + m_thread.set_read_buffer_size( exec_stream_t::s_out, STREAM_BUFFER_SIZE ); + m_thread.set_read_buffer_size( exec_stream_t::s_err, STREAM_BUFFER_SIZE ); + m_thread.start(); + } +} + +bool exec_stream_t::close_in() +{ + m_impl->m_thread.close_in(); + return true; +} + +bool exec_stream_t::close() +{ + close_in(); + if( !m_impl->m_thread.stop_thread() ) { + m_impl->m_thread.abort_thread(); + } + m_impl->m_in_pipe.close(); + m_impl->m_out_pipe.close(); + m_impl->m_err_pipe.close(); + + if( m_impl->m_child_pid!=-1 ) { + pid_t code=waitpid( m_impl->m_child_pid, &m_impl->m_exit_code, WNOHANG ); + if( code==-1 ) { + throw os_error_t( "exec_stream_t::close: first waitpid failed" ); + }else if( code==0 ) { + + struct timeval select_timeout; + select_timeout.tv_sec=m_impl->m_child_timeout/1000; + select_timeout.tv_usec=(m_impl->m_child_timeout%1000)*1000; + if( (code=select( 0, 0, 0, 0, &select_timeout ))==-1 ) { + throw os_error_t( "exec_stream_t::close: select failed" ); + } + + code=waitpid( m_impl->m_child_pid, &m_impl->m_exit_code, WNOHANG ); + if( code==-1 ) { + throw os_error_t( "exec_stream_t::close: second waitpid failed" ); + }else if( code==0 ) { + return false; + }else { + m_impl->m_child_pid=-1; + return true; + } + + }else { + m_impl->m_child_pid=-1; + return true; + } + } + return true; +} + +void exec_stream_t::kill() +{ + if( m_impl->m_child_pid!=-1 ) { + if( ::kill( m_impl->m_child_pid, SIGKILL )==-1 ) { + throw os_error_t( "exec_stream_t::kill: kill failed" ); + } + m_impl->m_child_pid=-1; + m_impl->m_exit_code=0; + } +} + +int exec_stream_t::exit_code() +{ + if( m_impl->m_child_pid!=-1 ) { + throw exec_stream_t::error_t( "exec_stream_t::exit_code: child process still running" ); + } + return WEXITSTATUS( m_impl->m_exit_code ); +} + +void exec_stream_t::set_binary_mode( int ) +{ +} + +void exec_stream_t::set_text_mode( int ) +{ +} diff --git a/libwebthree/libexecstream/win/exec-stream-helpers.cpp b/libwebthree/libexecstream/win/exec-stream-helpers.cpp new file mode 100644 index 0000000000..c9b6c5a3e2 --- /dev/null +++ b/libwebthree/libexecstream/win/exec-stream-helpers.cpp @@ -0,0 +1,727 @@ +/* +Copyright (C) 2004 Artem Khodush + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +3. The name of the author may not be used to endorse or promote products +derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +// os_error_t +os_error_t::os_error_t( std::string const & msg ) +{ + compose( msg, GetLastError() ); +} + +os_error_t::os_error_t( std::string const & msg, exec_stream_t::error_code_t code ) +{ + compose( msg, code ); +} + +void os_error_t::compose( std::string const & msg, exec_stream_t::error_code_t code ) +{ + std::string s( msg ); + s+='\n'; + LPVOID buf; + if( FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, + 0, + code, + MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), + (LPTSTR) &buf, + 0, + 0 + )==0 ) { + s+="[unable to retrieve error description]"; + }else { + // FormatMessage may return \n-terminated string + LPTSTR str_buf=(LPTSTR)buf; + std::size_t buf_len=strlen( str_buf ); + while( buf_len>0 && str_buf[buf_len-1]=='\n' ) { + --buf_len; + str_buf[buf_len]=0; + } + s+=(LPTSTR)buf; + LocalFree( buf ); + } + exec_stream_t::error_t::compose( s, code ); +} + +// pipe_t +pipe_t::pipe_t() +: m_direction( closed ), m_r( INVALID_HANDLE_VALUE ), m_w( INVALID_HANDLE_VALUE ) +{ + open(); +} + +pipe_t::~pipe_t() +{ + close(); +} + +void pipe_t::close_r() +{ + if( m_direction==both || m_direction==read ) { + if( !CloseHandle( m_r ) ) { + throw os_error_t( "pipe_t::close_r: CloseHandle failed" ); + } + m_direction= m_direction==both ? write : closed; + } +} + +void pipe_t::close_w() +{ + if( m_direction==both || m_direction==write ) { + if( !CloseHandle( m_w ) ) { + throw os_error_t( "pipe_t::close_w: CloseHandle failed" ); + } + m_direction= m_direction==both ? read : closed; + } +} + +void pipe_t::close() +{ + close_r(); + close_w(); +} + +void pipe_t::open() +{ + close(); + SECURITY_ATTRIBUTES sa; + sa.nLength=sizeof( sa ); + sa.bInheritHandle=true; + sa.lpSecurityDescriptor=0; + if( !CreatePipe( &m_r, &m_w, &sa, 0 ) ) + throw os_error_t( "pipe_t::pipe_t: CreatePipe failed" ); + m_direction=both; +} + +HANDLE pipe_t::r() const +{ + return m_r; +} + +HANDLE pipe_t::w() const +{ + return m_w; +} + +// set_stdhandle_t +set_stdhandle_t::set_stdhandle_t( DWORD kind, HANDLE handle ) +: m_kind( kind ), m_save_handle( GetStdHandle( kind ) ) +{ + if( m_save_handle==INVALID_HANDLE_VALUE ) + throw os_error_t( "set_stdhandle_t::set_stdhandle_t: GetStdHandle() failed" ); + if( !SetStdHandle( kind, handle ) ) + throw os_error_t( "set_stdhandle_t::set_stdhandle_t: SetStdHandle() failed" ); +} + +set_stdhandle_t::~set_stdhandle_t() +{ + SetStdHandle( m_kind, m_save_handle ); +} + +//wait_result_t +wait_result_t::wait_result_t() +{ + m_signaled_object=INVALID_HANDLE_VALUE; + m_timed_out=false; + m_error_code=ERROR_SUCCESS; + m_error_message=""; +} + +wait_result_t::wait_result_t( DWORD wait_result, int objects_count, HANDLE const * objects ) +{ + m_signaled_object=INVALID_HANDLE_VALUE; + m_timed_out=false; + m_error_code=ERROR_SUCCESS; + m_error_message=""; + if( wait_result>=WAIT_OBJECT_0 && wait_result=WAIT_ABANDONED_0 && wait_result( param ); + // accessing p anywhere here is safe because thread_buffer_t destructor + // ensures the thread is terminated before p get destroyed + char * read_buffer=0; + try { + read_buffer=new char[p->m_read_buffer_size]; + + while( true ) { + // see if get() wants more data, or if someone wants to stop the thread + wait_result_t wait_result=wait( p->m_stop_thread, p->m_want_data, p->m_wait_timeout ); + if( !wait_result.ok() && !wait_result.timed_out() ) { + p->note_thread_error( "thread_buffer_t::reader_thread: wait for want_data, destruction failed", wait_result.error_code(), wait_result.error_message() ); + break; + } + + if( wait_result.is_signaled( p->m_stop_thread ) ) { + // they want us to stop + break; + } + + if( wait_result.is_signaled( p->m_want_data ) ) { + // they want more data - read the file + DWORD read_size=0; + DWORD read_status=ERROR_SUCCESS; + if( !ReadFile( p->m_pipe, read_buffer, p->m_read_buffer_size, &read_size, 0 ) ) { + read_status=GetLastError(); + if( read_status!=ERROR_BROKEN_PIPE ) { + p->note_thread_error( "thread_buffer_t::reader_thread: ReadFile failed", read_status, "" ); + break; + } + } + + // read something - append to p->m_buffers + if( read_size!=0 ) { + grab_mutex_t grab_mutex( p->m_mutex, p->m_wait_timeout ); + if( !grab_mutex.ok() ) { + p->note_thread_error( "thread_buffer_t::reader_thread: wait for mutex failed", grab_mutex.error_code(), grab_mutex.error_message() ); + break; + } + + p->m_buffer_list.put( read_buffer, read_size ); + + // if buffer is too long - do not read any more until it shrinks + if( p->m_buffer_list.full( p->m_buffer_limit ) ) { + if( !p->m_want_data.reset() ) { + p->note_thread_error( "thread_buffer_t::reader_thread: unable to reset m_want_data event", GetLastError(), "" ); + break; + } + } + // tell get() we got some data + if( !p->m_got_data.set() ) { + p->note_thread_error( "thread_buffer_t::reader_thread: unable to set m_got_data event", GetLastError(), "" ); + break; + } + } + // pipe broken - quit thread, which will be seen by get() as eof. + if( read_status==ERROR_BROKEN_PIPE ) { + break; + } + } + } + }catch( ... ) { + // might only be std::bad_alloc + p->note_thread_error( "", ERROR_SUCCESS, "thread_buffer_t::reader_thread: unknown exception caught" ); + } + + delete[] read_buffer; + + // ensure that get() is not left waiting on got_data + p->m_got_data.set(); + return 0; +} + +void thread_buffer_t::put( char * const src, std::size_t & size, bool & no_more ) +{ + if( m_direction!=dir_write ) { + throw exec_stream_t::error_t( "thread_buffer_t::put: thread not started or started for reading" ); + } + // check thread status + DWORD thread_exit_code; + if( !GetExitCodeThread( m_thread, &thread_exit_code ) ) { + throw os_error_t( "thread_buffer_t::get: GetExitCodeThread failed" ); + } + + if( thread_exit_code!=STILL_ACTIVE ) { + // thread terminated - check for errors + check_error( m_message_prefix, m_error_code, m_error_message ); + // if terminated without error - signal eof, since no one will ever write our data + size=0; + no_more=true; + }else { + // wait for both m_want_data and m_mutex + wait_result_t wait_result=wait( m_want_data, m_wait_timeout ); + if( !wait_result.ok() ) { + check_error( "thread_buffer_t::put: wait for want_data failed", wait_result.error_code(), wait_result.error_message() ); + } + grab_mutex_t grab_mutex( m_mutex, m_wait_timeout ); + if( !grab_mutex.ok() ) { + check_error( "thread_buffer_t::put: wait for mutex failed", grab_mutex.error_code(), grab_mutex.error_message() ); + } + + // got them - put data + no_more=false; + if( m_translate_crlf ) { + m_buffer_list.put_translate_crlf( src, size ); + }else { + m_buffer_list.put( src, size ); + } + + // if the buffer is too long - make the next put() wait until it shrinks + if( m_buffer_list.full( m_buffer_limit ) ) { + if( !m_want_data.reset() ) { + throw os_error_t( "thread_buffer_t::put: unable to reset m_want_data event" ); + } + } + // tell the thread we got data + if( !m_buffer_list.empty() ) { + if( !m_got_data.set() ) { + throw os_error_t( "thread_buffer_t::put: unable to set m_got_data event" ); + } + } + } +} + +DWORD WINAPI thread_buffer_t::writer_thread( LPVOID param ) +{ + thread_buffer_t * p=static_cast< thread_buffer_t * >( param ); + // accessing p anywhere here is safe because thread_buffer_t destructor + // ensures the thread is terminated before p get destroyed + try { + buffer_list_t::buffer_t buffer; + buffer.data=0; + buffer.size=0; + std::size_t buffer_offset=0; + + while( true ) { + // wait for got_data or destruction, ignore timeout errors + // for destruction the timeout is normally expected, + // for got data the timeout is not normally expected but tolerable (no one wants to write) + wait_result_t wait_result=wait( p->m_got_data, p->m_stop_thread, p->m_wait_timeout ); + + if( !wait_result.ok() && !wait_result.timed_out() ) { + p->note_thread_error( "thread_buffer_t::writer_thread: wait for got_data, destruction failed", wait_result.error_code(), wait_result.error_message() ); + break; + } + + // if no data in local buffer to write - get from p->m_buffers + if( buffer.data==0 && wait_result.is_signaled( p->m_got_data ) ) { + grab_mutex_t grab_mutex( p->m_mutex, p->m_wait_timeout ); + if( !grab_mutex.ok() ) { + p->note_thread_error( "thread_buffer_t::writer_thread: wait for mutex failed", grab_mutex.error_code(), grab_mutex.error_message() ); + break; + } + if( !p->m_buffer_list.empty() ) { + // we've got buffer - detach it + buffer=p->m_buffer_list.detach(); + buffer_offset=0; + } + // if no data left in p->m_buffers - wait until it arrives + if( p->m_buffer_list.empty() ) { + if( !p->m_got_data.reset() ) { + p->note_thread_error( "thread_buffer_t::writer_thread: unable to reset m_got_data event", GetLastError(), "" ); + break; + } + } + // if buffer is not too long - tell put() it can proceed + if( !p->m_buffer_list.full( p->m_buffer_limit ) ) { + if( !p->m_want_data.set() ) { + p->note_thread_error( "thread_buffer_t::writer_thread: unable to set m_want_data event", GetLastError(), "" ); + break; + } + } + } + + // see if they want us to stop, but only when all is written + if( buffer.data==0 && wait_result.is_signaled( p->m_stop_thread ) ) { + break; + } + + if( buffer.data!=0 ) { + // we have buffer - write it + DWORD written_size; + if( !WriteFile( p->m_pipe, buffer.data+buffer_offset, buffer.size-buffer_offset, &written_size, 0 ) ) { + p->note_thread_error( "thread_buffer_t::writer_thread: WriteFile failed", GetLastError(), "" ); + break; + } + buffer_offset+=written_size; + if( buffer_offset==buffer.size ) { + delete[] buffer.data; + buffer.data=0; + } + } + + } + + // we won't be writing any more - close child's stdin + CloseHandle( p->m_pipe ); + + // buffer may be left astray - clean up + delete[] buffer.data; + + }catch( ... ) { + // unreachable code. really. + p->note_thread_error( "", ERROR_SUCCESS, "thread_buffer_t::writer_thread: unknown exception caught" ); + } + // ensure that put() is not left waiting on m_want_data + p->m_want_data.set(); + return 0; +} + +void thread_buffer_t::check_error( std::string const & message_prefix, DWORD error_code, std::string const & error_message ) +{ + if( !error_message.empty() ) { + throw exec_stream_t::error_t( message_prefix+"\n"+error_message, error_code ); + }else if( error_code!=ERROR_SUCCESS ) { + throw os_error_t( message_prefix, error_code ); + } +} + +void thread_buffer_t::note_thread_error( char const * message_prefix, DWORD error_code, char const * error_message ) +{ + m_message_prefix=message_prefix; + m_error_code=error_code; + m_error_message=error_message; +} + diff --git a/libwebthree/libexecstream/win/exec-stream-helpers.h b/libwebthree/libexecstream/win/exec-stream-helpers.h new file mode 100644 index 0000000000..9f17b8b0d5 --- /dev/null +++ b/libwebthree/libexecstream/win/exec-stream-helpers.h @@ -0,0 +1,183 @@ +/* +Copyright (C) 2004 Artem Khodush + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +3. The name of the author may not be used to endorse or promote products +derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +class os_error_t : public exec_stream_t::error_t { +public: + os_error_t( std::string const & msg ); + os_error_t( std::string const & msg, exec_stream_t::error_code_t code ); +private: + void compose( std::string const & msg, exec_stream_t::error_code_t code ); +}; + + +class pipe_t { +public: + pipe_t(); + ~pipe_t(); + HANDLE r() const; + HANDLE w() const; + void close_r(); + void close_w(); + void close(); + void open(); +private: + enum direction_t{ closed, read, write, both }; + direction_t m_direction; + HANDLE m_r; + HANDLE m_w; +}; + + +class set_stdhandle_t { +public: + set_stdhandle_t( DWORD kind, HANDLE handle ); + ~set_stdhandle_t(); +private: + DWORD m_kind; + HANDLE m_save_handle; +}; + + +class wait_result_t { +public: + wait_result_t(); + wait_result_t( DWORD wait_result, int objects_count, HANDLE const * objects ); + + bool ok(); + bool is_signaled( class event_t & event ); + bool timed_out(); + DWORD error_code(); + char const * error_message(); + +private: + + HANDLE m_signaled_object; + bool m_timed_out; + DWORD m_error_code; + char const * m_error_message; +}; + + +class event_t { +public: + event_t(); + ~event_t(); + bool set(); + bool reset(); + +private: + HANDLE m_handle; + + friend wait_result_t wait( event_t & e, DWORD timeout ); + friend wait_result_t wait( event_t & e1, event_t & e2, DWORD timeout ); + friend class wait_result_t; +}; + +wait_result_t wait( HANDLE e, DWORD timeout ); +wait_result_t wait( event_t & e, DWORD timeout ); +wait_result_t wait( event_t & e1, event_t & e2, DWORD timeout ); // waits for any one of e1, e2 + +class mutex_t { +public: + mutex_t(); + ~mutex_t(); + +private: + HANDLE m_handle; + friend class grab_mutex_t; +}; + +class grab_mutex_t { +public: + grab_mutex_t( mutex_t & mutex, DWORD timeout ); + ~grab_mutex_t(); + + bool ok(); + DWORD error_code(); + char const * error_message(); + +private: + HANDLE m_mutex; + wait_result_t m_wait_result; +}; + + +class thread_buffer_t { +public: + thread_buffer_t(); + ~thread_buffer_t(); + + // those three may be called only before the thread is started + void set_wait_timeout( DWORD milliseconds ); + void set_thread_termination_timeout( DWORD milliseconds ); + void set_buffer_limit( std::size_t limit ); + void set_read_buffer_size( std::size_t size ); + void set_binary_mode(); + void set_text_mode(); + + void start_reader_thread( HANDLE pipe ); + void start_writer_thread( HANDLE pipe); + + void get( exec_stream_t::stream_kind_t kind, char * dst, std::size_t & size, bool & no_more ); // may be called only after start_reader_thread + void put( char * const src, std::size_t & size, bool & no_more );// may be called only after start_writer_thread + + bool stop_thread(); + bool abort_thread(); + +private: + enum direction_t { dir_none, dir_read, dir_write }; + direction_t m_direction; // set by start_thread + + buffer_list_t m_buffer_list; + mutex_t m_mutex; // protecting m_buffer_list + + char const * m_message_prefix; // error occured in the thread, if any + DWORD m_error_code; // they are examined only after the thread has terminated + char const * m_error_message; // so setting them anywhere in the thread is safe + + DWORD m_wait_timeout; // parameters used in thread + std::size_t m_buffer_limit; // they are set before the thread is started, + std::size_t m_read_buffer_size; // so accessing them anywhere in the thread is safe + + HANDLE m_thread; + event_t m_want_data; // for synchronisation between get and reader_thread + event_t m_got_data; // or between put and writer_thread + event_t m_stop_thread; + HANDLE m_pipe; + DWORD m_thread_termination_timeout; + bool m_translate_crlf; + + void start_thread( HANDLE pipe, direction_t direction ); + static DWORD WINAPI reader_thread( LPVOID param ); + static DWORD WINAPI writer_thread( LPVOID param ); + + void check_error( std::string const & message_prefix, DWORD error_code, std::string const & error_message ); + void note_thread_error( char const * message_prefix, DWORD error_code, char const * error_message ); + bool check_thread_stopped(); +}; + diff --git a/libwebthree/libexecstream/win/exec-stream-impl.cpp b/libwebthree/libexecstream/win/exec-stream-impl.cpp new file mode 100644 index 0000000000..02cf429511 --- /dev/null +++ b/libwebthree/libexecstream/win/exec-stream-impl.cpp @@ -0,0 +1,316 @@ +/* +Copyright (C) 2004 Artem Khodush + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +3. The name of the author may not be used to endorse or promote products +derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +using namespace helpers; + +// exec_stream_t::impl_t +struct exec_stream_t::impl_t { + impl_t(); + + HANDLE m_child_process; + + HANDLE m_in_pipe; + HANDLE m_out_pipe; + HANDLE m_err_pipe; + + thread_buffer_t m_in_thread; + thread_buffer_t m_out_thread; + thread_buffer_t m_err_thread; + + exec_stream_buffer_t m_in_buffer; + exec_stream_buffer_t m_out_buffer; + exec_stream_buffer_t m_err_buffer; + + exec_ostream_t m_in; + exec_istream_t m_out; + exec_istream_t m_err; + + DWORD m_child_timeout; + int m_exit_code; +}; + +exec_stream_t::impl_t::impl_t() +: m_in_buffer( exec_stream_t::s_in, m_in_thread ), m_out_buffer( exec_stream_t::s_out, m_out_thread ), m_err_buffer( exec_stream_t::s_err, m_err_thread ), + m_in( m_in_buffer ), m_out( m_out_buffer ), m_err( m_err_buffer ) +{ + m_out.tie( &m_in ); + m_err.tie( &m_in ); + m_child_process=0; + m_in_pipe=0; + m_out_pipe=0; + m_err_pipe=0; + m_child_timeout=500; + m_exit_code=0; +} + + +void exec_stream_t::set_buffer_limit( int stream_kind, std::size_t size ) +{ + if( stream_kind&s_in ) { + m_impl->m_in_thread.set_buffer_limit( size ); + } + if( stream_kind&s_out ) { + m_impl->m_out_thread.set_buffer_limit( size ); + } + if( stream_kind&s_err ) { + m_impl->m_err_thread.set_buffer_limit( size ); + } +} + +void exec_stream_t::set_wait_timeout( int stream_kind, exec_stream_t::timeout_t milliseconds ) +{ + if( stream_kind&s_in ) { + m_impl->m_in_thread.set_wait_timeout( milliseconds ); + } + if( stream_kind&s_out ) { + m_impl->m_out_thread.set_wait_timeout( milliseconds ); + } + if( stream_kind&s_err ) { + m_impl->m_err_thread.set_wait_timeout( milliseconds ); + } + if( stream_kind&s_child ) { + m_impl->m_child_timeout=milliseconds; + m_impl->m_in_thread.set_thread_termination_timeout( milliseconds ); + m_impl->m_out_thread.set_thread_termination_timeout( milliseconds ); + m_impl->m_err_thread.set_thread_termination_timeout( milliseconds ); + } +} + +void exec_stream_t::set_binary_mode( int stream_kind ) +{ + if( stream_kind&s_in ) { + m_impl->m_in_thread.set_binary_mode(); + } + if( stream_kind&s_out ) { + m_impl->m_out_thread.set_binary_mode(); + } + if( stream_kind&s_err ) { + m_impl->m_err_thread.set_binary_mode(); + } +} + +void exec_stream_t::set_text_mode( int stream_kind ) +{ + if( stream_kind&s_in ) { + m_impl->m_in_thread.set_text_mode(); + } + if( stream_kind&s_out ) { + m_impl->m_out_thread.set_text_mode(); + } + if( stream_kind&s_err ) { + m_impl->m_err_thread.set_text_mode(); + } +} + +void exec_stream_t::start( std::string const & program, std::string const & arguments ) +{ + if( !close() ) { + throw exec_stream_t::error_t( "exec_stream_t::start: previous child process has not yet terminated" ); + } + + pipe_t in; + pipe_t out; + pipe_t err; + set_stdhandle_t set_in( STD_INPUT_HANDLE, in.r() ); + set_stdhandle_t set_out( STD_OUTPUT_HANDLE, out.w() ); + set_stdhandle_t set_err( STD_ERROR_HANDLE, err.w() ); + HANDLE cp=GetCurrentProcess(); + if( !DuplicateHandle( cp, in.w(), cp, &m_impl->m_in_pipe, 0, FALSE, DUPLICATE_SAME_ACCESS ) ) { + throw os_error_t( "exec_stream_t::start: unable to duplicate in handle" ); + } + in.close_w(); + if( !DuplicateHandle( cp, out.r(), cp, &m_impl->m_out_pipe, 0, FALSE, DUPLICATE_SAME_ACCESS ) ) { + throw os_error_t( "exec_stream_t::start: unable to duplicate out handle" ); + } + out.close_r(); + if( !DuplicateHandle( cp, err.r(), cp, &m_impl->m_err_pipe, 0, FALSE, DUPLICATE_SAME_ACCESS ) ) { + throw os_error_t( "exec_stream_t::start: unable to duplicate err handle" ); + } + err.close_r(); + + std::string command; + command.reserve( program.size()+arguments.size()+3 ); + if( program.find_first_of( " \t" )!=std::string::npos ) { + command+='"'; + command+=program; + command+='"'; + }else + command=program; + if( arguments.size()!=0 ) { + command+=' '; + command+=arguments; + } + STARTUPINFO si; + ZeroMemory( &si, sizeof( si ) ); + si.cb=sizeof( si ); + PROCESS_INFORMATION pi; + ZeroMemory( &pi, sizeof( pi ) ); + if( !CreateProcess( 0, const_cast< char * >( command.c_str() ), 0, 0, TRUE, 0, 0, 0, &si, &pi ) ) { + throw os_error_t( "exec_stream_t::start: CreateProcess failed.\n command line was: "+command ); + } + + m_impl->m_child_process=pi.hProcess; + + m_impl->m_in_buffer.clear(); + m_impl->m_out_buffer.clear(); + m_impl->m_err_buffer.clear(); + + m_impl->m_in.clear(); + m_impl->m_out.clear(); + m_impl->m_err.clear(); + + m_impl->m_out_thread.set_read_buffer_size( STREAM_BUFFER_SIZE ); + m_impl->m_out_thread.start_reader_thread( m_impl->m_out_pipe ); + + m_impl->m_err_thread.set_read_buffer_size( STREAM_BUFFER_SIZE ); + m_impl->m_err_thread.start_reader_thread( m_impl->m_err_pipe ); + + m_impl->m_in_thread.start_writer_thread( m_impl->m_in_pipe ); +} + +void exec_stream_t::start( std::string const & program, exec_stream_t::next_arg_t & next_arg ) +{ + std::string arguments; + while( std::string const * arg=next_arg.next() ) { + if( arg->find_first_of( " \t\"" )!=std::string::npos ) { + arguments+=" \""; + std::string::size_type cur=0; + while( cursize() ) { + std::string::size_type next=arg->find( '"', cur ); + if( next==std::string::npos ) { + next=arg->size(); + arguments.append( *arg, cur, next-cur ); + cur=next; + }else { + arguments.append( *arg, cur, next-cur ); + arguments+="\\\""; + cur=next+1; + } + } + arguments+="\""; + }else { + arguments+=" "+*arg; + } + } + start( program, arguments ); +} + +bool exec_stream_t::close_in() +{ + if( m_impl->m_in_pipe!=0 ) { + m_impl->m_in.flush(); + // stop writer thread before closing the handle it writes to, + // the thread will attempt to write anything it can and close child's stdin + // before thread_termination_timeout elapses + if( m_impl->m_in_thread.stop_thread() ) { + m_impl->m_in_pipe=0; + return true; + }else { + return false; + } + }else { + return true; + } +} + +bool exec_stream_t::close() +{ + if( !close_in() ) { + // need to close child's stdin no matter what, because otherwise "usual" child will run forever + // And before closing child's stdin the writer thread should be stopped no matter what, + // because it may be blocked on Write to m_in_pipe, and in that case closing m_in_pipe may block. + if( !m_impl->m_in_thread.abort_thread() ) { + throw exec_stream_t::error_t( "exec_stream_t::close: waiting till in_thread stops exceeded timeout" ); + } + // when thread is terminated abnormally, it may left child's stdin open + // try to close it here + CloseHandle( m_impl->m_in_pipe ); + m_impl->m_in_pipe=0; + } + if( !m_impl->m_out_thread.stop_thread() ) { + if( !m_impl->m_out_thread.abort_thread() ) { + throw exec_stream_t::error_t( "exec_stream_t::close: waiting till out_thread stops exceeded timeout" ); + } + } + if( !m_impl->m_err_thread.stop_thread() ) { + if( !m_impl->m_err_thread.abort_thread() ) { + throw exec_stream_t::error_t( "exec_stream_t::close: waiting till err_thread stops exceeded timeout" ); + } + } + if( m_impl->m_out_pipe!=0 ) { + if( !CloseHandle( m_impl->m_out_pipe ) ) { + throw os_error_t( "exec_stream_t::close: unable to close out_pipe handle" ); + } + m_impl->m_out_pipe=0; + } + if( m_impl->m_err_pipe!=0 ) { + if( !CloseHandle( m_impl->m_err_pipe ) ) { + throw os_error_t( "exec_stream_t::close: unable to close err_pipe handle" ); + } + m_impl->m_err_pipe=0; + } + if( m_impl->m_child_process!=0 ) { + wait_result_t wait_result=wait( m_impl->m_child_process, m_impl->m_child_timeout ); + if( !wait_result.ok() & !wait_result.timed_out() ) { + throw os_error_t( std::string( "exec_stream_t::close: wait for child process failed. " )+wait_result.error_message() ); + } + if( wait_result.ok() ) { + DWORD exit_code; + if( !GetExitCodeProcess( m_impl->m_child_process, &exit_code ) ) { + throw os_error_t( "exec_stream_t::close: unable to get process exit code" ); + } + m_impl->m_exit_code=exit_code; + if( !CloseHandle( m_impl->m_child_process ) ) { + throw os_error_t( "exec_stream_t::close: unable to close child process handle" ); + } + m_impl->m_child_process=0; + } + } + return m_impl->m_child_process==0; +} + +void exec_stream_t::kill() +{ + if( m_impl->m_child_process!=0 ) { + if( !TerminateProcess( m_impl->m_child_process, 0 ) ) { + throw os_error_t( "exec_stream_t::kill: unable to terminate child process" ); + } + m_impl->m_exit_code=0; + if( !CloseHandle( m_impl->m_child_process ) ) { + throw os_error_t( "exec_stream_t::close: unable to close child process handle" ); + } + m_impl->m_child_process=0; + } +} + +int exec_stream_t::exit_code() +{ + if( m_impl->m_child_process!=0 ) { + throw exec_stream_t::error_t( "exec_stream_t:exit_code: child process still running" ); + } + return m_impl->m_exit_code; +} diff --git a/libwhisper/BloomFilter.h b/libwhisper/BloomFilter.h new file mode 100644 index 0000000000..439020cc38 --- /dev/null +++ b/libwhisper/BloomFilter.h @@ -0,0 +1,143 @@ +/* +This file is part of cpp-ethereum. + +cpp-ethereum is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +cpp-ethereum 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with cpp-ethereum. If not, see . +*/ +/** @file BloomFilter.h +* @author Vladislav Gluhovsky +* @date June 2015 +*/ + +#pragma once + +#include "Common.h" + +namespace dev +{ +namespace shh +{ + +template +class TopicBloomFilterBase: public FixedHash +{ +public: + TopicBloomFilterBase() { init(); } + TopicBloomFilterBase(FixedHash const& _h): FixedHash(_h) { init(); } + + void addBloom(AbridgedTopic const& _h) { addRaw(bloom(_h)); } + void removeBloom(AbridgedTopic const& _h) { removeRaw(bloom(_h)); } + bool containsBloom(AbridgedTopic const& _h) const { return this->contains(bloom(_h)); } + + void addRaw(FixedHash const& _h); + void removeRaw(FixedHash const& _h); + bool containsRaw(FixedHash const& _h) const { return this->contains(_h); } + + static FixedHash bloom(AbridgedTopic const& _h); + static void setBit(FixedHash& _h, unsigned index); + static bool isBitSet(FixedHash const& _h, unsigned _index); + +private: + void init() { for (unsigned i = 0; i < CounterSize; ++i) m_refCounter[i] = 0; } + + static const unsigned CounterSize = N * 8; + std::array m_refCounter; +}; + +static unsigned const c_powerOfTwoBitMmask[8] = { 1, 2, 4, 8, 16, 32, 64, 128 }; + +template +void TopicBloomFilterBase::addRaw(FixedHash const& _h) +{ + *this |= _h; + for (unsigned i = 0; i < CounterSize; ++i) + if (isBitSet(_h, i)) + { + if (m_refCounter[i] != std::numeric_limits::max()) + m_refCounter[i]++; + else + BOOST_THROW_EXCEPTION(Overflow()); + } +} + +template +void TopicBloomFilterBase::removeRaw(FixedHash const& _h) +{ + for (unsigned i = 0; i < CounterSize; ++i) + if (isBitSet(_h, i)) + { + if (m_refCounter[i]) + m_refCounter[i]--; + + if (!m_refCounter[i]) + (*this)[i / 8] &= ~c_powerOfTwoBitMmask[i % 8]; + } +} + +template +bool TopicBloomFilterBase::isBitSet(FixedHash const& _h, unsigned _index) +{ + unsigned iByte = _index / 8; + unsigned iBit = _index % 8; + return (_h[iByte] & c_powerOfTwoBitMmask[iBit]) != 0; +} + +template +void TopicBloomFilterBase::setBit(FixedHash& _h, unsigned _index) +{ + unsigned iByte = _index / 8; + unsigned iBit = _index % 8; + _h[iByte] |= c_powerOfTwoBitMmask[iBit]; +} + +template +FixedHash TopicBloomFilterBase::bloom(AbridgedTopic const& _h) +{ + // The size of AbridgedTopic is 32 bits, and 27 of them participate in this algorithm. + + // We need to review the algorithm if any of the following constants will be changed. + static_assert(4 == AbridgedTopic::size, "wrong template parameter in TopicBloomFilterBase::bloom()"); + static_assert(3 == BitsPerBloom, "wrong template parameter in TopicBloomFilterBase::bloom()"); + + FixedHash ret; + + if (TopicBloomFilterSize == N) + for (unsigned i = 0; i < BitsPerBloom; ++i) + { + unsigned x = _h[i]; + if (_h[BitsPerBloom] & c_powerOfTwoBitMmask[i]) + x += 256; + + setBit(ret, x); + } + else + for (unsigned i = 0; i < BitsPerBloom; ++i) + { + unsigned x = unsigned(_h[i]) + unsigned(_h[i + 1]); + x %= N * 8; + setBit(ret, x); + } + + return ret; +} + +using TopicBloomFilter = TopicBloomFilterBase; + +} +} + + + + + + diff --git a/libwhisper/CMakeLists.txt b/libwhisper/CMakeLists.txt new file mode 100644 index 0000000000..f58427129b --- /dev/null +++ b/libwhisper/CMakeLists.txt @@ -0,0 +1,34 @@ +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") + +aux_source_directory(. SRC_LIST) + +file(GLOB HEADERS "*.h") + +add_library(whisper ${SRC_LIST} ${HEADERS}) + +find_package(Boost QUIET REQUIRED COMPONENTS regex) +find_package(Dev) + +target_include_directories(whisper PRIVATE ..) +target_include_directories(whisper PRIVATE ../utils) + +include_directories(../libodbc/include + ../libodbc/include/db2_linux + ../libodbc/include/ibase + ../libodbc/include/infomix + ../libodbc/include/mysql + ../libodbc/include/odbc_linux + ../libodbc/include/pgsql + ../libodbc/include/sqlbase + ../libodbc/include/sqllite + ../libodbc/include/ss_linux + ../libodbc/include/sybase) + + + +target_link_libraries(whisper ${Boost_REGEX_LIBRARIES}) +target_link_libraries(whisper ${Dev_DEVCORE_LIBRARIES}) +target_link_libraries(whisper ${Dev_DEVCRYPTO_LIBRARIES}) +target_link_libraries(whisper ${Dev_P2P_LIBRARIES}) + +install(TARGETS whisper RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib) diff --git a/libwhisper/Common.cpp b/libwhisper/Common.cpp new file mode 100644 index 0000000000..4258b93106 --- /dev/null +++ b/libwhisper/Common.cpp @@ -0,0 +1,122 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Common.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "Common.h" +#include +#include "Message.h" +#include "BloomFilter.h" + +using namespace std; +using namespace dev; +using namespace dev::p2p; +using namespace dev::shh; + +AbridgedTopic dev::shh::abridge(Topic const& _p) +{ + return AbridgedTopic(sha3(_p)); +} + +AbridgedTopics dev::shh::abridge(Topics const& _topics) +{ + AbridgedTopics ret; + ret.reserve(_topics.size()); + for (auto const& t: _topics) + ret.push_back(abridge(t)); + return ret; +} + +AbridgedTopics BuildTopic::toAbridgedTopics() const +{ + AbridgedTopics ret; + ret.reserve(m_parts.size()); + for (auto const& h: m_parts) + ret.push_back(abridge(h)); + return ret; +} + +BuildTopic& BuildTopic::shiftBytes(bytes const& _b) +{ + m_parts.push_back(dev::sha3(_b)); + return *this; +} + +h256 TopicFilter::sha3() const +{ + RLPStream s; + streamRLP(s); + return dev::sha3(s.out()); +} + +bool TopicFilter::matches(Envelope const& _e) const +{ + for (TopicMask const& t: m_topicMasks) + { + for (unsigned i = 0; i < t.size(); ++i) + { + for (auto et: _e.topic()) + if (((t[i].first ^ et) & t[i].second) == AbridgedTopic()) + goto NEXT_TOPICPART; + // failed to match topicmask against any topics: move on to next mask + goto NEXT_TOPICMASK; + NEXT_TOPICPART:; + } + // all topicmasks matched. + return true; + NEXT_TOPICMASK:; + } + return false; +} + +TopicFilter::TopicFilter(RLP const& _r) +{ + for (RLP const& i: _r) + { + m_topicMasks.push_back(TopicMask()); + for (RLP const& j: i) + m_topicMasks.back().push_back(j.toPair, FixedHash<4>>()); + } +} + +TopicBloomFilterHash TopicFilter::exportBloom() const +{ + TopicBloomFilterHash ret; + for (TopicMask const& t: m_topicMasks) + for (auto const& i: t) + ret |= TopicBloomFilter::bloom(i.first); + + return ret; +} + +TopicMask BuildTopicMask::toTopicMask() const +{ + TopicMask ret; + ret.reserve(m_parts.size()); + for (auto const& h: m_parts) + ret.push_back(make_pair(abridge(h), ~AbridgedTopic())); + return ret; +} + +/* +web3.shh.watch({}).arrived(function(m) { env.note("New message:\n"+JSON.stringify(m)); }) +k = web3.shh.newIdentity() +web3.shh.post({from: k, topic: web3.fromAscii("test"), payload: web3.fromAscii("Hello world!")}) +*/ + diff --git a/libwhisper/Common.h b/libwhisper/Common.h new file mode 100644 index 0000000000..6636ee897e --- /dev/null +++ b/libwhisper/Common.h @@ -0,0 +1,137 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Common.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include + +#include +#include +#include +#include + +namespace dev +{ +namespace shh +{ + +/* this makes these symbols ambiguous on VS2013 +using h256 = dev::h256; +using h256s = dev::h256s; +using bytes = dev::bytes; +using RLPStream = dev::RLPStream; +using RLP = dev::RLP; +using bytesRef = dev::bytesRef; +using bytesConstRef = dev::bytesConstRef; +using h256Set = dev::h256Set; +*/ + +class WhisperHost; +class WhisperPeer; +class Whisper; +class Envelope; + +enum WhisperPacket +{ + StatusPacket = 0, + MessagesPacket, + TopicFilterPacket, + PacketCount +}; + +static const unsigned TopicBloomFilterSize = 64; +static const unsigned BitsPerBloom = 3; +static const unsigned WhisperProtocolVersion = 3; + +using AbridgedTopic = FixedHash<4>; +using Topic = h256; + +using AbridgedTopics = std::vector; +using Topics = h256s; + +using TopicBloomFilterHash = FixedHash; + +AbridgedTopic abridge(Topic const& _topic); +AbridgedTopics abridge(Topics const& _topics); + +class BuildTopic +{ +public: + BuildTopic() {} + template BuildTopic(T const& _t) { shift(_t); } + + template BuildTopic& shift(T const& _r) { return shiftBytes(RLPStream().append(_r).out()); } + template BuildTopic& operator()(T const& _t) { return shift(_t); } + + BuildTopic& shiftRaw(h256 const& _part) { m_parts.push_back(_part); return *this; } + + operator AbridgedTopics() const { return toAbridgedTopics(); } + operator Topics() const { return toTopics(); } + AbridgedTopics toAbridgedTopics() const; + Topics toTopics() const { return m_parts; } + +protected: + BuildTopic& shiftBytes(bytes const& _b); + + h256s m_parts; +}; + +using TopicMask = std::vector>; // where pair::first is the actual abridged topic hash, pair::second is a constant (probably redundunt) +using TopicMasks = std::vector; + +class TopicFilter +{ +public: + TopicFilter() {} + TopicFilter(Topics const& _m) { m_topicMasks.push_back(TopicMask()); for (auto const& h: _m) m_topicMasks.back().push_back(std::make_pair(abridge(h), h ? ~AbridgedTopic() : AbridgedTopic())); } + TopicFilter(TopicMask const& _m): m_topicMasks(1, _m) {} + TopicFilter(TopicMasks const& _m): m_topicMasks(_m) {} + TopicFilter(RLP const& _r); + + void streamRLP(RLPStream& _s) const { _s << m_topicMasks; } + h256 sha3() const; + bool matches(Envelope const& _m) const; + TopicBloomFilterHash exportBloom() const; + +private: + TopicMasks m_topicMasks; +}; + +class BuildTopicMask: BuildTopic +{ +public: + BuildTopicMask() {} + template BuildTopicMask(T const& _t) { shift(_t); } + + template BuildTopicMask& shift(T const& _r) { BuildTopic::shift(_r); return *this; } + BuildTopicMask& shiftRaw(h256 const& _h) { BuildTopic::shiftRaw(_h); return *this; } + + template BuildTopicMask& operator()(T const& _t) { shift(_t); return *this; } + + operator TopicMask() const { return toTopicMask(); } + operator Topics() const { return toTopics(); } + TopicMask toTopicMask() const; + Topics toTopics() const { return m_parts; } +}; + +} +} diff --git a/libwhisper/Interface.cpp b/libwhisper/Interface.cpp new file mode 100644 index 0000000000..076a109645 --- /dev/null +++ b/libwhisper/Interface.cpp @@ -0,0 +1,34 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Interface.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "Interface.h" + +#include +#include +#include "WhisperHost.h" +using namespace std; +using namespace dev; +using namespace dev::p2p; +using namespace dev::shh; + +Interface::~Interface() +{ +} diff --git a/libwhisper/Interface.h b/libwhisper/Interface.h new file mode 100644 index 0000000000..736f93f8eb --- /dev/null +++ b/libwhisper/Interface.h @@ -0,0 +1,126 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Interface.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include +#include +#include +#include + +#include +#include +#include +#include "Common.h" +#include "Message.h" + +namespace dev +{ +namespace shh +{ + +class Watch; + +struct InstalledFilter +{ + InstalledFilter(Topics const& _t): full(_t), filter(_t) {} + + Topics full; + TopicFilter filter; + unsigned refCount = 1; +}; + +struct ClientWatch +{ + ClientWatch() {} + explicit ClientWatch(h256 _id): id(_id) {} + + h256 id; + h256s changes; +}; + +class Interface +{ +public: + virtual ~Interface(); + + virtual void inject(Envelope const& _m, WhisperPeer* _from = nullptr) = 0; + + virtual Topics const& fullTopics(unsigned _id) const = 0; + virtual unsigned installWatch(Topics const& _filter) = 0; + virtual void uninstallWatch(unsigned _watchId) = 0; + virtual h256s peekWatch(unsigned _watchId) const = 0; + virtual h256s checkWatch(unsigned _watchId) = 0; + virtual h256s watchMessages(unsigned _watchId) = 0; + + virtual Envelope envelope(h256 _m) const = 0; + + void post(bytes const& _payload, Topics _topics, unsigned _ttl = 50, unsigned _workToProve = 50) { inject(Message(_payload).seal(_topics, _ttl, _workToProve)); } + void post(Public _to, bytes const& _payload, Topics _topics, unsigned _ttl = 50, unsigned _workToProve = 50) { inject(Message(_payload).sealTo(_to, _topics, _ttl, _workToProve)); } + void post(Secret const& _from, bytes const& _payload, Topics _topics, unsigned _ttl = 50, unsigned _workToProve = 50) { inject(Message(_payload).seal(_from, _topics, _ttl, _workToProve)); } + void post(Secret const& _from, Public _to, bytes const& _payload, Topics _topics, unsigned _ttl = 50, unsigned _workToProve = 50) { inject(Message(_payload).sealTo(_from, _to, _topics, _ttl, _workToProve)); } +}; + +struct WatshhChannel: public dev::LogChannel { static const char* name() { return "shh"; } static const int verbosity = 1; }; +#define cwatshh dev::LogOutputStream() + +} +} + +namespace std { void swap(dev::shh::Watch& _a, dev::shh::Watch& _b); } + +namespace dev +{ +namespace shh +{ + +class Watch: public boost::noncopyable +{ + friend void std::swap(Watch& _a, Watch& _b); + +public: + Watch() {} + Watch(Interface& _c, Topics const& _t): m_c(&_c), m_id(_c.installWatch(_t)) {} + ~Watch() { if (m_c) m_c->uninstallWatch(m_id); } + + h256s check() { return m_c ? m_c->checkWatch(m_id) : h256s(); } + h256s peek() { return m_c ? m_c->peekWatch(m_id) : h256s(); } + +private: + Interface* m_c; + unsigned m_id; +}; + +} +} + +namespace std +{ + +inline void swap(dev::shh::Watch& _a, dev::shh::Watch& _b) +{ + swap(_a.m_c, _b.m_c); + swap(_a.m_id, _b.m_id); +} + +} + diff --git a/libwhisper/Message.cpp b/libwhisper/Message.cpp new file mode 100644 index 0000000000..7f79424287 --- /dev/null +++ b/libwhisper/Message.cpp @@ -0,0 +1,191 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Message.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "Message.h" +#include "BloomFilter.h" + +using namespace std; +using namespace dev; +using namespace dev::p2p; +using namespace dev::shh; + +Message::Message(Envelope const& _e, Topics const& _t, Secret const& _s) +{ + try + { + bytes b; + if (_s) + if (!decrypt(_s, &(_e.data()), b)) + return; + else{} + else if (!openBroadcastEnvelope(_e, _t, b)) + return; + + if (populate(b)) + if (_s) + m_to = KeyPair(_s).pub(); + } + catch (...) // Invalid secret? TODO: replace ... with InvalidSecret + { + } +} + +bool Message::openBroadcastEnvelope(Envelope const& _e, Topics const& _fk, bytes& o_b) +{ + // retrieve the key using the known topic and topicIndex. + unsigned topicIndex = 0; + Secret topicSecret; + + // determine topicSecret/topicIndex from knowledge of the collapsed topics (which give the order) and our full-size filter topic. + AbridgedTopics knownTopic = abridge(_fk); + for (unsigned ti = 0; ti < _fk.size() && !topicSecret; ++ti) + for (unsigned i = 0; i < _e.topic().size(); ++i) + if (_e.topic()[i] == knownTopic[ti]) + { + topicSecret = Secret(_fk[ti]); + topicIndex = i; + break; + } + + if (_e.data().size() < _e.topic().size() * h256::size) + return false; + + unsigned index = topicIndex * 2; + Secret encryptedKey(bytesConstRef(&(_e.data())).cropped(h256::size * index, h256::size)); + h256 salt = h256(bytesConstRef(&(_e.data())).cropped(h256::size * ++index, h256::size)); + Secret key = Secret(generateGamma(topicSecret, salt).makeInsecure() ^ encryptedKey.makeInsecure()); + bytesConstRef cipherText = bytesConstRef(&(_e.data())).cropped(h256::size * 2 * _e.topic().size()); + return decryptSym(key, cipherText, o_b); +} + +bool Message::populate(bytes const& _data) +{ + if (!_data.size()) + return false; + + byte flags = _data[0]; + if (!!(flags & ContainsSignature) && _data.size() >= sizeof(Signature) + 1) // has a signature + { + bytesConstRef payload = bytesConstRef(&_data).cropped(1, _data.size() - sizeof(Signature) - 1); + h256 h = sha3(payload); + Signature const& sig = *(Signature const*)&(_data[1 + payload.size()]); + m_from = recover(sig, h); + if (!m_from) + return false; + m_payload = payload.toBytes(); + } + else + m_payload = bytesConstRef(&_data).cropped(1).toBytes(); + return true; +} + +Envelope Message::seal(Secret const& _from, Topics const& _fullTopics, unsigned _ttl, unsigned _workToProve) const +{ + AbridgedTopics topics = abridge(_fullTopics); + Envelope ret(utcTime() + _ttl, _ttl, topics); + + bytes input(1 + m_payload.size()); + input[0] = 0; + memcpy(input.data() + 1, m_payload.data(), m_payload.size()); + + if (_from) // needs a signature + { + input.resize(1 + m_payload.size() + sizeof(Signature)); + input[0] |= ContainsSignature; + *(Signature*)&(input[1 + m_payload.size()]) = sign(_from, sha3(m_payload)); + // If this fails, the something is wrong with the sign-recover round-trip. + assert(recover(*(Signature*)&(input[1 + m_payload.size()]), sha3(m_payload)) == KeyPair(_from).pub()); + } + + if (m_to) + encrypt(m_to, &input, ret.m_data); + else + { + // this message is for broadcast (could be read by anyone who knows at least one of the topics) + // create the shared secret for encrypting the payload, then encrypt the shared secret with each topic + Secret s = Secret::random(); + for (h256 const& t: _fullTopics) + { + h256 salt = h256::random(); + ret.m_data += (generateGamma(Secret(t), salt).makeInsecure() ^ s.makeInsecure()).ref().toBytes(); + ret.m_data += salt.asBytes(); + } + + bytes d; + encryptSym(s, &input, d); + ret.m_data += d; + } + + ret.proveWork(_workToProve); + return ret; +} + +Envelope::Envelope(RLP const& _m) +{ + m_expiry = _m[0].toInt(); + m_ttl = _m[1].toInt(); + m_topic = _m[2].toVector>(); + m_data = _m[3].toBytes(); + m_nonce = _m[4].toInt(); +} + +Message Envelope::open(Topics const& _t, Secret const& _s) const +{ + return Message(*this, _t, _s); +} + +unsigned Envelope::workProved() const +{ + h256 d[2]; + d[0] = sha3(WithoutNonce); + d[1] = m_nonce; + return dev::sha3(bytesConstRef(d[0].data(), 64)).firstBitSet(); +} + +void Envelope::proveWork(unsigned _ms) +{ + h256 d[2]; + d[0] = sha3(WithoutNonce); + unsigned bestBitSet = 0; + bytesConstRef chuck(d[0].data(), 64); + + chrono::high_resolution_clock::time_point then = chrono::high_resolution_clock::now() + chrono::milliseconds(_ms); + while (chrono::high_resolution_clock::now() < then) + // do it rounds of 1024 for efficiency + for (unsigned i = 0; i < 1024; ++i, ++d[1]) + { + auto fbs = dev::sha3(chuck).firstBitSet(); + if (fbs > bestBitSet) + { + bestBitSet = fbs; + m_nonce = (h256::Arith)d[1]; + } + } +} + +bool Envelope::matchesBloomFilter(TopicBloomFilterHash const& f) const +{ + for (AbridgedTopic t: m_topic) + if (f.contains(TopicBloomFilter::bloom(t))) + return true; + + return false; +} diff --git a/libwhisper/Message.h b/libwhisper/Message.h new file mode 100644 index 0000000000..2ab555a3ba --- /dev/null +++ b/libwhisper/Message.h @@ -0,0 +1,138 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Message.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include "Common.h" + +namespace dev +{ +namespace shh +{ + +class Message; + +static const unsigned Undefined = (unsigned)-1; + +struct FilterKey +{ + FilterKey() {} + FilterKey(unsigned _tI, Secret const& _k): topicIndex(_tI), key(_k) {} + unsigned topicIndex = Undefined; + Secret key; +}; + +enum IncludeNonce +{ + WithoutNonce = 0, + WithNonce = 1 +}; + +class Envelope +{ + friend class Message; + +public: + Envelope() {} + Envelope(RLP const& _m); + + void streamRLP(RLPStream& _s, IncludeNonce _withNonce = WithNonce) const { _s.appendList(_withNonce ? 5 : 4) << m_expiry << m_ttl << m_topic << m_data; if (_withNonce) _s << m_nonce; } + h256 sha3(IncludeNonce _withNonce = WithNonce) const { RLPStream s; streamRLP(s, _withNonce); return dev::sha3(s.out()); } + Message open(Topics const& _t, Secret const& _s = Secret()) const; + unsigned workProved() const; + void proveWork(unsigned _ms); + + unsigned sent() const { return m_expiry - m_ttl; } + unsigned expiry() const { return m_expiry; } + unsigned ttl() const { return m_ttl; } + AbridgedTopics const& topic() const { return m_topic; } + bytes const& data() const { return m_data; } + + bool matchesBloomFilter(TopicBloomFilterHash const& f) const; + bool isExpired() const { return m_expiry <= utcTime(); } + +private: + Envelope(unsigned _exp, unsigned _ttl, AbridgedTopics const& _topic): m_expiry(_exp), m_ttl(_ttl), m_topic(_topic) {} + + unsigned m_expiry = 0; + unsigned m_ttl = 0; + u256 m_nonce; + + AbridgedTopics m_topic; + bytes m_data; +}; + +enum /*Message Flags*/ +{ + ContainsSignature = 1 +}; + +/// An (unencrypted) message, constructed from the combination of an Envelope, and, potentially, +/// a Secret key to decrypt the Message. +class Message +{ +public: + Message() {} + Message(Envelope const& _e, Topics const& _t, Secret const& _s = Secret()); + Message(bytes const& _payload): m_payload(_payload) {} + Message(bytesConstRef _payload): m_payload(_payload.toBytes()) {} + Message(bytes&& _payload) { std::swap(_payload, m_payload); } + + Public from() const { return m_from; } + Public to() const { return m_to; } + bytes const& payload() const { return m_payload; } + + void setFrom(Public _from) { m_from = _from; } + void setTo(Public _to) { m_to = _to; } + void setPayload(bytes const& _payload) { m_payload = _payload; } + void setPayload(bytes&& _payload) { swap(m_payload, _payload); } + + operator bool() const { return !!m_payload.size() || m_from || m_to; } + + /// Turn this message into a ditributable Envelope. + Envelope seal(Secret const& _from, Topics const& _topics, unsigned _ttl = 50, unsigned _workToProve = 50) const; + // Overloads for skipping _from or specifying _to. + Envelope seal(Topics const& _topics, unsigned _ttl = 50, unsigned _workToProve = 50) const { return seal(Secret(), _topics, _ttl, _workToProve); } + Envelope sealTo(Public _to, Topics const& _topics, unsigned _ttl = 50, unsigned _workToProve = 50) { m_to = _to; return seal(Secret(), _topics, _ttl, _workToProve); } + Envelope sealTo(Secret const& _from, Public _to, Topics const& _topics, unsigned _ttl = 50, unsigned _workToProve = 50) { m_to = _to; return seal(_from, _topics, _ttl, _workToProve); } + +private: + bool populate(bytes const& _data); + bool openBroadcastEnvelope(Envelope const& _e, Topics const& _t, bytes& o_b); + Secret generateGamma(Secret const& _key, h256 const& _salt) const { return sha3(_key ^ _salt); } + + Public m_from; + Public m_to; + bytes m_payload; +}; + +} +} diff --git a/libwhisper/WhisperDB.cpp b/libwhisper/WhisperDB.cpp new file mode 100644 index 0000000000..0945e7354a --- /dev/null +++ b/libwhisper/WhisperDB.cpp @@ -0,0 +1,159 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file WhisperDB.cpp +* @author Vladislav Gluhovsky +* @date July 2015 + */ + +#include "WhisperDB.h" +#include +#include +#include "WhisperHost.h" + +using namespace std; +using namespace dev; +using namespace dev::shh; +namespace fs = boost::filesystem; + +WhisperDB::WhisperDB(string const& _type) +{ + m_readOptions.verify_checksums = true; + string path = dev::getDataDir("shh"); + fs::create_directories(path); + DEV_IGNORE_EXCEPTIONS(fs::permissions(path, fs::owner_all)); + path += "/" + _type; + leveldb::Options op; + op.create_if_missing = true; + op.max_open_files = 256; + leveldb::DB* p = nullptr; + leveldb::Status status = leveldb::DB::Open(op, path, &p); + m_db.reset(p); + if (!status.ok()) + BOOST_THROW_EXCEPTION(FailedToOpenLevelDB(status.ToString())); +} + +string WhisperDB::lookup(dev::h256 const& _key) const +{ + string ret; + leveldb::Slice slice((char const*)_key.data(), _key.size); + leveldb::Status status = m_db->Get(m_readOptions, slice, &ret); + if (!status.ok() && !status.IsNotFound()) + BOOST_THROW_EXCEPTION(FailedLookupInLevelDB(status.ToString())); + + return ret; +} + +void WhisperDB::insert(dev::h256 const& _key, string const& _value) +{ + leveldb::Slice slice((char const*)_key.data(), _key.size); + leveldb::Status status = m_db->Put(m_writeOptions, slice, _value); + if (!status.ok()) + BOOST_THROW_EXCEPTION(FailedInsertInLevelDB(status.ToString())); +} + +void WhisperDB::insert(dev::h256 const& _key, bytes const& _value) +{ + leveldb::Slice k((char const*)_key.data(), _key.size); + leveldb::Slice v((char const*)_value.data(), _value.size()); + leveldb::Status status = m_db->Put(m_writeOptions, k, v); + if (!status.ok()) + BOOST_THROW_EXCEPTION(FailedInsertInLevelDB(status.ToString())); +} + +void WhisperDB::kill(dev::h256 const& _key) +{ + leveldb::Slice slice((char const*)_key.data(), _key.size); + leveldb::Status status = m_db->Delete(m_writeOptions, slice); + if (!status.ok()) + BOOST_THROW_EXCEPTION(FailedDeleteInLevelDB(status.ToString())); +} + +void WhisperMessagesDB::loadAllMessages(std::map& o_dst) +{ + leveldb::ReadOptions op; + op.fill_cache = false; + op.verify_checksums = true; + vector wasted; + unique_ptr it(m_db->NewIterator(op)); + unsigned const now = utcTime(); + + for (it->SeekToFirst(); it->Valid(); it->Next()) + { + leveldb::Slice const k = it->key(); + leveldb::Slice const v = it->value(); + bool useless = true; + + try + { + RLP rlp((byte const*)v.data(), v.size()); + Envelope e(rlp); + h256 h2 = e.sha3(); + h256 h1; + + if (k.size() == h256::size) + h1 = h256((byte const*)k.data(), h256::ConstructFromPointer); + + if (h1 != h2) + LOG(WARNING) << "Corrupted data in Level DB:" << h1.hex() << "versus" << h2.hex(); + else if (e.expiry() > now) + { + o_dst[h1] = e; + useless = false; + } + } + catch(RLPException const& ex) + { + LOG(WARNING) << "RLPException in WhisperDB::loadAll():" << ex.what(); + } + catch(Exception const& ex) + { + LOG(WARNING) << "Exception in WhisperDB::loadAll():" << ex.what(); + } + + if (useless) + wasted.push_back(k.ToString()); + } + + LOG(DEBUG) << "WhisperDB::loadAll(): loaded " << o_dst.size() << ", deleted " << wasted.size() << "messages"; + + for (auto const& k: wasted) + { + leveldb::Status status = m_db->Delete(m_writeOptions, k); + if (!status.ok()) + LOG(WARNING) << "Failed to delete an entry from Level DB:" << k; + } +} + +void WhisperMessagesDB::saveSingleMessage(h256 const& _key, Envelope const& _e) +{ + try + { + RLPStream rlp; + _e.streamRLP(rlp); + bytes b; + rlp.swapOut(b); + insert(_key, b); + } + catch(RLPException const& ex) + { + LOG(WARNING) << boost::diagnostic_information(ex); + } + catch(FailedInsertInLevelDB const& ex) + { + LOG(WARNING) << boost::diagnostic_information(ex); + } +} diff --git a/libwhisper/WhisperDB.h b/libwhisper/WhisperDB.h new file mode 100644 index 0000000000..0327c87dda --- /dev/null +++ b/libwhisper/WhisperDB.h @@ -0,0 +1,75 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file WhisperDB.h +* @author Vladislav Gluhovsky +* @date July 2015 + */ + +#pragma once + +#include +#include +#include "Common.h" +#include "Message.h" + +namespace dev +{ +namespace shh +{ + +struct WrongTypeLevelDB: virtual Exception {}; +struct FailedToOpenLevelDB: virtual Exception { FailedToOpenLevelDB(std::string const& _message): Exception(_message) {} }; +struct FailedInsertInLevelDB: virtual Exception { FailedInsertInLevelDB(std::string const& _message): Exception(_message) {} }; +struct FailedLookupInLevelDB: virtual Exception { FailedLookupInLevelDB(std::string const& _message): Exception(_message) {} }; +struct FailedDeleteInLevelDB: virtual Exception { FailedDeleteInLevelDB(std::string const& _message): Exception(_message) {} }; + +class WhisperHost; + +class WhisperDB +{ +public: + WhisperDB(std::string const& _type); + virtual ~WhisperDB() {} + std::string lookup(dev::h256 const& _key) const; + void insert(dev::h256 const& _key, std::string const& _value); + void insert(dev::h256 const& _key, bytes const& _value); + void kill(dev::h256 const& _key); + +protected: + leveldb::ReadOptions m_readOptions; + leveldb::WriteOptions m_writeOptions; + std::unique_ptr m_db; +}; + +class WhisperMessagesDB: public WhisperDB +{ +public: + WhisperMessagesDB(): WhisperDB("messages") {} + virtual ~WhisperMessagesDB() {} + void loadAllMessages(std::map& o_dst); + void saveSingleMessage(dev::h256 const& _key, Envelope const& _e); +}; + +class WhisperFiltersDB: public WhisperDB +{ +public: + WhisperFiltersDB(): WhisperDB("filters") {} + virtual ~WhisperFiltersDB() {} +}; + +} +} \ No newline at end of file diff --git a/libwhisper/WhisperHost.cpp b/libwhisper/WhisperHost.cpp new file mode 100644 index 0000000000..b6a479ffc7 --- /dev/null +++ b/libwhisper/WhisperHost.cpp @@ -0,0 +1,289 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file WhisperHost.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "WhisperHost.h" +#include +#include +#include +#include "WhisperDB.h" + +using namespace std; +using namespace dev; +using namespace dev::p2p; +using namespace dev::shh; + +WhisperHost::WhisperHost(bool _storeMessagesInDB): Worker("shh"), m_storeMessagesInDB(_storeMessagesInDB) +{ + loadMessagesFromBD(); +} + +WhisperHost::~WhisperHost() +{ + saveMessagesToBD(); +} + +void WhisperHost::streamMessage(h256 _m, RLPStream& _s) const +{ + UpgradableGuard l(x_messages); + if (m_messages.count(_m)) + { + UpgradeGuard ll(l); + auto const& m = m_messages.at(_m); +// cnote << "streamRLP: " << m.expiry() << m.ttl() << m.topic() << toHex(m.data()); + m.streamRLP(_s); + } +} + +void WhisperHost::inject(Envelope const& _m, WhisperPeer* _p) +{ + // this function processes both outgoing messages originated both by local host (_p == null) + // and incoming messages from remote peers (_p != null) + + //cnote << this << ": inject: " << _m.expiry() << _m.ttl() << _m.topic() << toHex(_m.data()); + + if (_m.isExpired()) + return; + + auto h = _m.sha3(); + { + UpgradableGuard l(x_messages); + if (m_messages.count(h)) + return; + UpgradeGuard ll(l); + m_messages[h] = _m; + m_expiryQueue.insert(make_pair(_m.expiry(), h)); + } + + // rating of incoming message from remote host is assessed according to the following criteria: + // 1. installed watch match; 2. bloom filter match; 2. ttl; 3. proof of work + + int rating = 0; + + DEV_GUARDED(m_filterLock) + if (_m.matchesBloomFilter(m_bloom)) + { + ++rating; + for (auto const& f: m_filters) + if (f.second.filter.matches(_m)) + for (auto& i: m_watches) + if (i.second.id == f.first) // match one of the watches + { + i.second.changes.push_back(h); + rating += 2; + } + } + + if (_p) // incoming message from remote peer + { + rating *= 256; + unsigned ttlReward = (256 > _m.ttl() ? 256 - _m.ttl() : 0); + rating += ttlReward; + rating *= 256; + rating += _m.workProved(); + } + + // TODO p2p: capability-based rating + for (auto i: peerSessions()) + { + auto w = capabilityFromSession(*i.first).get(); + if (w == _p) + w->addRating(rating); + else + w->noteNewMessage(h, _m); + } +} + +unsigned WhisperHost::installWatch(shh::Topics const& _t) +{ + InstalledFilter f(_t); + h256 h = f.filter.sha3(); + unsigned ret = 0; + + DEV_GUARDED(m_filterLock) + { + auto it = m_filters.find(h); + if (m_filters.end() == it) + m_filters.insert(make_pair(h, f)); + else + it->second.refCount++; + + m_bloom.addRaw(f.filter.exportBloom()); + ret = m_watches.size() ? m_watches.rbegin()->first + 1 : 0; + m_watches[ret] = ClientWatch(h); + cwatshh << "+++" << ret << h; + } + + noteAdvertiseTopicsOfInterest(); + return ret; +} + +void WhisperHost::uninstallWatch(unsigned _i) +{ + cwatshh << "XXX" << _i; + + DEV_GUARDED(m_filterLock) + { + auto it = m_watches.find(_i); + if (it == m_watches.end()) + return; + + auto id = it->second.id; + m_watches.erase(it); + + auto fit = m_filters.find(id); + if (fit != m_filters.end()) + { + m_bloom.removeRaw(fit->second.filter.exportBloom()); + if (!--fit->second.refCount) + m_filters.erase(fit); + } + } + + noteAdvertiseTopicsOfInterest(); +} + +h256s WhisperHost::watchMessages(unsigned _watchId) +{ + h256s ret; + auto wit = m_watches.find(_watchId); + if (wit == m_watches.end()) + return ret; + TopicFilter f; + { + Guard l(m_filterLock); + auto fit = m_filters.find(wit->second.id); + if (fit == m_filters.end()) + return ret; + f = fit->second.filter; + } + ReadGuard l(x_messages); + for (auto const& m: m_messages) + if (f.matches(m.second)) + ret.push_back(m.first); + return ret; +} + +h256s WhisperHost::checkWatch(unsigned _watchId) +{ + h256s ret; + cleanup(); + + dev::Guard l(m_filterLock); + try + { + ret = m_watches.at(_watchId).changes; + m_watches.at(_watchId).changes.clear(); + } + catch (...) + { + } + + return ret; +} + +void WhisperHost::doWork() +{ + for (auto i: peerSessions()) + capabilityFromSession(*i.first)->sendMessages(); + cleanup(); +} + +void WhisperHost::cleanup() +{ + // remove old messages. + // should be called every now and again. + uint64_t now = utcTime(); + WriteGuard l(x_messages); + for (auto it = m_expiryQueue.begin(); it != m_expiryQueue.end() && it->first <= now; it = m_expiryQueue.erase(it)) + m_messages.erase(it->second); +} + +void WhisperHost::noteAdvertiseTopicsOfInterest() +{ + for (auto i: peerSessions()) + capabilityFromSession(*i.first)->noteAdvertiseTopicsOfInterest(); +} + +bool WhisperHost::isWatched(Envelope const& _e) const +{ + DEV_GUARDED(m_filterLock) + if (_e.matchesBloomFilter(m_bloom)) + for (auto const& f: m_filters) + if (f.second.filter.matches(_e)) + for (auto const& i: m_watches) + if (i.second.id == f.first) + return true; + return false; +} + +void WhisperHost::saveMessagesToBD() +{ + if (!m_storeMessagesInDB) + return; + + try + { + WhisperMessagesDB db; + ReadGuard g(x_messages); + uint64_t now = utcTime(); + for (auto const& m: m_messages) + if (m.second.expiry() > now) + if (isWatched(m.second)) + db.saveSingleMessage(m.first, m.second); + } + catch(FailedToOpenLevelDB const& ex) + { + LOG(WARNING) << "Exception in WhisperHost::saveMessagesToBD() - failed to open DB:" << ex.what(); + } + catch(Exception const& ex) + { + LOG(WARNING) << "Exception in WhisperHost::saveMessagesToBD():" << ex.what(); + } + catch(...) + { + LOG(WARNING) << "Unknown Exception in WhisperHost::saveMessagesToBD()"; + } +} + +void WhisperHost::loadMessagesFromBD() +{ + if (!m_storeMessagesInDB) + return; + + try + { + map m; + WhisperMessagesDB db; + db.loadAllMessages(m); + WriteGuard g(x_messages); + m_messages.swap(m); + for (auto const& msg: m) + m_expiryQueue.insert(make_pair(msg.second.expiry(), msg.first)); + } + catch(Exception const& ex) + { + LOG(WARNING) << "Exception in WhisperHost::loadMessagesFromBD():" << ex.what(); + } + catch(...) + { + LOG(WARNING) << "Unknown Exception in WhisperHost::loadMessagesFromBD()"; + } +} diff --git a/libwhisper/WhisperHost.h b/libwhisper/WhisperHost.h new file mode 100644 index 0000000000..4b6a57f599 --- /dev/null +++ b/libwhisper/WhisperHost.h @@ -0,0 +1,92 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file WhisperHost.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include "Common.h" +#include "WhisperPeer.h" +#include "Interface.h" +#include "BloomFilter.h" + +namespace dev +{ +namespace shh +{ + +static const Topics EmptyTopics; + +class WhisperHost: public HostCapability, public Interface, public Worker +{ + friend class WhisperPeer; + +public: + WhisperHost(bool _storeMessagesInDB = false); + virtual ~WhisperHost(); + unsigned protocolVersion() const { return WhisperProtocolVersion; } + void cleanup(); ///< remove old messages + std::map all() const { dev::ReadGuard l(x_messages); return m_messages; } + TopicBloomFilterHash bloom() const { dev::Guard l(m_filterLock); return m_bloom; } + + virtual void inject(Envelope const& _e, WhisperPeer* _from = nullptr) override; + virtual Topics const& fullTopics(unsigned _id) const override { try { return m_filters.at(m_watches.at(_id).id).full; } catch (...) { return EmptyTopics; } } + virtual unsigned installWatch(Topics const& _filter) override; + virtual void uninstallWatch(unsigned _watchId) override; + virtual h256s peekWatch(unsigned _watchId) const override { dev::Guard l(m_filterLock); try { return m_watches.at(_watchId).changes; } catch (...) { return h256s(); } } + virtual h256s checkWatch(unsigned _watchId) override; + virtual h256s watchMessages(unsigned _watchId) override; ///< returns IDs of messages, which match specific watch criteria + virtual Envelope envelope(h256 _m) const override { try { dev::ReadGuard l(x_messages); return m_messages.at(_m); } catch (...) { return Envelope(); } } + +protected: + virtual void doWork() override; + void noteAdvertiseTopicsOfInterest(); + bool isWatched(Envelope const& _e) const; + +private: + virtual void onStarting() override { startWorking(); } + virtual void onStopping() override { stopWorking(); } + void streamMessage(h256 _m, RLPStream& _s) const; + void saveMessagesToBD(); + void loadMessagesFromBD(); + + mutable dev::SharedMutex x_messages; + std::map m_messages; + std::multimap m_expiryQueue; + + mutable dev::Mutex m_filterLock; + std::map m_filters; + std::map m_watches; + TopicBloomFilter m_bloom; + + bool m_storeMessagesInDB; ///< needed for tests and other special cases +}; + +} +} diff --git a/libwhisper/WhisperPeer.cpp b/libwhisper/WhisperPeer.cpp new file mode 100644 index 0000000000..8af0d582aa --- /dev/null +++ b/libwhisper/WhisperPeer.cpp @@ -0,0 +1,153 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file WhisperPeer.cpp + * @author Gav Wood + * @date 2014 + */ + +#include +#include +#include "WhisperHost.h" + +using namespace std; +using namespace dev; +using namespace dev::p2p; +using namespace dev::shh; + +WhisperPeer::WhisperPeer(std::shared_ptr _s, HostCapabilityFace* _h, unsigned _i, CapDesc const&, uint16_t _capID): + Capability(_s, _h, _i, _capID) +{ + RLPStream s; + sealAndSend(prep(s, StatusPacket, 1) << version()); + noteAdvertiseTopicsOfInterest(); +} + +WhisperPeer::~WhisperPeer() +{ +} + +WhisperHost* WhisperPeer::host() const +{ + return static_cast(Capability::hostCapability()); +} + +bool WhisperPeer::interpret(unsigned _id, RLP const& _r) +{ + switch (_id) + { + case StatusPacket: + { + auto protocolVersion = _r[0].toInt(); + + clog(NetMessageSummary) << "Status: " << protocolVersion; + + if (protocolVersion != version()) + disable("Invalid protocol version."); + + for (auto const& m: host()->all()) + { + Guard l(x_unseen); + m_unseen.insert(make_pair(0, m.first)); + } + + if (session()->id() < host()->host()->id()) + sendMessages(); + + noteAdvertiseTopicsOfInterest(); + break; + } + case MessagesPacket: + { + for (auto i: _r) + host()->inject(Envelope(i), this); + break; + } + case TopicFilterPacket: + { + setBloom((TopicBloomFilterHash)_r[0]); + break; + } + default: + return false; + } + return true; +} + +void WhisperPeer::sendMessages() +{ + if (m_advertiseTopicsOfInterest) + sendTopicsOfInterest(host()->bloom()); + + multimap available; + DEV_GUARDED(x_unseen) + m_unseen.swap(available); + + RLPStream amalg; + + // send the highest rated messages first + for (auto i = available.rbegin(); i != available.rend(); ++i) + host()->streamMessage(i->second, amalg); + + unsigned msgCount = available.size(); + if (msgCount) + { + RLPStream s; + prep(s, MessagesPacket, msgCount).appendRaw(amalg.out(), msgCount); + sealAndSend(s); + } +} + +void WhisperPeer::noteNewMessage(h256 _h, Envelope const& _m) +{ + unsigned rate = ratingForPeer(_m); + Guard l(x_unseen); + m_unseen.insert(make_pair(rate, _h)); +} + +unsigned WhisperPeer::ratingForPeer(Envelope const& e) const +{ + // we try to estimate, how valuable this nessage will be for the remote peer, + // according to the following criteria: + // 1. bloom filter + // 2. time to live + // 3. proof of work + + unsigned rating = 0; + + if (e.matchesBloomFilter(bloom())) + ++rating; + + rating *= 256; + unsigned ttlReward = (256 > e.ttl() ? 256 - e.ttl() : 0); + rating += ttlReward; + + rating *= 256; + rating += e.workProved(); + return rating; +} + +void WhisperPeer::sendTopicsOfInterest(TopicBloomFilterHash const& _bloom) +{ + DEV_GUARDED(x_advertiseTopicsOfInterest) + m_advertiseTopicsOfInterest = false; + + RLPStream s; + prep(s, TopicFilterPacket, 1); + s << _bloom; + sealAndSend(s); +} + diff --git a/libwhisper/WhisperPeer.h b/libwhisper/WhisperPeer.h new file mode 100644 index 0000000000..0ea5e00860 --- /dev/null +++ b/libwhisper/WhisperPeer.h @@ -0,0 +1,81 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file WhisperPeer.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include +#include +#include +#include + +#include +#include +#include +#include "Common.h" +#include "Message.h" + +namespace dev +{ +namespace shh +{ + +using p2p::SessionFace; +using p2p::HostCapabilityFace; +using p2p::HostCapability; +using p2p::Capability; +using p2p::CapDesc; + +class WhisperPeer: public Capability +{ + friend class WhisperHost; + +public: + WhisperPeer(std::shared_ptr _s, HostCapabilityFace* _h, unsigned _i, CapDesc const& _cap, uint16_t _capID); + virtual ~WhisperPeer(); + WhisperHost* host() const; + static std::string name() { return "shh"; } + static u256 version() { return WhisperProtocolVersion; } + static unsigned messageCount() { return PacketCount; } + TopicBloomFilterHash bloom() const { dev::Guard g(x_bloom); return m_bloom; } + void sendTopicsOfInterest(TopicBloomFilterHash const& _bloom); ///< sends our bloom filter to remote peer + void noteAdvertiseTopicsOfInterest() { dev::Guard g(x_advertiseTopicsOfInterest); m_advertiseTopicsOfInterest = true; } + +private: + virtual bool interpret(unsigned _id, RLP const&) override; + void sendMessages(); + unsigned ratingForPeer(Envelope const& e) const; + void noteNewMessage(h256 _h, Envelope const& _m); + void setBloom(TopicBloomFilterHash const& _b) { dev::Guard g(x_bloom); m_bloom = _b; } + + mutable dev::Mutex x_unseen; + std::multimap m_unseen; ///< Rated according to what they want. + std::chrono::system_clock::time_point m_timer = std::chrono::system_clock::now(); + + mutable dev::Mutex x_bloom; + TopicBloomFilterHash m_bloom; ///< Peer's topics of interest + + mutable dev::Mutex x_advertiseTopicsOfInterest; + bool m_advertiseTopicsOfInterest; +}; + +} +} diff --git a/log.conf b/log.conf new file mode 100644 index 0000000000..5d53a424aa --- /dev/null +++ b/log.conf @@ -0,0 +1,29 @@ +* GLOBAL: + ENABLED = true + TO_FILE = true + TO_STANDARD_OUTPUT = false + FORMAT = "%level|%datetime{%Y-%M-%d %H:%m:%s}|%msg" + FILENAME = "log/log_%datetime{%Y%M%d%H}.log" + MILLISECONDS_WIDTH = 3 + PERFORMANCE_TRACKING = false + MAX_LOG_FILE_SIZE = 209715200 ## 200MB - Comment starts with two hashes (##) + LOG_FLUSH_THRESHOLD = 100 ## Flush after every 100 logs + +* TRACE: + FILENAME = "log/trace_log_%datetime{%Y%M%d%H}.log" +* DEBUG: + FILENAME = "log/debug_log_%datetime{%Y%M%d%H}.log" +* FATAL: + ENABLED = false + +* ERROR: + FILENAME = "log/error_log_%datetime{%Y%M%d%H}.log" + +* WARNING: + ENABLED = false + +* INFO: + ENABLED = false + +* VERBOSE: + ENABLED = false \ No newline at end of file diff --git a/refilltests b/refilltests new file mode 100644 index 0000000000..e69de29bb2 diff --git a/sanitizer-blacklist.txt b/sanitizer-blacklist.txt new file mode 100644 index 0000000000..5d48e8afb8 --- /dev/null +++ b/sanitizer-blacklist.txt @@ -0,0 +1,8 @@ +# Ignore standard library headers. +src:*/include/c\+\+/* + +# Ignore boost libraries headers. +src:*/include/boost/* + +# Ignore Crypto++ library. We plan to remove it in the future. It exploits interger overflow and uses memcpy incorrectly. +src:*/include/cryptopp/* diff --git a/scripts/build.sh b/scripts/build.sh new file mode 100644 index 0000000000..21a3554b2d --- /dev/null +++ b/scripts/build.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash + +#------------------------------------------------------------------------------ +# Bash script to build cpp-ethereum within TravisCI. +# +# The documentation for cpp-ethereum is hosted at http://cpp-ethereum.org +# +# ------------------------------------------------------------------------------ +# This file is part of cpp-ethereum. +# +# cpp-ethereum is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# cpp-ethereum 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cpp-ethereum. If not, see +# +# (c) 2016 cpp-ethereum contributors. +#------------------------------------------------------------------------------ + +set -e -x + +# There is an implicit assumption here that we HAVE to run from repo root + +mkdir -p build +cd build +if [ $(uname -s) == "Linux" ]; then + cmake .. -DCMAKE_BUILD_TYPE=$1 -DTESTS=$2 -DEVMJIT=On -DLLVM_DIR=/usr/lib/llvm-3.9/lib/cmake/llvm +else + cmake .. -DCMAKE_BUILD_TYPE=$1 -DTESTS=$2 +fi + +make -j2 diff --git a/scripts/duplicates.sh b/scripts/duplicates.sh new file mode 100644 index 0000000000..4fb668c643 --- /dev/null +++ b/scripts/duplicates.sh @@ -0,0 +1,92 @@ +#!/usr/bin/env python +# -*- coding: iso-8859-15 -*- + +#------------------------------------------------------------------------------ +# Python script to analysis cpp-ethereum commits, and filter out duplicates +# +# The documentation for cpp-ethereum is hosted at http://cpp-ethereum.org +# +# ------------------------------------------------------------------------------ +# This file is part of cpp-ethereum. +# +# cpp-ethereum is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# cpp-ethereum 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cpp-ethereum. If not, see +# +# (c) 2016 cpp-ethereum contributors. +#------------------------------------------------------------------------------ + +import operator +import re + +authorRegex = re.compile('Author: (.*) <(.*)>') +dateRegex = re.compile('Date: (.*)') + +authorAliases = {} +authorAliases['arkpar'] = 'Arkadiy Paronyan' +authorAliases['arkady.paronyan@gmail.com'] = 'Arkadiy Paronyan' +authorAliases['Arkady Paronyan'] = 'Arkadiy Paronyan' +authorAliases['artur-zawlocki'] = 'Artur Zawłocki' +authorAliases['Artur Zawlocki'] = 'Artur Zawłocki' +authorAliases['Artur Zawłocki'] = 'Artur Zawłocki' +authorAliases['caktux'] = 'Vincent Gariepy' +authorAliases['chriseth'] = 'Christian Reitwiessner' +authorAliases['Christian'] = 'Christian Reitwiessner' +authorAliases['CJentzsch'] = 'Christoph Jentzsch' +authorAliases['debris'] = 'Marek Kotewicz' +authorAliases['debris-berlin'] = 'Marek Kotewicz' +authorAliases['Dimitry'] = 'Dimitry Khokhlov' +authorAliases['Dmitry K'] = 'Dimitry Khokhlov' +authorAliases['ethdev'] = 'Marek Kotewicz' +authorAliases['gluk256'] = 'Vlad Gluhovsky' +authorAliases['Greg'] = 'Greg Colvin' +authorAliases['Marian OANCΞA'] = 'Marian Oancea' +authorAliases['ethdev zug'] = 'Marek Kotewicz' +authorAliases['Gav Wood'] = 'Gavin Wood' +authorAliases['U-SVZ13\Arkady'] = 'Arkadiy Paronyan' +authorAliases['liana'] = 'Liana Husikyan' +authorAliases['LianaHus'] = 'Liana Husikyan' +authorAliases['subtly'] = 'Alex Leverington' +authorAliases['unknown'] = 'Marek Kotewicz' +authorAliases['vbuterin'] = 'Vitalik Buterin' +authorAliases['winsvega'] = 'Dimitry Khokhlov' +authorAliases['yann300'] = 'Yann Levreau' + + +commitCounts = {} + +commitAlreadySeen = {} + +with open('log.txt') as logFile: + author = "" + for line in logFile: + match = authorRegex.match(line) + if match: + author = match.group(1) + if authorAliases.has_key(author): + author = authorAliases[author] + + match = dateRegex.match(line) + if match: + date = match.group(1) + if commitAlreadySeen.has_key(author + date): + print "Filtering out .... " + author + " - " + date + else: + commitAlreadySeen[author + date] = 1 + if not commitCounts.has_key(author): + commitCounts[author] = 1 + else: + commitCounts[author] = commitCounts[author] + 1 + + +for key in sorted(commitCounts, key=commitCounts.get): #sorted(commitCounts.items()): + print key + " has " + str(commitCounts[key]) + " commits" diff --git a/scripts/install_cmake.sh b/scripts/install_cmake.sh new file mode 100644 index 0000000000..dd7e3f470b --- /dev/null +++ b/scripts/install_cmake.sh @@ -0,0 +1,51 @@ +#!/usr/bin/env sh + +# This script downloads the CMake binary and installs it in $PREFIX directory +# (the cmake executable will be in $PREFIX/bin). By default $PREFIX is +# ~/.local but can we changes with --prefix argument. + +# This is mostly suitable for CIs, not end users. + +set -e + +VERSION=3.7.1 + +if [ "$1" = "--prefix" ]; then + PREFIX="$2" +else + PREFIX=~/.local +fi + +OS=$(uname -s) +case $OS in +Linux) SHA256=7b4b7a1d9f314f45722899c0521c261e4bfab4a6b532609e37fef391da6bade2;; +Darwin) SHA256=1851d1448964893fdc5a8c05863326119f397a3790e0c84c40b83499c7960267;; +esac + + +BIN=$PREFIX/bin + +if test -f $BIN/cmake && ($BIN/cmake --version | grep -q "$VERSION"); then + echo "CMake $VERSION already installed in $BIN" +else + FILE=cmake-$VERSION-$OS-x86_64.tar.gz + URL=https://cmake.org/files/v3.7/$FILE + ERROR=0 + TMPFILE=$(mktemp --tmpdir cmake-$VERSION-$OS-x86_64.XXXXXXXX.tar.gz) + echo "Downloading CMake ($URL)..." + curl -s "$URL" > "$TMPFILE" + + if type -p sha256sum > /dev/null; then + SHASUM="sha256sum" + else + SHASUM="shasum -a256" + fi + + if ! ($SHASUM "$TMPFILE" | grep -q "$SHA256"); then + echo "Checksum mismatch ($TMPFILE)" + exit 1 + fi + mkdir -p "$PREFIX" + tar xzf "$TMPFILE" -C "$PREFIX" --strip 1 + rm $TMPFILE +fi diff --git a/scripts/install_deps.sh b/scripts/install_deps.sh new file mode 100644 index 0000000000..670889c47e --- /dev/null +++ b/scripts/install_deps.sh @@ -0,0 +1,288 @@ +#!/usr/bin/env sh + +#------------------------------------------------------------------------------ +# Bash script for installing pre-requisite packages for cpp-ethereum on a +# variety of Linux and other UNIX-derived platforms. +# +# This is an "infrastucture-as-code" alternative to the manual build +# instructions pages which we previously maintained, first as Wiki pages +# and later as readthedocs pages at http://ethdocs.org. +# +# The aim of this script is to simplify things down to the following basic +# flow for all supported operating systems: +# +# - git clone --recursive +# - ./install_deps.sh +# - cmake && make +# +# At the time of writing we are assuming that 'lsb_release' is present for all +# Linux distros, which is not a valid assumption. We will need a variety of +# approaches to actually get this working across all the distros which people +# are using. +# +# See http://unix.stackexchange.com/questions/92199/how-can-i-reliably-get-the-operating-systems-name +# for some more background on this common problem. +# +# TODO - There is no support here yet for cross-builds in any form, only +# native builds. Expanding the functionality here to cover the mobile, +# wearable and SBC platforms covered by doublethink and EthEmbedded would +# also bring in support for Android, iOS, watchOS, tvOS, Tizen, Sailfish, +# Maemo, MeeGo and Yocto. +# +# The documentation for cpp-ethereum is hosted at http://cpp-ethereum.org +# +# ------------------------------------------------------------------------------ +# This file is part of cpp-ethereum. +# +# cpp-ethereum is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# cpp-ethereum 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cpp-ethereum. If not, see +# +# (c) 2016 cpp-ethereum contributors. +#------------------------------------------------------------------------------ + +set -e + +# Check for 'uname' and abort if it is not available. +uname -v > /dev/null 2>&1 || { echo >&2 "ERROR - cpp-ethereum requires 'uname' to identify the platform."; exit 1; } + +case $(uname -s) in + +#------------------------------------------------------------------------------ +# macOS +#------------------------------------------------------------------------------ + +Darwin) + case $(sw_vers -productVersion | awk -F . '{print $1"."$2}') in + 10.9) + echo "Installing cpp-ethereum dependencies on OS X 10.9 Mavericks." + ;; + 10.10) + echo "Installing cpp-ethereum dependencies on OS X 10.10 Yosemite." + ;; + 10.11) + echo "Installing cpp-ethereum dependencies on OS X 10.11 El Capitan." + ;; + 10.12) + echo "Installing cpp-ethereum dependencies on macOS 10.12 Sierra." + echo "" + echo "NOTE - You are in unknown territory with this preview OS." + echo "Even Homebrew doesn't have official support yet, and there are" + echo "known issues (see https://github.com/ethereum/webthree-umbrella/issues/614)." + echo "If you would like to partner with us to work through these issues, that" + echo "would be fantastic. Please just comment on that issue. Thanks!" + ;; + *) + echo "Unsupported macOS version." + echo "We only support Mavericks, Yosemite and El Capitan, with work-in-progress on Sierra." + exit 1 + ;; + esac + + # Check for Homebrew install and abort if it is not installed. + brew -v > /dev/null 2>&1 || { echo >&2 "ERROR - cpp-ethereum requires a Homebrew install. See http://brew.sh."; exit 1; } + + # And finally install all the external dependencies. + brew install \ + leveldb \ + libmicrohttpd \ + miniupnpc + + ;; + +#------------------------------------------------------------------------------ +# FreeBSD +#------------------------------------------------------------------------------ +FreeBSD) + echo "Installing cpp-ethereum dependencies on FreeBSD." + echo "ERROR - 'install_deps.sh' doesn't have FreeBSD support yet." + echo "Please let us know if you see this error message, and we can work out what is missing." + echo "At https://gitter.im/ethereum/cpp-ethereum-development." + exit 1 + ;; + +#------------------------------------------------------------------------------ +# Linux +#------------------------------------------------------------------------------ +Linux) + + # Detect if sudo is needed. + if [ $(id -u) != 0 ]; then + SUDO="sudo" + fi + +#------------------------------------------------------------------------------ +# Arch Linux +#------------------------------------------------------------------------------ + + if [ -f "/etc/arch-release" ]; then + + echo "Installing cpp-ethereum dependencies on Arch Linux." + + # The majority of our dependencies can be found in the + # Arch Linux official repositories. + # See https://wiki.archlinux.org/index.php/Official_repositories + $SUDO pacman -Sy --noconfirm \ + autoconf \ + automake \ + gcc \ + libtool \ + boost \ + leveldb \ + libmicrohttpd \ + miniupnpc + + elif [ -f "/etc/os-release" ]; then + + DISTRO_NAME=$(. /etc/os-release; echo $NAME) + case $DISTRO_NAME in + + Debian*) + echo "Installing cpp-ethereum dependencies on Debian Linux." + + $SUDO apt-get -q update + $SUDO apt-get -qy install \ + build-essential \ + libboost-all-dev \ + libcurl4-openssl-dev \ + libgmp-dev \ + libleveldb-dev \ + libmicrohttpd-dev \ + libminiupnpc-dev + ;; + + Fedora) + echo "Installing cpp-ethereum dependencies on Fedora Linux." + $SUDO dnf -qy install \ + gcc-c++ \ + boost-devel \ + leveldb-devel \ + curl-devel \ + libmicrohttpd-devel \ + gmp-devel + ;; + +#------------------------------------------------------------------------------ +# Ubuntu +# +# TODO - I wonder whether all of the Ubuntu-variants need some special +# treatment? +# +# TODO - We should also test this code on Ubuntu Server, Ubuntu Snappy Core +# and Ubuntu Phone. +# +# TODO - Our Ubuntu build is only working for amd64 and i386 processors. +# It would be good to add armel, armhf and arm64. +# See https://github.com/ethereum/webthree-umbrella/issues/228. +#------------------------------------------------------------------------------ + Ubuntu|LinuxMint) + echo "Installing cpp-ethereum dependencies on Ubuntu." + if [ "$TRAVIS" ]; then + # Setup prebuilt LLVM on Travis CI: + $SUDO apt-get -qy remove llvm # Remove confilicting package. + echo "deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-3.9 main" | \ + $SUDO tee -a /etc/apt/sources.list > /dev/null + LLVM_PACKAGES="llvm-3.9-dev libz-dev" + fi + $SUDO apt-get -q update + $SUDO apt-get install -qy --no-install-recommends --allow-unauthenticated \ + build-essential \ + libboost-all-dev \ + libcurl4-openssl-dev \ + libgmp-dev \ + libleveldb-dev \ + libmicrohttpd-dev \ + libminiupnpc-dev \ + $LLVM_PACKAGES + ;; + + CentOS*) + echo "Installing cpp-ethereum dependencies on CentOS." + # Enable EPEL repo that contains leveldb-devel + $SUDO yum -y -q install epel-release + $SUDO yum -y -q install \ + make \ + gcc-c++ \ + boost-devel \ + leveldb-devel \ + curl-devel \ + libmicrohttpd-devel \ + gmp-devel \ + openssl openssl-devel + ;; + + *) + echo "Unsupported Linux distribution: $DISTRO_NAME." + exit 1 + ;; + + esac + + elif [ -f "/etc/alpine-release" ]; then + + # Alpine Linux + echo "Installing cpp-ethereum dependencies on Alpine Linux." + $SUDO apk add --no-cache --repository http://dl-cdn.alpinelinux.org/alpine/edge/testing/ \ + g++ \ + make \ + boost-dev \ + curl-dev \ + libmicrohttpd-dev \ + leveldb-dev + + else + + case $(lsb_release -is) in + +#------------------------------------------------------------------------------ +# OpenSUSE +#------------------------------------------------------------------------------ + openSUSE*) + #openSUSE + echo "Installing cpp-ethereum dependencies on openSUSE." + echo "ERROR - 'install_deps.sh' doesn't have openSUSE support yet." + echo "See http://cpp-ethereum.org/building-from-source/linux.html for manual instructions." + echo "If you would like to get 'install_deps.sh' working for openSUSE, that would be fantastic." + echo "See https://github.com/ethereum/webthree-umbrella/issues/552." + exit 1 + ;; + +#------------------------------------------------------------------------------ +# Other (unknown) Linux +# Major and medium distros which we are missing would include Mint, CentOS, +# RHEL, Raspbian, Cygwin, OpenWrt, gNewSense, Trisquel and SteamOS. +#------------------------------------------------------------------------------ + *) + #other Linux + echo "ERROR - Unsupported or unidentified Linux distro." + echo "See http://cpp-ethereum.org/building-from-source/linux.html for manual instructions." + echo "If you would like to get your distro working, that would be fantastic." + echo "Drop us a message at https://gitter.im/ethereum/cpp-ethereum-development." + exit 1 + ;; + esac + fi + ;; + +#------------------------------------------------------------------------------ +# Other platform (not Linux, FreeBSD or macOS). +# Not sure what might end up here? +# Maybe OpenBSD, NetBSD, AIX, Solaris, HP-UX? +#------------------------------------------------------------------------------ +*) + #other + echo "ERROR - Unsupported or unidentified operating system." + echo "See http://cpp-ethereum.org/building-from-source/ for manual instructions." + echo "If you would like to get your operating system working, that would be fantastic." + echo "Drop us a message at https://gitter.im/ethereum/cpp-ethereum-development." + ;; +esac diff --git a/scripts/ppabuild.sh b/scripts/ppabuild.sh new file mode 100644 index 0000000000..89e3904ef4 --- /dev/null +++ b/scripts/ppabuild.sh @@ -0,0 +1,107 @@ +#!/bin/sh +############################################################################## +## This is used to package .deb packages and upload them to the launchpad +## ppa servers for building. It requires one argument (passed via env): +## +## ethbranch: the branch to use for webthree-umbrella, either develop or +## release +## debplatform: target ubuntu "release", i.e. trusty, vivid, wily or xenial +## (we should switch to numbered releases at some point) +## +## The "debian" directories can be found in github.com/ethereum/ethereum-ppa +## The develop branch will be used for anything before wily, while wily and +## xenial have their own branches. +## +## The gnupg key for "build@ethdev.com" has to be present in order to sign +## the package. +## +## Caveats: A package with the same version number should not be uploaded +## multiple times to the build servers. This is not a big problem for the +## develop snapshots as the version will change with every commit, but +## for release packages, the version will be taken from the CMakeLists.txt +## file. This means that this script should only be run once for every +## release. If the source package was uploaded before, add '-sd' to the +## debuild command (see below). +############################################################################## + +set -e + +distribution=${debplatform} +echo "building for ${debplatform}" +if [ -z "$distribution" ] + then distribution=trusty +fi +arch=amd64 +mainrepo=webthree-umbrella +now=$(date +"%Y%m%d") +project="cpp-ethereum" +ppabranch=develop +if [ "${distribution}" = "wily" ]; then + ppabranch=wily +elif [ "${distribution}" = "xenial" ]; then + ppabranch=xenial +fi +codebranch=${ethbranch} +pparepo=ethereum/ethereum +if [ -z "$codebranch" ] +then + codebranch=develop +fi +if [ "$codebranch" = "develop" ] +then + pparepo=ethereum/ethereum-dev +fi +echo codebranch=${codebranch} +echo pparepo=${pparepo} + +keyid=703F83D0 +email=builds@ethereum.org +mainppa="http://ppa.launchpad.net/ethereum/ethereum/ubuntu" +devppa="http://ppa.launchpad.net/ethereum/ethereum-dev/ubuntu" + +# clone source repo +git clone https://github.com/ethereum/${mainrepo}.git -b ${codebranch} --recursive + +# create source tarball" +cd ${mainrepo} +version=`grep -oP "$project VERSION \"?\K[0-9.]+(?=\")"? CMakeLists.txt` +version="${version}" +revision=`git rev-parse --short HEAD` + +if [ "${codebranch}" = "release" ]; then + debversion=${version}~${distribution} + else + debversion=${version}-SNAPSHOT-${BUILD_NUMBER}-${now}-${revision}~${distribution} +fi + +echo debversion=${debversion} + +tar --exclude .git -czf ../${project}_${debversion}.orig.tar.gz . + +# get debian/ direcotry +wget https://github.com/ethereum/ethereum-ppa/archive/${ppabranch}.tar.gz -O- | +tar -zx --exclude package.sh --exclude README.md --strip-components=1 + +# bump version +EMAIL="$email" dch -v ${debversion}-0ubuntu1 "git build of ${revision}" + +# build source package +# If packages is rejected because original source is already present, add +# -sd to remove it from the .changes file +debuild -S -sa -us -uc + +# set PPA dependencies for pbuilder +echo "OTHERMIRROR=\"deb [trusted=yes] ${mainppa} ${distribution} main|deb-src [trusted=yes] ${mainppa} ${distribution} main|deb [trusted=yes] ${devppa} ${distribution} main|deb-src [trusted=yes] ${devppa} ${distribution} main|deb [trusted=yes]\"" > ~/.pbuilderrc + +# do the build +#pdebuild --buildresult . --pbuilder /usr/sbin/cowbuilder --architecture amd64 -- --buildresult . --basepath /var/cache/pbuilder/${distribution}-${arch}-ethereum.cow + +# prepare .changes file for Launchpad +sed -i -e s/UNRELEASED/${distribution}/ -e s/urgency=medium/urgency=low/ ../*.changes + +# sign the package +debsign -k ${keyid} ../${project}_${debversion}-0ubuntu1_source.changes + +# uploa +dput ppa:${pparepo} ../${project}_${debversion}-0ubuntu1_source.changes + diff --git a/scripts/release.sh b/scripts/release.sh new file mode 100644 index 0000000000..caa7658cae --- /dev/null +++ b/scripts/release.sh @@ -0,0 +1,116 @@ +#!/usr/bin/env bash + +#------------------------------------------------------------------------------ +# Bash script implementing release flow for cpp-ethereum for Linux and macOS. +# +# TODO - At the time of writing, we only have ZIPs working. Need to hook up +# support for Homebrew and PPAs. +# +# The documentation for cpp-ethereum is hosted at http://cpp-ethereum.org +# +# ------------------------------------------------------------------------------ +# This file is part of cpp-ethereum. +# +# cpp-ethereum is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# cpp-ethereum 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cpp-ethereum. If not, see +# +# (c) 2016 cpp-ethereum contributors. +#------------------------------------------------------------------------------ + +set -e + +ZIP_SUFFIX=$1 +ZIP_TEMP_DIR=$(pwd)/zip/ +TESTS=$2 + +if [[ "$OSTYPE" == "darwin"* ]]; then + DLL_EXT=dylib +else + DLL_EXT=so +fi + +mkdir -p $ZIP_TEMP_DIR + +# Copy all the cpp-ethereum executables into a temporary directory prior to ZIP creation + +cp bench/bench $ZIP_TEMP_DIR +cp eth/eth $ZIP_TEMP_DIR +cp ethkey/ethkey $ZIP_TEMP_DIR +cp ethminer/ethminer $ZIP_TEMP_DIR +cp ethvm/ethvm $ZIP_TEMP_DIR +cp rlp/rlp $ZIP_TEMP_DIR +if [[ "$TESTS" == "On" ]]; then + cp test/testeth $ZIP_TEMP_DIR +fi + +# Copy all the dynamic libraries into a temporary directory prior to ZIP creation. +# There are a lot of these, and it would be great if we didn't have to worry about them. +# There is work-in-progress to support static-linkage on the UNIX platforms, which +# is most promising on Alpine Linux using musl. macOS doesn't support statically +# linked binaries (ie. executables which make direct system calls to the kernel. +# +# See https://developer.apple.com/library/mac/qa/qa1118/_index.html. +# See https://github.com/ethereum/webthree-umbrella/issues/495. + +cp libdevcore/*.$DLL_EXT $ZIP_TEMP_DIR +cp libdevcrypto/*.$DLL_EXT $ZIP_TEMP_DIR +cp libethash/*.$DLL_EXT $ZIP_TEMP_DIR +cp libethash-cl/*.$DLL_EXT $ZIP_TEMP_DIR +cp libethashseal/*.$DLL_EXT $ZIP_TEMP_DIR +cp libethcore/*.$DLL_EXT $ZIP_TEMP_DIR +cp libethereum/*.$DLL_EXT $ZIP_TEMP_DIR +cp libevm/*.$DLL_EXT $ZIP_TEMP_DIR +cp libevmcore/*.$DLL_EXT $ZIP_TEMP_DIR +cp libp2p/*.$DLL_EXT $ZIP_TEMP_DIR +cp libweb3jsonrpc/*.$DLL_EXT $ZIP_TEMP_DIR +cp libwebthree/*.$DLL_EXT $ZIP_TEMP_DIR +cp libwhisper/*.$DLL_EXT $ZIP_TEMP_DIR +cp utils/libscrypt/*.$DLL_EXT $ZIP_TEMP_DIR + +# For macOS, we also copy the dynamic libraries for our external dependencies. +# When building from source on your own machine, these libraries will be installed +# globally, using Homebrew, but we don't want to rely on that for these ZIPs, so +# we copy these into the ZIP temporary directory too. +# +# TODO - So what happens for Linux and other UNIX distros in this case? +# There will be runtime dependencies on equivalent SO files being present, likely in +# a completely analogous way. Does that mean that ZIPs are actually useless on such +# distros, because there will be symbol links to global install locations (distro-specific) +# and those files will just be missing on the target machines? + +if [[ "$OSTYPE" == "darwin"* ]]; then + cp /usr/local/opt/cryptopp/lib/libcryptopp.dylib $ZIP_TEMP_DIR + cp /usr/local/opt/gmp/lib/libgmp.10.dylib $ZIP_TEMP_DIR + cp /usr/local/opt/jsoncpp/lib/libjsoncpp.1.dylib $ZIP_TEMP_DIR + cp /usr/local/opt/leveldb/lib/libleveldb.1.dylib $ZIP_TEMP_DIR + cp /usr/local/opt/libjson-rpc-cpp/lib/libjsonrpccpp-common.0.dylib $ZIP_TEMP_DIR + cp /usr/local/opt/libjson-rpc-cpp/lib/libjsonrpccpp-client.0.dylib $ZIP_TEMP_DIR + cp /usr/local/opt/libjson-rpc-cpp/lib/libjsonrpccpp-server.0.dylib $ZIP_TEMP_DIR + cp /usr/local/opt/libmicrohttpd/lib/libmicrohttpd.12.dylib $ZIP_TEMP_DIR + cp /usr/local/opt/miniupnpc/lib/libminiupnpc.16.dylib $ZIP_TEMP_DIR + cp /usr/local/opt/snappy/lib/libsnappy.1.dylib $ZIP_TEMP_DIR +fi + +# For macOS, we run a fix-up script which alters all of the symbolic links within +# the executables and dynamic libraries such that the ZIP becomes self-contained, by +# revectoring all the dylib references to be relative to the directory containing the +# application, so that the ZIPs are self-contained, with the only external references +# being for kernel-level dylibs. + +if [[ "$OSTYPE" == "darwin"* ]]; then + python $(pwd)/../homebrew/fix_homebrew_paths_in_standalone_zip.py $ZIP_TEMP_DIR +fi + +# And ZIP it all up, with a filename suffix passed in on the command-line. + +zip -j $(pwd)/../cpp-ethereum-develop-$ZIP_SUFFIX.zip $ZIP_TEMP_DIR/* diff --git a/scripts/runalltests.sh b/scripts/runalltests.sh new file mode 100644 index 0000000000..621795dd39 --- /dev/null +++ b/scripts/runalltests.sh @@ -0,0 +1,46 @@ +#!/usr/bin/env bash + +workdir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +#Clean the previous build +cd $workdir +rm -r cpp-ethereum +rm -r tests +exec &> $workdir/testlog.txt + +#Clonning Repositories +echo "Cloning Repositories" +git clone https://github.com/ethereum/tests.git +git clone --recursive https://github.com/ethereum/cpp-ethereum.git +cd tests +testHead=$(git rev-parse HEAD) +cd .. +cd cpp-ethereum +cppHead=$(git rev-parse HEAD) + +#Prepare test results +mkdir build +cd build +echo "Make cpp-ethereum develop:" +cmake .. +make -j8 +cd test +echo "Running all tests:" +echo "cpp-ethereum HEAD "$cppHead +echo "tests HEAD "$testHead +exec 2> $workdir/testerror.txt +timestart=$(date +%s.%N) +./testeth --all --exectimelog +timeend=$(date +%s.%N) + +#Prepare Header of the report +exec &> $workdir/testreport.txt +exectime=$(echo "$timeend - $timestart" | bc) +echo "REPORT" +echo "Test execution time: $exectime s" +cat $workdir/testerror.txt +cat $workdir/testreport.txt | cat - $workdir/testlog.txt > temp && mv temp $workdir/testlog.txt + +#Send Mails +date=$(date +%Y-%m-%d) +mail -s "cpp-ethereum test results "$date dimitry@ethereum.org < $workdir/testlog.txt #-A $workdir/results.zip +mail -s "cpp-ethereum test results "$date chris@ethereum.org < $workdir/testlog.txt #-A $workdir/results.zip diff --git a/scripts/tests.sh b/scripts/tests.sh new file mode 100644 index 0000000000..4b384ac00a --- /dev/null +++ b/scripts/tests.sh @@ -0,0 +1,53 @@ +#!/usr/bin/env bash + +#------------------------------------------------------------------------------ +# Bash script to execute the cpp-ethereum tests. +# +# The documentation for cpp-ethereum is hosted at http://cpp-ethereum.org +# +# ------------------------------------------------------------------------------ +# This file is part of cpp-ethereum. +# +# cpp-ethereum is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# cpp-ethereum 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cpp-ethereum. If not, see +# +# (c) 2016 cpp-ethereum contributors. +#------------------------------------------------------------------------------ + +set -e + +TESTS=$1 + +# There is an implicit assumption here that we HAVE to run from build directory. +BUILD_ROOT=$(pwd) + +if [[ "$TESTS" == "On" ]]; then + + # Clone the end-to-end test repo, and point environment variable at it. + cd ../.. + git clone https://github.com/ethereum/tests.git + export ETHEREUM_TEST_PATH=$(pwd)/tests/ + + # Run the tests for the Interpreter + cd cpp-ethereum/build + $BUILD_ROOT/test/testeth + + # Run the tests for the JIT (but only for Ubuntu, not macOS) + # The whole automation process is too slow for macOS, and we don't have + # enough time to build LLVM, build EVMJIT and run the tests twice within + # the 48 minute absolute maximum run time for TravisCI. + if [[ "$OSTYPE" != "darwin"* ]]; then + $BUILD_ROOT/test/testeth -t "VMTests*,StateTests*" -- --vm jit + fi + +fi diff --git a/scripts/upload-homebrew-formula.sh b/scripts/upload-homebrew-formula.sh new file mode 100644 index 0000000000..ea0186568f --- /dev/null +++ b/scripts/upload-homebrew-formula.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +# author: Lefteris Karapetsas +# +# Just upload the generated .rb file to homebrew ethereum + +echo ">>> Starting the script to upload .rb file to homebrew ethereum" +rm -rf homebrew-ethereum +git clone git@github.com:ethereum/homebrew-ethereum.git +cp webthree-umbrella/build/cpp-ethereum.rb homebrew-ethereum +cd homebrew-ethereum +git add . -u +git commit -m "update cpp-ethereum.rb" +git push origin +cd .. +rm -rf homebrew-ethereum +echo ">>> Succesfully uploaded the .rb file to homebrew ethereum" diff --git a/start.sh b/start.sh new file mode 100644 index 0000000000..5a595030ed --- /dev/null +++ b/start.sh @@ -0,0 +1,3 @@ +#!/bin/sh +./build/eth/eth --genesis ./genesis.json --config ./config.json + diff --git a/systemcontractv2/.babelrc b/systemcontractv2/.babelrc new file mode 100644 index 0000000000..b594f2adf1 --- /dev/null +++ b/systemcontractv2/.babelrc @@ -0,0 +1 @@ +{ "presets": ["es2017"] } diff --git a/systemcontractv2/Authority.sol b/systemcontractv2/Authority.sol new file mode 100644 index 0000000000..a0eac6a4d3 --- /dev/null +++ b/systemcontractv2/Authority.sol @@ -0,0 +1,36 @@ +pragma solidity ^0.4.4; +import "TransactionFilterBase.sol"; +import "Group.sol"; + +contract Authority is TransactionFilterBase { + bool private _enabled = false; //是否启用权限控制 + mapping (address => address) private _groups; //用户对应的角色 + + //设置用户的角色 + function setUserGroup(address user, address group) public { + _groups[user] = group; + } + + //获取用户的角色 + function getUserGroup(address user) public constant returns(address) { + return _groups[user]; + } + + function enable() { + _enabled = true; + } + + //检查用户某个操作的权限 + function process(address origin, address from, address to, string func, string input) public constant returns(bool) { + if(!_enabled) { + return true; + } + + return Group(_groups[origin]).getPermission(to, func); + } + + //新建一个角色 + function newGroup() public returns(address) { + return new Group(); + } +} \ No newline at end of file diff --git a/systemcontractv2/AuthorityFilter.sol b/systemcontractv2/AuthorityFilter.sol new file mode 100644 index 0000000000..44eb7a27c5 --- /dev/null +++ b/systemcontractv2/AuthorityFilter.sol @@ -0,0 +1,46 @@ +pragma solidity ^0.4.4; +import "TransactionFilterBase.sol"; +import "Group.sol"; + +contract AuthorityFilter is TransactionFilterBase { + bool private _enabled = false; //是否启用权限控制 + mapping (address => address) private _groups; //用户对应的角色 + + function AuthorityFilter(){ + + } + function getInfo()public returns(string,string){ + return (name,version); + } + //设置用户的角色 + function setUserGroup(address user, address group) public { + _groups[user] = group; + } + + //获取用户的角色 + function getUserGroup(address user) public constant returns(address) { + return _groups[user]; + } + + function enable() { + _enabled = true; + } + + //检查用户某个操作的权限 + function process(address origin, address from, address to, string func, string input) public constant returns(bool) { + if(!_enabled) { + return true; + } + address group=Group(_groups[origin]); + if( 0x0000000000000000000000000000000000000000 == group ){ + return false; + } + + return Group(group).getPermission(to, func); + } + + //新建一个角色 + function newGroup() public returns(address) { + return new Group(); + } +} \ No newline at end of file diff --git a/systemcontractv2/Base.sol b/systemcontractv2/Base.sol new file mode 100644 index 0000000000..aea0b9003d --- /dev/null +++ b/systemcontractv2/Base.sol @@ -0,0 +1,94 @@ +pragma solidity ^0.4.4; + +/* +import "SystemProxy.sol"; +import "SystemAction.sol"; +*/ + + +contract Base{ + event LogMessage(address addr, uint code,string msg); // Event + + /* + address m_systemproxy; + + modifier onlySystemAdmin(){ + + if(SystemAction(SystemProxy(m_systemproxy).getSystemAction()).isAdmin(msg.sender)){ + _; + } + + + } + */ + + enum Role{ + None, + General, + GroupAdmin, + SystemAdmin, + Max + } + // 所有权限 、赋帐号权限的权限 、部署合约权限 、普通交易权限、查询权限 + enum PermissionFlag{ + All, + Grant,//goupadmin 拥有 + Deploy, + Tx, + Call + } + enum FilterType{ + Account, + Node + } + enum FilterCheckType{ + CheckDeploy, + CheckTx, + CheckCall + } + + //检查场景 + enum FilterCheckScene{ + None, + CheckDeploy, + CheckTx, + CheckCall, + CheckDeployAndTxAndCall, + PackTranscation,//打包交易场景 要校验 accountfilter、干预filter 要处理 + ImportBlock, //bc import 新块 要校验 accountfilter、干预filter 要处理 + BlockExecuteTransation // Block::execute 执行交易 通用入口 + } + + enum FilterCheckCode{ + Ok, + NoDeployPermission, + NoTxPermission, + NoCallPermission, + NoGraoupAdmin, //不是组管理员帐号 + NoAdmin, //不是链管理员帐号 + InterveneAccount,//帐号被干预 + InterveneContract,//合约被干预 + InterveneContractFunc,//合约接口被干预 + NodeNoRegister, //节点未登记 + NodeNoregister, //节点未登记 + NodeCAError, //节点机构证书无效 + NodeCANoExist, //节点机构证书不存在 + NodeSignError, //节点签名错误 + Other + } + + //节点类型 + enum NodeType{ + None, + Core, // 核心 + Full, // 全节点 + Light // 轻节点 + } + + enum CaStatus{ + Invalid, //失效 + Ok //有效 + } + + +} \ No newline at end of file diff --git a/systemcontractv2/CAAction.sol b/systemcontractv2/CAAction.sol new file mode 100644 index 0000000000..643a6e9e05 --- /dev/null +++ b/systemcontractv2/CAAction.sol @@ -0,0 +1,94 @@ +pragma solidity ^0.4.4; + +import "Base.sol"; +import "StringTool.sol"; + + +contract CAAction is Base,StringTool { + struct CaInfo + { + string hash; // 节点机构证书哈希 + string pubkey;// 公钥 + string orgname; // 机构名称 + uint notbefore; + uint notafter; + CaStatus status; + string whitelist; //;分割 + string blacklist; + + uint blocknumber; + + + } + + mapping(string =>CaInfo) m_cadata; + string[] m_hashs; + + + function CAAction(address _systemproxy) { + + + + } + + + //更新证书信息 + function update (string _hash,string _pubkey,string _orgname,uint _notbefore,uint _notafter,CaStatus _status,string _whitelist,string _blacklist) returns(bool) { + + + bool find=false; + for( uint i=0;i Item) data; +} \ No newline at end of file diff --git a/systemcontractv2/FileInfoManager.sol b/systemcontractv2/FileInfoManager.sol new file mode 100644 index 0000000000..56764e794a --- /dev/null +++ b/systemcontractv2/FileInfoManager.sol @@ -0,0 +1,332 @@ +/** +*@file FileInfoManager.sol +*@author kelvin +*@time 2017-02-13 +*@desc 文件信息管理合约 +*/ + +pragma solidity ^0.4.2; + +import "OwnerNamed.sol"; +import "LibFile.sol"; + + +contract FileInfoManager is OwnerNamed { + using LibString for *; + using LibInt for *; + using LibFile for *; + + + mapping(string=>LibFile.FileInfo) fileInfoMap;// + string[] fileIdList; + string[] fileIdListTemp; + LibFile.FileInfo fileInfo; + uint defaultPageSize; + + enum FileError { + NO_ERROR, + JSON_INVALID, + ID_CONFLICTED, + NAME_EMPTY, + ID_NOT_EXISTS, + NO_PERMISSION, + CONTAINER_NOT_EXISTS + } + + //event to caller + event Notify(uint _errno, string _info); + + function FileInfoManager() { + defaultPageSize = 16; + } + + /** insert a file */ + function insert(string _fileJson) public returns(bool) { + if (!fileInfo.jsonParse(_fileJson)) { + errno = uint256(FileError.JSON_INVALID); + log("bad json file !"); + Notify(errno, "bad file json"); + return false; + } + + //check if exists + if (fileInfoMap[fileInfo.id].state != LibFile.FileState.FILE_INVALID){ + errno = uint256(FileError.ID_NOT_EXISTS); + log("the file already exists !"); + Notify(errno, "the file already exists"); + return false; + } + + fileInfo.state = LibFile.FileState.FILE_VALID; + fileInfo.updateTime = now * 1000; + + //add to list + fileIdList.push(fileInfo.id); + + //add to mapping + fileInfoMap[fileInfo.id] = fileInfo; + + errno = uint256(FileError.NO_ERROR); + log("insert file success !"); + Notify(errno, "insert file success"); + return true; + } + + /** + ** delete a file + ** + */ + function deleteById(string _fileId) public returns(bool) { + if (fileInfoMap[_fileId].state == LibFile.FileState.FILE_INVALID) { + errno = uint256(FileError.ID_NOT_EXISTS); + log("delete file not exists"); + Notify(errno, "delete file not exists"); + return true; + } + + delete fileIdListTemp; + for (uint i = 0 ; i < fileIdList.length; ++i) { + if (fileIdList[i].equals(_fileId)) { + continue; + } + + fileIdListTemp.push(fileIdList[i]); + } + + delete fileIdList; + for (i = 0 ; i < fileIdListTemp.length; ++i) { + fileIdList.push(fileIdListTemp[i]); + } + + fileInfoMap[_fileId].state = LibFile.FileState.FILE_INVALID; + errno = uint256(FileError.NO_ERROR); + log("delete file success, id: ", _fileId); + Notify(errno, "delete file success"); + return true; + } + + /** update file info */ + function update(string _fileJson) public returns(bool) { + fileInfo.reset(); + if (!fileInfo.jsonParse(_fileJson)) { + errno = uint256(FileError.JSON_INVALID); + log("bad file json"); + Notify(errno, "bad file json"); + return false; + } + + if (fileInfoMap[fileInfo.id].state == LibFile.FileState.FILE_INVALID) { + errno = uint256(FileError.ID_NOT_EXISTS); + log("update file not exists"); + Notify(errno, "update file not exists"); + return false; + } + + + if (!fileInfo.container.equals("")) { + //如果更新container则校验ID + } + + //update info + fileInfo.state = LibFile.FileState.FILE_VALID; + fileInfo.updateTime = now * 1000; + + fileInfoMap[fileInfo.id] = fileInfo; + errno = uint256(FileError.NO_ERROR); + log("update file success"); + Notify(errno, "update file success"); + return true; + } + + /** find a file by fileId and container */ + function find(string _fileId) constant public returns(string _ret) { + _ret = "{\"ret\":0,\"data\":{"; + + if (fileInfoMap[_fileId].state != LibFile.FileState.FILE_INVALID) { + _ret = _ret.concat(fileIdList.length.toKeyValue("total"), ",\"items\":["); + _ret = _ret.concat(fileInfoMap[_fileId].toJson()); + } else { + _ret = _ret.concat(fileIdList.length.toKeyValue("total"), ",\"items\":["); + } + + _ret = _ret.concat("]}}"); + } + + function getCount() constant public returns(uint _ret){ + _ret = fileIdList.length; + } + + function listAll() constant public returns (string _ret){ + _ret = "{\"ret\":0,\"data\":{"; + _ret = _ret.concat(fileIdList.length.toKeyValue("total"), ",\"items\":["); + uint total = 0; + for (uint index = 0; index < fileIdList.length; index++) { + if (fileInfoMap[fileIdList[index]].state != LibFile.FileState.FILE_INVALID) { + if (total > 0) { + _ret = _ret.concat(","); + } + _ret = _ret.concat(fileInfoMap[fileIdList[index]].toJson()); + + total = total + 1; + } + } + + _ret = _ret.concat("]}}"); + } + + /** list all file info by group */ + function listByGroup(string _group) constant public returns (string _ret){ + _ret = "{\"ret\":0,\"data\":{"; + _ret = _ret.concat(fileIdList.length.toKeyValue("total"), ",\"items\":["); + uint total = 0; + for (uint index = 0; index < fileIdList.length; index++) { + if (fileInfoMap[fileIdList[index]].node_group.equals(_group) && fileInfoMap[fileIdList[index]].state != LibFile.FileState.FILE_INVALID) { + if (total > 0) { + _ret = _ret.concat(","); + } + _ret = _ret.concat(fileInfoMap[fileIdList[index]].toJson()); + + total = total + 1; + } + } + + _ret = _ret.concat("]}}"); + } + + /** list files info by page in pageSize */ + function pageFiles(uint _pageNo, uint256 _pageSize) constant public returns(string _ret) { + uint startIndex = uint(_pageNo * _pageSize); + uint endIndex = uint(startIndex + _pageSize - 1); + + if (startIndex >= fileIdList.length || endIndex <= 0) + { + _ret = _ret.concat("{\"ret\":0,\"data\":{\"total\":0,\"items\":[]}}"); + log1("bad parameters in pageFiles", "FileInfoManager"); + return; + } + + _ret = "{\"ret\":0,\"data\":{"; + _ret = _ret.concat(fileIdList.length.toKeyValue("total"), ",\"items\":["); + + if (endIndex >= fileIdList.length) { + endIndex = fileIdList.length - 1; + } + + for (uint index = startIndex; index <= endIndex; index++) { + if (fileInfoMap[fileIdList[index]].state != LibFile.FileState.FILE_INVALID) { + _ret = _ret.concat(fileInfoMap[fileIdList[index]].toJson()); + if (index != endIndex){ + _ret = _ret.concat(","); + } + } + } + + //the {{[ pair + _ret = _ret.concat("]}}"); + } + + /** get the fixed group in a page, pagesize is default 16 */ + function pageByGroup(string _group, uint256 _pageNo) constant public returns(string _ret) { + uint total = getGroupFileCount(_group); + + uint pageCount = 0; + if (total % defaultPageSize == 0) + { + pageCount = total / defaultPageSize; + } + else { + pageCount = total / defaultPageSize + 1; + } + + if (_pageNo < 0 || _pageNo > pageCount-1) { + log1("bad parameters in pageByGroup", "FileInfoManager"); + _ret = "{\"ret\":0,\"data\":{\"total\":0,[]}}"; + return; + } + + _ret = "{\"ret\":0,\"data\":{"; + _ret = _ret.concat(total.toKeyValue("total"), ",\"items\":["); + + uint totalBefore = defaultPageSize * _pageNo; + uint pageStartCount = 0; + uint startIndex = 0; + + for (uint index = 0; index < fileIdList.length; index++) { + if (fileInfoMap[fileIdList[index]].state != LibFile.FileState.FILE_INVALID && fileInfoMap[fileIdList[index]].node_group.equals(_group)) { + pageStartCount = pageStartCount + 1; + } + + if (pageStartCount >= totalBefore) { + startIndex = index; + break; + } + } + + uint counter = 0; + for (index = startIndex; index < fileIdList.length && counter < defaultPageSize; index++) { + if (fileInfoMap[fileIdList[index]].state != LibFile.FileState.FILE_INVALID && fileInfoMap[fileIdList[index]].node_group.equals(_group)) { + counter = counter + 1; + _ret = _ret.concat(fileInfoMap[fileIdList[index]].toJson()); + if (counter < defaultPageSize && index < fileIdList.length-1){ + _ret = _ret.concat(","); + } + } + } + + //the {{[ pair + _ret = _ret.concat("]}}"); + } + + /** get the total pages in a group */ + function getGroupPageCount(string _group) constant public returns(uint256 _ret) { + uint count = getGroupFileCount(_group); + if (count % defaultPageSize == 0) + { + _ret = count / defaultPageSize; + } + else { + _ret = count / defaultPageSize + 1; + } + } + + /** get the total files in one group */ + function getGroupFileCount(string _group) constant public returns(uint256 _ret) { + _ret = 0; + for (uint index = 0; index < fileIdList.length; index++) { + if (fileInfoMap[fileIdList[index]].state != LibFile.FileState.FILE_INVALID && fileInfoMap[fileIdList[index]].node_group.equals(_group)) { + _ret = _ret + 1; + } + } + } + + /** get current page size */ + function getCurrentPageSize() constant public returns(uint256 _ret) { + _ret = uint256(defaultPageSize); + } + + /** get default page count */ + function getCurrentPageCount() constant public returns(uint256 _ret) { + if (fileIdList.length % defaultPageSize == 0) + { + _ret = fileIdList.length / defaultPageSize; + } + else { + _ret = fileIdList.length / defaultPageSize + 1; + } + } + + /** create a unqiue file ID by group, server, filename and time */ + function generateFileID(string _salt, string _groupID, string _serverId, string _filename) constant public returns(string _ret){ + //sha3(salt-groupid-serverid-filename-timestamp) + _ret = _salt; + _ret = _ret.concat("-").concat(_groupID); + _ret = _ret.concat("-").concat(_serverId); + + uint milliTime = now * 1000; + _ret = _ret.concat("-").concat(_filename); + _ret = _ret.concat("-").concat(milliTime.toString()); + uint sha3Value = uint(sha3(_ret));//bytes32 + _ret = sha3Value.toHexString64().toLower().substr(2, 64); + } + +} diff --git a/systemcontractv2/FileServerManager.sol b/systemcontractv2/FileServerManager.sol new file mode 100644 index 0000000000..b511553d88 --- /dev/null +++ b/systemcontractv2/FileServerManager.sol @@ -0,0 +1,235 @@ +/** +*@file FileServerManager.sol +*@author kelvin +*@time 2017-01-13 +*@desc the defination of FileServerManager contract +*/ + +pragma solidity ^0.4.2; + +import "LibFileServer.sol"; +import "OwnerNamed.sol"; + + +/** FileServerManager contract */ +contract FileServerManager is OwnerNamed { + using LibString for *; + using LibInt for *; + using LibFileServer for *; + + enum ServerError { + NO_ERROR, + JSON_INVALID, + ID_CONFLICTED, + NAME_EMPTY, + ID_NOT_EXISTS, + NO_PERMISSION + } + + mapping(string=>LibFileServer.FileServerInfo) fileServerInfoMap;// + string[] fileServerIdList; + string[] fileServerIdListTemp; + LibFileServer.FileServerInfo serverInfo; + + //event to caller + event Notify(uint256 _errno, string _info); + + function FileServerManager() { + } + + /*** insert a file server */ + function insert(string _json) public returns(bool) { + if (!serverInfo.jsonParse(_json)) { + errno = uint256(ServerError.JSON_INVALID); + log("bad server json !"); + Notify(errno, "bad server json"); + return false; + } + + //check if exists + if (fileServerInfoMap[serverInfo.id].state != LibFileServer.ServerState.INVALID){ + errno = uint256(ServerError.ID_NOT_EXISTS); + log("the server already exists !"); + Notify(errno, "the server already exists"); + return false; + } + + serverInfo.state = LibFileServer.ServerState.VALID; + serverInfo.updateTime = now * 1000; + + //add to list + fileServerIdList.push(serverInfo.id); + + //add to mapping + fileServerInfoMap[serverInfo.id] = serverInfo; + + errno = uint256(ServerError.NO_ERROR); + log("insert server success !"); + Notify(errno, "insert server success"); + return true; + } + + /** + ***delete a server + ** + */ + function deleteById(string _serverId) public returns(bool) { + if (fileServerInfoMap[_serverId].state == LibFileServer.ServerState.INVALID) { + errno = uint256(ServerError.ID_NOT_EXISTS); + log("delete server not exists"); + Notify(errno, "delete server not exists"); + return true; + } + + delete fileServerIdListTemp; + for (uint i = 0 ; i < fileServerIdList.length; ++i) { + if (fileServerIdList[i].equals(_serverId)) { + continue; + } + + fileServerIdListTemp.push(fileServerIdList[i]); + } + + delete fileServerIdList; + for (i = 0 ; i < fileServerIdListTemp.length; ++i) { + fileServerIdList.push(fileServerIdListTemp[i]); + } + + fileServerInfoMap[_serverId].state = LibFileServer.ServerState.INVALID; + errno = uint256(ServerError.NO_ERROR); + log("delete server success, id: ", _serverId); + Notify(errno, "delete server success"); + return true; + } + + /*** update server info */ + function update(string _json) public returns(bool) { + serverInfo.reset(); + if (!serverInfo.jsonParse(_json)) { + errno = uint256(ServerError.JSON_INVALID); + log("bad file json"); + Notify(errno, "bad file json"); + return false; + } + + if (fileServerInfoMap[serverInfo.id].state == LibFileServer.ServerState.INVALID) { + errno = uint256(ServerError.ID_NOT_EXISTS); + log("update file not exists"); + Notify(errno, "update file not exists"); + return false; + } + + //update info + serverInfo.state = LibFileServer.ServerState.VALID; + serverInfo.updateTime = now * 1000; + + fileServerInfoMap[serverInfo.id] = serverInfo; + errno = uint256(ServerError.NO_ERROR); + log("update file success"); + Notify(errno, "update file success"); + return true; + } + + /** enable or disable the file service of the node, 0 is disable, 1 or else is enable */ + function enable(string _serverId, uint256 _enable) public returns(bool) { + for (uint index = 0; index < fileServerIdList.length; index++) { + if (fileServerInfoMap[fileServerIdList[index]].id.equals(_serverId) && fileServerInfoMap[_serverId].state != LibFileServer.ServerState.INVALID) { + fileServerInfoMap[_serverId].enable = _enable; + if (_enable == 0) { + log("disable the server: ", _serverId, "FileServerManager"); + } + else { + log("enable the server: ", _serverId, "FileServerManager"); + } + + errno = uint256(ServerError.NO_ERROR); + Notify(errno, "enable server success"); + return true; + } + } + + log("enable server fail, ", _serverId, "FileServerManager"); + Notify(errno, "enable server fail"); + return false; + } + + /*** find a file by fileId and container */ + function find(string _serverId) constant public returns(string _ret) { + _ret = "{\"ret\":0,\"data\":{"; + uint count = 0; + + if (fileServerInfoMap[_serverId].state != LibFileServer.ServerState.INVALID) { + count = 1; + _ret = _ret.concat(count.toKeyValue("total"), ",\"items\":["); + _ret = _ret.concat(fileServerInfoMap[_serverId].toJson()); + } else { + _ret = _ret.concat(count.toKeyValue("total"), ",\"items\":["); + } + + _ret = _ret.concat("]}}"); + } + + /*** find a file by fileId and container */ + function isServerEnable(string _serverId) constant public returns(uint256 _ret) { + if (fileServerInfoMap[_serverId].state != LibFileServer.ServerState.INVALID && fileServerInfoMap[_serverId].enable != 0) { + _ret = 1; + } else { + _ret = 0; + } + } + + /** get the count of all servers includes disable servers */ + function getCount() constant public returns(uint256 _total) { + _total = fileServerIdList.length; + } + + /** list all the servers info */ + function listAll() constant public returns(string _ret){ + _ret = "{\"ret\":0,\"data\":{"; + _ret = _ret.concat(fileServerIdList.length.toKeyValue("total"), ",\"items\":["); + uint total = 0; + for (uint index = 0; index < fileServerIdList.length; index++) { + if (fileServerInfoMap[fileServerIdList[index]].state != LibFileServer.ServerState.INVALID) { + if (total > 0) { + _ret = _ret.concat(","); + } + + total = total + 1; + _ret = _ret.concat(fileServerInfoMap[fileServerIdList[index]].toJson()); + } + } + + _ret = _ret.concat("]}}"); + } + + /** list server by group name */ + function listByGroup(string _group) constant public returns(string _ret){ + _ret = "{\"ret\":0,\"data\":{"; + _ret = _ret.concat(fileServerIdList.length.toKeyValue("total"), ",\"items\":["); + uint total = 0; + for (uint index = 0; index < fileServerIdList.length; index++) { + if (fileServerInfoMap[fileServerIdList[index]].state != LibFileServer.ServerState.INVALID && fileServerInfoMap[fileServerIdList[index]].group.equals(_group)) { + if (total > 0) { + _ret = _ret.concat(","); + } + + total = total + 1; + _ret = _ret.concat(fileServerInfoMap[fileServerIdList[index]].toJson()); + } + } + + _ret = _ret.concat("]}}"); + } + + function findIdByHostPort(string _host, uint256 _port) constant public returns(string _ret) { + for (uint index = 0; index < fileServerIdList.length; index++) { + if (fileServerInfoMap[fileServerIdList[index]].state != LibFileServer.ServerState.INVALID && fileServerInfoMap[fileServerIdList[index]].host.equals(_host) && fileServerInfoMap[fileServerIdList[index]].port == _port) { + _ret = fileServerInfoMap[fileServerIdList[index]].id; + return; + } + } + + _ret = ""; + return; + } +} \ No newline at end of file diff --git a/systemcontractv2/Group.sol b/systemcontractv2/Group.sol new file mode 100644 index 0000000000..b374c081ca --- /dev/null +++ b/systemcontractv2/Group.sol @@ -0,0 +1,41 @@ +pragma solidity ^0.4.4; + +contract Group { + mapping (bytes32 => bool) private _permissions; //权限列表,key为sha256(合约地址, 函数名) + bool private _create = false; //是否可创建合约 + bool private _black = false; //黑名单模式 + + function getPermission(address to, string func) public constant returns(bool) { + return true;//所有人都有权限 + + bytes32 key = sha256(to, func); + + if(_black) { + return !_permissions[key]; + } + + return _permissions[key]; + } + + function setPermission(address to, string func, bool perrmission) public { + bytes32 key = sha256(to, func); + + _permissions[key] = perrmission; + } + + function getCreate() constant public returns(bool) { + return _create; + } + + function setCreate(bool create) public { + _create = create; + } + + function getBlack() constant public returns(bool) { + return _black; + } + + function setBlack(bool black) public { + _black = black; + } +} \ No newline at end of file diff --git a/systemcontractv2/LibFile.sol b/systemcontractv2/LibFile.sol new file mode 100644 index 0000000000..68a800b627 --- /dev/null +++ b/systemcontractv2/LibFile.sol @@ -0,0 +1,95 @@ + +/** +*@file LibFile.sol +*@author kelvin +*@time 2016-11-29 +*@desc the defination of LibFile +*/ + +pragma solidity ^0.4.2; + +import "LibInt.sol"; +import "LibString.sol"; + + +library LibFile { + using LibInt for *; + using LibString for *; + using LibFile for *; + + + /** @brief User state: invalid, valid */ + enum FileState { FILE_INVALID, FILE_VALID} + + /** @brief File Structure */ + struct FileInfo { + string id; + string container; + string filename; + uint256 updateTime; + uint256 size; + string owner; + string file_hash;/** md5 hash */ + string src_node;//server node id: TODO: 考虑删除 + string node_group; + uint256 Type;//status + string priviliges; + string info; + //uint256 expire;//new add + FileState state; + } + + + function toJson(FileInfo storage _self) internal returns(string _strjson){ + _strjson = "{"; + + _strjson = _strjson.concat(_self.id.toKeyValue("id"), ","); + _strjson = _strjson.concat(_self.container.toKeyValue("container"), ","); + _strjson = _strjson.concat(_self.filename.toKeyValue("filename"), ","); + _strjson = _strjson.concat(uint(_self.updateTime).toKeyValue("updateTime"), ","); + _strjson = _strjson.concat(uint(_self.size).toKeyValue("size"), ","); + _strjson = _strjson.concat(_self.file_hash.toKeyValue("file_hash"), ","); + _strjson = _strjson.concat(uint(_self.Type).toKeyValue("type"), ","); + _strjson = _strjson.concat(_self.priviliges.toKeyValue("priviliges"), ","); + _strjson = _strjson.concat(_self.src_node.toKeyValue("src_node"), ","); + _strjson = _strjson.concat(_self.node_group.toKeyValue("node_group"), ","); + _strjson = _strjson.concat(_self.info.toKeyValue("info"), "}"); + } + + function jsonParse(FileInfo storage _self, string _json) internal returns(bool) { + _self.reset(); + + _self.id = _json.getStringValueByKey("id"); + _self.filename = _json.getStringValueByKey("filename"); + _self.container = _json.getStringValueByKey("container"); + _self.size = uint256(_json.getIntValueByKey("size")); + _self.file_hash = _json.getStringValueByKey("file_hash"); + _self.Type = uint256(_json.getIntValueByKey("type")); + _self.priviliges = _json.getStringValueByKey("priviliges"); + _self.info = _json.getStringValueByKey("info"); + _self.src_node = _json.getStringValueByKey("src_node"); + _self.node_group = _json.getStringValueByKey("node_group"); + + if (bytes(_self.id).length == 0) { + return false; + } + + return true; + } + + function reset(FileInfo storage _self) internal { + _self.id = ""; + _self.filename = ""; + _self.container = ""; + _self.size = 0; + _self.file_hash = ""; + _self.node_group = ""; + _self.Type = 0; + _self.updateTime = 0; + _self.priviliges = ""; + _self.info = ""; + _self.src_node = ""; + + _self.state = FileState.FILE_INVALID; + } +} diff --git a/systemcontractv2/LibFileServer.sol b/systemcontractv2/LibFileServer.sol new file mode 100644 index 0000000000..750820be09 --- /dev/null +++ b/systemcontractv2/LibFileServer.sol @@ -0,0 +1,86 @@ + +/** +*@file LibFileServer.sol +*@author kelvin +*@time 2016-11-29 +*@desc the defination of LibFileServer +*/ + +pragma solidity ^0.4.2; + +import "LibInt.sol"; +import "LibString.sol"; + + +library LibFileServer { + using LibInt for *; + using LibString for *; + using LibFileServer for *; + + + /** @brief User state: invalid, valid */ + enum ServerState { INVALID, VALID} + + /** @brief File Structure */ + struct FileServerInfo { + string id; + string host; + uint256 port; + uint256 updateTime; + string organization; + string position; + string group; + string info; + uint256 enable; + ServerState state; + } + + + function toJson(FileServerInfo storage _self) internal returns(string _strjson){ + _strjson = "{"; + + _strjson = _strjson.concat(_self.id.toKeyValue("id"), ","); + _strjson = _strjson.concat(_self.host.toKeyValue("host"), ","); + _strjson = _strjson.concat(uint(_self.port).toKeyValue("port"), ","); + _strjson = _strjson.concat(uint(_self.updateTime).toKeyValue("updateTime"), ","); + _strjson = _strjson.concat(_self.position.toKeyValue("position"), ","); + _strjson = _strjson.concat(_self.group.toKeyValue("group"), ","); + _strjson = _strjson.concat(_self.organization.toKeyValue("organization"), ","); + _strjson = _strjson.concat(uint(_self.enable).toKeyValue("enable"), ","); + _strjson = _strjson.concat(_self.info.toKeyValue("info"), "}"); + } + + function jsonParse(FileServerInfo storage _self, string _json) internal returns(bool) { + _self.reset(); + + _self.id = _json.getStringValueByKey("id"); + _self.host = _json.getStringValueByKey("host"); + _self.port = uint256(_json.getIntValueByKey("port")); + //_self.updateTime = uint256(_json.getIntValueByKey("updateTime")); + _self.position = _json.getStringValueByKey("position"); + _self.group = _json.getStringValueByKey("group"); + _self.organization = _json.getStringValueByKey("organization"); + _self.info = _json.getStringValueByKey("info"); + _self.enable = (uint256)(_json.getIntValueByKey("enable")); + + if (bytes(_self.id).length == 0) { + return false; + } + + return true; + } + + function reset(FileServerInfo storage _self) internal { + _self.id = ""; + _self.host = ""; + _self.port = 0; + _self.updateTime = 0; + _self.position = ""; + _self.organization = ""; + _self.info = ""; + _self.group = ""; + _self.enable = 0; + + _self.state = ServerState.INVALID; + } +} diff --git a/systemcontractv2/LibInt.sol b/systemcontractv2/LibInt.sol new file mode 100644 index 0000000000..00c91b1549 --- /dev/null +++ b/systemcontractv2/LibInt.sol @@ -0,0 +1,224 @@ +/** +* file LibInt.sol +* author liaoyan +* time 2016-11-29 +* desc the defination of LibInt libary +*/ + +pragma solidity ^0.4.2; + +library LibInt { + using LibInt for *; + + function toString(uint _self) internal returns (string _ret) { + if (_self == 0) { + return "0"; + } + + uint8 len = 0; + uint tmp = _self; + while (tmp > 0) { + tmp /= 10; + len++; + } + + _ret = new string(len); + + uint8 i = len-1; + while (_self > 0) { + bytes(_ret)[i--] = byte(_self%10+0x30); + _self /= 10; + } + } + + function toHexString(uint _self) internal returns (string _ret) { + if (_self == 0) { + return "0x0"; + } + + uint8 len = 2; + uint tmp = _self; + while (tmp > 0) { + tmp /= 16; + len++; + } + + _ret = new string(len); + + uint8 i = len-1; + while (_self > 0) { + if (_self%16 > 9) { + bytes(_ret)[i--] = byte(_self%16+0x61-0xa); + } else { + bytes(_ret)[i--] = byte(_self%16+0x30); + } + + _self /= 16; + } + + bytes(_ret)[0] = byte(0x30); + bytes(_ret)[1] = byte(0x78); + } + + function toHexString64(uint _self) internal returns (string _ret) { + _ret = new string(66); + bytes(_ret)[0] = '0'; + bytes(_ret)[1] = 'x'; + + for (uint8 i=65; i>=2; --i) { + uint8 digit = uint8(_self&0x0F); + _self /= 16; + + if (digit < 10) + bytes(_ret)[i] = byte(digit+0x30); + else + bytes(_ret)[i] = byte(digit-10+0x61); + } + } + + function toString(int _self) internal returns (string _ret) { + if (_self == 0) { + return "0"; + } + + uint ui = uint(_self); + bool positive = true; + uint8 len = 0; + if (_self < 0) { + ui = uint(-_self); + positive = false; + len++; + } + + uint tmp = ui; + while (tmp > 0) { + tmp /= 10; + len++; + } + + _ret = new string(len); + if (!positive) { + bytes(_ret)[0] = '-'; + } + + uint8 i = len-1; + while (ui > 0) { + bytes(_ret)[i--] = byte(ui%10+0x30); + ui /= 10; + } + } + + function toAddrString(uint _self) internal returns (string _ret) { + _ret = new string(42); + bytes(_ret)[0] = '0'; + bytes(_ret)[1] = 'x'; + + for (uint8 i=41; i>=2; --i) { + uint8 digit = uint8(_self&0x0F); + _self /= 16; + + if (digit < 10) + bytes(_ret)[i] = byte(digit+0x30); + else + bytes(_ret)[i] = byte(digit-10+0x61); + } + } + + function toKeyValue(uint _self, string _key) internal returns (string _ret) { + uint len = bytes(_key).length+3; + + if (_self == 0) { + len += 1; + } else { + uint tmp = _self; + while (tmp > 0) { + tmp /= 10; + len++; + } + } + + _ret = new string(len); + + uint i = 0; + bytes(_ret)[i++] = '"'; + for (uint j=0; j < bytes(_key).length; j++) { + bytes(_ret)[i++] = bytes(_key)[j]; + } + bytes(_ret)[i++] = '"'; + + bytes(_ret)[i++] = ':'; + + i = len-1; + if (_self == 0) { + bytes(_ret)[i] = byte(0x30); + } else { + while (_self > 0) { + bytes(_ret)[i--] = byte(_self%10+0x30); + _self /= 10; + } + } + } + + function toKeyValue(int _self, string _key) internal returns (string _ret) { + uint ui = uint(_self); + bool positive = true; + uint len = bytes(_key).length+3; + if (_self < 0) { + ui = uint(-_self); + positive = false; + len++; + } + + if (_self == 0) { + len += 1; + } else { + uint tmp = ui; + while (tmp > 0) { + tmp /= 10; + len++; + } + } + + _ret = new string(len); + + uint i = 0; + bytes(_ret)[i++] = '"'; + for (uint j=0; j < bytes(_key).length; j++) { + bytes(_ret)[i++] = bytes(_key)[j]; + } + bytes(_ret)[i++] = '"'; + + bytes(_ret)[i++] = ':'; + + if (!positive) { + bytes(_ret)[i++] = '-'; + } + i = len-1; + if (_self == 0) { + bytes(_ret)[i] = byte(0x30); + } else { + while (ui > 0) { + bytes(_ret)[i--] = byte(ui%10+0x30); + ui /= 10; + } + } + } + + function recoveryToString(uint _self) internal returns (string _ret) { + uint tmp = _self; + uint len = 0; + while (tmp > 0) { + tmp /= 256; + len++; + } + + _ret = new string(len); + tmp = _self; + uint i = len-1; + while (tmp > 0) { + bytes(_ret)[i] = byte(tmp%256); + tmp /= 256; + i--; + } + } +} \ No newline at end of file diff --git a/systemcontractv2/LibPaillier.sol b/systemcontractv2/LibPaillier.sol new file mode 100644 index 0000000000..a76c3504de --- /dev/null +++ b/systemcontractv2/LibPaillier.sol @@ -0,0 +1,39 @@ +pragma solidity ^0.4.2; + +import "LibString.sol"; +import "LibInt.sol"; + +library LibPaillier { + using LibString for *; + using LibInt for *; + + function pai_add(string d1, string d2) internal constant returns (string) { + string memory cmd = "[69d98d6a04c41b4605aacb7bd2f74bee][08paillier]"; + cmd = cmd.concat("|", d1); + cmd = cmd.concat("|", d2); + + uint rLen = bytes(d1).length; + string memory result = new string(rLen); + + uint strptr; + assembly { + strptr := add(result, 0x20) + } + cmd = cmd.concat("|", strptr.toString()); + + bytes32 hash; + uint strlen = bytes(cmd).length; + assembly { + strptr := add(cmd, 0x20) + hash := sha3(strptr, strlen) + } + + string memory errRet = ""; + uint ret = uint(hash); + if (ret != 0) { + return errRet; + } + + return result; + } +} diff --git a/systemcontractv2/LibString.sol b/systemcontractv2/LibString.sol new file mode 100644 index 0000000000..d85a37c34c --- /dev/null +++ b/systemcontractv2/LibString.sol @@ -0,0 +1,885 @@ +/** +* file LibString.sol +* author liaoyan +* time 2016-11-29 +* desc the defination of LibString contract +*/ + +pragma solidity ^0.4.2; + +library LibString { + + using LibString for *; + + function memcpy(uint dest, uint src, uint len) private { + // Copy word-length chunks while possible + for(; len >= 32; len -= 32) { + assembly { + mstore(dest, mload(src)) + } + dest += 32; + src += 32; + } + + // Copy remaining bytes + uint mask = 256 ** (32 - len) - 1; + assembly { + let srcpart := and(mload(src), not(mask)) + let destpart := and(mload(dest), mask) + mstore(dest, or(destpart, srcpart)) + } + } + + // Returns the memory address of the first byte of the first occurrence of + // `needle` in `self`, or the first byte after `self` if not found. + function findPtr(uint selflen, uint selfptr, uint needlelen, uint needleptr) private returns (uint) { + uint ptr; + uint idx; + + if (needlelen <= selflen) { + if (needlelen <= 32) { + // Optimized assembly for 68 gas per byte on short strings + assembly { + let mask := not(sub(exp(2, mul(8, sub(32, needlelen))), 1)) + let needledata := and(mload(needleptr), mask) + let end := add(selfptr, sub(selflen, needlelen)) + ptr := selfptr + loop: + jumpi(exit, eq(and(mload(ptr), mask), needledata)) + ptr := add(ptr, 1) + jumpi(loop, lt(sub(ptr, 1), end)) + ptr := add(selfptr, selflen) + exit: + } + return ptr; + } else { + // For long needles, use hashing + bytes32 hash; + assembly { hash := sha3(needleptr, needlelen) } + ptr = selfptr; + for (idx = 0; idx <= selflen - needlelen; idx++) { + bytes32 testHash; + assembly { testHash := sha3(ptr, needlelen) } + if (hash == testHash) + return ptr; + ptr += 1; + } + } + } + return selfptr + selflen; + } + + /* + function length(string _self) internal returns (uint _ret) { + _ret = bytes(_self).length; + } + */ + + function compare(string _self, string _str) internal returns (int8 _ret) { + for (uint i=0; i bytes(_str)[i]) { + return 1; + } else if (bytes(_self)[i] < bytes(_str)[i]) { + return -1; + } + } + + if (bytes(_self).length > bytes(_str).length) { + return 1; + } if (bytes(_self).length < bytes(_str).length) { + return -1; + } else { + return 0; + } + } + + function compareNoCase(string _self, string _str) internal returns (int8 _ret) { + for (uint i=0; i= 'a' && ch1 <='z' && ch2 >= 'a' && ch2 <='z') { + if (ch1 > ch2) { + return 1; + } else if (ch1 < ch2) { + return -1; + } + } else { + if (bytes(_self)[i] > bytes(_str)[i]) { + return 1; + } else if (bytes(_self)[i] < bytes(_str)[i]) { + return -1; + } + } + } + + if (bytes(_self).length > bytes(_str).length) { + return 1; + } if (bytes(_self).length < bytes(_str).length) { + return -1; + } else { + return 0; + } + } + + function equals(string _self, string _str) internal returns (bool _ret) { + if (bytes(_self).length != bytes(_str).length) { + return false; + } + + for (uint i=0; i= 'a' && ch1 <='z' && ch2 >= 'a' && ch2 <='z') { + if (ch1 != ch2) { + return false; + } + } else { + if (bytes(_self)[i] != bytes(_str)[i]) { + return false; + } + } + } + + return true; + } + + function substr(string _self, uint _start, uint _len) internal returns (string _ret) { + if (_len > bytes(_self).length-_start) { + _len = bytes(_self).length-_start; + } + + if (_len <= 0) { + _ret = ""; + return; + } + + _ret = new string(_len); + + uint selfptr; + uint retptr; + assembly { + selfptr := add(_self, 0x20) + retptr := add(_ret, 0x20) + } + + memcpy(retptr, selfptr+_start, _len); + } + + function concat(string _self, string _str) internal returns (string _ret) { + _ret = new string(bytes(_self).length + bytes(_str).length); + + uint selfptr; + uint strptr; + uint retptr; + assembly { + selfptr := add(_self, 0x20) + strptr := add(_str, 0x20) + retptr := add(_ret, 0x20) + } + + memcpy(retptr, selfptr, bytes(_self).length); + memcpy(retptr+bytes(_self).length, strptr, bytes(_str).length); + } + + function concat(string _self, string _str1, string _str2) + internal returns (string _ret) { + _ret = new string(bytes(_self).length + bytes(_str1).length + bytes(_str2).length); + + uint selfptr; + uint str1ptr; + uint str2ptr; + uint retptr; + assembly { + selfptr := add(_self, 0x20) + str1ptr := add(_str1, 0x20) + str2ptr := add(_str2, 0x20) + retptr := add(_ret, 0x20) + } + + uint pos = 0; + memcpy(retptr+pos, selfptr, bytes(_self).length); + pos += bytes(_self).length; + memcpy(retptr+pos, str1ptr, bytes(_str1).length); + pos += bytes(_str1).length; + memcpy(retptr+pos, str2ptr, bytes(_str2).length); + pos += bytes(_str2).length; + } + + function concat(string _self, string _str1, string _str2, string _str3) + internal returns (string _ret) { + _ret = new string(bytes(_self).length + bytes(_str1).length + bytes(_str2).length + + bytes(_str3).length); + + uint selfptr; + uint str1ptr; + uint str2ptr; + uint str3ptr; + uint retptr; + assembly { + selfptr := add(_self, 0x20) + str1ptr := add(_str1, 0x20) + str2ptr := add(_str2, 0x20) + str3ptr := add(_str3, 0x20) + retptr := add(_ret, 0x20) + } + + uint pos = 0; + memcpy(retptr+pos, selfptr, bytes(_self).length); + pos += bytes(_self).length; + memcpy(retptr+pos, str1ptr, bytes(_str1).length); + pos += bytes(_str1).length; + memcpy(retptr+pos, str2ptr, bytes(_str2).length); + pos += bytes(_str2).length; + memcpy(retptr+pos, str3ptr, bytes(_str3).length); + pos += bytes(_str3).length; + } + + function trim(string _self) internal returns (string _ret) { + uint i; + uint8 ch; + for (i=0; i0; --i) { + ch = uint8(bytes(_self)[i-1]); + if (!(ch == 0x20 || ch == 0x09 || ch == 0x0D || ch == 0x0A)) { + break; + } + } + uint end = i; + + _ret = new string(end-start); + + uint selfptr; + uint retptr; + assembly { + selfptr := add(_self, 0x20) + retptr := add(_ret, 0x20) + } + + memcpy(retptr, selfptr+start, end-start); + } + + function trim(string _self, string _chars) internal returns (string _ret) { + uint16 i; + uint16 j; + bool matched; + for (i=0; i0; --i) { + matched = false; + for (j=0; j 0) { + ptr = findPtr(bytes(_self).length-pos, selfptr+pos, bytes(_delim).length, delimptr) - selfptr; + + if (ptr < bytes(_self).length) { + found = true; + } else { + ptr = bytes(_self).length; + } + } else { + ptr = bytes(_self).length; + } + + string memory elem = new string(ptr-pos); + uint elemptr; + assembly { + elemptr := add(elem, 0x20) + } + memcpy(elemptr, selfptr+pos, ptr-pos); + pos = ptr + bytes(_delim).length; + _array.push(elem); + + if (!found) { + break; + } + } + } + + function indexOf(string _self, string _str) internal returns (int _ret) { + uint selfptr; + uint strptr; + assembly { + selfptr := add(_self, 0x20) + strptr := add(_str, 0x20) + } + + uint ptr = findPtr(bytes(_self).length, selfptr, bytes(_str).length, strptr) - selfptr; + if (ptr < bytes(_self).length) { + _ret = int(ptr); + } else { + _ret = -1; + } + } + + function indexOf(string _self, string _str, uint pos) internal returns (int _ret) { + uint selfptr; + uint strptr; + assembly { + selfptr := add(_self, 0x20) + strptr := add(_str, 0x20) + } + + uint ptr = findPtr(bytes(_self).length-pos, selfptr+pos, bytes(_str).length, strptr) - selfptr; + if (ptr < bytes(_self).length) { + _ret = int(ptr); + } else { + _ret = -1; + } + } + + function toInt(string _self) internal returns (int _ret) { + _ret = 0; + if (bytes(_self).length == 0) { + return; + } + + uint16 i; + uint8 digit; + for (i=0; i= 0x30 && digit <= 0x39)) { + return; + } + _ret = _ret*10 + int(digit-0x30); + } + + if (!positive) { + _ret = -_ret; + } + } + + function toAddress(string _self) internal returns (address _ret) { + uint16 i; + uint8 digit; + for (i=0; i= 0x30 && digit <= 0x39) //'0'-'9' + digit -= 0x30; + else if (digit|0x20 >= 0x61 && digit|0x20 <= 0x66) //'a'-'f' + digit = digit-0x61+10; + else + return address(0); + + addr = addr*16+digit; + } + + return address(addr); + } + + function toKeyValue(string _self, string _key) internal returns (string _ret) { + _ret = new string(bytes(_self).length + bytes(_key).length + 5); + + uint selfptr; + uint keyptr; + uint retptr; + assembly { + selfptr := add(_self, 0x20) + keyptr := add(_key, 0x20) + retptr := add(_ret, 0x20) + } + + uint pos = 0; + + bytes(_ret)[pos++] = '"'; + memcpy(retptr+pos, keyptr, bytes(_key).length); + pos += bytes(_key).length; + bytes(_ret)[pos++] = '"'; + + bytes(_ret)[pos++] = ':'; + + bytes(_ret)[pos++] = '"'; + memcpy(retptr+pos, selfptr, bytes(_self).length); + pos += bytes(_self).length; + bytes(_ret)[pos++] = '"'; + } + + function toKeyValue(string[] storage _self, string _key) internal returns (string _ret) { + uint len = bytes(_key).length+5; + for (uint i=0; i<_self.length; ++i) { + if (i < _self.length-1) + len += bytes(_self[i]).length+3; + else + len += bytes(_self[i]).length+2; + } + + _ret = new string(len); + + uint pos = 0; + + bytes(_ret)[pos++] = '"'; + for (uint j=0; j= 0x30 && digit <= 0x39)) { + if (!positive) { + _ret = -_ret; + } + return; + } + _ret = _ret*10 + int(digit-0x30); + } + + if (!positive) { + _ret = -_ret; + } + } + + function getArrayValueByKey(string _self, string _key) internal returns (string _ret) { + int pos = -1; + uint searchStart = 0; + while (true) { + pos = _self.indexOf("\"".concat(_key, "\""), searchStart); + if (pos == -1) { + pos = _self.indexOf("'".concat(_key, "'"), searchStart); + if (pos == -1) { + return; + } + } + + pos += int(bytes(_key).length+2); + + bool colon = false; + while (uint(pos) < bytes(_self).length) { + if (bytes(_self)[uint(pos)] == ' ' || bytes(_self)[uint(pos)] == '\t' + || bytes(_self)[uint(pos)] == '\r' || bytes(_self)[uint(pos)] == '\n') { + pos++; + } else if (bytes(_self)[uint(pos)] == ':') { + pos++; + colon = true; + break; + } else { + break; + } + } + + if(uint(pos) == bytes(_self).length) { + return; + } + + if (colon) { + break; + } else { + searchStart = uint(pos); + } + } + + int start = _self.indexOf("[", uint(pos)); + if (start == -1) { + return; + } + start += 1; + + int end = _self.indexOf("]", uint(pos)); + if (end == -1) { + return; + } + + _ret = _self.substr(uint(start), uint(end-start)); + } + + function getArrayValueByKey(string _self, string _key, string[] storage _array) internal { + //Why can not use delete _array? + for (uint i=0; i<_array.length; ++i) { + delete _array[i]; + } + _array.length = 0; + + int pos = -1; + uint searchStart = 0; + while (true) { + pos = _self.indexOf("\"".concat(_key, "\""), searchStart); + if (pos == -1) { + pos = _self.indexOf("'".concat(_key, "'"), searchStart); + if (pos == -1) { + return; + } + } + + pos += int(bytes(_key).length+2); + + bool colon = false; + while (uint(pos) < bytes(_self).length) { + if (bytes(_self)[uint(pos)] == ' ' || bytes(_self)[uint(pos)] == '\t' + || bytes(_self)[uint(pos)] == '\r' || bytes(_self)[uint(pos)] == '\n') { + pos++; + } else if (bytes(_self)[uint(pos)] == ':') { + pos++; + colon = true; + break; + } else { + break; + } + } + + if(uint(pos) == bytes(_self).length) { + return; + } + + if (colon) { + break; + } else { + searchStart = uint(pos); + } + } + + int start = _self.indexOf("[", uint(pos)); + if (start == -1) { + return; + } + start += 1; + + int end = _self.indexOf("]", uint(pos)); + if (end == -1) { + return; + } + + string memory vals = _self.substr(uint(start), uint(end-start)).trim(" \t\r\n"); + + if (bytes(vals).length == 0) { + return; + } + + vals.split(",", _array); + + for (i=0; i<_array.length; ++i) { + _array[i] = _array[i].trim(" \t\r\n"); + _array[i] = _array[i].trim("'\""); + } + } + + function keyExists(string _self, string _key) internal returns (bool _ret) { + int pos = _self.indexOf("\"".concat(_key, "\"")); + if (pos == -1) { + pos = _self.indexOf("'".concat(_key, "'")); + if (pos == -1) { + return false; + } + } + + return true; + } + + function storageToUint(string _self) internal returns (uint _ret) { + uint len = bytes(_self).length; + if (len > 32) { + len = 32; + } + + _ret = 0; + for(uint i=0; i= 'a' && bytes(_self)[i] <= 'z') { + bytes(_self)[i] &= ~0x20; + } + } + + _ret = _self; + } + + function toLower(string _self) internal returns (string _ret) { + for (uint i=0; i= 'A' && bytes(_self)[i] <= 'Z') { + bytes(_self)[i] |= 0x20; + } + } + + _ret = _self; + } + } \ No newline at end of file diff --git a/systemcontractv2/NodeAction.sol b/systemcontractv2/NodeAction.sol new file mode 100644 index 0000000000..f7d783d5f6 --- /dev/null +++ b/systemcontractv2/NodeAction.sol @@ -0,0 +1,109 @@ +pragma solidity ^0.4.4; + +import "Base.sol"; +import "StringTool.sol"; + +contract NodeAction is Base ,StringTool{ + + + struct NodeInfo{ + string id; + string ip; + uint port; + NodeType category; + string desc; // 节点描述 + string CAhash; // 节点机构证书哈希 + string agencyinfo; + uint idx; + uint blocknumber; + } + + + + mapping(string =>NodeInfo) m_nodedata; + string[] m_nodeids; + + function NodeAction() { + } + + //变更之后 更新idx + function updateIdx() internal { + uint startCore=0;//核心节点开始 + for( var i=0;i 0 ){ + m_nodeids[i]=m_nodeids[m_nodeids.length-1]; + } + + m_nodeids.length--; + delete m_nodedata[_id]; + + updateIdx(); + return true; + } + } + + + + return false; + } + + + //查询节点信息 + function getNode(string _id) public constant returns(string,uint,NodeType,string,string,string,uint){ + + return (m_nodedata[_id].ip,m_nodedata[_id].port,m_nodedata[_id].category,m_nodedata[_id].desc,m_nodedata[_id].CAhash ,m_nodedata[_id].agencyinfo,m_nodedata[_id].blocknumber); + } + + function getNodeIdx(string _id) public constant returns(uint){ + + return (m_nodedata[_id].idx); + } + + function getNodeIdsLength() public constant returns(uint){ + return m_nodeids.length; + } + function getNodeId(uint _index) public constant returns(string){ + return m_nodeids[_index]; + } +} \ No newline at end of file diff --git a/systemcontractv2/OwnerNamed.sol b/systemcontractv2/OwnerNamed.sol new file mode 100644 index 0000000000..f8a4be82f3 --- /dev/null +++ b/systemcontractv2/OwnerNamed.sol @@ -0,0 +1,106 @@ +/** +*@file OwnerNamed.sol +*@author yanze +*@time 2016-11-29 +*@desc the defination of OwnerNamed contract +*/ + +pragma solidity ^0.4.2; + + +import "LibString.sol"; +import "LibInt.sol"; + +contract OwnerNamed { + using LibString for *; + using LibInt for *; + + address owner; + + function OwnerNamed() { + owner = msg.sender; + } + + function register(string _name, string _version) public { + //rm.register(_name,_version); + } + + function kill() public { + if (msg.sender != owner) { + return; + } + } + + //test begin + function getOwner() constant public returns (string _ret) { + _ret = owner.addrToAsciiString(); + } + + function getSender() constant public returns (string _ret) { + _ret = msg.sender.addrToAsciiString(); + } + + uint errno = 0; + + function getErrno() constant returns (uint) { + return errno; + } + + /** 日志函数, 内容长度限制为32字符,返回值必须(勿删除) */ + function log(string _str) constant public returns(uint) { + log0(bytes32(stringToUint(_str))); + return 0; + } + + /** 日志函数, 内容长度限制为32字符,返回值必须(勿删除) */ + function log(string _str, string _topic) constant public returns(uint) { + log1(bytes32(stringToUint(_str)), bytes32(stringToUint(_topic))); + return 0; + } + + /** 日志函数, 内容长度限制为32字符,返回值必须(勿删除) */ + function log(string _str, string _str2, string _topic) constant public returns(uint) { + string memory logStr = ""; + logStr = logStr.concat(_str, _str2); + log1(bytes32(stringToUint(logStr)), bytes32(stringToUint(_topic))); + } + + /** 日志函数, 内容长度限制为32字符,返回值必须(勿删除) */ + function log(string _str, uint _ui) constant public returns(uint) { + string memory logStr = ""; + logStr = logStr.concat(_str, _ui.toString()); + log0(bytes32(stringToUint(logStr))); + } + + /** 日志函数, 内容长度限制为32字符,返回值必须(勿删除) */ + function log(string _str, int _i) constant public returns(uint) { + string memory logStr = ""; + logStr = logStr.concat(_str, _i.toString()); + log0(bytes32(stringToUint(logStr))); + return 0; + } + + /** 日志函数, 内容长度限制为32字符,返回值必须(勿删除) */ + function log(string _str, address _addr) constant public returns(uint) { + string memory logStr = ""; + logStr = logStr.concat(_str, uint(_addr).toAddrString()); + log0(bytes32(stringToUint(logStr))); + return 0; + } + + /** string convert to uint256 */ + function stringToUint(string _str) constant returns(uint _ret) { + uint len = bytes(_str).length; + if (len > 32) { + len = 32; + } + + _ret = 0; + for(uint i=0; i<32; ++i) { + if (i < len) + _ret = _ret*256 + uint8(bytes(_str)[i]); + else + _ret = _ret*256; + } + } +} diff --git a/systemcontractv2/StringTool.sol b/systemcontractv2/StringTool.sol new file mode 100644 index 0000000000..6039f589e2 --- /dev/null +++ b/systemcontractv2/StringTool.sol @@ -0,0 +1,59 @@ +pragma solidity ^0.4.4; + + +contract StringTool{ + function compare(string _a, string _b) returns (int) { + bytes memory a = bytes(_a); + bytes memory b = bytes(_b); + uint minLength = a.length; + if (b.length < minLength) minLength = b.length; + //@todo unroll the loop into increments of 32 and do full 32 byte comparisons + for (uint i = 0; i < minLength; i ++) + if (a[i] < b[i]) + return -1; + else if (a[i] > b[i]) + return 1; + if (a.length < b.length) + return -1; + else if (a.length > b.length) + return 1; + else + return 0; + } + /// @dev Compares two strings and returns true iff they are equal. + function equal(string _a, string _b) returns (bool) { + return compare(_a, _b) == 0; + } + + function byte64ToString(byte[64] x) constant returns (string) { + bytes memory bytesString = new bytes(64); + uint charCount = 0; + for (uint j = 0; j < 64; j++) { + if (x[j] != 0) { + bytesString[charCount] = x[j]; + charCount++; + } + } + bytes memory bytesStringTrimmed = new bytes(charCount); + for (j = 0; j < charCount; j++) { + bytesStringTrimmed[j] = bytesString[j]; + } + return string(bytesStringTrimmed); + } + + function byte32ToString(byte[32] x) internal constant returns (string) { + bytes memory bytesString = new bytes(32); + uint charCount = 0; + for (uint j = 0; j < 32; j++) { + if (x[j] != 0) { + bytesString[charCount] = x[j]; + charCount++; + } + } + bytes memory bytesStringTrimmed = new bytes(charCount); + for (j = 0; j < charCount; j++) { + bytesStringTrimmed[j] = bytesString[j]; + } + return string(bytesStringTrimmed); + } +} \ No newline at end of file diff --git a/systemcontractv2/SystemProxy.sol b/systemcontractv2/SystemProxy.sol new file mode 100644 index 0000000000..dcc005af4e --- /dev/null +++ b/systemcontractv2/SystemProxy.sol @@ -0,0 +1,31 @@ +pragma solidity ^0.4.4; + +contract SystemProxy { + struct SystemContract { + address _addr; + bool _cache; + uint _blocknumber; + } + + mapping (string => SystemContract) private _routes; //路由表 + string[] _name; + + //mapping (address => string) private _names; + + //获取路由 + function getRoute(string key) public constant returns(address, bool,uint) { + return (_routes[key]._addr, _routes[key]._cache,_routes[key]._blocknumber); + } + + //设置路由 + function setRoute(string key, address addr, bool cache) public { + _routes[key] = SystemContract(addr, cache,block.number); + _name.push(key); + } + function getRouteNameByIndex(uint index) public constant returns(string){ + return _name[index]; + } + function getRouteSize() public constant returns(uint){ + return _name.length; + } +} \ No newline at end of file diff --git a/systemcontractv2/TransactionFilterBase.sol b/systemcontractv2/TransactionFilterBase.sol new file mode 100644 index 0000000000..8b5c4775fd --- /dev/null +++ b/systemcontractv2/TransactionFilterBase.sol @@ -0,0 +1,14 @@ +pragma solidity ^0.4.4; + +contract TransactionFilterBase { + string public name; + string public version; + function process(address origin, address from, address to, string func, string input) public constant returns(bool); + + function setName(string n) public constant { + name=n; + } + function setVersion(string v) public constant { + version=v; + } +} \ No newline at end of file diff --git a/systemcontractv2/TransactionFilterChain.sol b/systemcontractv2/TransactionFilterChain.sol new file mode 100644 index 0000000000..f5bce6855f --- /dev/null +++ b/systemcontractv2/TransactionFilterChain.sol @@ -0,0 +1,46 @@ +pragma solidity ^0.4.4; +import "TransactionFilterBase.sol"; + +contract TransactionFilterChain { + address[] private filters; //filters列表 + + function process(address origin, address from, address to, string func, string input) public constant returns(bool) { + for(var i=0; i/dev/null"); + console.log(filename+'编译成功!' ); + //console.log('编译成功!'); + } catch(e){ + console.log(filename+'编译失败!' + e); + } + +} + +(async function() { + + console.log("输出路径:"+config.Ouputpath); + await docompile("SystemProxy"); + await docompile("TransactionFilterChain"); + await docompile("AuthorityFilter"); + await docompile("Group"); + await docompile("CAAction"); + await docompile("NodeAction"); + await docompile("ConfigAction"); + + + +})(); diff --git a/systemcontractv2/config.js b/systemcontractv2/config.js new file mode 100644 index 0000000000..a7d93285dc --- /dev/null +++ b/systemcontractv2/config.js @@ -0,0 +1,14 @@ + +var proxy="http://127.0.0.1:6801"; + +console.log('RPC='+proxy); +var output="./output/"; +console.log('Ouputpath='+output); + +module.exports={ + HttpProvider:proxy, + Ouputpath:output, + privKey:"7d373eb4872368bb51d7ac083ac4752bca9ecb70066df43457500528faeea8f3", + account:"0xec23de21751378995fe87691f1c2e6c895cfa07b" +} + diff --git a/systemcontractv2/deploy.js b/systemcontractv2/deploy.js new file mode 100644 index 0000000000..d40d52b96a --- /dev/null +++ b/systemcontractv2/deploy.js @@ -0,0 +1,136 @@ +var Web3= require('web3'); +var config=require('./config'); +var fs=require('fs'); +var execSync =require('child_process').execSync; +var web3sync = require('./web3sync'); +var BigNumber = require('bignumber.js'); + +/* +* npm install --save-dev babel-cli babel-preset-es2017 +* echo '{ "presets": ["es2017"] }' > .babelrc +* npm install secp256k1 +* npm install keccak +* npm install rlp +*/ +if (typeof web3 !== 'undefined') { + web3 = new Web3(web3.currentProvider); +} else { + web3 = new Web3(new Web3.providers.HttpProvider(config.HttpProvider)); +} + +function getAbi(file){ + var abi=JSON.parse(fs.readFileSync(config.Ouputpath+"./"+file+".abi",'utf-8')); + return abi; +} + +(async function() { + //var account=web3.eth.accounts[0]; + + //console.log('account='+web3.eth.accounts[0]); + + + //部署合约,初始化参数 + var SystemProxyReicpt= await web3sync.rawDeploy(config.account, config.privKey, "SystemProxy"); + var SystemProxy=web3.eth.contract(getAbi("SystemProxy")).at(SystemProxyReicpt.contractAddress); + + var TransactionFilterChainReicpt= await web3sync.rawDeploy(config.account, config.privKey, "TransactionFilterChain"); + var TransactionFilterChain=web3.eth.contract(getAbi("TransactionFilterChain")).at(TransactionFilterChainReicpt.contractAddress); + + var AuthorityFilterReicpt= await web3sync.rawDeploy(config.account, config.privKey, "AuthorityFilter"); + var AuthorityFilter=web3.eth.contract(getAbi("AuthorityFilter")).at(AuthorityFilterReicpt.contractAddress); + + var FileInfoManagerReicept= await web3sync.rawDeploy(config.account, config.privKey, "FileInfoManager"); + var FileInfoManager=web3.eth.contract(getAbi("FileInfoManager")).at(FileInfoManagerReicept.contractAddress); + + var FileServerReicept= await web3sync.rawDeploy(config.account, config.privKey, "FileServerManager"); + var FileServerManager=web3.eth.contract(getAbi("FileServerManager")).at(FileServerReicept.contractAddress); + + var func = "setName(string)"; + var params = ["AuthorityFilter"]; + var receipt = await web3sync.sendRawTransaction(config.account, config.privKey, AuthorityFilter.address, func, params); + func = "setVersion(string)"; + params = ["1.0"]; + receipt = await web3sync.sendRawTransaction(config.account, config.privKey, AuthorityFilter.address, func, params); + console.log("AuthorityFilter版本号1.0"); + + var GroupReicpt= await web3sync.rawDeploy(config.account, config.privKey, "Group"); + var Group=web3.eth.contract(getAbi("Group")).at(GroupReicpt.contractAddress); + + var CAActionReicpt= await web3sync.rawDeploy(config.account, config.privKey, "CAAction"); + var CAAction=web3.eth.contract(getAbi("CAAction")).at(CAActionReicpt.contractAddress); + + var NodeActionReicpt= await web3sync.rawDeploy(config.account, config.privKey, "NodeAction"); + var NodeAction=web3.eth.contract(getAbi("NodeAction")).at(NodeActionReicpt.contractAddress); + + var ConfigActionReicpt= await web3sync.rawDeploy(config.account, config.privKey, "ConfigAction"); + var ConfigAction=web3.eth.contract(getAbi("ConfigAction")).at(ConfigActionReicpt.contractAddress); + + + + console.log("注册权限AuthorityFilter到TransactionFilterChain....."); + var func = "addFilter(address)"; + var params = [AuthorityFilter.address]; + var receipt = await web3sync.sendRawTransaction(config.account, config.privKey, TransactionFilterChain.address, func, params); + + + func = "setUserGroup(address,address)"; + params = [config.account, Group.address]; + receipt = await web3sync.sendRawTransaction(config.account, config.privKey, AuthorityFilter.address, func, params); + console.log("授予"+config.account+"角色"+Group.address); + + console.log("注册TransactionFilterChain....."); + func = "setRoute(string,address,bool)"; + params = ["TransactionFilterChain", TransactionFilterChain.address, false]; + receipt = await web3sync.sendRawTransaction(config.account, config.privKey, SystemProxy.address, func, params); + + console.log("注册ConfigAction....."); + func = "setRoute(string,address,bool)"; + params = ["ConfigAction", ConfigAction.address, false]; + receipt = await web3sync.sendRawTransaction(config.account, config.privKey, SystemProxy.address, func, params); + + console.log("注册NodeAction....."); + func = "setRoute(string,address,bool)"; + params = ["NodeAction", NodeAction.address, false]; + receipt = await web3sync.sendRawTransaction(config.account, config.privKey, SystemProxy.address, func, params); + + console.log("注册CAAction....."); + func = "setRoute(string,address,bool)"; + params = ["CAAction", CAAction.address, false]; + receipt = await web3sync.sendRawTransaction(config.account, config.privKey, SystemProxy.address, func, params); + + console.log("注册FileInfoManager....."); + func = "setRoute(string,address,bool)"; + params = ["FileInfoManager", FileInfoManager.address, false]; + receipt = await web3sync.sendRawTransaction(config.account, config.privKey, SystemProxy.address, func, params); + + console.log("注册FileServerManager....."); + func = "setRoute(string,address,bool)"; + params = ["FileServerManager", FileServerManager.address, false]; + receipt = await web3sync.sendRawTransaction(config.account, config.privKey, SystemProxy.address, func, params); + + console.log("合约部署完成 系统代理合约:" + SystemProxy.address); + //console.log(SystemProxy); + console.log("-----------------系统路由表----------------------") + var routelength=SystemProxy.getRouteSize(); + for( var i=0;i"+route[0].toString()+","+route[1].toString()+","+route[2].toString()); + + if( "TransactionFilterChain" == key ){ + var contract = web3.eth.contract(getAbi("TransactionFilterChain")); + var instance = contract.at(route[0]); + var filterlength=instance.getFiltersLength(); + for( var j=0;j"+version+","+filter); + } + } + } + + +})(); diff --git a/systemcontractv2/init_deploy.js b/systemcontractv2/init_deploy.js new file mode 100644 index 0000000000..699b0b0887 --- /dev/null +++ b/systemcontractv2/init_deploy.js @@ -0,0 +1,47 @@ +var Web3= require('web3'); +var config=require('./config_local'); +//var fs=require('fs'); +//var execSync =require('child_process').execSync; +//var BigNumber = require('bignumber.js'); +//var net = require('net'); +//var coder = require('./codeUtils'); +var web3sync = require('./web3sync'); + +if (typeof web3 !== 'undefined') { + web3 = new Web3(web3.currentProvider); +} else { + web3 = new Web3(new Web3.providers.HttpProvider(config.HttpProvider)); +} + +(async function() { + //部署合约,初始化参数 + var system_proxy = await web3sync.deploy(config.account, "SystemProxy"); + + var transaction_filter_chain = await web3sync.deploy(config.account, "TransactionFilterChain"); + var authority = await web3sync.deploy(config.account, "Authority"); + var group = await web3sync.deploy(config.account, "Group"); + + var ca_action = await web3sync.deploy(config.account, "CAAction"); + var node_action = await web3sync.deploy(config.account, "NodeAction"); + var config_action = await web3sync.deploy(config.account, "ConfigAction"); + + var test = await web3sync.deploy(config.account, "Test"); + + var func = "setRoute(string,address,bool)"; + var params = ["transactionFilterChain", transaction_filter_chain.address, false]; + var receipt = await web3sync.sendRawTransaction(config.account, config.privKey, group.address, func, params); + + func = "setRoute(string,address,bool)"; + params = ["CAAction", ca_action.address, false]; + receipt = await web3sync.sendRawTransaction(config.account, config.privKey, group.address, func, params); + + func = "setRoute(string,address,bool)"; + params = ["NodeAction", node_action.address, false]; + receipt = await web3sync.sendRawTransaction(config.account, config.privKey, group.address, func, params); + + func = "setRoute(string,address,bool)"; + params = ["ConfigAction", config_action.address, false]; + receipt = await web3sync.sendRawTransaction(config.account, config.privKey, group.address, func, params); + + console.log("合约部署完成 system_proxy:" + system_proxy.address); +})(); diff --git a/systemcontractv2/monitor.js b/systemcontractv2/monitor.js new file mode 100644 index 0000000000..b3c34e5591 --- /dev/null +++ b/systemcontractv2/monitor.js @@ -0,0 +1,65 @@ + +var Web3= require('web3'); +var config=require('./config'); +var fs=require('fs'); +var BigNumber = require('bignumber.js'); +var web3sync = require('./web3sync'); +var post=require('./post'); + +if (typeof web3 !== 'undefined') { + web3 = new Web3(web3.currentProvider); +} else { + web3 = new Web3(new Web3.providers.HttpProvider(config.HttpProvider)); +} + + + +async function getPeerCount() { + + return new Promise((resolve, reject) => { + web3.net.getPeerCount(function(e,d){ + resolve(d); + }); + }); +} + +async function sleep(timeout) { + return new Promise((resolve, reject) => { + setTimeout(function() { + resolve(); + }, timeout); + }); +} + +(async function() { + + + +while(1){ + console.log("已连接节点数:"+ await getPeerCount() ); + var peers=await post.post("admin_peers",[]); + try{ + peers=JSON.parse(peers); + for( var i=0;i=6.10.3", + "npm": ">=3.10.0" + } +} diff --git a/systemcontractv2/post.js b/systemcontractv2/post.js new file mode 100644 index 0000000000..5e5bb6b9b4 --- /dev/null +++ b/systemcontractv2/post.js @@ -0,0 +1,76 @@ + +var Web3= require('web3'); +var config=require('./config'); +var fs=require('fs'); +var BigNumber = require('bignumber.js'); +var web3sync = require('./web3sync'); + +if (typeof web3 !== 'undefined') { + web3 = new Web3(web3.currentProvider); +} else { + web3 = new Web3(new Web3.providers.HttpProvider(config.HttpProvider)); +} + + +var http = require('http'); + + + + + +async function post(method,params) { + + return new Promise((resolve, reject) => { + + //curl -X POST --data '{"jsonrpc":"2.0","method":"admin_peers","params":[],"id":74}' 127.0.0.1:8545 + var post_data = { + "jsonrpc":"2.0", + "method":method, + "params":params, + "id":74 + };//这是需要提交的数据 + + + var content = JSON.stringify(post_data); + + var options = { + hostname: config.HttpProvider.replace("http:\/\/","").replace(/:\d+/,''), + port: config.HttpProvider.replace(/http:.*:/,''), + path: '', + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' + } + }; + + var response=""; + var req = http.request(options, function (res) { + //console.log('STATUS: ' + res.statusCode); + //console.log('HEADERS: ' + JSON.stringify(res.headers)); + + res.setEncoding('utf8'); + res.on('data', function (chunk) { + //console.log('BODY: ' + chunk); + response+=chunk; + }); + res.on('end', function (chunk) { + + resolve(response); + }); + }); + + req.on('error', function (e) { + console.log('problem with request: ' + e.message); + }); + + // write data to request body + req.write(content); + + req.end(); + }); +} + + +exports.post=post; + + diff --git a/systemcontractv2/readme.txt b/systemcontractv2/readme.txt new file mode 100644 index 0000000000..5fdd18ffd2 --- /dev/null +++ b/systemcontractv2/readme.txt @@ -0,0 +1 @@ +npm install diff --git a/systemcontractv2/sha3.js b/systemcontractv2/sha3.js new file mode 100644 index 0000000000..03e86683e9 --- /dev/null +++ b/systemcontractv2/sha3.js @@ -0,0 +1,38 @@ +/* + This file is part of web3.js. + + web3.js is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + web3.js 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with web3.js. If not, see . +*/ +/** + * @file sha3.js + * @author Marek Kotewicz + * @date 2015 + */ + +var CryptoJS = require('crypto-js'); +var sha3 = require('crypto-js/sha3'); + +module.exports = function (value, options) { + if (options && options.encoding === 'hex') { + if (value.length > 2 && value.substr(0, 2) === '0x') { + value = value.substr(2); + } + value = CryptoJS.enc.Hex.parse(value); + } + + return sha3(value, { + outputLength: 256 + }).toString(); +}; + diff --git a/systemcontractv2/tool.js b/systemcontractv2/tool.js new file mode 100644 index 0000000000..0e10e03b74 --- /dev/null +++ b/systemcontractv2/tool.js @@ -0,0 +1,303 @@ + +var Web3= require('web3'); +var config=require('./config'); +var fs=require('fs'); +var BigNumber = require('bignumber.js'); +var web3sync = require('./web3sync'); + +if (typeof web3 !== 'undefined') { + web3 = new Web3(web3.currentProvider); +} else { + web3 = new Web3(new Web3.providers.HttpProvider(config.HttpProvider)); +} + +console.log(config); + + +function getAbi(file){ + var abi=JSON.parse(fs.readFileSync(config.Ouputpath+"./"+file+".sol:"+file+".abi",'utf-8')); + return abi; +} + +function getAddress(file){ + return (fs.readFileSync(config.Ouputpath+"./"+file+".address",'utf-8')); + +} + +var options = process.argv; +if( options.length < 3 ) +{ + console.log('Usage: node tool.js SystemProxy'); + console.log('Usage: node tool.js AuthorityFilter '); + + console.log('Usage: node tool.js NodeAction all|registerNode|cancelNode '); + console.log('Usage: node tool.js CAAction all|update|updateStatus '); + console.log('Usage: node tool.js ConfigAction get|set '); +} + +var filename=options[2]; + +var func=options[3]; +console.log('Soc File :'+options[2]); +console.log('Func :'+options[3]); + +console.log("系统合约地址"+getAddress("SystemProxy")); + +var initializer = {from: config.account,randomid:Math.ceil(Math.random()*100000000)}; + + +var SystemProxy=web3.eth.contract(getAbi("SystemProxy")).at(getAddress("SystemProxy")); + + + +function getAction(filename){ + var address=SystemProxy.getRoute(filename)[0].toString(); + console.log(filename+"合约地址"+address); + var contract = web3.eth.contract(getAbi(filename)); + return contract.at(address); + +} + + + +switch (filename){ + + case "ConfigAction": + { + switch(func){ + case "get": + { + if( options.length< 5 ){ + console.log("请输入key"); + break; + } + var key=options[4]; + var instance=getAction("ConfigAction"); + var value=instance.get(key, initializer); + console.log(key+"="+value[0].toString()+","+value[1].toString()); + + break; + } + case "set": + { + if( options.length< 6 ){ + console.log("请输入key,value"); + break; + } + var key=options[4]; + var value=options[5]; + + var instance=getAction("ConfigAction"); + + var func = "set(string,string)"; + var params = [key,value]; + var receipt = web3sync.sendRawTransaction(config.account, config.privKey, instance.address, func, params); + + console.log("配置项:"+key+","+value); + + break; + } + + default: + console.log("Mod Error"); + break; + } + break; + } + case "SystemProxy": + { + console.log("-----------------系统路由表----------------------") + + + + var routelength=SystemProxy.getRouteSize(); + for( var i=0;i"+route[0].toString()+","+route[1].toString()+","+route[2].toString()); + + if( "TransactionFilterChain" == key ){ + var contract = web3.eth.contract(getAbi("TransactionFilterChain")); + var instance = contract.at(route[0]); + var filterlength=instance.getFiltersLength(); + for( var j=0;j"+version+","+filter); + } + } + } + + + + break; + } + + case "AuthorityFilter": + { + if( options.length< 6 ){ + console.log("请输入账号、合约地址、函数名"); + break; + } + console.log("origin :"+options[3]); + console.log("to :"+options[4]); + console.log("func :"+options[5]); + + var AuthorityFilter=getAction("AuthorityFilter"); + //process(address origin, address from, address to, string func, string input) + + console.log("权限校验结果:"+AuthorityFilter.process(options[3],"",options[4],options[5],"")); + + break; + } + case "NodeAction": + { + switch(func){ + + case "all": + { + var instance=getAction("NodeAction"); + var len=instance.getNodeIdsLength(initializer); + console.log("NodeIdsLength= "+len); + for( var i=0;i= 0, 'number must be positive') + var hex = i.toString(16) + if (hex.length % 2) { + hex = '0' + hex + } + return '0x' + hex +} + +function setLength(msg, length, right) { + var buf = zeros(length) + msg = toBuffer(msg) + if (right) { + if (msg.length < length) { + msg.copy(buf) + return buf + } + return msg.slice(0, length) + } else { + if (msg.length < length) { + msg.copy(buf, length - msg.length) + return buf + } + return msg.slice(-length) + } +} + +function sha3(a, bits) { + a = toBuffer(a) + if (!bits) bits = 256 + return createKeccakHash('keccak' + bits).update(a).digest() +} + +function baToJSON(ba) { + if (Buffer.isBuffer(ba)) { + return '0x' + ba.toString('hex') + } else if (ba instanceof Array) { + var array = [] + for (var i = 0; i < ba.length; i++) { + array.push(baToJSON(ba[i])) + } + return array + } +} + +function zeros(bytes) { + return Buffer.allocUnsafe(bytes).fill(0) +} + +function stripZeros(a) { + a = stripHexPrefix(a) + var first = a[0] + while (a.length > 0 && first.toString() === '0') { + a = a.slice(1) + first = a[0] + } + return a +} + +function defineProperties(self, fields, data) { + self.raw = [] + self._fields = [] + + // attach the `toJSON` + self.toJSON = function (label) { + if (label) { + var obj = {} + self._fields.forEach(function (field) { + obj[field] = '0x' + self[field].toString('hex') + }) + return obj + } + return baToJSON(this.raw) + } + + self.serialize = function serialize () { + return rlp.encode(self.raw) + } + + fields.forEach(function (field, i) { + self._fields.push(field.name) + function getter () { + return self.raw[i] + } + function setter (v) { + v = toBuffer(v) + + if (v.toString('hex') === '00' && !field.allowZero) { + v = Buffer.allocUnsafe(0) + } + + if (field.allowLess && field.length) { + v = stripZeros(v) + assert(field.length >= v.length, 'The field ' + field.name + ' must not have more ' + field.length + ' bytes') + } else if (!(field.allowZero && v.length === 0) && field.length) { + assert(field.length === v.length, 'The field ' + field.name + ' must have byte length of ' + field.length) + } + + self.raw[i] = v + } + + Object.defineProperty(self, field.name, { + enumerable: true, + configurable: true, + get: getter, + set: setter + }) + + if (field.default) { + self[field.name] = field.default + } + + // attach alias + if (field.alias) { + Object.defineProperty(self, field.alias, { + enumerable: false, + configurable: true, + set: setter, + get: getter + }) + } + }) + + // if the constuctor is passed data + if (data) { + if (typeof data === 'string') { + data = Buffer.from(stripHexPrefix(data), 'hex') + } + + if (Buffer.isBuffer(data)) { + data = rlp.decode(data) + } + + if (Array.isArray(data)) { + if (data.length > self._fields.length) { + throw (new Error('wrong number of fields in data')) + } + + // make sure all the items are buffers + data.forEach(function (d, i) { + self[self._fields[i]] = toBuffer(d) + }) + } else if (typeof data === 'object') { + const keys = Object.keys(data) + fields.forEach(function (field) { + if (keys.indexOf(field.name) !== -1) self[field.name] = data[field.name] + if (keys.indexOf(field.alias) !== -1) self[field.alias] = data[field.alias] + }) + } else { + throw new Error('invalid data') + } + } +} + +function bufferToInt(buf) { + return new BN(toBuffer(buf)).toNumber() +} + +function rlphash(a) { + return sha3(rlp.encode(a)) +} + +function ecrecover(msgHash, v, r, s) { + var signature = Buffer.concat([setLength(r, 32), setLength(s, 32)], 64) + var recovery = v - 27 + if (recovery !== 0 && recovery !== 1) { + throw new Error('Invalid signature v value') + } + var senderPubKey = secp256k1.recover(msgHash, signature, recovery) + return secp256k1.publicKeyConvert(senderPubKey, false).slice(1) +} + +function ecsign(msgHash, privateKey) { + var sig = secp256k1.sign(msgHash, privateKey) + + var ret = {} + ret.r = sig.signature.slice(0, 32) + ret.s = sig.signature.slice(32, 64) + ret.v = sig.recovery + 27 + return ret +} + +//const BN = ethUtil.BN + +// secp256k1n/2 +const N_DIV_2 = new BN('7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0', 16) + +function Transaction(data) { + data = data || {} + // Define Properties + const fields = [{ + name: 'randomid', + length: 32, + allowLess: true, + default: new Buffer([]) + }, { + name: 'gasPrice', + length: 32, + allowLess: true, + default: new Buffer([]) + }, { + name: 'gasLimit', + alias: 'gas', + length: 32, + allowLess: true, + default: new Buffer([]) + }, { + name: 'blockLimit', + length: 32, + allowLess: true, + default: new Buffer([]) + },{ + name: 'to', + allowZero: true, + length: 20, + default: new Buffer([]) + }, { + name: 'value', + length: 32, + allowLess: true, + default: new Buffer([]) + }, { + name: 'data', + alias: 'input', + allowZero: true, + default: new Buffer([]) + }, { + name: 'v', + length: 1, + default: new Buffer([0x1c]) + }, { + name: 'r', + length: 32, + allowLess: true, + default: new Buffer([]) + }, { + name: 's', + length: 32, + allowLess: true, + default: new Buffer([]) + }] + + /** + * Returns the rlp encoding of the transaction + * @method serialize + * @return {Buffer} + */ + // attached serialize + defineProperties(this, fields, data) + + /** + * @prop {Buffer} from (read only) sender address of this transaction, mathematically derived from other parameters. + */ + Object.defineProperty(this, 'from', { + enumerable: true, + configurable: true, + get: this.getSenderAddress.bind(this) + }) + + // calculate chainId from signature + var sigV = bufferToInt(this.v) + var chainId = Math.floor((sigV - 35) / 2) + if (chainId < 0) chainId = 0 + + // set chainId + this._chainId = chainId || data.chainId || 0 + this._homestead = true + } + + /** + * If the tx's `to` is to the creation address + * @return {Boolean} + */ + Transaction.prototype.toCreationAddress=function () { + return this.to.toString('hex') === '' + } + + /** + * Computes a sha3-256 hash of the serialized tx + * @param {Boolean} [includeSignature=true] whether or not to inculde the signature + * @return {Buffer} + */ + Transaction.prototype.hash=function (includeSignature) { + if (includeSignature === undefined) includeSignature = true + // backup original signature + const rawCopy = this.raw.slice(0) + + // modify raw for signature generation only + if (this._chainId > 0) { + includeSignature = true + this.v = this._chainId + this.r = 0 + this.s = 0 + } + + // generate rlp params for hash + //console.log(this.raw.length) + var txRawForHash = includeSignature ? this.raw : this.raw.slice(0, this.raw.length - 3) + //var txRawForHash = includeSignature ? this.raw : this.raw.slice(0, 7) + + // restore original signature + this.raw = rawCopy.slice() + + // create hash + return rlphash(txRawForHash) + } + + /** + * returns the public key of the sender + * @return {Buffer} + */ + Transaction.prototype.getChainId=function() { + return this._chainId + } + + /** + * returns the sender's address + * @return {Buffer} + */ + Transaction.prototype.getSenderAddress = function() { + if (this._from) { + return this._from + } + const pubkey = this.getSenderPublicKey() + this._from = publicToAddress(pubkey) + return this._from + } + + /** + * returns the public key of the sender + * @return {Buffer} + */ + Transaction.prototype.getSenderPublicKey =function() { + if (!this._senderPubKey || !this._senderPubKey.length) { + if (!this.verifySignature()) throw new Error('Invalid Signature') + } + return this._senderPubKey + } + + /** + * Determines if the signature is valid + * @return {Boolean} + */ + Transaction.prototype.verifySignature =function() { + const msgHash = this.hash(false) + // All transaction signatures whose s-value is greater than secp256k1n/2 are considered invalid. + if (this._homestead && new BN(this.s).cmp(N_DIV_2) === 1) { + return false + } + + try { + var v = bufferToInt(this.v) + if (this._chainId > 0) { + v -= this._chainId * 2 + 8 + } + this._senderPubKey = ecrecover(msgHash, v, this.r, this.s) + } catch (e) { + return false + } + + return !!this._senderPubKey + } + + /** + * sign a transaction with a given a private key + * @param {Buffer} privateKey + */ + Transaction.prototype.sign =function(privateKey) { + const msgHash = this.hash(false) + const sig = ecsign(msgHash, privateKey) + if (this._chainId > 0) { + sig.v += this._chainId * 2 + 8 + } + Object.assign(this, sig) + } + + /** + * The amount of gas paid for the data in this tx + * @return {BN} + */ + Transaction.prototype.getDataFee=function() { + const data = this.raw[5] + const cost = new BN(0) + for (var i = 0; i < data.length; i++) { + data[i] === 0 ? cost.iaddn(fees.txDataZeroGas.v) : cost.iaddn(fees.txDataNonZeroGas.v) + } + return cost + } + + /** + * the minimum amount of gas the tx must have (DataFee + TxFee + Creation Fee) + * @return {BN} + */ + Transaction.prototype.getBaseFee =function() { + const fee = this.getDataFee().iaddn(fees.txGas.v) + if (this._homestead && this.toCreationAddress()) { + fee.iaddn(fees.txCreation.v) + } + return fee + } + + /** + * the up front amount that an account must have for this transaction to be valid + * @return {BN} + */ + Transaction.prototype.getUpfrontCost =function() { + return new BN(this.gasLimit) + .imul(new BN(this.gasPrice)) + .iadd(new BN(this.value)) + } + + /** + * validates the signature and checks to see if it has enough gas + * @param {Boolean} [stringError=false] whether to return a string with a dscription of why the validation failed or return a Bloolean + * @return {Boolean|String} + */ + Transaction.prototype.validate =function(stringError) { + const errors = [] + if (!this.verifySignature()) { + errors.push('Invalid Signature') + } + + if (this.getBaseFee().cmp(new BN(this.gasLimit)) > 0) { + errors.push([`gas limit is to low. Need at least ${this.getBaseFee()}`]) + } + + if (stringError === undefined || stringError === false) { + return errors.length === 0 + } else { + return errors.join(' ') + } + } + +//exports.Transaction=Transaction; + +function signTransaction(tx_data,privKey,callback) +{ + // convert string private key to a Buffer Object + var privateKey = new Buffer(privKey, 'hex'); + var tx = new Transaction(tx_data); + tx.sign(privateKey); + // Build a serialized hex version of the Tx + var serializedTx = '0x' + tx.serialize().toString('hex'); + if( null !== callback) + { + callback(serializedTx); + return ; + } + else + { + return serializedTx; + } +} + +//exports.signTransaction=signTransaction; + +/* +async function deploy(args,account, filename) { + try{ + execSync("solc --abi --bin -o " + config.Ouputpath + " " + filename + ".sol" + " &>/dev/null"); + + //console.log('编译成功!'); + } catch(e){ + console.log('编译失败!' + e); + } + + var abi=JSON.parse(fs.readFileSync(config.Ouputpath+filename+".sol:"+filename+'.abi', 'utf-8')); + var binary=fs.readFileSync(config.Ouputpath+filename+'.bin', 'utf-8'); + + var contract = web3.eth.contract(abi); + + var initializer = {from: account, data: binary}; + initializer.randomid=Math.ceil(Math.random()*100000000); + + return new Promise((resolve, reject) => { + var callback = function(e, contract){ + if(!e) { + if(!contract.address) { + //console.log("Contract transaction send: TransactionHash: " + contract.transactionHash + " waiting to be mined..."); + } else { + + + console.log(filename+"合约地址 "+contract.address); + + addressjson[filename]= contract.address; + fs.writeFileSync(config.Ouputpath+'address.json', JSON.stringify(addressjson), 'utf-8'); + var deployfilename=filename+'.deploy.js'; + fs.writeFileSync(config.Ouputpath+filename+'.deploy', JSON.stringify({"address":contract.address,"abi":contract.abi}), 'utf-8'); + + var now2=new Date(); + var endtime=now2.getTime(); + + resolve(contract); + } + } + else + { + console.log("Has Error"+e); + } + }; + + var now=new Date(); + var starttime=now.getTime(); + + //部署到网络 + var newcontract=contract.new; + //部署到网络 + //var token = contract.new(args,initializer, callback); + args.push(initializer); + args.push(callback); + var token = newcontract.apply(contract,args); + + }); +}*/ + +async function getBlockNumber() { + + return new Promise((resolve, reject) => { + web3.eth.getBlockNumber(function(e,d){ + //console.log(e+',blocknumber='+d); + resolve(d); + }); + }); +} + +function checkForTransactionResult(hash, callback){ + var count = 0, + callbackFired = false; + + // wait for receipt + //var filter = contract._eth.filter('latest', function(e){ + var filter = web3.eth.filter('latest', function(e){ + if (!e && !callbackFired) { + count++; + + // stop watching after 50 blocks (timeout) + if (count > 50) { + filter.stopWatching(function() {}); + callbackFired = true; + + if (callback) { + callback(new Error('Contract transaction couldn\'t be found after 50 blocks')); + } else { + throw new Error('Contract transaction couldn\'t be found after 50 blocks'); + } + } else { + web3.eth.getTransactionReceipt(hash, function(e, receipt){ + if(receipt && !callbackFired) { + //console.log(receipt); + callback(null, receipt); + filter.stopWatching(function() {}); + } + }); + } + } + }); +}; + +async function unlockAccount(account, password) { + return new Promise((resolve, reject) => { + web3.personal.unlockAccount(account,"123",1,function(err,data){ + resolve(data); + }) + }); +} +async function rawDeploy(account, privateKey,filename) { + + var binary=fs.readFileSync(config.Ouputpath+"./"+filename+".bin",'utf-8'); + + var postdata = { + input: "0x"+binary, + from: account, + to: null, + gas: 100000000, + randomid:Math.ceil(Math.random()*100000000), + blockLimit:await getBlockNumber() + 1000, + } + + var signTX = signTransaction(postdata, privateKey, null); + + return new Promise((resolve, reject) => { + web3.eth.sendRawTransaction(signTX, function(err, address) { + if (!err) { + //console.log("发送交易成功: " + address); + + checkForTransactionResult(address, (err, receipt) => { + var addressjson={}; + if( receipt.contractAddress ){ + + + console.log(filename+"合约地址 "+receipt.contractAddress); + fs.writeFileSync(config.Ouputpath+filename+'.address', receipt.contractAddress, 'utf-8'); + + }//if + + + resolve(receipt); + return; + }); + + return; + } + else { + console.log("发送交易失败!",err); + + return; + } + }); + }); +} + + + +async function sendRawTransaction(account, privateKey, to, func, params) { + var r = /^\w+\((.+)\)$/g.exec(func); + var types = r[1].split(','); + + var tx_data = coder.codeTxData(func,types,params); + + var postdata = { + data: tx_data, + from: account, + to: to, + gas: 1000000, + randomid:Math.ceil(Math.random()*100000000), + blockLimit:await getBlockNumber() + 1000, + } + + var signTX = signTransaction(postdata, privateKey, null); + + return new Promise((resolve, reject) => { + web3.eth.sendRawTransaction(signTX, function(err, address) { + if (!err) { + console.log("发送交易成功: " + address); + + checkForTransactionResult(address, (err, receipt) => { + resolve(receipt); + }); + + //resolve(address); + } + else { + console.log("发送交易失败!",err); + + return; + } + }); + }); +} + +exports.getBlockNumber=getBlockNumber; +exports.sendRawTransaction=sendRawTransaction; +exports.unlockAccount=unlockAccount; +exports.rawDeploy=rawDeploy; +//exports.deploy=deploy; diff --git a/tool/.babelrc b/tool/.babelrc new file mode 100644 index 0000000000..335376b678 --- /dev/null +++ b/tool/.babelrc @@ -0,0 +1 @@ +{ "presets": ["es2017"] } diff --git a/tool/HelloWorld.sol b/tool/HelloWorld.sol new file mode 100644 index 0000000000..653e754f9c --- /dev/null +++ b/tool/HelloWorld.sol @@ -0,0 +1,12 @@ +contract HelloWorld{ + string name; + function HelloWorld(){ + name="Hi,Welcome!"; + } + function get()constant returns(string){ + return name; + } + function set(string n){ + name=n; + } +} \ No newline at end of file diff --git a/tool/Ok.sol b/tool/Ok.sol new file mode 100644 index 0000000000..6843881a83 --- /dev/null +++ b/tool/Ok.sol @@ -0,0 +1,39 @@ +contract Ok{ + + struct Account{ + address account; + uint balance; + } + + struct Translog { + string time; + address from; + address to; + uint amount; + } + + Account from; + Account to; + + Translog[] log; + + function Ok(){ + from.account=0x1; + from.balance=10000000000; + to.account=0x2; + to.balance=0; + + } + function get()constant returns(uint){ + return to.balance; + } + function trans(uint num){ + from.balance=from.balance-num; + to.balance+=num; + + log.push(Translog("20170413",from.account,to.account,num)); + } + + + +} \ No newline at end of file diff --git a/tool/TestPaillier.sol b/tool/TestPaillier.sol new file mode 100644 index 0000000000..1aa17edae1 --- /dev/null +++ b/tool/TestPaillier.sol @@ -0,0 +1,14 @@ +pragma solidity ^0.4.2; + +import "LibPaillier.sol"; + +contract TestPaillier { + + function add(string d1, string d2) public constant returns (string) { + return LibPaillier.pai_add(d1, d2); + } + + function put() public constant returns (string) { + return "Hellp"; + } +} diff --git a/tool/Testout.sol b/tool/Testout.sol new file mode 100644 index 0000000000..4892b07cb5 --- /dev/null +++ b/tool/Testout.sol @@ -0,0 +1,13 @@ +contract Testout { + string data; + function put() public constant returns (string ret) { + ret = "hello"; + } + function test() public constant returns (string _ret) { + _ret = data; + } + function write(string _data) { + data = _data; + } + +} diff --git a/tool/ViewChangeCheck.js b/tool/ViewChangeCheck.js new file mode 100644 index 0000000000..f7ff48f1e8 --- /dev/null +++ b/tool/ViewChangeCheck.js @@ -0,0 +1,84 @@ + +var Web3= require('web3'); +var config=require('./config'); +var fs=require('fs'); +var BigNumber = require('bignumber.js'); + + +var web3sync = require('./web3sync'); + +if (typeof web3 !== 'undefined') { + web3 = new Web3(web3.currentProvider); +} else { + web3 = new Web3(new Web3.providers.HttpProvider(config.HttpProvider)); +} + +console.log(config); + +console.log('ViewChangeCheck.js ........................Start........................'); + + +async function sleep(timeout) { + return new Promise((resolve, reject) => { + setTimeout(function() { + resolve(); + }, timeout); + }); +} + + +var account=config.account;//web3.eth.accounts[0]; + +(async function() { + var start=1119000; + + + var end=await web3sync.getBlockNumber(); + console.log('start='+start+',end blocknumber='+end); + var lasttime=0; + var two=0; + var three=0; + var four=0; + var sum=end-start; + + for(var i=start;i 2000 && diff <3000){ + console.log("出块超过2s "+i); + two++; + } + else if( diff > 3000 && diff <4000){ + console.log("出块超过3s "+i); + three++; + } + else if( diff > 4000) { + console.log("出块超过4s "+i); + four++; + } + } + lasttime=block.timestamp; + } + console.log("出块超过2s :"+((two*100)/sum).toFixed(2)+"%"); + console.log("出块超过3s :"+((three*100)/sum).toFixed(2)+"%"); + console.log("出块超过4s :"+((four*100)/sum).toFixed(2)+"%"); + + + + + + +})(); + + + + + + + diff --git a/tool/accountCheck.js b/tool/accountCheck.js new file mode 100644 index 0000000000..f2d87ba0a8 --- /dev/null +++ b/tool/accountCheck.js @@ -0,0 +1,19 @@ +var crypto = require('crypto') +var utils = require('./utils.js') + +function newAccount(pwd) +{ + var pKey ="ee57ab3dd1db856a4e97c89030786b87775996489ef019472f545245320206e7"; + var privKey =new Buffer(pKey, 'hex'); + var pubKey = utils.privateToPublic(privKey); + var address = utils.privateToAddress(privKey); + var str_pri = '0x' + privKey.toString('hex'); + var str_pub = '0x' + pubKey.toString('hex'); + var str_addr = '0x' + address.toString('hex'); + console.log("privKey : ",privKey," - " , str_pri," | pubKey : " ,pubKey," - ", str_pub," | address : ",address," - ",str_addr); +} + +newAccount(123); + + + diff --git a/tool/accountManager.js b/tool/accountManager.js new file mode 100644 index 0000000000..eccc1658ec --- /dev/null +++ b/tool/accountManager.js @@ -0,0 +1,19 @@ +var crypto = require('crypto') +var utils = require('./utils.js') + +function newAccount(pwd) +{ + var privKey = crypto.randomBytes(32); + var pubKey = utils.privateToPublic(privKey); + var address = utils.privateToAddress(privKey); + var str_pri = '0x' + privKey.toString('hex'); + var str_pub = '0x' + pubKey.toString('hex'); + var str_addr = '0x' + address.toString('hex'); + //console.log("privKey : ",privKey," - " , str_pri," \n pubKey : " ,pubKey," - ", str_pub," \n address : ",address," - ",str_addr); + console.log("privKey : "+ str_pri+"\npubKey : " + str_pub+"\naddress : "+str_addr); +} + +newAccount(); + + + diff --git a/tool/codeUtils.js b/tool/codeUtils.js new file mode 100644 index 0000000000..9daa8d7ccf --- /dev/null +++ b/tool/codeUtils.js @@ -0,0 +1,50 @@ +/* +编码工具类,包含交易编码及日志编码 +*/ +var Web3 = require('web3'); +var sha3 = require("./sha3") +var Event = require('web3/lib/web3/event'); +var Coder = require('web3/lib/solidity/coder'); + +/* +#交易编码 +###参数编码 +*/ +function codeParams(types,params) +{ + var code_ret = Coder.encodeParams(types, params); + //console.log("code_ret : ",code_ret); + return code_ret; +} + +/* +###函数名编码 +*/ +function codeFun(fun_str) +{ + + var code_fun = '0x' + sha3(fun_str).slice(0, 8); + //console.log("code_fun : ",code_fun); + return code_fun; +} + +/* +###交易数据编码 +*/ +function codeTxData(fun_Str,types,params) +{ + var txData_code = codeFun(fun_Str); + txData_code += codeParams(types,params); + //console.log("txData_code : ",txData_code); + return txData_code; +} + +/* +var test_fun="SetAuth(string,string)"; +var types=['string','string']; +var params=['123','abc']; +codeTxData(test_fun,types,params); +*/ + + +exports.codeTxData=codeTxData; \ No newline at end of file diff --git a/tool/config.js b/tool/config.js new file mode 100644 index 0000000000..bb1f2adbfb --- /dev/null +++ b/tool/config.js @@ -0,0 +1,17 @@ + + + + +var proxy="http://127.0.0.1:6801"; + + +console.log('RPC='+proxy); +var output="./output/"; +console.log('Ouputpath='+output); + +module.exports={ + HttpProvider:proxy, + Ouputpath:output, + privKey:"7d373eb4872368bb51d7ac083ac4752bca9ecb70066df43457500528faeea8f3", + account:"ec23de21751378995fe87691f1c2e6c895cfa07b" +} diff --git a/tool/demoHelloWorld.js b/tool/demoHelloWorld.js new file mode 100644 index 0000000000..3e4dded624 --- /dev/null +++ b/tool/demoHelloWorld.js @@ -0,0 +1,55 @@ + +var Web3= require('web3'); +var config=require('./config'); +var fs=require('fs'); +var execSync =require('child_process').execSync; +var web3sync = require('./web3sync'); +var BigNumber = require('bignumber.js'); + + +if (typeof web3 !== 'undefined') { + web3 = new Web3(web3.currentProvider); +} else { + web3 = new Web3(new Web3.providers.HttpProvider(config.HttpProvider)); +} + +console.log(config); + + + + +var filename="HelloWorld"; + + + + +var address=fs.readFileSync(config.Ouputpath+filename+'.address','utf-8'); +var abi=JSON.parse(fs.readFileSync(config.Ouputpath/*+filename+".sol:"*/+filename+'.abi', 'utf-8')); +var contract = web3.eth.contract(abi); +var instance = contract.at(address); + + + +console.log(filename+"合约address:"+address); + + + +(async function(){ + + var name=instance.get(); + console.log("接口调用前读取接口返回:"+name.toString()); + + var func = "set(string)"; + var params = ["HelloWorld!"]; + var receipt = await web3sync.sendRawTransaction(config.account, config.privKey, address, func, params); + + + + console.log("调用更新接口设置name=\"HelloWorld\""+'(交易哈希:'+receipt.transactionHash+')'); + + name=instance.get(); + console.log("接口调用后读取接口返回:"+name.toString()); + + + +})() \ No newline at end of file diff --git a/tool/demoOk.js b/tool/demoOk.js new file mode 100644 index 0000000000..091b0f0df4 --- /dev/null +++ b/tool/demoOk.js @@ -0,0 +1,49 @@ + +var Web3= require('web3'); +var config=require('./config'); +var fs=require('fs'); +var execSync =require('child_process').execSync; +var web3sync = require('./web3sync'); +var BigNumber = require('bignumber.js'); + + +if (typeof web3 !== 'undefined') { + web3 = new Web3(web3.currentProvider); +} else { + web3 = new Web3(new Web3.providers.HttpProvider(config.HttpProvider)); +} + +console.log(config); + + + + +var filename="Ok"; + + + + +var address=fs.readFileSync(config.Ouputpath+filename+'.address','utf-8'); +var abi=JSON.parse(fs.readFileSync(config.Ouputpath/*+filename+".sol:"*/+filename+'.abi', 'utf-8')); +var contract = web3.eth.contract(abi); +var instance = contract.at(address); + + + +console.log("合约address:"+address); + + + +(async function(){ + + var func = "trans(uint256)"; + var params = [15]; + var receipt = await web3sync.sendRawTransaction(config.account, config.privKey, address, func, params); + console.log(receipt); + + var num=instance.get(); + console.log("num="+num.toString()); + + + +})() \ No newline at end of file diff --git a/tool/demoTestPaillie.js b/tool/demoTestPaillie.js new file mode 100644 index 0000000000..ba1a8e3752 --- /dev/null +++ b/tool/demoTestPaillie.js @@ -0,0 +1,63 @@ + +var Web3= require('web3'); +var config=require('./config'); +var fs=require('fs'); +var execSync =require('child_process').execSync; +var web3sync = require('./web3sync'); +var BigNumber = require('bignumber.js'); + + +if (typeof web3 !== 'undefined') { + web3 = new Web3(web3.currentProvider); +} else { + web3 = new Web3(new Web3.providers.HttpProvider(config.HttpProvider)); +} + +console.log(config); + +var filename="TestPaillier"; +var address=fs.readFileSync(config.Ouputpath+filename+'.address','utf-8'); +var abi=JSON.parse(fs.readFileSync(config.Ouputpath/*+filename+".sol:"*/+filename+'.abi', 'utf-8')); +var paillierjson = fs.readFileSync('./java/Pailler/paillier.json', 'utf-8'); +var paillie=JSON.parse(fs.readFileSync('./java/Pailler/paillier.json', 'utf-8')); +var contract = web3.eth.contract(abi); +var instance = contract.at(address); + +async function sleep(timeout) { + return new Promise((resolve, reject) => { + setTimeout(function() { + resolve(); + }, timeout); + }); +} + +(async function(){ + var put=instance.put(); + console.log("put="+put); + + var testsucceed = 0; + var testerr = 0; + + for(var key in paillie){ + //console.log("test begin paillie = ", paillie[key]); + + var c1 = paillie[key].c1; + var c2 = paillie[key].c2; + var c3 = paillie[key].c3; + + var o1 = paillie[key].o1; + var o2 = paillie[key].o2; + var o3 = paillie[key].o3; + + var result = instance.add(c1, c2); + if(c3 === result){ + testsucceed++; + console.log("test succeed key=", key, ",length=", Object.keys(paillie).length, ",o1=", o1, ",o2=", o2, ",o3=", o3); + }else{ + testerr++; + console.log("result=", result, ",c3=", c3, ",c1=", c1, ",c2=", c2); + } + } + + console.log("testsucceed=", testsucceed, ",testerr=", testerr, ",length=", Object.keys(paillie).length); +})() diff --git a/tool/demoTestout.js b/tool/demoTestout.js new file mode 100644 index 0000000000..fb6786ef0b --- /dev/null +++ b/tool/demoTestout.js @@ -0,0 +1,71 @@ + +var Web3= require('web3'); +var config=require('./config'); +var fs=require('fs'); +var execSync =require('child_process').execSync; +var web3sync = require('./web3sync'); +var BigNumber = require('bignumber.js'); + + +if (typeof web3 !== 'undefined') { + web3 = new Web3(web3.currentProvider); +} else { + web3 = new Web3(new Web3.providers.HttpProvider(config.HttpProvider)); +} + +console.log(config); + + + + +var filename="Testout"; + + + + +var address=fs.readFileSync(config.Ouputpath+filename+'.address','utf-8'); +var abi=JSON.parse(fs.readFileSync(config.Ouputpath/*+filename+".sol:"*/+filename+'.abi', 'utf-8')); +var contract = web3.eth.contract(abi); +var instance = contract.at(address); + + + +console.log(filename+"合约address:"+address); + +async function sleep(timeout) { + return new Promise((resolve, reject) => { + setTimeout(function() { + resolve(); + }, timeout); + }); +} + +(async function(){ + +var i=0; +//while(true) +{ + sleep(1000); + + /* + var name=instance.test(); + console.log("接口调用前读取接口返回:"+name.toString()); + i++; + var func = "write(string)"; + var params = ["HelloWorld!"+i]; + var receipt = await web3sync.sendRawTransaction(config.account, config.privKey, address, func, params); + + + + console.log("调用更新接口设置name=\"HelloWorld\""+'(交易哈希:'+receipt.transactionHash+')'); +*/ + //var name=instance.test(); + var put=instance.put(); + console.log("put="+put); + //console.log("接口调用后读取接口返回:"+name.toString()); + +} + + + +})() diff --git a/tool/deploy.js b/tool/deploy.js new file mode 100644 index 0000000000..15b5546ddb --- /dev/null +++ b/tool/deploy.js @@ -0,0 +1,48 @@ +var Web3= require('web3'); +var config=require('./config'); +var fs=require('fs'); +var execSync =require('child_process').execSync; +var web3sync = require('./web3sync'); + +if (typeof web3 !== 'undefined') { + web3 = new Web3(web3.currentProvider); +} else { + web3 = new Web3(new Web3.providers.HttpProvider(config.HttpProvider)); +} + + +console.log('deploy.js ........................Start........................'); + +// 1 读取文件参数 +var options = process.argv; +if( options.length < 3 ) +{ + console.log('Usage: node deplay.js xxx.soc '); + +} + + +var filename=options[2]; +console.log('Soc File :'+filename); + + +try{ + execSync("solc --abi --bin --overwrite -o "+config.Ouputpath+" "+filename+".sol"); + + console.log(filename+'编译成功!'); +}catch(e){ + + console.log(filename+'编译失败!'+e); +} + +var abi=JSON.parse(fs.readFileSync(config.Ouputpath/*+filename+".sol:"*/+filename+'.abi', 'utf-8')); +var binary=fs.readFileSync(config.Ouputpath+filename+'.bin', 'utf-8'); + +(async function() { + + var Contract= await web3sync.rawDeploy(config.account, config.privKey, filename); + console.log(filename+"部署成功!") + +})(); + + \ No newline at end of file diff --git a/tool/java/DfsSDK/.classpath b/tool/java/DfsSDK/.classpath new file mode 100644 index 0000000000..a0fbe6294c --- /dev/null +++ b/tool/java/DfsSDK/.classpath @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tool/java/DfsSDK/.project b/tool/java/DfsSDK/.project new file mode 100644 index 0000000000..0c3b3bf0a2 --- /dev/null +++ b/tool/java/DfsSDK/.project @@ -0,0 +1,17 @@ + + + DfsSDK + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/tool/java/DfsSDK/.settings/org.eclipse.core.resources.prefs b/tool/java/DfsSDK/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000000..4824b80263 --- /dev/null +++ b/tool/java/DfsSDK/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/tool/java/DfsSDK/.settings/org.eclipse.jdt.core.prefs b/tool/java/DfsSDK/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000000..bb35fa0a87 --- /dev/null +++ b/tool/java/DfsSDK/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,11 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/tool/java/DfsSDK/lib/asm-5.0.3.jar b/tool/java/DfsSDK/lib/asm-5.0.3.jar new file mode 100644 index 0000000000..573535b1d5 Binary files /dev/null and b/tool/java/DfsSDK/lib/asm-5.0.3.jar differ diff --git a/tool/java/DfsSDK/lib/asm-analysis-5.0.3.jar b/tool/java/DfsSDK/lib/asm-analysis-5.0.3.jar new file mode 100644 index 0000000000..8b73cf09d7 Binary files /dev/null and b/tool/java/DfsSDK/lib/asm-analysis-5.0.3.jar differ diff --git a/tool/java/DfsSDK/lib/asm-commons-5.0.3.jar b/tool/java/DfsSDK/lib/asm-commons-5.0.3.jar new file mode 100644 index 0000000000..514a6dc2e1 Binary files /dev/null and b/tool/java/DfsSDK/lib/asm-commons-5.0.3.jar differ diff --git a/tool/java/DfsSDK/lib/asm-tree-5.0.3.jar b/tool/java/DfsSDK/lib/asm-tree-5.0.3.jar new file mode 100644 index 0000000000..e7eae53576 Binary files /dev/null and b/tool/java/DfsSDK/lib/asm-tree-5.0.3.jar differ diff --git a/tool/java/DfsSDK/lib/asm-util-5.0.3.jar b/tool/java/DfsSDK/lib/asm-util-5.0.3.jar new file mode 100644 index 0000000000..e89f1b7b67 Binary files /dev/null and b/tool/java/DfsSDK/lib/asm-util-5.0.3.jar differ diff --git a/tool/java/DfsSDK/lib/bcprov-jdk15on-1.54.jar b/tool/java/DfsSDK/lib/bcprov-jdk15on-1.54.jar new file mode 100644 index 0000000000..bd95185ae8 Binary files /dev/null and b/tool/java/DfsSDK/lib/bcprov-jdk15on-1.54.jar differ diff --git a/tool/java/DfsSDK/lib/commons-codec-1.9.jar b/tool/java/DfsSDK/lib/commons-codec-1.9.jar new file mode 100644 index 0000000000..ef35f1c50d Binary files /dev/null and b/tool/java/DfsSDK/lib/commons-codec-1.9.jar differ diff --git a/tool/java/DfsSDK/lib/commons-io-2.5.jar b/tool/java/DfsSDK/lib/commons-io-2.5.jar new file mode 100644 index 0000000000..1234918271 Binary files /dev/null and b/tool/java/DfsSDK/lib/commons-io-2.5.jar differ diff --git a/tool/java/DfsSDK/lib/commons-logging-1.2.jar b/tool/java/DfsSDK/lib/commons-logging-1.2.jar new file mode 100644 index 0000000000..93a3b9f6db Binary files /dev/null and b/tool/java/DfsSDK/lib/commons-logging-1.2.jar differ diff --git a/tool/java/DfsSDK/lib/fastjson-1.2.24.jar b/tool/java/DfsSDK/lib/fastjson-1.2.24.jar new file mode 100644 index 0000000000..4a6652fb5a Binary files /dev/null and b/tool/java/DfsSDK/lib/fastjson-1.2.24.jar differ diff --git a/tool/java/DfsSDK/lib/httpclient-4.5.2.jar b/tool/java/DfsSDK/lib/httpclient-4.5.2.jar new file mode 100644 index 0000000000..701609fcc8 Binary files /dev/null and b/tool/java/DfsSDK/lib/httpclient-4.5.2.jar differ diff --git a/tool/java/DfsSDK/lib/httpcore-4.4.4.jar b/tool/java/DfsSDK/lib/httpcore-4.4.4.jar new file mode 100644 index 0000000000..ac4a877302 Binary files /dev/null and b/tool/java/DfsSDK/lib/httpcore-4.4.4.jar differ diff --git a/tool/java/DfsSDK/lib/httpmime-4.3.1.jar b/tool/java/DfsSDK/lib/httpmime-4.3.1.jar new file mode 100644 index 0000000000..2b26d7a79c Binary files /dev/null and b/tool/java/DfsSDK/lib/httpmime-4.3.1.jar differ diff --git a/tool/java/DfsSDK/lib/jackson-annotations-2.8.0.jar b/tool/java/DfsSDK/lib/jackson-annotations-2.8.0.jar new file mode 100644 index 0000000000..d19b67b0f1 Binary files /dev/null and b/tool/java/DfsSDK/lib/jackson-annotations-2.8.0.jar differ diff --git a/tool/java/DfsSDK/lib/jackson-core-2.8.5.jar b/tool/java/DfsSDK/lib/jackson-core-2.8.5.jar new file mode 100644 index 0000000000..05e1be2922 Binary files /dev/null and b/tool/java/DfsSDK/lib/jackson-core-2.8.5.jar differ diff --git a/tool/java/DfsSDK/lib/jackson-databind-2.8.5.jar b/tool/java/DfsSDK/lib/jackson-databind-2.8.5.jar new file mode 100644 index 0000000000..2794824673 Binary files /dev/null and b/tool/java/DfsSDK/lib/jackson-databind-2.8.5.jar differ diff --git a/tool/java/DfsSDK/lib/javapoet-1.7.0.jar b/tool/java/DfsSDK/lib/javapoet-1.7.0.jar new file mode 100644 index 0000000000..207af05755 Binary files /dev/null and b/tool/java/DfsSDK/lib/javapoet-1.7.0.jar differ diff --git a/tool/java/DfsSDK/lib/jffi-1.2.14-native.jar b/tool/java/DfsSDK/lib/jffi-1.2.14-native.jar new file mode 100644 index 0000000000..3ba318dc20 Binary files /dev/null and b/tool/java/DfsSDK/lib/jffi-1.2.14-native.jar differ diff --git a/tool/java/DfsSDK/lib/jffi-1.2.14.jar b/tool/java/DfsSDK/lib/jffi-1.2.14.jar new file mode 100644 index 0000000000..b912ebc22b Binary files /dev/null and b/tool/java/DfsSDK/lib/jffi-1.2.14.jar differ diff --git a/tool/java/DfsSDK/lib/jnr-constants-0.9.6.jar b/tool/java/DfsSDK/lib/jnr-constants-0.9.6.jar new file mode 100644 index 0000000000..751de97ae7 Binary files /dev/null and b/tool/java/DfsSDK/lib/jnr-constants-0.9.6.jar differ diff --git a/tool/java/DfsSDK/lib/jnr-enxio-0.14.jar b/tool/java/DfsSDK/lib/jnr-enxio-0.14.jar new file mode 100644 index 0000000000..95bc904056 Binary files /dev/null and b/tool/java/DfsSDK/lib/jnr-enxio-0.14.jar differ diff --git a/tool/java/DfsSDK/lib/jnr-ffi-2.1.2.jar b/tool/java/DfsSDK/lib/jnr-ffi-2.1.2.jar new file mode 100644 index 0000000000..576db97f6c Binary files /dev/null and b/tool/java/DfsSDK/lib/jnr-ffi-2.1.2.jar differ diff --git a/tool/java/DfsSDK/lib/jnr-posix-3.0.33.jar b/tool/java/DfsSDK/lib/jnr-posix-3.0.33.jar new file mode 100644 index 0000000000..50ca448984 Binary files /dev/null and b/tool/java/DfsSDK/lib/jnr-posix-3.0.33.jar differ diff --git a/tool/java/DfsSDK/lib/jnr-unixsocket-0.15.jar b/tool/java/DfsSDK/lib/jnr-unixsocket-0.15.jar new file mode 100644 index 0000000000..91eca2c10f Binary files /dev/null and b/tool/java/DfsSDK/lib/jnr-unixsocket-0.15.jar differ diff --git a/tool/java/DfsSDK/lib/jnr-x86asm-1.0.2.jar b/tool/java/DfsSDK/lib/jnr-x86asm-1.0.2.jar new file mode 100644 index 0000000000..dd4e695f3b Binary files /dev/null and b/tool/java/DfsSDK/lib/jnr-x86asm-1.0.2.jar differ diff --git a/tool/java/DfsSDK/lib/rxjava-1.2.4.jar b/tool/java/DfsSDK/lib/rxjava-1.2.4.jar new file mode 100644 index 0000000000..c8961dbf60 Binary files /dev/null and b/tool/java/DfsSDK/lib/rxjava-1.2.4.jar differ diff --git a/tool/java/DfsSDK/lib/scrypt-1.4.0.jar b/tool/java/DfsSDK/lib/scrypt-1.4.0.jar new file mode 100644 index 0000000000..7ebd8dee0d Binary files /dev/null and b/tool/java/DfsSDK/lib/scrypt-1.4.0.jar differ diff --git a/tool/java/DfsSDK/lib/web3j-2.1.0_main.jar b/tool/java/DfsSDK/lib/web3j-2.1.0_main.jar new file mode 100644 index 0000000000..3ac1b696d4 Binary files /dev/null and b/tool/java/DfsSDK/lib/web3j-2.1.0_main.jar differ diff --git a/tool/java/DfsSDK/src/com/dfs/entity/DataJson.java b/tool/java/DfsSDK/src/com/dfs/entity/DataJson.java new file mode 100644 index 0000000000..c5036d22f5 --- /dev/null +++ b/tool/java/DfsSDK/src/com/dfs/entity/DataJson.java @@ -0,0 +1,28 @@ +package com.dfs.entity; + +import com.alibaba.fastjson.JSONObject; + +/** + * Created by yanze on 2016/12/15. + */ +public class DataJson { + + private long total; + private JSONObject[] items; + + public JSONObject[] getItems() { + return items; + } + + public void setItems(JSONObject[] items) { + this.items = items; + } + + public long getTotal() { + return total; + } + + public void setTotal(long total) { + this.total = total; + } +} diff --git a/tool/java/DfsSDK/src/com/dfs/entity/DfsConst.java b/tool/java/DfsSDK/src/com/dfs/entity/DfsConst.java new file mode 100644 index 0000000000..ec68ab07fa --- /dev/null +++ b/tool/java/DfsSDK/src/com/dfs/entity/DfsConst.java @@ -0,0 +1,37 @@ +/** + * @Title: JuError.java + + * @date: 2017年3月7日 上午10:25:51 + + * @version: V1.0 + + */ +package com.dfs.entity; + + +/** + * @author Administrator + * + */ +public class DfsConst { + public static final String HTTP_STARTER = "http://"; + public static final int HTTP_JSONRPC_PORT_DEFAULT = 6789; + public static final String HTTP_FS_MODULE = "fs"; + public static final String HTTP_FS_VERSION = "v1"; + public static final String HTTP_FS_CONTAINER_ID_DEFAULT = "files"; + + public static final int JU_REQUEST_TIMEOUT = 10; + //error + public static final int DFS_ERROR_OK = 0; + public static final int DFS_ERROR_BAD = -1; + + public static final int DFS_ERROR_SUCCESS = 200; + public static final int DFS_ERROR_FAIL = 400; + public static final int DFS_ERROR_FILE_NOT_FIND = 404; + public static final int DFS_ERROR_NOT_INITIALIZED = 405; + public static final int DFS_ERROR_BAD_PARAMETER = 406; + public static final int DFS_ERROR_NULL_OBJECT = 407; + public static final int DFS_ERROR_NETWORK_EXCEPTION = 408; + + +} diff --git a/tool/java/DfsSDK/src/com/dfs/entity/QueryResultJson.java b/tool/java/DfsSDK/src/com/dfs/entity/QueryResultJson.java new file mode 100644 index 0000000000..eb004e8e96 --- /dev/null +++ b/tool/java/DfsSDK/src/com/dfs/entity/QueryResultJson.java @@ -0,0 +1,24 @@ +package com.dfs.entity; + + +public class QueryResultJson { + + private int ret; + private DataJson data; + + public int getRet() { + return ret; + } + + public void setRet(int ret) { + this.ret = ret; + } + + public DataJson getData() { + return data; + } + + public void setData(DataJson data) { + this.data = data; + } +} diff --git a/tool/java/DfsSDK/src/com/dfs/entity/RetEnum.java b/tool/java/DfsSDK/src/com/dfs/entity/RetEnum.java new file mode 100644 index 0000000000..1d1f548ba8 --- /dev/null +++ b/tool/java/DfsSDK/src/com/dfs/entity/RetEnum.java @@ -0,0 +1,40 @@ +package com.dfs.entity; + +public enum RetEnum { + + RET_SUCCESS(0,"成功"), + RET_FAIL(1,"失败"); + + private String name; + private int code; + + private RetEnum(int code, String name){ + this.name = name; + this.code = code; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public static RetEnum getEnumByCodeValue(int code){ + RetEnum[] allEnums = values(); + for(RetEnum enableStatus : allEnums){ + if(enableStatus.getCode()==code) + return enableStatus; + } + return null; + } +} diff --git a/tool/java/DfsSDK/src/com/dfs/fileserver/DfsEngine.java b/tool/java/DfsSDK/src/com/dfs/fileserver/DfsEngine.java new file mode 100644 index 0000000000..18b3be6936 --- /dev/null +++ b/tool/java/DfsSDK/src/com/dfs/fileserver/DfsEngine.java @@ -0,0 +1,1232 @@ +/** + * @Title: JuzhenDfsClient.java + + * @Description: dfs client + + * @date: 2017年3月2日 下午4:34:38 + + * @version: V1.0 + + */ +package com.dfs.fileserver; + +import java.io.File; +import java.io.IOException; +import java.math.BigInteger; +import java.util.Calendar; +import java.util.Collections; +import java.util.List; +import java.util.Random; +import java.util.Vector; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; + +import org.junit.internal.runners.ErrorReportingRunner; +import org.juzix.web3j.NonceTransactionManager; +import org.juzix.web3j.protocol.CostomerWeb3j; +import org.juzix.web3j.protocol.CustomerWeb3jFactory; +import org.web3j.abi.datatypes.Utf8String; +import org.web3j.abi.datatypes.generated.Uint256; +import org.web3j.crypto.Credentials; +import org.web3j.crypto.WalletUtils; +import org.web3j.protocol.Web3jService; +import org.web3j.protocol.core.methods.response.EthAccounts; +import org.web3j.protocol.core.methods.response.TransactionReceipt; +import org.web3j.protocol.http.HttpService; +import org.web3j.protocol.parity.Parity; +import org.web3j.tx.ClientTransactionManager; +import org.web3j.tx.RawTransactionManager; +import org.web3j.tx.TransactionManager; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.dfs.entity.DfsConst; +import com.dfs.entity.QueryResultJson; +import com.dfs.entity.RetEnum; +import com.dfs.http.FileHttpClient; +import com.dfs.message.FileInfo; +import com.dfs.message.FileServer; +import com.dfs.utils.DfsMD5; +import com.dfs.utils.DfsMutexLock; +import com.dfs.utils.DfsTimer; +import com.dfs.web3j.FileInfoManager; +import com.dfs.web3j.FileServerManager; +import com.dfs.web3j.FileInfoManager.NotifyEventResponse; +import com.dfs.web3j.tx.DfsRawTransactionManager; + + +public class DfsEngine { + //request, and then listener callback + private IDfsListener listener; + private DfsMutexLock locker; + protected String host; + protected int port; + private boolean isInit = false; + private String walletPassword; + private String keyPath; + + private static final String FILE_SERVER_MGR_ADDR = "0x1000000000000000000000000000000000000019"; + private static final String FILE_INFO_MGR_ADDR = "0x1000000000000000000000000000000000000018"; + private String fileServerContract; + private String fileInfoContract; + private int use_transaction_type = UserTransactionType.NonSigned;//1 for rawTransation, 2 for weiwan rawTransactio, 3: nonceCustomerizeTransction + + private FileHttpClient httpClient; + private String currentAccount; + private Credentials credentials; + private BigInteger gasPrice = new BigInteger("99999999999"); + private BigInteger gasLimited = new BigInteger("9999999999999"); + private Vector fileServers = new Vector(); + + private class UserTransactionType { + public static final int NonSigned = 0; + public static final int StandartRawSigned = 1; + public static final int WeiWanRawSigned = 2; + public static final int NonceCustomerizedRawSigned = 3; + } + + public DfsEngine() { + fileInfoContract = FILE_INFO_MGR_ADDR; + fileServerContract = FILE_SERVER_MGR_ADDR; + credentials = null; + httpClient = new FileHttpClient(); + locker = new DfsMutexLock(); + } + + /** + * @description 初始化, 微万合作版本请使用此接口 + * @param host 主机地址 + * @param port JSONRPC端口 + * @param listener 监听回调接口 + * @param walletPasswd 加密口令 + * @param walletFile 钱包文件 + * @param fileContract 文件信息合约 + * @param serverContract 文件服务合约 + * @return 0 :成功 其他:失败 + */ + public int init(String host, int port, IDfsListener listener, String walletPasswd, String walletFile, String fileContract, String serverContract) + { + fileInfoContract = fileContract; + fileServerContract = serverContract; + if (walletFile.isEmpty() || walletPasswd.isEmpty()) + return init(host, port, listener); + + locker.lock();///////// + registerListener(listener); + + this.host = host; + this.port = port; + httpClient.init(host, port); + + walletPassword = walletPasswd; + keyPath = walletFile; + if (fileContract.isEmpty() && fileServerContract.isEmpty()) { + use_transaction_type = UserTransactionType.StandartRawSigned; + } + else { + use_transaction_type = UserTransactionType.WeiWanRawSigned; + } + + try { + // 加载证书 + credentials = WalletUtils.loadCredentials(walletPassword, keyPath); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + locker.unlock(); + return DfsConst.DFS_ERROR_BAD; + } + listFileServersSync(); + + isInit = true; + + if (fileServers.isEmpty()) { + FileServer server = new FileServer(); + server.setPort(port); + server.setHost(host); + fileServers.add(server); + locker.unlock();///////// + return DfsConst.DFS_ERROR_OK; + } + + locker.unlock();///////// + return DfsConst.DFS_ERROR_OK; + } + + /** + * @description 初始化, 标准代签名 + * @param host 主机地址 + * @param port JSONRPC端口 + * @param listener 监听回调接口 + * @param walletPasswd 加密口令 + * @param walletFile 钱包文件 + * @return 0 :成功 其他:失败 + */ + public int init(String host, int port, IDfsListener listener, String walletPasswd, String walletFile) + { + return init(host, port, listener, walletPasswd, walletFile, false); + } + + /** + * @description 初始化, 签名 (可以指定是否使用拓展Nonce) + * @param host 主机地址 + * @param port JSONRPC端口 + * @param listener 监听回调接口 + * @param walletPasswd 加密口令 + * @param walletFile 钱包文件 + * @param nonceExtension 是否使用拓展Nonce + * @return 0 :成功 其他:失败 + */ + public int init(String host, int port, IDfsListener listener, String walletPasswd, String walletFile, Boolean nonceExtension) + { + if (nonceExtension) + { + use_transaction_type = UserTransactionType.NonceCustomerizedRawSigned; + } + else { + use_transaction_type = UserTransactionType.StandartRawSigned; + } + + locker.lock();///////// + registerListener(listener); + + this.host = host; + this.port = port; + httpClient.init(host, port); + + walletPassword = walletPasswd; + keyPath = walletFile; + + try { + // 加载证书 + credentials = WalletUtils.loadCredentials(walletPassword, keyPath); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + locker.unlock(); + return DfsConst.DFS_ERROR_BAD; + } + listFileServersSync(); + + isInit = true; + + if (fileServers.isEmpty()) { + FileServer server = new FileServer(); + server.setPort(port); + server.setHost(host); + fileServers.add(server); + locker.unlock();///////// + return DfsConst.DFS_ERROR_OK; + } + + locker.unlock();///////// + return DfsConst.DFS_ERROR_OK; + } + + /** + * @description 初始化 (交易不签名, 方式使用SDK) + * @param host 主机地址 + * @param port JSONRPC端口 + * @param listener 监听回调接口 + * @return 0 :成功 其他:失败 + */ + public int init(String host, int port, IDfsListener listener) + { + locker.lock();////////////// + isInit = false; + registerListener(listener); + + use_transaction_type = UserTransactionType.NonSigned; + + this.host = host; + this.port = port; + httpClient.init(host, port); + Parity parity = createParity(host, port); + + currentAccount = getFirstInnerAccount(parity); + listFileServersSync(); + + isInit = true; + + if (fileServers.isEmpty()) { + FileServer server = new FileServer(); + server.setPort(port); + server.setHost(host); + fileServers.add(server); + locker.unlock();///////// + return DfsConst.DFS_ERROR_FAIL; + } + + locker.unlock();////////////// + + return DfsConst.DFS_ERROR_OK; + } + + /** + * @description 下载文件 + * @param fileid 文件ID + * @param store_path 文件存储完整路径 + * @return + */ + public int downloadFile(String fileid, String storePath) + { + if (!isInit || listener == null) + return DfsConst.DFS_ERROR_BAD; + + new Thread() { + public void run() { + FileServer fileServer = getCurrentFileServer(); + FileInfoManager fileInfoManager = createFileInfoManager(fileServer); + + //find in contract + Vector fileinfos = new Vector(); + StringBuilder info = new StringBuilder(); + int ret = findFileFromBlock(fileInfoManager, fileid, fileinfos, info); + if (ret != DfsConst.DFS_ERROR_OK) { + //System.out.println("cannot find the file: " + fileid); + listener.errorCallback(ret, info.toString()); + return; + } + + if (DfsConst.DFS_ERROR_OK != httpClient.download(fileServer, fileid, storePath)) + { + listener.errorCallback(httpClient.getRet(), httpClient.getInfo()); + return; + } + + //validate the file hash + String strMd5 = DfsMD5.getMd5(storePath); + if (!strMd5.equals(fileinfos.elementAt(0).getFile_hash())){ + listener.errorCallback(DfsConst.DFS_ERROR_FAIL, "file corrupted, file imcompleted !"); + return; + } + + listener.downloadFileCallback(httpClient.getRet(), fileinfos.elementAt(0)); + } + }.start(); + + return DfsConst.DFS_ERROR_OK; + } + + /** + * @description 上传文件 + * @param fileInfo 文件信息 + * @param file 文件路径 + * @return + */ + public int uploadFile(FileInfo fileInfo, String file) { + FileServer fileServer = getCurrentFileServer(); + if (!isInit || listener == null || !checkFileServer(fileServer)) + return DfsConst.DFS_ERROR_BAD; + + File fileObj = new File(file); + if (!fileObj.exists()) { + return DfsConst.DFS_ERROR_BAD_PARAMETER; + } + + //async process + new Thread() { + public void run() { + String fName = file.trim(); + String fileName = fName.substring(fName.lastIndexOf(File.separatorChar)+1); + if (fileName.isEmpty()) + fileName = ""; + + DfsTimer timer = new DfsTimer(); + timer.start(); + String fileid = fetchFileId(fileServer, fileName); + timer.stop(); + + timer.start(); + fileInfo.setId(fileid); + fileInfo.setContainer(DfsConst.HTTP_FS_CONTAINER_ID_DEFAULT); + fileInfo.setNode_group(fileServer.getGroup()); + fileInfo.setSrc_node(fileServer.getId()); + fileInfo.setFilename(fileName); + fileInfo.setSize((int)fileObj.length()); + + String fileHash = DfsMD5.getMd5(file); + fileInfo.setFile_hash(fileHash); + + Calendar cal = Calendar.getInstance(); + fileInfo.setUpdateTime((int)cal.getTimeInMillis()/1000); + StringBuffer strRemoteFileHash = new StringBuffer(); + timer.stop(); + + timer.start(); + if (DfsConst.DFS_ERROR_OK != httpClient.upload(fileServer, fileInfo, file, strRemoteFileHash)) + { + listener.errorCallback(httpClient.getRet(), httpClient.getInfo()); + return; + } + timer.stop(); + + if (strRemoteFileHash.toString().equals(fileHash)) + { + httpClient.deleteFile(fileServer, fileInfo.getId()); + listener.errorCallback(DfsConst.DFS_ERROR_FAIL, "upload file not complete, try again"); + return; + } + + FileInfoManager fileInfoManager = createFileInfoManager(fileServer); + + Utf8String fileStr = new Utf8String(JSON.toJSONString(fileInfo)); + TransactionReceipt receipt = null; + timer.start(); + try { + receipt = fileInfoManager.insert(fileStr).get(DfsConst.JU_REQUEST_TIMEOUT, TimeUnit.SECONDS); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + //System.out.println("upload transaction Exception !"); + httpClient.deleteFile(fileServer, fileInfo.getId()); + listener.errorCallback(DfsConst.DFS_ERROR_FAIL, "upload transaction Exception"); + return; + } + timer.stop(); + + timer.start(); + List events = fileInfoManager.getNotifyEvents(receipt); + if (events.isEmpty()) + { + //System.out.println("upload no event"); + deleteFile(fileInfo.getId()); + listener.errorCallback(0, "upload no event"); + return; + } + + int errno = events.get(0)._errno.getValue().intValue(); + if (errno != 0) + { + //System.out.println("upload transaction failed !"); + listener.errorCallback(0, "upload transaction failed"); + return; + } + + listener.uploadFileCallback(httpClient.getRet(), fileInfo); + timer.stop(); + return; + } + }.start(); + + return DfsConst.DFS_ERROR_OK; + } + + /** + * @description 删除文件 + * @param fileid 文件id + * @return + */ + public int deleteFile(String fileid) + { + FileServer fileServer = getCurrentFileServer(); + if (!isInit || listener == null || !checkFileServer(fileServer)) + return DfsConst.DFS_ERROR_BAD; + + new Thread() { + public void run() { + FileInfoManager fileInfoManager = createFileInfoManager(fileServer); + + FileInfo objFileInfo = new FileInfo(); + objFileInfo.setId(fileid); + + if (DfsConst.DFS_ERROR_OK != httpClient.deleteFile(fileServer, fileid)) { + //System.out.println("delete file failed, fileid: " + fileid); + listener.errorCallback(httpClient.getRet(), httpClient.getInfo()); + return; + } + + //delete transaction + Utf8String fileidStr = new Utf8String(fileid); + TransactionReceipt receipt = null; + try { + receipt = fileInfoManager.deleteById(fileidStr).get(DfsConst.JU_REQUEST_TIMEOUT, TimeUnit.SECONDS); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + List events = fileInfoManager.getNotifyEvents(receipt); + if (events.size() <= 0) + { + //System.out.println("delete event not match"); + listener.errorCallback(0, "delete event not match"); + return; + } + + int errno = events.get(0)._errno.getValue().intValue(); + if (events.get(0)._errno.getValue().intValue() != 0) + { + //System.out.println("delete transaction failed !"); + listener.errorCallback(errno, events.get(0)._info.getValue()); + return; + } + + listener.deleteFileCallback(httpClient.getRet(), objFileInfo); + return; + } + }.start(); + + return DfsConst.DFS_ERROR_OK; + } + + /** + * @description 删除文件服务节点 + * @param _serverid 文件服务节点id + * @return + */ + public int deleteServer(String serverid) { + if (!isInit || listener == null) + return DfsConst.DFS_ERROR_BAD; + + if (serverid.isEmpty()) + return DfsConst.DFS_ERROR_BAD_PARAMETER; + + new Thread() { + public void run() { + FileServerManager fileServerManager = createFileServerManager(getCurrentFileServer()); + + TransactionReceipt receipt = null; + try { + receipt = fileServerManager.deleteById(new Utf8String(serverid)).get(DfsConst.JU_REQUEST_TIMEOUT, TimeUnit.SECONDS); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + listener.errorCallback(DfsConst.DFS_ERROR_FAIL, "list fileinfo failed"); + return; + } + + List events = fileServerManager.getNotifyEvents(receipt); + if (events.isEmpty()){ + listener.errorCallback(DfsConst.DFS_ERROR_FAIL, "delete server no event back"); + return; + } + + int errno = events.get(0)._errno.getValue().intValue(); + if (errno != 0){ + listener.errorCallback(errno, events.get(0)._info.getValue()); + return; + } + + FileServer fileServer = new FileServer(); + fileServer.setId(serverid); + listener.deleteServerCallback(errno, fileServer); + return; + } + }.start(); + + return DfsConst.DFS_ERROR_OK; + } + + /** + * @description 添加一个文件服务节点 + * @param newServer 添加到文件服务节点 + * @return 0: 成功, 其他: 失败 + */ + public int addServer(FileServer newServer) { + if (!isInit || listener == null) + return DfsConst.DFS_ERROR_BAD; + + if (newServer.getId().isEmpty()) + return DfsConst.DFS_ERROR_BAD_PARAMETER; + + new Thread() { + public void run() { + FileServerManager fileServerManager = createFileServerManager(getCurrentFileServer()); + + String serverInfo = JSON.toJSONString(newServer); + TransactionReceipt receipt = null; + try { + Future futureReceipt = fileServerManager.insert(new Utf8String(serverInfo)); + receipt = futureReceipt.get(10 * DfsConst.JU_REQUEST_TIMEOUT, TimeUnit.SECONDS); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + listener.errorCallback(DfsConst.DFS_ERROR_FAIL, "add server error"); + return; + } + + List events = fileServerManager.getNotifyEvents(receipt); + if (events.isEmpty()){ + listener.errorCallback(DfsConst.DFS_ERROR_FAIL, "add server timeout, no event back"); + return; + } + + int errno = events.get(0)._errno.getValue().intValue(); + if (errno != 0){ + listener.errorCallback(errno, events.get(0)._info.getValue()); + return; + } + + listener.addServerCallback(errno, newServer); + return; + } + }.start(); + + return DfsConst.DFS_ERROR_OK; + } + + /** + * @description 添加一个文件服务节点 + * @param newServer 添加到文件服务节点 + * @return 0: 成功, 其他: 失败 + */ + public int addServerSync(FileServer newServer, StringBuffer errorInfo) { + errorInfo.delete(0, errorInfo.length()); + + if (!isInit || listener == null) { + errorInfo.append("not init or null"); + return DfsConst.DFS_ERROR_BAD; + } + + if (newServer.getId().isEmpty()) { + errorInfo.append("serverid is null"); + return DfsConst.DFS_ERROR_BAD_PARAMETER; + } + + FileServerManager fileServerManager = createFileServerManager(getCurrentFileServer()); + + String serverInfo = JSON.toJSONString(newServer); + TransactionReceipt receipt = null; + try { + Future futureReceipt = fileServerManager.insert(new Utf8String(serverInfo)); + receipt = futureReceipt.get(10 * DfsConst.JU_REQUEST_TIMEOUT, TimeUnit.SECONDS); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + errorInfo.append("add server exception"); + return DfsConst.JU_REQUEST_TIMEOUT; + } + + List events = fileServerManager.getNotifyEvents(receipt); + if (events.isEmpty()){ + errorInfo.append("add server timeout, no event back"); + return DfsConst.DFS_ERROR_FAIL; + } + + int errno = events.get(0)._errno.getValue().intValue(); + if (errno != 0){ + errorInfo.append(events.get(0)._info.getValue()); + return DfsConst.DFS_ERROR_FAIL; + } + + return DfsConst.DFS_ERROR_OK; + } + + /** + * @description 开启或关闭文件服务 + * @param state 1: 开启, 0: 关闭 + * @return 0: 成功, 其他:失败 + */ + public int enableServer(String serverID, boolean enable) { + if (!isInit || listener == null) + return DfsConst.DFS_ERROR_BAD; + + new Thread() { + public void run() { + FileServerManager fileServerManager = createFileServerManager(getCurrentFileServer()); + long nEnable = enable ? 1: 0; + TransactionReceipt receipt = null; + try { + Future futureReceipt = fileServerManager.enable(new Utf8String(serverID), new Uint256(BigInteger.valueOf(nEnable))); + receipt = futureReceipt.get(DfsConst.JU_REQUEST_TIMEOUT, TimeUnit.SECONDS); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + listener.errorCallback(DfsConst.DFS_ERROR_FAIL, "enable server error"); + return; + } + + List events = fileServerManager.getNotifyEvents(receipt); + if (events.isEmpty()){ + listener.errorCallback(DfsConst.DFS_ERROR_FAIL, "enable server timeout, no event back"); + return; + } + + int errno = events.get(0)._errno.getValue().intValue(); + if (errno != 0){ + listener.errorCallback(errno, events.get(0)._info.getValue()); + return; + } + + listener.enableServerCallback(errno, serverID); + return; + } + }.start(); + + return DfsConst.DFS_ERROR_OK; + } + + + /** + * @description 列出所有文件信息 + * @return 0: 成功, 其他:失败 + */ + public int listFiles() + { + if (!isInit || listener == null) + return DfsConst.DFS_ERROR_BAD; + + new Thread() { + public void run() { + FileInfoManager fileInfoManager = createFileInfoManager(getCurrentFileServer()); + + Future result = fileInfoManager.listAll(); + Utf8String fileinfos = null; + + try { + fileinfos = result.get(); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (ExecutionException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + String strFiles = fileinfos.toString(); + //System.out.println("**** The file info list json: " + strFiles); + + //parse fileinfo list + QueryResultJson objQueryResult = JSON.parseObject(strFiles, QueryResultJson.class); + if (objQueryResult.getRet() != DfsConst.DFS_ERROR_OK && + objQueryResult.getRet() != DfsConst.DFS_ERROR_SUCCESS) { + listener.errorCallback(objQueryResult.getRet(), "list fileinfo failed"); + return; + } + + Vector vecFileinfos = new Vector(); + for (JSONObject item : objQueryResult.getData().getItems()) + { + FileInfo objFileInfo = JSON.toJavaObject((JSONObject)item, FileInfo.class); + vecFileinfos.addElement(objFileInfo); + } + listener.listFileinfoCallback(objQueryResult.getRet(), vecFileinfos); + return; + } + }.start(); + + return DfsConst.DFS_ERROR_OK; + } + + /** + * @description 列出所有文件信息 + * @return 0: 成功, 其他:失败 + */ + public int listFilesByGroup(String _group) + { + if (!isInit || listener == null) + return DfsConst.DFS_ERROR_BAD; + + new Thread() { + public void run() { + FileInfoManager fileInfoManager = createFileInfoManager(getCurrentFileServer()); + + Future result = fileInfoManager.listByGroup(new Utf8String(_group)); + Utf8String fileinfos = null; + + try { + fileinfos = result.get(); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (ExecutionException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + String strFiles = fileinfos.toString(); + //System.out.println("**** The file info list json: " + strFiles); + + //parse fileinfo list + QueryResultJson objQueryResult = JSON.parseObject(strFiles, QueryResultJson.class); + if (objQueryResult.getRet() != DfsConst.DFS_ERROR_OK && + objQueryResult.getRet() != DfsConst.DFS_ERROR_SUCCESS) { + listener.errorCallback(objQueryResult.getRet(), "list fileinfo failed"); + return; + } + + Vector vecFileinfos = new Vector(); + for (JSONObject item : objQueryResult.getData().getItems()) + { + FileInfo objFileInfo = JSON.toJavaObject((JSONObject)item, FileInfo.class); + vecFileinfos.addElement(objFileInfo); + } + listener.listFileinfoByGroupCallback(objQueryResult.getRet(), vecFileinfos); + return; + } + }.start(); + + return DfsConst.DFS_ERROR_OK; + } + + /** + * @description 查找文件信息 + * @param fileid 文件ID + * @return 0: 成功, 其他:失败 + */ + public int findFileinfo(String fileid) + { + if (!isInit || listener == null) + return DfsConst.DFS_ERROR_BAD; + + if (fileid == "" ){ + System.out.println("Bad parameters"); + return DfsConst.DFS_ERROR_BAD; + } + + new Thread(){ + public void run() { + FileInfoManager fileInfoManager = createFileInfoManager(getCurrentFileServer()); + + Vector vecFileinfos = new Vector(); + StringBuilder strErr = new StringBuilder(); + int ret = findFileFromBlock(fileInfoManager, fileid, vecFileinfos, strErr); + if (DfsConst.DFS_ERROR_OK != ret) { + //System.out.println("cannot find the file: " + fileid); + listener.errorCallback(ret, strErr.toString()); + return; + } + + listener.findFileinfoCallback(ret, vecFileinfos.elementAt(0)); + return; + } + }.start(); + + return DfsConst.DFS_ERROR_OK; + } + + /** + * @description 查询文件信息 (同步方式) + * @param fileInfoManager + * @param fileid + * @param fileinfos + * @param info + * @return + */ + private int findFileFromBlock(FileInfoManager fileInfoManager, String fileid, Vector fileinfos, StringBuilder info) + { + info.delete(0, info.length()); + + Future result = fileInfoManager.find(new Utf8String(fileid)); + Utf8String fileInfo = null; + try { + fileInfo = result.get(); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + + info.append("god exception: " + e.getMessage()); + return DfsConst.DFS_ERROR_NETWORK_EXCEPTION; + } + + //System.out.println("find response json: " + fileInfo.getValue()); + + + //parse the FileInfo object + String strFileInfo = fileInfo.getValue().toString(); + //System.out.println("**** The file info json: " + strFileInfo); + + //parse fileinfo list + QueryResultJson objQueryResult = JSON.parseObject(strFileInfo, QueryResultJson.class); + if (objQueryResult.getRet() != RetEnum.RET_SUCCESS.getCode() || + objQueryResult.getData().getItems().length < 1) { + info.append("find fileinfo failed"); + return DfsConst.DFS_ERROR_FILE_NOT_FIND; + } + + for (JSONObject item : objQueryResult.getData().getItems()) + { + FileInfo objFileInfo = JSON.toJavaObject((JSONObject)item, FileInfo.class); + fileinfos.addElement(objFileInfo); + } + + return DfsConst.DFS_ERROR_OK; + } + + /** + * @description 获取cache的服务节点列表 + * @return 节点列表 + */ + public Vector getFileServers() { + return fileServers; + } + + /** + * @description 获取文件服务节点列表 (节点信息返回后将会刷新缓存) + * @return + */ + public int listServers() { + if (!isInit || listener == null) + return DfsConst.DFS_ERROR_BAD; + + new Thread(){ + public void run() { + FileServerManager fileServerManager = createFileServerManager(getCurrentFileServer()); + + Future futureStr = fileServerManager.listAll(); + Utf8String strUtf8Json = null; + try { + strUtf8Json = futureStr.get(); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + listener.errorCallback(DfsConst.DFS_ERROR_FAIL, "list server excetion"); + return; + } + + String strjson = strUtf8Json.getValue(); + QueryResultJson objQueryJson = JSON.parseObject(strjson, QueryResultJson.class); + System.out.println("json: " + strjson); + if (objQueryJson.getRet() != DfsConst.DFS_ERROR_OK && + objQueryJson.getRet() != DfsConst.DFS_ERROR_SUCCESS) { + listener.errorCallback(objQueryJson.getRet(), "list server failed"); + return; + } + + Vector vecServers = new Vector(); + for (JSONObject object : objQueryJson.getData().getItems()) { + FileServer server = JSON.toJavaObject(object, FileServer.class); + vecServers.add(server); + } + + listener.listServersCallback(objQueryJson.getRet(), vecServers); + return; + }}.start(); + + return DfsConst.DFS_ERROR_OK; + } + + /** + * @description 按照组ID获取文件服务节点列表 (节点信息返回后将会刷新缓存) + * @param group 组ID + * @return + */ + public int listServerByGroup(String group) { + if (!isInit || listener == null) + return DfsConst.DFS_ERROR_BAD; + + new Thread(){ + public void run() { + FileServerManager fileServerManager = createFileServerManager(getCurrentFileServer()); + + Utf8String utf8String = new Utf8String(group); + Future futureStr = fileServerManager.listByGroup(utf8String); + Utf8String strUtf8Json = null; + try { + TimeUnit timeUnit = TimeUnit.SECONDS; + strUtf8Json = futureStr.get(DfsConst.JU_REQUEST_TIMEOUT/2, timeUnit); + } catch (Exception e) { + listener.errorCallback(DfsConst.DFS_ERROR_BAD, "list server by group exception"); + return; + } + + String strjson = strUtf8Json.getValue(); + QueryResultJson objQueryJson = JSON.parseObject(strjson, QueryResultJson.class); + if (objQueryJson.getRet() != DfsConst.DFS_ERROR_OK && + objQueryJson.getRet() != DfsConst.DFS_ERROR_SUCCESS) { + listener.errorCallback(objQueryJson.getRet(), "list server by group failed"); + return; + } + + Vector vecServers = new Vector(); + for (JSONObject object : objQueryJson.getData().getItems()) { + FileServer server = JSON.toJavaObject(object, FileServer.class); + vecServers.add(server); + } + + listener.listServersByGroupCallback(objQueryJson.getRet(), vecServers); + return; + }}.start(); + + return DfsConst.DFS_ERROR_OK; + } + + /** + * + * @description 获取文件ID (同步接口) + * @param fileServer 服务节点 + * @param filename 文件名 + */ + private String fetchFileId(FileServer fileServer, String filename) { + FileInfoManager fileInfoManager = createFileInfoManager(fileServer); + Random random = new Random(); + Calendar cal = Calendar.getInstance(); + String randomString = "" + cal.getTimeInMillis() + random.nextInt(1000000000); + Future futureStr = fileInfoManager.generateFileID(new Utf8String(randomString), new Utf8String(fileServer.getGroup()), new Utf8String(fileServer.getId()), new Utf8String(filename)); + Utf8String strFileId = null; + try { + strFileId = futureStr.get(); + } catch (Exception e) { + e.printStackTrace(); + return ""; + } + + return strFileId.getValue(); + } + + + /** + * @description 同步接口: 获取服务器列表 + */ + private int listFileServersSync() { + FileServer fileServer = new FileServer(); + fileServer.setHost(host); + fileServer.setPort(port); + + FileServerManager fileServerManager = createFileServerManager(fileServer); + Future futureStr = fileServerManager.listAll(); + Utf8String strUtf8Json = null; + try { + strUtf8Json = futureStr.get(); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (ExecutionException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return DfsConst.DFS_ERROR_FAIL; + } + + String strjson = strUtf8Json.getValue(); + QueryResultJson objQueryJson = JSON.parseObject(strjson, QueryResultJson.class); + if (objQueryJson.getRet() != DfsConst.DFS_ERROR_OK && + objQueryJson.getRet() != DfsConst.DFS_ERROR_SUCCESS) { + return DfsConst.DFS_ERROR_FAIL; + } + + Vector vecServers = new Vector(); + for (JSONObject object : objQueryJson.getData().getItems()) { + FileServer server = JSON.toJavaObject(object, FileServer.class); + vecServers.add(server); + } + if (vecServers.isEmpty()) + { + return DfsConst.DFS_ERROR_FAIL; + } + + //shuffle the servers + shuffleServers(vecServers); + + locker.lock(); + fileServers.clear(); + for (FileServer server : vecServers) { + if (server.getEnable() != 0) { + //we only want the on service server node + fileServers.addElement(server); + } + } + + locker.unlock(); + return DfsConst.DFS_ERROR_OK; + } + + /** + * @return the gasPrice + */ + public BigInteger getGasPrice() { + return gasPrice; + } + + /** + * @return the gasLimited + */ + public BigInteger getGasLimited() { + return gasLimited; + } + + /** + * @param keyPath the keyPath to set + */ + public void setKeyPath(String keyPath) { + this.keyPath = keyPath; + } + + /** + * @param 设置gasPrice + */ + public void setGasPrice(BigInteger gasPrice) { + this.gasPrice = gasPrice; + } + + /** + * @param 设置gasLimited + */ + public void setGasLimited(BigInteger gasLimited) { + this.gasLimited = gasLimited; + } + + /** + * @return 获取签名认证对象 + */ + public Credentials getCredentials() { + return credentials; + } + + /** + * @description 随机化服务器 + * @param vecServers 服务器列表 + */ + protected void shuffleServers(Vector vecServers) { + Random random = new Random(); + Calendar calendar = Calendar.getInstance(); + random.setSeed(calendar.getTimeInMillis()/1000); + Collections.shuffle(vecServers, random); + } + + /** + * @param host 主机地址 + * @param port JSONRPC端口 + * @return + */ + protected Parity createParity(String host, int port) { + Parity parity; + String uri = "http://"; + uri += host; + uri += ":"; + uri += port; + + parity = Parity.build(new HttpService(uri)); + return parity; + } + + /** + * @param fileServer文件服务器节点 + * @return + */ + protected Parity createParity(FileServer fileServer) { + return createParity(fileServer.getHost(), fileServer.getPort()); + } + + /** + * @description 注册监听器 + * @param listener + * @return + */ + private int registerListener(IDfsListener listener) + { + this.listener = listener; + return 0; + } + + /** + * @description 检查server参数 + */ + private boolean checkFileServer(FileServer fileServer) { + if (fileServer.getHost().isEmpty() || fileServer.getPort() <= 0 || !isServerParamValid(fileServer)) { + return false; + } + + return true; + } + + /** + * @description 检查null或空串 + */ + private boolean isServerParamValid(FileServer fileServer) { + if (fileServer.getId() == null || fileServer.getGroup() == null) { + return false; + } + + if (fileServer.getId().isEmpty() || fileServer.getGroup().isEmpty()) { + return false; + } + + return true; + } + + /** + * @param parity + */ + private String getFirstInnerAccount(Parity parity) { + EthAccounts accounts = null; + try { + accounts = parity.ethAccounts().send(); + } catch (IOException e) { + e.printStackTrace(); + return null; + } + + return accounts.getAccounts().get(0); + } + + /** + * @description 创建文件信息合约对象 + */ + private FileInfoManager createFileInfoManager(FileServer fileServer) { + Parity parity = createParity(fileServer); + String addr = fileInfoContract; + + if (credentials == null) { + currentAccount = getFirstInnerAccount(parity); + return FileInfoManager.load(addr, parity, new ClientTransactionManager(parity, currentAccount), gasPrice, gasLimited); + } + + // with signed, 1 for standard, 2 for weiwan, 3, for nonceExtension + if (use_transaction_type == UserTransactionType.StandartRawSigned) { + return FileInfoManager.load(addr, parity, new RawTransactionManager(parity, credentials, 100, 100) , gasPrice, gasLimited); + } + else if (use_transaction_type == UserTransactionType.WeiWanRawSigned) { + return FileInfoManager.load(addr, parity, new DfsRawTransactionManager(parity, credentials, 100, 100) , gasPrice, gasLimited); + } + else//3 or other is default for nonceExtension + { + String uri = "http://"; + uri += host; + uri += ":"; + uri += port; + + HttpService httpService = new HttpService(uri); + CostomerWeb3j web3jExt = CustomerWeb3jFactory.buildweb3j(httpService); + return FileInfoManager.load(addr, parity, new NonceTransactionManager(web3jExt, credentials, 100, 100) , gasPrice, gasLimited); + } + } + + /** + * @description 更新文件服务合约对象 + */ + private FileServerManager createFileServerManager(FileServer fileServer) { + Parity parity = createParity(fileServer); + String addr = fileServerContract; + + if (credentials == null) { + currentAccount = getFirstInnerAccount(parity); + return FileServerManager.load(addr, parity, new ClientTransactionManager(parity, currentAccount), gasPrice, gasLimited); + } + + // with signed, 1 for standard, 2 for weiwan, 3, for nonceExtension + if (use_transaction_type == UserTransactionType.StandartRawSigned) { + return FileServerManager.load(addr, parity, new RawTransactionManager(parity, credentials, 100, 100) , gasPrice, gasLimited); + } + else if (use_transaction_type == UserTransactionType.WeiWanRawSigned) { + return FileServerManager.load(addr, parity, new DfsRawTransactionManager(parity, credentials, 100, 100) , gasPrice, gasLimited); + } + else//3 or other is default for nonceExtension + { + String uri = "http://"; + uri += host; + uri += ":"; + uri += port; + + HttpService httpService = new HttpService(uri); + CostomerWeb3j web3jExt = CustomerWeb3jFactory.buildweb3j(httpService); + return FileServerManager.load(addr, parity, new NonceTransactionManager(web3jExt, credentials, 100, 100) , gasPrice, gasLimited); + } + } + + /** + * @return 获取当前文件服务节点 + */ + public FileServer getCurrentFileServer() { + for (FileServer server : fileServers) { + if (server.getEnable() != 0 && server.getHost().equals(host) && server.getPort() == port) + return server; + } + + FileServer defaultServer = new FileServer(); + defaultServer.setPort(port); + defaultServer.setHost(host); + return defaultServer; + } +} diff --git a/tool/java/DfsSDK/src/com/dfs/fileserver/IDfsListener.java b/tool/java/DfsSDK/src/com/dfs/fileserver/IDfsListener.java new file mode 100644 index 0000000000..15aafebaa5 --- /dev/null +++ b/tool/java/DfsSDK/src/com/dfs/fileserver/IDfsListener.java @@ -0,0 +1,116 @@ +/** + * @brief 回调接口类 + * @Title: IJuListener.java + + * @date: 2017年3月2日 下午4:43:28 + + * @version: V1.0 + + */ +package com.dfs.fileserver; + +import java.util.Vector; + +import com.dfs.message.FileInfo; +import com.dfs.message.FileServer; + + +/** + * @brief 回调接口类 + * + */ +public interface IDfsListener { + /** + * @description 下载请求回调 + * @param ret 返回值 + * @param fileinfo 文件信息 + */ + public void downloadFileCallback(int ret, FileInfo fileinfo); + + /** + * @description 上传请求回调 + * @param ret 返回值 + * @param fileinfo 文件信息 + */ + public void uploadFileCallback(int ret, FileInfo fileinfo); + + /** + * @description 删除文件请求回调 + * @param ret + * @param fileinfo + */ + public void deleteFileCallback(int ret, FileInfo fileinfo); + + /** + * @description 列出所有文件信息请求回调 + * @param ret 返回值 + * @param fileinfos 文件信息列表 + */ + public void listFileinfoCallback(int ret, Vector fileinfoList); + + /** + * @description 列出所有文件信息请求回调 + * @param ret 返回值 + * @param fileinfoList 文件信息列表 + */ + public void listFileinfoByGroupCallback(int ret, Vector fileinfoList); + + /** + * @description 查找文件信息请求回调 + * @param ret 返回值 + * @param fileinfo 文件信息 + */ + public void findFileinfoCallback(int ret, FileInfo fileinfo); + + /** + * @description 列出服务器请求回调 + * @param ret 返回值 + * @param fileServerList 服务器信息列表 + */ + public void listServersCallback(int ret, Vector fileServerList); + + /** + * @description 按组列出服务器请求回调 + * @param ret 返回值 + * @param fileServerList 服务器信息列表 + */ + public void listServersByGroupCallback(int ret, Vector fileServerList); + + /** + * @description 查找服务器请求回调 + * @param ret 返回值 + * @param fileServer 服务器信息 + */ + public void findServerCallback(int ret, FileServer fileServer); + + /** + * @description 下载请求回调 + * @param ret 返回值 + * @param server 文件信息 + */ + public void addServerCallback(int ret, FileServer server); + + /** + * @description 删除服务节点请求回调 + * @param ret 返回值 + * @param server 服务i节点信息 + */ + public void deleteServerCallback(int ret, FileServer server); + + /** + * @description 下载请求回调 + * @param ret 返回值 + * @param serverID 服务节点ID + */ + public void enableServerCallback(int ret, String serverID); + + + /** + * @description 错误请求回调 + * @param code 错误码 + * @param error 错误信息 + */ + public void errorCallback(int code, String error); + + +} diff --git a/tool/java/DfsSDK/src/com/dfs/http/FileHttpClient.java b/tool/java/DfsSDK/src/com/dfs/http/FileHttpClient.java new file mode 100644 index 0000000000..fd2ab8a0f1 --- /dev/null +++ b/tool/java/DfsSDK/src/com/dfs/http/FileHttpClient.java @@ -0,0 +1,503 @@ +/** + + * @Title: FileHttpClient.java + + * @date: 2017年3月7日 上午10:04:29 + + * @version: V1.0 + + */ +package com.dfs.http; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; + +import org.apache.http.HttpEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpDelete; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpPut; +import org.apache.http.entity.StringEntity; +import org.apache.http.entity.mime.MultipartEntityBuilder; +import org.apache.http.entity.mime.content.FileBody; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; + +import com.alibaba.fastjson.JSON; +import com.dfs.entity.DfsConst; +import com.dfs.message.FileInfo; +import com.dfs.message.FileOpResponse; +import com.dfs.message.FileServer; + +/** + * @author Administrator + * + */ +public class FileHttpClient { + private String m_Host; + private int m_Port; + private boolean m_Init = false; + + private int m_Ret; + private int m_Code; + private String m_Info; + + public FileHttpClient() + { + m_Host = ""; + m_Port = 0; + m_Init = false; + m_Ret = DfsConst.DFS_ERROR_OK; + m_Code = DfsConst.DFS_ERROR_SUCCESS; + m_Info = ""; + } + + public int init(String host, int port) { + this.m_Host = host; + this.m_Port = port; + m_Init = true; + return 0; + } + + public int download(FileServer fileServer, String fileid, String store_path) + { + resetState(); + + if (!m_Init) + { + m_Ret = DfsConst.DFS_ERROR_NOT_INITIALIZED; + return DfsConst.DFS_ERROR_NOT_INITIALIZED; + } + + //url: http://host:port/fs/v1/files/fileid + String url = fillUrl(fileServer, DfsConst.HTTP_FS_CONTAINER_ID_DEFAULT, fileid); + int ret = DfsConst.DFS_ERROR_OK; + // 把一个普通参数和文件上传给下面这个地址 是一个servlet + CloseableHttpClient httpClient = HttpClients.createDefault(); + OutputStream out = null; + InputStream in = null; + + try { + HttpGet httpGet = new HttpGet(url); + CloseableHttpResponse httpResponse = httpClient.execute(httpGet); + HttpEntity entity = httpResponse.getEntity(); + in = entity.getContent(); + + long length = entity.getContentLength(); + if (length <= 0) { + System.out.println("下载文件不存在!"); + m_Code = DfsConst.DFS_ERROR_FILE_NOT_FIND; + m_Ret = DfsConst.DFS_ERROR_FILE_NOT_FIND; + m_Info = "download file not exists"; + httpResponse.close(); + httpClient.close(); + + return DfsConst.DFS_ERROR_FILE_NOT_FIND; + } + + File file = new File(store_path); + if(!file.exists()){ + file.createNewFile(); + } + + out = new FileOutputStream(file); + byte[] buffer = new byte[4096]; + int readLength = 0; + while ((readLength=in.read(buffer)) > 0) { + byte[] bytes = new byte[readLength]; + System.arraycopy(buffer, 0, bytes, 0, readLength); + out.write(bytes); + } + + out.flush(); + + } catch (Exception e) { + ret = DfsConst.DFS_ERROR_FAIL; + m_Ret = ret; + m_Code = ret; + m_Info = "download file failed!"; + e.printStackTrace(); + }finally{ + try { + if(in != null){ + in.close(); + } + + if(out != null){ + out.close(); + } + } catch (IOException e) { + ret = DfsConst.DFS_ERROR_FAIL; + m_Ret = ret; + m_Code = ret; + e.printStackTrace(); + } + } + + return ret; + } + + public int upload(FileServer fileServer, FileInfo fileinfo, String store_path, StringBuffer remoteHash) { + resetState(); + + if (!m_Init) + { + m_Ret = DfsConst.DFS_ERROR_NOT_INITIALIZED; + return DfsConst.DFS_ERROR_NOT_INITIALIZED; + } + + if (fileinfo.getId().length() <= 0 || + fileinfo.getContainer() != DfsConst.HTTP_FS_CONTAINER_ID_DEFAULT || + fileinfo.getSrc_node().length() <= 0) { + m_Ret = DfsConst.DFS_ERROR_BAD_PARAMETER; + m_Code = DfsConst.DFS_ERROR_FAIL; + return DfsConst.DFS_ERROR_BAD_PARAMETER; + } + + File f = new File(store_path); + if(!f.exists() || f.isDirectory()) { + // do something + m_Ret = DfsConst.DFS_ERROR_FILE_NOT_FIND; + m_Code = DfsConst.DFS_ERROR_FAIL; + return DfsConst.DFS_ERROR_FILE_NOT_FIND; + } + + //url: http://host:port/fs/v1/files/fileid + String url = fillUrl(fileServer, DfsConst.HTTP_FS_CONTAINER_ID_DEFAULT, fileinfo.getId()); + System.out.println("the url: " + url); + String strJson = new String(); + CloseableHttpClient httpClient = null; + CloseableHttpResponse response = null; + try { + httpClient = HttpClients.createDefault(); + + //构造一个post对象 + HttpPost httpPost = new HttpPost(url); + + // 把文件转换成流对象FileBody + FileBody inFile = new FileBody(new File(store_path)); + HttpEntity reqEntity = MultipartEntityBuilder.create().addPart("file", inFile).build(); + httpPost.setEntity(reqEntity); + + // 发起请求 并返回请求的响应 + response = httpClient.execute(httpPost); + + // 获取响应对象 + HttpEntity resEntity = response.getEntity(); + if (resEntity != null) { + strJson = EntityUtils.toString(resEntity, Charset.forName("UTF-8")); + //parse json + FileOpResponse objFileOpRsp = JSON.parseObject(strJson, FileOpResponse.class); + if (objFileOpRsp.getRet() != DfsConst.DFS_ERROR_OK + && objFileOpRsp.getRet() != DfsConst.DFS_ERROR_SUCCESS) { + // 销毁 + EntityUtils.consume(resEntity); + m_Ret = DfsConst.DFS_ERROR_FAIL; + m_Code = DfsConst.DFS_ERROR_FAIL; + return DfsConst.DFS_ERROR_FAIL; + } + + remoteHash.append(objFileOpRsp.getHash()); + } + + // 销毁 + EntityUtils.consume(resEntity); + }catch (Exception e){ + e.printStackTrace(); + m_Ret = DfsConst.DFS_ERROR_FAIL; + m_Info = "bad request or service unavaiable !"; + }finally { + try { + if(response != null){ + response.close(); + } + + if(httpClient != null){ + httpClient.close(); + } + } catch (IOException e) { + e.printStackTrace(); + m_Ret = DfsConst.DFS_ERROR_FAIL; + m_Code = DfsConst.DFS_ERROR_FAIL; + return DfsConst.DFS_ERROR_FAIL; + } + } + + return m_Ret; + } + + public int deleteFile(FileServer fileServer, String fileid) + { + resetState(); + + if (!m_Init) + { + m_Ret = DfsConst.DFS_ERROR_NOT_INITIALIZED; + m_Code = DfsConst.DFS_ERROR_NOT_INITIALIZED; + return DfsConst.DFS_ERROR_NOT_INITIALIZED; + } + + //url: http://host:port/fs/v1/files/fileid + String url = fillUrl(DfsConst.HTTP_FS_CONTAINER_ID_DEFAULT, fileid); + StringBuffer rspBuffer = new StringBuffer(); + + CloseableHttpClient httpClient = null; + CloseableHttpResponse response = null; + + httpClient = HttpClients.createDefault(); + + // 把一个普通参数和文件上传给下面这个地址 是一个servlet + HttpDelete httpDelete = new HttpDelete(url); + try { + response = httpClient.execute(httpDelete); + BufferedReader br = new BufferedReader(new InputStreamReader((response.getEntity().getContent()))); + + String output; + System.out.println("Output from Server .... \n"); + while ((output = br.readLine()) != null) { + rspBuffer.append(output); + } + + br.close(); + + } catch (IOException e) { + e.printStackTrace(); + m_Ret = DfsConst.DFS_ERROR_NETWORK_EXCEPTION; + m_Code = DfsConst.DFS_ERROR_NETWORK_EXCEPTION; + + } finally { + try { + if (response != null) + response.close(); + + if (httpClient != null) + httpClient.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + m_Ret = DfsConst.DFS_ERROR_FAIL; + m_Code = DfsConst.DFS_ERROR_FAIL; + return DfsConst.DFS_ERROR_FAIL; + } + + } + + //parse json + String strJson = rspBuffer.toString(); + FileOpResponse objFileOpRsp = JSON.parseObject(strJson, FileOpResponse.class); + if (objFileOpRsp.getRet() != DfsConst.DFS_ERROR_OK + && objFileOpRsp.getRet() != DfsConst.DFS_ERROR_SUCCESS) { + m_Ret = DfsConst.DFS_ERROR_FAIL; + m_Code = DfsConst.DFS_ERROR_FAIL; + return DfsConst.DFS_ERROR_FAIL; + } + + return m_Ret; + } + + public int modify(FileServer fileServer, String fileid, String filename) + { + resetState(); + + if (!m_Init) + return DfsConst.DFS_ERROR_NOT_INITIALIZED; + + if (fileid.isEmpty() || filename.isEmpty()) + return DfsConst.DFS_ERROR_BAD_PARAMETER; + + //url: http://host:port/fs/v1/files/fileid + String url = fillUrl(fileServer, DfsConst.HTTP_FS_CONTAINER_ID_DEFAULT, fileid); + StringBuffer rspBuffer = new StringBuffer(); + + CloseableHttpClient httpClient = null; + CloseableHttpResponse response = null; + + httpClient = HttpClients.createDefault(); + + // 把一个普通参数和文件上传给下面这个地址 是一个servlet + HttpPut httpPut = new HttpPut(url); + FileInfo objFileinfo = new FileInfo(); + objFileinfo.setId(fileid); + objFileinfo.setFilename(filename); + String json = JSON.toJSONString(objFileinfo); + StringEntity putString = null; + try { + putString = new StringEntity(json); + } catch (UnsupportedEncodingException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + m_Ret = DfsConst.DFS_ERROR_FAIL; + m_Code = DfsConst.DFS_ERROR_FAIL; + return DfsConst.DFS_ERROR_FAIL; + } + httpPut.setEntity(putString); + httpPut.setHeader("Content-type", "application/json"); + + try { + response = httpClient.execute(httpPut); + BufferedReader br = new BufferedReader(new InputStreamReader((response.getEntity().getContent()))); + + String output; + System.out.println("Output from Server .... \n"); + while ((output = br.readLine()) != null) { + rspBuffer.append(output); + } + br.close(); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + m_Ret = DfsConst.DFS_ERROR_FAIL; + m_Code = DfsConst.DFS_ERROR_FAIL; + } finally { + try { + if (response != null) + response.close(); + if (httpClient != null) + httpClient.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + m_Ret = DfsConst.DFS_ERROR_FAIL; + m_Code = DfsConst.DFS_ERROR_FAIL; + return DfsConst.DFS_ERROR_FAIL; + } + } + + return m_Ret; + } + + private String fillUrl(String container, String fileid) { + String url = new String(); + url = DfsConst.HTTP_STARTER; + url += m_Host; + url += ":"; + url += m_Port; + url += "/"; + url += DfsConst.HTTP_FS_MODULE; + url += "/"; + url += DfsConst.HTTP_FS_VERSION; + url += "/"; + url += container; + url += "/"; + url += fileid; + + return url; + } + + private String fillUrl(FileServer fileServer, String container, String fileid) { + String url = new String(); + url = DfsConst.HTTP_STARTER; + url += fileServer.getHost(); + url += ":"; + url += fileServer.getPort(); + url += "/"; + url += DfsConst.HTTP_FS_MODULE; + url += "/"; + url += DfsConst.HTTP_FS_VERSION; + url += "/"; + url += container; + url += "/"; + url += fileid; + + return url; + } + + private void resetState() { + m_Ret = DfsConst.DFS_ERROR_OK; + m_Code = DfsConst.DFS_ERROR_OK; + m_Info = ""; + } + + /** + * @return the m_Host + */ + public String getHost() { + return m_Host; + } + + /** + * @return the m_Port + */ + public int getPort() { + return m_Port; + } + + /** + * @return the m_Init + */ + public boolean isInit() { + return m_Init; + } + + /** + * @return the m_Ret + */ + public int getRet() { + return m_Ret; + } + + /** + * @return the m_Code + */ + public int getCode() { + return m_Code; + } + + /** + * @return the m_Info + */ + public String getInfo() { + return m_Info; + } + + /** + * @param m_Host the m_Host to set + */ + public void setHost(String m_Host) { + this.m_Host = m_Host; + } + + /** + * @param m_Port the m_Port to set + */ + public void setPort(int m_Port) { + this.m_Port = m_Port; + } + + /** + * @param m_Init the m_Init to set + */ + public void setInit(boolean m_Init) { + this.m_Init = m_Init; + } + + /** + * @param m_Ret the m_Ret to set + */ + public void setRet(int m_Ret) { + this.m_Ret = m_Ret; + } + + /** + * @param m_Code the m_Code to set + */ + public void setCode(int m_Code) { + this.m_Code = m_Code; + } + + /** + * @param m_Info the m_Info to set + */ + public void setInfo(String m_Info) { + this.m_Info = m_Info; + } +} diff --git a/tool/java/DfsSDK/src/com/dfs/message/CommonResponseData.java b/tool/java/DfsSDK/src/com/dfs/message/CommonResponseData.java new file mode 100644 index 0000000000..d79a283485 --- /dev/null +++ b/tool/java/DfsSDK/src/com/dfs/message/CommonResponseData.java @@ -0,0 +1,43 @@ +package com.dfs.message; + +import java.util.Vector; + +public class CommonResponseData { + private int total; + private Vector items; + + public CommonResponseData() { + total = 0; + items = new Vector(); + } + + /** + * @return the total + */ + public int getTotal() { + return total; + } + + /** + * @return the items + */ + public Vector getItems() { + return items; + } + + /** + * @param total the total to set + */ + public void setTotal(int total) { + this.total = total; + } + + /** + * @param items the items to set + */ + public void setItems(Vector items) { + this.items = items; + } + + +} diff --git a/tool/java/DfsSDK/src/com/dfs/message/CommonRespsoneJson.java b/tool/java/DfsSDK/src/com/dfs/message/CommonRespsoneJson.java new file mode 100644 index 0000000000..efe82873c2 --- /dev/null +++ b/tool/java/DfsSDK/src/com/dfs/message/CommonRespsoneJson.java @@ -0,0 +1,37 @@ +package com.dfs.message; + +public class CommonRespsoneJson { + private int ret; + private CommonResponseData data; + + public CommonRespsoneJson() { + ret = 0; + data = new CommonResponseData(); + } + + /** + * @return the ret + */ + public int getRet() { + return ret; + } + /** + * @return the data + */ + public CommonResponseData getData() { + return data; + } + /** + * @param ret the ret to set + */ + public void setRet(int ret) { + this.ret = ret; + } + /** + * @param data the data to set + */ + public void setData(CommonResponseData data) { + this.data = data; + } + +} diff --git a/tool/java/DfsSDK/src/com/dfs/message/FileInfo.java b/tool/java/DfsSDK/src/com/dfs/message/FileInfo.java new file mode 100644 index 0000000000..3e23649162 --- /dev/null +++ b/tool/java/DfsSDK/src/com/dfs/message/FileInfo.java @@ -0,0 +1,361 @@ +/** + * @Title: FileInfo.java + + * @date: 2017年3月2日 下午3:53:21 + + * @version: V1.0 + + */ + + +package com.dfs.message; + +/** + * @author Administrator + * + */ +public class FileInfo { + private String id;/** 文件ID */ + private String container;/** 容器ID(可选) */ + private String filename;/** 文件名称 */ + private int updateTime;/** 更新时间 */ + private int size;/** 文件大小 */ + private String owner;/** 文件owner */ + private String file_hash;/** md5 hash */ + private String src_node;/** 上传源节点ID */ + private String node_group;/** 节点群组ID */ + private int type;/** 文件类型 */ + private String priviliges;/** 文件权限 */ + private String info;/** 文件信息 */ + private int state;/** 文件状态 */ + + + public FileInfo() { + } + + + /** + * @return the id + */ + public String getId() { + return id; + } + + + /** + * @return the container + */ + public String getContainer() { + return container; + } + + + /** + * @return the filename + */ + public String getFilename() { + return filename; + } + + + /** + * @return the updateTime + */ + public int getUpdateTime() { + return updateTime; + } + + + /** + * @return the size + */ + public int getSize() { + return size; + } + + + /** + * @return the owner + */ + public String getOwner() { + return owner; + } + + + /** + * @return the file_hash + */ + public String getFile_hash() { + return file_hash; + } + + + /** + * @return the src_node + */ + public String getSrc_node() { + return src_node; + } + + + /** + * @return the node_group + */ + public String getNode_group() { + return node_group; + } + + + /** + * @return the type + */ + public int getType() { + return type; + } + + + /** + * @return the priviliges + */ + public String getPriviliges() { + return priviliges; + } + + + /** + * @return the info + */ + public String getInfo() { + return info; + } + + + /** + * @return the state + */ + public int getState() { + return state; + } + + + /** + * @param id the id to set + */ + public void setId(String id) { + this.id = id; + } + + + /** + * @param container the container to set + */ + public void setContainer(String container) { + this.container = container; + } + + + /** + * @param filename the filename to set + */ + public void setFilename(String filename) { + this.filename = filename; + } + + + /** + * @param updateTime the updateTime to set + */ + public void setUpdateTime(int updateTime) { + this.updateTime = updateTime; + } + + + /** + * @param size the size to set + */ + public void setSize(int size) { + this.size = size; + } + + + /** + * @param owner the owner to set + */ + public void setOwner(String owner) { + this.owner = owner; + } + + + /** + * @param file_hash the file_hash to set + */ + public void setFile_hash(String file_hash) { + this.file_hash = file_hash; + } + + + /** + * @param src_node the src_node to set + */ + public void setSrc_node(String src_node) { + this.src_node = src_node; + } + + + /** + * @param node_group the node_group to set + */ + public void setNode_group(String node_group) { + this.node_group = node_group; + } + + + /** + * @param type the type to set + */ + public void setType(int type) { + this.type = type; + } + + + /** + * @param priviliges the priviliges to set + */ + public void setPriviliges(String priviliges) { + this.priviliges = priviliges; + } + + + /** + * @param info the info to set + */ + public void setInfo(String info) { + this.info = info; + } + + + /** + * @param state the state to set + */ + public void setState(int state) { + this.state = state; + } + + + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((container == null) ? 0 : container.hashCode()); + result = prime * result + ((file_hash == null) ? 0 : file_hash.hashCode()); + result = prime * result + ((filename == null) ? 0 : filename.hashCode()); + result = prime * result + ((id == null) ? 0 : id.hashCode()); + result = prime * result + ((info == null) ? 0 : info.hashCode()); + result = prime * result + ((node_group == null) ? 0 : node_group.hashCode()); + result = prime * result + ((owner == null) ? 0 : owner.hashCode()); + result = prime * result + ((priviliges == null) ? 0 : priviliges.hashCode()); + result = prime * result + size; + result = prime * result + ((src_node == null) ? 0 : src_node.hashCode()); + result = prime * result + state; + result = prime * result + type; + result = prime * result + updateTime; + return result; + } + + + /* (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof FileInfo)) { + return false; + } + FileInfo other = (FileInfo) obj; + if (container == null) { + if (other.container != null) { + return false; + } + } else if (!container.equals(other.container)) { + return false; + } + if (file_hash == null) { + if (other.file_hash != null) { + return false; + } + } else if (!file_hash.equals(other.file_hash)) { + return false; + } + if (filename == null) { + if (other.filename != null) { + return false; + } + } else if (!filename.equals(other.filename)) { + return false; + } + if (id == null) { + if (other.id != null) { + return false; + } + } else if (!id.equals(other.id)) { + return false; + } + if (info == null) { + if (other.info != null) { + return false; + } + } else if (!info.equals(other.info)) { + return false; + } + if (node_group == null) { + if (other.node_group != null) { + return false; + } + } else if (!node_group.equals(other.node_group)) { + return false; + } + if (owner == null) { + if (other.owner != null) { + return false; + } + } else if (!owner.equals(other.owner)) { + return false; + } + if (priviliges == null) { + if (other.priviliges != null) { + return false; + } + } else if (!priviliges.equals(other.priviliges)) { + return false; + } + if (size != other.size) { + return false; + } + if (src_node == null) { + if (other.src_node != null) { + return false; + } + } else if (!src_node.equals(other.src_node)) { + return false; + } + if (state != other.state) { + return false; + } + if (type != other.type) { + return false; + } + if (updateTime != other.updateTime) { + return false; + } + return true; + } +} diff --git a/tool/java/DfsSDK/src/com/dfs/message/FileOpResponse.java b/tool/java/DfsSDK/src/com/dfs/message/FileOpResponse.java new file mode 100644 index 0000000000..293bd909d1 --- /dev/null +++ b/tool/java/DfsSDK/src/com/dfs/message/FileOpResponse.java @@ -0,0 +1,73 @@ +/** + * @Title: FileOpResponse.java + + * @Description: 文件操作响应 + + * @date: 2017年3月1日 下午6:12:48 + + * @version: V1.0 + + */ + +package com.dfs.message; + + +public class FileOpResponse { + private int ret; + private int code; + private String info; + private String hash; + + + public FileOpResponse() { + ret = 0; + code = 0; + info = ""; + } + + /** + * @return the ret + */ + public int getRet() { + return ret; + } + /** + * @return the code + */ + public int getCode() { + return code; + } + /** + * @return the info + */ + public String getInfo() { + return info; + } + /** + * @param ret the ret to set + */ + public void setRet(int ret) { + this.ret = ret; + } + /** + * @param code the code to set + */ + public void setCode(int code) { + this.code = code; + } + /** + * @param info the info to set + */ + public void setInfo(String info) { + this.info = info; + } + + public String getHash() { + // TODO Auto-generated method stub + return this.hash; + } + + public void setHash(String hash){ + this.hash = hash; + } +} diff --git a/tool/java/DfsSDK/src/com/dfs/message/FileServer.java b/tool/java/DfsSDK/src/com/dfs/message/FileServer.java new file mode 100644 index 0000000000..40236c3802 --- /dev/null +++ b/tool/java/DfsSDK/src/com/dfs/message/FileServer.java @@ -0,0 +1,227 @@ +/** + * @Title: FileServer.java + + * @date: 2017年3月2日 下午4:17:52 + + * @version: V1.0 + + */ +package com.dfs.message; + + +public class FileServer { + private String id;/** 服务节点ID */ + private String host;/** 主机地址 */ + private int port;/** 主机RPC端口 */ + private int updateTime;/** 更新时间 */ + private String organization;/** 组织名 */ + private String position;/** 位置 */ + private String group;/** 节点群组ID */ + private String info;/** 信息 */ + private int enable;/** 是否开启 */ + + public FileServer() { + super(); + // TODO Auto-generated constructor stub + } + + /** + * @return the id + */ + public String getId() { + return id; + } + /** + * @return the host + */ + public String getHost() { + return host; + } + /** + * @return the port + */ + public int getPort() { + return port; + } + /** + * @return the updateTime + */ + public int getUpdateTime() { + return updateTime; + } + /** + * @return the organization + */ + public String getOrganization() { + return organization; + } + /** + * @return the position + */ + public String getPosition() { + return position; + } + /** + * @return the group + */ + public String getGroup() { + return group; + } + /** + * @return the info + */ + public String getInfo() { + return info; + } + /** + * @param id the id to set + */ + public void setId(String id) { + this.id = id; + } + /** + * @param host the host to set + */ + public void setHost(String host) { + this.host = host; + } + /** + * @param port the port to set + */ + public void setPort(int port) { + this.port = port; + } + /** + * @param updateTime the updateTime to set + */ + public void setUpdateTime(int updateTime) { + this.updateTime = updateTime; + } + /** + * @param organization the organization to set + */ + public void setOrganization(String organization) { + this.organization = organization; + } + /** + * @param position the position to set + */ + public void setPosition(String position) { + this.position = position; + } + /** + * @param group the group to set + */ + public void setGroup(String group) { + this.group = group; + } + /** + * @param info the info to set + */ + public void setInfo(String info) { + this.info = info; + } + + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((group == null) ? 0 : group.hashCode()); + result = prime * result + ((host == null) ? 0 : host.hashCode()); + result = prime * result + ((id == null) ? 0 : id.hashCode()); + result = prime * result + ((info == null) ? 0 : info.hashCode()); + result = prime * result + ((organization == null) ? 0 : organization.hashCode()); + result = prime * result + port; + result = prime * result + ((position == null) ? 0 : position.hashCode()); + result = prime * result + updateTime; + return result; + } + + /* (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof FileServer)) { + return false; + } + FileServer other = (FileServer) obj; + if (group == null) { + if (other.group != null) { + return false; + } + } else if (!group.equals(other.group)) { + return false; + } + if (host == null) { + if (other.host != null) { + return false; + } + } else if (!host.equals(other.host)) { + return false; + } + if (id == null) { + if (other.id != null) { + return false; + } + } else if (!id.equals(other.id)) { + return false; + } + if (info == null) { + if (other.info != null) { + return false; + } + } else if (!info.equals(other.info)) { + return false; + } + if (organization == null) { + if (other.organization != null) { + return false; + } + } else if (!organization.equals(other.organization)) { + return false; + } + if (port != other.port) { + return false; + } + if (position == null) { + if (other.position != null) { + return false; + } + } else if (!position.equals(other.position)) { + return false; + } + if (updateTime != other.updateTime) { + return false; + } + + if (enable != other.enable) { + return false; + } + + return true; + } + + /** + * @return the enable + */ + public int getEnable() { + return enable; + } + + /** + * @param enable the enable to set + */ + public void setEnable(int enable) { + this.enable = enable; + } +} diff --git a/tool/java/DfsSDK/src/com/dfs/utils/DfsMD5.java b/tool/java/DfsSDK/src/com/dfs/utils/DfsMD5.java new file mode 100644 index 0000000000..efe2369fdb --- /dev/null +++ b/tool/java/DfsSDK/src/com/dfs/utils/DfsMD5.java @@ -0,0 +1,49 @@ +/** + * @Title: JuMD5.java + + * @date: 2017年3月8日 下午3:09:43 + + * @version: V1.0 + + */ +package com.dfs.utils; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; + +/** + * @author Administrator + * + */ + + +import org.apache.commons.codec.digest.DigestUtils; +import org.apache.commons.io.IOUtils; + +public class DfsMD5 { + + //静态方法,便于作为工具类 + public static String getMd5(String file) { + FileInputStream fis = null; + try { + fis = new FileInputStream(file); + } catch (FileNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + String md5 = null; + try { + md5 = DigestUtils.md5Hex(IOUtils.toByteArray(fis)); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + IOUtils.closeQuietly(fis); + //System.out.println("MD5:"+md5); + + return md5; + } + +} diff --git a/tool/java/DfsSDK/src/com/dfs/utils/DfsMutexLock.java b/tool/java/DfsSDK/src/com/dfs/utils/DfsMutexLock.java new file mode 100644 index 0000000000..1a9332b658 --- /dev/null +++ b/tool/java/DfsSDK/src/com/dfs/utils/DfsMutexLock.java @@ -0,0 +1,34 @@ +/** + * @Title: JuMutexLock.java + + * @date: 2017年3月9日 下午5:11:55 + + * @version: V1.0 + + */ +package com.dfs.utils; + +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +/** + * @author Administrator + * + */ +public class DfsMutexLock { + //需要声明这个锁 + private Lock lock; + + public DfsMutexLock() { + // TODO Auto-generated constructor stub + lock = new ReentrantLock(); + } + + public void lock(){ + lock.lock(); + } + + public void unlock(){ + lock.unlock(); + } +} diff --git a/tool/java/DfsSDK/src/com/dfs/utils/DfsTimer.java b/tool/java/DfsSDK/src/com/dfs/utils/DfsTimer.java new file mode 100644 index 0000000000..5a415606a5 --- /dev/null +++ b/tool/java/DfsSDK/src/com/dfs/utils/DfsTimer.java @@ -0,0 +1,24 @@ +package com.dfs.utils; + +import java.util.Calendar; + + +public class DfsTimer { + private long startTime; + private long endTime; + + public DfsTimer() { + startTime = Calendar.getInstance().getTimeInMillis(); + endTime = startTime; + } + + public void start() { + startTime = Calendar.getInstance().getTimeInMillis(); + } + + public long stop(){ + endTime = Calendar.getInstance().getTimeInMillis(); + System.out.println("cost time: " + (endTime - startTime)); + return (endTime - startTime); + } +} diff --git a/tool/java/DfsSDK/src/com/dfs/web3j/FileInfoManager.java b/tool/java/DfsSDK/src/com/dfs/web3j/FileInfoManager.java new file mode 100644 index 0000000000..80f44fabd2 --- /dev/null +++ b/tool/java/DfsSDK/src/com/dfs/web3j/FileInfoManager.java @@ -0,0 +1,276 @@ +package com.dfs.web3j; + +import java.lang.Override; +import java.lang.String; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.Future; +import org.web3j.abi.EventEncoder; +import org.web3j.abi.EventValues; +import org.web3j.abi.TypeReference; +import org.web3j.abi.datatypes.Address; +import org.web3j.abi.datatypes.Event; +import org.web3j.abi.datatypes.Function; +import org.web3j.abi.datatypes.Type; +import org.web3j.abi.datatypes.Utf8String; +import org.web3j.abi.datatypes.generated.Int256; +import org.web3j.abi.datatypes.generated.Uint256; +import org.web3j.crypto.Credentials; +import org.web3j.protocol.Web3j; +import org.web3j.protocol.core.DefaultBlockParameterName; +import org.web3j.protocol.core.methods.request.EthFilter; +import org.web3j.protocol.core.methods.response.Log; +import org.web3j.protocol.core.methods.response.TransactionReceipt; +import org.web3j.tx.Contract; +import org.web3j.tx.TransactionManager; +import rx.Observable; +import rx.functions.Func1; + +/** + *

Auto generated code.
+ * Do not modify!
+ * Please use {@link org.web3j.codegen.SolidityFunctionWrapperGenerator} to update. + * + *

Generated with web3j version 2.0.1. + */ +public final class FileInfoManager extends Contract { + private static final String BINARY = "60606040526000600155341561001157fe5b5b5b33600060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b60106012819055505b5b617ab5806200006f6000396000f30060606040523615610152576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063180db1b4146101545780631bd951551461017a57806324b508a3146101e8578063276e6472146102c95780632ced7cef1461033b578063310eff5d1461042f578063319af333146105195780633ca6268e146105a65780633d7403a31461061d5780633ffbd47f1461068f57806341304fac1461072c57806341c0e1b51461079a5780634b5c4277146107ac5780635e01eb5a1461085d57806378a9eeed146108f6578063800c7e381461098f57806382b7b500146109b5578063887240d014610a9657806388d97c3014610c40578063893d20e814610cae578063a87d942c14610d47578063b1498e2914610d6d578063b60e72cc14610ddf578063da421df514610e56578063e9e69a4814610f06578063ffcad44e14610f2c575bfe5b341561015c57fe5b610164610f9a565b6040518082815260200191505060405180910390f35b341561018257fe5b6101d2600480803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050610fa5565b6040518082815260200191505060405180910390f35b34156101f057fe5b610240600480803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190505061107f565b604051808060200182810382528381815181526020019150805190602001908083836000831461028f575b80518252602083111561028f5760208201915060208101905060208303925061026b565b505050905090810190601f1680156102bb5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34156102d157fe5b610321600480803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919050506114dd565b604051808215151515815260200191505060405180910390f35b341561034357fe5b610419600480803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190505061199d565b6040518082815260200191505060405180910390f35b341561043757fe5b610490600480803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091908035906020019091905050611a13565b60405180806020018281038252838181518152602001915080519060200190808383600083146104df575b8051825260208311156104df576020820191506020810190506020830392506104bb565b505050905090810190601f16801561050b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561052157fe5b610590600480803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506121de565b6040518082815260200191505060405180910390f35b34156105ae57fe5b610607600480803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091908035906020019091905050612265565b6040518082815260200191505060405180910390f35b341561062557fe5b610675600480803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919050506122d6565b604051808215151515815260200191505060405180910390f35b341561069757fe5b61072a600480803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050612938565b005b341561073457fe5b610784600480803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190505061293d565b6040518082815260200191505060405180910390f35b34156107a257fe5b6107aa612972565b005b34156107b457fe5b610847600480803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919050506129d1565b6040518082815260200191505060405180910390f35b341561086557fe5b61086d612a17565b60405180806020018281038252838181518152602001915080519060200190808383600083146108bc575b8051825260208311156108bc57602082019150602081019050602083039250610898565b505050905090810190601f1680156108e85780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34156108fe57fe5b610906612a44565b6040518080602001828103825283818151815260200191508051906020019080838360008314610955575b80518252602083111561095557602082019150602081019050602083039250610931565b505050905090810190601f1680156109815780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561099757fe5b61099f612d5c565b6040518082815260200191505060405180910390f35b34156109bd57fe5b610a0d600480803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050612db0565b6040518080602001828103825283818151815260200191508051906020019080838360008314610a5c575b805182526020831115610a5c57602082019150602081019050602083039250610a38565b505050905090810190601f168015610a885780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3415610a9e57fe5b610bb7600480803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190505061309a565b6040518080602001828103825283818151815260200191508051906020019080838360008314610c06575b805182526020831115610c0657602082019150602081019050602083039250610be2565b505050905090810190601f168015610c325780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3415610c4857fe5b610c98600480803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919050506132c7565b6040518082815260200191505060405180910390f35b3415610cb657fe5b610cbe61331c565b6040518080602001828103825283818151815260200191508051906020019080838360008314610d0d575b805182526020831115610d0d57602082019150602081019050602083039250610ce9565b505050905090810190601f168015610d395780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3415610d4f57fe5b610d5761336b565b6040518082815260200191505060405180910390f35b3415610d7557fe5b610dc5600480803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050613379565b604051808215151515815260200191505060405180910390f35b3415610de757fe5b610e40600480803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190803590602001909190505061395d565b6040518082815260200191505060405180910390f35b3415610e5e57fe5b610e7d60048080359060200190919080359060200190919050506139ca565b6040518080602001828103825283818151815260200191508051906020019080838360008314610ecc575b805182526020831115610ecc57602082019150602081019050602083039250610ea8565b505050905090810190601f168015610ef85780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3415610f0e57fe5b610f16613de7565b6040518082815260200191505060405180910390f35b3415610f3457fe5b610f84600480803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050613df2565b6040518082815260200191505060405180910390f35b600060015490505b90565b600060006000835191506020821115610fbd57602091505b60009250600090505b60208110156110775781811015611063578381815181101515610fe557fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027f0100000000000000000000000000000000000000000000000000000000000000900460ff16610100840201925061106b565b610100830292505b5b806001019050610fc6565b5b5050919050565b6110876177ec565b60006000604060405190810160405280601181526020017f7b22726574223a302c2264617461223a7b000000000000000000000000000000815250925061115c611115604060405190810160405280600581526020017f746f74616c00000000000000000000000000000000000000000000000000000081525060038054905061402a90919063ffffffff16565b604060405190810160405280600a81526020017f2c226974656d73223a5b00000000000000000000000000000000000000000000815250856143a49092919063ffffffff16565b925060009150600090505b60038054905081101561148a576112b084600260038481548110151561118957fe5b906000526020600020900160005b5060405180828054600181600116156101000203166002900480156111f35780601f106111d15761010080835404028352918201916111f3565b820191906000526020600020905b8154815290600101906020018083116111df575b505091505090815260200160405180910390206008018054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561129d5780601f106112725761010080835404028352916020019161129d565b820191906000526020600020905b81548152906001019060200180831161128057829003601f168201915b505050505061444490919063ffffffff16565b80156113715750600060018111156112c457fe5b60026003838154811015156112d557fe5b906000526020600020900160005b50604051808280546001816001161561010002031660029004801561133f5780601f1061131d57610100808354040283529182019161133f565b820191906000526020600020905b81548152906001019060200180831161132b575b50509150509081526020016040518091039020600c0160009054906101000a900460ff16600181111561136e57fe5b14155b1561147c5760008211156113cb576113c8604060405190810160405280600181526020017f2c000000000000000000000000000000000000000000000000000000000000008152508461458890919063ffffffff16565b92505b61147361146460026003848154811015156113e257fe5b906000526020600020900160005b50604051808280546001816001161561010002031660029004801561144c5780601f1061142a57610100808354040283529182019161144c565b820191906000526020600020905b815481529060010190602001808311611438575b505091505090815260200160405180910390206145f3565b8461458890919063ffffffff16565b92506001820191505b5b8080600101915050611167565b6114d3604060405190810160405280600381526020017f5d7d7d00000000000000000000000000000000000000000000000000000000008152508461458890919063ffffffff16565b92505b5050919050565b60006000600060018111156114ee57fe5b6002846040518082805190602001908083835b602083106115245780518252602082019150602081019050602083039250611501565b6001836020036101000a0380198251168184511680821785525050505050509050019150509081526020016040518091039020600c0160009054906101000a900460ff16600181111561157357fe5b1415611647576004600681111561158657fe5b6001819055506115cb604060405190810160405280601681526020017f64656c6574652066696c65206e6f74206578697374730000000000000000000081525061293d565b507f6f52e1083ea2b4deef2cb48dbb504881c8b27cfedc2d85bc841b9ed1613c54cc6001546040518082815260200180602001828103825260168152602001807f64656c6574652066696c65206e6f7420657869737473000000000000000000008152506020019250505060405180910390a160019150611997565b600460006116559190617800565b600090505b6003805490508110156117ac576117308360038381548110151561167a57fe5b906000526020600020900160005b508054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561171d5780601f106116f25761010080835404028352916020019161171d565b820191906000526020600020905b81548152906001019060200180831161170057829003601f168201915b505050505061444490919063ffffffff16565b1561173a576117a1565b6004805480600101828161174e9190617822565b916000526020600020900160005b60038481548110151561176b57fe5b906000526020600020900160005b509091909150908054600181600116156101000203166002900461179e92919061784e565b50505b80600101905061165a565b600360006117ba9190617800565b600090505b60048054905081101561183e57600380548060010182816117e09190617822565b916000526020600020900160005b6004848154811015156117fd57fe5b906000526020600020900160005b509091909150908054600181600116156101000203166002900461183092919061784e565b50505b8060010190506117bf565b60006002846040518082805190602001908083835b602083106118765780518252602082019150602081019050602083039250611853565b6001836020036101000a0380198251168184511680821785525050505050509050019150509081526020016040518091039020600c0160006101000a81548160ff021916908360018111156118c757fe5b0217905550600060068111156118d957fe5b60018190555061191f604060405190810160405280601981526020017f64656c6574652066696c6520737563636573732c2069643a2000000000000000815250846129d1565b507f6f52e1083ea2b4deef2cb48dbb504881c8b27cfedc2d85bc841b9ed1613c54cc6001546040518082815260200180602001828103825260138152602001807f64656c6574652066696c652073756363657373000000000000000000000000008152506020019250505060405180910390a1600191505b50919050565b60006119a76177ec565b602060405190810160405280600081525090506119cf8585836143a49092919063ffffffff16565b90506119da83610fa5565b600102600019166119ea82610fa5565b60010260405180826000191660001916815260200191505060405180910390a15b509392505050565b611a1b6177ec565b6000600060006000600060006000611a328a613df2565b965060009550600060125488811515611a4757fe5b061415611a635760125487811515611a5b57fe5b049550611a77565b600160125488811515611a7257fe5b040195505b6000891080611a8857506001860389115b15611b22577f46696c65496e666f4d616e61676572000000000000000000000000000000000060405180807f62616420706172616d657465727320696e2070616765427947726f7570000000815250601d01905060405180910390a1604060405190810160405280601f81526020017f7b22726574223a302c2264617461223a7b22746f74616c223a302c5b5d7d7d0081525097506121d1565b604060405190810160405280601181526020017f7b22726574223a302c2264617461223a7b0000000000000000000000000000008152509750611bee611ba7604060405190810160405280600581526020017f746f74616c0000000000000000000000000000000000000000000000000000008152508961402a90919063ffffffff16565b604060405190810160405280600a81526020017f2c226974656d73223a5b000000000000000000000000000000000000000000008152508a6143a49092919063ffffffff16565b9750886012540294506000935060009250600091505b600380549050821015611e395760006001811115611c1e57fe5b6002600384815481101515611c2f57fe5b906000526020600020900160005b506040518082805460018160011615610100020316600290048015611c995780601f10611c77576101008083540402835291820191611c99565b820191906000526020600020905b815481529060010190602001808311611c85575b50509150509081526020016040518091039020600c0160009054906101000a900460ff166001811115611cc857fe5b14158015611e0e5750611e0d8a6002600385815481101515611ce657fe5b906000526020600020900160005b506040518082805460018160011615610100020316600290048015611d505780601f10611d2e576101008083540402835291820191611d50565b820191906000526020600020905b815481529060010190602001808311611d3c575b505091505090815260200160405180910390206008018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611dfa5780601f10611dcf57610100808354040283529160200191611dfa565b820191906000526020600020905b815481529060010190602001808311611ddd57829003601f168201915b505050505061444490919063ffffffff16565b5b15611e1a576001840193505b8484101515611e2b57819250611e39565b5b8180600101925050611c04565b600090508291505b60038054905082108015611e56575060125481105b156121855760006001811115611e6857fe5b6002600384815481101515611e7957fe5b906000526020600020900160005b506040518082805460018160011615610100020316600290048015611ee35780601f10611ec1576101008083540402835291820191611ee3565b820191906000526020600020905b815481529060010190602001808311611ecf575b50509150509081526020016040518091039020600c0160009054906101000a900460ff166001811115611f1257fe5b1415801561205857506120578a6002600385815481101515611f3057fe5b906000526020600020900160005b506040518082805460018160011615610100020316600290048015611f9a5780601f10611f78576101008083540402835291820191611f9a565b820191906000526020600020905b815481529060010190602001808311611f86575b505091505090815260200160405180910390206008018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156120445780601f1061201957610100808354040283529160200191612044565b820191906000526020600020905b81548152906001019060200180831161202757829003601f168201915b505050505061444490919063ffffffff16565b5b156121775760018101905061210b6120fc600260038581548110151561207a57fe5b906000526020600020900160005b5060405180828054600181600116156101000203166002900480156120e45780601f106120c25761010080835404028352918201916120e4565b820191906000526020600020905b8154815290600101906020018083116120d0575b505091505090815260200160405180910390206145f3565b8961458890919063ffffffff16565b975060125481108015612125575060016003805490500382105b1561217657612173604060405190810160405280600181526020017f2c000000000000000000000000000000000000000000000000000000000000008152508961458890919063ffffffff16565b97505b5b5b8180600101925050611e41565b6121ce604060405190810160405280600381526020017f5d7d7d00000000000000000000000000000000000000000000000000000000008152508961458890919063ffffffff16565b97505b5050505050505092915050565b60006121e86177ec565b6020604051908101604052806000815250905061222e8461221e8573ffffffffffffffffffffffffffffffffffffffff1661518d565b836143a49092919063ffffffff16565b905061223981610fa5565b60010260405180826000191660001916815260200191505060405180910390a0600091505b5092915050565b600061226f6177ec565b6020604051908101604052806000815250905061229f8461228f8561539b565b836143a49092919063ffffffff16565b90506122aa81610fa5565b60010260405180826000191660001916815260200191505060405180910390a0600091505b5092915050565b60006122e2600561557a565b6122f682600561570a90919063ffffffff16565b15156123ca576001600681111561230957fe5b60018190555061234e604060405190810160405280600d81526020017f6261642066696c65206a736f6e0000000000000000000000000000000000000081525061293d565b507f6f52e1083ea2b4deef2cb48dbb504881c8b27cfedc2d85bc841b9ed1613c54cc60015460405180828152602001806020018281038252600d8152602001807f6261642066696c65206a736f6e000000000000000000000000000000000000008152506020019250505060405180910390a160009050612933565b600060018111156123d757fe5b6002600560000160405180828054600181600116156101000203166002900480156124395780601f10612417576101008083540402835291820191612439565b820191906000526020600020905b815481529060010190602001808311612425575b50509150509081526020016040518091039020600c0160009054906101000a900460ff16600181111561246857fe5b141561253c576004600681111561247b57fe5b6001819055506124c0604060405190810160405280601681526020017f7570646174652066696c65206e6f74206578697374730000000000000000000081525061293d565b507f6f52e1083ea2b4deef2cb48dbb504881c8b27cfedc2d85bc841b9ed1613c54cc6001546040518082815260200180602001828103825260168152602001807f7570646174652066696c65206e6f7420657869737473000000000000000000008152506020019250505060405180910390a160009050612933565b6125fc602060405190810160405280600081525060056001018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156125e95780601f106125be576101008083540402835291602001916125e9565b820191906000526020600020905b8154815290600101906020018083116125cc57829003601f168201915b505050505061444490919063ffffffff16565b505b60016005600c0160006101000a81548160ff0219169083600181111561262057fe5b02179055506103e8420260056003018190555060056002600560000160405180828054600181600116156101000203166002900480156126975780601f10612675576101008083540402835291820191612697565b820191906000526020600020905b815481529060010190602001808311612683575b50509150509081526020016040518091039020600082018160000190805460018160011615610100020316600290046126d19291906178d5565b50600182018160010190805460018160011615610100020316600290046126f99291906178d5565b50600282018160020190805460018160011615610100020316600290046127219291906178d5565b5060038201548160030155600482015481600401556005820181600501908054600181600116156101000203166002900461275d9291906178d5565b50600682018160060190805460018160011615610100020316600290046127859291906178d5565b50600782018160070190805460018160011615610100020316600290046127ad9291906178d5565b50600882018160080190805460018160011615610100020316600290046127d59291906178d5565b5060098201548160090155600a820181600a0190805460018160011615610100020316600290046128079291906178d5565b50600b820181600b01908054600181600116156101000203166002900461282f9291906178d5565b50600c820160009054906101000a900460ff1681600c0160006101000a81548160ff0219169083600181111561286157fe5b02179055509050506000600681111561287657fe5b6001819055506128bb604060405190810160405280601381526020017f7570646174652066696c6520737563636573730000000000000000000000000081525061293d565b507f6f52e1083ea2b4deef2cb48dbb504881c8b27cfedc2d85bc841b9ed1613c54cc6001546040518082815260200180602001828103825260138152602001807f7570646174652066696c652073756363657373000000000000000000000000008152506020019250505060405180910390a1600190505b919050565b5b5050565b600061294882610fa5565b60010260405180826000191660001916815260200191505060405180910390a0600090505b919050565b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156129ce576129cf565b5b565b60006129dc82610fa5565b600102600019166129ec84610fa5565b60010260405180826000191660001916815260200191505060405180910390a1600090505b92915050565b612a1f6177ec565b612a3e3373ffffffffffffffffffffffffffffffffffffffff16615af4565b90505b90565b612a4c6177ec565b60006000604060405190810160405280601181526020017f7b22726574223a302c2264617461223a7b0000000000000000000000000000008152509250612b21612ada604060405190810160405280600581526020017f746f74616c00000000000000000000000000000000000000000000000000000081525060038054905061402a90919063ffffffff16565b604060405190810160405280600a81526020017f2c226974656d73223a5b00000000000000000000000000000000000000000000815250856143a49092919063ffffffff16565b925060009150600090505b600380549050811015612d0b5760006001811115612b4657fe5b6002600383815481101515612b5757fe5b906000526020600020900160005b506040518082805460018160011615610100020316600290048015612bc15780601f10612b9f576101008083540402835291820191612bc1565b820191906000526020600020905b815481529060010190602001808311612bad575b50509150509081526020016040518091039020600c0160009054906101000a900460ff166001811115612bf057fe5b141515612cfd576000821115612c4c57612c49604060405190810160405280600181526020017f2c000000000000000000000000000000000000000000000000000000000000008152508461458890919063ffffffff16565b92505b612cf4612ce56002600384815481101515612c6357fe5b906000526020600020900160005b506040518082805460018160011615610100020316600290048015612ccd5780601f10612cab576101008083540402835291820191612ccd565b820191906000526020600020905b815481529060010190602001808311612cb9575b505091505090815260200160405180910390206145f3565b8461458890919063ffffffff16565b92506001820191505b5b8080600101915050612b2c565b612d54604060405190810160405280600381526020017f5d7d7d00000000000000000000000000000000000000000000000000000000008152508461458890919063ffffffff16565b92505b505090565b60006000601254600380549050811515612d7257fe5b061415612d9357601254600380549050811515612d8b57fe5b049050612dac565b6001601254600380549050811515612da757fe5b040190505b5b90565b612db86177ec565b604060405190810160405280601181526020017f7b22726574223a302c2264617461223a7b000000000000000000000000000000815250905060006001811115612dfe57fe5b6002836040518082805190602001908083835b60208310612e345780518252602082019150602081019050602083039250612e11565b6001836020036101000a0380198251168184511680821785525050505050509050019150509081526020016040518091039020600c0160009054906101000a900460ff166001811115612e8357fe5b141515612fae57612f22612edb604060405190810160405280600581526020017f746f74616c00000000000000000000000000000000000000000000000000000081525060038054905061402a90919063ffffffff16565b604060405190810160405280600a81526020017f2c226974656d73223a5b00000000000000000000000000000000000000000000815250836143a49092919063ffffffff16565b9050612fa7612f986002846040518082805190602001908083835b60208310612f605780518252602082019150602081019050602083039250612f3d565b6001836020036101000a03801982511681845116808217855250505050505090500191505090815260200160405180910390206145f3565b8261458890919063ffffffff16565b9050613049565b613046612fff604060405190810160405280600581526020017f746f74616c00000000000000000000000000000000000000000000000000000081525060038054905061402a90919063ffffffff16565b604060405190810160405280600a81526020017f2c226974656d73223a5b00000000000000000000000000000000000000000000815250836143a49092919063ffffffff16565b90505b613092604060405190810160405280600381526020017f5d7d7d00000000000000000000000000000000000000000000000000000000008152508261458890919063ffffffff16565b90505b919050565b6130a26177ec565b60006000869250613104866130f6604060405190810160405280600181526020017f2d000000000000000000000000000000000000000000000000000000000000008152508661458890919063ffffffff16565b61458890919063ffffffff16565b925061316185613153604060405190810160405280600181526020017f2d000000000000000000000000000000000000000000000000000000000000008152508661458890919063ffffffff16565b61458890919063ffffffff16565b92506103e8420291506131c5846131b7604060405190810160405280600181526020017f2d000000000000000000000000000000000000000000000000000000000000008152508661458890919063ffffffff16565b61458890919063ffffffff16565b925061322a6131d383615d06565b61321c604060405190810160405280600181526020017f2d000000000000000000000000000000000000000000000000000000000000008152508661458890919063ffffffff16565b61458890919063ffffffff16565b9250826040518082805190602001908083835b60208310613260578051825260208201915060208101905060208303925061323d565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390206001900490506132ba600260406132ab6132a685615e54565b616062565b6162879092919063ffffffff16565b92505b5050949350505050565b600060006132d483613df2565b90506000601254828115156132e557fe5b06141561330157601254818115156132f957fe5b049150613315565b60016012548281151561331057fe5b040191505b5b50919050565b6133246177ec565b613365600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16615af4565b90505b90565b600060038054905090505b90565b600061338f82600561570a90919063ffffffff16565b151561346357600160068111156133a257fe5b6001819055506133e7604060405190810160405280600f81526020017f626164206a736f6e2066696c652021000000000000000000000000000000000081525061293d565b507f6f52e1083ea2b4deef2cb48dbb504881c8b27cfedc2d85bc841b9ed1613c54cc60015460405180828152602001806020018281038252600d8152602001807f6261642066696c65206a736f6e000000000000000000000000000000000000008152506020019250505060405180910390a160009050613958565b6000600181111561347057fe5b6002600560000160405180828054600181600116156101000203166002900480156134d25780601f106134b05761010080835404028352918201916134d2565b820191906000526020600020905b8154815290600101906020018083116134be575b50509150509081526020016040518091039020600c0160009054906101000a900460ff16600181111561350157fe5b1415156135d6576004600681111561351557fe5b60018190555061355a604060405190810160405280601981526020017f7468652066696c6520616c72656164792065786973747320210000000000000081525061293d565b507f6f52e1083ea2b4deef2cb48dbb504881c8b27cfedc2d85bc841b9ed1613c54cc6001546040518082815260200180602001828103825260178152602001807f7468652066696c6520616c7265616479206578697374730000000000000000008152506020019250505060405180910390a160009050613958565b60016005600c0160006101000a81548160ff021916908360018111156135f857fe5b02179055506103e842026005600301819055506003805480600101828161361f9190617822565b916000526020600020900160005b60056000019091909150908054600181600116156101000203166002900461365692919061784e565b505060056002600560000160405180828054600181600116156101000203166002900480156136bc5780601f1061369a5761010080835404028352918201916136bc565b820191906000526020600020905b8154815290600101906020018083116136a8575b50509150509081526020016040518091039020600082018160000190805460018160011615610100020316600290046136f69291906178d5565b506001820181600101908054600181600116156101000203166002900461371e9291906178d5565b50600282018160020190805460018160011615610100020316600290046137469291906178d5565b506003820154816003015560048201548160040155600582018160050190805460018160011615610100020316600290046137829291906178d5565b50600682018160060190805460018160011615610100020316600290046137aa9291906178d5565b50600782018160070190805460018160011615610100020316600290046137d29291906178d5565b50600882018160080190805460018160011615610100020316600290046137fa9291906178d5565b5060098201548160090155600a820181600a01908054600181600116156101000203166002900461382c9291906178d5565b50600b820181600b0190805460018160011615610100020316600290046138549291906178d5565b50600c820160009054906101000a900460ff1681600c0160006101000a81548160ff0219169083600181111561388657fe5b02179055509050506000600681111561389b57fe5b6001819055506138e0604060405190810160405280601581526020017f696e736572742066696c6520737563636573732021000000000000000000000081525061293d565b507f6f52e1083ea2b4deef2cb48dbb504881c8b27cfedc2d85bc841b9ed1613c54cc6001546040518082815260200180602001828103825260138152602001807f696e736572742066696c652073756363657373000000000000000000000000008152506020019250505060405180910390a1600190505b919050565b60006139676177ec565b602060405190810160405280600081525090506139978461398785615d06565b836143a49092919063ffffffff16565b90506139a281610fa5565b60010260405180826000191660001916815260200191505060405180910390a05b5092915050565b6139d26177ec565b60006000600084860292506001858401039150600380549050831015806139fa575060008211155b15613acc57613a6e606060405190810160405280602781526020017f7b22726574223a302c2264617461223a7b22746f74616c223a302c226974656d81526020017f73223a5b5d7d7d000000000000000000000000000000000000000000000000008152508561458890919063ffffffff16565b93507f46696c65496e666f4d616e61676572000000000000000000000000000000000060405180807f62616420706172616d657465727320696e207061676546696c65730000000000815250601b01905060405180910390a1613dde565b604060405190810160405280601181526020017f7b22726574223a302c2264617461223a7b0000000000000000000000000000008152509350613b9d613b56604060405190810160405280600581526020017f746f74616c00000000000000000000000000000000000000000000000000000081525060038054905061402a90919063ffffffff16565b604060405190810160405280600a81526020017f2c226974656d73223a5b00000000000000000000000000000000000000000000815250866143a49092919063ffffffff16565b935060038054905082101515613bb95760016003805490500391505b8290505b8181111515613d925760006001811115613bd357fe5b6002600383815481101515613be457fe5b906000526020600020900160005b506040518082805460018160011615610100020316600290048015613c4e5780601f10613c2c576101008083540402835291820191613c4e565b820191906000526020600020905b815481529060010190602001808311613c3a575b50509150509081526020016040518091039020600c0160009054906101000a900460ff166001811115613c7d57fe5b141515613d8457613d2c613d1d6002600384815481101515613c9b57fe5b906000526020600020900160005b506040518082805460018160011615610100020316600290048015613d055780601f10613ce3576101008083540402835291820191613d05565b820191906000526020600020905b815481529060010190602001808311613cf1575b505091505090815260200160405180910390206145f3565b8561458890919063ffffffff16565b93508181141515613d8357613d80604060405190810160405280600181526020017f2c000000000000000000000000000000000000000000000000000000000000008152508561458890919063ffffffff16565b93505b5b5b8080600101915050613bbd565b613ddb604060405190810160405280600381526020017f5d7d7d00000000000000000000000000000000000000000000000000000000008152508561458890919063ffffffff16565b93505b50505092915050565b600060125490505b90565b6000600060009150600090505b6003805490508110156140235760006001811115613e1957fe5b6002600383815481101515613e2a57fe5b906000526020600020900160005b506040518082805460018160011615610100020316600290048015613e945780601f10613e72576101008083540402835291820191613e94565b820191906000526020600020905b815481529060010190602001808311613e80575b50509150509081526020016040518091039020600c0160009054906101000a900460ff166001811115613ec357fe5b141580156140095750614008836002600384815481101515613ee157fe5b906000526020600020900160005b506040518082805460018160011615610100020316600290048015613f4b5780601f10613f29576101008083540402835291820191613f4b565b820191906000526020600020905b815481529060010190602001808311613f37575b505091505090815260200160405180910390206008018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015613ff55780601f10613fca57610100808354040283529160200191613ff5565b820191906000526020600020905b815481529060010190602001808311613fd857829003601f168201915b505050505061444490919063ffffffff16565b5b15614015576001820191505b5b8080600101915050613dff565b5b50919050565b6140326177ec565b60006000600060006003865101935060008714156140555760018401935061407f565b8692505b600083111561407e57600a8381151561406e57fe5b0492508380600101945050614059565b5b8360405180591061408d5750595b908082528060200260200182016040525b509450600091507f220000000000000000000000000000000000000000000000000000000000000085838060010194508151811015156140da57fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600090505b85518110156141c357858181518110151561412657fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f010000000000000000000000000000000000000000000000000000000000000002858380600101945081518110151561418557fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053505b808060010191505061410f565b7f220000000000000000000000000000000000000000000000000000000000000085838060010194508151811015156141f857fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f3a00000000000000000000000000000000000000000000000000000000000000858380600101945081518110151561425d57fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060018403915060008714156143035760307f01000000000000000000000000000000000000000000000000000000000000000285838151811015156142ce57fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350614399565b5b6000871115614398576030600a8881151561431b57fe5b06017f01000000000000000000000000000000000000000000000000000000000000000285838060019003945081518110151561435457fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a8781151561439057fe5b049650614304565b5b5b5050505092915050565b6143ac6177ec565b60006000600060006000865188518a5101016040518059106143cb5750595b908082528060200260200182016040525b50955060208901945060208801935060208701925060208601915060009050614409818301868b5161630c565b88518101905061441d818301858a5161630c565b87518101905061443181830184895161630c565b8651810190505b50505050509392505050565b600060008251845114151561445c5760009150614581565b600090505b835181101561457c57828181518110151561447857fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191684828151811015156144f357fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415156145705760009150614581565b5b806001019050614461565b600191505b5092915050565b6145906177ec565b60006000600084518651016040518059106145a85750595b908082528060200260200182016040525b5093506020860192506020850191506020840190506145da8184885161630c565b6145e98651820183875161630c565b5b50505092915050565b6145fb6177ec565b604060405190810160405280600181526020017f7b00000000000000000000000000000000000000000000000000000000000000815250905061476361471c604060405190810160405280600281526020017f6964000000000000000000000000000000000000000000000000000000000000815250846000018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156147095780601f106146de57610100808354040283529160200191614709565b820191906000526020600020905b8154815290600101906020018083116146ec57829003601f168201915b505050505061635990919063ffffffff16565b604060405190810160405280600181526020017f2c00000000000000000000000000000000000000000000000000000000000000815250836143a49092919063ffffffff16565b905061489461484d604060405190810160405280600981526020017f636f6e7461696e65720000000000000000000000000000000000000000000000815250846001018054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561483a5780601f1061480f5761010080835404028352916020019161483a565b820191906000526020600020905b81548152906001019060200180831161481d57829003601f168201915b505050505061635990919063ffffffff16565b604060405190810160405280600181526020017f2c00000000000000000000000000000000000000000000000000000000000000815250836143a49092919063ffffffff16565b90506149c561497e604060405190810160405280600881526020017f66696c656e616d65000000000000000000000000000000000000000000000000815250846002018054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561496b5780601f106149405761010080835404028352916020019161496b565b820191906000526020600020905b81548152906001019060200180831161494e57829003601f168201915b505050505061635990919063ffffffff16565b604060405190810160405280600181526020017f2c00000000000000000000000000000000000000000000000000000000000000815250836143a49092919063ffffffff16565b9050614a5e614a17604060405190810160405280600a81526020017f75706461746554696d6500000000000000000000000000000000000000000000815250846003015461402a90919063ffffffff16565b604060405190810160405280600181526020017f2c00000000000000000000000000000000000000000000000000000000000000815250836143a49092919063ffffffff16565b9050614af7614ab0604060405190810160405280600481526020017f73697a6500000000000000000000000000000000000000000000000000000000815250846004015461402a90919063ffffffff16565b604060405190810160405280600181526020017f2c00000000000000000000000000000000000000000000000000000000000000815250836143a49092919063ffffffff16565b9050614c28614be1604060405190810160405280600981526020017f66696c655f686173680000000000000000000000000000000000000000000000815250846006018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015614bce5780601f10614ba357610100808354040283529160200191614bce565b820191906000526020600020905b815481529060010190602001808311614bb157829003601f168201915b505050505061635990919063ffffffff16565b604060405190810160405280600181526020017f2c00000000000000000000000000000000000000000000000000000000000000815250836143a49092919063ffffffff16565b9050614cc1614c7a604060405190810160405280600481526020017f7479706500000000000000000000000000000000000000000000000000000000815250846009015461402a90919063ffffffff16565b604060405190810160405280600181526020017f2c00000000000000000000000000000000000000000000000000000000000000815250836143a49092919063ffffffff16565b9050614df2614dab604060405190810160405280600a81526020017f70726976696c696765730000000000000000000000000000000000000000000081525084600a018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015614d985780601f10614d6d57610100808354040283529160200191614d98565b820191906000526020600020905b815481529060010190602001808311614d7b57829003601f168201915b505050505061635990919063ffffffff16565b604060405190810160405280600181526020017f2c00000000000000000000000000000000000000000000000000000000000000815250836143a49092919063ffffffff16565b9050614f23614edc604060405190810160405280600881526020017f7372635f6e6f6465000000000000000000000000000000000000000000000000815250846007018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015614ec95780601f10614e9e57610100808354040283529160200191614ec9565b820191906000526020600020905b815481529060010190602001808311614eac57829003601f168201915b505050505061635990919063ffffffff16565b604060405190810160405280600181526020017f2c00000000000000000000000000000000000000000000000000000000000000815250836143a49092919063ffffffff16565b905061505461500d604060405190810160405280600a81526020017f6e6f64655f67726f757000000000000000000000000000000000000000000000815250846008018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015614ffa5780601f10614fcf57610100808354040283529160200191614ffa565b820191906000526020600020905b815481529060010190602001808311614fdd57829003601f168201915b505050505061635990919063ffffffff16565b604060405190810160405280600181526020017f2c00000000000000000000000000000000000000000000000000000000000000815250836143a49092919063ffffffff16565b905061518561513e604060405190810160405280600481526020017f696e666f0000000000000000000000000000000000000000000000000000000081525084600b018054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561512b5780601f106151005761010080835404028352916020019161512b565b820191906000526020600020905b81548152906001019060200180831161510e57829003601f168201915b505050505061635990919063ffffffff16565b604060405190810160405280600181526020017f7d00000000000000000000000000000000000000000000000000000000000000815250836143a49092919063ffffffff16565b90505b919050565b6151956177ec565b60006000602a6040518059106151a85750595b908082528060200260200182016040525b5092507f30000000000000000000000000000000000000000000000000000000000000008360008151811015156151ec57fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000083600181518110151561524c57fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350602991505b60028260ff1610151561539357600f841690506010848115156152a057fe5b049350600a8160ff16101561531b57603081017f010000000000000000000000000000000000000000000000000000000000000002838360ff168151811015156152e657fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350615386565b6061600a8203017f010000000000000000000000000000000000000000000000000000000000000002838360ff1681518110151561535557fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053505b5b81600190039150615281565b5b5050919050565b6153a36177ec565b6000600060006000600060008714156153f457604060405190810160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509550615570565b8694506001935060009250600087121561541b578660000394506000935082806001019350505b8491505b600082111561544457600a8281151561543457fe5b049150828060010193505061541f565b8260ff166040518059106154555750595b908082528060200260200182016040525b5095508315156154d1577f2d000000000000000000000000000000000000000000000000000000000000008660008151811015156154a057fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053505b6001830390505b600085111561556f576030600a868115156154ef57fe5b06017f01000000000000000000000000000000000000000000000000000000000000000286828060019003935060ff1681518110151561552b57fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a8581151561556757fe5b0494506154d8565b5b5050505050919050565b60206040519081016040528060008152508160000190805190602001906155a292919061795c565b5060206040519081016040528060008152508160020190805190602001906155cb92919061795c565b5060206040519081016040528060008152508160010190805190602001906155f492919061795c565b5060008160040181905550602060405190810160405280600081525081600601908051906020019061562792919061795c565b50602060405190810160405280600081525081600801908051906020019061565092919061795c565b506000816009018190555060008160030181905550602060405190810160405280600081525081600a01908051906020019061568d92919061795c565b50602060405190810160405280600081525081600b0190805190602001906156b692919061795c565b5060206040519081016040528060008152508160070190805190602001906156df92919061795c565b50600081600c0160006101000a81548160ff0219169083600181111561570157fe5b02179055505b50565b60006157158361557a565b61575e604060405190810160405280600281526020017f6964000000000000000000000000000000000000000000000000000000000000815250836165d490919063ffffffff16565b83600001908051906020019061577592919061795c565b506157bf604060405190810160405280600881526020017f66696c656e616d65000000000000000000000000000000000000000000000000815250836165d490919063ffffffff16565b8360020190805190602001906157d692919061795c565b50615820604060405190810160405280600981526020017f636f6e7461696e65720000000000000000000000000000000000000000000000815250836165d490919063ffffffff16565b83600101908051906020019061583792919061795c565b50615881604060405190810160405280600481526020017f73697a650000000000000000000000000000000000000000000000000000000081525083616d2490919063ffffffff16565b83600401819055506158d2604060405190810160405280600981526020017f66696c655f686173680000000000000000000000000000000000000000000000815250836165d490919063ffffffff16565b8360060190805190602001906158e992919061795c565b50615933604060405190810160405280600481526020017f747970650000000000000000000000000000000000000000000000000000000081525083616d2490919063ffffffff16565b8360090181905550615984604060405190810160405280600a81526020017f70726976696c6967657300000000000000000000000000000000000000000000815250836165d490919063ffffffff16565b83600a01908051906020019061599b92919061795c565b506159e5604060405190810160405280600481526020017f696e666f00000000000000000000000000000000000000000000000000000000815250836165d490919063ffffffff16565b83600b0190805190602001906159fc92919061795c565b50615a46604060405190810160405280600881526020017f7372635f6e6f6465000000000000000000000000000000000000000000000000815250836165d490919063ffffffff16565b836007019080519060200190615a5d92919061795c565b50615aa7604060405190810160405280600a81526020017f6e6f64655f67726f757000000000000000000000000000000000000000000000815250836165d490919063ffffffff16565b836008019080519060200190615abe92919061795c565b506000836000018054600181600116156101000203166002900490501415615ae95760009050615aee565b600190505b92915050565b615afc6177ec565b615b046179dc565b60006000600060006028604051805910615b1b5750595b908082528060200260200182016040525b509450600093505b6014841015615cf8578360130360080260020a8773ffffffffffffffffffffffffffffffffffffffff16811515615b6757fe5b047f01000000000000000000000000000000000000000000000000000000000000000292506010837f0100000000000000000000000000000000000000000000000000000000000000900460ff16811515615bbe57fe5b047f0100000000000000000000000000000000000000000000000000000000000000029150817f01000000000000000000000000000000000000000000000000000000000000009004601002837f01000000000000000000000000000000000000000000000000000000000000009004037f0100000000000000000000000000000000000000000000000000000000000000029050615c5c826175cd565b8585600202815181101515615c6d57fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350615ca6816175cd565b8560018660020201815181101515615cba57fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053505b8380600101945050615b34565b8495505b5050505050919050565b615d0e6177ec565b6000600060006000851415615d5b57604060405190810160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509350615e4c565b600092508491505b6000821115615d8857600a82811515615d7857fe5b0491508280600101935050615d63565b8260ff16604051805910615d995750595b908082528060200260200182016040525b5093506001830390505b6000851115615e4b576030600a86811515615dcb57fe5b06017f01000000000000000000000000000000000000000000000000000000000000000284828060019003935060ff16815181101515615e0757fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a85811515615e4357fe5b049450615db4565b5b505050919050565b615e5c6177ec565b600060006042604051805910615e6f5750595b908082528060200260200182016040525b5092507f3000000000000000000000000000000000000000000000000000000000000000836000815181101515615eb357fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f7800000000000000000000000000000000000000000000000000000000000000836001815181101515615f1357fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350604191505b60028260ff1610151561605a57600f84169050601084811515615f6757fe5b049350600a8160ff161015615fe257603081017f010000000000000000000000000000000000000000000000000000000000000002838360ff16815181101515615fad57fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535061604d565b6061600a8203017f010000000000000000000000000000000000000000000000000000000000000002838360ff1681518110151561601c57fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053505b5b81600190039150615f48565b5b5050919050565b61606a6177ec565b6000600090505b825181101561627d577f410000000000000000000000000000000000000000000000000000000000000083828151811015156160a957fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916101580156161be57507f5a00000000000000000000000000000000000000000000000000000000000000838281518110151561614e57fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191611155b156162715760207f01000000000000000000000000000000000000000000000000000000000000000283828151811015156161f557fe5b90602001018181517f010000000000000000000000000000000000000000000000000000000000000090047f010000000000000000000000000000000000000000000000000000000000000002179150907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053505b5b806001019050616071565b8291505b50919050565b61628f6177ec565b60006000848651038411156162a5578486510393505b6000841115156162c75760206040519081016040528060008152509250616303565b836040518059106162d55750595b908082528060200260200182016040525b509250602086019150602083019050616302818684018661630c565b5b50509392505050565b60005b60208210151561633557825184526020840193506020830192505b60208203915061630f565b6001826020036101000a039050801983511681855116818117865250505b50505050565b6163616177ec565b6000600060006000600586518851010160405180591061637e5750595b908082528060200260200182016040525b509450602087019350602086019250602085019150600090507f220000000000000000000000000000000000000000000000000000000000000085828060010193508151811015156163dd57fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535061641b81830184885161630c565b8551810190507f2200000000000000000000000000000000000000000000000000000000000000858280600101935081518110151561645657fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f3a0000000000000000000000000000000000000000000000000000000000000085828060010193508151811015156164bb57fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f2200000000000000000000000000000000000000000000000000000000000000858280600101935081518110151561652057fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535061655e81830185895161630c565b8651810190507f2200000000000000000000000000000000000000000000000000000000000000858280600101935081518110151561659957fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053505b5050505092915050565b6165dc6177ec565b6000600060006000600060007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9550600094505b600115616b2d576166ac61669b89604060405190810160405280600181526020017f2200000000000000000000000000000000000000000000000000000000000000815250604060405190810160405280600181526020017f22000000000000000000000000000000000000000000000000000000000000008152506143a49092919063ffffffff16565b868b6176c29092919063ffffffff16565b95507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff86141561679b5761676b61675a89604060405190810160405280600181526020017f2700000000000000000000000000000000000000000000000000000000000000815250604060405190810160405280600181526020017f27000000000000000000000000000000000000000000000000000000000000008152506143a49092919063ffffffff16565b868b6176c29092919063ffffffff16565b95507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff86141561679a57616d18565b5b600288510186019550600093505b8851861015616b0b577f200000000000000000000000000000000000000000000000000000000000000089878151811015156167e157fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806168f357507f0900000000000000000000000000000000000000000000000000000000000000898781518110151561688457fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061699757507f0d00000000000000000000000000000000000000000000000000000000000000898781518110151561692857fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80616a3b57507f0a0000000000000000000000000000000000000000000000000000000000000089878151811015156169cc57fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b15616a4d578580600101965050616b06565b7f3a000000000000000000000000000000000000000000000000000000000000008987815181101515616a7c57fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415616b0057858060010196505060019350616b0b565b616b0b565b5b6167a9565b8851861415616b1957616d18565b8315616b2457616b2d565b8594505b616610565b60019250616b7c604060405190810160405280600181526020017f2200000000000000000000000000000000000000000000000000000000000000815250878b6176c29092919063ffffffff16565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415616c255760009250616bf5604060405190810160405280600181526020017f2700000000000000000000000000000000000000000000000000000000000000815250878b6176c29092919063ffffffff16565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415616c2457616d18565b5b6001820191508215616c8357616c7c604060405190810160405280600181526020017f2200000000000000000000000000000000000000000000000000000000000000815250838b6176c29092919063ffffffff16565b9050616cd1565b616cce604060405190810160405280600181526020017f2700000000000000000000000000000000000000000000000000000000000000815250838b6176c29092919063ffffffff16565b90505b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811415616cfe57616d18565b616d15828383038b6162879092919063ffffffff16565b96505b50505050505092915050565b6000600060006000600060006000600096507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9550600094505b60011561727b57616dfa616de989604060405190810160405280600181526020017f2200000000000000000000000000000000000000000000000000000000000000815250604060405190810160405280600181526020017f22000000000000000000000000000000000000000000000000000000000000008152506143a49092919063ffffffff16565b868b6176c29092919063ffffffff16565b95507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff861415616ee957616eb9616ea889604060405190810160405280600181526020017f2700000000000000000000000000000000000000000000000000000000000000815250604060405190810160405280600181526020017f27000000000000000000000000000000000000000000000000000000000000008152506143a49092919063ffffffff16565b868b6176c29092919063ffffffff16565b95507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff861415616ee8576175c1565b5b600288510186019550600093505b8851861015617259577f20000000000000000000000000000000000000000000000000000000000000008987815181101515616f2f57fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061704157507f09000000000000000000000000000000000000000000000000000000000000008987815181101515616fd257fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806170e557507f0d00000000000000000000000000000000000000000000000000000000000000898781518110151561707657fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061718957507f0a00000000000000000000000000000000000000000000000000000000000000898781518110151561711a57fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b1561719b578580600101965050617254565b7f3a0000000000000000000000000000000000000000000000000000000000000089878151811015156171ca57fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561724e57858060010196505060019350617259565b617259565b5b616ef7565b8851861415617267576175c1565b83156172725761727b565b8594505b616d5e565b8592505b885183101561737857888381518110151561729657fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027f01000000000000000000000000000000000000000000000000000000000000009004915060208260ff16148061731b575060098260ff16145b806173295750600d8260ff16145b806173375750600a8260ff16145b806173455750603a8260ff16145b80617353575060228260ff16145b80617361575060278260ff16145b151561736c57617378565b5b82600101925061727f565b600190507f2b0000000000000000000000000000000000000000000000000000000000000089848151811015156173ab57fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561742f576001905082806001019350506174df565b7f2d00000000000000000000000000000000000000000000000000000000000000898481518110151561745e57fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156174de576000905082806001019350505b5b5b88518310156175b25788838151811015156174f757fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027f01000000000000000000000000000000000000000000000000000000000000009004915060308260ff161015801561757f575060398260ff1611155b151561759857801515617593578660000396505b6175c1565b6030820360ff16600a88020196505b8260010192506174e0565b8015156175c0578660000396505b5b50505050505092915050565b6000600a7f010000000000000000000000000000000000000000000000000000000000000002827effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916101561766c576030827f01000000000000000000000000000000000000000000000000000000000000009004017f01000000000000000000000000000000000000000000000000000000000000000290506176bd565b6057827f01000000000000000000000000000000000000000000000000000000000000009004017f01000000000000000000000000000000000000000000000000000000000000000290506176bd565b5b919050565b6000600060006000602087019250602086019150826176e98689510387860189518661772c565b03905086518110156176fd57809350617721565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff93505b5b5050509392505050565b6000600060006000600088871115156177da5760208711151561778f5760018760200360080260020a031980875116888b038a018a96505b81838851161461778457600187019650806001880310617764578b8b0196505b5050508394506177e0565b8686209150879350600092505b868903831115156177d85786842090508060001916826000191614156177c4578394506177e0565b6001840193505b828060010193505061779c565b5b5b88880194505b50505050949350505050565b602060405190810160405280600081525090565b508054600082559060005260206000209081019061781e91906179f0565b5b50565b8154818355818115116178495781836000526020600020918201910161784891906179f0565b5b505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061788757805485556178c4565b828001600101855582156178c457600052602060002091601f016020900482015b828111156178c35782548255916001019190600101906178a8565b5b5090506178d19190617a1c565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061790e578054855561794b565b8280016001018555821561794b57600052602060002091601f016020900482015b8281111561794a57825482559160010191906001019061792f565b5b5090506179589190617a1c565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061799d57805160ff19168380011785556179cb565b828001600101855582156179cb579182015b828111156179ca5782518255916020019190600101906179af565b5b5090506179d89190617a1c565b5090565b602060405190810160405280600081525090565b617a1991905b80821115617a155760008181617a0c9190617a41565b506001016179f6565b5090565b90565b617a3e91905b80821115617a3a576000816000905550600101617a22565b5090565b90565b50805460018160011615610100020316600290046000825580601f10617a675750617a86565b601f016020900490600052602060002090810190617a859190617a1c565b5b505600a165627a7a72305820f54abace1701ba15f6c760a7a6260d485c9bba4737a068d12e837fce14fba4b10029"; + + private FileInfoManager(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) { + super(contractAddress, web3j, credentials, gasPrice, gasLimit); + } + + private FileInfoManager(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) { + super(contractAddress, web3j, transactionManager, gasPrice, gasLimit); + } + + public List getNotifyEvents(TransactionReceipt transactionReceipt) { + final Event event = new Event("Notify", + Arrays.>asList(), + Arrays.>asList(new TypeReference() {}, new TypeReference() {})); + List valueList = extractEventParameters(event,transactionReceipt); + ArrayList responses = new ArrayList(valueList.size()); + for(EventValues eventValues : valueList) { + NotifyEventResponse typedResponse = new NotifyEventResponse(); + typedResponse._errno = (Uint256)eventValues.getNonIndexedValues().get(0); + typedResponse._info = (Utf8String)eventValues.getNonIndexedValues().get(1); + responses.add(typedResponse); + } + return responses; + } + + public Observable notifyEventObservable() { + final Event event = new Event("Notify", + Arrays.>asList(), + Arrays.>asList(new TypeReference() {}, new TypeReference() {})); + EthFilter filter = new EthFilter(DefaultBlockParameterName.EARLIEST,DefaultBlockParameterName.LATEST, getContractAddress()); + filter.addSingleTopic(EventEncoder.encode(event)); + return web3j.ethLogObservable(filter).map(new Func1() { + @Override + public NotifyEventResponse call(Log log) { + EventValues eventValues = extractEventParameters(event, log); + NotifyEventResponse typedResponse = new NotifyEventResponse(); + typedResponse._errno = (Uint256)eventValues.getNonIndexedValues().get(0); + typedResponse._info = (Utf8String)eventValues.getNonIndexedValues().get(1); + return typedResponse; + } + }); + } + + public Future getErrno() { + Function function = new Function("getErrno", + Arrays.asList(), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future stringToUint(Utf8String _str) { + Function function = new Function("stringToUint", + Arrays.asList(_str), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future listByGroup(Utf8String _group) { + Function function = new Function("listByGroup", + Arrays.asList(_group), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future deleteById(Utf8String _fileId) { + Function function = new Function("deleteById", Arrays.asList(_fileId), Collections.>emptyList()); + return executeTransactionAsync(function); + } + + public Future log(Utf8String _str, Utf8String _str2, Utf8String _topic) { + Function function = new Function("log", + Arrays.asList(_str, _str2, _topic), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future pageByGroup(Utf8String _group, Uint256 _pageNo) { + Function function = new Function("pageByGroup", + Arrays.asList(_group, _pageNo), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future log(Utf8String _str, Address _addr) { + Function function = new Function("log", + Arrays.asList(_str, _addr), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future log(Utf8String _str, Int256 _i) { + Function function = new Function("log", + Arrays.asList(_str, _i), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future update(Utf8String _fileJson) { + Function function = new Function("update", Arrays.asList(_fileJson), Collections.>emptyList()); + return executeTransactionAsync(function); + } + + public Future register(Utf8String _name, Utf8String _version) { + Function function = new Function("register", Arrays.asList(_name, _version), Collections.>emptyList()); + return executeTransactionAsync(function); + } + + public Future log(Utf8String _str) { + Function function = new Function("log", + Arrays.asList(_str), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future kill() { + Function function = new Function("kill", Arrays.asList(), Collections.>emptyList()); + return executeTransactionAsync(function); + } + + public Future log(Utf8String _str, Utf8String _topic) { + Function function = new Function("log", + Arrays.asList(_str, _topic), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future getSender() { + Function function = new Function("getSender", + Arrays.asList(), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future listAll() { + Function function = new Function("listAll", + Arrays.asList(), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future getCurrentPageCount() { + Function function = new Function("getCurrentPageCount", + Arrays.asList(), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future find(Utf8String _fileId) { + Function function = new Function("find", + Arrays.asList(_fileId), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future generateFileID(Utf8String _salt, Utf8String _groupID, Utf8String _serverId, Utf8String _filename) { + Function function = new Function("generateFileID", + Arrays.asList(_salt, _groupID, _serverId, _filename), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future getGroupPageCount(Utf8String _group) { + Function function = new Function("getGroupPageCount", + Arrays.asList(_group), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future getOwner() { + Function function = new Function("getOwner", + Arrays.asList(), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future getCount() { + Function function = new Function("getCount", + Arrays.asList(), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future insert(Utf8String _fileJson) { + Function function = new Function("insert", Arrays.asList(_fileJson), Collections.>emptyList()); + return executeTransactionAsync(function); + } + + public Future log(Utf8String _str, Uint256 _ui) { + Function function = new Function("log", + Arrays.asList(_str, _ui), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future pageFiles(Uint256 _pageNo, Uint256 _pageSize) { + Function function = new Function("pageFiles", + Arrays.asList(_pageNo, _pageSize), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future getCurrentPageSize() { + Function function = new Function("getCurrentPageSize", + Arrays.asList(), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future getGroupFileCount(Utf8String _group) { + Function function = new Function("getGroupFileCount", + Arrays.asList(_group), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public static Future deploy(Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit, BigInteger initialValue) { + return deployAsync(FileInfoManager.class, web3j, credentials, gasPrice, gasLimit, BINARY, "", initialValue); + } + + public static Future deploy(Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit, BigInteger initialValue) { + return deployAsync(FileInfoManager.class, web3j, transactionManager, gasPrice, gasLimit, BINARY, "", initialValue); + } + + public static FileInfoManager load(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) { + return new FileInfoManager(contractAddress, web3j, credentials, gasPrice, gasLimit); + } + + public static FileInfoManager load(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) { + return new FileInfoManager(contractAddress, web3j, transactionManager, gasPrice, gasLimit); + } + + public static class NotifyEventResponse { + public Uint256 _errno; + + public Utf8String _info; + } +} diff --git a/tool/java/DfsSDK/src/com/dfs/web3j/FileServerManager.java b/tool/java/DfsSDK/src/com/dfs/web3j/FileServerManager.java new file mode 100644 index 0000000000..716f9b05aa --- /dev/null +++ b/tool/java/DfsSDK/src/com/dfs/web3j/FileServerManager.java @@ -0,0 +1,246 @@ +package com.dfs.web3j; + +import java.lang.Override; +import java.lang.String; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.Future; +import org.web3j.abi.EventEncoder; +import org.web3j.abi.EventValues; +import org.web3j.abi.TypeReference; +import org.web3j.abi.datatypes.Address; +import org.web3j.abi.datatypes.Event; +import org.web3j.abi.datatypes.Function; +import org.web3j.abi.datatypes.Type; +import org.web3j.abi.datatypes.Utf8String; +import org.web3j.abi.datatypes.generated.Int256; +import org.web3j.abi.datatypes.generated.Uint256; +import org.web3j.crypto.Credentials; +import org.web3j.protocol.Web3j; +import org.web3j.protocol.core.DefaultBlockParameterName; +import org.web3j.protocol.core.methods.request.EthFilter; +import org.web3j.protocol.core.methods.response.Log; +import org.web3j.protocol.core.methods.response.TransactionReceipt; +import org.web3j.tx.Contract; +import org.web3j.tx.TransactionManager; +import rx.Observable; +import rx.functions.Func1; + +/** + *

Auto generated code.
+ * Do not modify!
+ * Please use {@link org.web3j.codegen.SolidityFunctionWrapperGenerator} to update. + * + *

Generated with web3j version 2.0.1. + */ +public final class FileServerManager extends Contract { + private static final String BINARY = "60606040526000600155341561001157fe5b5b5b33600060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5b5b6167c680620000676000396000f30060606040523615610126576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063180db1b4146101285780631bd951551461014e57806324b508a3146101bc578063276e64721461029d5780632ced7cef1461030f578063319af333146104035780633ca6268e146104905780633d7403a3146105075780633ffbd47f1461057957806341304fac1461061657806341c0e1b5146106845780634b5c4277146106965780635e01eb5a1461074757806378a9eeed146107e057806382b7b50014610879578063893d20e81461095a578063a0d578f4146109f3578063a87d942c14610a61578063b1498e2914610a87578063b2a840c014610af9578063b60e72cc14610b74578063ca0941b414610beb575bfe5b341561013057fe5b610138610cd5565b6040518082815260200191505060405180910390f35b341561015657fe5b6101a6600480803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050610ce0565b6040518082815260200191505060405180910390f35b34156101c457fe5b610214600480803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050610dba565b6040518080602001828103825283818151815260200191508051906020019080838360008314610263575b8051825260208311156102635760208201915060208101905060208303925061023f565b505050905090810190601f16801561028f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34156102a557fe5b6102f5600480803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050611218565b604051808215151515815260200191505060405180910390f35b341561031757fe5b6103ed600480803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919050506116d8565b6040518082815260200191505060405180910390f35b341561040b57fe5b61047a600480803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061174e565b6040518082815260200191505060405180910390f35b341561049857fe5b6104f1600480803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919080359060200190919050506117d5565b6040518082815260200191505060405180910390f35b341561050f57fe5b61055f600480803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050611846565b604051808215151515815260200191505060405180910390f35b341561058157fe5b610614600480803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050611d6e565b005b341561061e57fe5b61066e600480803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050611d73565b6040518082815260200191505060405180910390f35b341561068c57fe5b610694611da8565b005b341561069e57fe5b610731600480803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050611e07565b6040518082815260200191505060405180910390f35b341561074f57fe5b610757611e4d565b60405180806020018281038252838181518152602001915080519060200190808383600083146107a6575b8051825260208311156107a657602082019150602081019050602083039250610782565b505050905090810190601f1680156107d25780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34156107e857fe5b6107f0611e7a565b604051808060200182810382528381815181526020019150805190602001908083836000831461083f575b80518252602083111561083f5760208201915060208101905060208303925061081b565b505050905090810190601f16801561086b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561088157fe5b6108d1600480803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050612192565b6040518080602001828103825283818151815260200191508051906020019080838360008314610920575b805182526020831115610920576020820191506020810190506020830392506108fc565b505050905090810190601f16801561094c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561096257fe5b61096a61247d565b60405180806020018281038252838181518152602001915080519060200190808383600083146109b9575b8051825260208311156109b957602082019150602081019050602083039250610995565b505050905090810190601f1680156109e55780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34156109fb57fe5b610a4b600480803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919050506124cc565b6040518082815260200191505060405180910390f35b3415610a6957fe5b610a716125f4565b6040518082815260200191505060405180910390f35b3415610a8f57fe5b610adf600480803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050612602565b604051808215151515815260200191505060405180910390f35b3415610b0157fe5b610b5a600480803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091908035906020019091905050612b6e565b604051808215151515815260200191505060405180910390f35b3415610b7c57fe5b610bd5600480803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091908035906020019091905050613063565b6040518082815260200191505060405180910390f35b3415610bf357fe5b610c4c600480803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919080359060200190919050506130d0565b6040518080602001828103825283818151815260200191508051906020019080838360008314610c9b575b805182526020831115610c9b57602082019150602081019050602083039250610c77565b505050905090810190601f168015610cc75780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b600060015490505b90565b600060006000835191506020821115610cf857602091505b60009250600090505b6020811015610db25781811015610d9e578381815181101515610d2057fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027f0100000000000000000000000000000000000000000000000000000000000000900460ff166101008402019250610da6565b610100830292505b5b806001019050610d01565b5b5050919050565b610dc26164fd565b60006000604060405190810160405280601181526020017f7b22726574223a302c2264617461223a7b0000000000000000000000000000008152509250610e97610e50604060405190810160405280600581526020017f746f74616c0000000000000000000000000000000000000000000000000000008152506003805490506134e490919063ffffffff16565b604060405190810160405280600a81526020017f2c226974656d73223a5b000000000000000000000000000000000000000000008152508561385e9092919063ffffffff16565b925060009150600090505b6003805490508110156111c55760006001811115610ebc57fe5b6002600383815481101515610ecd57fe5b906000526020600020900160005b506040518082805460018160011615610100020316600290048015610f375780601f10610f15576101008083540402835291820191610f37565b820191906000526020600020905b815481529060010190602001808311610f23575b5050915050908152602001604051809103902060090160009054906101000a900460ff166001811115610f6657fe5b141580156110ac57506110ab846002600384815481101515610f8457fe5b906000526020600020900160005b506040518082805460018160011615610100020316600290048015610fee5780601f10610fcc576101008083540402835291820191610fee565b820191906000526020600020905b815481529060010190602001808311610fda575b505091505090815260200160405180910390206006018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156110985780601f1061106d57610100808354040283529160200191611098565b820191906000526020600020905b81548152906001019060200180831161107b57829003601f168201915b50505050506138fe90919063ffffffff16565b5b156111b757600082111561110657611103604060405190810160405280600181526020017f2c0000000000000000000000000000000000000000000000000000000000000081525084613a4290919063ffffffff16565b92505b6001820191506111b46111a5600260038481548110151561112357fe5b906000526020600020900160005b50604051808280546001816001161561010002031660029004801561118d5780601f1061116b57610100808354040283529182019161118d565b820191906000526020600020905b815481529060010190602001808311611179575b50509150509081526020016040518091039020613aad565b84613a4290919063ffffffff16565b92505b5b8080600101915050610ea2565b61120e604060405190810160405280600381526020017f5d7d7d000000000000000000000000000000000000000000000000000000000081525084613a4290919063ffffffff16565b92505b5050919050565b600060006000600181111561122957fe5b6002846040518082805190602001908083835b6020831061125f578051825260208201915060208101905060208303925061123c565b6001836020036101000a038019825116818451168082178552505050505050905001915050908152602001604051809103902060090160009054906101000a900460ff1660018111156112ae57fe5b141561138257600460058111156112c157fe5b600181905550611306604060405190810160405280601881526020017f64656c65746520736572766572206e6f74206578697374730000000000000000815250611d73565b507f6f52e1083ea2b4deef2cb48dbb504881c8b27cfedc2d85bc841b9ed1613c54cc6001546040518082815260200180602001828103825260188152602001807f64656c65746520736572766572206e6f742065786973747300000000000000008152506020019250505060405180910390a1600191506116d2565b600460006113909190616511565b600090505b6003805490508110156114e75761146b836003838154811015156113b557fe5b906000526020600020900160005b508054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156114585780601f1061142d57610100808354040283529160200191611458565b820191906000526020600020905b81548152906001019060200180831161143b57829003601f168201915b50505050506138fe90919063ffffffff16565b15611475576114dc565b600480548060010182816114899190616533565b916000526020600020900160005b6003848154811015156114a657fe5b906000526020600020900160005b50909190915090805460018160011615610100020316600290046114d992919061655f565b50505b806001019050611395565b600360006114f59190616511565b600090505b600480549050811015611579576003805480600101828161151b9190616533565b916000526020600020900160005b60048481548110151561153857fe5b906000526020600020900160005b509091909150908054600181600116156101000203166002900461156b92919061655f565b50505b8060010190506114fa565b60006002846040518082805190602001908083835b602083106115b1578051825260208201915060208101905060208303925061158e565b6001836020036101000a038019825116818451168082178552505050505050905001915050908152602001604051809103902060090160006101000a81548160ff0219169083600181111561160257fe5b02179055506000600581111561161457fe5b60018190555061165a604060405190810160405280601b81526020017f64656c6574652073657276657220737563636573732c2069643a20000000000081525084611e07565b507f6f52e1083ea2b4deef2cb48dbb504881c8b27cfedc2d85bc841b9ed1613c54cc6001546040518082815260200180602001828103825260158152602001807f64656c65746520736572766572207375636365737300000000000000000000008152506020019250505060405180910390a1600191505b50919050565b60006116e26164fd565b6020604051908101604052806000815250905061170a85858361385e9092919063ffffffff16565b905061171583610ce0565b6001026000191661172582610ce0565b60010260405180826000191660001916815260200191505060405180910390a15b509392505050565b60006117586164fd565b6020604051908101604052806000815250905061179e8461178e8573ffffffffffffffffffffffffffffffffffffffff166143e5565b8361385e9092919063ffffffff16565b90506117a981610ce0565b60010260405180826000191660001916815260200191505060405180910390a0600091505b5092915050565b60006117df6164fd565b6020604051908101604052806000815250905061180f846117ff856145f3565b8361385e9092919063ffffffff16565b905061181a81610ce0565b60010260405180826000191660001916815260200191505060405180910390a0600091505b5092915050565b600061185260056147d2565b61186682600561491090919063ffffffff16565b151561193a576001600581111561187957fe5b6001819055506118be604060405190810160405280600d81526020017f6261642066696c65206a736f6e00000000000000000000000000000000000000815250611d73565b507f6f52e1083ea2b4deef2cb48dbb504881c8b27cfedc2d85bc841b9ed1613c54cc60015460405180828152602001806020018281038252600d8152602001807f6261642066696c65206a736f6e000000000000000000000000000000000000008152506020019250505060405180910390a160009050611d69565b6000600181111561194757fe5b6002600560000160405180828054600181600116156101000203166002900480156119a95780601f106119875761010080835404028352918201916119a9565b820191906000526020600020905b815481529060010190602001808311611995575b5050915050908152602001604051809103902060090160009054906101000a900460ff1660018111156119d857fe5b1415611aac57600460058111156119eb57fe5b600181905550611a30604060405190810160405280601681526020017f7570646174652066696c65206e6f742065786973747300000000000000000000815250611d73565b507f6f52e1083ea2b4deef2cb48dbb504881c8b27cfedc2d85bc841b9ed1613c54cc6001546040518082815260200180602001828103825260168152602001807f7570646174652066696c65206e6f7420657869737473000000000000000000008152506020019250505060405180910390a160009050611d69565b6001600560090160006101000a81548160ff02191690836001811115611ace57fe5b02179055506103e842026005600301819055506005600260056000016040518082805460018160011615610100020316600290048015611b455780601f10611b23576101008083540402835291820191611b45565b820191906000526020600020905b815481529060010190602001808311611b31575b5050915050908152602001604051809103902060008201816000019080546001816001161561010002031660029004611b7f9291906165e6565b5060018201816001019080546001816001161561010002031660029004611ba79291906165e6565b50600282015481600201556003820154816003015560048201816004019080546001816001161561010002031660029004611be39291906165e6565b5060058201816005019080546001816001161561010002031660029004611c0b9291906165e6565b5060068201816006019080546001816001161561010002031660029004611c339291906165e6565b5060078201816007019080546001816001161561010002031660029004611c5b9291906165e6565b50600882015481600801556009820160009054906101000a900460ff168160090160006101000a81548160ff02191690836001811115611c9757fe5b021790555090505060006005811115611cac57fe5b600181905550611cf1604060405190810160405280601381526020017f7570646174652066696c65207375636365737300000000000000000000000000815250611d73565b507f6f52e1083ea2b4deef2cb48dbb504881c8b27cfedc2d85bc841b9ed1613c54cc6001546040518082815260200180602001828103825260138152602001807f7570646174652066696c652073756363657373000000000000000000000000008152506020019250505060405180910390a1600190505b919050565b5b5050565b6000611d7e82610ce0565b60010260405180826000191660001916815260200191505060405180910390a0600090505b919050565b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611e0457611e05565b5b565b6000611e1282610ce0565b60010260001916611e2284610ce0565b60010260405180826000191660001916815260200191505060405180910390a1600090505b92915050565b611e556164fd565b611e743373ffffffffffffffffffffffffffffffffffffffff16614c38565b90505b90565b611e826164fd565b60006000604060405190810160405280601181526020017f7b22726574223a302c2264617461223a7b0000000000000000000000000000008152509250611f57611f10604060405190810160405280600581526020017f746f74616c0000000000000000000000000000000000000000000000000000008152506003805490506134e490919063ffffffff16565b604060405190810160405280600a81526020017f2c226974656d73223a5b000000000000000000000000000000000000000000008152508561385e9092919063ffffffff16565b925060009150600090505b6003805490508110156121415760006001811115611f7c57fe5b6002600383815481101515611f8d57fe5b906000526020600020900160005b506040518082805460018160011615610100020316600290048015611ff75780601f10611fd5576101008083540402835291820191611ff7565b820191906000526020600020905b815481529060010190602001808311611fe3575b5050915050908152602001604051809103902060090160009054906101000a900460ff16600181111561202657fe5b1415156121335760008211156120825761207f604060405190810160405280600181526020017f2c0000000000000000000000000000000000000000000000000000000000000081525084613a4290919063ffffffff16565b92505b600182019150612130612121600260038481548110151561209f57fe5b906000526020600020900160005b5060405180828054600181600116156101000203166002900480156121095780601f106120e7576101008083540402835291820191612109565b820191906000526020600020905b8154815290600101906020018083116120f5575b50509150509081526020016040518091039020613aad565b84613a4290919063ffffffff16565b92505b5b8080600101915050611f62565b61218a604060405190810160405280600381526020017f5d7d7d000000000000000000000000000000000000000000000000000000000081525084613a4290919063ffffffff16565b92505b505090565b61219a6164fd565b6000604060405190810160405280601181526020017f7b22726574223a302c2264617461223a7b000000000000000000000000000000815250915060009050600060018111156121e657fe5b6002846040518082805190602001908083835b6020831061221c57805182526020820191506020810190506020830392506121f9565b6001836020036101000a038019825116818451168082178552505050505050905001915050908152602001604051809103902060090160009054906101000a900460ff16600181111561226b57fe5b14151561239557600190506123096122c2604060405190810160405280600581526020017f746f74616c000000000000000000000000000000000000000000000000000000815250836134e490919063ffffffff16565b604060405190810160405280600a81526020017f2c226974656d73223a5b000000000000000000000000000000000000000000008152508461385e9092919063ffffffff16565b915061238e61237f6002856040518082805190602001908083835b602083106123475780518252602082019150602081019050602083039250612324565b6001836020036101000a0380198251168184511680821785525050505050509050019150509081526020016040518091039020613aad565b83613a4290919063ffffffff16565b915061242b565b6124286123e1604060405190810160405280600581526020017f746f74616c000000000000000000000000000000000000000000000000000000815250836134e490919063ffffffff16565b604060405190810160405280600a81526020017f2c226974656d73223a5b000000000000000000000000000000000000000000008152508461385e9092919063ffffffff16565b91505b612474604060405190810160405280600381526020017f5d7d7d000000000000000000000000000000000000000000000000000000000081525083613a4290919063ffffffff16565b91505b50919050565b6124856164fd565b6124c6600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16614c38565b90505b90565b6000600060018111156124db57fe5b6002836040518082805190602001908083835b6020831061251157805182526020820191506020810190506020830392506124ee565b6001836020036101000a038019825116818451168082178552505050505050905001915050908152602001604051809103902060090160009054906101000a900460ff16600181111561256057fe5b141580156125db575060006002836040518082805190602001908083835b602083106125a1578051825260208201915060208101905060208303925061257e565b6001836020036101000a03801982511681845116808217855250505050505090500191505090815260200160405180910390206008015414155b156125e957600190506125ee565b600090505b5b919050565b600060038054905090505b90565b600061261882600561491090919063ffffffff16565b15156126ec576001600581111561262b57fe5b600181905550612670604060405190810160405280601181526020017f62616420736572766572206a736f6e2021000000000000000000000000000000815250611d73565b507f6f52e1083ea2b4deef2cb48dbb504881c8b27cfedc2d85bc841b9ed1613c54cc60015460405180828152602001806020018281038252600f8152602001807f62616420736572766572206a736f6e00000000000000000000000000000000008152506020019250505060405180910390a160009050612b69565b600060018111156126f957fe5b60026005600001604051808280546001816001161561010002031660029004801561275b5780601f1061273957610100808354040283529182019161275b565b820191906000526020600020905b815481529060010190602001808311612747575b5050915050908152602001604051809103902060090160009054906101000a900460ff16600181111561278a57fe5b14151561285f576004600581111561279e57fe5b6001819055506127e3604060405190810160405280601b81526020017f7468652073657276657220616c72656164792065786973747320210000000000815250611d73565b507f6f52e1083ea2b4deef2cb48dbb504881c8b27cfedc2d85bc841b9ed1613c54cc6001546040518082815260200180602001828103825260198152602001807f7468652073657276657220616c726561647920657869737473000000000000008152506020019250505060405180910390a160009050612b69565b6001600560090160006101000a81548160ff0219169083600181111561288157fe5b02179055506103e84202600560030181905550600380548060010182816128a89190616533565b916000526020600020900160005b6005600001909190915090805460018160011615610100020316600290046128df92919061655f565b505060056002600560000160405180828054600181600116156101000203166002900480156129455780601f10612923576101008083540402835291820191612945565b820191906000526020600020905b815481529060010190602001808311612931575b505091505090815260200160405180910390206000820181600001908054600181600116156101000203166002900461297f9291906165e6565b50600182018160010190805460018160011615610100020316600290046129a79291906165e6565b506002820154816002015560038201548160030155600482018160040190805460018160011615610100020316600290046129e39291906165e6565b5060058201816005019080546001816001161561010002031660029004612a0b9291906165e6565b5060068201816006019080546001816001161561010002031660029004612a339291906165e6565b5060078201816007019080546001816001161561010002031660029004612a5b9291906165e6565b50600882015481600801556009820160009054906101000a900460ff168160090160006101000a81548160ff02191690836001811115612a9757fe5b021790555090505060006005811115612aac57fe5b600181905550612af1604060405190810160405280601781526020017f696e736572742073657276657220737563636573732021000000000000000000815250611d73565b507f6f52e1083ea2b4deef2cb48dbb504881c8b27cfedc2d85bc841b9ed1613c54cc6001546040518082815260200180602001828103825260158152602001807f696e7365727420736572766572207375636365737300000000000000000000008152506020019250505060405180910390a1600190505b919050565b60006000600090505b600380549050811015612f6d57612cc0846002600384815481101515612b9957fe5b906000526020600020900160005b506040518082805460018160011615610100020316600290048015612c035780601f10612be1576101008083540402835291820191612c03565b820191906000526020600020905b815481529060010190602001808311612bef575b505091505090815260200160405180910390206000018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015612cad5780601f10612c8257610100808354040283529160200191612cad565b820191906000526020600020905b815481529060010190602001808311612c9057829003601f168201915b50505050506138fe90919063ffffffff16565b8015612d5c575060006001811115612cd457fe5b6002856040518082805190602001908083835b60208310612d0a5780518252602082019150602081019050602083039250612ce7565b6001836020036101000a038019825116818451168082178552505050505050905001915050908152602001604051809103902060090160009054906101000a900460ff166001811115612d5957fe5b14155b15612f5f57826002856040518082805190602001908083835b60208310612d985780518252602082019150602081019050602083039250612d75565b6001836020036101000a0380198251168184511680821785525050505050509050019150509081526020016040518091039020600801819055506000831415612e5857612e52604060405190810160405280601481526020017f64697361626c6520746865207365727665723a2000000000000000000000000081525085604060405190810160405280601181526020017f46696c655365727665724d616e616765720000000000000000000000000000008152506116d8565b50612ed1565b612ecf604060405190810160405280601381526020017f656e61626c6520746865207365727665723a200000000000000000000000000081525085604060405190810160405280601181526020017f46696c655365727665724d616e616765720000000000000000000000000000008152506116d8565b505b60006005811115612ede57fe5b6001819055507f6f52e1083ea2b4deef2cb48dbb504881c8b27cfedc2d85bc841b9ed1613c54cc6001546040518082815260200180602001828103825260158152602001807f656e61626c6520736572766572207375636365737300000000000000000000008152506020019250505060405180910390a16001915061305c565b5b8080600101915050612b77565b612fe4604060405190810160405280601481526020017f656e61626c6520736572766572206661696c2c2000000000000000000000000081525085604060405190810160405280601181526020017f46696c655365727665724d616e616765720000000000000000000000000000008152506116d8565b507f6f52e1083ea2b4deef2cb48dbb504881c8b27cfedc2d85bc841b9ed1613c54cc6001546040518082815260200180602001828103825260128152602001807f656e61626c6520736572766572206661696c00000000000000000000000000008152506020019250505060405180910390a1600091505b5092915050565b600061306d6164fd565b6020604051908101604052806000815250905061309d8461308d85614e4a565b8361385e9092919063ffffffff16565b90506130a881610ce0565b60010260405180826000191660001916815260200191505060405180910390a05b5092915050565b6130d86164fd565b6000600090505b6003805490508110156134c957600060018111156130f957fe5b600260038381548110151561310a57fe5b906000526020600020900160005b5060405180828054600181600116156101000203166002900480156131745780601f10613152576101008083540402835291820191613174565b820191906000526020600020905b815481529060010190602001808311613160575b5050915050908152602001604051809103902060090160009054906101000a900460ff1660018111156131a357fe5b141580156132e957506132e88460026003848154811015156131c157fe5b906000526020600020900160005b50604051808280546001816001161561010002031660029004801561322b5780601f1061320957610100808354040283529182019161322b565b820191906000526020600020905b815481529060010190602001808311613217575b505091505090815260200160405180910390206001018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156132d55780601f106132aa576101008083540402835291602001916132d5565b820191906000526020600020905b8154815290600101906020018083116132b857829003601f168201915b50505050506138fe90919063ffffffff16565b5b8015613385575082600260038381548110151561330257fe5b906000526020600020900160005b50604051808280546001816001161561010002031660029004801561336c5780601f1061334a57610100808354040283529182019161336c565b820191906000526020600020905b815481529060010190602001808311613358575b5050915050908152602001604051809103902060020154145b156134bb57600260038281548110151561339b57fe5b906000526020600020900160005b5060405180828054600181600116156101000203166002900480156134055780601f106133e3576101008083540402835291820191613405565b820191906000526020600020905b8154815290600101906020018083116133f1575b505091505090815260200160405180910390206000018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156134af5780601f10613484576101008083540402835291602001916134af565b820191906000526020600020905b81548152906001019060200180831161349257829003601f168201915b505050505091506134dd565b5b80806001019150506130df565b602060405190810160405280600081525091505b5092915050565b6134ec6164fd565b600060006000600060038651019350600087141561350f57600184019350613539565b8692505b600083111561353857600a8381151561352857fe5b0492508380600101945050613513565b5b836040518059106135475750595b908082528060200260200182016040525b509450600091507f2200000000000000000000000000000000000000000000000000000000000000858380600101945081518110151561359457fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600090505b855181101561367d5785818151811015156135e057fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f010000000000000000000000000000000000000000000000000000000000000002858380600101945081518110151561363f57fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053505b80806001019150506135c9565b7f220000000000000000000000000000000000000000000000000000000000000085838060010194508151811015156136b257fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f3a00000000000000000000000000000000000000000000000000000000000000858380600101945081518110151561371757fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060018403915060008714156137bd5760307f010000000000000000000000000000000000000000000000000000000000000002858381518110151561378857fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350613853565b5b6000871115613852576030600a888115156137d557fe5b06017f01000000000000000000000000000000000000000000000000000000000000000285838060019003945081518110151561380e57fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a8781151561384a57fe5b0496506137be565b5b5b5050505092915050565b6138666164fd565b60006000600060006000865188518a5101016040518059106138855750595b908082528060200260200182016040525b509550602089019450602088019350602087019250602086019150600090506138c3818301868b51614f98565b8851810190506138d7818301858a51614f98565b8751810190506138eb818301848951614f98565b8651810190505b50505050509392505050565b60006000825184511415156139165760009150613a3b565b600090505b8351811015613a3657828181518110151561393257fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191684828151811015156139ad57fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141515613a2a5760009150613a3b565b5b80600101905061391b565b600191505b5092915050565b613a4a6164fd565b6000600060008451865101604051805910613a625750595b908082528060200260200182016040525b509350602086019250602085019150602084019050613a9481848851614f98565b613aa386518201838751614f98565b5b50505092915050565b613ab56164fd565b604060405190810160405280600181526020017f7b000000000000000000000000000000000000000000000000000000000000008152509050613c1d613bd6604060405190810160405280600281526020017f6964000000000000000000000000000000000000000000000000000000000000815250846000018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015613bc35780601f10613b9857610100808354040283529160200191613bc3565b820191906000526020600020905b815481529060010190602001808311613ba657829003601f168201915b5050505050614fe590919063ffffffff16565b604060405190810160405280600181526020017f2c000000000000000000000000000000000000000000000000000000000000008152508361385e9092919063ffffffff16565b9050613d4e613d07604060405190810160405280600481526020017f686f737400000000000000000000000000000000000000000000000000000000815250846001018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015613cf45780601f10613cc957610100808354040283529160200191613cf4565b820191906000526020600020905b815481529060010190602001808311613cd757829003601f168201915b5050505050614fe590919063ffffffff16565b604060405190810160405280600181526020017f2c000000000000000000000000000000000000000000000000000000000000008152508361385e9092919063ffffffff16565b9050613de7613da0604060405190810160405280600481526020017f706f72740000000000000000000000000000000000000000000000000000000081525084600201546134e490919063ffffffff16565b604060405190810160405280600181526020017f2c000000000000000000000000000000000000000000000000000000000000008152508361385e9092919063ffffffff16565b9050613e80613e39604060405190810160405280600a81526020017f75706461746554696d650000000000000000000000000000000000000000000081525084600301546134e490919063ffffffff16565b604060405190810160405280600181526020017f2c000000000000000000000000000000000000000000000000000000000000008152508361385e9092919063ffffffff16565b9050613fb1613f6a604060405190810160405280600881526020017f706f736974696f6e000000000000000000000000000000000000000000000000815250846005018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015613f575780601f10613f2c57610100808354040283529160200191613f57565b820191906000526020600020905b815481529060010190602001808311613f3a57829003601f168201915b5050505050614fe590919063ffffffff16565b604060405190810160405280600181526020017f2c000000000000000000000000000000000000000000000000000000000000008152508361385e9092919063ffffffff16565b90506140e261409b604060405190810160405280600581526020017f67726f7570000000000000000000000000000000000000000000000000000000815250846006018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156140885780601f1061405d57610100808354040283529160200191614088565b820191906000526020600020905b81548152906001019060200180831161406b57829003601f168201915b5050505050614fe590919063ffffffff16565b604060405190810160405280600181526020017f2c000000000000000000000000000000000000000000000000000000000000008152508361385e9092919063ffffffff16565b90506142136141cc604060405190810160405280600c81526020017f6f7267616e697a6174696f6e0000000000000000000000000000000000000000815250846004018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156141b95780601f1061418e576101008083540402835291602001916141b9565b820191906000526020600020905b81548152906001019060200180831161419c57829003601f168201915b5050505050614fe590919063ffffffff16565b604060405190810160405280600181526020017f2c000000000000000000000000000000000000000000000000000000000000008152508361385e9092919063ffffffff16565b90506142ac614265604060405190810160405280600681526020017f656e61626c65000000000000000000000000000000000000000000000000000081525084600801546134e490919063ffffffff16565b604060405190810160405280600181526020017f2c000000000000000000000000000000000000000000000000000000000000008152508361385e9092919063ffffffff16565b90506143dd614396604060405190810160405280600481526020017f696e666f00000000000000000000000000000000000000000000000000000000815250846007018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156143835780601f1061435857610100808354040283529160200191614383565b820191906000526020600020905b81548152906001019060200180831161436657829003601f168201915b5050505050614fe590919063ffffffff16565b604060405190810160405280600181526020017f7d000000000000000000000000000000000000000000000000000000000000008152508361385e9092919063ffffffff16565b90505b919050565b6143ed6164fd565b60006000602a6040518059106144005750595b908082528060200260200182016040525b5092507f300000000000000000000000000000000000000000000000000000000000000083600081518110151561444457fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008360018151811015156144a457fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350602991505b60028260ff161015156145eb57600f841690506010848115156144f857fe5b049350600a8160ff16101561457357603081017f010000000000000000000000000000000000000000000000000000000000000002838360ff1681518110151561453e57fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506145de565b6061600a8203017f010000000000000000000000000000000000000000000000000000000000000002838360ff168151811015156145ad57fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053505b5b816001900391506144d9565b5b5050919050565b6145fb6164fd565b60006000600060006000600087141561464c57604060405190810160405280600181526020017f300000000000000000000000000000000000000000000000000000000000000081525095506147c8565b86945060019350600092506000871215614673578660000394506000935082806001019350505b8491505b600082111561469c57600a8281151561468c57fe5b0491508280600101935050614677565b8260ff166040518059106146ad5750595b908082528060200260200182016040525b509550831515614729577f2d000000000000000000000000000000000000000000000000000000000000008660008151811015156146f857fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053505b6001830390505b60008511156147c7576030600a8681151561474757fe5b06017f01000000000000000000000000000000000000000000000000000000000000000286828060019003935060ff1681518110151561478357fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a858115156147bf57fe5b049450614730565b5b5050505050919050565b60206040519081016040528060008152508160000190805190602001906147fa92919061666d565b50602060405190810160405280600081525081600101908051906020019061482392919061666d565b506000816002018190555060008160030181905550602060405190810160405280600081525081600501908051906020019061486092919061666d565b50602060405190810160405280600081525081600401908051906020019061488992919061666d565b5060206040519081016040528060008152508160070190805190602001906148b292919061666d565b5060206040519081016040528060008152508160060190805190602001906148db92919061666d565b506000816008018190555060008160090160006101000a81548160ff0219169083600181111561490757fe5b02179055505b50565b600061491b836147d2565b614964604060405190810160405280600281526020017f69640000000000000000000000000000000000000000000000000000000000008152508361526090919063ffffffff16565b83600001908051906020019061497b92919061666d565b506149c5604060405190810160405280600481526020017f686f7374000000000000000000000000000000000000000000000000000000008152508361526090919063ffffffff16565b8360010190805190602001906149dc92919061666d565b50614a26604060405190810160405280600481526020017f706f727400000000000000000000000000000000000000000000000000000000815250836159b090919063ffffffff16565b8360020181905550614a77604060405190810160405280600881526020017f706f736974696f6e0000000000000000000000000000000000000000000000008152508361526090919063ffffffff16565b836005019080519060200190614a8e92919061666d565b50614ad8604060405190810160405280600581526020017f67726f75700000000000000000000000000000000000000000000000000000008152508361526090919063ffffffff16565b836006019080519060200190614aef92919061666d565b50614b39604060405190810160405280600c81526020017f6f7267616e697a6174696f6e00000000000000000000000000000000000000008152508361526090919063ffffffff16565b836004019080519060200190614b5092919061666d565b50614b9a604060405190810160405280600481526020017f696e666f000000000000000000000000000000000000000000000000000000008152508361526090919063ffffffff16565b836007019080519060200190614bb192919061666d565b50614bfb604060405190810160405280600681526020017f656e61626c650000000000000000000000000000000000000000000000000000815250836159b090919063ffffffff16565b83600801819055506000836000018054600181600116156101000203166002900490501415614c2d5760009050614c32565b600190505b92915050565b614c406164fd565b614c486166ed565b60006000600060006028604051805910614c5f5750595b908082528060200260200182016040525b509450600093505b6014841015614e3c578360130360080260020a8773ffffffffffffffffffffffffffffffffffffffff16811515614cab57fe5b047f01000000000000000000000000000000000000000000000000000000000000000292506010837f0100000000000000000000000000000000000000000000000000000000000000900460ff16811515614d0257fe5b047f0100000000000000000000000000000000000000000000000000000000000000029150817f01000000000000000000000000000000000000000000000000000000000000009004601002837f01000000000000000000000000000000000000000000000000000000000000009004037f0100000000000000000000000000000000000000000000000000000000000000029050614da082616259565b8585600202815181101515614db157fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350614dea81616259565b8560018660020201815181101515614dfe57fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053505b8380600101945050614c78565b8495505b5050505050919050565b614e526164fd565b6000600060006000851415614e9f57604060405190810160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509350614f90565b600092508491505b6000821115614ecc57600a82811515614ebc57fe5b0491508280600101935050614ea7565b8260ff16604051805910614edd5750595b908082528060200260200182016040525b5093506001830390505b6000851115614f8f576030600a86811515614f0f57fe5b06017f01000000000000000000000000000000000000000000000000000000000000000284828060019003935060ff16815181101515614f4b57fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a85811515614f8757fe5b049450614ef8565b5b505050919050565b60005b602082101515614fc157825184526020840193506020830192505b602082039150614f9b565b6001826020036101000a039050801983511681855116818117865250505b50505050565b614fed6164fd565b6000600060006000600586518851010160405180591061500a5750595b908082528060200260200182016040525b509450602087019350602086019250602085019150600090507f2200000000000000000000000000000000000000000000000000000000000000858280600101935081518110151561506957fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506150a7818301848851614f98565b8551810190507f220000000000000000000000000000000000000000000000000000000000000085828060010193508151811015156150e257fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f3a00000000000000000000000000000000000000000000000000000000000000858280600101935081518110151561514757fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f220000000000000000000000000000000000000000000000000000000000000085828060010193508151811015156151ac57fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506151ea818301858951614f98565b8651810190507f2200000000000000000000000000000000000000000000000000000000000000858280600101935081518110151561522557fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053505b5050505092915050565b6152686164fd565b6000600060006000600060007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9550600094505b6001156157b95761533861532789604060405190810160405280600181526020017f2200000000000000000000000000000000000000000000000000000000000000815250604060405190810160405280600181526020017f220000000000000000000000000000000000000000000000000000000000000081525061385e9092919063ffffffff16565b868b61634e9092919063ffffffff16565b95507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff861415615427576153f76153e689604060405190810160405280600181526020017f2700000000000000000000000000000000000000000000000000000000000000815250604060405190810160405280600181526020017f270000000000000000000000000000000000000000000000000000000000000081525061385e9092919063ffffffff16565b868b61634e9092919063ffffffff16565b95507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff861415615426576159a4565b5b600288510186019550600093505b8851861015615797577f2000000000000000000000000000000000000000000000000000000000000000898781518110151561546d57fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061557f57507f0900000000000000000000000000000000000000000000000000000000000000898781518110151561551057fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061562357507f0d0000000000000000000000000000000000000000000000000000000000000089878151811015156155b457fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806156c757507f0a00000000000000000000000000000000000000000000000000000000000000898781518110151561565857fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b156156d9578580600101965050615792565b7f3a00000000000000000000000000000000000000000000000000000000000000898781518110151561570857fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561578c57858060010196505060019350615797565b615797565b5b615435565b88518614156157a5576159a4565b83156157b0576157b9565b8594505b61529c565b60019250615808604060405190810160405280600181526020017f2200000000000000000000000000000000000000000000000000000000000000815250878b61634e9092919063ffffffff16565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156158b15760009250615881604060405190810160405280600181526020017f2700000000000000000000000000000000000000000000000000000000000000815250878b61634e9092919063ffffffff16565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156158b0576159a4565b5b600182019150821561590f57615908604060405190810160405280600181526020017f2200000000000000000000000000000000000000000000000000000000000000815250838b61634e9092919063ffffffff16565b905061595d565b61595a604060405190810160405280600181526020017f2700000000000000000000000000000000000000000000000000000000000000815250838b61634e9092919063ffffffff16565b90505b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81141561598a576159a4565b6159a1828383038b6163b89092919063ffffffff16565b96505b50505050505092915050565b6000600060006000600060006000600096507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9550600094505b600115615f0757615a86615a7589604060405190810160405280600181526020017f2200000000000000000000000000000000000000000000000000000000000000815250604060405190810160405280600181526020017f220000000000000000000000000000000000000000000000000000000000000081525061385e9092919063ffffffff16565b868b61634e9092919063ffffffff16565b95507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff861415615b7557615b45615b3489604060405190810160405280600181526020017f2700000000000000000000000000000000000000000000000000000000000000815250604060405190810160405280600181526020017f270000000000000000000000000000000000000000000000000000000000000081525061385e9092919063ffffffff16565b868b61634e9092919063ffffffff16565b95507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff861415615b745761624d565b5b600288510186019550600093505b8851861015615ee5577f20000000000000000000000000000000000000000000000000000000000000008987815181101515615bbb57fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480615ccd57507f09000000000000000000000000000000000000000000000000000000000000008987815181101515615c5e57fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80615d7157507f0d000000000000000000000000000000000000000000000000000000000000008987815181101515615d0257fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80615e1557507f0a000000000000000000000000000000000000000000000000000000000000008987815181101515615da657fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b15615e27578580600101965050615ee0565b7f3a000000000000000000000000000000000000000000000000000000000000008987815181101515615e5657fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415615eda57858060010196505060019350615ee5565b615ee5565b5b615b83565b8851861415615ef35761624d565b8315615efe57615f07565b8594505b6159ea565b8592505b8851831015616004578883815181101515615f2257fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027f01000000000000000000000000000000000000000000000000000000000000009004915060208260ff161480615fa7575060098260ff16145b80615fb55750600d8260ff16145b80615fc35750600a8260ff16145b80615fd15750603a8260ff16145b80615fdf575060228260ff16145b80615fed575060278260ff16145b1515615ff857616004565b5b826001019250615f0b565b600190507f2b00000000000000000000000000000000000000000000000000000000000000898481518110151561603757fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156160bb5760019050828060010193505061616b565b7f2d0000000000000000000000000000000000000000000000000000000000000089848151811015156160ea57fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561616a576000905082806001019350505b5b5b885183101561623e57888381518110151561618357fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027f01000000000000000000000000000000000000000000000000000000000000009004915060308260ff161015801561620b575060398260ff1611155b15156162245780151561621f578660000396505b61624d565b6030820360ff16600a88020196505b82600101925061616c565b80151561624c578660000396505b5b50505050505092915050565b6000600a7f010000000000000000000000000000000000000000000000000000000000000002827effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191610156162f8576030827f01000000000000000000000000000000000000000000000000000000000000009004017f0100000000000000000000000000000000000000000000000000000000000000029050616349565b6057827f01000000000000000000000000000000000000000000000000000000000000009004017f0100000000000000000000000000000000000000000000000000000000000000029050616349565b5b919050565b6000600060006000602087019250602086019150826163758689510387860189518661643d565b0390508651811015616389578093506163ad565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff93505b5b5050509392505050565b6163c06164fd565b60006000848651038411156163d6578486510393505b6000841115156163f85760206040519081016040528060008152509250616434565b836040518059106164065750595b908082528060200260200182016040525b5092506020860191506020830190506164338186840186614f98565b5b50509392505050565b6000600060006000600088871115156164eb576020871115156164a05760018760200360080260020a031980875116888b038a018a96505b81838851161461649557600187019650806001880310616475578b8b0196505b5050508394506164f1565b8686209150879350600092505b868903831115156164e95786842090508060001916826000191614156164d5578394506164f1565b6001840193505b82806001019350506164ad565b5b5b88880194505b50505050949350505050565b602060405190810160405280600081525090565b508054600082559060005260206000209081019061652f9190616701565b5b50565b81548183558181151161655a578183600052602060002091820191016165599190616701565b5b505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061659857805485556165d5565b828001600101855582156165d557600052602060002091601f016020900482015b828111156165d45782548255916001019190600101906165b9565b5b5090506165e2919061672d565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061661f578054855561665c565b8280016001018555821561665c57600052602060002091601f016020900482015b8281111561665b578254825591600101919060010190616640565b5b509050616669919061672d565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106166ae57805160ff19168380011785556166dc565b828001600101855582156166dc579182015b828111156166db5782518255916020019190600101906166c0565b5b5090506166e9919061672d565b5090565b602060405190810160405280600081525090565b61672a91905b80821115616726576000818161671d9190616752565b50600101616707565b5090565b90565b61674f91905b8082111561674b576000816000905550600101616733565b5090565b90565b50805460018160011615610100020316600290046000825580601f106167785750616797565b601f016020900490600052602060002090810190616796919061672d565b5b505600a165627a7a723058200c99de41b038d68e92d92a22df9a5fddd027322eabd57e1c9c50cc832f9eee6e0029"; + + private FileServerManager(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) { + super(contractAddress, web3j, credentials, gasPrice, gasLimit); + } + + private FileServerManager(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) { + super(contractAddress, web3j, transactionManager, gasPrice, gasLimit); + } + + public List getNotifyEvents(TransactionReceipt transactionReceipt) { + final Event event = new Event("Notify", + Arrays.>asList(), + Arrays.>asList(new TypeReference() {}, new TypeReference() {})); + List valueList = extractEventParameters(event,transactionReceipt); + ArrayList responses = new ArrayList(valueList.size()); + for(EventValues eventValues : valueList) { + NotifyEventResponse typedResponse = new NotifyEventResponse(); + typedResponse._errno = (Uint256)eventValues.getNonIndexedValues().get(0); + typedResponse._info = (Utf8String)eventValues.getNonIndexedValues().get(1); + responses.add(typedResponse); + } + return responses; + } + + public Observable notifyEventObservable() { + final Event event = new Event("Notify", + Arrays.>asList(), + Arrays.>asList(new TypeReference() {}, new TypeReference() {})); + EthFilter filter = new EthFilter(DefaultBlockParameterName.EARLIEST,DefaultBlockParameterName.LATEST, getContractAddress()); + filter.addSingleTopic(EventEncoder.encode(event)); + return web3j.ethLogObservable(filter).map(new Func1() { + @Override + public NotifyEventResponse call(Log log) { + EventValues eventValues = extractEventParameters(event, log); + NotifyEventResponse typedResponse = new NotifyEventResponse(); + typedResponse._errno = (Uint256)eventValues.getNonIndexedValues().get(0); + typedResponse._info = (Utf8String)eventValues.getNonIndexedValues().get(1); + return typedResponse; + } + }); + } + + public Future getErrno() { + Function function = new Function("getErrno", + Arrays.asList(), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future stringToUint(Utf8String _str) { + Function function = new Function("stringToUint", + Arrays.asList(_str), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future listByGroup(Utf8String _group) { + Function function = new Function("listByGroup", + Arrays.asList(_group), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future deleteById(Utf8String _serverId) { + Function function = new Function("deleteById", Arrays.asList(_serverId), Collections.>emptyList()); + return executeTransactionAsync(function); + } + + public Future log(Utf8String _str, Utf8String _str2, Utf8String _topic) { + Function function = new Function("log", + Arrays.asList(_str, _str2, _topic), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future log(Utf8String _str, Address _addr) { + Function function = new Function("log", + Arrays.asList(_str, _addr), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future log(Utf8String _str, Int256 _i) { + Function function = new Function("log", + Arrays.asList(_str, _i), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future update(Utf8String _json) { + Function function = new Function("update", Arrays.asList(_json), Collections.>emptyList()); + return executeTransactionAsync(function); + } + + public Future register(Utf8String _name, Utf8String _version) { + Function function = new Function("register", Arrays.asList(_name, _version), Collections.>emptyList()); + return executeTransactionAsync(function); + } + + public Future log(Utf8String _str) { + Function function = new Function("log", + Arrays.asList(_str), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future kill() { + Function function = new Function("kill", Arrays.asList(), Collections.>emptyList()); + return executeTransactionAsync(function); + } + + public Future log(Utf8String _str, Utf8String _topic) { + Function function = new Function("log", + Arrays.asList(_str, _topic), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future getSender() { + Function function = new Function("getSender", + Arrays.asList(), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future listAll() { + Function function = new Function("listAll", + Arrays.asList(), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future find(Utf8String _serverId) { + Function function = new Function("find", + Arrays.asList(_serverId), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future getOwner() { + Function function = new Function("getOwner", + Arrays.asList(), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future isServerEnable(Utf8String _serverId) { + Function function = new Function("isServerEnable", + Arrays.asList(_serverId), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future getCount() { + Function function = new Function("getCount", + Arrays.asList(), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future insert(Utf8String _json) { + Function function = new Function("insert", Arrays.asList(_json), Collections.>emptyList()); + return executeTransactionAsync(function); + } + + public Future enable(Utf8String _serverId, Uint256 _enable) { + Function function = new Function("enable", Arrays.asList(_serverId, _enable), Collections.>emptyList()); + return executeTransactionAsync(function); + } + + public Future log(Utf8String _str, Uint256 _ui) { + Function function = new Function("log", + Arrays.asList(_str, _ui), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public Future findIdByHostPort(Utf8String _host, Uint256 _port) { + Function function = new Function("findIdByHostPort", + Arrays.asList(_host, _port), + Arrays.>asList(new TypeReference() {})); + return executeCallSingleValueReturnAsync(function); + } + + public static Future deploy(Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit, BigInteger initialValue) { + return deployAsync(FileServerManager.class, web3j, credentials, gasPrice, gasLimit, BINARY, "", initialValue); + } + + public static Future deploy(Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit, BigInteger initialValue) { + return deployAsync(FileServerManager.class, web3j, transactionManager, gasPrice, gasLimit, BINARY, "", initialValue); + } + + public static FileServerManager load(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) { + return new FileServerManager(contractAddress, web3j, credentials, gasPrice, gasLimit); + } + + public static FileServerManager load(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) { + return new FileServerManager(contractAddress, web3j, transactionManager, gasPrice, gasLimit); + } + + public static class NotifyEventResponse { + public Uint256 _errno; + + public Utf8String _info; + } +} diff --git a/tool/java/DfsSDK/src/com/dfs/web3j/tx/DfsRawTransactionManager.java b/tool/java/DfsSDK/src/com/dfs/web3j/tx/DfsRawTransactionManager.java new file mode 100644 index 0000000000..df1760465e --- /dev/null +++ b/tool/java/DfsSDK/src/com/dfs/web3j/tx/DfsRawTransactionManager.java @@ -0,0 +1,120 @@ +/** + * + */ +package com.dfs.web3j.tx; + +import java.io.IOException; +import java.math.BigInteger; +import java.util.concurrent.ExecutionException; +import org.web3j.crypto.Credentials; +import org.web3j.protocol.Web3j; +import org.web3j.protocol.core.DefaultBlockParameterName; +import org.web3j.protocol.core.methods.request.RawTransaction; +import org.web3j.protocol.core.methods.response.EthBlockNumber; +import org.web3j.protocol.core.methods.response.EthGetTransactionCount; +import org.web3j.protocol.core.methods.response.EthSendTransaction; +import org.web3j.tx.ChainId; +import org.web3j.tx.TransactionManager; +import org.web3j.utils.Numeric; + +/** + * @author Administrator + * + */ +public class DfsRawTransactionManager extends TransactionManager { + + private final Web3j web3j; + final Credentials credentials; + + private final byte chainId; + private DfsTransactionEncoder juTransactionEncoder; + + public DfsRawTransactionManager(Web3j web3j, Credentials credentials, byte chainId) { + super(web3j); + this.web3j = web3j; + this.credentials = credentials; + + this.chainId = chainId; + this.juTransactionEncoder = new DfsTransactionEncoder(); + } + + public DfsRawTransactionManager( + Web3j web3j, Credentials credentials, byte chainId, int attempts, int sleepDuration) { + super(web3j, attempts, sleepDuration); + this.web3j = web3j; + this.credentials = credentials; + + this.chainId = chainId; + this.juTransactionEncoder = new DfsTransactionEncoder(); + } + + public DfsRawTransactionManager(Web3j web3j, Credentials credentials) { + this(web3j, credentials, ChainId.NONE); + } + + public DfsRawTransactionManager( + Web3j web3j, Credentials credentials, int attempts, int sleepDuration) { + this(web3j, credentials, ChainId.NONE, attempts, sleepDuration); + } + + BigInteger getNonce() throws ExecutionException, InterruptedException { + EthGetTransactionCount ethGetTransactionCount = web3j.ethGetTransactionCount( + credentials.getAddress(), DefaultBlockParameterName.LATEST).sendAsync().get(); + + return ethGetTransactionCount.getTransactionCount(); + } + + @Override + public EthSendTransaction sendTransaction( + BigInteger gasPrice, BigInteger gasLimit, String to, + String data, BigInteger value) throws ExecutionException, InterruptedException { + + BigInteger nonce = getNonce(); + + RawTransaction rawTransaction = RawTransaction.createTransaction( + nonce, + gasPrice, + gasLimit, + to, + value, + data); + + return signAndSend(rawTransaction); + } + + public EthSendTransaction signAndSend(RawTransaction rawTransaction) + throws ExecutionException, InterruptedException { + + byte[] signedMessage; + + //retrieve the blockNumber + org.web3j.protocol.core.Request blockNumber = web3j.ethBlockNumber(); + EthBlockNumber blockNumber2 = new EthBlockNumber(); + BigInteger blockLimited = null; + try { + blockNumber2 = blockNumber.send(); + blockLimited = blockNumber2.getBlockNumber(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + blockLimited = blockLimited.add(new BigInteger("100", 10)); + juTransactionEncoder.setBlockLimited(blockLimited); + if (chainId > ChainId.NONE) { + signedMessage = juTransactionEncoder.signMessage(rawTransaction, chainId, credentials); + } else { + signedMessage = juTransactionEncoder.signMessage(rawTransaction, credentials); + } + + String hexValue = Numeric.toHexString(signedMessage); + + return web3j.ethSendRawTransaction(hexValue).sendAsync().get(); + } + + @Override + public String getFromAddress() { + return credentials.getAddress(); + } + +} diff --git a/tool/java/DfsSDK/src/com/dfs/web3j/tx/DfsTransactionEncoder.java b/tool/java/DfsSDK/src/com/dfs/web3j/tx/DfsTransactionEncoder.java new file mode 100644 index 0000000000..7cec9edc0b --- /dev/null +++ b/tool/java/DfsSDK/src/com/dfs/web3j/tx/DfsTransactionEncoder.java @@ -0,0 +1,131 @@ +/** + * + */ +package com.dfs.web3j.tx; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; +import java.util.Random; + +import org.web3j.crypto.Credentials; +import org.web3j.crypto.Sign; +import org.web3j.crypto.Sign.SignatureData; +import org.web3j.protocol.core.methods.request.RawTransaction; +import org.web3j.rlp.RlpEncoder; +import org.web3j.rlp.RlpList; +import org.web3j.rlp.RlpString; +import org.web3j.rlp.RlpType; +import org.web3j.utils.Numeric; + +/** + * @author Administrator + * + */ +public class DfsTransactionEncoder { + + private BigInteger blockLimited = new BigInteger("100"); + + /** + * + */ + public DfsTransactionEncoder() { + } + + public List asRlpValues( + RawTransaction rawTransaction, SignatureData signatureData) { + List result = new ArrayList<>(); + + Random random = new Random(); + random.setSeed(Calendar.getInstance().getTimeInMillis()); + //rlp[0] randomid + BigInteger ramdomid = new BigInteger(256, random); + result.add(RlpString.create(ramdomid)); + + result.add(RlpString.create(rawTransaction.getGasPrice())); + //result.add(RlpString.create(rawTransaction.getNonce())); + result.add(RlpString.create(rawTransaction.getGasLimit())); + + //rlp[3] blockLimited + result.add(RlpString.create(blockLimited)); + + // an empty to address (contract creation) should not be encoded as a numeric 0 value + String to = rawTransaction.getTo(); + if (to != null && to.length() > 0) { + result.add(RlpString.create(Numeric.toBigInt(to))); + } else { + result.add(RlpString.create("")); + } + + result.add(RlpString.create(rawTransaction.getValue())); + + // value field will already be hex encoded, so we need to convert into binary first + byte[] data = Numeric.hexStringToByteArray(rawTransaction.getData()); + result.add(RlpString.create(data)); + + if (signatureData != null) { + result.add(RlpString.create(signatureData.getV())); + result.add(RlpString.create(signatureData.getR())); + result.add(RlpString.create(signatureData.getS())); + } + + return result; + } + + /** + * @return the blockLimited + */ + public BigInteger getBlockLimited() { + return blockLimited; + } + + /** + * @param blockLimited the blockLimited to set + */ + public void setBlockLimited(BigInteger blockLimited) { + this.blockLimited = blockLimited; + } + + public byte[] signMessage(RawTransaction rawTransaction, Credentials credentials) { + byte[] encodedTransaction = encode(rawTransaction); + org.web3j.crypto.Sign.SignatureData signatureData = Sign.signMessage( + encodedTransaction, credentials.getEcKeyPair()); + + return encode(rawTransaction, signatureData); + } + + public byte[] signMessage( + RawTransaction rawTransaction, byte chainId, Credentials credentials) { + byte[] encodedTransaction = encode(rawTransaction, chainId); + Sign.SignatureData signatureData = Sign.signMessage( + encodedTransaction, credentials.getEcKeyPair()); + + Sign.SignatureData eip155SignatureData = createEip155SignatureData(signatureData, chainId); + return encode(rawTransaction, eip155SignatureData); + } + + public Sign.SignatureData createEip155SignatureData( + Sign.SignatureData signatureData, byte chainId) { + byte v = (byte) (signatureData.getV() + (chainId << 1) + 8); + + return new Sign.SignatureData( + v, signatureData.getR(), signatureData.getS()); + } + + public byte[] encode(RawTransaction rawTransaction) { + return encode(rawTransaction, null); + } + + public byte[] encode(RawTransaction rawTransaction, byte chainId) { + Sign.SignatureData signatureData = new Sign.SignatureData( + chainId, new byte[] {}, new byte[] {}); + return encode(rawTransaction, signatureData); + } + + private byte[] encode(RawTransaction rawTransaction, Sign.SignatureData signatureData) { + List values = asRlpValues(rawTransaction, signatureData); + RlpList rlpList = new RlpList(values); + return RlpEncoder.encode(rlpList); + } +} diff --git a/tool/java/DfsSample/.classpath b/tool/java/DfsSample/.classpath new file mode 100644 index 0000000000..a6e05793bb --- /dev/null +++ b/tool/java/DfsSample/.classpath @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tool/java/DfsSample/.project b/tool/java/DfsSample/.project new file mode 100644 index 0000000000..9ae1136721 --- /dev/null +++ b/tool/java/DfsSample/.project @@ -0,0 +1,17 @@ + + + DfsSample + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/tool/java/DfsSample/.settings/org.eclipse.jdt.core.prefs b/tool/java/DfsSample/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000000..bb35fa0a87 --- /dev/null +++ b/tool/java/DfsSample/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,11 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/tool/java/DfsSample/lib/DfsSDK.jar b/tool/java/DfsSample/lib/DfsSDK.jar new file mode 100644 index 0000000000..221e7bbef2 Binary files /dev/null and b/tool/java/DfsSample/lib/DfsSDK.jar differ diff --git a/tool/java/DfsSample/lib/asm-5.0.3.jar b/tool/java/DfsSample/lib/asm-5.0.3.jar new file mode 100644 index 0000000000..573535b1d5 Binary files /dev/null and b/tool/java/DfsSample/lib/asm-5.0.3.jar differ diff --git a/tool/java/DfsSample/lib/asm-analysis-5.0.3.jar b/tool/java/DfsSample/lib/asm-analysis-5.0.3.jar new file mode 100644 index 0000000000..8b73cf09d7 Binary files /dev/null and b/tool/java/DfsSample/lib/asm-analysis-5.0.3.jar differ diff --git a/tool/java/DfsSample/lib/asm-commons-5.0.3.jar b/tool/java/DfsSample/lib/asm-commons-5.0.3.jar new file mode 100644 index 0000000000..514a6dc2e1 Binary files /dev/null and b/tool/java/DfsSample/lib/asm-commons-5.0.3.jar differ diff --git a/tool/java/DfsSample/lib/asm-tree-5.0.3.jar b/tool/java/DfsSample/lib/asm-tree-5.0.3.jar new file mode 100644 index 0000000000..e7eae53576 Binary files /dev/null and b/tool/java/DfsSample/lib/asm-tree-5.0.3.jar differ diff --git a/tool/java/DfsSample/lib/asm-util-5.0.3.jar b/tool/java/DfsSample/lib/asm-util-5.0.3.jar new file mode 100644 index 0000000000..e89f1b7b67 Binary files /dev/null and b/tool/java/DfsSample/lib/asm-util-5.0.3.jar differ diff --git a/tool/java/DfsSample/lib/bcprov-jdk15on-1.54.jar b/tool/java/DfsSample/lib/bcprov-jdk15on-1.54.jar new file mode 100644 index 0000000000..bd95185ae8 Binary files /dev/null and b/tool/java/DfsSample/lib/bcprov-jdk15on-1.54.jar differ diff --git a/tool/java/DfsSample/lib/commons-codec-1.9.jar b/tool/java/DfsSample/lib/commons-codec-1.9.jar new file mode 100644 index 0000000000..ef35f1c50d Binary files /dev/null and b/tool/java/DfsSample/lib/commons-codec-1.9.jar differ diff --git a/tool/java/DfsSample/lib/commons-io-2.5.jar b/tool/java/DfsSample/lib/commons-io-2.5.jar new file mode 100644 index 0000000000..1234918271 Binary files /dev/null and b/tool/java/DfsSample/lib/commons-io-2.5.jar differ diff --git a/tool/java/DfsSample/lib/commons-logging-1.2.jar b/tool/java/DfsSample/lib/commons-logging-1.2.jar new file mode 100644 index 0000000000..93a3b9f6db Binary files /dev/null and b/tool/java/DfsSample/lib/commons-logging-1.2.jar differ diff --git a/tool/java/DfsSample/lib/fastjson-1.2.24.jar b/tool/java/DfsSample/lib/fastjson-1.2.24.jar new file mode 100644 index 0000000000..4a6652fb5a Binary files /dev/null and b/tool/java/DfsSample/lib/fastjson-1.2.24.jar differ diff --git a/tool/java/DfsSample/lib/httpclient-4.5.2.jar b/tool/java/DfsSample/lib/httpclient-4.5.2.jar new file mode 100644 index 0000000000..701609fcc8 Binary files /dev/null and b/tool/java/DfsSample/lib/httpclient-4.5.2.jar differ diff --git a/tool/java/DfsSample/lib/httpcore-4.4.4.jar b/tool/java/DfsSample/lib/httpcore-4.4.4.jar new file mode 100644 index 0000000000..ac4a877302 Binary files /dev/null and b/tool/java/DfsSample/lib/httpcore-4.4.4.jar differ diff --git a/tool/java/DfsSample/lib/httpmime-4.3.1.jar b/tool/java/DfsSample/lib/httpmime-4.3.1.jar new file mode 100644 index 0000000000..2b26d7a79c Binary files /dev/null and b/tool/java/DfsSample/lib/httpmime-4.3.1.jar differ diff --git a/tool/java/DfsSample/lib/jackson-annotations-2.8.0.jar b/tool/java/DfsSample/lib/jackson-annotations-2.8.0.jar new file mode 100644 index 0000000000..d19b67b0f1 Binary files /dev/null and b/tool/java/DfsSample/lib/jackson-annotations-2.8.0.jar differ diff --git a/tool/java/DfsSample/lib/jackson-core-2.8.5.jar b/tool/java/DfsSample/lib/jackson-core-2.8.5.jar new file mode 100644 index 0000000000..05e1be2922 Binary files /dev/null and b/tool/java/DfsSample/lib/jackson-core-2.8.5.jar differ diff --git a/tool/java/DfsSample/lib/jackson-databind-2.8.5.jar b/tool/java/DfsSample/lib/jackson-databind-2.8.5.jar new file mode 100644 index 0000000000..2794824673 Binary files /dev/null and b/tool/java/DfsSample/lib/jackson-databind-2.8.5.jar differ diff --git a/tool/java/DfsSample/lib/javapoet-1.7.0.jar b/tool/java/DfsSample/lib/javapoet-1.7.0.jar new file mode 100644 index 0000000000..207af05755 Binary files /dev/null and b/tool/java/DfsSample/lib/javapoet-1.7.0.jar differ diff --git a/tool/java/DfsSample/lib/jffi-1.2.14-native.jar b/tool/java/DfsSample/lib/jffi-1.2.14-native.jar new file mode 100644 index 0000000000..3ba318dc20 Binary files /dev/null and b/tool/java/DfsSample/lib/jffi-1.2.14-native.jar differ diff --git a/tool/java/DfsSample/lib/jffi-1.2.14.jar b/tool/java/DfsSample/lib/jffi-1.2.14.jar new file mode 100644 index 0000000000..b912ebc22b Binary files /dev/null and b/tool/java/DfsSample/lib/jffi-1.2.14.jar differ diff --git a/tool/java/DfsSample/lib/jnr-constants-0.9.6.jar b/tool/java/DfsSample/lib/jnr-constants-0.9.6.jar new file mode 100644 index 0000000000..751de97ae7 Binary files /dev/null and b/tool/java/DfsSample/lib/jnr-constants-0.9.6.jar differ diff --git a/tool/java/DfsSample/lib/jnr-enxio-0.14.jar b/tool/java/DfsSample/lib/jnr-enxio-0.14.jar new file mode 100644 index 0000000000..95bc904056 Binary files /dev/null and b/tool/java/DfsSample/lib/jnr-enxio-0.14.jar differ diff --git a/tool/java/DfsSample/lib/jnr-ffi-2.1.2.jar b/tool/java/DfsSample/lib/jnr-ffi-2.1.2.jar new file mode 100644 index 0000000000..576db97f6c Binary files /dev/null and b/tool/java/DfsSample/lib/jnr-ffi-2.1.2.jar differ diff --git a/tool/java/DfsSample/lib/jnr-posix-3.0.33.jar b/tool/java/DfsSample/lib/jnr-posix-3.0.33.jar new file mode 100644 index 0000000000..50ca448984 Binary files /dev/null and b/tool/java/DfsSample/lib/jnr-posix-3.0.33.jar differ diff --git a/tool/java/DfsSample/lib/jnr-unixsocket-0.15.jar b/tool/java/DfsSample/lib/jnr-unixsocket-0.15.jar new file mode 100644 index 0000000000..91eca2c10f Binary files /dev/null and b/tool/java/DfsSample/lib/jnr-unixsocket-0.15.jar differ diff --git a/tool/java/DfsSample/lib/jnr-x86asm-1.0.2.jar b/tool/java/DfsSample/lib/jnr-x86asm-1.0.2.jar new file mode 100644 index 0000000000..dd4e695f3b Binary files /dev/null and b/tool/java/DfsSample/lib/jnr-x86asm-1.0.2.jar differ diff --git a/tool/java/DfsSample/lib/rxjava-1.2.4.jar b/tool/java/DfsSample/lib/rxjava-1.2.4.jar new file mode 100644 index 0000000000..c8961dbf60 Binary files /dev/null and b/tool/java/DfsSample/lib/rxjava-1.2.4.jar differ diff --git a/tool/java/DfsSample/lib/scrypt-1.4.0.jar b/tool/java/DfsSample/lib/scrypt-1.4.0.jar new file mode 100644 index 0000000000..7ebd8dee0d Binary files /dev/null and b/tool/java/DfsSample/lib/scrypt-1.4.0.jar differ diff --git a/tool/java/DfsSample/lib/web3j-2.1.0_main.jar b/tool/java/DfsSample/lib/web3j-2.1.0_main.jar new file mode 100644 index 0000000000..3ac1b696d4 Binary files /dev/null and b/tool/java/DfsSample/lib/web3j-2.1.0_main.jar differ diff --git a/tool/java/DfsSample/src/com/dfs/unittest/DfsEngineTest.java b/tool/java/DfsSample/src/com/dfs/unittest/DfsEngineTest.java new file mode 100644 index 0000000000..bd2c28575c --- /dev/null +++ b/tool/java/DfsSample/src/com/dfs/unittest/DfsEngineTest.java @@ -0,0 +1,343 @@ +/** + * @Title: DfsEngineTest.java + */ + +package com.dfs.unittest; + +import java.io.File; +import java.util.Calendar; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import com.dfs.entity.DfsConst; +import com.dfs.fileserver.DfsEngine; +import com.dfs.fileserver.IDfsListener; +import com.dfs.message.FileInfo; +import com.dfs.message.FileServer; + +/** + * @author Administrator + * + */ +public class DfsEngineTest extends DfsEngine { + private int threadCount = 0; + private IDfsListener TestListener; + private static int rpcPort = 8545; + private static String connHost = "192.168.8.219"; + private boolean isInited = false; + + //FileInfoManager contract address + private static String fileContract = "0x317523b03a8ed12a4994342d5dd8216f10483533"; + //FileServerManager contract address + private static String serverContract = "0x997736ea4fbedcbed96cbdc15955a1468886abb4"; + + private String walletPassword = "1111"; + private static String walletPath = "E:\\keys\\2429feaf-0e46-ddd5-5b72-0594e0a4ab00.json"; + + public DfsEngineTest() { + TestListener = new DfsTestListener(); + DfsTestListener childListener = (DfsTestListener)TestListener; + childListener.client = this; + + if (DfsConst.DFS_ERROR_OK != init(connHost, rpcPort, TestListener, walletPassword, walletPath, fileContract, serverContract)) { + System.err.println("init DfsEngine failed ! check input parameters and server node !"); + isInited = false; + } + isInited = true; + } + + /** + * @description 初始化 + * @param host 主机地址 + * @param port JSONRPC端口 + * @param listener 监听回调接口 + * @param walletPasswd 加密口令 + * @param walletFile 钱包文件 + * @param fileContract 文件信息合约 + * @param serverContract 文件服务合约 + * @return 0 :成功 其他:失败 + */ + public int init(String host, int port, IDfsListener listener, String walletPasswd, String walletFile, String fileContract, String serverContract) { + if (DfsConst.DFS_ERROR_OK != super.init(host, port, listener, walletPasswd, walletFile, fileContract, serverContract)) { + System.err.println("init DfsEngine failed !"); + return DfsConst.DFS_ERROR_FAIL; + } + + // we now add a server if in need. If we have already added one, this code can be comment + //{{ add servers here !!!!! + FileServer fileServer = new FileServer(); + fileServer.setGroup("group1"); + fileServer.setId("24cc3b974e9d8ee369f53fd018b840a735f12ce5e58af7f80d1644f6ed94631625b0aafb3fac778f639fa966f1bdc7387a438d71015c4f53f3c802ed4c127703"); + fileServer.setHost(connHost); + fileServer.setPort(rpcPort); + fileServer.setInfo("the master node"); + fileServer.setOrganization("group1"); + fileServer.setEnable(1); + Calendar calendar = Calendar.getInstance(); + fileServer.setUpdateTime((int)calendar.getTime().getTime() / 1000); + StringBuffer errorInfo = new StringBuffer(); + if (DfsConst.DFS_ERROR_OK != addServerSync(fileServer, errorInfo)) { + System.out.println("add serve failed: " + errorInfo.toString()); + } + + fileServer.setGroup("group1"); + fileServer.setId("bedade1701411a12fd073538af0852911df990a288390ae53daae1c5ca681988bcf73621e7d0f0672b269d03e13ce4150798fdf9db25c4bf55b923b8757859e0"); + fileServer.setHost("192.168.8.200"); + fileServer.setPort(rpcPort); + fileServer.setInfo("the slaver node"); + fileServer.setOrganization("group1"); + fileServer.setEnable(1); + fileServer.setUpdateTime((int)calendar.getTime().getTime() / 1000); + errorInfo = new StringBuffer(); + if (DfsConst.DFS_ERROR_OK != addServerSync(fileServer, errorInfo)) { + System.out.println("add serve failed: " + errorInfo.toString()); + } + //}} add servers here !!!!! + + return DfsConst.DFS_ERROR_OK; + } + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception { + // to ensure the child thread run successfully, the code below should not be removed + threadCount = Thread.activeCount(); + System.out.println("The active thread before test: " + threadCount); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception { + // to ensure the child thread run successfully, the code below should not be removed + while (Thread.activeCount() > threadCount) { + //wait + Thread.sleep(1000); + } + + threadCount = Thread.activeCount(); + System.out.println("The active thread after test: " + threadCount); + } + +// /** +// * Test method for {@link com.dfs.fileserver.DfsEngine#download(java.lang.String, java.lang.String)}. +// */ +// @Test +// public void testDownload() { +// String store_path = "E://test_download-be1942a0c692ae747aa37ca46266a17fa62297b6e7ac6d11fb75a888b9a9237a.log"; +// DfsTestListener childListener = (DfsTestListener)TestListener; +// childListener.updateTimeout(); +// downloadFile("be1942a0c692ae747aa37ca46266a17fa62297b6e7ac6d11fb75a888b9a9237a", store_path); +// } +// +// /** +// * Test method for {@link com.dfs.fileserver.DfsEngine#upload(com.dfs.message.FileInfo, java.lang.String)}. +// * @throws InterruptedException +// */ +// @Test +// public void testUpload_1M() throws InterruptedException { +// FileInfo fileInfo = new FileInfo(); +// fileInfo.setOwner("group1"); +// fileInfo.setPriviliges("rwx"); +// String file = "E:"+ File.separatorChar + "test1m.log"; +// +// for (int i = 1; i <= 1; i++) { +// System.out.println("**** upload file ... "); +// DfsTestListener childListener = (DfsTestListener)TestListener; +// childListener.updateTimeout(); +// int ret = uploadFile(fileInfo, file); +// if (DfsConst.DFS_ERROR_OK != ret){ +// System.out.println("**** upload file failed, check the parameters, ret: " + ret); +// } +// +// DfsTestListener testListener = (DfsTestListener)TestListener; +// while (testListener.upload_file_count != i) { +// Thread.sleep(1000); +// } +// +// System.out.println("upload file id: " + fileInfo.getId() + " succcess !"); +// } +// +// System.out.println("upload all files success !"); +// } + + /** + * Test method for {@link com.dfs.fileserver.DfsEngine#upload(com.ju.message.FileInfo, java.lang.String)}. + * @throws InterruptedException + */ + @Test + public void testUpload_10M() throws InterruptedException { + if (!isInited) { + System.err.println("init failed, should not upload files !"); + } + + FileInfo fileInfo = new FileInfo(); + fileInfo.setOwner("group1"); + fileInfo.setPriviliges("rwx"); + String file = "E:" + File.separatorChar + "test10m.log"; + + for (int i = 1; i <= 1; i++) { + boolean state = true; + System.out.println("**** upload file ... "); + DfsTestListener testListener = (DfsTestListener)TestListener; + testListener.updateTimeout(); + int ret = uploadFile(fileInfo, file); + if (DfsConst.DFS_ERROR_OK != ret) { + System.out.println("**** upload file failed, check the parameters, ret: " + ret); + state = false; + } + + while (testListener.upload_file_count != i && state) { + Thread.sleep(1000); + } + + System.out.println("upload file id: " + fileInfo.getId() + " succcess !"); + } + + System.out.println("upload all files success !"); + } + +// /** +// * Test method for {@link com.dfs.fileserver.DfsEngine#upload(com.ju.message.FileInfo, java.lang.String)}. +// * @throws InterruptedException +// */ +// @Test +// public void testUpload_100M() throws InterruptedException { +// FileServer server = getTheFileServer(); +// FileInfo fileInfo = new FileInfo(); +// fileInfo.setOwner("group1"); +// fileInfo.setPriviliges("rwx"); +// String file = "E:"+ File.separatorChar + "test100m.log"; +// +// for (int i = 1; i <= 10; i++) { +// System.out.println("**** upload file ... "); +// int ret = uploadFile(fileInfo, file); +// if (DfsFileConst.JU_ERROR_OK != ret){ +// System.out.println("**** upload file failed, check the parameters, ret: " + ret); +// } +// +// DfsTestListener testListener = (DfsTestListener)TestListener; +// while (testListener.upload_file_count != i) { +// Thread.sleep(1000); +// } +// +// System.out.println("upload file id: " + fileInfo.getId() + " succcess !"); +// } +// +// System.out.println("upload all files success !"); +// } +// +// +// /** +// * Test method for {@link com.dfs.fileserver.DfsEngine#delete(java.lang.String)}. +// */ +// @Test +// public void testDeleteFile() { +// deleteFile("03aa3e823cb7899b7b589ea242cdc2f26717d5fc");// +// } +// +// /** +// * Test method for {@link com.dfs.fileserver.DfsEngine#listFiles()}. +// */ +// @Test +// public void testListFiles() { +// listFiles(); +// } + +// /** +// * Test method for {@link com.dfs.fileserver.DfsEngine#findFile(java.lang.String)}. +// */ +// @Test +// public void testFindFile() { +// findFile("d9aab95fba4a1cff09161f258f5e5f439290a9d353f9775243c54a0242889769"); +// } +// +// +// /** +// * Test method for {@link com.dfs.fileserver.DfsEngine#listServerByGroup(java.lang.String)}. +// */ +// @Test +// public void testAddMasterServer() { +// FileServer fileServer = new FileServer(); +// fileServer.setGroup("group1"); +// fileServer.setId("03aa3e823cb7899b7b589ea242cdc2f26717d5fc"); +// fileServer.setHost("192.168.8.200"); +// fileServer.setPort(rpcPort); +// fileServer.setInfo("the master node"); +// fileServer.setOrganization("file server"); +// fileServer.setEnable(1); +// Calendar calendar = Calendar.getInstance(); +// fileServer.setUpdateTime((int)calendar.getTime().getTime()/1000); +// +// addServer(fileServer); +// System.out.println("-------------------------"); +// //assertEquals(DfsFileConst.JU_ERROR_OK, ret); +// } +// +// /** +// * Test method for {@link com.dfs.fileserver.DfsEngine#listServerByGroup(java.lang.String)}. +// */ +// @Test +// public void testAddSlaverServer() { +// FileServer fileServer = new FileServer(); +// fileServer.setGroup("group1"); +// fileServer.setId("66d708b2e46aee031f96ab89cea8f886526817b0"); +// fileServer.setHost("192.168.8.212"); +// fileServer.setPort(6789); +// fileServer.setInfo("the slaver node"); +// fileServer.setOrganization("group1"); +// fileServer.setEnable(1); +// Calendar calendar = Calendar.getInstance(); +// fileServer.setUpdateTime((int)calendar.getTime().getTime()/1000); +// addServer(fileServer); +// +// } + +// +// /** +// * Test method for {@link com.dfs.fileserver.DfsEngine#listServerByGroup(java.lang.String)}. +// */ +// @Test +// public void testDeleteServer() { +// deleteServer("03aa3e823cb7899b7b589ea242cdc2f26717d5fc"); +// } + +// /** +// * Test method for {@link com.dfs.fileserver.DfsEngine#listServer()}. +// */ +// @Test +// public void testListServer() { +// listServers(); +// } +// + /** + * Test method for {@link com.dfs.fileserver.DfsEngine#listServerByGroup(java.lang.String)}. + */ + @Test + public void testListServerByGroup() { + listServerByGroup("group1"); + } + +// public FileServer getTheFileServer() { +// final FileServer defaultServer = new FileServer(); +// defaultServer.setPort(port); +// defaultServer.setHost(host); +// defaultServer.setId("node001"); +// defaultServer.setGroup("group1"); +// if (getFileServers().size() <= 0){ +// return defaultServer; +// } +// +// Vector vecFiles = getFileServers(); +// for (FileServer file : vecFiles) { +// if (host.equals(file.getHost()) == true) +// return file; +// } +// +// return defaultServer; +// } + +} diff --git a/tool/java/DfsSample/src/com/dfs/unittest/DfsTestListener.java b/tool/java/DfsSample/src/com/dfs/unittest/DfsTestListener.java new file mode 100644 index 0000000000..e66e08f432 --- /dev/null +++ b/tool/java/DfsSample/src/com/dfs/unittest/DfsTestListener.java @@ -0,0 +1,134 @@ +/** + * @Title: JuTestListener.java + + * @date: 2017年3月7日 下午6:19:36 + + * @version: V1.0 + + */ +package com.dfs.unittest; + +import java.util.Calendar; +import java.util.Vector; +import java.util.concurrent.locks.ReentrantLock; +import com.dfs.fileserver.IDfsListener; +import com.dfs.message.FileInfo; +import com.dfs.message.FileServer; + +/** + * @author Administrator + * + */ +public class DfsTestListener implements IDfsListener{ + public DfsEngineTest client; + public Vector fileservers; + public volatile int upload_file_count = 0; + public ReentrantLock lock = new ReentrantLock(); + + public long Timeout = 0; + + public DfsTestListener() { + Timeout = Calendar.getInstance().getTimeInMillis(); + } + + public void updateTimeout() { + Timeout = Calendar.getInstance().getTimeInMillis(); + } + + @Override + public void downloadFileCallback(int ret, FileInfo fileinfo) { + // TODO Auto-generated method stub + Calendar calendar = Calendar.getInstance(); + long costTime = calendar.getTimeInMillis() - Timeout; + Timeout = Calendar.getInstance().getTimeInMillis(); + System.out.println("download_file_back, the ret: " + ret + ", info: " + fileinfo.getId() + ", cost time: " + costTime); + } + + @Override + public void uploadFileCallback(int ret, FileInfo fileinfo) { + long endTime = Calendar.getInstance().getTimeInMillis(); + long costTime = endTime - Timeout; + System.out.println("upload_file_back, the ret: " + ret + ", info: " + fileinfo.getId() + ", upload id: " + (upload_file_count+1) + ", cost time: " + costTime + ", start: " + Timeout + ", end: " + endTime); + Timeout = Calendar.getInstance().getTimeInMillis(); + lock.lock(); + ++upload_file_count; + lock.unlock(); + } + + @Override + public void deleteFileCallback(int ret, FileInfo fileinfo) { + // TODO Auto-generated method stub + System.out.println("delete_file_back, the ret: " + ret + ", info: " + fileinfo.getId()); + } + + @Override + public void listFileinfoCallback(int ret, Vector fileinfos) { + // TODO Auto-generated method stub + System.out.println("list_fileinfo_back, the ret: " + ret + ", has : " + fileinfos.size() + " fileinfo elements: " + fileinfos); + } + + @Override + public void findFileinfoCallback(int ret, FileInfo fileinfo) { + // TODO Auto-generated method stub + System.out.println("find_fileinfo_back, the ret: " + ret + ", info: " + fileinfo.getId()); + } + + @Override + public void listServersCallback(int ret, Vector fileservers) { + // TODO Auto-generated method stub + System.out.println("list_servers_back, the ret: " + ret + ", has : " + fileservers.size() + " fileserver elements"); + this.fileservers = fileservers; + } + + @Override + public void findServerCallback(int ret, FileServer fileserver) { + // TODO Auto-generated method stub + System.out.println("find_server_back, the ret: " + ret + ", info: " + fileserver.getId()); + } + + @Override + public void addServerCallback(int ret, FileServer fileinfo) { + // TODO Auto-generated method stub + System.out.println("add_server_back, the ret: " + ret + ", info: " + fileinfo.getId()); + } + + @Override + public void errorCallback(int code, String error) { + // TODO Auto-generated method stub + System.out.println("#### error_back, the ret: " + code + ", info: " + error); + } + + @Override + public void deleteServerCallback(int ret, FileServer fileinfo) { + // TODO Auto-generated method stub + System.out.println("delete_server_back, the ret: " + ret + ", info: " + fileinfo.getId()); + } + + @Override + public void listFileinfoByGroupCallback(int ret, Vector fileinfos) { + System.out.println("list_fileinfo_by_group_back, the ret: " + ret + ", has : " + fileinfos.size() + " fileinfo elements"); + } + + @Override + public void listServersByGroupCallback(int ret, Vector fileservers) { + System.out.println("list_servers_by_group_back, the ret: " + ret + ", has : " + fileservers.size() + " fileserver elements"); + } + + public Vector getServersByGroup(String group) { + Vector servers = new Vector(); + for (FileServer fileServer : fileservers) { + if (fileServer.getGroup() == group) { + servers.add(fileServer); + } + } + + return servers; + } + + @Override + public void enableServerCallback(int ret, String serverID) { + // TODO Auto-generated method stub + System.out.println("enable_server_back, the ret: " + ret + ", server : " + serverID); + } + +} diff --git a/tool/java/DfsSample/src/com/sample/HelloDfs.java b/tool/java/DfsSample/src/com/sample/HelloDfs.java new file mode 100644 index 0000000000..1fde30343b --- /dev/null +++ b/tool/java/DfsSample/src/com/sample/HelloDfs.java @@ -0,0 +1,117 @@ +package com.sample; + +import java.io.File; +import java.util.Calendar; + +import com.dfs.entity.DfsConst; +import com.dfs.fileserver.DfsEngine; +import com.dfs.message.FileInfo; +import com.dfs.message.FileServer; + +public class HelloDfs { + //Note: 修改这些常量与实际运行环境一致 + final static String walletPassword = "1111";//钱包口令 + final static String keyPath = "E:\\keys\\2429feaf-0e46-ddd5-5b72-0594e0a4ab00.json";//钱包文件 + final static String fileContract = "0x9e86c1b4c4d82607298faac27da7d78364434c58";//文件信息合约地址 + + final static String fileServerContract = "0x0d76426479e438fe0d261dbb165cd3adcc4a1dd7";//文件服务合约地址 + final static String host = "192.168.8.232";//服务节点主机 + final static int port = 8545;//JSONRPC端口 + + public HelloDfs() { + } + + public static void main(String[] args) { + System.out.println("The sample process starting..."); + + HelloDfs helloDfs = new HelloDfs(); + helloDfs.Hello(); + + System.out.println("The sample process is finished !"); + } + + public void Hello() { + //由于接口是异步的, 这里启动一个线程处理 + Thread thread = new Thread("DfsTestThread") { + public void run() { + //1. 初始化SDK + HelloListener helloListener = new HelloListener(); + DfsEngine engine = new DfsEngine(); + if (DfsConst.DFS_ERROR_OK != engine.init(host, port, helloListener, walletPassword, keyPath, fileContract, fileServerContract)) { //初始化 + System.out.println("init engine failed !!"); + return; + } + + //2. 添加文件服务节点 + FileServer fileServer = new FileServer(); + fileServer.setGroup("group1"); + fileServer.setId("0c1585a170e75c14564427f2faa8d74850c65765a10ce9aa4fcc55c7cdd60ab7768dd7fa066145d0ebada2214705fca7f464186e61ea163a18e6ebb9c99c7627"); + fileServer.setHost("192.168.8.232"); + fileServer.setPort(8545); + fileServer.setInfo("the master node"); + fileServer.setOrganization("weiwan"); + fileServer.setEnable(1); + Calendar calendar = Calendar.getInstance(); + fileServer.setUpdateTime((int)calendar.getTime().getTime() / 1000); + if (DfsConst.DFS_ERROR_OK != engine.addServer(fileServer)) { //添加文件服务节点 + System.out.println("addServer request failed ! bad parameters"); + return; + } + + //等待回调add_server_back回调成功 + try { + Thread.sleep(10000); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + }//10s + + //3. 上传文件 + FileInfo fileInfo = new FileInfo(); + fileInfo.setOwner("weiwan"); + fileInfo.setPriviliges("rwx"); + String file = "E:" + File.separatorChar + "test.txt"; + if (DfsConst.DFS_ERROR_OK != engine.uploadFile(fileInfo, file)) { //异步上传文件 + System.out.println("uploadFile request failed ! bad parameters"); + return; + } + + //等待回调upload_file_back...回调成功 + try { + Thread.sleep(10000); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + }//10s + + //使用文件ID下载文件 + //4. 下载文件 + String store_path = "C://download.txt"; + if (DfsConst.DFS_ERROR_OK != engine.downloadFile(helloListener.fileid, store_path)) { //异步下载文件 + System.out.println("downloadFile request failed ! bad parameters"); + return; + } + + //等待回调upload_file_back...回调成功 + try { + Thread.sleep(10000); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + }//10s + + System.out.println("Hello Done !"); + return; + } + }; + thread.start(); + + System.out.println("... waiting for bussiness handle thread exit..."); + try { + thread.join(); + } catch (InterruptedException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + } +} diff --git a/tool/java/DfsSample/src/com/sample/HelloListener.java b/tool/java/DfsSample/src/com/sample/HelloListener.java new file mode 100644 index 0000000000..eaeebcdf7f --- /dev/null +++ b/tool/java/DfsSample/src/com/sample/HelloListener.java @@ -0,0 +1,82 @@ +package com.sample; + +import java.util.Vector; + +import com.dfs.fileserver.IDfsListener; +import com.dfs.message.FileInfo; +import com.dfs.message.FileServer; + +public class HelloListener implements IDfsListener { + public String fileid; + + public HelloListener() { + fileid = ""; + } + + @Override + public void downloadFileCallback(int ret, FileInfo fileinfo) { + System.out.println("downloadFileCallback"); + } + + @Override + public void uploadFileCallback(int ret, FileInfo fileinfo) { + System.out.println("uploadFileCallback"); + fileid = fileinfo.getId(); + } + + @Override + public void deleteFileCallback(int ret, FileInfo fileinfo) { + System.out.println("deleteFileCallback"); + } + + @Override + public void listFileinfoCallback(int ret, Vector fileinfos) { + System.out.println("listFileinfoCallback"); + } + + @Override + public void listFileinfoByGroupCallback(int ret, Vector fileinfos) { + System.out.println("listFileinfoByGroupCallback"); + } + + @Override + public void findFileinfoCallback(int ret, FileInfo fileinfo) { + System.out.println("findFileinfoCallback"); + } + + @Override + public void listServersCallback(int ret, Vector fileservers) { + System.out.println("list_servers_back"); + } + + @Override + public void listServersByGroupCallback(int ret, Vector fileservers) { + System.out.println("list_servers_by_group_back"); + } + + @Override + public void findServerCallback(int ret, FileServer fileserver) { + System.out.println("find_server_back"); + } + + @Override + public void addServerCallback(int ret, FileServer server) { + System.out.println("add_server_back"); + } + + @Override + public void deleteServerCallback(int ret, FileServer server) { + System.out.println("delete_server_back"); + } + + @Override + public void enableServerCallback(int ret, String serverID) { + System.out.println("enable_server_back"); + } + + @Override + public void errorCallback(int code, String error) { + System.out.println("error_back"); + } + +} diff --git a/tool/java/Pailler/.classpath b/tool/java/Pailler/.classpath new file mode 100644 index 0000000000..ca374d50b5 --- /dev/null +++ b/tool/java/Pailler/.classpath @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/tool/java/Pailler/.project b/tool/java/Pailler/.project new file mode 100644 index 0000000000..6bcabb7910 --- /dev/null +++ b/tool/java/Pailler/.project @@ -0,0 +1,17 @@ + + + paillier + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/tool/java/Pailler/javascript/asn1hex.js b/tool/java/Pailler/javascript/asn1hex.js new file mode 100644 index 0000000000..4237a7d40e --- /dev/null +++ b/tool/java/Pailler/javascript/asn1hex.js @@ -0,0 +1,106 @@ +// +// asn1hex.js - Hexadecimal represented ASN.1 string library +// +// +// version: 1.0 (2010-Jun-03) +// +// Copyright (c) 2010 Kenji Urushima (kenji.urushima@gmail.com) +// +// This software is licensed under the terms of the MIT License. +// http://www.opensource.org/licenses/mit-license.php +// +// The above copyright and license notice shall be +// included in all copies or substantial portions of the Software. +// +// +// Depends on: +// + +// MEMO: +// f('3082025b02...', 2) ... 82025b ... 3bytes +// f('020100', 2) ... 01 ... 1byte +// f('0203001...', 2) ... 03 ... 1byte +// f('02818003...', 2) ... 8180 ... 2bytes +// f('3080....0000', 2) ... 80 ... -1 +// +// Requirements: +// - ASN.1 type octet length MUST be 1. +// (i.e. ASN.1 primitives like SET, SEQUENCE, INTEGER, OCTETSTRING ...) +// - +function _asnhex_getByteLengthOfL_AtObj(s, pos) { + if (s.substring(pos + 2, pos + 3) != '8') return 1; + var i = parseInt(s.substring(pos + 3, pos + 4)); + if (i == 0) return -1; // length octet '80' indefinite length + if (0 < i && i < 10) return i + 1; // including '8?' octet; + return -2; // malformed format +} + +function _asnhex_getHexOfL_AtObj(s, pos) { + var len = _asnhex_getByteLengthOfL_AtObj(s, pos); + if (len < 1) return ''; + return s.substring(pos + 2, pos + 2 + len * 2); +} + +// +// getting ASN.1 length value at the position 'idx' of +// hexa decimal string 's'. +// +// f('3082025b02...', 0) ... 82025b ... ??? +// f('020100', 0) ... 01 ... 1 +// f('0203001...', 0) ... 03 ... 3 +// f('02818003...', 0) ... 8180 ... 128 +function _asnhex_getIntOfL_AtObj(s, pos) { + var hLength = _asnhex_getHexOfL_AtObj(s, pos); + if (hLength == '') return -1; + var bi; + if (parseInt(hLength.substring(0, 1)) < 8) { + bi = parseBigInt(hLength, 16); + } else { + bi = parseBigInt(hLength.substring(2), 16); + } + return bi.intValue(); +} + +// +// get ASN.1 value starting string position +// for ASN.1 object refered by index 'idx'. +// +function _asnhex_getStartPosOfV_AtObj(s, pos) { + var l_len = _asnhex_getByteLengthOfL_AtObj(s, pos); + if (l_len < 0) return l_len; + return pos + (l_len + 1) * 2; +} + +function _asnhex_getHexOfV_AtObj(s, pos) { + var pos1 = _asnhex_getStartPosOfV_AtObj(s, pos); + var len = _asnhex_getIntOfL_AtObj(s, pos); + return s.substring(pos1, pos1 + len * 2); +} + +function _asnhex_getPosOfNextSibling_AtObj(s, pos) { + var pos1 = _asnhex_getStartPosOfV_AtObj(s, pos); + var len = _asnhex_getIntOfL_AtObj(s, pos); + return pos1 + len * 2; +} + +function _asnhex_getPosArrayOfChildren_AtObj(h, pos) { + var a = new Array(); + var p0 = _asnhex_getStartPosOfV_AtObj(h, pos); + a.push(p0); + + var len = _asnhex_getIntOfL_AtObj(h, pos); + var p = p0; + var k = 0; + while (1) { + var pNext = _asnhex_getPosOfNextSibling_AtObj(h, p); + if (pNext == null || (pNext - p0 >= (len * 2))) break; + if (k >= 200) break; + + a.push(pNext); + p = pNext; + + k++; + } + + return a; +} diff --git a/tool/java/Pailler/javascript/base64.js b/tool/java/Pailler/javascript/base64.js new file mode 100644 index 0000000000..18bc46c260 --- /dev/null +++ b/tool/java/Pailler/javascript/base64.js @@ -0,0 +1,71 @@ +var b64map="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +var b64padchar="="; + +function hex2b64(h) { + var i; + var c; + var ret = ""; + for(i = 0; i+3 <= h.length; i+=3) { + c = parseInt(h.substring(i,i+3),16); + ret += b64map.charAt(c >> 6) + b64map.charAt(c & 63); + } + if(i+1 == h.length) { + c = parseInt(h.substring(i,i+1),16); + ret += b64map.charAt(c << 2); + } + else if(i+2 == h.length) { + c = parseInt(h.substring(i,i+2),16); + ret += b64map.charAt(c >> 2) + b64map.charAt((c & 3) << 4); + } + while((ret.length & 3) > 0) ret += b64padchar; + return ret; +} + +// convert a base64 string to hex +function b64tohex(s) { + var ret = "" + var i; + var k = 0; // b64 state, 0-3 + var slop; + for(i = 0; i < s.length; ++i) { + if(s.charAt(i) == b64padchar) break; + v = b64map.indexOf(s.charAt(i)); + if(v < 0) continue; + if(k == 0) { + ret += int2char(v >> 2); + slop = v & 3; + k = 1; + } + else if(k == 1) { + ret += int2char((slop << 2) | (v >> 4)); + slop = v & 0xf; + k = 2; + } + else if(k == 2) { + ret += int2char(slop); + ret += int2char(v >> 2); + slop = v & 3; + k = 3; + } + else { + ret += int2char((slop << 2) | (v >> 4)); + ret += int2char(v & 0xf); + k = 0; + } + } + if(k == 1) + ret += int2char(slop << 2); + return ret; +} + +// convert a base64 string to a byte/number array +function b64toBA(s) { + //piggyback on b64tohex for now, optimize later + var h = b64tohex(s); + var i; + var a = new Array(); + for(i = 0; 2*i < h.length; ++i) { + a[i] = parseInt(h.substring(2*i,2*i+2),16); + } + return a; +} diff --git a/tool/java/Pailler/javascript/jsbn.js b/tool/java/Pailler/javascript/jsbn.js new file mode 100644 index 0000000000..e163555e5c --- /dev/null +++ b/tool/java/Pailler/javascript/jsbn.js @@ -0,0 +1,1217 @@ +// Copyright (c) 2005 Tom Wu +// All Rights Reserved. +// See "LICENSE" for details. + +// Basic JavaScript BN library - subset useful for RSA encryption. + +// Bits per digit +var dbits; + +// JavaScript engine analysis +var canary = 0xdeadbeefcafe; +var j_lm = ((canary&0xffffff)==0xefcafe); + +// (public) Constructor +function BigInteger(a,b,c) { + if(a != null) + if("number" == typeof a) this.fromNumber(a,b,c); + else if(b == null && "string" != typeof a) this.fromString(a,256); + else this.fromString(a,b); +} + +// return new, unset BigInteger +function nbi() { return new BigInteger(null); } + +// am: Compute w_j += (x*this_i), propagate carries, +// c is initial carry, returns final carry. +// c < 3*dvalue, x < 2*dvalue, this_i < dvalue +// We need to select the fastest one that works in this environment. + +// am1: use a single mult and divide to get the high bits, +// max digit bits should be 26 because +// max internal value = 2*dvalue^2-2*dvalue (< 2^53) +function am1(i,x,w,j,c,n) { + while(--n >= 0) { + var v = x*this[i++]+w[j]+c; + c = Math.floor(v/0x4000000); + w[j++] = v&0x3ffffff; + } + return c; +} +// am2 avoids a big mult-and-extract completely. +// Max digit bits should be <= 30 because we do bitwise ops +// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31) +function am2(i,x,w,j,c,n) { + var xl = x&0x7fff, xh = x>>15; + while(--n >= 0) { + var l = this[i]&0x7fff; + var h = this[i++]>>15; + var m = xh*l+h*xl; + l = xl*l+((m&0x7fff)<<15)+w[j]+(c&0x3fffffff); + c = (l>>>30)+(m>>>15)+xh*h+(c>>>30); + w[j++] = l&0x3fffffff; + } + return c; +} +// Alternately, set max digit bits to 28 since some +// browsers slow down when dealing with 32-bit numbers. +function am3(i,x,w,j,c,n) { + var xl = x&0x3fff, xh = x>>14; + while(--n >= 0) { + var l = this[i]&0x3fff; + var h = this[i++]>>14; + var m = xh*l+h*xl; + l = xl*l+((m&0x3fff)<<14)+w[j]+c; + c = (l>>28)+(m>>14)+xh*h; + w[j++] = l&0xfffffff; + } + return c; +} +if(j_lm && (navigator.appName == "Microsoft Internet Explorer")) { + BigInteger.prototype.am = am2; + dbits = 30; +} +else if(j_lm && (navigator.appName != "Netscape")) { + BigInteger.prototype.am = am1; + dbits = 26; +} +else { // Mozilla/Netscape seems to prefer am3 + BigInteger.prototype.am = am3; + dbits = 28; +} + +BigInteger.prototype.DB = dbits; +BigInteger.prototype.DM = ((1<= 0; --i) r[i] = this[i]; + r.t = this.t; + r.s = this.s; +} + +// (protected) set from integer value x, -DV <= x < DV +function bnpFromInt(x) { + this.t = 1; + this.s = (x<0)?-1:0; + if(x > 0) this[0] = x; + else if(x < -1) this[0] = x+this.DV; + else this.t = 0; +} + +// return bigint initialized to value +function nbv(i) { var r = nbi(); r.fromInt(i); return r; } + +// (protected) set from string and radix +function bnpFromString(s,b) { + var k; + if(b == 16) k = 4; + else if(b == 8) k = 3; + else if(b == 256) k = 8; // byte array + else if(b == 2) k = 1; + else if(b == 32) k = 5; + else if(b == 4) k = 2; + else { this.fromRadix(s,b); return; } + this.t = 0; + this.s = 0; + var i = s.length, mi = false, sh = 0; + while(--i >= 0) { + var x = (k==8)?s[i]&0xff:intAt(s,i); + if(x < 0) { + if(s.charAt(i) == "-") mi = true; + continue; + } + mi = false; + if(sh == 0) + this[this.t++] = x; + else if(sh+k > this.DB) { + this[this.t-1] |= (x&((1<<(this.DB-sh))-1))<>(this.DB-sh)); + } + else + this[this.t-1] |= x<= this.DB) sh -= this.DB; + } + if(k == 8 && (s[0]&0x80) != 0) { + this.s = -1; + if(sh > 0) this[this.t-1] |= ((1<<(this.DB-sh))-1)< 0 && this[this.t-1] == c) --this.t; +} + +// (public) return string representation in given radix +function bnToString(b) { + if(this.s < 0) return "-"+this.negate().toString(b); + var k; + if(b == 16) k = 4; + else if(b == 8) k = 3; + else if(b == 2) k = 1; + else if(b == 32) k = 5; + else if(b == 4) k = 2; + else return this.toRadix(b); + var km = (1< 0) { + if(p < this.DB && (d = this[i]>>p) > 0) { m = true; r = int2char(d); } + while(i >= 0) { + if(p < k) { + d = (this[i]&((1<>(p+=this.DB-k); + } + else { + d = (this[i]>>(p-=k))&km; + if(p <= 0) { p += this.DB; --i; } + } + if(d > 0) m = true; + if(m) r += int2char(d); + } + } + return m?r:"0"; +} + +// (public) -this +function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; } + +// (public) |this| +function bnAbs() { return (this.s<0)?this.negate():this; } + +// (public) return + if this > a, - if this < a, 0 if equal +function bnCompareTo(a) { + var r = this.s-a.s; + if(r != 0) return r; + var i = this.t; + r = i-a.t; + if(r != 0) return (this.s<0)?-r:r; + while(--i >= 0) if((r=this[i]-a[i]) != 0) return r; + return 0; +} + +// returns bit length of the integer x +function nbits(x) { + var r = 1, t; + if((t=x>>>16) != 0) { x = t; r += 16; } + if((t=x>>8) != 0) { x = t; r += 8; } + if((t=x>>4) != 0) { x = t; r += 4; } + if((t=x>>2) != 0) { x = t; r += 2; } + if((t=x>>1) != 0) { x = t; r += 1; } + return r; +} + +// (public) return the number of bits in "this" +function bnBitLength() { + if(this.t <= 0) return 0; + return this.DB*(this.t-1)+nbits(this[this.t-1]^(this.s&this.DM)); +} + +// (protected) r = this << n*DB +function bnpDLShiftTo(n,r) { + var i; + for(i = this.t-1; i >= 0; --i) r[i+n] = this[i]; + for(i = n-1; i >= 0; --i) r[i] = 0; + r.t = this.t+n; + r.s = this.s; +} + +// (protected) r = this >> n*DB +function bnpDRShiftTo(n,r) { + for(var i = n; i < this.t; ++i) r[i-n] = this[i]; + r.t = Math.max(this.t-n,0); + r.s = this.s; +} + +// (protected) r = this << n +function bnpLShiftTo(n,r) { + var bs = n%this.DB; + var cbs = this.DB-bs; + var bm = (1<= 0; --i) { + r[i+ds+1] = (this[i]>>cbs)|c; + c = (this[i]&bm)<= 0; --i) r[i] = 0; + r[ds] = c; + r.t = this.t+ds+1; + r.s = this.s; + r.clamp(); +} + +// (protected) r = this >> n +function bnpRShiftTo(n,r) { + r.s = this.s; + var ds = Math.floor(n/this.DB); + if(ds >= this.t) { r.t = 0; return; } + var bs = n%this.DB; + var cbs = this.DB-bs; + var bm = (1<>bs; + for(var i = ds+1; i < this.t; ++i) { + r[i-ds-1] |= (this[i]&bm)<>bs; + } + if(bs > 0) r[this.t-ds-1] |= (this.s&bm)<>= this.DB; + } + if(a.t < this.t) { + c -= a.s; + while(i < this.t) { + c += this[i]; + r[i++] = c&this.DM; + c >>= this.DB; + } + c += this.s; + } + else { + c += this.s; + while(i < a.t) { + c -= a[i]; + r[i++] = c&this.DM; + c >>= this.DB; + } + c -= a.s; + } + r.s = (c<0)?-1:0; + if(c < -1) r[i++] = this.DV+c; + else if(c > 0) r[i++] = c; + r.t = i; + r.clamp(); +} + +// (protected) r = this * a, r != this,a (HAC 14.12) +// "this" should be the larger one if appropriate. +function bnpMultiplyTo(a,r) { + var x = this.abs(), y = a.abs(); + var i = x.t; + r.t = i+y.t; + while(--i >= 0) r[i] = 0; + for(i = 0; i < y.t; ++i) r[i+x.t] = x.am(0,y[i],r,i,0,x.t); + r.s = 0; + r.clamp(); + if(this.s != a.s) BigInteger.ZERO.subTo(r,r); +} + +// (protected) r = this^2, r != this (HAC 14.16) +function bnpSquareTo(r) { + var x = this.abs(); + var i = r.t = 2*x.t; + while(--i >= 0) r[i] = 0; + for(i = 0; i < x.t-1; ++i) { + var c = x.am(i,x[i],r,2*i,0,1); + if((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1)) >= x.DV) { + r[i+x.t] -= x.DV; + r[i+x.t+1] = 1; + } + } + if(r.t > 0) r[r.t-1] += x.am(i,x[i],r,2*i,0,1); + r.s = 0; + r.clamp(); +} + +// (protected) divide this by m, quotient and remainder to q, r (HAC 14.20) +// r != q, this != m. q or r may be null. +function bnpDivRemTo(m,q,r) { + var pm = m.abs(); + if(pm.t <= 0) return; + var pt = this.abs(); + if(pt.t < pm.t) { + if(q != null) q.fromInt(0); + if(r != null) this.copyTo(r); + return; + } + if(r == null) r = nbi(); + var y = nbi(), ts = this.s, ms = m.s; + var nsh = this.DB-nbits(pm[pm.t-1]); // normalize modulus + if(nsh > 0) { pm.lShiftTo(nsh,y); pt.lShiftTo(nsh,r); } + else { pm.copyTo(y); pt.copyTo(r); } + var ys = y.t; + var y0 = y[ys-1]; + if(y0 == 0) return; + var yt = y0*(1<1)?y[ys-2]>>this.F2:0); + var d1 = this.FV/yt, d2 = (1<= 0) { + r[r.t++] = 1; + r.subTo(t,r); + } + BigInteger.ONE.dlShiftTo(ys,t); + t.subTo(y,y); // "negative" y so we can replace sub with am later + while(y.t < ys) y[y.t++] = 0; + while(--j >= 0) { + // Estimate quotient digit + var qd = (r[--i]==y0)?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2); + if((r[i]+=y.am(0,qd,r,j,0,ys)) < qd) { // Try it out + y.dlShiftTo(j,t); + r.subTo(t,r); + while(r[i] < --qd) r.subTo(t,r); + } + } + if(q != null) { + r.drShiftTo(ys,q); + if(ts != ms) BigInteger.ZERO.subTo(q,q); + } + r.t = ys; + r.clamp(); + if(nsh > 0) r.rShiftTo(nsh,r); // Denormalize remainder + if(ts < 0) BigInteger.ZERO.subTo(r,r); +} + +// (public) this mod a +function bnMod(a) { + var r = nbi(); + this.abs().divRemTo(a,null,r); + if(this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r,r); + return r; +} + +// Modular reduction using "classic" algorithm +function Classic(m) { this.m = m; } +function cConvert(x) { + if(x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m); + else return x; +} +function cRevert(x) { return x; } +function cReduce(x) { x.divRemTo(this.m,null,x); } +function cMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } +function cSqrTo(x,r) { x.squareTo(r); this.reduce(r); } + +Classic.prototype.convert = cConvert; +Classic.prototype.revert = cRevert; +Classic.prototype.reduce = cReduce; +Classic.prototype.mulTo = cMulTo; +Classic.prototype.sqrTo = cSqrTo; + +// (protected) return "-1/this % 2^DB"; useful for Mont. reduction +// justification: +// xy == 1 (mod m) +// xy = 1+km +// xy(2-xy) = (1+km)(1-km) +// x[y(2-xy)] = 1-k^2m^2 +// x[y(2-xy)] == 1 (mod m^2) +// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2 +// should reduce x and y(2-xy) by m^2 at each step to keep size bounded. +// JS multiply "overflows" differently from C/C++, so care is needed here. +function bnpInvDigit() { + if(this.t < 1) return 0; + var x = this[0]; + if((x&1) == 0) return 0; + var y = x&3; // y == 1/x mod 2^2 + y = (y*(2-(x&0xf)*y))&0xf; // y == 1/x mod 2^4 + y = (y*(2-(x&0xff)*y))&0xff; // y == 1/x mod 2^8 + y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff; // y == 1/x mod 2^16 + // last step - calculate inverse mod DV directly; + // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints + y = (y*(2-x*y%this.DV))%this.DV; // y == 1/x mod 2^dbits + // we really want the negative inverse, and -DV < y < DV + return (y>0)?this.DV-y:-y; +} + +// Montgomery reduction +function Montgomery(m) { + this.m = m; + this.mp = m.invDigit(); + this.mpl = this.mp&0x7fff; + this.mph = this.mp>>15; + this.um = (1<<(m.DB-15))-1; + this.mt2 = 2*m.t; +} + +// xR mod m +function montConvert(x) { + var r = nbi(); + x.abs().dlShiftTo(this.m.t,r); + r.divRemTo(this.m,null,r); + if(x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r,r); + return r; +} + +// x/R mod m +function montRevert(x) { + var r = nbi(); + x.copyTo(r); + this.reduce(r); + return r; +} + +// x = x/R mod m (HAC 14.32) +function montReduce(x) { + while(x.t <= this.mt2) // pad x so am has enough room later + x[x.t++] = 0; + for(var i = 0; i < this.m.t; ++i) { + // faster way of calculating u0 = x[i]*mp mod DV + var j = x[i]&0x7fff; + var u0 = (j*this.mpl+(((j*this.mph+(x[i]>>15)*this.mpl)&this.um)<<15))&x.DM; + // use am to combine the multiply-shift-add into one call + j = i+this.m.t; + x[j] += this.m.am(0,u0,x,i,0,this.m.t); + // propagate carry + while(x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; } + } + x.clamp(); + x.drShiftTo(this.m.t,x); + if(x.compareTo(this.m) >= 0) x.subTo(this.m,x); +} + +// r = "x^2/R mod m"; x != r +function montSqrTo(x,r) { x.squareTo(r); this.reduce(r); } + +// r = "xy/R mod m"; x,y != r +function montMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } + +Montgomery.prototype.convert = montConvert; +Montgomery.prototype.revert = montRevert; +Montgomery.prototype.reduce = montReduce; +Montgomery.prototype.mulTo = montMulTo; +Montgomery.prototype.sqrTo = montSqrTo; + +// (protected) true iff this is even +function bnpIsEven() { return ((this.t>0)?(this[0]&1):this.s) == 0; } + +// (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79) +function bnpExp(e,z) { + if(e > 0xffffffff || e < 1) return BigInteger.ONE; + var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e)-1; + g.copyTo(r); + while(--i >= 0) { + z.sqrTo(r,r2); + if((e&(1< 0) z.mulTo(r2,g,r); + else { var t = r; r = r2; r2 = t; } + } + return z.revert(r); +} + +// (public) this^e % m, 0 <= e < 2^32 +function bnModPowInt(e,m) { + var z; + if(e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m); + return this.exp(e,z); +} + +// protected +BigInteger.prototype.copyTo = bnpCopyTo; +BigInteger.prototype.fromInt = bnpFromInt; +BigInteger.prototype.fromString = bnpFromString; +BigInteger.prototype.clamp = bnpClamp; +BigInteger.prototype.dlShiftTo = bnpDLShiftTo; +BigInteger.prototype.drShiftTo = bnpDRShiftTo; +BigInteger.prototype.lShiftTo = bnpLShiftTo; +BigInteger.prototype.rShiftTo = bnpRShiftTo; +BigInteger.prototype.subTo = bnpSubTo; +BigInteger.prototype.multiplyTo = bnpMultiplyTo; +BigInteger.prototype.squareTo = bnpSquareTo; +BigInteger.prototype.divRemTo = bnpDivRemTo; +BigInteger.prototype.invDigit = bnpInvDigit; +BigInteger.prototype.isEven = bnpIsEven; +BigInteger.prototype.exp = bnpExp; + +// public +BigInteger.prototype.toString = bnToString; +BigInteger.prototype.negate = bnNegate; +BigInteger.prototype.abs = bnAbs; +BigInteger.prototype.compareTo = bnCompareTo; +BigInteger.prototype.bitLength = bnBitLength; +BigInteger.prototype.mod = bnMod; +BigInteger.prototype.modPowInt = bnModPowInt; + +// "constants" +BigInteger.ZERO = nbv(0); +BigInteger.ONE = nbv(1); + +// Copyright (c) 2005-2009 Tom Wu +// All Rights Reserved. +// See "LICENSE" for details. + +// Extended JavaScript BN functions, required for RSA private ops. + +// Version 1.1: new BigInteger("0", 10) returns "proper" zero +// Version 1.2: square() API, isProbablePrime fix + +// (public) +function bnClone() { var r = nbi(); this.copyTo(r); return r; } + +// (public) return value as integer +function bnIntValue() { + if(this.s < 0) { + if(this.t == 1) return this[0]-this.DV; + else if(this.t == 0) return -1; + } + else if(this.t == 1) return this[0]; + else if(this.t == 0) return 0; + // assumes 16 < DB < 32 + return ((this[1]&((1<<(32-this.DB))-1))<>24; } + +// (public) return value as short (assumes DB>=16) +function bnShortValue() { return (this.t==0)?this.s:(this[0]<<16)>>16; } + +// (protected) return x s.t. r^x < DV +function bnpChunkSize(r) { return Math.floor(Math.LN2*this.DB/Math.log(r)); } + +// (public) 0 if this == 0, 1 if this > 0 +function bnSigNum() { + if(this.s < 0) return -1; + else if(this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0; + else return 1; +} + +// (protected) convert to radix string +function bnpToRadix(b) { + if(b == null) b = 10; + if(this.signum() == 0 || b < 2 || b > 36) return "0"; + var cs = this.chunkSize(b); + var a = Math.pow(b,cs); + var d = nbv(a), y = nbi(), z = nbi(), r = ""; + this.divRemTo(d,y,z); + while(y.signum() > 0) { + r = (a+z.intValue()).toString(b).substr(1) + r; + y.divRemTo(d,y,z); + } + return z.intValue().toString(b) + r; +} + +// (protected) convert from radix string +function bnpFromRadix(s,b) { + this.fromInt(0); + if(b == null) b = 10; + var cs = this.chunkSize(b); + var d = Math.pow(b,cs), mi = false, j = 0, w = 0; + for(var i = 0; i < s.length; ++i) { + var x = intAt(s,i); + if(x < 0) { + if(s.charAt(i) == "-" && this.signum() == 0) mi = true; + continue; + } + w = b*w+x; + if(++j >= cs) { + this.dMultiply(d); + this.dAddOffset(w,0); + j = 0; + w = 0; + } + } + if(j > 0) { + this.dMultiply(Math.pow(b,j)); + this.dAddOffset(w,0); + } + if(mi) BigInteger.ZERO.subTo(this,this); +} + +// (protected) alternate constructor +function bnpFromNumber(a,b,c) { + if("number" == typeof b) { + // new BigInteger(int,int,RNG) + if(a < 2) this.fromInt(1); + else { + this.fromNumber(a,c); + if(!this.testBit(a-1)) // force MSB set + this.bitwiseTo(BigInteger.ONE.shiftLeft(a-1),op_or,this); + if(this.isEven()) this.dAddOffset(1,0); // force odd + while(!this.isProbablePrime(b)) { + this.dAddOffset(2,0); + if(this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a-1),this); + } + } + } + else { + // new BigInteger(int,RNG) + var x = new Array(), t = a&7; + x.length = (a>>3)+1; + b.nextBytes(x); + if(t > 0) x[0] &= ((1< 0) { + if(p < this.DB && (d = this[i]>>p) != (this.s&this.DM)>>p) + r[k++] = d|(this.s<<(this.DB-p)); + while(i >= 0) { + if(p < 8) { + d = (this[i]&((1<>(p+=this.DB-8); + } + else { + d = (this[i]>>(p-=8))&0xff; + if(p <= 0) { p += this.DB; --i; } + } + if((d&0x80) != 0) d |= -256; + if(k == 0 && (this.s&0x80) != (d&0x80)) ++k; + if(k > 0 || d != this.s) r[k++] = d; + } + } + return r; +} + +function bnEquals(a) { return(this.compareTo(a)==0); } +function bnMin(a) { return(this.compareTo(a)<0)?this:a; } +function bnMax(a) { return(this.compareTo(a)>0)?this:a; } + +// (protected) r = this op a (bitwise) +function bnpBitwiseTo(a,op,r) { + var i, f, m = Math.min(a.t,this.t); + for(i = 0; i < m; ++i) r[i] = op(this[i],a[i]); + if(a.t < this.t) { + f = a.s&this.DM; + for(i = m; i < this.t; ++i) r[i] = op(this[i],f); + r.t = this.t; + } + else { + f = this.s&this.DM; + for(i = m; i < a.t; ++i) r[i] = op(f,a[i]); + r.t = a.t; + } + r.s = op(this.s,a.s); + r.clamp(); +} + +// (public) this & a +function op_and(x,y) { return x&y; } +function bnAnd(a) { var r = nbi(); this.bitwiseTo(a,op_and,r); return r; } + +// (public) this | a +function op_or(x,y) { return x|y; } +function bnOr(a) { var r = nbi(); this.bitwiseTo(a,op_or,r); return r; } + +// (public) this ^ a +function op_xor(x,y) { return x^y; } +function bnXor(a) { var r = nbi(); this.bitwiseTo(a,op_xor,r); return r; } + +// (public) this & ~a +function op_andnot(x,y) { return x&~y; } +function bnAndNot(a) { var r = nbi(); this.bitwiseTo(a,op_andnot,r); return r; } + +// (public) ~this +function bnNot() { + var r = nbi(); + for(var i = 0; i < this.t; ++i) r[i] = this.DM&~this[i]; + r.t = this.t; + r.s = ~this.s; + return r; +} + +// (public) this << n +function bnShiftLeft(n) { + var r = nbi(); + if(n < 0) this.rShiftTo(-n,r); else this.lShiftTo(n,r); + return r; +} + +// (public) this >> n +function bnShiftRight(n) { + var r = nbi(); + if(n < 0) this.lShiftTo(-n,r); else this.rShiftTo(n,r); + return r; +} + +// return index of lowest 1-bit in x, x < 2^31 +function lbit(x) { + if(x == 0) return -1; + var r = 0; + if((x&0xffff) == 0) { x >>= 16; r += 16; } + if((x&0xff) == 0) { x >>= 8; r += 8; } + if((x&0xf) == 0) { x >>= 4; r += 4; } + if((x&3) == 0) { x >>= 2; r += 2; } + if((x&1) == 0) ++r; + return r; +} + +// (public) returns index of lowest 1-bit (or -1 if none) +function bnGetLowestSetBit() { + for(var i = 0; i < this.t; ++i) + if(this[i] != 0) return i*this.DB+lbit(this[i]); + if(this.s < 0) return this.t*this.DB; + return -1; +} + +// return number of 1 bits in x +function cbit(x) { + var r = 0; + while(x != 0) { x &= x-1; ++r; } + return r; +} + +// (public) return number of set bits +function bnBitCount() { + var r = 0, x = this.s&this.DM; + for(var i = 0; i < this.t; ++i) r += cbit(this[i]^x); + return r; +} + +// (public) true iff nth bit is set +function bnTestBit(n) { + var j = Math.floor(n/this.DB); + if(j >= this.t) return(this.s!=0); + return((this[j]&(1<<(n%this.DB)))!=0); +} + +// (protected) this op (1<>= this.DB; + } + if(a.t < this.t) { + c += a.s; + while(i < this.t) { + c += this[i]; + r[i++] = c&this.DM; + c >>= this.DB; + } + c += this.s; + } + else { + c += this.s; + while(i < a.t) { + c += a[i]; + r[i++] = c&this.DM; + c >>= this.DB; + } + c += a.s; + } + r.s = (c<0)?-1:0; + if(c > 0) r[i++] = c; + else if(c < -1) r[i++] = this.DV+c; + r.t = i; + r.clamp(); +} + +// (public) this + a +function bnAdd(a) { var r = nbi(); this.addTo(a,r); return r; } + +// (public) this - a +function bnSubtract(a) { var r = nbi(); this.subTo(a,r); return r; } + +// (public) this * a +function bnMultiply(a) { var r = nbi(); this.multiplyTo(a,r); return r; } + +// (public) this^2 +function bnSquare() { var r = nbi(); this.squareTo(r); return r; } + +// (public) this / a +function bnDivide(a) { var r = nbi(); this.divRemTo(a,r,null); return r; } + +// (public) this % a +function bnRemainder(a) { var r = nbi(); this.divRemTo(a,null,r); return r; } + +// (public) [this/a,this%a] +function bnDivideAndRemainder(a) { + var q = nbi(), r = nbi(); + this.divRemTo(a,q,r); + return new Array(q,r); +} + +// (protected) this *= n, this >= 0, 1 < n < DV +function bnpDMultiply(n) { + this[this.t] = this.am(0,n-1,this,0,0,this.t); + ++this.t; + this.clamp(); +} + +// (protected) this += n << w words, this >= 0 +function bnpDAddOffset(n,w) { + if(n == 0) return; + while(this.t <= w) this[this.t++] = 0; + this[w] += n; + while(this[w] >= this.DV) { + this[w] -= this.DV; + if(++w >= this.t) this[this.t++] = 0; + ++this[w]; + } +} + +// A "null" reducer +function NullExp() {} +function nNop(x) { return x; } +function nMulTo(x,y,r) { x.multiplyTo(y,r); } +function nSqrTo(x,r) { x.squareTo(r); } + +NullExp.prototype.convert = nNop; +NullExp.prototype.revert = nNop; +NullExp.prototype.mulTo = nMulTo; +NullExp.prototype.sqrTo = nSqrTo; + +// (public) this^e +function bnPow(e) { return this.exp(e,new NullExp()); } + +// (protected) r = lower n words of "this * a", a.t <= n +// "this" should be the larger one if appropriate. +function bnpMultiplyLowerTo(a,n,r) { + var i = Math.min(this.t+a.t,n); + r.s = 0; // assumes a,this >= 0 + r.t = i; + while(i > 0) r[--i] = 0; + var j; + for(j = r.t-this.t; i < j; ++i) r[i+this.t] = this.am(0,a[i],r,i,0,this.t); + for(j = Math.min(a.t,n); i < j; ++i) this.am(0,a[i],r,i,0,n-i); + r.clamp(); +} + +// (protected) r = "this * a" without lower n words, n > 0 +// "this" should be the larger one if appropriate. +function bnpMultiplyUpperTo(a,n,r) { + --n; + var i = r.t = this.t+a.t-n; + r.s = 0; // assumes a,this >= 0 + while(--i >= 0) r[i] = 0; + for(i = Math.max(n-this.t,0); i < a.t; ++i) + r[this.t+i-n] = this.am(n-i,a[i],r,0,0,this.t+i-n); + r.clamp(); + r.drShiftTo(1,r); +} + +// Barrett modular reduction +function Barrett(m) { + // setup Barrett + this.r2 = nbi(); + this.q3 = nbi(); + BigInteger.ONE.dlShiftTo(2*m.t,this.r2); + this.mu = this.r2.divide(m); + this.m = m; +} + +function barrettConvert(x) { + if(x.s < 0 || x.t > 2*this.m.t) return x.mod(this.m); + else if(x.compareTo(this.m) < 0) return x; + else { var r = nbi(); x.copyTo(r); this.reduce(r); return r; } +} + +function barrettRevert(x) { return x; } + +// x = x mod m (HAC 14.42) +function barrettReduce(x) { + x.drShiftTo(this.m.t-1,this.r2); + if(x.t > this.m.t+1) { x.t = this.m.t+1; x.clamp(); } + this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3); + this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2); + while(x.compareTo(this.r2) < 0) x.dAddOffset(1,this.m.t+1); + x.subTo(this.r2,x); + while(x.compareTo(this.m) >= 0) x.subTo(this.m,x); +} + +// r = x^2 mod m; x != r +function barrettSqrTo(x,r) { x.squareTo(r); this.reduce(r); } + +// r = x*y mod m; x,y != r +function barrettMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } + +Barrett.prototype.convert = barrettConvert; +Barrett.prototype.revert = barrettRevert; +Barrett.prototype.reduce = barrettReduce; +Barrett.prototype.mulTo = barrettMulTo; +Barrett.prototype.sqrTo = barrettSqrTo; + +// (public) this^e % m (HAC 14.85) +function bnModPow(e,m) { + var i = e.bitLength(), k, r = nbv(1), z; + if(i <= 0) return r; + else if(i < 18) k = 1; + else if(i < 48) k = 3; + else if(i < 144) k = 4; + else if(i < 768) k = 5; + else k = 6; + if(i < 8) + z = new Classic(m); + else if(m.isEven()) + z = new Barrett(m); + else + z = new Montgomery(m); + + // precomputation + var g = new Array(), n = 3, k1 = k-1, km = (1< 1) { + var g2 = nbi(); + z.sqrTo(g[1],g2); + while(n <= km) { + g[n] = nbi(); + z.mulTo(g2,g[n-2],g[n]); + n += 2; + } + } + + var j = e.t-1, w, is1 = true, r2 = nbi(), t; + i = nbits(e[j])-1; + while(j >= 0) { + if(i >= k1) w = (e[j]>>(i-k1))&km; + else { + w = (e[j]&((1<<(i+1))-1))<<(k1-i); + if(j > 0) w |= e[j-1]>>(this.DB+i-k1); + } + + n = k; + while((w&1) == 0) { w >>= 1; --n; } + if((i -= n) < 0) { i += this.DB; --j; } + if(is1) { // ret == 1, don't bother squaring or multiplying it + g[w].copyTo(r); + is1 = false; + } + else { + while(n > 1) { z.sqrTo(r,r2); z.sqrTo(r2,r); n -= 2; } + if(n > 0) z.sqrTo(r,r2); else { t = r; r = r2; r2 = t; } + z.mulTo(r2,g[w],r); + } + + while(j >= 0 && (e[j]&(1< 0) { + x.rShiftTo(g,x); + y.rShiftTo(g,y); + } + while(x.signum() > 0) { + if((i = x.getLowestSetBit()) > 0) x.rShiftTo(i,x); + if((i = y.getLowestSetBit()) > 0) y.rShiftTo(i,y); + if(x.compareTo(y) >= 0) { + x.subTo(y,x); + x.rShiftTo(1,x); + } + else { + y.subTo(x,y); + y.rShiftTo(1,y); + } + } + if(g > 0) y.lShiftTo(g,y); + return y; +} + +// (protected) this % n, n < 2^26 +function bnpModInt(n) { + if(n <= 0) return 0; + var d = this.DV%n, r = (this.s<0)?n-1:0; + if(this.t > 0) + if(d == 0) r = this[0]%n; + else for(var i = this.t-1; i >= 0; --i) r = (d*r+this[i])%n; + return r; +} + +// (public) 1/this % m (HAC 14.61) +function bnModInverse(m) { + var ac = m.isEven(); + if((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO; + var u = m.clone(), v = this.clone(); + var a = nbv(1), b = nbv(0), c = nbv(0), d = nbv(1); + while(u.signum() != 0) { + while(u.isEven()) { + u.rShiftTo(1,u); + if(ac) { + if(!a.isEven() || !b.isEven()) { a.addTo(this,a); b.subTo(m,b); } + a.rShiftTo(1,a); + } + else if(!b.isEven()) b.subTo(m,b); + b.rShiftTo(1,b); + } + while(v.isEven()) { + v.rShiftTo(1,v); + if(ac) { + if(!c.isEven() || !d.isEven()) { c.addTo(this,c); d.subTo(m,d); } + c.rShiftTo(1,c); + } + else if(!d.isEven()) d.subTo(m,d); + d.rShiftTo(1,d); + } + if(u.compareTo(v) >= 0) { + u.subTo(v,u); + if(ac) a.subTo(c,a); + b.subTo(d,b); + } + else { + v.subTo(u,v); + if(ac) c.subTo(a,c); + d.subTo(b,d); + } + } + if(v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO; + if(d.compareTo(m) >= 0) return d.subtract(m); + if(d.signum() < 0) d.addTo(m,d); else return d; + if(d.signum() < 0) return d.add(m); else return d; +} + +var lowprimes = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997]; +var lplim = (1<<26)/lowprimes[lowprimes.length-1]; + +// (public) test primality with certainty >= 1-.5^t +function bnIsProbablePrime(t) { + var i, x = this.abs(); + if(x.t == 1 && x[0] <= lowprimes[lowprimes.length-1]) { + for(i = 0; i < lowprimes.length; ++i) + if(x[0] == lowprimes[i]) return true; + return false; + } + if(x.isEven()) return false; + i = 1; + while(i < lowprimes.length) { + var m = lowprimes[i], j = i+1; + while(j < lowprimes.length && m < lplim) m *= lowprimes[j++]; + m = x.modInt(m); + while(i < j) if(m%lowprimes[i++] == 0) return false; + } + return x.millerRabin(t); +} + +// (protected) true if probably prime (HAC 4.24, Miller-Rabin) +function bnpMillerRabin(t) { + var n1 = this.subtract(BigInteger.ONE); + var k = n1.getLowestSetBit(); + if(k <= 0) return false; + var r = n1.shiftRight(k); + t = (t+1)>>1; + if(t > lowprimes.length) t = lowprimes.length; + var a = nbi(); + for(var i = 0; i < t; ++i) { + //Pick bases at random, instead of starting at 2 + a.fromInt(lowprimes[Math.floor(Math.random()*lowprimes.length)]); + var y = a.modPow(r,this); + if(y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) { + var j = 1; + while(j++ < k && y.compareTo(n1) != 0) { + y = y.modPowInt(2,this); + if(y.compareTo(BigInteger.ONE) == 0) return false; + } + if(y.compareTo(n1) != 0) return false; + } + } + return true; +} + +// protected +BigInteger.prototype.chunkSize = bnpChunkSize; +BigInteger.prototype.toRadix = bnpToRadix; +BigInteger.prototype.fromRadix = bnpFromRadix; +BigInteger.prototype.fromNumber = bnpFromNumber; +BigInteger.prototype.bitwiseTo = bnpBitwiseTo; +BigInteger.prototype.changeBit = bnpChangeBit; +BigInteger.prototype.addTo = bnpAddTo; +BigInteger.prototype.dMultiply = bnpDMultiply; +BigInteger.prototype.dAddOffset = bnpDAddOffset; +BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo; +BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo; +BigInteger.prototype.modInt = bnpModInt; +BigInteger.prototype.millerRabin = bnpMillerRabin; + +// public +BigInteger.prototype.clone = bnClone; +BigInteger.prototype.intValue = bnIntValue; +BigInteger.prototype.byteValue = bnByteValue; +BigInteger.prototype.shortValue = bnShortValue; +BigInteger.prototype.signum = bnSigNum; +BigInteger.prototype.toByteArray = bnToByteArray; +BigInteger.prototype.equals = bnEquals; +BigInteger.prototype.min = bnMin; +BigInteger.prototype.max = bnMax; +BigInteger.prototype.and = bnAnd; +BigInteger.prototype.or = bnOr; +BigInteger.prototype.xor = bnXor; +BigInteger.prototype.andNot = bnAndNot; +BigInteger.prototype.not = bnNot; +BigInteger.prototype.shiftLeft = bnShiftLeft; +BigInteger.prototype.shiftRight = bnShiftRight; +BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit; +BigInteger.prototype.bitCount = bnBitCount; +BigInteger.prototype.testBit = bnTestBit; +BigInteger.prototype.setBit = bnSetBit; +BigInteger.prototype.clearBit = bnClearBit; +BigInteger.prototype.flipBit = bnFlipBit; +BigInteger.prototype.add = bnAdd; +BigInteger.prototype.subtract = bnSubtract; +BigInteger.prototype.multiply = bnMultiply; +BigInteger.prototype.divide = bnDivide; +BigInteger.prototype.remainder = bnRemainder; +BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder; +BigInteger.prototype.modPow = bnModPow; +BigInteger.prototype.modInverse = bnModInverse; +BigInteger.prototype.pow = bnPow; +BigInteger.prototype.gcd = bnGCD; +BigInteger.prototype.isProbablePrime = bnIsProbablePrime; + +// JSBN-specific extension +BigInteger.prototype.square = bnSquare; + +// BigInteger interfaces not implemented in jsbn: + +// BigInteger(int signum, byte[] magnitude) +// double doubleValue() +// float floatValue() +// int hashCode() +// long longValue() +// static BigInteger valueOf(long val) + diff --git a/tool/java/Pailler/javascript/paillierKey.js b/tool/java/Pailler/javascript/paillierKey.js new file mode 100644 index 0000000000..1fc20879f5 --- /dev/null +++ b/tool/java/Pailler/javascript/paillierKey.js @@ -0,0 +1,333 @@ + +// convert a (hex) string to a bignum object +function parseBigInt(str,r) { + return new BigInteger(str,r); +} + +function _pem_extractEncodedData(sPEMString, sHead) { + var s = sPEMString; + s = s.replace("-----BEGIN " + sHead + "-----", ""); + s = s.replace("-----END " + sHead + "-----", ""); + s = s.replace(/[ \n]+/g, ""); + return s; +} + +function _rsapem_getPosArrayOfChildrenFromHex(hPrivateKey) { + var a = new Array(); + var v1 = _asnhex_getStartPosOfV_AtObj(hPrivateKey, 0); + var n1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, v1); + var e1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, n1); + var d1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, e1); + var p1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, d1); + var q1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, p1); + var dp1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, q1); + var dq1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, dp1); + var co1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, dq1); + a.push(v1, n1, e1, d1, p1, q1, dp1, dq1, co1); + return a; +} + +function _rsapem_getHexValueArrayOfChildrenFromHex(hPrivateKey) { + var posArray = _rsapem_getPosArrayOfChildrenFromHex(hPrivateKey); + var v = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[0]); + var n = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[1]); + var e = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[2]); + var d = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[3]); + var p = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[4]); + var q = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[5]); + var dp = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[6]); + var dq = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[7]); + var co = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[8]); + var a = new Array(); + a.push(v, n, e, d, p, q, dp, dq, co); + return a; +} + +function _rsapem_getPosArrayOfChildrenFromPublicKeyHex(hPrivateKey) { + var a = new Array(); + var header = _asnhex_getStartPosOfV_AtObj(hPrivateKey, 0); + var keys = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, header); + a.push(header, keys); + return a; +} + +function _rsapem_getPosArrayOfChildrenFromPrivateKeyHex(hPrivateKey) { + var a = new Array(); + var integer = _asnhex_getStartPosOfV_AtObj(hPrivateKey, 0); + var header = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, integer); + var keys = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, header); + a.push(integer, header, keys); + return a; +} + +function _rsapem_getHexValueArrayOfChildrenFromPublicKeyHex(hPrivateKey) { + var posArray = _rsapem_getPosArrayOfChildrenFromPublicKeyHex(hPrivateKey); + var headerVal = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[0]); + var keysVal = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[1]); + + var keysSequence = keysVal.substring(2); + posArray = _rsapem_getPosArrayOfChildrenFromPublicKeyHex(keysSequence); + var modulus = _asnhex_getHexOfV_AtObj(keysSequence, posArray[0]); + var publicExp = _asnhex_getHexOfV_AtObj(keysSequence, posArray[1]); + + var a = new Array(); + a.push(modulus, publicExp); + return a; +} + + +function _rsapem_getHexValueArrayOfChildrenFromPrivateKeyHex(hPrivateKey) { + var posArray = _rsapem_getPosArrayOfChildrenFromPrivateKeyHex(hPrivateKey); + var integerVal = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[0]); + var headerVal = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[1]); + var keysVal = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[2]); + + var keysSequence = keysVal.substring(2); + return _rsapem_getHexValueArrayOfChildrenFromHex(keysSequence); +} + +function _rsapem_readPrivateKeyFromPkcs1PemString(keyPEM) { + var keyB64 = _rsapem_extractEncodedData(keyPEM); + var keyHex = b64tohex(keyB64) // depends base64.js + var a = _rsapem_getHexValueArrayOfChildrenFromHex(keyHex); + this.setPrivateEx(a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8]); +} + +function _rsapem_readPrivateKeyFromPkcs8PemString(keyPEM) { + var keyB64 = _rsapem_extractEncodedData(keyPEM); + var keyHex = b64tohex(keyB64) // depends base64.js + var a = _rsapem_getHexValueArrayOfChildrenFromPrivateKeyHex(keyHex); + this.setPrivateEx(a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8]); +} + +function _rsapem_readPublicKeyFromX509PemString(keyPEM) { + var keyB64 = _rsapem_extractEncodedData(keyPEM); + var keyHex = b64tohex(keyB64) // depends base64.js + var a = _rsapem_getHexValueArrayOfChildrenFromPublicKeyHex(keyHex); + this.setPublic(a[0],a[1]); +} + +/** +* Pad string with leading zeros, to use even number of bytes. +*/ +function _rsapem_padWithZero(numString) { + if (numString.length % 2 == 1) { + return "0" + numString; + } + return numString; +} + +/** +* Encode length in DER format (if length <0x80, then one byte, else first byte is 0x80 + length of length :) + n-bytes of length). +*/ +function _rsapem_encodeLength(length) { + if (length >= parseInt("80", 16)) { + var realLength = _rsapem_padWithZero(length.toString(16)); + var lengthOfLength = (realLength.length / 2); + return (parseInt("80", 16) + lengthOfLength).toString(16) + realLength; + } else { + return _rsapem_padWithZero(length.toString(16)); + } +} + +/** +* Encode number in DER encoding ("02" + length + number). +*/ +function _rsapem_derEncodeNumber(number) { + var numberString = _rsapem_padWithZero(number.toString(16)); + if (numberString[0] > '7') { + numberString = "00" + numberString; + } + var lenString = _rsapem_encodeLength(numberString.length / 2); + return "02" + lenString + numberString; +} + +/** +* Converts private & public part of given key to ASN1 Hex String. +*/ +function _rsapem_privateKeyToPkcs1HexString(rsaKey) { + var result = _rsapem_derEncodeNumber(0); + result += _rsapem_derEncodeNumber(rsaKey.n); + result += _rsapem_derEncodeNumber(rsaKey.e); + result += _rsapem_derEncodeNumber(rsaKey.d); + result += _rsapem_derEncodeNumber(rsaKey.p); + result += _rsapem_derEncodeNumber(rsaKey.q); + result += _rsapem_derEncodeNumber(rsaKey.dmp1); + result += _rsapem_derEncodeNumber(rsaKey.dmq1); + result += _rsapem_derEncodeNumber(rsaKey.coeff); + + var fullLen = _rsapem_encodeLength(result.length / 2); + return '30' + fullLen + result; +} + +/** +* Converts private & public part of given key to PKCS#8 Hex String. +*/ +function _rsapem_privateKeyToPkcs8HexString(rsaKey) { + var zeroInteger = "020100"; + var encodedIdentifier = "06092A864886F70D010101"; + var encodedNull = "0500"; + var headerSequence = "300D" + encodedIdentifier + encodedNull; + var keySequence = _rsapem_privateKeyToPkcs1HexString(rsaKey); + + var keyOctetString = "04" + _rsapem_encodeLength(keySequence.length / 2) + keySequence; + + var mainSequence = zeroInteger + headerSequence + keyOctetString; + return "30" + _rsapem_encodeLength(mainSequence.length / 2) + mainSequence; +} + +/** +* Converts public part of given key to ASN1 Hex String. +*/ +function _rsapem_publicKeyToX509HexString(rsaKey) { + var encodedIdentifier = "06092A864886F70D010101"; + var encodedNull = "0500"; + var headerSequence = "300D" + encodedIdentifier + encodedNull; + + var keys = _rsapem_derEncodeNumber(rsaKey.n); + keys += _rsapem_derEncodeNumber(rsaKey.e); + + var keySequence = "0030" + _rsapem_encodeLength(keys.length / 2) + keys; + var bitstring = "03" + _rsapem_encodeLength(keySequence.length / 2) + keySequence; + + var mainSequence = headerSequence + bitstring; + + return "30" + _rsapem_encodeLength(mainSequence.length / 2) + mainSequence; +} + +/** +* Output private & public part of the key in PKCS#1 PEM format. +*/ +function _rsapem_privateKeyToPkcs1PemString() { + var b64Cert = hex2b64(_rsapem_privateKeyToPkcs1HexString(this)); + var s = "-----BEGIN RSA PRIVATE KEY-----\n"; + s = s + _rsa_splitKey(b64Cert, 64); + s = s + "\n-----END RSA PRIVATE KEY-----"; + return s; +} + +/** +* Output private & public part of the key in PKCS#8 PEM format. +*/ +function _rsapem_privateKeyToPkcs8PemString() { + var b64Cert = hex2b64(_rsapem_privateKeyToPkcs8HexString(this)); + var s = "-----BEGIN RSA PRIVATE KEY-----\n"; + s = s + _rsa_splitKey(b64Cert, 64); + s = s + "\n-----END RSA PRIVATE KEY-----"; + return s; +} + +/** +* Output public part of the key in x509 PKCS#1 PEM format. +*/ +function _rsapem_publicKeyToX509PemString() { + var b64Cert = hex2b64(_rsapem_publicKeyToX509HexString(this)); + var s = "-----BEGIN PUBLIC KEY-----\n"; + s = s + _rsa_splitKey(b64Cert, 64); + s = s + "\n-----END PUBLIC KEY-----"; + return s; +} + +function _rsa_splitKey(key, line) { + var splitKey = ""; + for (var i = 0; i < key.length; i++) { + if (i % line == 0 && i != 0 && i != (key.length - 1)) { + splitKey += "\n"; + } + splitKey += key[i]; + } + + return splitKey; +} + +function _paillier_padHex(s, n) { + var slen = s.length; + if(slen < n) { + for(var i = 0; i < n - slen; i++) { + s = "0" + s; + } + } + return s; +} + +function _paillier_encrypt(m) { + var rng = new SecureRandom(); + var random = null; + for (;;) + { + for (;;) + { + random = new BigInteger(this.n.bitLength(), 1, rng); + if (random.isProbablePrime(64)) break; + } + if(random.signum() == 1) break; + } + + if(m.signum() == -1) { + m = m.mod(this.n); + } + + var nsquare = this.n.multiply(this.n); + var g = this.n.add(BigInteger.ONE); + var cipher = g.modPow(m, nsquare).multiply(random.modPow(this.n, nsquare)).mod(nsquare); + var nstr = this.n.toString(16); + var nlen = Math.ceil(this.n.bitLength() / 8); + return _paillier_padHex(nlen.toString(16), 4) + nstr + _paillier_padHex(cipher.toString(16), nlen * 4); +} + +function _paillier_decrypt(ciphertext) { + var nlen = parseInt("0x" + c1.substr(0,4)) * 2; + var nstr = ciphertext.substr(4, nlen); + var cstr = ciphertext.substr(nlen + 4); + var n1 = parseBigInt(nstr, 16); + var intCiphertext = parseBigInt(cstr, 16); + if(n1.compareTo(this.n) != 0) return null; + + var lambda = this.p.subtract(BigInteger.ONE).multiply(this.q.subtract(BigInteger.ONE)); + var mu = lambda.modInverse(this.n); + var nsquare = this.n.multiply(this.n); + var message = intCiphertext.modPow(lambda, nsquare).subtract(BigInteger.ONE).divide(this.n).multiply(mu).mod(this.n); + var maxValue = BigInteger.ONE.shiftLeft(this.n.bitLength() / 2); + if(message.bitLength() > this.n.bitLength() / 2) { + return message.subtract(this.n); + } + else { + return message; + } +} + +function _paillier_add(c1, c2) { + var nlen1 = parseInt("0x" + c1.substr(0,4)) * 2; + var nstr1 = c1.substr(4, nlen1); + var cstr1 = c1.substr(nlen1 + 4); + var nlen2 = parseInt("0x" + c2.substr(0,4)) * 2; + var nstr2 = c2.substr(4, nlen2); + var cstr2 = c2.substr(nlen2 + 4); + var n1 = parseBigInt(nstr1, 16); + var n2 = parseBigInt(nstr2, 16); + + if(n2.compareTo(n1) != 0) { + return null; + } + + var ct1 = parseBigInt(cstr1, 16); + var ct2 = parseBigInt(cstr2, 16); + var nsquare = n1.multiply(n1); + var ct = ct1.multiply(ct2).mod(nsquare); + return _paillier_padHex(nlen1.toString(16), 4) + nstr1 + _paillier_padHex(ct.toString(16), nlen1 * 2); +} + +RSAKey.prototype.readPrivateKeyFromPkcs1PemString = _rsapem_readPrivateKeyFromPkcs1PemString; +RSAKey.prototype.privateKeyToPkcs1PemString = _rsapem_privateKeyToPkcs1PemString; + +RSAKey.prototype.readPrivateKeyFromPkcs8PemString = _rsapem_readPrivateKeyFromPkcs8PemString; +RSAKey.prototype.privateKeyToPkcs8PemString = _rsapem_privateKeyToPkcs8PemString; + +RSAKey.prototype.readPublicKeyFromX509PEMString = _rsapem_readPublicKeyFromX509PemString; +RSAKey.prototype.publicKeyToX509PemString = _rsapem_publicKeyToX509PemString; + +RSAKey.prototype.paillierEncrypt = _paillier_encrypt; +RSAKey.prototype.paillierDecrypt = _paillier_decrypt; +RSAKey.prototype.paillierAdd = _paillier_add; +RSAKey.prototype.splitKey = _rsa_splitKey; + diff --git a/tool/java/Pailler/javascript/rng.js b/tool/java/Pailler/javascript/rng.js new file mode 100644 index 0000000000..ff5b2f3d45 --- /dev/null +++ b/tool/java/Pailler/javascript/rng.js @@ -0,0 +1,121 @@ +// prng4.js - uses Arcfour as a PRNG + +function Arcfour() { + this.i = 0; + this.j = 0; + this.S = new Array(); +} + +// Initialize arcfour context from key, an array of ints, each from [0..255] +function ARC4init(key) { + var i, j, t; + for(i = 0; i < 256; ++i) + this.S[i] = i; + j = 0; + for(i = 0; i < 256; ++i) { + j = (j + this.S[i] + key[i % key.length]) & 255; + t = this.S[i]; + this.S[i] = this.S[j]; + this.S[j] = t; + } + this.i = 0; + this.j = 0; +} + +function ARC4next() { + var t; + this.i = (this.i + 1) & 255; + this.j = (this.j + this.S[this.i]) & 255; + t = this.S[this.i]; + this.S[this.i] = this.S[this.j]; + this.S[this.j] = t; + return this.S[(t + this.S[this.i]) & 255]; +} + +Arcfour.prototype.init = ARC4init; +Arcfour.prototype.next = ARC4next; + +// Plug in your RNG constructor here +function prng_newstate() { + return new Arcfour(); +} + +// Pool size must be a multiple of 4 and greater than 32. +// An array of bytes the size of the pool will be passed to init() +var rng_psize = 256; + +// Random number generator - requires a PRNG backend, e.g. prng4.js + +// For best results, put code like +// +// in your main HTML document. + +var rng_state; +var rng_pool; +var rng_pptr; + +// Mix in a 32-bit integer into the pool +function rng_seed_int(x) { + rng_pool[rng_pptr++] ^= x & 255; + rng_pool[rng_pptr++] ^= (x >> 8) & 255; + rng_pool[rng_pptr++] ^= (x >> 16) & 255; + rng_pool[rng_pptr++] ^= (x >> 24) & 255; + if(rng_pptr >= rng_psize) rng_pptr -= rng_psize; +} + +// Mix in the current time (w/milliseconds) into the pool +function rng_seed_time() { + rng_seed_int(new Date().getTime()); +} + +// Initialize the pool with junk if needed. +if(rng_pool == null) { + rng_pool = new Array(); + rng_pptr = 0; + var t; + if(window.crypto && window.crypto.getRandomValues) { + // Use webcrypto if available + var ua = new Uint8Array(32); + window.crypto.getRandomValues(ua); + for(t = 0; t < 32; ++t) + rng_pool[rng_pptr++] = ua[t]; + } + if(navigator.appName == "Netscape" && navigator.appVersion < "5" && window.crypto) { + // Extract entropy (256 bits) from NS4 RNG if available + var z = window.crypto.random(32); + for(t = 0; t < z.length; ++t) + rng_pool[rng_pptr++] = z.charCodeAt(t) & 255; + } + while(rng_pptr < rng_psize) { // extract some randomness from Math.random() + t = Math.floor(65536 * Math.random()); + rng_pool[rng_pptr++] = t >>> 8; + rng_pool[rng_pptr++] = t & 255; + } + rng_pptr = 0; + rng_seed_time(); + //rng_seed_int(window.screenX); + //rng_seed_int(window.screenY); +} + +function rng_get_byte() { + if(rng_state == null) { + rng_seed_time(); + rng_state = prng_newstate(); + rng_state.init(rng_pool); + for(rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr) + rng_pool[rng_pptr] = 0; + rng_pptr = 0; + //rng_pool = null; + } + // TODO: allow reseeding after first request + return rng_state.next(); +} + +function rng_get_bytes(ba) { + var i; + for(i = 0; i < ba.length; ++i) ba[i] = rng_get_byte(); +} + +function SecureRandom() {} + +SecureRandom.prototype.nextBytes = rng_get_bytes; diff --git a/tool/java/Pailler/javascript/rsa.js b/tool/java/Pailler/javascript/rsa.js new file mode 100644 index 0000000000..36fb7f5d33 --- /dev/null +++ b/tool/java/Pailler/javascript/rsa.js @@ -0,0 +1,247 @@ +// Depends on jsbn.js and rng.js + +// Version 1.1: support utf-8 encoding in pkcs1pad2 + +// convert a (hex) string to a bignum object +function parseBigInt(str,r) { + return new BigInteger(str,r); +} + +function linebrk(s,n) { + var ret = ""; + var i = 0; + while(i + n < s.length) { + ret += s.substring(i,i+n) + "\n"; + i += n; + } + return ret + s.substring(i,s.length); +} + +function byte2Hex(b) { + if(b < 0x10) + return "0" + b.toString(16); + else + return b.toString(16); +} + +// PKCS#1 (type 2, random) pad input string s to n bytes, and return a bigint +function pkcs1pad2(s,n) { + if(n < s.length + 11) { // TODO: fix for utf-8 + alert("Message too long for RSA"); + return null; + } + var ba = new Array(); + var i = s.length - 1; + while(i >= 0 && n > 0) { + var c = s.charCodeAt(i--); + if(c < 128) { // encode using utf-8 + ba[--n] = c; + } + else if((c > 127) && (c < 2048)) { + ba[--n] = (c & 63) | 128; + ba[--n] = (c >> 6) | 192; + } + else { + ba[--n] = (c & 63) | 128; + ba[--n] = ((c >> 6) & 63) | 128; + ba[--n] = (c >> 12) | 224; + } + } + ba[--n] = 0; + var rng = new SecureRandom(); + var x = new Array(); + while(n > 2) { // random non-zero pad + x[0] = 0; + while(x[0] == 0) rng.nextBytes(x); + ba[--n] = x[0]; + } + ba[--n] = 2; + ba[--n] = 0; + return new BigInteger(ba); +} + +// "empty" RSA key constructor +function RSAKey() { + this.n = null; + this.e = 0; + this.d = null; + this.p = null; + this.q = null; + this.dmp1 = null; + this.dmq1 = null; + this.coeff = null; +} + +// Set the public key fields N and e from hex strings +function RSASetPublic(N,E) { + if(N != null && E != null && N.length > 0 && E.length > 0) { + this.n = parseBigInt(N,16); + this.e = parseInt(E,16); + } + else + alert("Invalid RSA public key"); +} + +// Perform raw public operation on "x": return x^e (mod n) +function RSADoPublic(x) { + return x.modPowInt(this.e, this.n); +} + +// Return the PKCS#1 RSA encryption of "text" as an even-length hex string +function RSAEncrypt(text) { + var m = pkcs1pad2(text,(this.n.bitLength()+7)>>3); + if(m == null) return null; + var c = this.doPublic(m); + if(c == null) return null; + var h = c.toString(16); + if((h.length & 1) == 0) return h; else return "0" + h; +} + +// Return the PKCS#1 RSA encryption of "text" as a Base64-encoded string +//function RSAEncryptB64(text) { +// var h = this.encrypt(text); +// if(h) return hex2b64(h); else return null; +//} + +// protected +RSAKey.prototype.doPublic = RSADoPublic; + +// public +RSAKey.prototype.setPublic = RSASetPublic; +RSAKey.prototype.encrypt = RSAEncrypt; +//RSAKey.prototype.encrypt_b64 = RSAEncryptB64; + + +// Depends on rsa.js and jsbn2.js + +// Version 1.1: support utf-8 decoding in pkcs1unpad2 + +// Undo PKCS#1 (type 2, random) padding and, if valid, return the plaintext +function pkcs1unpad2(d,n) { + var b = d.toByteArray(); + var i = 0; + while(i < b.length && b[i] == 0) ++i; + if(b.length-i != n-1 || b[i] != 2) + return null; + ++i; + while(b[i] != 0) + if(++i >= b.length) return null; + var ret = ""; + while(++i < b.length) { + var c = b[i] & 255; + if(c < 128) { // utf-8 decode + ret += String.fromCharCode(c); + } + else if((c > 191) && (c < 224)) { + ret += String.fromCharCode(((c & 31) << 6) | (b[i+1] & 63)); + ++i; + } + else { + ret += String.fromCharCode(((c & 15) << 12) | ((b[i+1] & 63) << 6) | (b[i+2] & 63)); + i += 2; + } + } + return ret; +} + +// Set the private key fields N, e, and d from hex strings +function RSASetPrivate(N,E,D) { + if(N != null && E != null && N.length > 0 && E.length > 0) { + this.n = parseBigInt(N,16); + this.e = parseInt(E,16); + this.d = parseBigInt(D,16); + } + else + alert("Invalid RSA private key"); +} + +// Set the private key fields N, e, d and CRT params from hex strings +function RSASetPrivateEx(N,E,D,P,Q,DP,DQ,C) { + if(N != null && E != null && N.length > 0 && E.length > 0) { + this.n = parseBigInt(N,16); + this.e = parseInt(E,16); + this.d = parseBigInt(D,16); + this.p = parseBigInt(P,16); + this.q = parseBigInt(Q,16); + this.dmp1 = parseBigInt(DP,16); + this.dmq1 = parseBigInt(DQ,16); + this.coeff = parseBigInt(C,16); + } + else + alert("Invalid RSA private key"); +} + +// Generate a new random private key B bits long, using public expt E +function RSAGenerate(B) { + var rng = new SecureRandom(); + var qs = B>>1; + this.e = 65537; + var ee = new BigInteger("10001", 16); + for(;;) { + for(;;) { + this.p = new BigInteger(B-qs,1,rng); + if(this.p.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.p.isProbablePrime(64)) break; + } + for(;;) { + this.q = new BigInteger(qs,1,rng); + if(this.q.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.q.isProbablePrime(64)) break; + } + if(this.p.compareTo(this.q) <= 0) { + var t = this.p; + this.p = this.q; + this.q = t; + } + var p1 = this.p.subtract(BigInteger.ONE); + var q1 = this.q.subtract(BigInteger.ONE); + var phi = p1.multiply(q1); + if(phi.gcd(ee).compareTo(BigInteger.ONE) == 0) { + this.n = this.p.multiply(this.q); + this.d = ee.modInverse(phi); + this.dmp1 = this.d.mod(p1); + this.dmq1 = this.d.mod(q1); + this.coeff = this.q.modInverse(this.p); + break; + } + } +} + +// Perform raw private operation on "x": return x^d (mod n) +function RSADoPrivate(x) { + if(this.p == null || this.q == null) + return x.modPow(this.d, this.n); + + // TODO: re-calculate any missing CRT params + var xp = x.mod(this.p).modPow(this.dmp1, this.p); + var xq = x.mod(this.q).modPow(this.dmq1, this.q); + + while(xp.compareTo(xq) < 0) + xp = xp.add(this.p); + return xp.subtract(xq).multiply(this.coeff).mod(this.p).multiply(this.q).add(xq); +} + +// Return the PKCS#1 RSA decryption of "ctext". +// "ctext" is an even-length hex string and the output is a plain string. +function RSADecrypt(ctext) { + var c = parseBigInt(ctext, 16); + var m = this.doPrivate(c); + if(m == null) return null; + return pkcs1unpad2(m, (this.n.bitLength()+7)>>3); +} + +// Return the PKCS#1 RSA decryption of "ctext". +// "ctext" is a Base64-encoded string and the output is a plain string. +//function RSAB64Decrypt(ctext) { +// var h = b64tohex(ctext); +// if(h) return this.decrypt(h); else return null; +//} + +// protected +RSAKey.prototype.doPrivate = RSADoPrivate; + +// public +RSAKey.prototype.setPrivate = RSASetPrivate; +RSAKey.prototype.setPrivateEx = RSASetPrivateEx; +RSAKey.prototype.generate = RSAGenerate; +RSAKey.prototype.decrypt = RSADecrypt; +//RSAKey.prototype.b64_decrypt = RSAB64Decrypt; + diff --git a/tool/java/Pailler/javascript/test.html b/tool/java/Pailler/javascript/test.html new file mode 100644 index 0000000000..45170ed700 --- /dev/null +++ b/tool/java/Pailler/javascript/test.html @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + diff --git a/tool/java/Pailler/lib/bcprov-jdk15on-1.54.jar b/tool/java/Pailler/lib/bcprov-jdk15on-1.54.jar new file mode 100644 index 0000000000..bd95185ae8 Binary files /dev/null and b/tool/java/Pailler/lib/bcprov-jdk15on-1.54.jar differ diff --git a/tool/java/Pailler/paillier/asn1hex.js b/tool/java/Pailler/paillier/asn1hex.js new file mode 100644 index 0000000000..4237a7d40e --- /dev/null +++ b/tool/java/Pailler/paillier/asn1hex.js @@ -0,0 +1,106 @@ +// +// asn1hex.js - Hexadecimal represented ASN.1 string library +// +// +// version: 1.0 (2010-Jun-03) +// +// Copyright (c) 2010 Kenji Urushima (kenji.urushima@gmail.com) +// +// This software is licensed under the terms of the MIT License. +// http://www.opensource.org/licenses/mit-license.php +// +// The above copyright and license notice shall be +// included in all copies or substantial portions of the Software. +// +// +// Depends on: +// + +// MEMO: +// f('3082025b02...', 2) ... 82025b ... 3bytes +// f('020100', 2) ... 01 ... 1byte +// f('0203001...', 2) ... 03 ... 1byte +// f('02818003...', 2) ... 8180 ... 2bytes +// f('3080....0000', 2) ... 80 ... -1 +// +// Requirements: +// - ASN.1 type octet length MUST be 1. +// (i.e. ASN.1 primitives like SET, SEQUENCE, INTEGER, OCTETSTRING ...) +// - +function _asnhex_getByteLengthOfL_AtObj(s, pos) { + if (s.substring(pos + 2, pos + 3) != '8') return 1; + var i = parseInt(s.substring(pos + 3, pos + 4)); + if (i == 0) return -1; // length octet '80' indefinite length + if (0 < i && i < 10) return i + 1; // including '8?' octet; + return -2; // malformed format +} + +function _asnhex_getHexOfL_AtObj(s, pos) { + var len = _asnhex_getByteLengthOfL_AtObj(s, pos); + if (len < 1) return ''; + return s.substring(pos + 2, pos + 2 + len * 2); +} + +// +// getting ASN.1 length value at the position 'idx' of +// hexa decimal string 's'. +// +// f('3082025b02...', 0) ... 82025b ... ??? +// f('020100', 0) ... 01 ... 1 +// f('0203001...', 0) ... 03 ... 3 +// f('02818003...', 0) ... 8180 ... 128 +function _asnhex_getIntOfL_AtObj(s, pos) { + var hLength = _asnhex_getHexOfL_AtObj(s, pos); + if (hLength == '') return -1; + var bi; + if (parseInt(hLength.substring(0, 1)) < 8) { + bi = parseBigInt(hLength, 16); + } else { + bi = parseBigInt(hLength.substring(2), 16); + } + return bi.intValue(); +} + +// +// get ASN.1 value starting string position +// for ASN.1 object refered by index 'idx'. +// +function _asnhex_getStartPosOfV_AtObj(s, pos) { + var l_len = _asnhex_getByteLengthOfL_AtObj(s, pos); + if (l_len < 0) return l_len; + return pos + (l_len + 1) * 2; +} + +function _asnhex_getHexOfV_AtObj(s, pos) { + var pos1 = _asnhex_getStartPosOfV_AtObj(s, pos); + var len = _asnhex_getIntOfL_AtObj(s, pos); + return s.substring(pos1, pos1 + len * 2); +} + +function _asnhex_getPosOfNextSibling_AtObj(s, pos) { + var pos1 = _asnhex_getStartPosOfV_AtObj(s, pos); + var len = _asnhex_getIntOfL_AtObj(s, pos); + return pos1 + len * 2; +} + +function _asnhex_getPosArrayOfChildren_AtObj(h, pos) { + var a = new Array(); + var p0 = _asnhex_getStartPosOfV_AtObj(h, pos); + a.push(p0); + + var len = _asnhex_getIntOfL_AtObj(h, pos); + var p = p0; + var k = 0; + while (1) { + var pNext = _asnhex_getPosOfNextSibling_AtObj(h, p); + if (pNext == null || (pNext - p0 >= (len * 2))) break; + if (k >= 200) break; + + a.push(pNext); + p = pNext; + + k++; + } + + return a; +} diff --git a/tool/java/Pailler/paillier/base64.js b/tool/java/Pailler/paillier/base64.js new file mode 100644 index 0000000000..2eda5af8e4 --- /dev/null +++ b/tool/java/Pailler/paillier/base64.js @@ -0,0 +1,68 @@ +var b64map="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +var b64pad="="; +function hex2b64(h) { + var i; + var c; + var ret = ""; + for(i = 0; i+3 <= h.length; i+=3) { + c = parseInt(h.substring(i,i+3),16); + ret += b64map.charAt(c >> 6) + b64map.charAt(c & 63); + } + if(i+1 == h.length) { + c = parseInt(h.substring(i,i+1),16); + ret += b64map.charAt(c << 2); + } + else if(i+2 == h.length) { + c = parseInt(h.substring(i,i+2),16); + ret += b64map.charAt(c >> 2) + b64map.charAt((c & 3) << 4); + } + while((ret.length & 3) > 0) ret += b64pad; + return ret; +} +// convert a base64 string to hex +function b64tohex(s) { + var ret = "" + var i; + var k = 0; // b64 state, 0-3 + var slop; + for(i = 0; i < s.length; ++i) { + if(s.charAt(i) == b64pad) break; + v = b64map.indexOf(s.charAt(i)); + if(v < 0) continue; + if(k == 0) { + ret += int2char(v >> 2); + slop = v & 3; + k = 1; + } + else if(k == 1) { + ret += int2char((slop << 2) | (v >> 4)); + slop = v & 0xf; + k = 2; + } + else if(k == 2) { + ret += int2char(slop); + ret += int2char(v >> 2); + slop = v & 3; + k = 3; + } + else { + ret += int2char((slop << 2) | (v >> 4)); + ret += int2char(v & 0xf); + k = 0; + } + } + if(k == 1) + ret += int2char(slop << 2); + return ret; +} +// convert a base64 string to a byte/number array +function b64toBA(s) { + //piggyback on b64tohex for now, optimize later + var h = b64tohex(s); + var i; + var a = new Array(); + for(i = 0; 2*i < h.length; ++i) { + a[i] = parseInt(h.substring(2*i,2*i+2),16); + } + return a; +} diff --git a/tool/java/Pailler/paillier/biginteger.js b/tool/java/Pailler/paillier/biginteger.js new file mode 100644 index 0000000000..d660917314 --- /dev/null +++ b/tool/java/Pailler/paillier/biginteger.js @@ -0,0 +1,1200 @@ + +var dbits; + +// JavaScript engine analysis +var canary = 0xdeadbeefcafe; +var j_lm = ((canary&0xffffff)==0xefcafe); + +// (public) Constructor +function BigInteger(a,b,c) { + if(a != null) + if("number" == typeof a) this.fromNumber(a,b,c); + else if(b == null && "string" != typeof a) this.fromString(a,256); + else this.fromString(a,b); +} + +// return new, unset BigInteger +function nbi() { return new BigInteger(null); } + +// am: Compute w_j += (x*this_i), propagate carries, +// c is initial carry, returns final carry. +// c < 3*dvalue, x < 2*dvalue, this_i < dvalue +// We need to select the fastest one that works in this environment. + +// am1: use a single mult and divide to get the high bits, +// max digit bits should be 26 because +// max internal value = 2*dvalue^2-2*dvalue (< 2^53) +function am1(i,x,w,j,c,n) { + while(--n >= 0) { + var v = x*this[i++]+w[j]+c; + c = Math.floor(v/0x4000000); + w[j++] = v&0x3ffffff; + } + return c; +} +// am2 avoids a big mult-and-extract completely. +// Max digit bits should be <= 30 because we do bitwise ops +// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31) +function am2(i,x,w,j,c,n) { + var xl = x&0x7fff, xh = x>>15; + while(--n >= 0) { + var l = this[i]&0x7fff; + var h = this[i++]>>15; + var m = xh*l+h*xl; + l = xl*l+((m&0x7fff)<<15)+w[j]+(c&0x3fffffff); + c = (l>>>30)+(m>>>15)+xh*h+(c>>>30); + w[j++] = l&0x3fffffff; + } + return c; +} +// Alternately, set max digit bits to 28 since some +// browsers slow down when dealing with 32-bit numbers. +function am3(i,x,w,j,c,n) { + var xl = x&0x3fff, xh = x>>14; + while(--n >= 0) { + var l = this[i]&0x3fff; + var h = this[i++]>>14; + var m = xh*l+h*xl; + l = xl*l+((m&0x3fff)<<14)+w[j]+c; + c = (l>>28)+(m>>14)+xh*h; + w[j++] = l&0xfffffff; + } + return c; +} +if(j_lm && (navigator.appName == "Microsoft Internet Explorer")) { + BigInteger.prototype.am = am2; + dbits = 30; +} +else if(j_lm && (navigator.appName != "Netscape")) { + BigInteger.prototype.am = am1; + dbits = 26; +} +else { // Mozilla/Netscape seems to prefer am3 + BigInteger.prototype.am = am3; + dbits = 28; +} + +BigInteger.prototype.DB = dbits; +BigInteger.prototype.DM = ((1<= 0; --i) r[i] = this[i]; + r.t = this.t; + r.s = this.s; +} + +// (protected) set from integer value x, -DV <= x < DV +function bnpFromInt(x) { + this.t = 1; + this.s = (x<0)?-1:0; + if(x > 0) this[0] = x; + else if(x < -1) this[0] = x+this.DV; + else this.t = 0; +} + +// return bigint initialized to value +function nbv(i) { var r = nbi(); r.fromInt(i); return r; } + +// (protected) set from string and radix +function bnpFromString(s,b) { + var k; + if(b == 16) k = 4; + else if(b == 8) k = 3; + else if(b == 256) k = 8; // byte array + else if(b == 2) k = 1; + else if(b == 32) k = 5; + else if(b == 4) k = 2; + else { this.fromRadix(s,b); return; } + this.t = 0; + this.s = 0; + var i = s.length, mi = false, sh = 0; + while(--i >= 0) { + var x = (k==8)?s[i]&0xff:intAt(s,i); + if(x < 0) { + if(s.charAt(i) == "-") mi = true; + continue; + } + mi = false; + if(sh == 0) + this[this.t++] = x; + else if(sh+k > this.DB) { + this[this.t-1] |= (x&((1<<(this.DB-sh))-1))<>(this.DB-sh)); + } + else + this[this.t-1] |= x<= this.DB) sh -= this.DB; + } + if(k == 8 && (s[0]&0x80) != 0) { + this.s = -1; + if(sh > 0) this[this.t-1] |= ((1<<(this.DB-sh))-1)< 0 && this[this.t-1] == c) --this.t; +} + +// (public) return string representation in given radix +function bnToString(b) { + if(this.s < 0) return "-"+this.negate().toString(b); + var k; + if(b == 16) k = 4; + else if(b == 8) k = 3; + else if(b == 2) k = 1; + else if(b == 32) k = 5; + else if(b == 4) k = 2; + else return this.toRadix(b); + var km = (1< 0) { + if(p < this.DB && (d = this[i]>>p) > 0) { m = true; r = int2char(d); } + while(i >= 0) { + if(p < k) { + d = (this[i]&((1<>(p+=this.DB-k); + } + else { + d = (this[i]>>(p-=k))&km; + if(p <= 0) { p += this.DB; --i; } + } + if(d > 0) m = true; + if(m) r += int2char(d); + } + } + return m?r:"0"; +} + +// (public) -this +function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; } + +// (public) |this| +function bnAbs() { return (this.s<0)?this.negate():this; } + +// (public) return + if this > a, - if this < a, 0 if equal +function bnCompareTo(a) { + var r = this.s-a.s; + if(r != 0) return r; + var i = this.t; + r = i-a.t; + if(r != 0) return (this.s<0)?-r:r; + while(--i >= 0) if((r=this[i]-a[i]) != 0) return r; + return 0; +} + +// returns bit length of the integer x +function nbits(x) { + var r = 1, t; + if((t=x>>>16) != 0) { x = t; r += 16; } + if((t=x>>8) != 0) { x = t; r += 8; } + if((t=x>>4) != 0) { x = t; r += 4; } + if((t=x>>2) != 0) { x = t; r += 2; } + if((t=x>>1) != 0) { x = t; r += 1; } + return r; +} + +// (public) return the number of bits in "this" +function bnBitLength() { + if(this.t <= 0) return 0; + return this.DB*(this.t-1)+nbits(this[this.t-1]^(this.s&this.DM)); +} + +// (protected) r = this << n*DB +function bnpDLShiftTo(n,r) { + var i; + for(i = this.t-1; i >= 0; --i) r[i+n] = this[i]; + for(i = n-1; i >= 0; --i) r[i] = 0; + r.t = this.t+n; + r.s = this.s; +} + +// (protected) r = this >> n*DB +function bnpDRShiftTo(n,r) { + for(var i = n; i < this.t; ++i) r[i-n] = this[i]; + r.t = Math.max(this.t-n,0); + r.s = this.s; +} + +// (protected) r = this << n +function bnpLShiftTo(n,r) { + var bs = n%this.DB; + var cbs = this.DB-bs; + var bm = (1<= 0; --i) { + r[i+ds+1] = (this[i]>>cbs)|c; + c = (this[i]&bm)<= 0; --i) r[i] = 0; + r[ds] = c; + r.t = this.t+ds+1; + r.s = this.s; + r.clamp(); +} + +// (protected) r = this >> n +function bnpRShiftTo(n,r) { + r.s = this.s; + var ds = Math.floor(n/this.DB); + if(ds >= this.t) { r.t = 0; return; } + var bs = n%this.DB; + var cbs = this.DB-bs; + var bm = (1<>bs; + for(var i = ds+1; i < this.t; ++i) { + r[i-ds-1] |= (this[i]&bm)<>bs; + } + if(bs > 0) r[this.t-ds-1] |= (this.s&bm)<>= this.DB; + } + if(a.t < this.t) { + c -= a.s; + while(i < this.t) { + c += this[i]; + r[i++] = c&this.DM; + c >>= this.DB; + } + c += this.s; + } + else { + c += this.s; + while(i < a.t) { + c -= a[i]; + r[i++] = c&this.DM; + c >>= this.DB; + } + c -= a.s; + } + r.s = (c<0)?-1:0; + if(c < -1) r[i++] = this.DV+c; + else if(c > 0) r[i++] = c; + r.t = i; + r.clamp(); +} + +// (protected) r = this * a, r != this,a (HAC 14.12) +// "this" should be the larger one if appropriate. +function bnpMultiplyTo(a,r) { + var x = this.abs(), y = a.abs(); + var i = x.t; + r.t = i+y.t; + while(--i >= 0) r[i] = 0; + for(i = 0; i < y.t; ++i) r[i+x.t] = x.am(0,y[i],r,i,0,x.t); + r.s = 0; + r.clamp(); + if(this.s != a.s) BigInteger.ZERO.subTo(r,r); +} + +// (protected) r = this^2, r != this (HAC 14.16) +function bnpSquareTo(r) { + var x = this.abs(); + var i = r.t = 2*x.t; + while(--i >= 0) r[i] = 0; + for(i = 0; i < x.t-1; ++i) { + var c = x.am(i,x[i],r,2*i,0,1); + if((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1)) >= x.DV) { + r[i+x.t] -= x.DV; + r[i+x.t+1] = 1; + } + } + if(r.t > 0) r[r.t-1] += x.am(i,x[i],r,2*i,0,1); + r.s = 0; + r.clamp(); +} + +// (protected) divide this by m, quotient and remainder to q, r (HAC 14.20) +// r != q, this != m. q or r may be null. +function bnpDivRemTo(m,q,r) { + var pm = m.abs(); + if(pm.t <= 0) return; + var pt = this.abs(); + if(pt.t < pm.t) { + if(q != null) q.fromInt(0); + if(r != null) this.copyTo(r); + return; + } + if(r == null) r = nbi(); + var y = nbi(), ts = this.s, ms = m.s; + var nsh = this.DB-nbits(pm[pm.t-1]); // normalize modulus + if(nsh > 0) { pm.lShiftTo(nsh,y); pt.lShiftTo(nsh,r); } + else { pm.copyTo(y); pt.copyTo(r); } + var ys = y.t; + var y0 = y[ys-1]; + if(y0 == 0) return; + var yt = y0*(1<1)?y[ys-2]>>this.F2:0); + var d1 = this.FV/yt, d2 = (1<= 0) { + r[r.t++] = 1; + r.subTo(t,r); + } + BigInteger.ONE.dlShiftTo(ys,t); + t.subTo(y,y); // "negative" y so we can replace sub with am later + while(y.t < ys) y[y.t++] = 0; + while(--j >= 0) { + // Estimate quotient digit + var qd = (r[--i]==y0)?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2); + if((r[i]+=y.am(0,qd,r,j,0,ys)) < qd) { // Try it out + y.dlShiftTo(j,t); + r.subTo(t,r); + while(r[i] < --qd) r.subTo(t,r); + } + } + if(q != null) { + r.drShiftTo(ys,q); + if(ts != ms) BigInteger.ZERO.subTo(q,q); + } + r.t = ys; + r.clamp(); + if(nsh > 0) r.rShiftTo(nsh,r); // Denormalize remainder + if(ts < 0) BigInteger.ZERO.subTo(r,r); +} + +// (public) this mod a +function bnMod(a) { + var r = nbi(); + this.abs().divRemTo(a,null,r); + if(this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r,r); + return r; +} + +// Modular reduction using "classic" algorithm +function Classic(m) { this.m = m; } +function cConvert(x) { + if(x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m); + else return x; +} +function cRevert(x) { return x; } +function cReduce(x) { x.divRemTo(this.m,null,x); } +function cMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } +function cSqrTo(x,r) { x.squareTo(r); this.reduce(r); } + +Classic.prototype.convert = cConvert; +Classic.prototype.revert = cRevert; +Classic.prototype.reduce = cReduce; +Classic.prototype.mulTo = cMulTo; +Classic.prototype.sqrTo = cSqrTo; + +// (protected) return "-1/this % 2^DB"; useful for Mont. reduction +// justification: +// xy == 1 (mod m) +// xy = 1+km +// xy(2-xy) = (1+km)(1-km) +// x[y(2-xy)] = 1-k^2m^2 +// x[y(2-xy)] == 1 (mod m^2) +// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2 +// should reduce x and y(2-xy) by m^2 at each step to keep size bounded. +// JS multiply "overflows" differently from C/C++, so care is needed here. +function bnpInvDigit() { + if(this.t < 1) return 0; + var x = this[0]; + if((x&1) == 0) return 0; + var y = x&3; // y == 1/x mod 2^2 + y = (y*(2-(x&0xf)*y))&0xf; // y == 1/x mod 2^4 + y = (y*(2-(x&0xff)*y))&0xff; // y == 1/x mod 2^8 + y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff; // y == 1/x mod 2^16 + // last step - calculate inverse mod DV directly; + // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints + y = (y*(2-x*y%this.DV))%this.DV; // y == 1/x mod 2^dbits + // we really want the negative inverse, and -DV < y < DV + return (y>0)?this.DV-y:-y; +} + +// Montgomery reduction +function Montgomery(m) { + this.m = m; + this.mp = m.invDigit(); + this.mpl = this.mp&0x7fff; + this.mph = this.mp>>15; + this.um = (1<<(m.DB-15))-1; + this.mt2 = 2*m.t; +} + +// xR mod m +function montConvert(x) { + var r = nbi(); + x.abs().dlShiftTo(this.m.t,r); + r.divRemTo(this.m,null,r); + if(x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r,r); + return r; +} + +// x/R mod m +function montRevert(x) { + var r = nbi(); + x.copyTo(r); + this.reduce(r); + return r; +} + +// x = x/R mod m (HAC 14.32) +function montReduce(x) { + while(x.t <= this.mt2) // pad x so am has enough room later + x[x.t++] = 0; + for(var i = 0; i < this.m.t; ++i) { + // faster way of calculating u0 = x[i]*mp mod DV + var j = x[i]&0x7fff; + var u0 = (j*this.mpl+(((j*this.mph+(x[i]>>15)*this.mpl)&this.um)<<15))&x.DM; + // use am to combine the multiply-shift-add into one call + j = i+this.m.t; + x[j] += this.m.am(0,u0,x,i,0,this.m.t); + // propagate carry + while(x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; } + } + x.clamp(); + x.drShiftTo(this.m.t,x); + if(x.compareTo(this.m) >= 0) x.subTo(this.m,x); +} + +// r = "x^2/R mod m"; x != r +function montSqrTo(x,r) { x.squareTo(r); this.reduce(r); } + +// r = "xy/R mod m"; x,y != r +function montMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } + +Montgomery.prototype.convert = montConvert; +Montgomery.prototype.revert = montRevert; +Montgomery.prototype.reduce = montReduce; +Montgomery.prototype.mulTo = montMulTo; +Montgomery.prototype.sqrTo = montSqrTo; + +// (protected) true iff this is even +function bnpIsEven() { return ((this.t>0)?(this[0]&1):this.s) == 0; } + +// (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79) +function bnpExp(e,z) { + if(e > 0xffffffff || e < 1) return BigInteger.ONE; + var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e)-1; + g.copyTo(r); + while(--i >= 0) { + z.sqrTo(r,r2); + if((e&(1< 0) z.mulTo(r2,g,r); + else { var t = r; r = r2; r2 = t; } + } + return z.revert(r); +} + +// (public) this^e % m, 0 <= e < 2^32 +function bnModPowInt(e,m) { + var z; + if(e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m); + return this.exp(e,z); +} + +// protected +BigInteger.prototype.copyTo = bnpCopyTo; +BigInteger.prototype.fromInt = bnpFromInt; +BigInteger.prototype.fromString = bnpFromString; +BigInteger.prototype.clamp = bnpClamp; +BigInteger.prototype.dlShiftTo = bnpDLShiftTo; +BigInteger.prototype.drShiftTo = bnpDRShiftTo; +BigInteger.prototype.lShiftTo = bnpLShiftTo; +BigInteger.prototype.rShiftTo = bnpRShiftTo; +BigInteger.prototype.subTo = bnpSubTo; +BigInteger.prototype.multiplyTo = bnpMultiplyTo; +BigInteger.prototype.squareTo = bnpSquareTo; +BigInteger.prototype.divRemTo = bnpDivRemTo; +BigInteger.prototype.invDigit = bnpInvDigit; +BigInteger.prototype.isEven = bnpIsEven; +BigInteger.prototype.exp = bnpExp; + +// public +BigInteger.prototype.toString = bnToString; +BigInteger.prototype.negate = bnNegate; +BigInteger.prototype.abs = bnAbs; +BigInteger.prototype.compareTo = bnCompareTo; +BigInteger.prototype.bitLength = bnBitLength; +BigInteger.prototype.mod = bnMod; +BigInteger.prototype.modPowInt = bnModPowInt; + +// "constants" +BigInteger.ZERO = nbv(0); +BigInteger.ONE = nbv(1); + +function bnClone() { var r = nbi(); this.copyTo(r); return r; } + +// (public) return value as integer +function bnIntValue() { + if(this.s < 0) { + if(this.t == 1) return this[0]-this.DV; + else if(this.t == 0) return -1; + } + else if(this.t == 1) return this[0]; + else if(this.t == 0) return 0; + // assumes 16 < DB < 32 + return ((this[1]&((1<<(32-this.DB))-1))<>24; } + +// (public) return value as short (assumes DB>=16) +function bnShortValue() { return (this.t==0)?this.s:(this[0]<<16)>>16; } + +// (protected) return x s.t. r^x < DV +function bnpChunkSize(r) { return Math.floor(Math.LN2*this.DB/Math.log(r)); } + +// (public) 0 if this == 0, 1 if this > 0 +function bnSigNum() { + if(this.s < 0) return -1; + else if(this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0; + else return 1; +} + +// (protected) convert to radix string +function bnpToRadix(b) { + if(b == null) b = 10; + if(this.signum() == 0 || b < 2 || b > 36) return "0"; + var cs = this.chunkSize(b); + var a = Math.pow(b,cs); + var d = nbv(a), y = nbi(), z = nbi(), r = ""; + this.divRemTo(d,y,z); + while(y.signum() > 0) { + r = (a+z.intValue()).toString(b).substr(1) + r; + y.divRemTo(d,y,z); + } + return z.intValue().toString(b) + r; +} + +// (protected) convert from radix string +function bnpFromRadix(s,b) { + this.fromInt(0); + if(b == null) b = 10; + var cs = this.chunkSize(b); + var d = Math.pow(b,cs), mi = false, j = 0, w = 0; + for(var i = 0; i < s.length; ++i) { + var x = intAt(s,i); + if(x < 0) { + if(s.charAt(i) == "-" && this.signum() == 0) mi = true; + continue; + } + w = b*w+x; + if(++j >= cs) { + this.dMultiply(d); + this.dAddOffset(w,0); + j = 0; + w = 0; + } + } + if(j > 0) { + this.dMultiply(Math.pow(b,j)); + this.dAddOffset(w,0); + } + if(mi) BigInteger.ZERO.subTo(this,this); +} + +// (protected) alternate constructor +function bnpFromNumber(a,b,c) { + if("number" == typeof b) { + // new BigInteger(int,int,RNG) + if(a < 2) this.fromInt(1); + else { + this.fromNumber(a,c); + if(!this.testBit(a-1)) // force MSB set + this.bitwiseTo(BigInteger.ONE.shiftLeft(a-1),op_or,this); + if(this.isEven()) this.dAddOffset(1,0); // force odd + while(!this.isProbablePrime(b)) { + this.dAddOffset(2,0); + if(this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a-1),this); + } + } + } + else { + // new BigInteger(int,RNG) + var x = new Array(), t = a&7; + x.length = (a>>3)+1; + b.nextBytes(x); + if(t > 0) x[0] &= ((1< 0) { + if(p < this.DB && (d = this[i]>>p) != (this.s&this.DM)>>p) + r[k++] = d|(this.s<<(this.DB-p)); + while(i >= 0) { + if(p < 8) { + d = (this[i]&((1<>(p+=this.DB-8); + } + else { + d = (this[i]>>(p-=8))&0xff; + if(p <= 0) { p += this.DB; --i; } + } + if((d&0x80) != 0) d |= -256; + if(k == 0 && (this.s&0x80) != (d&0x80)) ++k; + if(k > 0 || d != this.s) r[k++] = d; + } + } + return r; +} + +function bnEquals(a) { return(this.compareTo(a)==0); } +function bnMin(a) { return(this.compareTo(a)<0)?this:a; } +function bnMax(a) { return(this.compareTo(a)>0)?this:a; } + +// (protected) r = this op a (bitwise) +function bnpBitwiseTo(a,op,r) { + var i, f, m = Math.min(a.t,this.t); + for(i = 0; i < m; ++i) r[i] = op(this[i],a[i]); + if(a.t < this.t) { + f = a.s&this.DM; + for(i = m; i < this.t; ++i) r[i] = op(this[i],f); + r.t = this.t; + } + else { + f = this.s&this.DM; + for(i = m; i < a.t; ++i) r[i] = op(f,a[i]); + r.t = a.t; + } + r.s = op(this.s,a.s); + r.clamp(); +} + +// (public) this & a +function op_and(x,y) { return x&y; } +function bnAnd(a) { var r = nbi(); this.bitwiseTo(a,op_and,r); return r; } + +// (public) this | a +function op_or(x,y) { return x|y; } +function bnOr(a) { var r = nbi(); this.bitwiseTo(a,op_or,r); return r; } + +// (public) this ^ a +function op_xor(x,y) { return x^y; } +function bnXor(a) { var r = nbi(); this.bitwiseTo(a,op_xor,r); return r; } + +// (public) this & ~a +function op_andnot(x,y) { return x&~y; } +function bnAndNot(a) { var r = nbi(); this.bitwiseTo(a,op_andnot,r); return r; } + +// (public) ~this +function bnNot() { + var r = nbi(); + for(var i = 0; i < this.t; ++i) r[i] = this.DM&~this[i]; + r.t = this.t; + r.s = ~this.s; + return r; +} + +// (public) this << n +function bnShiftLeft(n) { + var r = nbi(); + if(n < 0) this.rShiftTo(-n,r); else this.lShiftTo(n,r); + return r; +} + +// (public) this >> n +function bnShiftRight(n) { + var r = nbi(); + if(n < 0) this.lShiftTo(-n,r); else this.rShiftTo(n,r); + return r; +} + +// return index of lowest 1-bit in x, x < 2^31 +function lbit(x) { + if(x == 0) return -1; + var r = 0; + if((x&0xffff) == 0) { x >>= 16; r += 16; } + if((x&0xff) == 0) { x >>= 8; r += 8; } + if((x&0xf) == 0) { x >>= 4; r += 4; } + if((x&3) == 0) { x >>= 2; r += 2; } + if((x&1) == 0) ++r; + return r; +} + +// (public) returns index of lowest 1-bit (or -1 if none) +function bnGetLowestSetBit() { + for(var i = 0; i < this.t; ++i) + if(this[i] != 0) return i*this.DB+lbit(this[i]); + if(this.s < 0) return this.t*this.DB; + return -1; +} + +// return number of 1 bits in x +function cbit(x) { + var r = 0; + while(x != 0) { x &= x-1; ++r; } + return r; +} + +// (public) return number of set bits +function bnBitCount() { + var r = 0, x = this.s&this.DM; + for(var i = 0; i < this.t; ++i) r += cbit(this[i]^x); + return r; +} + +// (public) true iff nth bit is set +function bnTestBit(n) { + var j = Math.floor(n/this.DB); + if(j >= this.t) return(this.s!=0); + return((this[j]&(1<<(n%this.DB)))!=0); +} + +// (protected) this op (1<>= this.DB; + } + if(a.t < this.t) { + c += a.s; + while(i < this.t) { + c += this[i]; + r[i++] = c&this.DM; + c >>= this.DB; + } + c += this.s; + } + else { + c += this.s; + while(i < a.t) { + c += a[i]; + r[i++] = c&this.DM; + c >>= this.DB; + } + c += a.s; + } + r.s = (c<0)?-1:0; + if(c > 0) r[i++] = c; + else if(c < -1) r[i++] = this.DV+c; + r.t = i; + r.clamp(); +} + +// (public) this + a +function bnAdd(a) { var r = nbi(); this.addTo(a,r); return r; } + +// (public) this - a +function bnSubtract(a) { var r = nbi(); this.subTo(a,r); return r; } + +// (public) this * a +function bnMultiply(a) { var r = nbi(); this.multiplyTo(a,r); return r; } + +// (public) this^2 +function bnSquare() { var r = nbi(); this.squareTo(r); return r; } + +// (public) this / a +function bnDivide(a) { var r = nbi(); this.divRemTo(a,r,null); return r; } + +// (public) this % a +function bnRemainder(a) { var r = nbi(); this.divRemTo(a,null,r); return r; } + +// (public) [this/a,this%a] +function bnDivideAndRemainder(a) { + var q = nbi(), r = nbi(); + this.divRemTo(a,q,r); + return new Array(q,r); +} + +// (protected) this *= n, this >= 0, 1 < n < DV +function bnpDMultiply(n) { + this[this.t] = this.am(0,n-1,this,0,0,this.t); + ++this.t; + this.clamp(); +} + +// (protected) this += n << w words, this >= 0 +function bnpDAddOffset(n,w) { + if(n == 0) return; + while(this.t <= w) this[this.t++] = 0; + this[w] += n; + while(this[w] >= this.DV) { + this[w] -= this.DV; + if(++w >= this.t) this[this.t++] = 0; + ++this[w]; + } +} + +// A "null" reducer +function NullExp() {} +function nNop(x) { return x; } +function nMulTo(x,y,r) { x.multiplyTo(y,r); } +function nSqrTo(x,r) { x.squareTo(r); } + +NullExp.prototype.convert = nNop; +NullExp.prototype.revert = nNop; +NullExp.prototype.mulTo = nMulTo; +NullExp.prototype.sqrTo = nSqrTo; + +// (public) this^e +function bnPow(e) { return this.exp(e,new NullExp()); } + +// (protected) r = lower n words of "this * a", a.t <= n +// "this" should be the larger one if appropriate. +function bnpMultiplyLowerTo(a,n,r) { + var i = Math.min(this.t+a.t,n); + r.s = 0; // assumes a,this >= 0 + r.t = i; + while(i > 0) r[--i] = 0; + var j; + for(j = r.t-this.t; i < j; ++i) r[i+this.t] = this.am(0,a[i],r,i,0,this.t); + for(j = Math.min(a.t,n); i < j; ++i) this.am(0,a[i],r,i,0,n-i); + r.clamp(); +} + +// (protected) r = "this * a" without lower n words, n > 0 +// "this" should be the larger one if appropriate. +function bnpMultiplyUpperTo(a,n,r) { + --n; + var i = r.t = this.t+a.t-n; + r.s = 0; // assumes a,this >= 0 + while(--i >= 0) r[i] = 0; + for(i = Math.max(n-this.t,0); i < a.t; ++i) + r[this.t+i-n] = this.am(n-i,a[i],r,0,0,this.t+i-n); + r.clamp(); + r.drShiftTo(1,r); +} + +// Barrett modular reduction +function Barrett(m) { + // setup Barrett + this.r2 = nbi(); + this.q3 = nbi(); + BigInteger.ONE.dlShiftTo(2*m.t,this.r2); + this.mu = this.r2.divide(m); + this.m = m; +} + +function barrettConvert(x) { + if(x.s < 0 || x.t > 2*this.m.t) return x.mod(this.m); + else if(x.compareTo(this.m) < 0) return x; + else { var r = nbi(); x.copyTo(r); this.reduce(r); return r; } +} + +function barrettRevert(x) { return x; } + +// x = x mod m (HAC 14.42) +function barrettReduce(x) { + x.drShiftTo(this.m.t-1,this.r2); + if(x.t > this.m.t+1) { x.t = this.m.t+1; x.clamp(); } + this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3); + this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2); + while(x.compareTo(this.r2) < 0) x.dAddOffset(1,this.m.t+1); + x.subTo(this.r2,x); + while(x.compareTo(this.m) >= 0) x.subTo(this.m,x); +} + +// r = x^2 mod m; x != r +function barrettSqrTo(x,r) { x.squareTo(r); this.reduce(r); } + +// r = x*y mod m; x,y != r +function barrettMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } + +Barrett.prototype.convert = barrettConvert; +Barrett.prototype.revert = barrettRevert; +Barrett.prototype.reduce = barrettReduce; +Barrett.prototype.mulTo = barrettMulTo; +Barrett.prototype.sqrTo = barrettSqrTo; + +// (public) this^e % m (HAC 14.85) +function bnModPow(e,m) { + var i = e.bitLength(), k, r = nbv(1), z; + if(i <= 0) return r; + else if(i < 18) k = 1; + else if(i < 48) k = 3; + else if(i < 144) k = 4; + else if(i < 768) k = 5; + else k = 6; + if(i < 8) + z = new Classic(m); + else if(m.isEven()) + z = new Barrett(m); + else + z = new Montgomery(m); + + // precomputation + var g = new Array(), n = 3, k1 = k-1, km = (1< 1) { + var g2 = nbi(); + z.sqrTo(g[1],g2); + while(n <= km) { + g[n] = nbi(); + z.mulTo(g2,g[n-2],g[n]); + n += 2; + } + } + + var j = e.t-1, w, is1 = true, r2 = nbi(), t; + i = nbits(e[j])-1; + while(j >= 0) { + if(i >= k1) w = (e[j]>>(i-k1))&km; + else { + w = (e[j]&((1<<(i+1))-1))<<(k1-i); + if(j > 0) w |= e[j-1]>>(this.DB+i-k1); + } + + n = k; + while((w&1) == 0) { w >>= 1; --n; } + if((i -= n) < 0) { i += this.DB; --j; } + if(is1) { // ret == 1, don't bother squaring or multiplying it + g[w].copyTo(r); + is1 = false; + } + else { + while(n > 1) { z.sqrTo(r,r2); z.sqrTo(r2,r); n -= 2; } + if(n > 0) z.sqrTo(r,r2); else { t = r; r = r2; r2 = t; } + z.mulTo(r2,g[w],r); + } + + while(j >= 0 && (e[j]&(1< 0) { + x.rShiftTo(g,x); + y.rShiftTo(g,y); + } + while(x.signum() > 0) { + if((i = x.getLowestSetBit()) > 0) x.rShiftTo(i,x); + if((i = y.getLowestSetBit()) > 0) y.rShiftTo(i,y); + if(x.compareTo(y) >= 0) { + x.subTo(y,x); + x.rShiftTo(1,x); + } + else { + y.subTo(x,y); + y.rShiftTo(1,y); + } + } + if(g > 0) y.lShiftTo(g,y); + return y; +} + +// (protected) this % n, n < 2^26 +function bnpModInt(n) { + if(n <= 0) return 0; + var d = this.DV%n, r = (this.s<0)?n-1:0; + if(this.t > 0) + if(d == 0) r = this[0]%n; + else for(var i = this.t-1; i >= 0; --i) r = (d*r+this[i])%n; + return r; +} + +// (public) 1/this % m (HAC 14.61) +function bnModInverse(m) { + var ac = m.isEven(); + if((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO; + var u = m.clone(), v = this.clone(); + var a = nbv(1), b = nbv(0), c = nbv(0), d = nbv(1); + while(u.signum() != 0) { + while(u.isEven()) { + u.rShiftTo(1,u); + if(ac) { + if(!a.isEven() || !b.isEven()) { a.addTo(this,a); b.subTo(m,b); } + a.rShiftTo(1,a); + } + else if(!b.isEven()) b.subTo(m,b); + b.rShiftTo(1,b); + } + while(v.isEven()) { + v.rShiftTo(1,v); + if(ac) { + if(!c.isEven() || !d.isEven()) { c.addTo(this,c); d.subTo(m,d); } + c.rShiftTo(1,c); + } + else if(!d.isEven()) d.subTo(m,d); + d.rShiftTo(1,d); + } + if(u.compareTo(v) >= 0) { + u.subTo(v,u); + if(ac) a.subTo(c,a); + b.subTo(d,b); + } + else { + v.subTo(u,v); + if(ac) c.subTo(a,c); + d.subTo(b,d); + } + } + if(v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO; + if(d.compareTo(m) >= 0) return d.subtract(m); + if(d.signum() < 0) d.addTo(m,d); else return d; + if(d.signum() < 0) return d.add(m); else return d; +} + +var lowprimes = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997]; +var lplim = (1<<26)/lowprimes[lowprimes.length-1]; + +// (public) test primality with certainty >= 1-.5^t +function bnIsProbablePrime(t) { + var i, x = this.abs(); + if(x.t == 1 && x[0] <= lowprimes[lowprimes.length-1]) { + for(i = 0; i < lowprimes.length; ++i) + if(x[0] == lowprimes[i]) return true; + return false; + } + if(x.isEven()) return false; + i = 1; + while(i < lowprimes.length) { + var m = lowprimes[i], j = i+1; + while(j < lowprimes.length && m < lplim) m *= lowprimes[j++]; + m = x.modInt(m); + while(i < j) if(m%lowprimes[i++] == 0) return false; + } + return x.millerRabin(t); +} + +// (protected) true if probably prime (HAC 4.24, Miller-Rabin) +function bnpMillerRabin(t) { + var n1 = this.subtract(BigInteger.ONE); + var k = n1.getLowestSetBit(); + if(k <= 0) return false; + var r = n1.shiftRight(k); + t = (t+1)>>1; + if(t > lowprimes.length) t = lowprimes.length; + var a = nbi(); + for(var i = 0; i < t; ++i) { + //Pick bases at random, instead of starting at 2 + a.fromInt(lowprimes[Math.floor(Math.random()*lowprimes.length)]); + var y = a.modPow(r,this); + if(y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) { + var j = 1; + while(j++ < k && y.compareTo(n1) != 0) { + y = y.modPowInt(2,this); + if(y.compareTo(BigInteger.ONE) == 0) return false; + } + if(y.compareTo(n1) != 0) return false; + } + } + return true; +} + +// protected +BigInteger.prototype.chunkSize = bnpChunkSize; +BigInteger.prototype.toRadix = bnpToRadix; +BigInteger.prototype.fromRadix = bnpFromRadix; +BigInteger.prototype.fromNumber = bnpFromNumber; +BigInteger.prototype.bitwiseTo = bnpBitwiseTo; +BigInteger.prototype.changeBit = bnpChangeBit; +BigInteger.prototype.addTo = bnpAddTo; +BigInteger.prototype.dMultiply = bnpDMultiply; +BigInteger.prototype.dAddOffset = bnpDAddOffset; +BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo; +BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo; +BigInteger.prototype.modInt = bnpModInt; +BigInteger.prototype.millerRabin = bnpMillerRabin; + +// public +BigInteger.prototype.clone = bnClone; +BigInteger.prototype.intValue = bnIntValue; +BigInteger.prototype.byteValue = bnByteValue; +BigInteger.prototype.shortValue = bnShortValue; +BigInteger.prototype.signum = bnSigNum; +BigInteger.prototype.toByteArray = bnToByteArray; +BigInteger.prototype.equals = bnEquals; +BigInteger.prototype.min = bnMin; +BigInteger.prototype.max = bnMax; +BigInteger.prototype.and = bnAnd; +BigInteger.prototype.or = bnOr; +BigInteger.prototype.xor = bnXor; +BigInteger.prototype.andNot = bnAndNot; +BigInteger.prototype.not = bnNot; +BigInteger.prototype.shiftLeft = bnShiftLeft; +BigInteger.prototype.shiftRight = bnShiftRight; +BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit; +BigInteger.prototype.bitCount = bnBitCount; +BigInteger.prototype.testBit = bnTestBit; +BigInteger.prototype.setBit = bnSetBit; +BigInteger.prototype.clearBit = bnClearBit; +BigInteger.prototype.flipBit = bnFlipBit; +BigInteger.prototype.add = bnAdd; +BigInteger.prototype.subtract = bnSubtract; +BigInteger.prototype.multiply = bnMultiply; +BigInteger.prototype.divide = bnDivide; +BigInteger.prototype.remainder = bnRemainder; +BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder; +BigInteger.prototype.modPow = bnModPow; +BigInteger.prototype.modInverse = bnModInverse; +BigInteger.prototype.pow = bnPow; +BigInteger.prototype.gcd = bnGCD; +BigInteger.prototype.isProbablePrime = bnIsProbablePrime; + +// JSBN-specific extension +BigInteger.prototype.square = bnSquare; + +// BigInteger interfaces not implemented in jsbn: + +// BigInteger(int signum, byte[] magnitude) +// double doubleValue() +// float floatValue() +// int hashCode() +// long longValue() +// static BigInteger valueOf(long val) diff --git a/tool/java/Pailler/paillier/paillierKey.js b/tool/java/Pailler/paillier/paillierKey.js new file mode 100644 index 0000000000..dc4f846182 --- /dev/null +++ b/tool/java/Pailler/paillier/paillierKey.js @@ -0,0 +1,408 @@ + +// convert a (hex) string to a bignum object +function parseBigInt(str,r) { + return new BigInteger(str,r); +} + +function _pem_extractEncodedData(sPEMString, sHead) { + var s = sPEMString; + s = s.replace("-----BEGIN " + sHead + "-----", ""); + s = s.replace("-----END " + sHead + "-----", ""); + s = s.replace(/[ \n]+/g, ""); + return s; +} + +function _pem_getPosArrayOfChildrenFromHex(hPrivateKey) { + var a = new Array(); + var v1 = _asnhex_getStartPosOfV_AtObj(hPrivateKey, 0); + var n1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, v1); + var e1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, n1); + var d1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, e1); + var p1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, d1); + var q1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, p1); + var dp1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, q1); + var dq1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, dp1); + var co1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, dq1); + a.push(v1, n1, e1, d1, p1, q1, dp1, dq1, co1); + return a; +} + +function _pem_getHexValueArrayOfChildrenFromHex(hPrivateKey) { + var posArray = _pem_getPosArrayOfChildrenFromHex(hPrivateKey); + var v = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[0]); + var n = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[1]); + var e = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[2]); + var d = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[3]); + var p = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[4]); + var q = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[5]); + var dp = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[6]); + var dq = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[7]); + var co = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[8]); + var a = new Array(); + a.push(v, n, e, d, p, q, dp, dq, co); + return a; +} + +function _pem_getPosArrayOfChildrenFromPublicKeyHex(hPrivateKey) { + var a = new Array(); + var header = _asnhex_getStartPosOfV_AtObj(hPrivateKey, 0); + var keys = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, header); + a.push(header, keys); + return a; +} + +function _pem_getPosArrayOfChildrenFromPrivateKeyHex(hPrivateKey) { + var a = new Array(); + var integer = _asnhex_getStartPosOfV_AtObj(hPrivateKey, 0); + var header = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, integer); + var keys = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, header); + a.push(integer, header, keys); + return a; +} + +function _pem_getHexValueArrayOfChildrenFromPublicKeyHex(hPrivateKey) { + var posArray = _pem_getPosArrayOfChildrenFromPublicKeyHex(hPrivateKey); + var headerVal = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[0]); + var keysVal = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[1]); + + var keysSequence = keysVal.substring(2); + posArray = _pem_getPosArrayOfChildrenFromPublicKeyHex(keysSequence); + var modulus = _asnhex_getHexOfV_AtObj(keysSequence, posArray[0]); + var publicExp = _asnhex_getHexOfV_AtObj(keysSequence, posArray[1]); + + var a = new Array(); + a.push(modulus, publicExp); + return a; +} + + +function _pem_getHexValueArrayOfChildrenFromPrivateKeyHex(hPrivateKey) { + var posArray = _pem_getPosArrayOfChildrenFromPrivateKeyHex(hPrivateKey); + var integerVal = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[0]); + var headerVal = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[1]); + var keysVal = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[2]); + + var keysSequence = keysVal.substring(2); + return _pem_getHexValueArrayOfChildrenFromHex(keysSequence); +} + +function _pem_readPrivateKeyFromPkcs1PemString(keyPEM) { + var keyB64 = _pem_extractEncodedData(keyPEM); + var keyHex = b64tohex(keyB64) // depends base64.js + var a = _pem_getHexValueArrayOfChildrenFromHex(keyHex); + this.setPrivateEx(a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8]); +} + +function _pem_readPrivateKeyFromPkcs8PemString(keyPEM) { + var keyB64 = _pem_extractEncodedData(keyPEM); + var keyHex = b64tohex(keyB64) // depends base64.js + var a = _pem_getHexValueArrayOfChildrenFromPrivateKeyHex(keyHex); + this.setPrivateEx(a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8]); +} + +function _pem_readPublicKeyFromX509PemString(keyPEM) { + var keyB64 = _pem_extractEncodedData(keyPEM); + var keyHex = b64tohex(keyB64) // depends base64.js + var a = _pem_getHexValueArrayOfChildrenFromPublicKeyHex(keyHex); + this.setPublic(a[0],a[1]); +} + +/** +* Pad string with leading zeros, to use even number of bytes. +*/ +function _pem_padWithZero(numString) { + if (numString.length % 2 == 1) { + return "0" + numString; + } + return numString; +} + +/** +* Encode length in DER format (if length <0x80, then one byte, else first byte is 0x80 + length of length :) + n-bytes of length). +*/ +function _pem_encodeLength(length) { + if (length >= parseInt("80", 16)) { + var realLength = _pem_padWithZero(length.toString(16)); + var lengthOfLength = (realLength.length / 2); + return (parseInt("80", 16) + lengthOfLength).toString(16) + realLength; + } else { + return _pem_padWithZero(length.toString(16)); + } +} + +/** +* Encode number in DER encoding ("02" + length + number). +*/ +function _pem_derEncodeNumber(number) { + var numberString = _pem_padWithZero(number.toString(16)); + if (numberString[0] > '7') { + numberString = "00" + numberString; + } + var lenString = _pem_encodeLength(numberString.length / 2); + return "02" + lenString + numberString; +} + +/** +* Converts private & public part of given key to ASN1 Hex String. +*/ +function _pem_privateKeyToPkcs1HexString(paillierKey) { + var result = _pem_derEncodeNumber(0); + result += _pem_derEncodeNumber(paillierKey.n); + result += _pem_derEncodeNumber(paillierKey.e); + result += _pem_derEncodeNumber(paillierKey.d); + result += _pem_derEncodeNumber(paillierKey.p); + result += _pem_derEncodeNumber(paillierKey.q); + result += _pem_derEncodeNumber(paillierKey.dmp1); + result += _pem_derEncodeNumber(paillierKey.dmq1); + result += _pem_derEncodeNumber(paillierKey.coeff); + + var fullLen = _pem_encodeLength(result.length / 2); + return '30' + fullLen + result; +} + +/** +* Converts private & public part of given key to PKCS#8 Hex String. +*/ +function _pem_privateKeyToPkcs8HexString(paillierKey) { + var zeroInteger = "020100"; + var encodedIdentifier = "06092A864886F70D010101"; + var encodedNull = "0500"; + var headerSequence = "300D" + encodedIdentifier + encodedNull; + var keySequence = _pem_privateKeyToPkcs1HexString(paillierKey); + + var keyOctetString = "04" + _pem_encodeLength(keySequence.length / 2) + keySequence; + + var mainSequence = zeroInteger + headerSequence + keyOctetString; + return "30" + _pem_encodeLength(mainSequence.length / 2) + mainSequence; +} + +/** +* Converts public part of given key to ASN1 Hex String. +*/ +function _pem_publicKeyToX509HexString(paillierKey) { + var encodedIdentifier = "06092A864886F70D010101"; + var encodedNull = "0500"; + var headerSequence = "300D" + encodedIdentifier + encodedNull; + + var keys = _pem_derEncodeNumber(paillierKey.n); + keys += _pem_derEncodeNumber(paillierKey.g); + + var keySequence = "0030" + _pem_encodeLength(keys.length / 2) + keys; + var bitstring = "03" + _pem_encodeLength(keySequence.length / 2) + keySequence; + + var mainSequence = headerSequence + bitstring; + + return "30" + _pem_encodeLength(mainSequence.length / 2) + mainSequence; +} + +/** +* Output private & public part of the key in PKCS#1 PEM format. +*/ +function _pem_privateKeyToPkcs1PemString() { + var b64Cert = hex2b64(_pem_privateKeyToPkcs1HexString(this)); + var s = "-----BEGIN PRIVATE KEY-----\n"; + s = s + _paillier_splitKey(b64Cert, 64); + s = s + "\n-----END PRIVATE KEY-----"; + return s; +} + +/** +* Output private & public part of the key in PKCS#8 PEM format. +*/ +function _pem_privateKeyToPkcs8PemString() { + var b64Cert = hex2b64(_pem_privateKeyToPkcs8HexString(this)); + var s = "-----BEGIN PRIVATE KEY-----\n"; + s = s + _paillier_splitKey(b64Cert, 64); + s = s + "\n-----END PRIVATE KEY-----"; + return s; +} + +/** +* Output public part of the key in x509 PKCS#1 PEM format. +*/ +function _pem_publicKeyToX509PemString() { + var b64Cert = hex2b64(_pem_publicKeyToX509HexString(this)); + var s = "-----BEGIN PUBLIC KEY-----\n"; + s = s + _paillier_splitKey(b64Cert, 64); + s = s + "\n-----END PUBLIC KEY-----"; + return s; +} + +function _paillier_splitKey(key, line) { + var splitKey = ""; + for (var i = 0; i < key.length; i++) { + if (i % line == 0 && i != 0 && i != (key.length - 1)) { + splitKey += "\n"; + } + splitKey += key[i]; + } + + return splitKey; +} + +function _paillier_setPublic(N,G) { + if(N != null && G != null && N.length > 0 && G.length > 0) { + this.n = parseBigInt(N,16); + this.g = parseBigInt(G,16); + } + else + alert("Invalid Paillier public key"); +} + +// Set the private key fields N, e, and d from hex strings +function _paillier_setPrivate(N,E,D) { + if(N != null && E != null && N.length > 0 && E.length > 0) { + this.n = parseBigInt(N,16); + this.e = parseInt(E,16); + this.d = parseBigInt(D,16); + } + else + alert("Invalid Paillier private key"); +} + +// Set the private key fields N, e, d and CRT params from hex strings +function _paillier_setPrivateEx(N,E,D,P,Q,DP,DQ,C) { + if(N != null && E != null && N.length > 0 && E.length > 0) { + this.n = parseBigInt(N,16); + this.e = parseInt(E,16); + this.d = parseBigInt(D,16); + this.p = parseBigInt(P,16); + this.q = parseBigInt(Q,16); + this.dmp1 = parseBigInt(DP,16); + this.dmq1 = parseBigInt(DQ,16); + this.coeff = parseBigInt(C,16); + } + else + alert("Invalid Paillier private key"); +} + +function _paillier_genKeyPair(B) { + var rng = new SecureRandom(); + var qs = B>>1; + for(;;) { + for(;;) { + this.p = new BigInteger(B-qs,1,rng); + if(this.p.isProbablePrime(64)) break; + } + for(;;) { + this.q = new BigInteger(qs,1,rng); + if(this.q.isProbablePrime(64)) break; + } + var p1 = this.p.subtract(BigInteger.ONE); + var q1 = this.q.subtract(BigInteger.ONE); + this.n = this.p.multiply(this.q); + if(this.n.bitLength() != B) continue; + var nsquare = this.n.multiply(this.n); + this.d = this.p.subtract(BigInteger.ONE).multiply(this.q.subtract(BigInteger.ONE)); + this.g = this.n.add(BigInteger.ONE); + if (this.g.modPow(this.d, nsquare).subtract(BigInteger.ONE).divide(this.n).gcd(this.n).intValue() == 1) { + this.dmp1 = this.d.mod(p1); + this.dmq1 = this.d.mod(q1); + this.coeff = this.q.modInverse(this.p); + break; + } + } +} + +function _paillier_padHex(s, n) { + var slen = s.length; + if(slen < n) { + for(var i = 0; i < n - slen; i++) { + s = "0" + s; + } + } + return s; +} + +function _paillier_encrypt(m) { + var rng = new SeededRandom(); + var random = null; + for (;;) + { + for (;;) + { + random = new BigInteger(this.n.bitLength(), 1, rng); + if (random.isProbablePrime(64)) break; + } + if(random.signum() == 1) break; + } + + if(m.signum() == -1) { + m = m.mod(this.n); + } + + var nsquare = this.n.multiply(this.n); + var cipher = this.g.modPow(m, nsquare).multiply(random.modPow(this.n, nsquare)).mod(nsquare); + var nstr = this.n.toString(16); + var nlen = Math.ceil(this.n.bitLength() / 8); + return _paillier_padHex(nlen.toString(16), 4) + nstr + _paillier_padHex(cipher.toString(16), nlen * 4); +} + +function _paillier_decrypt(ciphertext) { + var nlen = parseInt("0x" + c1.substr(0,4)) * 2; + var nstr = ciphertext.substr(4, nlen); + var cstr = ciphertext.substr(nlen + 4); + var n1 = parseBigInt(nstr, 16); + var intCiphertext = parseBigInt(cstr, 16); + if(n1.compareTo(this.n) != 0) return null; + + var mu = this.d.modInverse(this.n); + var nsquare = this.n.multiply(this.n); + var message = intCiphertext.modPow(this.d, nsquare).subtract(BigInteger.ONE).divide(this.n).multiply(mu).mod(this.n); + var maxValue = BigInteger.ONE.shiftLeft(this.n.bitLength() / 2); + if(message.bitLength() > this.n.bitLength() / 2) { + return message.subtract(this.n); + } + else { + return message; + } +} + +function _paillier_add(c1, c2) { + var nlen1 = parseInt("0x" + c1.substr(0,4)) * 2; + var nstr1 = c1.substr(4, nlen1); + var cstr1 = c1.substr(nlen1 + 4); + var nlen2 = parseInt("0x" + c2.substr(0,4)) * 2; + var nstr2 = c2.substr(4, nlen2); + var cstr2 = c2.substr(nlen2 + 4); + var n1 = parseBigInt(nstr1, 16); + var n2 = parseBigInt(nstr2, 16); + + if(n2.compareTo(n1) != 0) { + return null; + } + + var ct1 = parseBigInt(cstr1, 16); + var ct2 = parseBigInt(cstr2, 16); + var nsquare = n1.multiply(n1); + var ct = ct1.multiply(ct2).mod(nsquare); + return _paillier_padHex(nlen1.toString(16), 4) + nstr1 + _paillier_padHex(ct.toString(16), nlen1 * 2); +} + +function PaillierKey() { + this.n = null; + this.e = 0; + this.g = null; + this.d = null; + this.p = null; + this.q = null; + this.dmp1 = null; + this.dmq1 = null; + this.coeff = null; + +} + +PaillierKey.prototype.readPublicKeyFromX509PEMString = _pem_readPublicKeyFromX509PemString; +PaillierKey.prototype.publicKeyToX509PemString = _pem_publicKeyToX509PemString; +PaillierKey.prototype.readPrivateKeyFromPkcs1PemString = _pem_readPrivateKeyFromPkcs1PemString; +PaillierKey.prototype.privateKeyToPkcs1PemString = _pem_privateKeyToPkcs1PemString; +PaillierKey.prototype.readPrivateKeyFromPkcs8PemString = _pem_readPrivateKeyFromPkcs8PemString; +PaillierKey.prototype.privateKeyToPkcs8PemString = _pem_privateKeyToPkcs8PemString; +PaillierKey.prototype.setPublic = _paillier_setPublic; +PaillierKey.prototype.setPrivate = _paillier_setPrivate; +PaillierKey.prototype.setPrivateEx = _paillier_setPrivateEx; +PaillierKey.prototype.genKeyPair = _paillier_genKeyPair; +PaillierKey.prototype.encrypt = _paillier_encrypt; +PaillierKey.prototype.decrypt = _paillier_decrypt; +PaillierKey.prototype.add = _paillier_add; + diff --git a/tool/java/Pailler/paillier/seedrandom.js b/tool/java/Pailler/paillier/seedrandom.js new file mode 100644 index 0000000000..7beacdb4c0 --- /dev/null +++ b/tool/java/Pailler/paillier/seedrandom.js @@ -0,0 +1,442 @@ +// seedrandom.js version 2.0. +// Author: David Bau 4/2/2011 +// +// Defines a method Math.seedrandom() that, when called, substitutes +// an explicitly seeded RC4-based algorithm for Math.random(). Also +// supports automatic seeding from local or network sources of entropy. +// +// Usage: +// +// +// +// Math.seedrandom('yipee'); Sets Math.random to a function that is +// initialized using the given explicit seed. +// +// Math.seedrandom(); Sets Math.random to a function that is +// seeded using the current time, dom state, +// and other accumulated local entropy. +// The generated seed string is returned. +// +// Math.seedrandom('yowza', true); +// Seeds using the given explicit seed mixed +// together with accumulated entropy. +// +// +// Seeds using physical random bits downloaded +// from random.org. +// +// Seeds using urandom bits from call.jsonlib.com, +// which is faster than random.org. +// +// Examples: +// +// Math.seedrandom("hello"); // Use "hello" as the seed. +// document.write(Math.random()); // Always 0.5463663768140734 +// document.write(Math.random()); // Always 0.43973793770592234 +// var rng1 = Math.random; // Remember the current prng. +// +// var autoseed = Math.seedrandom(); // New prng with an automatic seed. +// document.write(Math.random()); // Pretty much unpredictable. +// +// Math.random = rng1; // Continue "hello" prng sequence. +// document.write(Math.random()); // Always 0.554769432473455 +// +// Math.seedrandom(autoseed); // Restart at the previous seed. +// document.write(Math.random()); // Repeat the 'unpredictable' value. +// +// Notes: +// +// Each time seedrandom('arg') is called, entropy from the passed seed +// is accumulated in a pool to help generate future seeds for the +// zero-argument form of Math.seedrandom, so entropy can be injected over +// time by calling seedrandom with explicit data repeatedly. +// +// On speed - This javascript implementation of Math.random() is about +// 3-10x slower than the built-in Math.random() because it is not native +// code, but this is typically fast enough anyway. Seeding is more expensive, +// especially if you use auto-seeding. Some details (timings on Chrome 4): +// +// Our Math.random() - avg less than 0.002 milliseconds per call +// seedrandom('explicit') - avg less than 0.5 milliseconds per call +// seedrandom('explicit', true) - avg less than 2 milliseconds per call +// seedrandom() - avg about 38 milliseconds per call +// +// LICENSE (BSD): +// +// Copyright 2010 David Bau, all rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of this module nor the names of its contributors may +// be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/** + * All code is in an anonymous closure to keep the global namespace clean. + * + * @param {number=} overflow + * @param {number=} startdenom + */ +(function (pool, math, width, chunks, significance, overflow, startdenom) +{ + + + // + // seedrandom() + // This is the seedrandom function described above. + // + math['seedrandom'] = function seedrandom(seed, use_entropy) + { + var key = []; + var arc4; + + // Flatten the seed string or build one from local entropy if needed. + seed = mixkey(flatten( + use_entropy ? [seed, pool] : arguments.length ? seed : [new Date().getTime(), pool, window], 3), key); + + // Use the seed to initialize an ARC4 generator. + arc4 = new ARC4(key); + + // Mix the randomness into accumulated entropy. + mixkey(arc4.S, pool); + + // Override Math.random + // This function returns a random double in [0, 1) that contains + // randomness in every bit of the mantissa of the IEEE 754 value. + math['random'] = function random() + { // Closure to return a random double: + var n = arc4.g(chunks); // Start with a numerator n < 2 ^ 48 + var d = startdenom; // and denominator d = 2 ^ 48. + var x = 0; // and no 'extra last byte'. + while (n < significance) + { // Fill up all significant digits by + n = (n + x) * width; // shifting numerator and + d *= width; // denominator and generating a + x = arc4.g(1); // new least-significant-byte. + } + while (n >= overflow) + { // To avoid rounding up, before adding + n /= 2; // last byte, shift everything + d /= 2; // right using integer math until + x >>>= 1; // we have exactly the desired bits. + } + return (n + x) / d; // Form the number within [0, 1). + }; + + // Return the seed that was used + return seed; + }; + + // + // ARC4 + // + // An ARC4 implementation. The constructor takes a key in the form of + // an array of at most (width) integers that should be 0 <= x < (width). + // + // The g(count) method returns a pseudorandom integer that concatenates + // the next (count) outputs from ARC4. Its return value is a number x + // that is in the range 0 <= x < (width ^ count). + // + /** @constructor */ + + function ARC4(key) + { + var t, u, me = this, + keylen = key.length; + var i = 0, + j = me.i = me.j = me.m = 0; + me.S = []; + me.c = []; + + // The empty key [] is treated as [0]. + if (!keylen) + { + key = [keylen++]; + } + + // Set up S using the standard key scheduling algorithm. + while (i < width) + { + me.S[i] = i++; + } + for (i = 0; i < width; i++) + { + t = me.S[i]; + j = lowbits(j + t + key[i % keylen]); + u = me.S[j]; + me.S[i] = u; + me.S[j] = t; + } + + // The "g" method returns the next (count) outputs as one number. + me.g = function getnext(count) + { + var s = me.S; + var i = lowbits(me.i + 1); + var t = s[i]; + var j = lowbits(me.j + t); + var u = s[j]; + s[i] = u; + s[j] = t; + var r = s[lowbits(t + u)]; + while (--count) + { + i = lowbits(i + 1); + t = s[i]; + j = lowbits(j + t); + u = s[j]; + s[i] = u; + s[j] = t; + r = r * width + s[lowbits(t + u)]; + } + me.i = i; + me.j = j; + return r; + }; + // For robust unpredictability discard an initial batch of values. + // See http://www.rsa.com/rsalabs/node.asp?id=2009 + me.g(width); + } + + // + // flatten() + // Converts an object tree to nested arrays of strings. + // + /** @param {Object=} result + * @param {string=} prop + * @param {string=} typ */ + + function flatten(obj, depth, result, prop, typ) + { + result = []; + typ = typeof (obj); + if (depth && typ == 'object') + { + for (prop in obj) + { + if (prop.indexOf('S') < 5) + { // Avoid FF3 bug (local/sessionStorage) + try + { + result.push(flatten(obj[prop], depth - 1)); + } + catch (e) + {} + } + } + } + return (result.length ? result : obj + (typ != 'string' ? '\0' : '')); + } + + // + // mixkey() + // Mixes a string seed into a key that is an array of integers, and + // returns a shortened string seed that is equivalent to the result key. + // + /** @param {number=} smear + * @param {number=} j */ + + function mixkey(seed, key, smear, j) + { + seed += ''; // Ensure the seed is a string + smear = 0; + for (j = 0; j < seed.length; j++) + { + key[lowbits(j)] = lowbits((smear ^= key[lowbits(j)] * 19) + seed.charCodeAt(j)); + } + seed = ''; + for (j in key) + { + seed += String.fromCharCode(key[j]); + } + return seed; + } + + // + // lowbits() + // A quick "n mod width" for width a power of 2. + // + + + function lowbits(n) + { + return n & (width - 1); + } + + // + // The following constants are related to IEEE 754 limits. + // + startdenom = math.pow(width, chunks); + significance = math.pow(2, significance); + overflow = significance * 2; + + // + // When seedrandom.js is loaded, we immediately mix a few bits + // from the built-in RNG into the entropy pool. Because we do + // not want to intefere with determinstic PRNG state later, + // seedrandom will not call math.random on its own again after + // initialization. + // + mixkey(math.random(), pool); + + // End anonymous scope, and pass initial values. +})([], // pool: entropy pool starts empty +Math, // math: package containing random, pow, and seedrandom +256, // width: each RC4 output is 0 <= x < 256 +6, // chunks: at least six RC4 outputs for each double +52 // significance: there are 52 significant digits in a double +); + + +// This is not really a random number generator object, and two SeededRandom +// objects will conflict with one another, but it's good enough for generating +// the rsa key. +function SeededRandom(){} + +function SRnextBytes(ba) +{ + var i; + for(i = 0; i < ba.length; i++) + { + ba[i] = Math.floor(Math.random() * 256); + } +} + +SeededRandom.prototype.nextBytes = SRnextBytes; + +// prng4.js - uses Arcfour as a PRNG + +function Arcfour() { + this.i = 0; + this.j = 0; + this.S = new Array(); +} + +// Initialize arcfour context from key, an array of ints, each from [0..255] +function ARC4init(key) { + var i, j, t; + for(i = 0; i < 256; ++i) + this.S[i] = i; + j = 0; + for(i = 0; i < 256; ++i) { + j = (j + this.S[i] + key[i % key.length]) & 255; + t = this.S[i]; + this.S[i] = this.S[j]; + this.S[j] = t; + } + this.i = 0; + this.j = 0; +} + +function ARC4next() { + var t; + this.i = (this.i + 1) & 255; + this.j = (this.j + this.S[this.i]) & 255; + t = this.S[this.i]; + this.S[this.i] = this.S[this.j]; + this.S[this.j] = t; + return this.S[(t + this.S[this.i]) & 255]; +} + +Arcfour.prototype.init = ARC4init; +Arcfour.prototype.next = ARC4next; + +// Plug in your RNG constructor here +function prng_newstate() { + return new Arcfour(); +} + +// Pool size must be a multiple of 4 and greater than 32. +// An array of bytes the size of the pool will be passed to init() +var rng_psize = 256; + +// Random number generator - requires a PRNG backend, e.g. prng4.js + +// For best results, put code like +// +// in your main HTML document. + +var rng_state; +var rng_pool; +var rng_pptr; + +// Mix in a 32-bit integer into the pool +function rng_seed_int(x) { + rng_pool[rng_pptr++] ^= x & 255; + rng_pool[rng_pptr++] ^= (x >> 8) & 255; + rng_pool[rng_pptr++] ^= (x >> 16) & 255; + rng_pool[rng_pptr++] ^= (x >> 24) & 255; + if(rng_pptr >= rng_psize) rng_pptr -= rng_psize; +} + +// Mix in the current time (w/milliseconds) into the pool +function rng_seed_time() { + rng_seed_int(new Date().getTime()); +} + +// Initialize the pool with junk if needed. +if(rng_pool == null) { + rng_pool = new Array(); + rng_pptr = 0; + var t; + if(navigator.appName == "Netscape" && navigator.appVersion < "5" && window.crypto) { + // Extract entropy (256 bits) from NS4 RNG if available + var z = window.crypto.random(32); + for(t = 0; t < z.length; ++t) + rng_pool[rng_pptr++] = z.charCodeAt(t) & 255; + } + while(rng_pptr < rng_psize) { // extract some randomness from Math.random() + t = Math.floor(65536 * Math.random()); + rng_pool[rng_pptr++] = t >>> 8; + rng_pool[rng_pptr++] = t & 255; + } + rng_pptr = 0; + rng_seed_time(); + //rng_seed_int(window.screenX); + //rng_seed_int(window.screenY); +} + +function rng_get_byte() { + if(rng_state == null) { + rng_seed_time(); + rng_state = prng_newstate(); + rng_state.init(rng_pool); + for(rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr) + rng_pool[rng_pptr] = 0; + rng_pptr = 0; + //rng_pool = null; + } + // TODO: allow reseeding after first request + return rng_state.next(); +} + +function rng_get_bytes(ba) { + var i; + for(i = 0; i < ba.length; ++i) ba[i] = rng_get_byte(); +} + +function SecureRandom() {} + +SecureRandom.prototype.nextBytes = rng_get_bytes; + diff --git a/tool/java/Pailler/paillier/test.html b/tool/java/Pailler/paillier/test.html new file mode 100644 index 0000000000..be5d9aeed4 --- /dev/null +++ b/tool/java/Pailler/paillier/test.html @@ -0,0 +1,49 @@ + + + + + + + + + + + + + diff --git a/tool/java/Pailler/src/paillier/CommonUtils.java b/tool/java/Pailler/src/paillier/CommonUtils.java new file mode 100644 index 0000000000..c7a9218a35 --- /dev/null +++ b/tool/java/Pailler/src/paillier/CommonUtils.java @@ -0,0 +1,110 @@ +package paillier; + +import java.math.BigInteger; + +public class CommonUtils { + public CommonUtils() { + } + + public static byte[] intToByte4(int i) { + byte[] targets = new byte[4]; + targets[3] = (byte) (i & 0xFF); + targets[2] = (byte) (i >> 8 & 0xFF); + targets[1] = (byte) (i >> 16 & 0xFF); + targets[0] = (byte) (i >> 24 & 0xFF); + return targets; + } + + public static byte[] longToByte8(long lo) { + byte[] targets = new byte[8]; + for (int i = 0; i < 8; i++) { + int offset = (targets.length - 1 - i) * 8; + targets[i] = (byte) ((lo >>> offset) & 0xFF); + } + return targets; + } + + public static byte[] unsignedShortToByte2(int s) { + byte[] targets = new byte[2]; + targets[0] = (byte) (s >> 8 & 0xFF); + targets[1] = (byte) (s & 0xFF); + return targets; + } + + public static int byte2ToUnsignedShort(byte[] bytes) { + return byte2ToUnsignedShort(bytes, 0); + } + + public static int byte2ToUnsignedShort(byte[] bytes, int off) { + int high = bytes[off]; + int low = bytes[off + 1]; + return (high << 8 & 0xFF00) | (low & 0xFF); + } + + public static int byte4ToInt(byte[] bytes, int off) { + int b0 = bytes[off] & 0xFF; + int b1 = bytes[off + 1] & 0xFF; + int b2 = bytes[off + 2] & 0xFF; + int b3 = bytes[off + 3] & 0xFF; + return (b0 << 24) | (b1 << 16) | (b2 << 8) | b3; + } + + public static byte[] asUnsignedByteArray(BigInteger paramBigInteger) { + byte[] arrayOfByte1 = paramBigInteger.toByteArray(); + if (arrayOfByte1[0] == 0) { + byte[] arrayOfByte2 = new byte[arrayOfByte1.length - 1]; + System.arraycopy(arrayOfByte1, 1, arrayOfByte2, 0, arrayOfByte2.length); + return arrayOfByte2; + } + return arrayOfByte1; + } + + public static byte[] asUnsignedByteArray(BigInteger paramBigInteger, int byteLength) { + byte[] arrayOfByte1 = asUnsignedByteArray(paramBigInteger); + if(arrayOfByte1.length < byteLength) { + byte[] arrayOfByte2 = new byte[byteLength]; + int offset = byteLength - arrayOfByte1.length; + for(int i=0; i + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tool/java/web3j-v2.1.0_src/.project b/tool/java/web3j-v2.1.0_src/.project new file mode 100644 index 0000000000..76db9146a1 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/.project @@ -0,0 +1,17 @@ + + + web3j-v2.0.1_src + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/tool/java/web3j-v2.1.0_src/.settings/org.eclipse.core.resources.prefs b/tool/java/web3j-v2.1.0_src/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000000..4824b80263 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/tool/java/web3j-v2.1.0_src/.settings/org.eclipse.jdt.core.prefs b/tool/java/web3j-v2.1.0_src/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000000..bb35fa0a87 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,11 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/tool/java/web3j-v2.1.0_src/lib/asm-5.0.3.jar b/tool/java/web3j-v2.1.0_src/lib/asm-5.0.3.jar new file mode 100644 index 0000000000..573535b1d5 Binary files /dev/null and b/tool/java/web3j-v2.1.0_src/lib/asm-5.0.3.jar differ diff --git a/tool/java/web3j-v2.1.0_src/lib/asm-analysis-5.0.3.jar b/tool/java/web3j-v2.1.0_src/lib/asm-analysis-5.0.3.jar new file mode 100644 index 0000000000..8b73cf09d7 Binary files /dev/null and b/tool/java/web3j-v2.1.0_src/lib/asm-analysis-5.0.3.jar differ diff --git a/tool/java/web3j-v2.1.0_src/lib/asm-commons-5.0.3.jar b/tool/java/web3j-v2.1.0_src/lib/asm-commons-5.0.3.jar new file mode 100644 index 0000000000..514a6dc2e1 Binary files /dev/null and b/tool/java/web3j-v2.1.0_src/lib/asm-commons-5.0.3.jar differ diff --git a/tool/java/web3j-v2.1.0_src/lib/asm-tree-5.0.3.jar b/tool/java/web3j-v2.1.0_src/lib/asm-tree-5.0.3.jar new file mode 100644 index 0000000000..e7eae53576 Binary files /dev/null and b/tool/java/web3j-v2.1.0_src/lib/asm-tree-5.0.3.jar differ diff --git a/tool/java/web3j-v2.1.0_src/lib/asm-util-5.0.3.jar b/tool/java/web3j-v2.1.0_src/lib/asm-util-5.0.3.jar new file mode 100644 index 0000000000..e89f1b7b67 Binary files /dev/null and b/tool/java/web3j-v2.1.0_src/lib/asm-util-5.0.3.jar differ diff --git a/tool/java/web3j-v2.1.0_src/lib/bcprov-jdk15on-1.54.jar b/tool/java/web3j-v2.1.0_src/lib/bcprov-jdk15on-1.54.jar new file mode 100644 index 0000000000..bd95185ae8 Binary files /dev/null and b/tool/java/web3j-v2.1.0_src/lib/bcprov-jdk15on-1.54.jar differ diff --git a/tool/java/web3j-v2.1.0_src/lib/commons-codec-1.9.jar b/tool/java/web3j-v2.1.0_src/lib/commons-codec-1.9.jar new file mode 100644 index 0000000000..ef35f1c50d Binary files /dev/null and b/tool/java/web3j-v2.1.0_src/lib/commons-codec-1.9.jar differ diff --git a/tool/java/web3j-v2.1.0_src/lib/commons-logging-1.2.jar b/tool/java/web3j-v2.1.0_src/lib/commons-logging-1.2.jar new file mode 100644 index 0000000000..93a3b9f6db Binary files /dev/null and b/tool/java/web3j-v2.1.0_src/lib/commons-logging-1.2.jar differ diff --git a/tool/java/web3j-v2.1.0_src/lib/core-2.1.0.jar b/tool/java/web3j-v2.1.0_src/lib/core-2.1.0.jar new file mode 100644 index 0000000000..a2a6faba80 Binary files /dev/null and b/tool/java/web3j-v2.1.0_src/lib/core-2.1.0.jar differ diff --git a/tool/java/web3j-v2.1.0_src/lib/httpclient-4.5.2.jar b/tool/java/web3j-v2.1.0_src/lib/httpclient-4.5.2.jar new file mode 100644 index 0000000000..701609fcc8 Binary files /dev/null and b/tool/java/web3j-v2.1.0_src/lib/httpclient-4.5.2.jar differ diff --git a/tool/java/web3j-v2.1.0_src/lib/httpcore-4.4.4.jar b/tool/java/web3j-v2.1.0_src/lib/httpcore-4.4.4.jar new file mode 100644 index 0000000000..ac4a877302 Binary files /dev/null and b/tool/java/web3j-v2.1.0_src/lib/httpcore-4.4.4.jar differ diff --git a/tool/java/web3j-v2.1.0_src/lib/jackson-annotations-2.8.0.jar b/tool/java/web3j-v2.1.0_src/lib/jackson-annotations-2.8.0.jar new file mode 100644 index 0000000000..d19b67b0f1 Binary files /dev/null and b/tool/java/web3j-v2.1.0_src/lib/jackson-annotations-2.8.0.jar differ diff --git a/tool/java/web3j-v2.1.0_src/lib/jackson-core-2.8.5.jar b/tool/java/web3j-v2.1.0_src/lib/jackson-core-2.8.5.jar new file mode 100644 index 0000000000..05e1be2922 Binary files /dev/null and b/tool/java/web3j-v2.1.0_src/lib/jackson-core-2.8.5.jar differ diff --git a/tool/java/web3j-v2.1.0_src/lib/jackson-databind-2.8.5.jar b/tool/java/web3j-v2.1.0_src/lib/jackson-databind-2.8.5.jar new file mode 100644 index 0000000000..2794824673 Binary files /dev/null and b/tool/java/web3j-v2.1.0_src/lib/jackson-databind-2.8.5.jar differ diff --git a/tool/java/web3j-v2.1.0_src/lib/javapoet-1.7.0.jar b/tool/java/web3j-v2.1.0_src/lib/javapoet-1.7.0.jar new file mode 100644 index 0000000000..207af05755 Binary files /dev/null and b/tool/java/web3j-v2.1.0_src/lib/javapoet-1.7.0.jar differ diff --git a/tool/java/web3j-v2.1.0_src/lib/jffi-1.2.14-native.jar b/tool/java/web3j-v2.1.0_src/lib/jffi-1.2.14-native.jar new file mode 100644 index 0000000000..3ba318dc20 Binary files /dev/null and b/tool/java/web3j-v2.1.0_src/lib/jffi-1.2.14-native.jar differ diff --git a/tool/java/web3j-v2.1.0_src/lib/jffi-1.2.14.jar b/tool/java/web3j-v2.1.0_src/lib/jffi-1.2.14.jar new file mode 100644 index 0000000000..b912ebc22b Binary files /dev/null and b/tool/java/web3j-v2.1.0_src/lib/jffi-1.2.14.jar differ diff --git a/tool/java/web3j-v2.1.0_src/lib/jnr-constants-0.9.6.jar b/tool/java/web3j-v2.1.0_src/lib/jnr-constants-0.9.6.jar new file mode 100644 index 0000000000..751de97ae7 Binary files /dev/null and b/tool/java/web3j-v2.1.0_src/lib/jnr-constants-0.9.6.jar differ diff --git a/tool/java/web3j-v2.1.0_src/lib/jnr-enxio-0.14.jar b/tool/java/web3j-v2.1.0_src/lib/jnr-enxio-0.14.jar new file mode 100644 index 0000000000..95bc904056 Binary files /dev/null and b/tool/java/web3j-v2.1.0_src/lib/jnr-enxio-0.14.jar differ diff --git a/tool/java/web3j-v2.1.0_src/lib/jnr-ffi-2.1.2.jar b/tool/java/web3j-v2.1.0_src/lib/jnr-ffi-2.1.2.jar new file mode 100644 index 0000000000..576db97f6c Binary files /dev/null and b/tool/java/web3j-v2.1.0_src/lib/jnr-ffi-2.1.2.jar differ diff --git a/tool/java/web3j-v2.1.0_src/lib/jnr-posix-3.0.33.jar b/tool/java/web3j-v2.1.0_src/lib/jnr-posix-3.0.33.jar new file mode 100644 index 0000000000..50ca448984 Binary files /dev/null and b/tool/java/web3j-v2.1.0_src/lib/jnr-posix-3.0.33.jar differ diff --git a/tool/java/web3j-v2.1.0_src/lib/jnr-unixsocket-0.15.jar b/tool/java/web3j-v2.1.0_src/lib/jnr-unixsocket-0.15.jar new file mode 100644 index 0000000000..91eca2c10f Binary files /dev/null and b/tool/java/web3j-v2.1.0_src/lib/jnr-unixsocket-0.15.jar differ diff --git a/tool/java/web3j-v2.1.0_src/lib/jnr-x86asm-1.0.2.jar b/tool/java/web3j-v2.1.0_src/lib/jnr-x86asm-1.0.2.jar new file mode 100644 index 0000000000..dd4e695f3b Binary files /dev/null and b/tool/java/web3j-v2.1.0_src/lib/jnr-x86asm-1.0.2.jar differ diff --git a/tool/java/web3j-v2.1.0_src/lib/rxjava-1.2.4.jar b/tool/java/web3j-v2.1.0_src/lib/rxjava-1.2.4.jar new file mode 100644 index 0000000000..c8961dbf60 Binary files /dev/null and b/tool/java/web3j-v2.1.0_src/lib/rxjava-1.2.4.jar differ diff --git a/tool/java/web3j-v2.1.0_src/lib/scrypt-1.4.0.jar b/tool/java/web3j-v2.1.0_src/lib/scrypt-1.4.0.jar new file mode 100644 index 0000000000..7ebd8dee0d Binary files /dev/null and b/tool/java/web3j-v2.1.0_src/lib/scrypt-1.4.0.jar differ diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/EventEncoder.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/EventEncoder.java new file mode 100644 index 0000000000..508d6a3c81 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/EventEncoder.java @@ -0,0 +1,55 @@ +package org.web3j.abi; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +import org.web3j.abi.datatypes.Event; +import org.web3j.abi.datatypes.Type; +import org.web3j.crypto.Hash; +import org.web3j.utils.Numeric; + +/** + *

Ethereum filter encoding. + * Further limited details are available + * here. + *

+ */ +public class EventEncoder { + + private EventEncoder() { } + + public static String encode(Event function) { + List> indexedParameters = function.getIndexedParameters(); + List> nonIndexedParameters = function.getNonIndexedParameters(); + + String methodSignature = buildMethodSignature(function.getName(), + indexedParameters, nonIndexedParameters); + + return buildEventSignature(methodSignature); + } + + static String buildMethodSignature( + String methodName, List> indexParameters, + List> nonIndexedParameters) { + + List> parameters = new ArrayList<>(indexParameters); + parameters.addAll(nonIndexedParameters); + + StringBuilder result = new StringBuilder(); + result.append(methodName); + result.append("("); + String params = parameters.stream() + .map(p -> Utils.getTypeName(p)) + .collect(Collectors.joining(",")); + result.append(params); + result.append(")"); + return result.toString(); + } + + static String buildEventSignature(String methodSignature) { + byte[] input = methodSignature.getBytes(); + byte[] hash = Hash.sha3(input); + return Numeric.toHexString(hash); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/EventValues.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/EventValues.java new file mode 100644 index 0000000000..902f0c0a80 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/EventValues.java @@ -0,0 +1,26 @@ +package org.web3j.abi; + +import java.util.List; + +import org.web3j.abi.datatypes.Type; + +/** + * Persisted solidity event parameters + */ +public class EventValues { + private final List indexedValues; + private final List nonIndexedValues; + + public EventValues(List indexedValues, List nonIndexedValues) { + this.indexedValues = indexedValues; + this.nonIndexedValues = nonIndexedValues; + } + + public List getIndexedValues() { + return indexedValues; + } + + public List getNonIndexedValues() { + return nonIndexedValues; + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/FunctionEncoder.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/FunctionEncoder.java new file mode 100644 index 0000000000..b095e6255e --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/FunctionEncoder.java @@ -0,0 +1,91 @@ +package org.web3j.abi; + +import java.math.BigInteger; +import java.util.List; +import java.util.stream.Collectors; + +import org.web3j.abi.datatypes.Function; +import org.web3j.abi.datatypes.StaticArray; +import org.web3j.abi.datatypes.Type; +import org.web3j.abi.datatypes.Uint; +import org.web3j.crypto.Hash; +import org.web3j.utils.Numeric; + +/** + *

Ethereum Contract Application Binary Interface (ABI) encoding for functions. + * Further details are available + * here. + *

+ */ +public class FunctionEncoder { + + private FunctionEncoder() { } + + public static String encode(Function function) { + List parameters = function.getInputParameters(); + + String methodSignature = buildMethodSignature(function.getName(), parameters); + String methodId = buildMethodId(methodSignature); + + StringBuilder result = new StringBuilder(); + result.append(methodId); + + return encodeParameters(parameters, result); + } + + public static String encodeConstructor(List parameters) { + return encodeParameters(parameters, new StringBuilder()); + } + + private static String encodeParameters(List parameters, StringBuilder result) { + int dynamicDataOffset = getLength(parameters) * Type.MAX_BYTE_LENGTH; + StringBuilder dynamicData = new StringBuilder(); + + for (Type parameter:parameters) { + String encodedValue = TypeEncoder.encode(parameter); + + if (TypeEncoder.isDynamic(parameter)) { + String encodedDataOffset = TypeEncoder.encodeNumeric( + new Uint(BigInteger.valueOf(dynamicDataOffset))); + result.append(encodedDataOffset); + dynamicData.append(encodedValue); + dynamicDataOffset += encodedValue.length() >> 1; + } else { + result.append(encodedValue); + } + } + result.append(dynamicData); + + return result.toString(); + } + + private static int getLength(List parameters) { + int count = 0; + for (Type type:parameters) { + if (type instanceof StaticArray) { + count += ((StaticArray) type).getValue().size(); + } else { + count++; + } + } + return count; + } + + static String buildMethodSignature(String methodName, List parameters) { + StringBuilder result = new StringBuilder(); + result.append(methodName); + result.append("("); + String params = parameters.stream() + .map(Type::getTypeAsString) + .collect(Collectors.joining(",")); + result.append(params); + result.append(")"); + return result.toString(); + } + + static String buildMethodId(String methodSignature) { + byte[] input = methodSignature.getBytes(); + byte[] hash = Hash.sha3(input); + return Numeric.toHexString(hash).substring(0, 10); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/FunctionReturnDecoder.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/FunctionReturnDecoder.java new file mode 100644 index 0000000000..5945bef095 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/FunctionReturnDecoder.java @@ -0,0 +1,130 @@ +package org.web3j.abi; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.web3j.abi.datatypes.Array; +import org.web3j.abi.datatypes.BytesType; +import org.web3j.abi.datatypes.DynamicArray; +import org.web3j.abi.datatypes.DynamicBytes; +import org.web3j.abi.datatypes.StaticArray; +import org.web3j.abi.datatypes.Type; +import org.web3j.abi.datatypes.Utf8String; +import org.web3j.abi.datatypes.generated.Bytes32; +import org.web3j.utils.Numeric; + +import static org.web3j.abi.TypeDecoder.MAX_BYTE_LENGTH_FOR_HEX_STRING; + +/** + * Decodes values returned by function or event calls. + */ +public class FunctionReturnDecoder { + + private FunctionReturnDecoder() { } + + /** + * Decode ABI encoded return values from smart contract function call. + * + * @param rawInput ABI encoded input + * @param outputParameters list of return types as {@link TypeReference} + * @return {@link List} of values returned by function, {@link Collections#emptyList()} if + * invalid response + */ + public static List decode( + String rawInput, List> outputParameters) { + String input = Numeric.cleanHexPrefix(rawInput); + + if (input.isEmpty()) { + return Collections.emptyList(); + } else { + return build(input, outputParameters); + } + } + + /** + *

Decodes an indexed parameter associated with an event. Indexed parameters are individually + * encoded, unlike non-indexed parameters which are encoded as per ABI-encoded function + * parameters and return values.

+ * + *

If any of the following types are indexed, the Keccak-256 hashes of the values are returned + * instead. These are returned as a bytes32 value.

+ * + *
    + *
  • Arrays
  • + *
  • Strings
  • + *
  • Bytes
  • + *
+ * + *

See the + * + * Solidity documentation for further information.

+ * + * @param rawInput ABI encoded input + * @param typeReference of expected result type + * @param type of TypeReference + * @return the decode value + */ + public static Type decodeIndexedValue( + String rawInput, TypeReference typeReference) { + String input = Numeric.cleanHexPrefix(rawInput); + + try { + Class type = typeReference.getClassType(); + + if (Array.class.isAssignableFrom(type) || + BytesType.class.isAssignableFrom(type) || + Utf8String.class.isAssignableFrom(type)) { + return TypeDecoder.decodeBytes(input, Bytes32.class); + } else { + return TypeDecoder.decode(input, type); + } + } catch (ClassNotFoundException e) { + throw new UnsupportedOperationException("Invalid class reference provided", e); + } + } + + private static List build( + String input, List> outputParameters) { + List results = new ArrayList<>(outputParameters.size()); + + int offset = 0; + for (TypeReference typeReference:outputParameters) { + try { + Class type = (Class) typeReference.getClassType(); + + int hexStringDataOffset = getDataOffset(input, offset, type); + + Type result; + if (DynamicArray.class.isAssignableFrom(type)) { + result = TypeDecoder.decodeDynamicArray( + input, hexStringDataOffset, typeReference); + offset += MAX_BYTE_LENGTH_FOR_HEX_STRING; + } else if (StaticArray.class.isAssignableFrom(type)) { + int length = ((TypeReference.StaticArrayTypeReference) typeReference).getSize(); + result = TypeDecoder.decodeStaticArray( + input, hexStringDataOffset, typeReference, length); + offset += length * MAX_BYTE_LENGTH_FOR_HEX_STRING; + } else { + result = TypeDecoder.decode(input, hexStringDataOffset, type); + offset += MAX_BYTE_LENGTH_FOR_HEX_STRING; + } + results.add(result); + + } catch (ClassNotFoundException e) { + throw new UnsupportedOperationException("Invalid class reference provided", e); + } + } + return results; + } + + private static int getDataOffset(String input, int offset, Class type) { + if (DynamicBytes.class.isAssignableFrom(type) + || Utf8String.class.isAssignableFrom(type) + || DynamicArray.class.isAssignableFrom(type)) { + return TypeDecoder.decodeUintAsInt(input, offset) << 1; + } else { + return offset; + } + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/TypeDecoder.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/TypeDecoder.java new file mode 100644 index 0000000000..b768a4189f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/TypeDecoder.java @@ -0,0 +1,258 @@ +package org.web3j.abi; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.ParameterizedType; +import java.math.BigInteger; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import java.util.function.BiFunction; + +import org.web3j.abi.datatypes.Address; +import org.web3j.abi.datatypes.Array; +import org.web3j.abi.datatypes.Bool; +import org.web3j.abi.datatypes.Bytes; +import org.web3j.abi.datatypes.DynamicArray; +import org.web3j.abi.datatypes.DynamicBytes; +import org.web3j.abi.datatypes.Fixed; +import org.web3j.abi.datatypes.FixedPointType; +import org.web3j.abi.datatypes.Int; +import org.web3j.abi.datatypes.IntType; +import org.web3j.abi.datatypes.NumericType; +import org.web3j.abi.datatypes.StaticArray; +import org.web3j.abi.datatypes.Type; +import org.web3j.abi.datatypes.Ufixed; +import org.web3j.abi.datatypes.Uint; +import org.web3j.abi.datatypes.Utf8String; +import org.web3j.utils.Numeric; + +/** + *

Ethereum Contract Application Binary Interface (ABI) decoding for types. + * Decoding is not documented, but is the reverse of the encoding details located + * here. + *

+ */ +class TypeDecoder { + + static final int MAX_BYTE_LENGTH_FOR_HEX_STRING = Type.MAX_BYTE_LENGTH << 1; + + static int getSingleElementLength(String input, int offset, Class type) { + if (input.length() == offset) { + return 0; + } else if (DynamicBytes.class.isAssignableFrom(type) + || Utf8String.class.isAssignableFrom(type)) { + // length field + data value + return (decodeUintAsInt(input, offset) / Type.MAX_BYTE_LENGTH) + 2; + } else { + return 1; + } + } + + @SuppressWarnings("unchecked") + static T decode(String input, int offset, Class type) { + if (NumericType.class.isAssignableFrom(type)) { + return (T) decodeNumeric(input.substring(offset), (Class) type); + } else if (Bool.class.isAssignableFrom(type)) { + return (T) decodeBool(input, offset); + } else if (Bytes.class.isAssignableFrom(type)) { + return (T) decodeBytes(input, offset, (Class) type); + } else if (DynamicBytes.class.isAssignableFrom(type)) { + return (T) decodeDynamicBytes(input, offset); + } else if (Utf8String.class.isAssignableFrom(type)) { + return (T) decodeUtf8String(input, offset); + } else if (Array.class.isAssignableFrom(type)) { + throw new UnsupportedOperationException( + "Array types must be wrapped in a TypeReference"); + } else { + throw new UnsupportedOperationException( + "Type cannot be encoded: " + type.getClass()); + } + } + + public static T decode(String input, int offset, TypeReference typeReference) { + Class cls = ((ParameterizedType) typeReference.getType()).getRawType().getClass(); + if (StaticArray.class.isAssignableFrom(cls)) { + return decodeStaticArray(input, offset, typeReference, 1); + } else if (DynamicArray.class.isAssignableFrom(cls)) { + return decodeDynamicArray(input, offset, typeReference); + } else { + throw new UnsupportedOperationException("Unsupported TypeReference: " + + cls.getName() + ", only Array types can be passed as TypeReferences"); + } + } + + static T decode(String input, Class type) { + return decode(input, 0, type); + } + + static T decodeNumeric(String input, Class type) { + try { + byte[] inputByteArray = Numeric.hexStringToByteArray(input); + int typeLengthAsBytes = getTypeLengthInBytes(type); + + byte[] resultByteArray = new byte[typeLengthAsBytes + 1]; + + if (Int.class.isAssignableFrom(type) || Fixed.class.isAssignableFrom(type)) { + resultByteArray[0] = inputByteArray[0]; // take MSB as sign bit + } + + int valueOffset = Type.MAX_BYTE_LENGTH - typeLengthAsBytes; + System.arraycopy(inputByteArray, valueOffset, resultByteArray, 1, typeLengthAsBytes); + + BigInteger numericValue = new BigInteger(resultByteArray); + return type.getConstructor(BigInteger.class).newInstance(numericValue); + + } catch (NoSuchMethodException | SecurityException | + InstantiationException | IllegalAccessException | + IllegalArgumentException | InvocationTargetException e) { + throw new UnsupportedOperationException( + "Unable to create instance of " + type.getName(), e); + } + } + + static int getTypeLengthInBytes(Class type) { + return getTypeLength(type) >> 3; // divide by 8 + } + + static int getTypeLength(Class type) { + if (IntType.class.isAssignableFrom(type)) { + String regex = "(" + Uint.class.getSimpleName() + "|" + Int.class.getSimpleName() + ")"; + String[] splitName = type.getSimpleName().split(regex); + if (splitName.length == 2) { + return Integer.parseInt(splitName[1]); + } + } else if (FixedPointType.class.isAssignableFrom(type)) { + String regex = "(" + Ufixed.class.getSimpleName() + "|" + Fixed.class.getSimpleName() + ")"; + String[] splitName = type.getSimpleName().split(regex); + if (splitName.length == 2) { + String[] bitsCounts = splitName[1].split("x"); + return Integer.parseInt(bitsCounts[0]) + Integer.parseInt(bitsCounts[1]); + } + } else if (Address.class.isAssignableFrom(type)) { + return Address.LENGTH; + } + return Type.MAX_BIT_LENGTH; + } + + static int decodeUintAsInt(String rawInput, int offset) { + String input = rawInput.substring(offset, offset + MAX_BYTE_LENGTH_FOR_HEX_STRING); + return decode(input, 0, Uint.class).getValue().intValue(); + } + + static Bool decodeBool(String rawInput, int offset) { + String input = rawInput.substring(offset, offset + MAX_BYTE_LENGTH_FOR_HEX_STRING); + BigInteger numericValue = Numeric.toBigInt(input); + boolean value = numericValue.equals(BigInteger.ONE); + return new Bool(value); + } + + static T decodeBytes(String input, Class type) { + return decodeBytes(input, 0, type); + } + + static T decodeBytes(String input, int offset, Class type) { + try { + String simpleName = type.getSimpleName(); + String[] splitName = simpleName.split(Bytes.class.getSimpleName()); + int length = Integer.parseInt(splitName[1]); + int hexStringLength = length << 1; + + byte[] bytes = Numeric.hexStringToByteArray(input.substring(offset, offset+hexStringLength)); + return type.getConstructor(byte[].class).newInstance(bytes); + } catch (NoSuchMethodException | SecurityException | + InstantiationException | IllegalAccessException | + IllegalArgumentException | InvocationTargetException e) { + throw new UnsupportedOperationException( + "Unable to create instance of " + type.getName(), e); + } + } + + static DynamicBytes decodeDynamicBytes(String input, int offset) { + int encodedLength = decodeUintAsInt(input, offset); + int hexStringEncodedLength = encodedLength << 1; + + int valueOffset = offset + MAX_BYTE_LENGTH_FOR_HEX_STRING; + + String data = input.substring(valueOffset, + valueOffset + hexStringEncodedLength); + byte[] bytes = Numeric.hexStringToByteArray(data); + + return new DynamicBytes(bytes); + } + + static Utf8String decodeUtf8String(String input, int offset) { + DynamicBytes dynamicBytesResult = decodeDynamicBytes(input, offset); + byte[] bytes = dynamicBytesResult.getValue(); + + return new Utf8String(new String(bytes, StandardCharsets.UTF_8)); + } + + /** + * Static array length cannot be passed as a type. + */ + @SuppressWarnings("unchecked") + static T decodeStaticArray( + String input, int offset, TypeReference typeReference, int length) { + + BiFunction, String, T> function = (elements, typeName) -> { + if (elements.isEmpty()) { + throw new UnsupportedOperationException("Zero length fixed array is invalid type"); + } else { + return (T) new StaticArray<>(elements); + } + }; + + return decodeArrayElements(input, offset, typeReference, length, function); + } + + @SuppressWarnings("unchecked") + static T decodeDynamicArray( + String input, int offset, TypeReference typeReference) { + + int length = decodeUintAsInt(input, offset); + + BiFunction, String, T> function = (elements, typeName) -> { + if (elements.isEmpty()) { + return (T) DynamicArray.empty(typeName); + } else { + return (T) new DynamicArray<>(elements); + } + }; + + int valueOffset = offset + MAX_BYTE_LENGTH_FOR_HEX_STRING; + + return decodeArrayElements(input, valueOffset, typeReference, length, function); + } + + private static T decodeArrayElements( + String input, int offset, TypeReference typeReference, int length, + BiFunction, String, T> consumer) { + + try { + Class cls = Utils.getParameterizedTypeFromArray(typeReference); + if (Array.class.isAssignableFrom(cls)) { + throw new UnsupportedOperationException( + "Arrays of arrays are not currently supported for external functions, " + + "see http://solidity.readthedocs.io/en/develop/types.html#members"); + } else { + List elements = new ArrayList<>(length); + + for (int i = 0, currOffset = offset; + i < length; + i++, currOffset += getSingleElementLength(input, currOffset, cls) + * MAX_BYTE_LENGTH_FOR_HEX_STRING) { + T value = decode(input, currOffset, cls); + elements.add(value); + } + + String typeName = Utils.getSimpleTypeName(cls); + + return consumer.apply(elements, typeName); + } + } catch (ClassNotFoundException e) { + throw new UnsupportedOperationException( + "Unable to access parameterized type " + typeReference.getType().getTypeName(), + e); + } + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/TypeEncoder.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/TypeEncoder.java new file mode 100644 index 0000000000..2e21d5b1de --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/TypeEncoder.java @@ -0,0 +1,157 @@ +package org.web3j.abi; + +import java.math.BigInteger; +import java.nio.charset.StandardCharsets; + +import org.web3j.abi.datatypes.Array; +import org.web3j.abi.datatypes.Bool; +import org.web3j.abi.datatypes.Bytes; +import org.web3j.abi.datatypes.BytesType; +import org.web3j.abi.datatypes.DynamicArray; +import org.web3j.abi.datatypes.DynamicBytes; +import org.web3j.abi.datatypes.NumericType; +import org.web3j.abi.datatypes.StaticArray; +import org.web3j.abi.datatypes.Type; +import org.web3j.abi.datatypes.Ufixed; +import org.web3j.abi.datatypes.Uint; +import org.web3j.abi.datatypes.Utf8String; +import org.web3j.utils.Numeric; + +import static org.web3j.abi.datatypes.Type.MAX_BIT_LENGTH; +import static org.web3j.abi.datatypes.Type.MAX_BYTE_LENGTH; + +/** + *

Ethereum Contract Application Binary Interface (ABI) encoding for types. + * Further details are available + * here. + *

+ */ +public class TypeEncoder { + + private TypeEncoder() { } + + static boolean isDynamic(Type parameter) { + return parameter instanceof DynamicBytes || + parameter instanceof Utf8String || + parameter instanceof DynamicArray; + } + + static String encode(Type parameter) { + if (parameter instanceof NumericType) { + return encodeNumeric(((NumericType) parameter)); + } else if (parameter instanceof Bool) { + return encodeBool((Bool) parameter); + } else if (parameter instanceof Bytes) { + return encodeBytes((Bytes) parameter); + } else if (parameter instanceof DynamicBytes) { + return encodeDynamicBytes((DynamicBytes) parameter); + } else if (parameter instanceof Utf8String) { + return encodeString((Utf8String) parameter); + } else if (parameter instanceof StaticArray) { + return encodeArrayValues((StaticArray) parameter); + } else if (parameter instanceof DynamicArray) { + return encodeDynamicArray((DynamicArray) parameter); + } else { + throw new UnsupportedOperationException( + "Type cannot be encoded: " + parameter.getClass()); + } + } + + static String encodeNumeric(NumericType numericType) { + byte[] rawValue = toByteArray(numericType); + byte paddingValue = getPaddingValue(numericType); + byte[] paddedRawValue = new byte[MAX_BYTE_LENGTH]; + if (paddingValue != 0) { + for (int i = 0; i < paddedRawValue.length; i++) { + paddedRawValue[i] = paddingValue; + } + } + + System.arraycopy( + rawValue, 0, + paddedRawValue, MAX_BYTE_LENGTH - rawValue.length, + rawValue.length); + return Numeric.toHexStringNoPrefix(paddedRawValue); + } + + private static byte getPaddingValue(NumericType numericType) { + if (numericType.getValue().signum() == -1) { + return (byte) 0xff; + } else { + return 0; + } + } + + private static byte[] toByteArray(NumericType numericType) { + BigInteger value = numericType.getValue(); + if (numericType instanceof Ufixed || numericType instanceof Uint) { + if (value.bitCount() == MAX_BIT_LENGTH) { + // As BigInteger is signed, if we have a 256 bit value, the resultant byte array will + // contain a sign byte in it's MSB, which we should ignore for this unsigned integer type. + byte[] byteArray = new byte[MAX_BYTE_LENGTH]; + System.arraycopy(value.toByteArray(), 1, byteArray, 0, MAX_BYTE_LENGTH); + return byteArray; + } + } + return value.toByteArray(); + } + + static String encodeBool(Bool value) { + byte[] rawValue = new byte[MAX_BYTE_LENGTH]; + if (value.getValue()) { + rawValue[rawValue.length - 1] = 1; + } + return Numeric.toHexStringNoPrefix(rawValue); + } + + static String encodeBytes(BytesType bytesType) { + byte[] value = bytesType.getValue(); + int length = value.length; + int mod = length % MAX_BYTE_LENGTH; + + byte[] dest; + if (mod != 0) { + int padding = MAX_BYTE_LENGTH - mod; + dest = new byte[length + padding]; + System.arraycopy(value, 0, dest, 0, length); + } else { + dest = value; + } + return Numeric.toHexStringNoPrefix(dest); + } + + static String encodeDynamicBytes(DynamicBytes dynamicBytes) { + int size = dynamicBytes.getValue().length; + String encodedLength = encode(new Uint(BigInteger.valueOf(size))); + String encodedValue = encodeBytes(dynamicBytes); + + StringBuilder result = new StringBuilder(); + result.append(encodedLength); + result.append(encodedValue); + return result.toString(); + } + + static String encodeString(Utf8String string) { + byte[] utfEncoded = string.getValue().getBytes(StandardCharsets.UTF_8); + return encodeDynamicBytes(new DynamicBytes(utfEncoded)); + } + + static String encodeArrayValues(Array value) { + StringBuilder result = new StringBuilder(); + for (Type type:value.getValue()) { + result.append(TypeEncoder.encode(type)); + } + return result.toString(); + } + + static String encodeDynamicArray(DynamicArray value) { + int size = value.getValue().size(); + String encodedLength = encode(new Uint(BigInteger.valueOf(size))); + String encodedValues = encodeArrayValues(value); + + StringBuilder result = new StringBuilder(); + result.append(encodedLength); + result.append(encodedValues); + return result.toString(); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/TypeReference.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/TypeReference.java new file mode 100644 index 0000000000..22a28d8393 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/TypeReference.java @@ -0,0 +1,80 @@ +package org.web3j.abi; + +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; + +/** + *

Type wrapper to get around limitations of Java's type erasure.
+ * This is so that we can pass around Typed {@link org.web3j.abi.datatypes.Array} types.

+ * + *

See this blog post + * for further details.

+ * + *

It may make sense to switch to using Java's reflection + * Type to + * avoid working around this fundamental generics limitation.

+ */ +public abstract class TypeReference implements Comparable> { + + private final Type type; + + protected TypeReference() { + Type superclass = getClass().getGenericSuperclass(); + if (superclass instanceof Class) { + throw new RuntimeException("Missing type parameter."); + } + this.type = ((ParameterizedType) superclass).getActualTypeArguments()[0]; + } + + public int compareTo(TypeReference o) { + // taken from the blog post comments - this results in an errror if the + // type parameter is left out. + return 0; + } + + public Type getType() { + return type; + } + + /** + * Workaround to ensure type does not come back as T due to erasure, this enables you to + * create a TypeReference via {@link Class Class<T>}. + * + * @return the parameterized Class type if applicable, otherwise a regular class + * @throws ClassNotFoundException if the class type cannot be determined + */ + @SuppressWarnings("unchecked") + public Class getClassType() throws ClassNotFoundException { + Type clsType = getType(); + + if (getType() instanceof ParameterizedType) { + return (Class) ((ParameterizedType) clsType).getRawType(); + } else { + return (Class) Class.forName(clsType.getTypeName()); + } + } + + public static TypeReference create(Class cls) { + return new TypeReference(){ + @Override + public Type getType() { + return cls; + } + }; + } + + public static abstract class StaticArrayTypeReference + extends TypeReference { + + private final int size; + + protected StaticArrayTypeReference(int size) { + super(); + this.size = size; + } + + public int getSize() { + return size; + } + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/Utils.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/Utils.java new file mode 100644 index 0000000000..e69a0b45b2 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/Utils.java @@ -0,0 +1,98 @@ +package org.web3j.abi; + +import java.lang.reflect.ParameterizedType; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +import org.web3j.abi.datatypes.DynamicArray; +import org.web3j.abi.datatypes.DynamicBytes; +import org.web3j.abi.datatypes.Fixed; +import org.web3j.abi.datatypes.Int; +import org.web3j.abi.datatypes.StaticArray; +import org.web3j.abi.datatypes.Type; +import org.web3j.abi.datatypes.Ufixed; +import org.web3j.abi.datatypes.Uint; +import org.web3j.abi.datatypes.Utf8String; + +/** + * Utility functions. + */ +public class Utils { + private Utils() {} + + static String getTypeName(TypeReference typeReference) { + try { + java.lang.reflect.Type reflectedType = typeReference.getType(); + + Class type; + if (reflectedType instanceof ParameterizedType) { + type = (Class) ((ParameterizedType) reflectedType).getRawType(); + return getParameterizedTypeName(typeReference, type); + } else { + type = Class.forName(reflectedType.getTypeName()); + return getSimpleTypeName(type); + } + } catch (ClassNotFoundException e) { + throw new UnsupportedOperationException("Invalid class reference provided", e); + } + } + + static String getSimpleTypeName(Class type) { + String simpleName = type.getSimpleName().toLowerCase(); + + if (type.equals(Uint.class) || type.equals(Int.class) + || type.equals(Ufixed.class) || type.equals(Fixed.class)) { + return simpleName + "256"; + } else if (type.equals(Utf8String.class)) { + return "string"; + } else if (type.equals(DynamicBytes.class)) { + return "bytes"; + } else { + return simpleName; + } + } + + static String getParameterizedTypeName( + TypeReference typeReference, Class type) { + + try { + if (type.equals(DynamicArray.class)) { + Class parameterizedType = getParameterizedTypeFromArray(typeReference); + String parameterizedTypeName = getSimpleTypeName(parameterizedType); + return parameterizedTypeName + "[]"; + } else if (type.equals(StaticArray.class)) { + Class parameterizedType = getParameterizedTypeFromArray(typeReference); + String parameterizedTypeName = getSimpleTypeName(parameterizedType); + return parameterizedTypeName + + "[" + + ((TypeReference.StaticArrayTypeReference) typeReference).getSize() + + "]"; + } else { + throw new UnsupportedOperationException("Invalid type provided " + type.getName()); + } + } catch (ClassNotFoundException e) { + throw new UnsupportedOperationException("Invalid class reference provided", e); + } + } + + static Class getParameterizedTypeFromArray( + TypeReference typeReference) throws ClassNotFoundException { + + java.lang.reflect.Type type = typeReference.getType(); + java.lang.reflect.Type[] typeArguments = + ((ParameterizedType) type).getActualTypeArguments(); + + String parameterizedTypeName = typeArguments[0].getTypeName(); + return (Class) Class.forName(parameterizedTypeName); + } + + @SuppressWarnings("unchecked") + public static List> convert(List> input) { + List> result = new ArrayList<>(input.size()); + result.addAll(input.stream() + .map(typeReference -> (TypeReference) typeReference) + .collect(Collectors.toList())); + return result; + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/Address.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/Address.java new file mode 100644 index 0000000000..2fc1079840 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/Address.java @@ -0,0 +1,34 @@ +package org.web3j.abi.datatypes; + +import java.math.BigInteger; + +import org.web3j.crypto.Keys; +import org.web3j.utils.Numeric; + +/** + * Address type, which is equivalent to uint160. + */ +public class Address extends Uint { + + public static final String TYPE_NAME = "address"; + public static final int LENGTH = 160; + public static final Address DEFAULT = new Address(BigInteger.ZERO); + + public Address(BigInteger value) { + super(TYPE_NAME, LENGTH, value); + } + + public Address(String hexValue) { + this(Numeric.toBigInt(hexValue)); + } + + @Override + public String getTypeAsString() { + return TYPE_NAME; + } + + @Override + public String toString() { + return Numeric.toHexStringWithPrefixZeroPadded(value, Keys.ADDRESS_LENGTH_IN_HEX); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/Array.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/Array.java new file mode 100644 index 0000000000..9f3800536c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/Array.java @@ -0,0 +1,76 @@ +package org.web3j.abi.datatypes; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * Fixed size array. + */ +public abstract class Array implements Type> { + + private String type; + private List value; + + Array(String type, T... values) { + if (!valid(values, type)) { + throw new UnsupportedOperationException( + "If empty list is provided, use empty array instance"); + } + + this.type = type; + this.value = Arrays.asList(values); + } + + Array(String type, List values) { + if (!valid(values, type)) { + throw new UnsupportedOperationException( + "If empty list is provided, use empty array instance"); + } + + this.type = type; + this.value = values; + } + + Array(String type) { + this.type = type; + this.value = Collections.emptyList(); + } + + @Override + public List getValue() { + return value; + } + + @Override + public String getTypeAsString() { + return type; + } + + private boolean valid(T[] values, String type) { + return values != null || values.length != 0 || type != null; + } + + private boolean valid(List values, String type) { + return values != null || values.size() != 0 || type != null; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Array array = (Array) o; + + if (!type.equals(array.type)) return false; + return value != null ? value.equals(array.value) : array.value == null; + + } + + @Override + public int hashCode() { + int result = type.hashCode(); + result = 31 * result + (value != null ? value.hashCode() : 0); + return result; + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/Bool.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/Bool.java new file mode 100644 index 0000000000..67b38384a1 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/Bool.java @@ -0,0 +1,42 @@ +package org.web3j.abi.datatypes; + +/** + * Boolean type. + */ +public class Bool implements Type { + + public static final String TYPE_NAME = "bool"; + public static final Bool DEFAULT = new Bool(false); + + private boolean value; + + public Bool(boolean value) { + this.value = value; + } + + @Override + public String getTypeAsString() { + return TYPE_NAME; + } + + @Override + public Boolean getValue() { + return value; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Bool bool = (Bool) o; + + return value == bool.value; + + } + + @Override + public int hashCode() { + return (value ? 1 : 0); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/Bytes.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/Bytes.java new file mode 100644 index 0000000000..b8054ea796 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/Bytes.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes; + +/** + * Statically allocated sequence of bytes. + */ +public class Bytes extends BytesType { + + public static final String TYPE_NAME = "bytes"; + + protected Bytes(int byteSize, byte[] value) { + super(value, TYPE_NAME + value.length); + if (!isValid(byteSize, value)) { + throw new UnsupportedOperationException( + "Input byte array must be in range 0 < M <= 32 and length must match type"); + } + } + + private boolean isValid(int byteSize, byte[] value) { + int length = value.length; + return length > 0 && length <= 32 && length == byteSize; + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/BytesType.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/BytesType.java new file mode 100644 index 0000000000..2c2ff68fe7 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/BytesType.java @@ -0,0 +1,46 @@ +package org.web3j.abi.datatypes; + +import java.util.Arrays; + +/** + * Binary sequence of bytes. + */ +public class BytesType implements Type { + + private byte[] value; + private String type; + + public BytesType(byte[] src, String type) { + this.value = src; + this.type = type; + } + + @Override + public byte[] getValue() { + return value; + } + + @Override + public String getTypeAsString() { + return type; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + BytesType bytesType = (BytesType) o; + + if (!Arrays.equals(value, bytesType.value)) return false; + return type.equals(bytesType.type); + + } + + @Override + public int hashCode() { + int result = Arrays.hashCode(value); + result = 31 * result + type.hashCode(); + return result; + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/DynamicArray.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/DynamicArray.java new file mode 100644 index 0000000000..afe64d1f54 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/DynamicArray.java @@ -0,0 +1,26 @@ +package org.web3j.abi.datatypes; + + +import java.util.List; + +/** + * Dynamic array type. + */ +public class DynamicArray extends Array { + + public DynamicArray(T... values) { + super(values[0].getTypeAsString() + "[]", values); + } + + public DynamicArray(List values) { + super(values.get(0).getTypeAsString() + "[]", values); + } + + private DynamicArray(String type) { + super(type); + } + + public static DynamicArray empty(String type) { + return new DynamicArray(type); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/DynamicBytes.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/DynamicBytes.java new file mode 100644 index 0000000000..2dcd4ba8c4 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/DynamicBytes.java @@ -0,0 +1,14 @@ +package org.web3j.abi.datatypes; + +/** + * Dynamically allocated sequence of bytes. + */ +public class DynamicBytes extends BytesType { + + public static final String TYPE_NAME = "bytes"; + public static final DynamicBytes DEFAULT = new DynamicBytes(new byte[]{}); + + public DynamicBytes(byte[] value) { + super(value, TYPE_NAME); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/Event.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/Event.java new file mode 100644 index 0000000000..98772b0e9b --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/Event.java @@ -0,0 +1,36 @@ +package org.web3j.abi.datatypes; + + +import java.util.List; + +import org.web3j.abi.TypeReference; + +import static org.web3j.abi.Utils.convert; + +/** + * Event wrapper + */ +public class Event { + private String name; + private List> indexedParameters; + private List> nonIndexedParameters; + + public Event(String name, List> indexedParameters, + List> nonIndexedParameters) { + this.name = name; + this.indexedParameters = convert(indexedParameters); + this.nonIndexedParameters = convert(nonIndexedParameters); + } + + public String getName() { + return name; + } + + public List> getIndexedParameters() { + return indexedParameters; + } + + public List> getNonIndexedParameters() { + return nonIndexedParameters; + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/Fixed.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/Fixed.java new file mode 100644 index 0000000000..cd3becdfe8 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/Fixed.java @@ -0,0 +1,28 @@ +package org.web3j.abi.datatypes; + +import java.math.BigInteger; + +/** + * Signed fixed type. + */ +public class Fixed extends FixedPointType { + + public static final String TYPE_NAME = "fixed"; + public static final Fixed DEFAULT = new Fixed(BigInteger.ZERO); + + protected Fixed(int mBitSize, int nBitSize, BigInteger value) { + super(TYPE_NAME , mBitSize, nBitSize, value); + } + + public Fixed(BigInteger value) { + this(DEFAULT_BIT_LENGTH, DEFAULT_BIT_LENGTH, value); + } + + public Fixed(BigInteger m, BigInteger n) { + this(convert(m, n)); + } + + protected Fixed(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + this(convert(mBitSize, nBitSize, m, n)); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/FixedPointType.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/FixedPointType.java new file mode 100644 index 0000000000..f645d0a90f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/FixedPointType.java @@ -0,0 +1,49 @@ +package org.web3j.abi.datatypes; + +import java.math.BigInteger; + +/** + * Common fixed-point type properties. + */ +public abstract class FixedPointType extends NumericType { + + static final int DEFAULT_BIT_LENGTH = MAX_BIT_LENGTH >> 1; + + public FixedPointType(String typePrefix, int mBitSize, int nBitSize, BigInteger value) { + super(typePrefix + mBitSize + "x" + nBitSize, value); + if (!valid(mBitSize, nBitSize, value)) { + throw new UnsupportedOperationException( + "Bitsize must be 8 bit aligned, and in range 0 < bitSize <= 256"); + } + } + + boolean valid(int mBitSize, int nBitSize, BigInteger value) { + return isValidBitSize(mBitSize, nBitSize) + && isValidBitCount(mBitSize, nBitSize, value); + } + + static boolean isValidBitSize(int mBitSize, int nBitSize) { + int bitSize = mBitSize + nBitSize; + return mBitSize % 8 == 0 + && nBitSize % 8 == 0 + && bitSize > 0 + && bitSize <= MAX_BIT_LENGTH; + } + + private static boolean isValidBitCount(int mBitSize, int nBitSize, BigInteger value) { + return value.bitCount() <= mBitSize + nBitSize; + } + + static BigInteger convert(BigInteger m, BigInteger n) { + return convert(DEFAULT_BIT_LENGTH, DEFAULT_BIT_LENGTH, m, n); + } + + static BigInteger convert(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + BigInteger mPadded = m.shiftLeft(nBitSize); + int nBitLength = n.bitLength(); + + // find next multiple of 4 + int shift = (nBitLength + 3) & ~0x03; + return mPadded.or(n.shiftLeft(nBitSize - shift)); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/Function.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/Function.java new file mode 100644 index 0000000000..29ec1af65f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/Function.java @@ -0,0 +1,35 @@ +package org.web3j.abi.datatypes; + +import java.util.List; + +import org.web3j.abi.TypeReference; + +import static org.web3j.abi.Utils.convert; + +/** + * Function wrapper + */ +public class Function { + private String name; + private List inputParameters; + private List> outputParameters; + + public Function(String name, List inputParameters, + List> outputParameters) { + this.name = name; + this.inputParameters = inputParameters; + this.outputParameters = convert(outputParameters); + } + + public String getName() { + return name; + } + + public List getInputParameters() { + return inputParameters; + } + + public List> getOutputParameters() { + return outputParameters; + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/Int.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/Int.java new file mode 100644 index 0000000000..72bf551d04 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/Int.java @@ -0,0 +1,21 @@ +package org.web3j.abi.datatypes; + +import java.math.BigInteger; + +/** + * Integer type. + */ +public class Int extends IntType { + + public static final String TYPE_NAME = "int"; + public static final Int DEFAULT = new Int(BigInteger.ZERO); + + public Int(BigInteger value) { + // "int" values should be declared as int256 in computing function selectors + this(MAX_BIT_LENGTH, value); + } + + protected Int(int bitSize, BigInteger value) { + super(TYPE_NAME, bitSize, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/IntType.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/IntType.java new file mode 100644 index 0000000000..9a20551a55 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/IntType.java @@ -0,0 +1,32 @@ +package org.web3j.abi.datatypes; + +import java.math.BigInteger; + +/** + * Common integer properties. + */ +public abstract class IntType extends NumericType { + + public IntType(String typePrefix, int bitSize, BigInteger value) { + super(typePrefix + bitSize, value); + if (!valid(bitSize, value)) { + throw new UnsupportedOperationException( + "Bitsize must be 8 bit aligned, and in range 0 < bitSize <= 256"); + } + } + + boolean valid(int bitSize, BigInteger value) { + return isValidBitSize(bitSize) + && isValidBitCount(bitSize, value); + } + + static boolean isValidBitSize(int bitSize) { + return bitSize % 8 == 0 + && bitSize > 0 + && bitSize <= MAX_BIT_LENGTH; + } + + private static boolean isValidBitCount(int bitSize, BigInteger value) { + return value.bitCount() <= bitSize; + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/NumericType.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/NumericType.java new file mode 100644 index 0000000000..6e075304ea --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/NumericType.java @@ -0,0 +1,46 @@ +package org.web3j.abi.datatypes; + +import java.math.BigInteger; + +/** + * Common numeric type. + */ +public abstract class NumericType implements Type { + + private String type; + BigInteger value; + + public NumericType(String type, BigInteger value) { + this.type = type; + this.value = value; + } + + @Override + public String getTypeAsString() { + return type; + } + + @Override + public BigInteger getValue() { + return value; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + NumericType that = (NumericType) o; + + if (!type.equals(that.type)) return false; + return value != null ? value.equals(that.value) : that.value == null; + + } + + @Override + public int hashCode() { + int result = type.hashCode(); + result = 31 * result + (value != null ? value.hashCode() : 0); + return result; + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/StaticArray.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/StaticArray.java new file mode 100644 index 0000000000..838bd00ccc --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/StaticArray.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes; + + +import java.util.List; + +/** + * Static array type. + */ +public class StaticArray extends Array { + + public StaticArray(T... values) { + super(values[0].getTypeAsString() + "[" + values.length + "]", values); + } + + public StaticArray(List values) { + super(values.get(0).getTypeAsString() + "[" + values.size() + "]", values); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/Type.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/Type.java new file mode 100644 index 0000000000..d4e0bef79b --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/Type.java @@ -0,0 +1,13 @@ +package org.web3j.abi.datatypes; + +/** + * ABI Types. + */ +public interface Type { + int MAX_BIT_LENGTH = 256; + int MAX_BYTE_LENGTH = MAX_BIT_LENGTH / 8; + + T getValue(); + + String getTypeAsString(); +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/Ufixed.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/Ufixed.java new file mode 100644 index 0000000000..353aaffcfe --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/Ufixed.java @@ -0,0 +1,34 @@ +package org.web3j.abi.datatypes; + +import java.math.BigInteger; + +/** + * Signed fixed type. + */ +public class Ufixed extends FixedPointType { + + public static final String TYPE_NAME = "ufixed"; + public static final Ufixed DEFAULT = new Ufixed(BigInteger.ZERO); + + protected Ufixed(int mBitSize, int nBitSize, BigInteger value) { + super(TYPE_NAME, mBitSize, nBitSize, value); + } + + public Ufixed(BigInteger value) { + this(DEFAULT_BIT_LENGTH, DEFAULT_BIT_LENGTH, value); + } + + public Ufixed(BigInteger m, BigInteger n) { + this(convert(m, n)); + } + + protected Ufixed(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + this(convert(mBitSize, nBitSize, m, n)); + } + + @Override + boolean valid(int mBitSize, int nBitSize, BigInteger value) { + return super.valid(mBitSize, nBitSize, value) + && value.signum() != -1; + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/Uint.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/Uint.java new file mode 100644 index 0000000000..5ff7c7bbef --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/Uint.java @@ -0,0 +1,34 @@ +package org.web3j.abi.datatypes; + +import java.math.BigInteger; + +/** + * Unsigned integer type. + */ +public class Uint extends IntType { + + public static final String TYPE_NAME = "uint"; + public static final Uint DEFAULT = new Uint(BigInteger.ZERO); + + /** + * This constructor is required by the {@link Address} type. + */ + Uint(String typePrefix, int bitSize, BigInteger value) { + super(typePrefix, bitSize, value); + } + + protected Uint(int bitSize, BigInteger value) { + this(TYPE_NAME, bitSize, value); + } + + public Uint(BigInteger value) { + // "int" values should be declared as int256 in computing function selectors + this(MAX_BIT_LENGTH, value); + } + + @Override + boolean valid(int bitSize, BigInteger value) { + return super.valid(bitSize, value) + && value.signum() != -1; + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/Utf8String.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/Utf8String.java new file mode 100644 index 0000000000..c6bf9d41b8 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/Utf8String.java @@ -0,0 +1,47 @@ +package org.web3j.abi.datatypes; + +/** + * UTF-8 encoded string type. + */ +public class Utf8String implements Type { + + public static final String TYPE_NAME = "string"; + public static final Utf8String DEFAULT = new Utf8String(""); + + private String value; + + public Utf8String(String value) { + this.value = value; + } + + @Override + public String getValue() { + return value; + } + + @Override + public String getTypeAsString() { + return TYPE_NAME; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Utf8String that = (Utf8String) o; + + return value != null ? value.equals(that.value) : that.value == null; + + } + + @Override + public int hashCode() { + return value != null ? value.hashCode() : 0; + } + + @Override + public String toString() { + return value; + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/AbiTypes.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/AbiTypes.java new file mode 100644 index 0000000000..01cc69d4b2 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/AbiTypes.java @@ -0,0 +1,347 @@ +package org.web3j.abi.datatypes.generated; + +import org.web3j.abi.datatypes.Address; +import org.web3j.abi.datatypes.Bool; +import org.web3j.abi.datatypes.DynamicBytes; +import org.web3j.abi.datatypes.Utf8String; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesMapperGenerator} to update.

+ */ +public final class AbiTypes { + private AbiTypes() { + } + + public static Class getType(String type) { + switch (type) { + case "address": + return Address.class; + case "bool": + return Bool.class; + case "string": + return Utf8String.class; + case "bytes": + return DynamicBytes.class; + case "uint8": + return Uint8.class; + case "int8": + return Int8.class; + case "uint16": + return Uint16.class; + case "int16": + return Int16.class; + case "uint24": + return Uint24.class; + case "int24": + return Int24.class; + case "uint32": + return Uint32.class; + case "int32": + return Int32.class; + case "uint40": + return Uint40.class; + case "int40": + return Int40.class; + case "uint48": + return Uint48.class; + case "int48": + return Int48.class; + case "uint56": + return Uint56.class; + case "int56": + return Int56.class; + case "uint64": + return Uint64.class; + case "int64": + return Int64.class; + case "uint72": + return Uint72.class; + case "int72": + return Int72.class; + case "uint80": + return Uint80.class; + case "int80": + return Int80.class; + case "uint88": + return Uint88.class; + case "int88": + return Int88.class; + case "uint96": + return Uint96.class; + case "int96": + return Int96.class; + case "uint104": + return Uint104.class; + case "int104": + return Int104.class; + case "uint112": + return Uint112.class; + case "int112": + return Int112.class; + case "uint120": + return Uint120.class; + case "int120": + return Int120.class; + case "uint128": + return Uint128.class; + case "int128": + return Int128.class; + case "uint136": + return Uint136.class; + case "int136": + return Int136.class; + case "uint144": + return Uint144.class; + case "int144": + return Int144.class; + case "uint152": + return Uint152.class; + case "int152": + return Int152.class; + case "uint160": + return Uint160.class; + case "int160": + return Int160.class; + case "uint168": + return Uint168.class; + case "int168": + return Int168.class; + case "uint176": + return Uint176.class; + case "int176": + return Int176.class; + case "uint184": + return Uint184.class; + case "int184": + return Int184.class; + case "uint192": + return Uint192.class; + case "int192": + return Int192.class; + case "uint200": + return Uint200.class; + case "int200": + return Int200.class; + case "uint208": + return Uint208.class; + case "int208": + return Int208.class; + case "uint216": + return Uint216.class; + case "int216": + return Int216.class; + case "uint224": + return Uint224.class; + case "int224": + return Int224.class; + case "uint232": + return Uint232.class; + case "int232": + return Int232.class; + case "uint240": + return Uint240.class; + case "int240": + return Int240.class; + case "uint248": + return Uint248.class; + case "int248": + return Int248.class; + case "uint256": + return Uint256.class; + case "int256": + return Int256.class; + case "ufixed8x248": + return Ufixed8x248.class; + case "fixed8x248": + return Fixed8x248.class; + case "ufixed16x240": + return Ufixed16x240.class; + case "fixed16x240": + return Fixed16x240.class; + case "ufixed24x232": + return Ufixed24x232.class; + case "fixed24x232": + return Fixed24x232.class; + case "ufixed32x224": + return Ufixed32x224.class; + case "fixed32x224": + return Fixed32x224.class; + case "ufixed40x216": + return Ufixed40x216.class; + case "fixed40x216": + return Fixed40x216.class; + case "ufixed48x208": + return Ufixed48x208.class; + case "fixed48x208": + return Fixed48x208.class; + case "ufixed56x200": + return Ufixed56x200.class; + case "fixed56x200": + return Fixed56x200.class; + case "ufixed64x192": + return Ufixed64x192.class; + case "fixed64x192": + return Fixed64x192.class; + case "ufixed72x184": + return Ufixed72x184.class; + case "fixed72x184": + return Fixed72x184.class; + case "ufixed80x176": + return Ufixed80x176.class; + case "fixed80x176": + return Fixed80x176.class; + case "ufixed88x168": + return Ufixed88x168.class; + case "fixed88x168": + return Fixed88x168.class; + case "ufixed96x160": + return Ufixed96x160.class; + case "fixed96x160": + return Fixed96x160.class; + case "ufixed104x152": + return Ufixed104x152.class; + case "fixed104x152": + return Fixed104x152.class; + case "ufixed112x144": + return Ufixed112x144.class; + case "fixed112x144": + return Fixed112x144.class; + case "ufixed120x136": + return Ufixed120x136.class; + case "fixed120x136": + return Fixed120x136.class; + case "ufixed128x128": + return Ufixed128x128.class; + case "fixed128x128": + return Fixed128x128.class; + case "ufixed136x120": + return Ufixed136x120.class; + case "fixed136x120": + return Fixed136x120.class; + case "ufixed144x112": + return Ufixed144x112.class; + case "fixed144x112": + return Fixed144x112.class; + case "ufixed152x104": + return Ufixed152x104.class; + case "fixed152x104": + return Fixed152x104.class; + case "ufixed160x96": + return Ufixed160x96.class; + case "fixed160x96": + return Fixed160x96.class; + case "ufixed168x88": + return Ufixed168x88.class; + case "fixed168x88": + return Fixed168x88.class; + case "ufixed176x80": + return Ufixed176x80.class; + case "fixed176x80": + return Fixed176x80.class; + case "ufixed184x72": + return Ufixed184x72.class; + case "fixed184x72": + return Fixed184x72.class; + case "ufixed192x64": + return Ufixed192x64.class; + case "fixed192x64": + return Fixed192x64.class; + case "ufixed200x56": + return Ufixed200x56.class; + case "fixed200x56": + return Fixed200x56.class; + case "ufixed208x48": + return Ufixed208x48.class; + case "fixed208x48": + return Fixed208x48.class; + case "ufixed216x40": + return Ufixed216x40.class; + case "fixed216x40": + return Fixed216x40.class; + case "ufixed224x32": + return Ufixed224x32.class; + case "fixed224x32": + return Fixed224x32.class; + case "ufixed232x24": + return Ufixed232x24.class; + case "fixed232x24": + return Fixed232x24.class; + case "ufixed240x16": + return Ufixed240x16.class; + case "fixed240x16": + return Fixed240x16.class; + case "ufixed248x8": + return Ufixed248x8.class; + case "fixed248x8": + return Fixed248x8.class; + case "bytes1": + return Bytes1.class; + case "bytes2": + return Bytes2.class; + case "bytes3": + return Bytes3.class; + case "bytes4": + return Bytes4.class; + case "bytes5": + return Bytes5.class; + case "bytes6": + return Bytes6.class; + case "bytes7": + return Bytes7.class; + case "bytes8": + return Bytes8.class; + case "bytes9": + return Bytes9.class; + case "bytes10": + return Bytes10.class; + case "bytes11": + return Bytes11.class; + case "bytes12": + return Bytes12.class; + case "bytes13": + return Bytes13.class; + case "bytes14": + return Bytes14.class; + case "bytes15": + return Bytes15.class; + case "bytes16": + return Bytes16.class; + case "bytes17": + return Bytes17.class; + case "bytes18": + return Bytes18.class; + case "bytes19": + return Bytes19.class; + case "bytes20": + return Bytes20.class; + case "bytes21": + return Bytes21.class; + case "bytes22": + return Bytes22.class; + case "bytes23": + return Bytes23.class; + case "bytes24": + return Bytes24.class; + case "bytes25": + return Bytes25.class; + case "bytes26": + return Bytes26.class; + case "bytes27": + return Bytes27.class; + case "bytes28": + return Bytes28.class; + case "bytes29": + return Bytes29.class; + case "bytes30": + return Bytes30.class; + case "bytes31": + return Bytes31.class; + case "bytes32": + return Bytes32.class; + default: + throw new UnsupportedOperationException("Unsupported type encountered: " + type); + } + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes1.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes1.java new file mode 100644 index 0000000000..d1913c64d3 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes1.java @@ -0,0 +1,16 @@ +package org.web3j.abi.datatypes.generated; + +import org.web3j.abi.datatypes.Bytes; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Bytes1 extends Bytes { + public static final Bytes1 DEFAULT = new Bytes1(new byte[1]); + + public Bytes1(byte[] value) { + super(1, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes10.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes10.java new file mode 100644 index 0000000000..26fc350791 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes10.java @@ -0,0 +1,16 @@ +package org.web3j.abi.datatypes.generated; + +import org.web3j.abi.datatypes.Bytes; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Bytes10 extends Bytes { + public static final Bytes10 DEFAULT = new Bytes10(new byte[10]); + + public Bytes10(byte[] value) { + super(10, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes11.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes11.java new file mode 100644 index 0000000000..25269cfb98 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes11.java @@ -0,0 +1,16 @@ +package org.web3j.abi.datatypes.generated; + +import org.web3j.abi.datatypes.Bytes; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Bytes11 extends Bytes { + public static final Bytes11 DEFAULT = new Bytes11(new byte[11]); + + public Bytes11(byte[] value) { + super(11, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes12.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes12.java new file mode 100644 index 0000000000..f9474ad864 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes12.java @@ -0,0 +1,16 @@ +package org.web3j.abi.datatypes.generated; + +import org.web3j.abi.datatypes.Bytes; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Bytes12 extends Bytes { + public static final Bytes12 DEFAULT = new Bytes12(new byte[12]); + + public Bytes12(byte[] value) { + super(12, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes13.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes13.java new file mode 100644 index 0000000000..5f3034f014 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes13.java @@ -0,0 +1,16 @@ +package org.web3j.abi.datatypes.generated; + +import org.web3j.abi.datatypes.Bytes; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Bytes13 extends Bytes { + public static final Bytes13 DEFAULT = new Bytes13(new byte[13]); + + public Bytes13(byte[] value) { + super(13, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes14.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes14.java new file mode 100644 index 0000000000..5d47723f7d --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes14.java @@ -0,0 +1,16 @@ +package org.web3j.abi.datatypes.generated; + +import org.web3j.abi.datatypes.Bytes; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Bytes14 extends Bytes { + public static final Bytes14 DEFAULT = new Bytes14(new byte[14]); + + public Bytes14(byte[] value) { + super(14, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes15.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes15.java new file mode 100644 index 0000000000..d24b4c128a --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes15.java @@ -0,0 +1,16 @@ +package org.web3j.abi.datatypes.generated; + +import org.web3j.abi.datatypes.Bytes; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Bytes15 extends Bytes { + public static final Bytes15 DEFAULT = new Bytes15(new byte[15]); + + public Bytes15(byte[] value) { + super(15, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes16.java new file mode 100644 index 0000000000..cab8e5705f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes16.java @@ -0,0 +1,16 @@ +package org.web3j.abi.datatypes.generated; + +import org.web3j.abi.datatypes.Bytes; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Bytes16 extends Bytes { + public static final Bytes16 DEFAULT = new Bytes16(new byte[16]); + + public Bytes16(byte[] value) { + super(16, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes17.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes17.java new file mode 100644 index 0000000000..a66696bc91 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes17.java @@ -0,0 +1,16 @@ +package org.web3j.abi.datatypes.generated; + +import org.web3j.abi.datatypes.Bytes; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Bytes17 extends Bytes { + public static final Bytes17 DEFAULT = new Bytes17(new byte[17]); + + public Bytes17(byte[] value) { + super(17, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes18.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes18.java new file mode 100644 index 0000000000..16e6794f44 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes18.java @@ -0,0 +1,16 @@ +package org.web3j.abi.datatypes.generated; + +import org.web3j.abi.datatypes.Bytes; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Bytes18 extends Bytes { + public static final Bytes18 DEFAULT = new Bytes18(new byte[18]); + + public Bytes18(byte[] value) { + super(18, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes19.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes19.java new file mode 100644 index 0000000000..372218fc5c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes19.java @@ -0,0 +1,16 @@ +package org.web3j.abi.datatypes.generated; + +import org.web3j.abi.datatypes.Bytes; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Bytes19 extends Bytes { + public static final Bytes19 DEFAULT = new Bytes19(new byte[19]); + + public Bytes19(byte[] value) { + super(19, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes2.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes2.java new file mode 100644 index 0000000000..f1c222f1f5 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes2.java @@ -0,0 +1,16 @@ +package org.web3j.abi.datatypes.generated; + +import org.web3j.abi.datatypes.Bytes; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Bytes2 extends Bytes { + public static final Bytes2 DEFAULT = new Bytes2(new byte[2]); + + public Bytes2(byte[] value) { + super(2, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes20.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes20.java new file mode 100644 index 0000000000..28ac8ebe4b --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes20.java @@ -0,0 +1,16 @@ +package org.web3j.abi.datatypes.generated; + +import org.web3j.abi.datatypes.Bytes; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Bytes20 extends Bytes { + public static final Bytes20 DEFAULT = new Bytes20(new byte[20]); + + public Bytes20(byte[] value) { + super(20, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes21.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes21.java new file mode 100644 index 0000000000..7837fe8814 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes21.java @@ -0,0 +1,16 @@ +package org.web3j.abi.datatypes.generated; + +import org.web3j.abi.datatypes.Bytes; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Bytes21 extends Bytes { + public static final Bytes21 DEFAULT = new Bytes21(new byte[21]); + + public Bytes21(byte[] value) { + super(21, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes22.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes22.java new file mode 100644 index 0000000000..64b91da417 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes22.java @@ -0,0 +1,16 @@ +package org.web3j.abi.datatypes.generated; + +import org.web3j.abi.datatypes.Bytes; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Bytes22 extends Bytes { + public static final Bytes22 DEFAULT = new Bytes22(new byte[22]); + + public Bytes22(byte[] value) { + super(22, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes23.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes23.java new file mode 100644 index 0000000000..ce046ef6d3 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes23.java @@ -0,0 +1,16 @@ +package org.web3j.abi.datatypes.generated; + +import org.web3j.abi.datatypes.Bytes; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Bytes23 extends Bytes { + public static final Bytes23 DEFAULT = new Bytes23(new byte[23]); + + public Bytes23(byte[] value) { + super(23, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes24.java new file mode 100644 index 0000000000..1f16463023 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes24.java @@ -0,0 +1,16 @@ +package org.web3j.abi.datatypes.generated; + +import org.web3j.abi.datatypes.Bytes; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Bytes24 extends Bytes { + public static final Bytes24 DEFAULT = new Bytes24(new byte[24]); + + public Bytes24(byte[] value) { + super(24, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes25.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes25.java new file mode 100644 index 0000000000..9f6ed543f6 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes25.java @@ -0,0 +1,16 @@ +package org.web3j.abi.datatypes.generated; + +import org.web3j.abi.datatypes.Bytes; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Bytes25 extends Bytes { + public static final Bytes25 DEFAULT = new Bytes25(new byte[25]); + + public Bytes25(byte[] value) { + super(25, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes26.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes26.java new file mode 100644 index 0000000000..ac07b9f19d --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes26.java @@ -0,0 +1,16 @@ +package org.web3j.abi.datatypes.generated; + +import org.web3j.abi.datatypes.Bytes; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Bytes26 extends Bytes { + public static final Bytes26 DEFAULT = new Bytes26(new byte[26]); + + public Bytes26(byte[] value) { + super(26, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes27.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes27.java new file mode 100644 index 0000000000..27827730ae --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes27.java @@ -0,0 +1,16 @@ +package org.web3j.abi.datatypes.generated; + +import org.web3j.abi.datatypes.Bytes; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Bytes27 extends Bytes { + public static final Bytes27 DEFAULT = new Bytes27(new byte[27]); + + public Bytes27(byte[] value) { + super(27, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes28.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes28.java new file mode 100644 index 0000000000..b500dc7f0c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes28.java @@ -0,0 +1,16 @@ +package org.web3j.abi.datatypes.generated; + +import org.web3j.abi.datatypes.Bytes; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Bytes28 extends Bytes { + public static final Bytes28 DEFAULT = new Bytes28(new byte[28]); + + public Bytes28(byte[] value) { + super(28, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes29.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes29.java new file mode 100644 index 0000000000..128f317e9f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes29.java @@ -0,0 +1,16 @@ +package org.web3j.abi.datatypes.generated; + +import org.web3j.abi.datatypes.Bytes; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Bytes29 extends Bytes { + public static final Bytes29 DEFAULT = new Bytes29(new byte[29]); + + public Bytes29(byte[] value) { + super(29, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes3.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes3.java new file mode 100644 index 0000000000..f810fd39b8 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes3.java @@ -0,0 +1,16 @@ +package org.web3j.abi.datatypes.generated; + +import org.web3j.abi.datatypes.Bytes; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Bytes3 extends Bytes { + public static final Bytes3 DEFAULT = new Bytes3(new byte[3]); + + public Bytes3(byte[] value) { + super(3, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes30.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes30.java new file mode 100644 index 0000000000..43bf7a16bb --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes30.java @@ -0,0 +1,16 @@ +package org.web3j.abi.datatypes.generated; + +import org.web3j.abi.datatypes.Bytes; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Bytes30 extends Bytes { + public static final Bytes30 DEFAULT = new Bytes30(new byte[30]); + + public Bytes30(byte[] value) { + super(30, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes31.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes31.java new file mode 100644 index 0000000000..39b293d295 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes31.java @@ -0,0 +1,16 @@ +package org.web3j.abi.datatypes.generated; + +import org.web3j.abi.datatypes.Bytes; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Bytes31 extends Bytes { + public static final Bytes31 DEFAULT = new Bytes31(new byte[31]); + + public Bytes31(byte[] value) { + super(31, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes32.java new file mode 100644 index 0000000000..09ca59c891 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes32.java @@ -0,0 +1,16 @@ +package org.web3j.abi.datatypes.generated; + +import org.web3j.abi.datatypes.Bytes; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Bytes32 extends Bytes { + public static final Bytes32 DEFAULT = new Bytes32(new byte[32]); + + public Bytes32(byte[] value) { + super(32, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes4.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes4.java new file mode 100644 index 0000000000..6ad70e676d --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes4.java @@ -0,0 +1,16 @@ +package org.web3j.abi.datatypes.generated; + +import org.web3j.abi.datatypes.Bytes; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Bytes4 extends Bytes { + public static final Bytes4 DEFAULT = new Bytes4(new byte[4]); + + public Bytes4(byte[] value) { + super(4, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes5.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes5.java new file mode 100644 index 0000000000..1ac54c0fae --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes5.java @@ -0,0 +1,16 @@ +package org.web3j.abi.datatypes.generated; + +import org.web3j.abi.datatypes.Bytes; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Bytes5 extends Bytes { + public static final Bytes5 DEFAULT = new Bytes5(new byte[5]); + + public Bytes5(byte[] value) { + super(5, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes6.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes6.java new file mode 100644 index 0000000000..72944d3e7a --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes6.java @@ -0,0 +1,16 @@ +package org.web3j.abi.datatypes.generated; + +import org.web3j.abi.datatypes.Bytes; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Bytes6 extends Bytes { + public static final Bytes6 DEFAULT = new Bytes6(new byte[6]); + + public Bytes6(byte[] value) { + super(6, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes7.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes7.java new file mode 100644 index 0000000000..c0b6dfb6ba --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes7.java @@ -0,0 +1,16 @@ +package org.web3j.abi.datatypes.generated; + +import org.web3j.abi.datatypes.Bytes; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Bytes7 extends Bytes { + public static final Bytes7 DEFAULT = new Bytes7(new byte[7]); + + public Bytes7(byte[] value) { + super(7, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes8.java new file mode 100644 index 0000000000..67c2411c78 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes8.java @@ -0,0 +1,16 @@ +package org.web3j.abi.datatypes.generated; + +import org.web3j.abi.datatypes.Bytes; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Bytes8 extends Bytes { + public static final Bytes8 DEFAULT = new Bytes8(new byte[8]); + + public Bytes8(byte[] value) { + super(8, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes9.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes9.java new file mode 100644 index 0000000000..d906cb854e --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Bytes9.java @@ -0,0 +1,16 @@ +package org.web3j.abi.datatypes.generated; + +import org.web3j.abi.datatypes.Bytes; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Bytes9 extends Bytes { + public static final Bytes9 DEFAULT = new Bytes9(new byte[9]); + + public Bytes9(byte[] value) { + super(9, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x104.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x104.java new file mode 100644 index 0000000000..69119183c7 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x104.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed104x104 extends Fixed { + public static final Fixed104x104 DEFAULT = new Fixed104x104(BigInteger.ZERO); + + public Fixed104x104(BigInteger value) { + super(104, 104, value); + } + + public Fixed104x104(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(104, 104, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x112.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x112.java new file mode 100644 index 0000000000..8fe28033d4 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x112.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed104x112 extends Fixed { + public static final Fixed104x112 DEFAULT = new Fixed104x112(BigInteger.ZERO); + + public Fixed104x112(BigInteger value) { + super(104, 112, value); + } + + public Fixed104x112(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(104, 112, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x120.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x120.java new file mode 100644 index 0000000000..0aa4cd4404 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x120.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed104x120 extends Fixed { + public static final Fixed104x120 DEFAULT = new Fixed104x120(BigInteger.ZERO); + + public Fixed104x120(BigInteger value) { + super(104, 120, value); + } + + public Fixed104x120(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(104, 120, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x128.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x128.java new file mode 100644 index 0000000000..d330862c79 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x128.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed104x128 extends Fixed { + public static final Fixed104x128 DEFAULT = new Fixed104x128(BigInteger.ZERO); + + public Fixed104x128(BigInteger value) { + super(104, 128, value); + } + + public Fixed104x128(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(104, 128, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x136.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x136.java new file mode 100644 index 0000000000..e4281c6762 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x136.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed104x136 extends Fixed { + public static final Fixed104x136 DEFAULT = new Fixed104x136(BigInteger.ZERO); + + public Fixed104x136(BigInteger value) { + super(104, 136, value); + } + + public Fixed104x136(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(104, 136, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x144.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x144.java new file mode 100644 index 0000000000..36d33ef37d --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x144.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed104x144 extends Fixed { + public static final Fixed104x144 DEFAULT = new Fixed104x144(BigInteger.ZERO); + + public Fixed104x144(BigInteger value) { + super(104, 144, value); + } + + public Fixed104x144(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(104, 144, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x152.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x152.java new file mode 100644 index 0000000000..e6f123e7a4 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x152.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed104x152 extends Fixed { + public static final Fixed104x152 DEFAULT = new Fixed104x152(BigInteger.ZERO); + + public Fixed104x152(BigInteger value) { + super(104, 152, value); + } + + public Fixed104x152(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(104, 152, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x16.java new file mode 100644 index 0000000000..7784e4e11a --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed104x16 extends Fixed { + public static final Fixed104x16 DEFAULT = new Fixed104x16(BigInteger.ZERO); + + public Fixed104x16(BigInteger value) { + super(104, 16, value); + } + + public Fixed104x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(104, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x24.java new file mode 100644 index 0000000000..881ce37c9f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed104x24 extends Fixed { + public static final Fixed104x24 DEFAULT = new Fixed104x24(BigInteger.ZERO); + + public Fixed104x24(BigInteger value) { + super(104, 24, value); + } + + public Fixed104x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(104, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x32.java new file mode 100644 index 0000000000..d6e9428eca --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed104x32 extends Fixed { + public static final Fixed104x32 DEFAULT = new Fixed104x32(BigInteger.ZERO); + + public Fixed104x32(BigInteger value) { + super(104, 32, value); + } + + public Fixed104x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(104, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x40.java new file mode 100644 index 0000000000..b34281597e --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed104x40 extends Fixed { + public static final Fixed104x40 DEFAULT = new Fixed104x40(BigInteger.ZERO); + + public Fixed104x40(BigInteger value) { + super(104, 40, value); + } + + public Fixed104x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(104, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x48.java new file mode 100644 index 0000000000..b05532be23 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed104x48 extends Fixed { + public static final Fixed104x48 DEFAULT = new Fixed104x48(BigInteger.ZERO); + + public Fixed104x48(BigInteger value) { + super(104, 48, value); + } + + public Fixed104x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(104, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x56.java new file mode 100644 index 0000000000..3f72b22ecd --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x56.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed104x56 extends Fixed { + public static final Fixed104x56 DEFAULT = new Fixed104x56(BigInteger.ZERO); + + public Fixed104x56(BigInteger value) { + super(104, 56, value); + } + + public Fixed104x56(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(104, 56, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x64.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x64.java new file mode 100644 index 0000000000..9a1fdb3943 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x64.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed104x64 extends Fixed { + public static final Fixed104x64 DEFAULT = new Fixed104x64(BigInteger.ZERO); + + public Fixed104x64(BigInteger value) { + super(104, 64, value); + } + + public Fixed104x64(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(104, 64, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x72.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x72.java new file mode 100644 index 0000000000..106078a4e2 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x72.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed104x72 extends Fixed { + public static final Fixed104x72 DEFAULT = new Fixed104x72(BigInteger.ZERO); + + public Fixed104x72(BigInteger value) { + super(104, 72, value); + } + + public Fixed104x72(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(104, 72, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x8.java new file mode 100644 index 0000000000..f91062cbb6 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed104x8 extends Fixed { + public static final Fixed104x8 DEFAULT = new Fixed104x8(BigInteger.ZERO); + + public Fixed104x8(BigInteger value) { + super(104, 8, value); + } + + public Fixed104x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(104, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x80.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x80.java new file mode 100644 index 0000000000..f6bbd379b2 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x80.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed104x80 extends Fixed { + public static final Fixed104x80 DEFAULT = new Fixed104x80(BigInteger.ZERO); + + public Fixed104x80(BigInteger value) { + super(104, 80, value); + } + + public Fixed104x80(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(104, 80, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x88.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x88.java new file mode 100644 index 0000000000..015c09ad3f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x88.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed104x88 extends Fixed { + public static final Fixed104x88 DEFAULT = new Fixed104x88(BigInteger.ZERO); + + public Fixed104x88(BigInteger value) { + super(104, 88, value); + } + + public Fixed104x88(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(104, 88, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x96.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x96.java new file mode 100644 index 0000000000..a6fff9e4a1 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed104x96.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed104x96 extends Fixed { + public static final Fixed104x96 DEFAULT = new Fixed104x96(BigInteger.ZERO); + + public Fixed104x96(BigInteger value) { + super(104, 96, value); + } + + public Fixed104x96(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(104, 96, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x104.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x104.java new file mode 100644 index 0000000000..9c1c98ddef --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x104.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed112x104 extends Fixed { + public static final Fixed112x104 DEFAULT = new Fixed112x104(BigInteger.ZERO); + + public Fixed112x104(BigInteger value) { + super(112, 104, value); + } + + public Fixed112x104(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(112, 104, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x112.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x112.java new file mode 100644 index 0000000000..6fab722cc5 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x112.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed112x112 extends Fixed { + public static final Fixed112x112 DEFAULT = new Fixed112x112(BigInteger.ZERO); + + public Fixed112x112(BigInteger value) { + super(112, 112, value); + } + + public Fixed112x112(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(112, 112, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x120.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x120.java new file mode 100644 index 0000000000..d8075625d9 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x120.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed112x120 extends Fixed { + public static final Fixed112x120 DEFAULT = new Fixed112x120(BigInteger.ZERO); + + public Fixed112x120(BigInteger value) { + super(112, 120, value); + } + + public Fixed112x120(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(112, 120, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x128.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x128.java new file mode 100644 index 0000000000..20b34ecdd3 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x128.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed112x128 extends Fixed { + public static final Fixed112x128 DEFAULT = new Fixed112x128(BigInteger.ZERO); + + public Fixed112x128(BigInteger value) { + super(112, 128, value); + } + + public Fixed112x128(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(112, 128, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x136.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x136.java new file mode 100644 index 0000000000..230d81524e --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x136.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed112x136 extends Fixed { + public static final Fixed112x136 DEFAULT = new Fixed112x136(BigInteger.ZERO); + + public Fixed112x136(BigInteger value) { + super(112, 136, value); + } + + public Fixed112x136(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(112, 136, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x144.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x144.java new file mode 100644 index 0000000000..c36cfde3ae --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x144.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed112x144 extends Fixed { + public static final Fixed112x144 DEFAULT = new Fixed112x144(BigInteger.ZERO); + + public Fixed112x144(BigInteger value) { + super(112, 144, value); + } + + public Fixed112x144(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(112, 144, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x16.java new file mode 100644 index 0000000000..26ee46ad53 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed112x16 extends Fixed { + public static final Fixed112x16 DEFAULT = new Fixed112x16(BigInteger.ZERO); + + public Fixed112x16(BigInteger value) { + super(112, 16, value); + } + + public Fixed112x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(112, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x24.java new file mode 100644 index 0000000000..9ad6a1dff3 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed112x24 extends Fixed { + public static final Fixed112x24 DEFAULT = new Fixed112x24(BigInteger.ZERO); + + public Fixed112x24(BigInteger value) { + super(112, 24, value); + } + + public Fixed112x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(112, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x32.java new file mode 100644 index 0000000000..d068510d45 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed112x32 extends Fixed { + public static final Fixed112x32 DEFAULT = new Fixed112x32(BigInteger.ZERO); + + public Fixed112x32(BigInteger value) { + super(112, 32, value); + } + + public Fixed112x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(112, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x40.java new file mode 100644 index 0000000000..d9952b6898 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed112x40 extends Fixed { + public static final Fixed112x40 DEFAULT = new Fixed112x40(BigInteger.ZERO); + + public Fixed112x40(BigInteger value) { + super(112, 40, value); + } + + public Fixed112x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(112, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x48.java new file mode 100644 index 0000000000..ff0fc0dd22 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed112x48 extends Fixed { + public static final Fixed112x48 DEFAULT = new Fixed112x48(BigInteger.ZERO); + + public Fixed112x48(BigInteger value) { + super(112, 48, value); + } + + public Fixed112x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(112, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x56.java new file mode 100644 index 0000000000..d7981baee1 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x56.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed112x56 extends Fixed { + public static final Fixed112x56 DEFAULT = new Fixed112x56(BigInteger.ZERO); + + public Fixed112x56(BigInteger value) { + super(112, 56, value); + } + + public Fixed112x56(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(112, 56, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x64.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x64.java new file mode 100644 index 0000000000..0d15df9da5 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x64.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed112x64 extends Fixed { + public static final Fixed112x64 DEFAULT = new Fixed112x64(BigInteger.ZERO); + + public Fixed112x64(BigInteger value) { + super(112, 64, value); + } + + public Fixed112x64(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(112, 64, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x72.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x72.java new file mode 100644 index 0000000000..c1b9e73545 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x72.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed112x72 extends Fixed { + public static final Fixed112x72 DEFAULT = new Fixed112x72(BigInteger.ZERO); + + public Fixed112x72(BigInteger value) { + super(112, 72, value); + } + + public Fixed112x72(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(112, 72, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x8.java new file mode 100644 index 0000000000..512694dfb4 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed112x8 extends Fixed { + public static final Fixed112x8 DEFAULT = new Fixed112x8(BigInteger.ZERO); + + public Fixed112x8(BigInteger value) { + super(112, 8, value); + } + + public Fixed112x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(112, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x80.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x80.java new file mode 100644 index 0000000000..1ad6a1a823 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x80.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed112x80 extends Fixed { + public static final Fixed112x80 DEFAULT = new Fixed112x80(BigInteger.ZERO); + + public Fixed112x80(BigInteger value) { + super(112, 80, value); + } + + public Fixed112x80(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(112, 80, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x88.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x88.java new file mode 100644 index 0000000000..4b8a75d253 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x88.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed112x88 extends Fixed { + public static final Fixed112x88 DEFAULT = new Fixed112x88(BigInteger.ZERO); + + public Fixed112x88(BigInteger value) { + super(112, 88, value); + } + + public Fixed112x88(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(112, 88, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x96.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x96.java new file mode 100644 index 0000000000..20caf0d006 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed112x96.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed112x96 extends Fixed { + public static final Fixed112x96 DEFAULT = new Fixed112x96(BigInteger.ZERO); + + public Fixed112x96(BigInteger value) { + super(112, 96, value); + } + + public Fixed112x96(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(112, 96, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x104.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x104.java new file mode 100644 index 0000000000..58e95f41b1 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x104.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed120x104 extends Fixed { + public static final Fixed120x104 DEFAULT = new Fixed120x104(BigInteger.ZERO); + + public Fixed120x104(BigInteger value) { + super(120, 104, value); + } + + public Fixed120x104(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(120, 104, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x112.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x112.java new file mode 100644 index 0000000000..b6cb72b28c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x112.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed120x112 extends Fixed { + public static final Fixed120x112 DEFAULT = new Fixed120x112(BigInteger.ZERO); + + public Fixed120x112(BigInteger value) { + super(120, 112, value); + } + + public Fixed120x112(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(120, 112, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x120.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x120.java new file mode 100644 index 0000000000..94280513a4 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x120.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed120x120 extends Fixed { + public static final Fixed120x120 DEFAULT = new Fixed120x120(BigInteger.ZERO); + + public Fixed120x120(BigInteger value) { + super(120, 120, value); + } + + public Fixed120x120(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(120, 120, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x128.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x128.java new file mode 100644 index 0000000000..877329aa5c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x128.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed120x128 extends Fixed { + public static final Fixed120x128 DEFAULT = new Fixed120x128(BigInteger.ZERO); + + public Fixed120x128(BigInteger value) { + super(120, 128, value); + } + + public Fixed120x128(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(120, 128, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x136.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x136.java new file mode 100644 index 0000000000..690990e92f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x136.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed120x136 extends Fixed { + public static final Fixed120x136 DEFAULT = new Fixed120x136(BigInteger.ZERO); + + public Fixed120x136(BigInteger value) { + super(120, 136, value); + } + + public Fixed120x136(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(120, 136, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x16.java new file mode 100644 index 0000000000..249b024860 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed120x16 extends Fixed { + public static final Fixed120x16 DEFAULT = new Fixed120x16(BigInteger.ZERO); + + public Fixed120x16(BigInteger value) { + super(120, 16, value); + } + + public Fixed120x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(120, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x24.java new file mode 100644 index 0000000000..e304e5feba --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed120x24 extends Fixed { + public static final Fixed120x24 DEFAULT = new Fixed120x24(BigInteger.ZERO); + + public Fixed120x24(BigInteger value) { + super(120, 24, value); + } + + public Fixed120x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(120, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x32.java new file mode 100644 index 0000000000..e457e60335 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed120x32 extends Fixed { + public static final Fixed120x32 DEFAULT = new Fixed120x32(BigInteger.ZERO); + + public Fixed120x32(BigInteger value) { + super(120, 32, value); + } + + public Fixed120x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(120, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x40.java new file mode 100644 index 0000000000..609c566564 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed120x40 extends Fixed { + public static final Fixed120x40 DEFAULT = new Fixed120x40(BigInteger.ZERO); + + public Fixed120x40(BigInteger value) { + super(120, 40, value); + } + + public Fixed120x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(120, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x48.java new file mode 100644 index 0000000000..a3778f2e45 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed120x48 extends Fixed { + public static final Fixed120x48 DEFAULT = new Fixed120x48(BigInteger.ZERO); + + public Fixed120x48(BigInteger value) { + super(120, 48, value); + } + + public Fixed120x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(120, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x56.java new file mode 100644 index 0000000000..248f67af15 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x56.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed120x56 extends Fixed { + public static final Fixed120x56 DEFAULT = new Fixed120x56(BigInteger.ZERO); + + public Fixed120x56(BigInteger value) { + super(120, 56, value); + } + + public Fixed120x56(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(120, 56, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x64.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x64.java new file mode 100644 index 0000000000..a48df69346 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x64.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed120x64 extends Fixed { + public static final Fixed120x64 DEFAULT = new Fixed120x64(BigInteger.ZERO); + + public Fixed120x64(BigInteger value) { + super(120, 64, value); + } + + public Fixed120x64(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(120, 64, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x72.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x72.java new file mode 100644 index 0000000000..12100bc9b6 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x72.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed120x72 extends Fixed { + public static final Fixed120x72 DEFAULT = new Fixed120x72(BigInteger.ZERO); + + public Fixed120x72(BigInteger value) { + super(120, 72, value); + } + + public Fixed120x72(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(120, 72, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x8.java new file mode 100644 index 0000000000..61575d2cf7 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed120x8 extends Fixed { + public static final Fixed120x8 DEFAULT = new Fixed120x8(BigInteger.ZERO); + + public Fixed120x8(BigInteger value) { + super(120, 8, value); + } + + public Fixed120x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(120, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x80.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x80.java new file mode 100644 index 0000000000..e0b8cfd21b --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x80.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed120x80 extends Fixed { + public static final Fixed120x80 DEFAULT = new Fixed120x80(BigInteger.ZERO); + + public Fixed120x80(BigInteger value) { + super(120, 80, value); + } + + public Fixed120x80(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(120, 80, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x88.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x88.java new file mode 100644 index 0000000000..22debc2d3b --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x88.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed120x88 extends Fixed { + public static final Fixed120x88 DEFAULT = new Fixed120x88(BigInteger.ZERO); + + public Fixed120x88(BigInteger value) { + super(120, 88, value); + } + + public Fixed120x88(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(120, 88, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x96.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x96.java new file mode 100644 index 0000000000..2a273d5857 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed120x96.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed120x96 extends Fixed { + public static final Fixed120x96 DEFAULT = new Fixed120x96(BigInteger.ZERO); + + public Fixed120x96(BigInteger value) { + super(120, 96, value); + } + + public Fixed120x96(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(120, 96, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed128x104.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed128x104.java new file mode 100644 index 0000000000..41458a87db --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed128x104.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed128x104 extends Fixed { + public static final Fixed128x104 DEFAULT = new Fixed128x104(BigInteger.ZERO); + + public Fixed128x104(BigInteger value) { + super(128, 104, value); + } + + public Fixed128x104(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(128, 104, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed128x112.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed128x112.java new file mode 100644 index 0000000000..c449c80197 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed128x112.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed128x112 extends Fixed { + public static final Fixed128x112 DEFAULT = new Fixed128x112(BigInteger.ZERO); + + public Fixed128x112(BigInteger value) { + super(128, 112, value); + } + + public Fixed128x112(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(128, 112, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed128x120.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed128x120.java new file mode 100644 index 0000000000..1bd7496be6 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed128x120.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed128x120 extends Fixed { + public static final Fixed128x120 DEFAULT = new Fixed128x120(BigInteger.ZERO); + + public Fixed128x120(BigInteger value) { + super(128, 120, value); + } + + public Fixed128x120(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(128, 120, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed128x128.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed128x128.java new file mode 100644 index 0000000000..629f85d1ac --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed128x128.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed128x128 extends Fixed { + public static final Fixed128x128 DEFAULT = new Fixed128x128(BigInteger.ZERO); + + public Fixed128x128(BigInteger value) { + super(128, 128, value); + } + + public Fixed128x128(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(128, 128, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed128x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed128x16.java new file mode 100644 index 0000000000..7a2005f887 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed128x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed128x16 extends Fixed { + public static final Fixed128x16 DEFAULT = new Fixed128x16(BigInteger.ZERO); + + public Fixed128x16(BigInteger value) { + super(128, 16, value); + } + + public Fixed128x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(128, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed128x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed128x24.java new file mode 100644 index 0000000000..76c094d476 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed128x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed128x24 extends Fixed { + public static final Fixed128x24 DEFAULT = new Fixed128x24(BigInteger.ZERO); + + public Fixed128x24(BigInteger value) { + super(128, 24, value); + } + + public Fixed128x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(128, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed128x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed128x32.java new file mode 100644 index 0000000000..7573c72714 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed128x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed128x32 extends Fixed { + public static final Fixed128x32 DEFAULT = new Fixed128x32(BigInteger.ZERO); + + public Fixed128x32(BigInteger value) { + super(128, 32, value); + } + + public Fixed128x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(128, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed128x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed128x40.java new file mode 100644 index 0000000000..7855c7b316 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed128x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed128x40 extends Fixed { + public static final Fixed128x40 DEFAULT = new Fixed128x40(BigInteger.ZERO); + + public Fixed128x40(BigInteger value) { + super(128, 40, value); + } + + public Fixed128x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(128, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed128x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed128x48.java new file mode 100644 index 0000000000..ac42868e02 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed128x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed128x48 extends Fixed { + public static final Fixed128x48 DEFAULT = new Fixed128x48(BigInteger.ZERO); + + public Fixed128x48(BigInteger value) { + super(128, 48, value); + } + + public Fixed128x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(128, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed128x56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed128x56.java new file mode 100644 index 0000000000..9eb56c1774 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed128x56.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed128x56 extends Fixed { + public static final Fixed128x56 DEFAULT = new Fixed128x56(BigInteger.ZERO); + + public Fixed128x56(BigInteger value) { + super(128, 56, value); + } + + public Fixed128x56(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(128, 56, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed128x64.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed128x64.java new file mode 100644 index 0000000000..caeac4bda8 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed128x64.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed128x64 extends Fixed { + public static final Fixed128x64 DEFAULT = new Fixed128x64(BigInteger.ZERO); + + public Fixed128x64(BigInteger value) { + super(128, 64, value); + } + + public Fixed128x64(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(128, 64, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed128x72.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed128x72.java new file mode 100644 index 0000000000..cf90f223e8 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed128x72.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed128x72 extends Fixed { + public static final Fixed128x72 DEFAULT = new Fixed128x72(BigInteger.ZERO); + + public Fixed128x72(BigInteger value) { + super(128, 72, value); + } + + public Fixed128x72(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(128, 72, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed128x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed128x8.java new file mode 100644 index 0000000000..972434ed6c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed128x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed128x8 extends Fixed { + public static final Fixed128x8 DEFAULT = new Fixed128x8(BigInteger.ZERO); + + public Fixed128x8(BigInteger value) { + super(128, 8, value); + } + + public Fixed128x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(128, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed128x80.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed128x80.java new file mode 100644 index 0000000000..595b93c69c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed128x80.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed128x80 extends Fixed { + public static final Fixed128x80 DEFAULT = new Fixed128x80(BigInteger.ZERO); + + public Fixed128x80(BigInteger value) { + super(128, 80, value); + } + + public Fixed128x80(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(128, 80, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed128x88.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed128x88.java new file mode 100644 index 0000000000..74f3140c32 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed128x88.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed128x88 extends Fixed { + public static final Fixed128x88 DEFAULT = new Fixed128x88(BigInteger.ZERO); + + public Fixed128x88(BigInteger value) { + super(128, 88, value); + } + + public Fixed128x88(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(128, 88, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed128x96.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed128x96.java new file mode 100644 index 0000000000..e10bab49d2 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed128x96.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed128x96 extends Fixed { + public static final Fixed128x96 DEFAULT = new Fixed128x96(BigInteger.ZERO); + + public Fixed128x96(BigInteger value) { + super(128, 96, value); + } + + public Fixed128x96(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(128, 96, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed136x104.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed136x104.java new file mode 100644 index 0000000000..f99a0d34e9 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed136x104.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed136x104 extends Fixed { + public static final Fixed136x104 DEFAULT = new Fixed136x104(BigInteger.ZERO); + + public Fixed136x104(BigInteger value) { + super(136, 104, value); + } + + public Fixed136x104(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(136, 104, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed136x112.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed136x112.java new file mode 100644 index 0000000000..0ad826a184 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed136x112.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed136x112 extends Fixed { + public static final Fixed136x112 DEFAULT = new Fixed136x112(BigInteger.ZERO); + + public Fixed136x112(BigInteger value) { + super(136, 112, value); + } + + public Fixed136x112(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(136, 112, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed136x120.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed136x120.java new file mode 100644 index 0000000000..f0757974be --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed136x120.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed136x120 extends Fixed { + public static final Fixed136x120 DEFAULT = new Fixed136x120(BigInteger.ZERO); + + public Fixed136x120(BigInteger value) { + super(136, 120, value); + } + + public Fixed136x120(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(136, 120, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed136x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed136x16.java new file mode 100644 index 0000000000..6efc720eef --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed136x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed136x16 extends Fixed { + public static final Fixed136x16 DEFAULT = new Fixed136x16(BigInteger.ZERO); + + public Fixed136x16(BigInteger value) { + super(136, 16, value); + } + + public Fixed136x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(136, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed136x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed136x24.java new file mode 100644 index 0000000000..6ef30662b6 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed136x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed136x24 extends Fixed { + public static final Fixed136x24 DEFAULT = new Fixed136x24(BigInteger.ZERO); + + public Fixed136x24(BigInteger value) { + super(136, 24, value); + } + + public Fixed136x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(136, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed136x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed136x32.java new file mode 100644 index 0000000000..3db3e64904 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed136x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed136x32 extends Fixed { + public static final Fixed136x32 DEFAULT = new Fixed136x32(BigInteger.ZERO); + + public Fixed136x32(BigInteger value) { + super(136, 32, value); + } + + public Fixed136x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(136, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed136x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed136x40.java new file mode 100644 index 0000000000..3784a8b01e --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed136x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed136x40 extends Fixed { + public static final Fixed136x40 DEFAULT = new Fixed136x40(BigInteger.ZERO); + + public Fixed136x40(BigInteger value) { + super(136, 40, value); + } + + public Fixed136x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(136, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed136x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed136x48.java new file mode 100644 index 0000000000..412c65ece2 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed136x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed136x48 extends Fixed { + public static final Fixed136x48 DEFAULT = new Fixed136x48(BigInteger.ZERO); + + public Fixed136x48(BigInteger value) { + super(136, 48, value); + } + + public Fixed136x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(136, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed136x56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed136x56.java new file mode 100644 index 0000000000..540cff205b --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed136x56.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed136x56 extends Fixed { + public static final Fixed136x56 DEFAULT = new Fixed136x56(BigInteger.ZERO); + + public Fixed136x56(BigInteger value) { + super(136, 56, value); + } + + public Fixed136x56(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(136, 56, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed136x64.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed136x64.java new file mode 100644 index 0000000000..2d427a2634 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed136x64.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed136x64 extends Fixed { + public static final Fixed136x64 DEFAULT = new Fixed136x64(BigInteger.ZERO); + + public Fixed136x64(BigInteger value) { + super(136, 64, value); + } + + public Fixed136x64(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(136, 64, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed136x72.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed136x72.java new file mode 100644 index 0000000000..09e8e6b550 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed136x72.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed136x72 extends Fixed { + public static final Fixed136x72 DEFAULT = new Fixed136x72(BigInteger.ZERO); + + public Fixed136x72(BigInteger value) { + super(136, 72, value); + } + + public Fixed136x72(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(136, 72, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed136x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed136x8.java new file mode 100644 index 0000000000..8383f6c4ff --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed136x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed136x8 extends Fixed { + public static final Fixed136x8 DEFAULT = new Fixed136x8(BigInteger.ZERO); + + public Fixed136x8(BigInteger value) { + super(136, 8, value); + } + + public Fixed136x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(136, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed136x80.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed136x80.java new file mode 100644 index 0000000000..70220d36ce --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed136x80.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed136x80 extends Fixed { + public static final Fixed136x80 DEFAULT = new Fixed136x80(BigInteger.ZERO); + + public Fixed136x80(BigInteger value) { + super(136, 80, value); + } + + public Fixed136x80(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(136, 80, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed136x88.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed136x88.java new file mode 100644 index 0000000000..24e49d9357 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed136x88.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed136x88 extends Fixed { + public static final Fixed136x88 DEFAULT = new Fixed136x88(BigInteger.ZERO); + + public Fixed136x88(BigInteger value) { + super(136, 88, value); + } + + public Fixed136x88(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(136, 88, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed136x96.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed136x96.java new file mode 100644 index 0000000000..fdd56654ee --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed136x96.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed136x96 extends Fixed { + public static final Fixed136x96 DEFAULT = new Fixed136x96(BigInteger.ZERO); + + public Fixed136x96(BigInteger value) { + super(136, 96, value); + } + + public Fixed136x96(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(136, 96, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed144x104.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed144x104.java new file mode 100644 index 0000000000..37bb0e31ce --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed144x104.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed144x104 extends Fixed { + public static final Fixed144x104 DEFAULT = new Fixed144x104(BigInteger.ZERO); + + public Fixed144x104(BigInteger value) { + super(144, 104, value); + } + + public Fixed144x104(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(144, 104, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed144x112.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed144x112.java new file mode 100644 index 0000000000..5587282108 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed144x112.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed144x112 extends Fixed { + public static final Fixed144x112 DEFAULT = new Fixed144x112(BigInteger.ZERO); + + public Fixed144x112(BigInteger value) { + super(144, 112, value); + } + + public Fixed144x112(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(144, 112, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed144x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed144x16.java new file mode 100644 index 0000000000..5aabe765ed --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed144x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed144x16 extends Fixed { + public static final Fixed144x16 DEFAULT = new Fixed144x16(BigInteger.ZERO); + + public Fixed144x16(BigInteger value) { + super(144, 16, value); + } + + public Fixed144x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(144, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed144x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed144x24.java new file mode 100644 index 0000000000..ff0dc8295f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed144x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed144x24 extends Fixed { + public static final Fixed144x24 DEFAULT = new Fixed144x24(BigInteger.ZERO); + + public Fixed144x24(BigInteger value) { + super(144, 24, value); + } + + public Fixed144x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(144, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed144x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed144x32.java new file mode 100644 index 0000000000..97f2cfc97c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed144x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed144x32 extends Fixed { + public static final Fixed144x32 DEFAULT = new Fixed144x32(BigInteger.ZERO); + + public Fixed144x32(BigInteger value) { + super(144, 32, value); + } + + public Fixed144x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(144, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed144x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed144x40.java new file mode 100644 index 0000000000..7092de89cc --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed144x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed144x40 extends Fixed { + public static final Fixed144x40 DEFAULT = new Fixed144x40(BigInteger.ZERO); + + public Fixed144x40(BigInteger value) { + super(144, 40, value); + } + + public Fixed144x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(144, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed144x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed144x48.java new file mode 100644 index 0000000000..c8fb8aeefd --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed144x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed144x48 extends Fixed { + public static final Fixed144x48 DEFAULT = new Fixed144x48(BigInteger.ZERO); + + public Fixed144x48(BigInteger value) { + super(144, 48, value); + } + + public Fixed144x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(144, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed144x56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed144x56.java new file mode 100644 index 0000000000..1a1887f5ed --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed144x56.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed144x56 extends Fixed { + public static final Fixed144x56 DEFAULT = new Fixed144x56(BigInteger.ZERO); + + public Fixed144x56(BigInteger value) { + super(144, 56, value); + } + + public Fixed144x56(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(144, 56, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed144x64.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed144x64.java new file mode 100644 index 0000000000..776260adb0 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed144x64.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed144x64 extends Fixed { + public static final Fixed144x64 DEFAULT = new Fixed144x64(BigInteger.ZERO); + + public Fixed144x64(BigInteger value) { + super(144, 64, value); + } + + public Fixed144x64(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(144, 64, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed144x72.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed144x72.java new file mode 100644 index 0000000000..44be8dfba5 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed144x72.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed144x72 extends Fixed { + public static final Fixed144x72 DEFAULT = new Fixed144x72(BigInteger.ZERO); + + public Fixed144x72(BigInteger value) { + super(144, 72, value); + } + + public Fixed144x72(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(144, 72, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed144x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed144x8.java new file mode 100644 index 0000000000..dcc5c43c67 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed144x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed144x8 extends Fixed { + public static final Fixed144x8 DEFAULT = new Fixed144x8(BigInteger.ZERO); + + public Fixed144x8(BigInteger value) { + super(144, 8, value); + } + + public Fixed144x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(144, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed144x80.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed144x80.java new file mode 100644 index 0000000000..a5d603bca2 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed144x80.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed144x80 extends Fixed { + public static final Fixed144x80 DEFAULT = new Fixed144x80(BigInteger.ZERO); + + public Fixed144x80(BigInteger value) { + super(144, 80, value); + } + + public Fixed144x80(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(144, 80, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed144x88.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed144x88.java new file mode 100644 index 0000000000..cba2037ea8 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed144x88.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed144x88 extends Fixed { + public static final Fixed144x88 DEFAULT = new Fixed144x88(BigInteger.ZERO); + + public Fixed144x88(BigInteger value) { + super(144, 88, value); + } + + public Fixed144x88(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(144, 88, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed144x96.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed144x96.java new file mode 100644 index 0000000000..205efeb146 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed144x96.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed144x96 extends Fixed { + public static final Fixed144x96 DEFAULT = new Fixed144x96(BigInteger.ZERO); + + public Fixed144x96(BigInteger value) { + super(144, 96, value); + } + + public Fixed144x96(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(144, 96, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed152x104.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed152x104.java new file mode 100644 index 0000000000..e77c6e6dfe --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed152x104.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed152x104 extends Fixed { + public static final Fixed152x104 DEFAULT = new Fixed152x104(BigInteger.ZERO); + + public Fixed152x104(BigInteger value) { + super(152, 104, value); + } + + public Fixed152x104(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(152, 104, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed152x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed152x16.java new file mode 100644 index 0000000000..bdb701a0e1 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed152x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed152x16 extends Fixed { + public static final Fixed152x16 DEFAULT = new Fixed152x16(BigInteger.ZERO); + + public Fixed152x16(BigInteger value) { + super(152, 16, value); + } + + public Fixed152x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(152, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed152x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed152x24.java new file mode 100644 index 0000000000..beb481b39b --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed152x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed152x24 extends Fixed { + public static final Fixed152x24 DEFAULT = new Fixed152x24(BigInteger.ZERO); + + public Fixed152x24(BigInteger value) { + super(152, 24, value); + } + + public Fixed152x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(152, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed152x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed152x32.java new file mode 100644 index 0000000000..5cf2ab4d55 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed152x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed152x32 extends Fixed { + public static final Fixed152x32 DEFAULT = new Fixed152x32(BigInteger.ZERO); + + public Fixed152x32(BigInteger value) { + super(152, 32, value); + } + + public Fixed152x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(152, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed152x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed152x40.java new file mode 100644 index 0000000000..0d9168b89d --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed152x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed152x40 extends Fixed { + public static final Fixed152x40 DEFAULT = new Fixed152x40(BigInteger.ZERO); + + public Fixed152x40(BigInteger value) { + super(152, 40, value); + } + + public Fixed152x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(152, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed152x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed152x48.java new file mode 100644 index 0000000000..6f4e638193 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed152x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed152x48 extends Fixed { + public static final Fixed152x48 DEFAULT = new Fixed152x48(BigInteger.ZERO); + + public Fixed152x48(BigInteger value) { + super(152, 48, value); + } + + public Fixed152x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(152, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed152x56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed152x56.java new file mode 100644 index 0000000000..4791e00799 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed152x56.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed152x56 extends Fixed { + public static final Fixed152x56 DEFAULT = new Fixed152x56(BigInteger.ZERO); + + public Fixed152x56(BigInteger value) { + super(152, 56, value); + } + + public Fixed152x56(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(152, 56, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed152x64.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed152x64.java new file mode 100644 index 0000000000..1fe7e03fed --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed152x64.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed152x64 extends Fixed { + public static final Fixed152x64 DEFAULT = new Fixed152x64(BigInteger.ZERO); + + public Fixed152x64(BigInteger value) { + super(152, 64, value); + } + + public Fixed152x64(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(152, 64, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed152x72.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed152x72.java new file mode 100644 index 0000000000..b6142c3503 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed152x72.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed152x72 extends Fixed { + public static final Fixed152x72 DEFAULT = new Fixed152x72(BigInteger.ZERO); + + public Fixed152x72(BigInteger value) { + super(152, 72, value); + } + + public Fixed152x72(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(152, 72, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed152x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed152x8.java new file mode 100644 index 0000000000..b65be4b1a8 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed152x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed152x8 extends Fixed { + public static final Fixed152x8 DEFAULT = new Fixed152x8(BigInteger.ZERO); + + public Fixed152x8(BigInteger value) { + super(152, 8, value); + } + + public Fixed152x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(152, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed152x80.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed152x80.java new file mode 100644 index 0000000000..4c20d0037c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed152x80.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed152x80 extends Fixed { + public static final Fixed152x80 DEFAULT = new Fixed152x80(BigInteger.ZERO); + + public Fixed152x80(BigInteger value) { + super(152, 80, value); + } + + public Fixed152x80(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(152, 80, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed152x88.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed152x88.java new file mode 100644 index 0000000000..b386df5bae --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed152x88.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed152x88 extends Fixed { + public static final Fixed152x88 DEFAULT = new Fixed152x88(BigInteger.ZERO); + + public Fixed152x88(BigInteger value) { + super(152, 88, value); + } + + public Fixed152x88(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(152, 88, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed152x96.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed152x96.java new file mode 100644 index 0000000000..422dc87338 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed152x96.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed152x96 extends Fixed { + public static final Fixed152x96 DEFAULT = new Fixed152x96(BigInteger.ZERO); + + public Fixed152x96(BigInteger value) { + super(152, 96, value); + } + + public Fixed152x96(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(152, 96, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed160x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed160x16.java new file mode 100644 index 0000000000..6405b4bb44 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed160x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed160x16 extends Fixed { + public static final Fixed160x16 DEFAULT = new Fixed160x16(BigInteger.ZERO); + + public Fixed160x16(BigInteger value) { + super(160, 16, value); + } + + public Fixed160x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(160, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed160x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed160x24.java new file mode 100644 index 0000000000..6dd0c84b7f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed160x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed160x24 extends Fixed { + public static final Fixed160x24 DEFAULT = new Fixed160x24(BigInteger.ZERO); + + public Fixed160x24(BigInteger value) { + super(160, 24, value); + } + + public Fixed160x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(160, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed160x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed160x32.java new file mode 100644 index 0000000000..4d47aa3fe3 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed160x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed160x32 extends Fixed { + public static final Fixed160x32 DEFAULT = new Fixed160x32(BigInteger.ZERO); + + public Fixed160x32(BigInteger value) { + super(160, 32, value); + } + + public Fixed160x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(160, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed160x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed160x40.java new file mode 100644 index 0000000000..e1739419f4 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed160x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed160x40 extends Fixed { + public static final Fixed160x40 DEFAULT = new Fixed160x40(BigInteger.ZERO); + + public Fixed160x40(BigInteger value) { + super(160, 40, value); + } + + public Fixed160x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(160, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed160x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed160x48.java new file mode 100644 index 0000000000..aa1ba14746 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed160x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed160x48 extends Fixed { + public static final Fixed160x48 DEFAULT = new Fixed160x48(BigInteger.ZERO); + + public Fixed160x48(BigInteger value) { + super(160, 48, value); + } + + public Fixed160x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(160, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed160x56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed160x56.java new file mode 100644 index 0000000000..f358dd8472 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed160x56.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed160x56 extends Fixed { + public static final Fixed160x56 DEFAULT = new Fixed160x56(BigInteger.ZERO); + + public Fixed160x56(BigInteger value) { + super(160, 56, value); + } + + public Fixed160x56(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(160, 56, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed160x64.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed160x64.java new file mode 100644 index 0000000000..41fde85895 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed160x64.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed160x64 extends Fixed { + public static final Fixed160x64 DEFAULT = new Fixed160x64(BigInteger.ZERO); + + public Fixed160x64(BigInteger value) { + super(160, 64, value); + } + + public Fixed160x64(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(160, 64, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed160x72.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed160x72.java new file mode 100644 index 0000000000..2807ba7a81 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed160x72.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed160x72 extends Fixed { + public static final Fixed160x72 DEFAULT = new Fixed160x72(BigInteger.ZERO); + + public Fixed160x72(BigInteger value) { + super(160, 72, value); + } + + public Fixed160x72(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(160, 72, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed160x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed160x8.java new file mode 100644 index 0000000000..48dadb3a15 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed160x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed160x8 extends Fixed { + public static final Fixed160x8 DEFAULT = new Fixed160x8(BigInteger.ZERO); + + public Fixed160x8(BigInteger value) { + super(160, 8, value); + } + + public Fixed160x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(160, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed160x80.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed160x80.java new file mode 100644 index 0000000000..6daf0cc092 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed160x80.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed160x80 extends Fixed { + public static final Fixed160x80 DEFAULT = new Fixed160x80(BigInteger.ZERO); + + public Fixed160x80(BigInteger value) { + super(160, 80, value); + } + + public Fixed160x80(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(160, 80, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed160x88.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed160x88.java new file mode 100644 index 0000000000..bd5c786c2a --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed160x88.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed160x88 extends Fixed { + public static final Fixed160x88 DEFAULT = new Fixed160x88(BigInteger.ZERO); + + public Fixed160x88(BigInteger value) { + super(160, 88, value); + } + + public Fixed160x88(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(160, 88, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed160x96.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed160x96.java new file mode 100644 index 0000000000..937be34023 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed160x96.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed160x96 extends Fixed { + public static final Fixed160x96 DEFAULT = new Fixed160x96(BigInteger.ZERO); + + public Fixed160x96(BigInteger value) { + super(160, 96, value); + } + + public Fixed160x96(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(160, 96, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed168x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed168x16.java new file mode 100644 index 0000000000..19be4cec67 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed168x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed168x16 extends Fixed { + public static final Fixed168x16 DEFAULT = new Fixed168x16(BigInteger.ZERO); + + public Fixed168x16(BigInteger value) { + super(168, 16, value); + } + + public Fixed168x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(168, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed168x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed168x24.java new file mode 100644 index 0000000000..834a324ede --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed168x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed168x24 extends Fixed { + public static final Fixed168x24 DEFAULT = new Fixed168x24(BigInteger.ZERO); + + public Fixed168x24(BigInteger value) { + super(168, 24, value); + } + + public Fixed168x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(168, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed168x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed168x32.java new file mode 100644 index 0000000000..0934739418 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed168x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed168x32 extends Fixed { + public static final Fixed168x32 DEFAULT = new Fixed168x32(BigInteger.ZERO); + + public Fixed168x32(BigInteger value) { + super(168, 32, value); + } + + public Fixed168x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(168, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed168x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed168x40.java new file mode 100644 index 0000000000..d5bbf71928 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed168x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed168x40 extends Fixed { + public static final Fixed168x40 DEFAULT = new Fixed168x40(BigInteger.ZERO); + + public Fixed168x40(BigInteger value) { + super(168, 40, value); + } + + public Fixed168x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(168, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed168x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed168x48.java new file mode 100644 index 0000000000..2cf8e990f4 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed168x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed168x48 extends Fixed { + public static final Fixed168x48 DEFAULT = new Fixed168x48(BigInteger.ZERO); + + public Fixed168x48(BigInteger value) { + super(168, 48, value); + } + + public Fixed168x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(168, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed168x56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed168x56.java new file mode 100644 index 0000000000..d20c771d2a --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed168x56.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed168x56 extends Fixed { + public static final Fixed168x56 DEFAULT = new Fixed168x56(BigInteger.ZERO); + + public Fixed168x56(BigInteger value) { + super(168, 56, value); + } + + public Fixed168x56(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(168, 56, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed168x64.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed168x64.java new file mode 100644 index 0000000000..2329287e81 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed168x64.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed168x64 extends Fixed { + public static final Fixed168x64 DEFAULT = new Fixed168x64(BigInteger.ZERO); + + public Fixed168x64(BigInteger value) { + super(168, 64, value); + } + + public Fixed168x64(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(168, 64, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed168x72.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed168x72.java new file mode 100644 index 0000000000..fa30744822 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed168x72.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed168x72 extends Fixed { + public static final Fixed168x72 DEFAULT = new Fixed168x72(BigInteger.ZERO); + + public Fixed168x72(BigInteger value) { + super(168, 72, value); + } + + public Fixed168x72(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(168, 72, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed168x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed168x8.java new file mode 100644 index 0000000000..79de04471f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed168x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed168x8 extends Fixed { + public static final Fixed168x8 DEFAULT = new Fixed168x8(BigInteger.ZERO); + + public Fixed168x8(BigInteger value) { + super(168, 8, value); + } + + public Fixed168x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(168, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed168x80.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed168x80.java new file mode 100644 index 0000000000..fbbfdc8155 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed168x80.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed168x80 extends Fixed { + public static final Fixed168x80 DEFAULT = new Fixed168x80(BigInteger.ZERO); + + public Fixed168x80(BigInteger value) { + super(168, 80, value); + } + + public Fixed168x80(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(168, 80, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed168x88.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed168x88.java new file mode 100644 index 0000000000..cb0b28b109 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed168x88.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed168x88 extends Fixed { + public static final Fixed168x88 DEFAULT = new Fixed168x88(BigInteger.ZERO); + + public Fixed168x88(BigInteger value) { + super(168, 88, value); + } + + public Fixed168x88(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(168, 88, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x104.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x104.java new file mode 100644 index 0000000000..9ad2783430 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x104.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed16x104 extends Fixed { + public static final Fixed16x104 DEFAULT = new Fixed16x104(BigInteger.ZERO); + + public Fixed16x104(BigInteger value) { + super(16, 104, value); + } + + public Fixed16x104(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 104, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x112.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x112.java new file mode 100644 index 0000000000..b457701e43 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x112.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed16x112 extends Fixed { + public static final Fixed16x112 DEFAULT = new Fixed16x112(BigInteger.ZERO); + + public Fixed16x112(BigInteger value) { + super(16, 112, value); + } + + public Fixed16x112(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 112, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x120.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x120.java new file mode 100644 index 0000000000..235a523048 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x120.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed16x120 extends Fixed { + public static final Fixed16x120 DEFAULT = new Fixed16x120(BigInteger.ZERO); + + public Fixed16x120(BigInteger value) { + super(16, 120, value); + } + + public Fixed16x120(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 120, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x128.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x128.java new file mode 100644 index 0000000000..f44e195b5b --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x128.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed16x128 extends Fixed { + public static final Fixed16x128 DEFAULT = new Fixed16x128(BigInteger.ZERO); + + public Fixed16x128(BigInteger value) { + super(16, 128, value); + } + + public Fixed16x128(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 128, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x136.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x136.java new file mode 100644 index 0000000000..715b628dda --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x136.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed16x136 extends Fixed { + public static final Fixed16x136 DEFAULT = new Fixed16x136(BigInteger.ZERO); + + public Fixed16x136(BigInteger value) { + super(16, 136, value); + } + + public Fixed16x136(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 136, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x144.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x144.java new file mode 100644 index 0000000000..b409d427ff --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x144.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed16x144 extends Fixed { + public static final Fixed16x144 DEFAULT = new Fixed16x144(BigInteger.ZERO); + + public Fixed16x144(BigInteger value) { + super(16, 144, value); + } + + public Fixed16x144(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 144, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x152.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x152.java new file mode 100644 index 0000000000..4d24836563 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x152.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed16x152 extends Fixed { + public static final Fixed16x152 DEFAULT = new Fixed16x152(BigInteger.ZERO); + + public Fixed16x152(BigInteger value) { + super(16, 152, value); + } + + public Fixed16x152(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 152, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x16.java new file mode 100644 index 0000000000..434fc93f56 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed16x16 extends Fixed { + public static final Fixed16x16 DEFAULT = new Fixed16x16(BigInteger.ZERO); + + public Fixed16x16(BigInteger value) { + super(16, 16, value); + } + + public Fixed16x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x160.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x160.java new file mode 100644 index 0000000000..5005af6919 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x160.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed16x160 extends Fixed { + public static final Fixed16x160 DEFAULT = new Fixed16x160(BigInteger.ZERO); + + public Fixed16x160(BigInteger value) { + super(16, 160, value); + } + + public Fixed16x160(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 160, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x168.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x168.java new file mode 100644 index 0000000000..158824df17 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x168.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed16x168 extends Fixed { + public static final Fixed16x168 DEFAULT = new Fixed16x168(BigInteger.ZERO); + + public Fixed16x168(BigInteger value) { + super(16, 168, value); + } + + public Fixed16x168(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 168, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x176.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x176.java new file mode 100644 index 0000000000..8e1fa93fd7 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x176.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed16x176 extends Fixed { + public static final Fixed16x176 DEFAULT = new Fixed16x176(BigInteger.ZERO); + + public Fixed16x176(BigInteger value) { + super(16, 176, value); + } + + public Fixed16x176(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 176, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x184.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x184.java new file mode 100644 index 0000000000..27491c9e6b --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x184.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed16x184 extends Fixed { + public static final Fixed16x184 DEFAULT = new Fixed16x184(BigInteger.ZERO); + + public Fixed16x184(BigInteger value) { + super(16, 184, value); + } + + public Fixed16x184(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 184, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x192.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x192.java new file mode 100644 index 0000000000..d493797b57 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x192.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed16x192 extends Fixed { + public static final Fixed16x192 DEFAULT = new Fixed16x192(BigInteger.ZERO); + + public Fixed16x192(BigInteger value) { + super(16, 192, value); + } + + public Fixed16x192(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 192, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x200.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x200.java new file mode 100644 index 0000000000..881f04f4d9 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x200.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed16x200 extends Fixed { + public static final Fixed16x200 DEFAULT = new Fixed16x200(BigInteger.ZERO); + + public Fixed16x200(BigInteger value) { + super(16, 200, value); + } + + public Fixed16x200(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 200, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x208.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x208.java new file mode 100644 index 0000000000..003030b33d --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x208.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed16x208 extends Fixed { + public static final Fixed16x208 DEFAULT = new Fixed16x208(BigInteger.ZERO); + + public Fixed16x208(BigInteger value) { + super(16, 208, value); + } + + public Fixed16x208(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 208, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x216.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x216.java new file mode 100644 index 0000000000..3b1e2f53cf --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x216.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed16x216 extends Fixed { + public static final Fixed16x216 DEFAULT = new Fixed16x216(BigInteger.ZERO); + + public Fixed16x216(BigInteger value) { + super(16, 216, value); + } + + public Fixed16x216(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 216, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x224.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x224.java new file mode 100644 index 0000000000..938828ece1 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x224.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed16x224 extends Fixed { + public static final Fixed16x224 DEFAULT = new Fixed16x224(BigInteger.ZERO); + + public Fixed16x224(BigInteger value) { + super(16, 224, value); + } + + public Fixed16x224(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 224, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x232.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x232.java new file mode 100644 index 0000000000..83f501ec2f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x232.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed16x232 extends Fixed { + public static final Fixed16x232 DEFAULT = new Fixed16x232(BigInteger.ZERO); + + public Fixed16x232(BigInteger value) { + super(16, 232, value); + } + + public Fixed16x232(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 232, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x24.java new file mode 100644 index 0000000000..3ba7169c12 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed16x24 extends Fixed { + public static final Fixed16x24 DEFAULT = new Fixed16x24(BigInteger.ZERO); + + public Fixed16x24(BigInteger value) { + super(16, 24, value); + } + + public Fixed16x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x240.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x240.java new file mode 100644 index 0000000000..b88c5a25de --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x240.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed16x240 extends Fixed { + public static final Fixed16x240 DEFAULT = new Fixed16x240(BigInteger.ZERO); + + public Fixed16x240(BigInteger value) { + super(16, 240, value); + } + + public Fixed16x240(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 240, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x32.java new file mode 100644 index 0000000000..7bb7824380 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed16x32 extends Fixed { + public static final Fixed16x32 DEFAULT = new Fixed16x32(BigInteger.ZERO); + + public Fixed16x32(BigInteger value) { + super(16, 32, value); + } + + public Fixed16x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x40.java new file mode 100644 index 0000000000..0b315ded54 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed16x40 extends Fixed { + public static final Fixed16x40 DEFAULT = new Fixed16x40(BigInteger.ZERO); + + public Fixed16x40(BigInteger value) { + super(16, 40, value); + } + + public Fixed16x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x48.java new file mode 100644 index 0000000000..8728c9789e --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed16x48 extends Fixed { + public static final Fixed16x48 DEFAULT = new Fixed16x48(BigInteger.ZERO); + + public Fixed16x48(BigInteger value) { + super(16, 48, value); + } + + public Fixed16x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x56.java new file mode 100644 index 0000000000..0439d6c2d8 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x56.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed16x56 extends Fixed { + public static final Fixed16x56 DEFAULT = new Fixed16x56(BigInteger.ZERO); + + public Fixed16x56(BigInteger value) { + super(16, 56, value); + } + + public Fixed16x56(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 56, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x64.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x64.java new file mode 100644 index 0000000000..2710b2a6fe --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x64.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed16x64 extends Fixed { + public static final Fixed16x64 DEFAULT = new Fixed16x64(BigInteger.ZERO); + + public Fixed16x64(BigInteger value) { + super(16, 64, value); + } + + public Fixed16x64(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 64, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x72.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x72.java new file mode 100644 index 0000000000..7ac21506db --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x72.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed16x72 extends Fixed { + public static final Fixed16x72 DEFAULT = new Fixed16x72(BigInteger.ZERO); + + public Fixed16x72(BigInteger value) { + super(16, 72, value); + } + + public Fixed16x72(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 72, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x8.java new file mode 100644 index 0000000000..fa937ada4e --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed16x8 extends Fixed { + public static final Fixed16x8 DEFAULT = new Fixed16x8(BigInteger.ZERO); + + public Fixed16x8(BigInteger value) { + super(16, 8, value); + } + + public Fixed16x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x80.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x80.java new file mode 100644 index 0000000000..318f59185c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x80.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed16x80 extends Fixed { + public static final Fixed16x80 DEFAULT = new Fixed16x80(BigInteger.ZERO); + + public Fixed16x80(BigInteger value) { + super(16, 80, value); + } + + public Fixed16x80(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 80, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x88.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x88.java new file mode 100644 index 0000000000..9b730ac820 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x88.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed16x88 extends Fixed { + public static final Fixed16x88 DEFAULT = new Fixed16x88(BigInteger.ZERO); + + public Fixed16x88(BigInteger value) { + super(16, 88, value); + } + + public Fixed16x88(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 88, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x96.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x96.java new file mode 100644 index 0000000000..a2c4145752 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed16x96.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed16x96 extends Fixed { + public static final Fixed16x96 DEFAULT = new Fixed16x96(BigInteger.ZERO); + + public Fixed16x96(BigInteger value) { + super(16, 96, value); + } + + public Fixed16x96(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 96, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed176x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed176x16.java new file mode 100644 index 0000000000..07487cb61d --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed176x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed176x16 extends Fixed { + public static final Fixed176x16 DEFAULT = new Fixed176x16(BigInteger.ZERO); + + public Fixed176x16(BigInteger value) { + super(176, 16, value); + } + + public Fixed176x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(176, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed176x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed176x24.java new file mode 100644 index 0000000000..facda87f88 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed176x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed176x24 extends Fixed { + public static final Fixed176x24 DEFAULT = new Fixed176x24(BigInteger.ZERO); + + public Fixed176x24(BigInteger value) { + super(176, 24, value); + } + + public Fixed176x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(176, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed176x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed176x32.java new file mode 100644 index 0000000000..1e64db0a61 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed176x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed176x32 extends Fixed { + public static final Fixed176x32 DEFAULT = new Fixed176x32(BigInteger.ZERO); + + public Fixed176x32(BigInteger value) { + super(176, 32, value); + } + + public Fixed176x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(176, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed176x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed176x40.java new file mode 100644 index 0000000000..1f3e51c342 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed176x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed176x40 extends Fixed { + public static final Fixed176x40 DEFAULT = new Fixed176x40(BigInteger.ZERO); + + public Fixed176x40(BigInteger value) { + super(176, 40, value); + } + + public Fixed176x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(176, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed176x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed176x48.java new file mode 100644 index 0000000000..c49430838d --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed176x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed176x48 extends Fixed { + public static final Fixed176x48 DEFAULT = new Fixed176x48(BigInteger.ZERO); + + public Fixed176x48(BigInteger value) { + super(176, 48, value); + } + + public Fixed176x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(176, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed176x56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed176x56.java new file mode 100644 index 0000000000..a1ee8e57fe --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed176x56.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed176x56 extends Fixed { + public static final Fixed176x56 DEFAULT = new Fixed176x56(BigInteger.ZERO); + + public Fixed176x56(BigInteger value) { + super(176, 56, value); + } + + public Fixed176x56(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(176, 56, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed176x64.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed176x64.java new file mode 100644 index 0000000000..89d50d9eee --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed176x64.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed176x64 extends Fixed { + public static final Fixed176x64 DEFAULT = new Fixed176x64(BigInteger.ZERO); + + public Fixed176x64(BigInteger value) { + super(176, 64, value); + } + + public Fixed176x64(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(176, 64, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed176x72.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed176x72.java new file mode 100644 index 0000000000..eda8a6fde5 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed176x72.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed176x72 extends Fixed { + public static final Fixed176x72 DEFAULT = new Fixed176x72(BigInteger.ZERO); + + public Fixed176x72(BigInteger value) { + super(176, 72, value); + } + + public Fixed176x72(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(176, 72, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed176x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed176x8.java new file mode 100644 index 0000000000..6186ae1bf6 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed176x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed176x8 extends Fixed { + public static final Fixed176x8 DEFAULT = new Fixed176x8(BigInteger.ZERO); + + public Fixed176x8(BigInteger value) { + super(176, 8, value); + } + + public Fixed176x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(176, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed176x80.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed176x80.java new file mode 100644 index 0000000000..9c505348ee --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed176x80.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed176x80 extends Fixed { + public static final Fixed176x80 DEFAULT = new Fixed176x80(BigInteger.ZERO); + + public Fixed176x80(BigInteger value) { + super(176, 80, value); + } + + public Fixed176x80(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(176, 80, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed184x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed184x16.java new file mode 100644 index 0000000000..d783dd7f57 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed184x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed184x16 extends Fixed { + public static final Fixed184x16 DEFAULT = new Fixed184x16(BigInteger.ZERO); + + public Fixed184x16(BigInteger value) { + super(184, 16, value); + } + + public Fixed184x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(184, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed184x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed184x24.java new file mode 100644 index 0000000000..f62f22f976 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed184x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed184x24 extends Fixed { + public static final Fixed184x24 DEFAULT = new Fixed184x24(BigInteger.ZERO); + + public Fixed184x24(BigInteger value) { + super(184, 24, value); + } + + public Fixed184x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(184, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed184x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed184x32.java new file mode 100644 index 0000000000..268bf8e8e2 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed184x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed184x32 extends Fixed { + public static final Fixed184x32 DEFAULT = new Fixed184x32(BigInteger.ZERO); + + public Fixed184x32(BigInteger value) { + super(184, 32, value); + } + + public Fixed184x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(184, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed184x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed184x40.java new file mode 100644 index 0000000000..bfa185549c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed184x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed184x40 extends Fixed { + public static final Fixed184x40 DEFAULT = new Fixed184x40(BigInteger.ZERO); + + public Fixed184x40(BigInteger value) { + super(184, 40, value); + } + + public Fixed184x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(184, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed184x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed184x48.java new file mode 100644 index 0000000000..6f6fcee169 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed184x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed184x48 extends Fixed { + public static final Fixed184x48 DEFAULT = new Fixed184x48(BigInteger.ZERO); + + public Fixed184x48(BigInteger value) { + super(184, 48, value); + } + + public Fixed184x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(184, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed184x56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed184x56.java new file mode 100644 index 0000000000..114238c45a --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed184x56.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed184x56 extends Fixed { + public static final Fixed184x56 DEFAULT = new Fixed184x56(BigInteger.ZERO); + + public Fixed184x56(BigInteger value) { + super(184, 56, value); + } + + public Fixed184x56(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(184, 56, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed184x64.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed184x64.java new file mode 100644 index 0000000000..8debd0cd8a --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed184x64.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed184x64 extends Fixed { + public static final Fixed184x64 DEFAULT = new Fixed184x64(BigInteger.ZERO); + + public Fixed184x64(BigInteger value) { + super(184, 64, value); + } + + public Fixed184x64(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(184, 64, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed184x72.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed184x72.java new file mode 100644 index 0000000000..cc8f68a242 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed184x72.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed184x72 extends Fixed { + public static final Fixed184x72 DEFAULT = new Fixed184x72(BigInteger.ZERO); + + public Fixed184x72(BigInteger value) { + super(184, 72, value); + } + + public Fixed184x72(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(184, 72, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed184x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed184x8.java new file mode 100644 index 0000000000..c0977749e5 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed184x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed184x8 extends Fixed { + public static final Fixed184x8 DEFAULT = new Fixed184x8(BigInteger.ZERO); + + public Fixed184x8(BigInteger value) { + super(184, 8, value); + } + + public Fixed184x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(184, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed192x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed192x16.java new file mode 100644 index 0000000000..d8057594e0 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed192x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed192x16 extends Fixed { + public static final Fixed192x16 DEFAULT = new Fixed192x16(BigInteger.ZERO); + + public Fixed192x16(BigInteger value) { + super(192, 16, value); + } + + public Fixed192x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(192, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed192x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed192x24.java new file mode 100644 index 0000000000..09dfc31daa --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed192x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed192x24 extends Fixed { + public static final Fixed192x24 DEFAULT = new Fixed192x24(BigInteger.ZERO); + + public Fixed192x24(BigInteger value) { + super(192, 24, value); + } + + public Fixed192x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(192, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed192x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed192x32.java new file mode 100644 index 0000000000..4ba2807a62 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed192x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed192x32 extends Fixed { + public static final Fixed192x32 DEFAULT = new Fixed192x32(BigInteger.ZERO); + + public Fixed192x32(BigInteger value) { + super(192, 32, value); + } + + public Fixed192x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(192, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed192x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed192x40.java new file mode 100644 index 0000000000..2d7c73b56c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed192x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed192x40 extends Fixed { + public static final Fixed192x40 DEFAULT = new Fixed192x40(BigInteger.ZERO); + + public Fixed192x40(BigInteger value) { + super(192, 40, value); + } + + public Fixed192x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(192, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed192x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed192x48.java new file mode 100644 index 0000000000..5bd21fabf7 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed192x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed192x48 extends Fixed { + public static final Fixed192x48 DEFAULT = new Fixed192x48(BigInteger.ZERO); + + public Fixed192x48(BigInteger value) { + super(192, 48, value); + } + + public Fixed192x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(192, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed192x56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed192x56.java new file mode 100644 index 0000000000..70c0f4c69c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed192x56.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed192x56 extends Fixed { + public static final Fixed192x56 DEFAULT = new Fixed192x56(BigInteger.ZERO); + + public Fixed192x56(BigInteger value) { + super(192, 56, value); + } + + public Fixed192x56(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(192, 56, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed192x64.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed192x64.java new file mode 100644 index 0000000000..70b8070576 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed192x64.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed192x64 extends Fixed { + public static final Fixed192x64 DEFAULT = new Fixed192x64(BigInteger.ZERO); + + public Fixed192x64(BigInteger value) { + super(192, 64, value); + } + + public Fixed192x64(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(192, 64, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed192x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed192x8.java new file mode 100644 index 0000000000..2816ee7ccd --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed192x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed192x8 extends Fixed { + public static final Fixed192x8 DEFAULT = new Fixed192x8(BigInteger.ZERO); + + public Fixed192x8(BigInteger value) { + super(192, 8, value); + } + + public Fixed192x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(192, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed200x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed200x16.java new file mode 100644 index 0000000000..720333f331 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed200x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed200x16 extends Fixed { + public static final Fixed200x16 DEFAULT = new Fixed200x16(BigInteger.ZERO); + + public Fixed200x16(BigInteger value) { + super(200, 16, value); + } + + public Fixed200x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(200, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed200x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed200x24.java new file mode 100644 index 0000000000..bc87fa2dab --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed200x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed200x24 extends Fixed { + public static final Fixed200x24 DEFAULT = new Fixed200x24(BigInteger.ZERO); + + public Fixed200x24(BigInteger value) { + super(200, 24, value); + } + + public Fixed200x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(200, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed200x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed200x32.java new file mode 100644 index 0000000000..60f8719cac --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed200x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed200x32 extends Fixed { + public static final Fixed200x32 DEFAULT = new Fixed200x32(BigInteger.ZERO); + + public Fixed200x32(BigInteger value) { + super(200, 32, value); + } + + public Fixed200x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(200, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed200x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed200x40.java new file mode 100644 index 0000000000..fa159ca4f1 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed200x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed200x40 extends Fixed { + public static final Fixed200x40 DEFAULT = new Fixed200x40(BigInteger.ZERO); + + public Fixed200x40(BigInteger value) { + super(200, 40, value); + } + + public Fixed200x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(200, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed200x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed200x48.java new file mode 100644 index 0000000000..37697d6835 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed200x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed200x48 extends Fixed { + public static final Fixed200x48 DEFAULT = new Fixed200x48(BigInteger.ZERO); + + public Fixed200x48(BigInteger value) { + super(200, 48, value); + } + + public Fixed200x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(200, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed200x56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed200x56.java new file mode 100644 index 0000000000..0214bc2570 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed200x56.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed200x56 extends Fixed { + public static final Fixed200x56 DEFAULT = new Fixed200x56(BigInteger.ZERO); + + public Fixed200x56(BigInteger value) { + super(200, 56, value); + } + + public Fixed200x56(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(200, 56, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed200x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed200x8.java new file mode 100644 index 0000000000..856c811058 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed200x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed200x8 extends Fixed { + public static final Fixed200x8 DEFAULT = new Fixed200x8(BigInteger.ZERO); + + public Fixed200x8(BigInteger value) { + super(200, 8, value); + } + + public Fixed200x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(200, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed208x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed208x16.java new file mode 100644 index 0000000000..337fc584a4 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed208x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed208x16 extends Fixed { + public static final Fixed208x16 DEFAULT = new Fixed208x16(BigInteger.ZERO); + + public Fixed208x16(BigInteger value) { + super(208, 16, value); + } + + public Fixed208x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(208, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed208x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed208x24.java new file mode 100644 index 0000000000..f6ed07b788 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed208x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed208x24 extends Fixed { + public static final Fixed208x24 DEFAULT = new Fixed208x24(BigInteger.ZERO); + + public Fixed208x24(BigInteger value) { + super(208, 24, value); + } + + public Fixed208x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(208, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed208x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed208x32.java new file mode 100644 index 0000000000..19ecc751c1 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed208x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed208x32 extends Fixed { + public static final Fixed208x32 DEFAULT = new Fixed208x32(BigInteger.ZERO); + + public Fixed208x32(BigInteger value) { + super(208, 32, value); + } + + public Fixed208x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(208, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed208x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed208x40.java new file mode 100644 index 0000000000..8d2562a18c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed208x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed208x40 extends Fixed { + public static final Fixed208x40 DEFAULT = new Fixed208x40(BigInteger.ZERO); + + public Fixed208x40(BigInteger value) { + super(208, 40, value); + } + + public Fixed208x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(208, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed208x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed208x48.java new file mode 100644 index 0000000000..44e574fc56 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed208x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed208x48 extends Fixed { + public static final Fixed208x48 DEFAULT = new Fixed208x48(BigInteger.ZERO); + + public Fixed208x48(BigInteger value) { + super(208, 48, value); + } + + public Fixed208x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(208, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed208x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed208x8.java new file mode 100644 index 0000000000..115c065dd5 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed208x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed208x8 extends Fixed { + public static final Fixed208x8 DEFAULT = new Fixed208x8(BigInteger.ZERO); + + public Fixed208x8(BigInteger value) { + super(208, 8, value); + } + + public Fixed208x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(208, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed216x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed216x16.java new file mode 100644 index 0000000000..6dfd4a2d72 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed216x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed216x16 extends Fixed { + public static final Fixed216x16 DEFAULT = new Fixed216x16(BigInteger.ZERO); + + public Fixed216x16(BigInteger value) { + super(216, 16, value); + } + + public Fixed216x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(216, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed216x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed216x24.java new file mode 100644 index 0000000000..324e20eaa2 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed216x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed216x24 extends Fixed { + public static final Fixed216x24 DEFAULT = new Fixed216x24(BigInteger.ZERO); + + public Fixed216x24(BigInteger value) { + super(216, 24, value); + } + + public Fixed216x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(216, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed216x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed216x32.java new file mode 100644 index 0000000000..f98f059e88 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed216x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed216x32 extends Fixed { + public static final Fixed216x32 DEFAULT = new Fixed216x32(BigInteger.ZERO); + + public Fixed216x32(BigInteger value) { + super(216, 32, value); + } + + public Fixed216x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(216, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed216x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed216x40.java new file mode 100644 index 0000000000..12988d8921 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed216x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed216x40 extends Fixed { + public static final Fixed216x40 DEFAULT = new Fixed216x40(BigInteger.ZERO); + + public Fixed216x40(BigInteger value) { + super(216, 40, value); + } + + public Fixed216x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(216, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed216x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed216x8.java new file mode 100644 index 0000000000..eb2cc3e3e8 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed216x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed216x8 extends Fixed { + public static final Fixed216x8 DEFAULT = new Fixed216x8(BigInteger.ZERO); + + public Fixed216x8(BigInteger value) { + super(216, 8, value); + } + + public Fixed216x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(216, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed224x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed224x16.java new file mode 100644 index 0000000000..b5a429f3fd --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed224x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed224x16 extends Fixed { + public static final Fixed224x16 DEFAULT = new Fixed224x16(BigInteger.ZERO); + + public Fixed224x16(BigInteger value) { + super(224, 16, value); + } + + public Fixed224x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(224, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed224x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed224x24.java new file mode 100644 index 0000000000..2c8568cb76 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed224x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed224x24 extends Fixed { + public static final Fixed224x24 DEFAULT = new Fixed224x24(BigInteger.ZERO); + + public Fixed224x24(BigInteger value) { + super(224, 24, value); + } + + public Fixed224x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(224, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed224x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed224x32.java new file mode 100644 index 0000000000..3a126c4085 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed224x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed224x32 extends Fixed { + public static final Fixed224x32 DEFAULT = new Fixed224x32(BigInteger.ZERO); + + public Fixed224x32(BigInteger value) { + super(224, 32, value); + } + + public Fixed224x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(224, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed224x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed224x8.java new file mode 100644 index 0000000000..be88c9c049 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed224x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed224x8 extends Fixed { + public static final Fixed224x8 DEFAULT = new Fixed224x8(BigInteger.ZERO); + + public Fixed224x8(BigInteger value) { + super(224, 8, value); + } + + public Fixed224x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(224, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed232x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed232x16.java new file mode 100644 index 0000000000..1ecf1d648a --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed232x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed232x16 extends Fixed { + public static final Fixed232x16 DEFAULT = new Fixed232x16(BigInteger.ZERO); + + public Fixed232x16(BigInteger value) { + super(232, 16, value); + } + + public Fixed232x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(232, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed232x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed232x24.java new file mode 100644 index 0000000000..a5bb190ecd --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed232x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed232x24 extends Fixed { + public static final Fixed232x24 DEFAULT = new Fixed232x24(BigInteger.ZERO); + + public Fixed232x24(BigInteger value) { + super(232, 24, value); + } + + public Fixed232x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(232, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed232x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed232x8.java new file mode 100644 index 0000000000..83814c9749 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed232x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed232x8 extends Fixed { + public static final Fixed232x8 DEFAULT = new Fixed232x8(BigInteger.ZERO); + + public Fixed232x8(BigInteger value) { + super(232, 8, value); + } + + public Fixed232x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(232, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed240x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed240x16.java new file mode 100644 index 0000000000..24aa50c9b8 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed240x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed240x16 extends Fixed { + public static final Fixed240x16 DEFAULT = new Fixed240x16(BigInteger.ZERO); + + public Fixed240x16(BigInteger value) { + super(240, 16, value); + } + + public Fixed240x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(240, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed240x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed240x8.java new file mode 100644 index 0000000000..de13dd9893 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed240x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed240x8 extends Fixed { + public static final Fixed240x8 DEFAULT = new Fixed240x8(BigInteger.ZERO); + + public Fixed240x8(BigInteger value) { + super(240, 8, value); + } + + public Fixed240x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(240, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed248x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed248x8.java new file mode 100644 index 0000000000..10ca50f936 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed248x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed248x8 extends Fixed { + public static final Fixed248x8 DEFAULT = new Fixed248x8(BigInteger.ZERO); + + public Fixed248x8(BigInteger value) { + super(248, 8, value); + } + + public Fixed248x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(248, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x104.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x104.java new file mode 100644 index 0000000000..a41b70b9ed --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x104.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed24x104 extends Fixed { + public static final Fixed24x104 DEFAULT = new Fixed24x104(BigInteger.ZERO); + + public Fixed24x104(BigInteger value) { + super(24, 104, value); + } + + public Fixed24x104(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 104, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x112.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x112.java new file mode 100644 index 0000000000..9311d1acb1 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x112.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed24x112 extends Fixed { + public static final Fixed24x112 DEFAULT = new Fixed24x112(BigInteger.ZERO); + + public Fixed24x112(BigInteger value) { + super(24, 112, value); + } + + public Fixed24x112(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 112, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x120.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x120.java new file mode 100644 index 0000000000..258a1d2092 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x120.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed24x120 extends Fixed { + public static final Fixed24x120 DEFAULT = new Fixed24x120(BigInteger.ZERO); + + public Fixed24x120(BigInteger value) { + super(24, 120, value); + } + + public Fixed24x120(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 120, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x128.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x128.java new file mode 100644 index 0000000000..777039dedd --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x128.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed24x128 extends Fixed { + public static final Fixed24x128 DEFAULT = new Fixed24x128(BigInteger.ZERO); + + public Fixed24x128(BigInteger value) { + super(24, 128, value); + } + + public Fixed24x128(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 128, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x136.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x136.java new file mode 100644 index 0000000000..6c17b189f7 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x136.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed24x136 extends Fixed { + public static final Fixed24x136 DEFAULT = new Fixed24x136(BigInteger.ZERO); + + public Fixed24x136(BigInteger value) { + super(24, 136, value); + } + + public Fixed24x136(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 136, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x144.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x144.java new file mode 100644 index 0000000000..519979e7da --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x144.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed24x144 extends Fixed { + public static final Fixed24x144 DEFAULT = new Fixed24x144(BigInteger.ZERO); + + public Fixed24x144(BigInteger value) { + super(24, 144, value); + } + + public Fixed24x144(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 144, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x152.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x152.java new file mode 100644 index 0000000000..1deaa4670a --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x152.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed24x152 extends Fixed { + public static final Fixed24x152 DEFAULT = new Fixed24x152(BigInteger.ZERO); + + public Fixed24x152(BigInteger value) { + super(24, 152, value); + } + + public Fixed24x152(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 152, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x16.java new file mode 100644 index 0000000000..29e44b404e --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed24x16 extends Fixed { + public static final Fixed24x16 DEFAULT = new Fixed24x16(BigInteger.ZERO); + + public Fixed24x16(BigInteger value) { + super(24, 16, value); + } + + public Fixed24x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x160.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x160.java new file mode 100644 index 0000000000..f0b4aab73d --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x160.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed24x160 extends Fixed { + public static final Fixed24x160 DEFAULT = new Fixed24x160(BigInteger.ZERO); + + public Fixed24x160(BigInteger value) { + super(24, 160, value); + } + + public Fixed24x160(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 160, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x168.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x168.java new file mode 100644 index 0000000000..67f1c4d4b6 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x168.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed24x168 extends Fixed { + public static final Fixed24x168 DEFAULT = new Fixed24x168(BigInteger.ZERO); + + public Fixed24x168(BigInteger value) { + super(24, 168, value); + } + + public Fixed24x168(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 168, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x176.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x176.java new file mode 100644 index 0000000000..2719b34fc4 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x176.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed24x176 extends Fixed { + public static final Fixed24x176 DEFAULT = new Fixed24x176(BigInteger.ZERO); + + public Fixed24x176(BigInteger value) { + super(24, 176, value); + } + + public Fixed24x176(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 176, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x184.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x184.java new file mode 100644 index 0000000000..f7be61056f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x184.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed24x184 extends Fixed { + public static final Fixed24x184 DEFAULT = new Fixed24x184(BigInteger.ZERO); + + public Fixed24x184(BigInteger value) { + super(24, 184, value); + } + + public Fixed24x184(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 184, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x192.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x192.java new file mode 100644 index 0000000000..2390552a01 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x192.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed24x192 extends Fixed { + public static final Fixed24x192 DEFAULT = new Fixed24x192(BigInteger.ZERO); + + public Fixed24x192(BigInteger value) { + super(24, 192, value); + } + + public Fixed24x192(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 192, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x200.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x200.java new file mode 100644 index 0000000000..459c727d09 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x200.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed24x200 extends Fixed { + public static final Fixed24x200 DEFAULT = new Fixed24x200(BigInteger.ZERO); + + public Fixed24x200(BigInteger value) { + super(24, 200, value); + } + + public Fixed24x200(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 200, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x208.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x208.java new file mode 100644 index 0000000000..5cea34faf5 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x208.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed24x208 extends Fixed { + public static final Fixed24x208 DEFAULT = new Fixed24x208(BigInteger.ZERO); + + public Fixed24x208(BigInteger value) { + super(24, 208, value); + } + + public Fixed24x208(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 208, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x216.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x216.java new file mode 100644 index 0000000000..5bc3e6c168 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x216.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed24x216 extends Fixed { + public static final Fixed24x216 DEFAULT = new Fixed24x216(BigInteger.ZERO); + + public Fixed24x216(BigInteger value) { + super(24, 216, value); + } + + public Fixed24x216(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 216, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x224.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x224.java new file mode 100644 index 0000000000..81ddc45578 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x224.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed24x224 extends Fixed { + public static final Fixed24x224 DEFAULT = new Fixed24x224(BigInteger.ZERO); + + public Fixed24x224(BigInteger value) { + super(24, 224, value); + } + + public Fixed24x224(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 224, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x232.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x232.java new file mode 100644 index 0000000000..2700d1e8dd --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x232.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed24x232 extends Fixed { + public static final Fixed24x232 DEFAULT = new Fixed24x232(BigInteger.ZERO); + + public Fixed24x232(BigInteger value) { + super(24, 232, value); + } + + public Fixed24x232(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 232, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x24.java new file mode 100644 index 0000000000..585b9080d6 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed24x24 extends Fixed { + public static final Fixed24x24 DEFAULT = new Fixed24x24(BigInteger.ZERO); + + public Fixed24x24(BigInteger value) { + super(24, 24, value); + } + + public Fixed24x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x32.java new file mode 100644 index 0000000000..208374985b --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed24x32 extends Fixed { + public static final Fixed24x32 DEFAULT = new Fixed24x32(BigInteger.ZERO); + + public Fixed24x32(BigInteger value) { + super(24, 32, value); + } + + public Fixed24x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x40.java new file mode 100644 index 0000000000..83c3a0b5b8 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed24x40 extends Fixed { + public static final Fixed24x40 DEFAULT = new Fixed24x40(BigInteger.ZERO); + + public Fixed24x40(BigInteger value) { + super(24, 40, value); + } + + public Fixed24x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x48.java new file mode 100644 index 0000000000..bcf64ebb94 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed24x48 extends Fixed { + public static final Fixed24x48 DEFAULT = new Fixed24x48(BigInteger.ZERO); + + public Fixed24x48(BigInteger value) { + super(24, 48, value); + } + + public Fixed24x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x56.java new file mode 100644 index 0000000000..dae72599ca --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x56.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed24x56 extends Fixed { + public static final Fixed24x56 DEFAULT = new Fixed24x56(BigInteger.ZERO); + + public Fixed24x56(BigInteger value) { + super(24, 56, value); + } + + public Fixed24x56(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 56, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x64.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x64.java new file mode 100644 index 0000000000..e1518ead68 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x64.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed24x64 extends Fixed { + public static final Fixed24x64 DEFAULT = new Fixed24x64(BigInteger.ZERO); + + public Fixed24x64(BigInteger value) { + super(24, 64, value); + } + + public Fixed24x64(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 64, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x72.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x72.java new file mode 100644 index 0000000000..50c7c1fd16 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x72.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed24x72 extends Fixed { + public static final Fixed24x72 DEFAULT = new Fixed24x72(BigInteger.ZERO); + + public Fixed24x72(BigInteger value) { + super(24, 72, value); + } + + public Fixed24x72(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 72, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x8.java new file mode 100644 index 0000000000..7f3923659f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed24x8 extends Fixed { + public static final Fixed24x8 DEFAULT = new Fixed24x8(BigInteger.ZERO); + + public Fixed24x8(BigInteger value) { + super(24, 8, value); + } + + public Fixed24x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x80.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x80.java new file mode 100644 index 0000000000..81cb48b22d --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x80.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed24x80 extends Fixed { + public static final Fixed24x80 DEFAULT = new Fixed24x80(BigInteger.ZERO); + + public Fixed24x80(BigInteger value) { + super(24, 80, value); + } + + public Fixed24x80(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 80, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x88.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x88.java new file mode 100644 index 0000000000..c7a6f24143 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x88.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed24x88 extends Fixed { + public static final Fixed24x88 DEFAULT = new Fixed24x88(BigInteger.ZERO); + + public Fixed24x88(BigInteger value) { + super(24, 88, value); + } + + public Fixed24x88(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 88, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x96.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x96.java new file mode 100644 index 0000000000..cd6bd69d3d --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed24x96.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed24x96 extends Fixed { + public static final Fixed24x96 DEFAULT = new Fixed24x96(BigInteger.ZERO); + + public Fixed24x96(BigInteger value) { + super(24, 96, value); + } + + public Fixed24x96(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 96, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x104.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x104.java new file mode 100644 index 0000000000..b96e6757e8 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x104.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed32x104 extends Fixed { + public static final Fixed32x104 DEFAULT = new Fixed32x104(BigInteger.ZERO); + + public Fixed32x104(BigInteger value) { + super(32, 104, value); + } + + public Fixed32x104(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 104, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x112.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x112.java new file mode 100644 index 0000000000..c76e4661f1 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x112.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed32x112 extends Fixed { + public static final Fixed32x112 DEFAULT = new Fixed32x112(BigInteger.ZERO); + + public Fixed32x112(BigInteger value) { + super(32, 112, value); + } + + public Fixed32x112(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 112, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x120.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x120.java new file mode 100644 index 0000000000..abc4935501 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x120.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed32x120 extends Fixed { + public static final Fixed32x120 DEFAULT = new Fixed32x120(BigInteger.ZERO); + + public Fixed32x120(BigInteger value) { + super(32, 120, value); + } + + public Fixed32x120(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 120, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x128.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x128.java new file mode 100644 index 0000000000..ef20bb2d9d --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x128.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed32x128 extends Fixed { + public static final Fixed32x128 DEFAULT = new Fixed32x128(BigInteger.ZERO); + + public Fixed32x128(BigInteger value) { + super(32, 128, value); + } + + public Fixed32x128(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 128, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x136.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x136.java new file mode 100644 index 0000000000..394a1881b1 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x136.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed32x136 extends Fixed { + public static final Fixed32x136 DEFAULT = new Fixed32x136(BigInteger.ZERO); + + public Fixed32x136(BigInteger value) { + super(32, 136, value); + } + + public Fixed32x136(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 136, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x144.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x144.java new file mode 100644 index 0000000000..daf26dcf12 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x144.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed32x144 extends Fixed { + public static final Fixed32x144 DEFAULT = new Fixed32x144(BigInteger.ZERO); + + public Fixed32x144(BigInteger value) { + super(32, 144, value); + } + + public Fixed32x144(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 144, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x152.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x152.java new file mode 100644 index 0000000000..eb54df0377 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x152.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed32x152 extends Fixed { + public static final Fixed32x152 DEFAULT = new Fixed32x152(BigInteger.ZERO); + + public Fixed32x152(BigInteger value) { + super(32, 152, value); + } + + public Fixed32x152(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 152, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x16.java new file mode 100644 index 0000000000..75d0967e17 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed32x16 extends Fixed { + public static final Fixed32x16 DEFAULT = new Fixed32x16(BigInteger.ZERO); + + public Fixed32x16(BigInteger value) { + super(32, 16, value); + } + + public Fixed32x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x160.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x160.java new file mode 100644 index 0000000000..023ff44897 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x160.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed32x160 extends Fixed { + public static final Fixed32x160 DEFAULT = new Fixed32x160(BigInteger.ZERO); + + public Fixed32x160(BigInteger value) { + super(32, 160, value); + } + + public Fixed32x160(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 160, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x168.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x168.java new file mode 100644 index 0000000000..2a90b09f67 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x168.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed32x168 extends Fixed { + public static final Fixed32x168 DEFAULT = new Fixed32x168(BigInteger.ZERO); + + public Fixed32x168(BigInteger value) { + super(32, 168, value); + } + + public Fixed32x168(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 168, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x176.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x176.java new file mode 100644 index 0000000000..e1cc61e5c2 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x176.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed32x176 extends Fixed { + public static final Fixed32x176 DEFAULT = new Fixed32x176(BigInteger.ZERO); + + public Fixed32x176(BigInteger value) { + super(32, 176, value); + } + + public Fixed32x176(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 176, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x184.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x184.java new file mode 100644 index 0000000000..6229d253ba --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x184.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed32x184 extends Fixed { + public static final Fixed32x184 DEFAULT = new Fixed32x184(BigInteger.ZERO); + + public Fixed32x184(BigInteger value) { + super(32, 184, value); + } + + public Fixed32x184(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 184, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x192.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x192.java new file mode 100644 index 0000000000..36507332d0 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x192.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed32x192 extends Fixed { + public static final Fixed32x192 DEFAULT = new Fixed32x192(BigInteger.ZERO); + + public Fixed32x192(BigInteger value) { + super(32, 192, value); + } + + public Fixed32x192(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 192, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x200.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x200.java new file mode 100644 index 0000000000..9052094c0b --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x200.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed32x200 extends Fixed { + public static final Fixed32x200 DEFAULT = new Fixed32x200(BigInteger.ZERO); + + public Fixed32x200(BigInteger value) { + super(32, 200, value); + } + + public Fixed32x200(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 200, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x208.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x208.java new file mode 100644 index 0000000000..1b391b2ee9 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x208.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed32x208 extends Fixed { + public static final Fixed32x208 DEFAULT = new Fixed32x208(BigInteger.ZERO); + + public Fixed32x208(BigInteger value) { + super(32, 208, value); + } + + public Fixed32x208(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 208, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x216.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x216.java new file mode 100644 index 0000000000..ed83b13082 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x216.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed32x216 extends Fixed { + public static final Fixed32x216 DEFAULT = new Fixed32x216(BigInteger.ZERO); + + public Fixed32x216(BigInteger value) { + super(32, 216, value); + } + + public Fixed32x216(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 216, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x224.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x224.java new file mode 100644 index 0000000000..db9c9ba3bf --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x224.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed32x224 extends Fixed { + public static final Fixed32x224 DEFAULT = new Fixed32x224(BigInteger.ZERO); + + public Fixed32x224(BigInteger value) { + super(32, 224, value); + } + + public Fixed32x224(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 224, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x24.java new file mode 100644 index 0000000000..d59ed6b303 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed32x24 extends Fixed { + public static final Fixed32x24 DEFAULT = new Fixed32x24(BigInteger.ZERO); + + public Fixed32x24(BigInteger value) { + super(32, 24, value); + } + + public Fixed32x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x32.java new file mode 100644 index 0000000000..c7e24c6349 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed32x32 extends Fixed { + public static final Fixed32x32 DEFAULT = new Fixed32x32(BigInteger.ZERO); + + public Fixed32x32(BigInteger value) { + super(32, 32, value); + } + + public Fixed32x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x40.java new file mode 100644 index 0000000000..2a163b1058 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed32x40 extends Fixed { + public static final Fixed32x40 DEFAULT = new Fixed32x40(BigInteger.ZERO); + + public Fixed32x40(BigInteger value) { + super(32, 40, value); + } + + public Fixed32x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x48.java new file mode 100644 index 0000000000..6eed732c1e --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed32x48 extends Fixed { + public static final Fixed32x48 DEFAULT = new Fixed32x48(BigInteger.ZERO); + + public Fixed32x48(BigInteger value) { + super(32, 48, value); + } + + public Fixed32x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x56.java new file mode 100644 index 0000000000..a34811129c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x56.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed32x56 extends Fixed { + public static final Fixed32x56 DEFAULT = new Fixed32x56(BigInteger.ZERO); + + public Fixed32x56(BigInteger value) { + super(32, 56, value); + } + + public Fixed32x56(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 56, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x64.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x64.java new file mode 100644 index 0000000000..af82ad5671 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x64.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed32x64 extends Fixed { + public static final Fixed32x64 DEFAULT = new Fixed32x64(BigInteger.ZERO); + + public Fixed32x64(BigInteger value) { + super(32, 64, value); + } + + public Fixed32x64(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 64, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x72.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x72.java new file mode 100644 index 0000000000..dc95dd288f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x72.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed32x72 extends Fixed { + public static final Fixed32x72 DEFAULT = new Fixed32x72(BigInteger.ZERO); + + public Fixed32x72(BigInteger value) { + super(32, 72, value); + } + + public Fixed32x72(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 72, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x8.java new file mode 100644 index 0000000000..743e1f799f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed32x8 extends Fixed { + public static final Fixed32x8 DEFAULT = new Fixed32x8(BigInteger.ZERO); + + public Fixed32x8(BigInteger value) { + super(32, 8, value); + } + + public Fixed32x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x80.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x80.java new file mode 100644 index 0000000000..08c480ec59 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x80.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed32x80 extends Fixed { + public static final Fixed32x80 DEFAULT = new Fixed32x80(BigInteger.ZERO); + + public Fixed32x80(BigInteger value) { + super(32, 80, value); + } + + public Fixed32x80(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 80, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x88.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x88.java new file mode 100644 index 0000000000..d69aa0eacc --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x88.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed32x88 extends Fixed { + public static final Fixed32x88 DEFAULT = new Fixed32x88(BigInteger.ZERO); + + public Fixed32x88(BigInteger value) { + super(32, 88, value); + } + + public Fixed32x88(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 88, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x96.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x96.java new file mode 100644 index 0000000000..b932f5a9c2 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed32x96.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed32x96 extends Fixed { + public static final Fixed32x96 DEFAULT = new Fixed32x96(BigInteger.ZERO); + + public Fixed32x96(BigInteger value) { + super(32, 96, value); + } + + public Fixed32x96(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 96, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x104.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x104.java new file mode 100644 index 0000000000..bd4b53cf60 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x104.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed40x104 extends Fixed { + public static final Fixed40x104 DEFAULT = new Fixed40x104(BigInteger.ZERO); + + public Fixed40x104(BigInteger value) { + super(40, 104, value); + } + + public Fixed40x104(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 104, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x112.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x112.java new file mode 100644 index 0000000000..d363805ccc --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x112.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed40x112 extends Fixed { + public static final Fixed40x112 DEFAULT = new Fixed40x112(BigInteger.ZERO); + + public Fixed40x112(BigInteger value) { + super(40, 112, value); + } + + public Fixed40x112(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 112, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x120.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x120.java new file mode 100644 index 0000000000..629d68691e --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x120.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed40x120 extends Fixed { + public static final Fixed40x120 DEFAULT = new Fixed40x120(BigInteger.ZERO); + + public Fixed40x120(BigInteger value) { + super(40, 120, value); + } + + public Fixed40x120(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 120, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x128.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x128.java new file mode 100644 index 0000000000..65a68fff4c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x128.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed40x128 extends Fixed { + public static final Fixed40x128 DEFAULT = new Fixed40x128(BigInteger.ZERO); + + public Fixed40x128(BigInteger value) { + super(40, 128, value); + } + + public Fixed40x128(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 128, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x136.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x136.java new file mode 100644 index 0000000000..da82ffb0e6 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x136.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed40x136 extends Fixed { + public static final Fixed40x136 DEFAULT = new Fixed40x136(BigInteger.ZERO); + + public Fixed40x136(BigInteger value) { + super(40, 136, value); + } + + public Fixed40x136(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 136, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x144.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x144.java new file mode 100644 index 0000000000..cc8cabc4e2 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x144.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed40x144 extends Fixed { + public static final Fixed40x144 DEFAULT = new Fixed40x144(BigInteger.ZERO); + + public Fixed40x144(BigInteger value) { + super(40, 144, value); + } + + public Fixed40x144(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 144, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x152.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x152.java new file mode 100644 index 0000000000..213d5885da --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x152.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed40x152 extends Fixed { + public static final Fixed40x152 DEFAULT = new Fixed40x152(BigInteger.ZERO); + + public Fixed40x152(BigInteger value) { + super(40, 152, value); + } + + public Fixed40x152(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 152, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x16.java new file mode 100644 index 0000000000..65e012329b --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed40x16 extends Fixed { + public static final Fixed40x16 DEFAULT = new Fixed40x16(BigInteger.ZERO); + + public Fixed40x16(BigInteger value) { + super(40, 16, value); + } + + public Fixed40x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x160.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x160.java new file mode 100644 index 0000000000..b8254f10e0 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x160.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed40x160 extends Fixed { + public static final Fixed40x160 DEFAULT = new Fixed40x160(BigInteger.ZERO); + + public Fixed40x160(BigInteger value) { + super(40, 160, value); + } + + public Fixed40x160(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 160, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x168.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x168.java new file mode 100644 index 0000000000..786cf7fa6e --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x168.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed40x168 extends Fixed { + public static final Fixed40x168 DEFAULT = new Fixed40x168(BigInteger.ZERO); + + public Fixed40x168(BigInteger value) { + super(40, 168, value); + } + + public Fixed40x168(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 168, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x176.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x176.java new file mode 100644 index 0000000000..b71690ab0d --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x176.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed40x176 extends Fixed { + public static final Fixed40x176 DEFAULT = new Fixed40x176(BigInteger.ZERO); + + public Fixed40x176(BigInteger value) { + super(40, 176, value); + } + + public Fixed40x176(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 176, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x184.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x184.java new file mode 100644 index 0000000000..b25a709076 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x184.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed40x184 extends Fixed { + public static final Fixed40x184 DEFAULT = new Fixed40x184(BigInteger.ZERO); + + public Fixed40x184(BigInteger value) { + super(40, 184, value); + } + + public Fixed40x184(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 184, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x192.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x192.java new file mode 100644 index 0000000000..dd5330df89 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x192.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed40x192 extends Fixed { + public static final Fixed40x192 DEFAULT = new Fixed40x192(BigInteger.ZERO); + + public Fixed40x192(BigInteger value) { + super(40, 192, value); + } + + public Fixed40x192(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 192, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x200.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x200.java new file mode 100644 index 0000000000..6db0b513bf --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x200.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed40x200 extends Fixed { + public static final Fixed40x200 DEFAULT = new Fixed40x200(BigInteger.ZERO); + + public Fixed40x200(BigInteger value) { + super(40, 200, value); + } + + public Fixed40x200(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 200, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x208.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x208.java new file mode 100644 index 0000000000..c0393f81f4 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x208.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed40x208 extends Fixed { + public static final Fixed40x208 DEFAULT = new Fixed40x208(BigInteger.ZERO); + + public Fixed40x208(BigInteger value) { + super(40, 208, value); + } + + public Fixed40x208(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 208, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x216.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x216.java new file mode 100644 index 0000000000..6212c86ef2 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x216.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed40x216 extends Fixed { + public static final Fixed40x216 DEFAULT = new Fixed40x216(BigInteger.ZERO); + + public Fixed40x216(BigInteger value) { + super(40, 216, value); + } + + public Fixed40x216(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 216, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x24.java new file mode 100644 index 0000000000..9e489573bd --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed40x24 extends Fixed { + public static final Fixed40x24 DEFAULT = new Fixed40x24(BigInteger.ZERO); + + public Fixed40x24(BigInteger value) { + super(40, 24, value); + } + + public Fixed40x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x32.java new file mode 100644 index 0000000000..4c8522d66d --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed40x32 extends Fixed { + public static final Fixed40x32 DEFAULT = new Fixed40x32(BigInteger.ZERO); + + public Fixed40x32(BigInteger value) { + super(40, 32, value); + } + + public Fixed40x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x40.java new file mode 100644 index 0000000000..734b143de0 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed40x40 extends Fixed { + public static final Fixed40x40 DEFAULT = new Fixed40x40(BigInteger.ZERO); + + public Fixed40x40(BigInteger value) { + super(40, 40, value); + } + + public Fixed40x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x48.java new file mode 100644 index 0000000000..cd417f45d8 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed40x48 extends Fixed { + public static final Fixed40x48 DEFAULT = new Fixed40x48(BigInteger.ZERO); + + public Fixed40x48(BigInteger value) { + super(40, 48, value); + } + + public Fixed40x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x56.java new file mode 100644 index 0000000000..ca37c56ad8 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x56.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed40x56 extends Fixed { + public static final Fixed40x56 DEFAULT = new Fixed40x56(BigInteger.ZERO); + + public Fixed40x56(BigInteger value) { + super(40, 56, value); + } + + public Fixed40x56(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 56, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x64.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x64.java new file mode 100644 index 0000000000..39e56359e5 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x64.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed40x64 extends Fixed { + public static final Fixed40x64 DEFAULT = new Fixed40x64(BigInteger.ZERO); + + public Fixed40x64(BigInteger value) { + super(40, 64, value); + } + + public Fixed40x64(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 64, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x72.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x72.java new file mode 100644 index 0000000000..7181415cc0 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x72.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed40x72 extends Fixed { + public static final Fixed40x72 DEFAULT = new Fixed40x72(BigInteger.ZERO); + + public Fixed40x72(BigInteger value) { + super(40, 72, value); + } + + public Fixed40x72(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 72, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x8.java new file mode 100644 index 0000000000..ba2e1929e8 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed40x8 extends Fixed { + public static final Fixed40x8 DEFAULT = new Fixed40x8(BigInteger.ZERO); + + public Fixed40x8(BigInteger value) { + super(40, 8, value); + } + + public Fixed40x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x80.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x80.java new file mode 100644 index 0000000000..a8b2ea0800 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x80.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed40x80 extends Fixed { + public static final Fixed40x80 DEFAULT = new Fixed40x80(BigInteger.ZERO); + + public Fixed40x80(BigInteger value) { + super(40, 80, value); + } + + public Fixed40x80(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 80, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x88.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x88.java new file mode 100644 index 0000000000..c1a45c577a --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x88.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed40x88 extends Fixed { + public static final Fixed40x88 DEFAULT = new Fixed40x88(BigInteger.ZERO); + + public Fixed40x88(BigInteger value) { + super(40, 88, value); + } + + public Fixed40x88(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 88, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x96.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x96.java new file mode 100644 index 0000000000..24ad4332dd --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed40x96.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed40x96 extends Fixed { + public static final Fixed40x96 DEFAULT = new Fixed40x96(BigInteger.ZERO); + + public Fixed40x96(BigInteger value) { + super(40, 96, value); + } + + public Fixed40x96(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 96, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x104.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x104.java new file mode 100644 index 0000000000..acba4b62bc --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x104.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed48x104 extends Fixed { + public static final Fixed48x104 DEFAULT = new Fixed48x104(BigInteger.ZERO); + + public Fixed48x104(BigInteger value) { + super(48, 104, value); + } + + public Fixed48x104(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 104, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x112.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x112.java new file mode 100644 index 0000000000..875502df0f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x112.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed48x112 extends Fixed { + public static final Fixed48x112 DEFAULT = new Fixed48x112(BigInteger.ZERO); + + public Fixed48x112(BigInteger value) { + super(48, 112, value); + } + + public Fixed48x112(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 112, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x120.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x120.java new file mode 100644 index 0000000000..4b43d0ec3a --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x120.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed48x120 extends Fixed { + public static final Fixed48x120 DEFAULT = new Fixed48x120(BigInteger.ZERO); + + public Fixed48x120(BigInteger value) { + super(48, 120, value); + } + + public Fixed48x120(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 120, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x128.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x128.java new file mode 100644 index 0000000000..b296fab2cc --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x128.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed48x128 extends Fixed { + public static final Fixed48x128 DEFAULT = new Fixed48x128(BigInteger.ZERO); + + public Fixed48x128(BigInteger value) { + super(48, 128, value); + } + + public Fixed48x128(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 128, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x136.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x136.java new file mode 100644 index 0000000000..477a8bfa9d --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x136.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed48x136 extends Fixed { + public static final Fixed48x136 DEFAULT = new Fixed48x136(BigInteger.ZERO); + + public Fixed48x136(BigInteger value) { + super(48, 136, value); + } + + public Fixed48x136(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 136, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x144.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x144.java new file mode 100644 index 0000000000..38857a7b02 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x144.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed48x144 extends Fixed { + public static final Fixed48x144 DEFAULT = new Fixed48x144(BigInteger.ZERO); + + public Fixed48x144(BigInteger value) { + super(48, 144, value); + } + + public Fixed48x144(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 144, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x152.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x152.java new file mode 100644 index 0000000000..a03e9632bb --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x152.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed48x152 extends Fixed { + public static final Fixed48x152 DEFAULT = new Fixed48x152(BigInteger.ZERO); + + public Fixed48x152(BigInteger value) { + super(48, 152, value); + } + + public Fixed48x152(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 152, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x16.java new file mode 100644 index 0000000000..78e8b474a5 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed48x16 extends Fixed { + public static final Fixed48x16 DEFAULT = new Fixed48x16(BigInteger.ZERO); + + public Fixed48x16(BigInteger value) { + super(48, 16, value); + } + + public Fixed48x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x160.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x160.java new file mode 100644 index 0000000000..ccb3be8dd4 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x160.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed48x160 extends Fixed { + public static final Fixed48x160 DEFAULT = new Fixed48x160(BigInteger.ZERO); + + public Fixed48x160(BigInteger value) { + super(48, 160, value); + } + + public Fixed48x160(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 160, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x168.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x168.java new file mode 100644 index 0000000000..afcb1d797f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x168.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed48x168 extends Fixed { + public static final Fixed48x168 DEFAULT = new Fixed48x168(BigInteger.ZERO); + + public Fixed48x168(BigInteger value) { + super(48, 168, value); + } + + public Fixed48x168(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 168, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x176.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x176.java new file mode 100644 index 0000000000..e4666dc0c3 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x176.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed48x176 extends Fixed { + public static final Fixed48x176 DEFAULT = new Fixed48x176(BigInteger.ZERO); + + public Fixed48x176(BigInteger value) { + super(48, 176, value); + } + + public Fixed48x176(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 176, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x184.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x184.java new file mode 100644 index 0000000000..725e22fde9 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x184.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed48x184 extends Fixed { + public static final Fixed48x184 DEFAULT = new Fixed48x184(BigInteger.ZERO); + + public Fixed48x184(BigInteger value) { + super(48, 184, value); + } + + public Fixed48x184(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 184, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x192.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x192.java new file mode 100644 index 0000000000..ddfb8def87 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x192.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed48x192 extends Fixed { + public static final Fixed48x192 DEFAULT = new Fixed48x192(BigInteger.ZERO); + + public Fixed48x192(BigInteger value) { + super(48, 192, value); + } + + public Fixed48x192(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 192, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x200.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x200.java new file mode 100644 index 0000000000..8a84466565 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x200.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed48x200 extends Fixed { + public static final Fixed48x200 DEFAULT = new Fixed48x200(BigInteger.ZERO); + + public Fixed48x200(BigInteger value) { + super(48, 200, value); + } + + public Fixed48x200(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 200, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x208.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x208.java new file mode 100644 index 0000000000..8f23a7467a --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x208.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed48x208 extends Fixed { + public static final Fixed48x208 DEFAULT = new Fixed48x208(BigInteger.ZERO); + + public Fixed48x208(BigInteger value) { + super(48, 208, value); + } + + public Fixed48x208(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 208, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x24.java new file mode 100644 index 0000000000..dcfcd011fa --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed48x24 extends Fixed { + public static final Fixed48x24 DEFAULT = new Fixed48x24(BigInteger.ZERO); + + public Fixed48x24(BigInteger value) { + super(48, 24, value); + } + + public Fixed48x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x32.java new file mode 100644 index 0000000000..623435e209 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed48x32 extends Fixed { + public static final Fixed48x32 DEFAULT = new Fixed48x32(BigInteger.ZERO); + + public Fixed48x32(BigInteger value) { + super(48, 32, value); + } + + public Fixed48x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x40.java new file mode 100644 index 0000000000..943c4a7ab4 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed48x40 extends Fixed { + public static final Fixed48x40 DEFAULT = new Fixed48x40(BigInteger.ZERO); + + public Fixed48x40(BigInteger value) { + super(48, 40, value); + } + + public Fixed48x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x48.java new file mode 100644 index 0000000000..b794b8ef7b --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed48x48 extends Fixed { + public static final Fixed48x48 DEFAULT = new Fixed48x48(BigInteger.ZERO); + + public Fixed48x48(BigInteger value) { + super(48, 48, value); + } + + public Fixed48x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x56.java new file mode 100644 index 0000000000..3712dc67bf --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x56.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed48x56 extends Fixed { + public static final Fixed48x56 DEFAULT = new Fixed48x56(BigInteger.ZERO); + + public Fixed48x56(BigInteger value) { + super(48, 56, value); + } + + public Fixed48x56(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 56, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x64.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x64.java new file mode 100644 index 0000000000..e8a7502e5f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x64.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed48x64 extends Fixed { + public static final Fixed48x64 DEFAULT = new Fixed48x64(BigInteger.ZERO); + + public Fixed48x64(BigInteger value) { + super(48, 64, value); + } + + public Fixed48x64(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 64, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x72.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x72.java new file mode 100644 index 0000000000..c5ea95d227 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x72.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed48x72 extends Fixed { + public static final Fixed48x72 DEFAULT = new Fixed48x72(BigInteger.ZERO); + + public Fixed48x72(BigInteger value) { + super(48, 72, value); + } + + public Fixed48x72(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 72, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x8.java new file mode 100644 index 0000000000..7e59a20680 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed48x8 extends Fixed { + public static final Fixed48x8 DEFAULT = new Fixed48x8(BigInteger.ZERO); + + public Fixed48x8(BigInteger value) { + super(48, 8, value); + } + + public Fixed48x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x80.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x80.java new file mode 100644 index 0000000000..b26dda2180 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x80.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed48x80 extends Fixed { + public static final Fixed48x80 DEFAULT = new Fixed48x80(BigInteger.ZERO); + + public Fixed48x80(BigInteger value) { + super(48, 80, value); + } + + public Fixed48x80(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 80, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x88.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x88.java new file mode 100644 index 0000000000..69cf6a2b28 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x88.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed48x88 extends Fixed { + public static final Fixed48x88 DEFAULT = new Fixed48x88(BigInteger.ZERO); + + public Fixed48x88(BigInteger value) { + super(48, 88, value); + } + + public Fixed48x88(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 88, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x96.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x96.java new file mode 100644 index 0000000000..716f0ea3ec --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed48x96.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed48x96 extends Fixed { + public static final Fixed48x96 DEFAULT = new Fixed48x96(BigInteger.ZERO); + + public Fixed48x96(BigInteger value) { + super(48, 96, value); + } + + public Fixed48x96(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 96, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x104.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x104.java new file mode 100644 index 0000000000..512678c371 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x104.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed56x104 extends Fixed { + public static final Fixed56x104 DEFAULT = new Fixed56x104(BigInteger.ZERO); + + public Fixed56x104(BigInteger value) { + super(56, 104, value); + } + + public Fixed56x104(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(56, 104, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x112.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x112.java new file mode 100644 index 0000000000..f5ff4382e5 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x112.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed56x112 extends Fixed { + public static final Fixed56x112 DEFAULT = new Fixed56x112(BigInteger.ZERO); + + public Fixed56x112(BigInteger value) { + super(56, 112, value); + } + + public Fixed56x112(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(56, 112, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x120.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x120.java new file mode 100644 index 0000000000..978bf0a327 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x120.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed56x120 extends Fixed { + public static final Fixed56x120 DEFAULT = new Fixed56x120(BigInteger.ZERO); + + public Fixed56x120(BigInteger value) { + super(56, 120, value); + } + + public Fixed56x120(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(56, 120, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x128.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x128.java new file mode 100644 index 0000000000..9a3daa802b --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x128.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed56x128 extends Fixed { + public static final Fixed56x128 DEFAULT = new Fixed56x128(BigInteger.ZERO); + + public Fixed56x128(BigInteger value) { + super(56, 128, value); + } + + public Fixed56x128(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(56, 128, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x136.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x136.java new file mode 100644 index 0000000000..38426a3403 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x136.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed56x136 extends Fixed { + public static final Fixed56x136 DEFAULT = new Fixed56x136(BigInteger.ZERO); + + public Fixed56x136(BigInteger value) { + super(56, 136, value); + } + + public Fixed56x136(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(56, 136, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x144.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x144.java new file mode 100644 index 0000000000..3442d1a1ab --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x144.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed56x144 extends Fixed { + public static final Fixed56x144 DEFAULT = new Fixed56x144(BigInteger.ZERO); + + public Fixed56x144(BigInteger value) { + super(56, 144, value); + } + + public Fixed56x144(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(56, 144, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x152.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x152.java new file mode 100644 index 0000000000..298776c06c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x152.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed56x152 extends Fixed { + public static final Fixed56x152 DEFAULT = new Fixed56x152(BigInteger.ZERO); + + public Fixed56x152(BigInteger value) { + super(56, 152, value); + } + + public Fixed56x152(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(56, 152, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x16.java new file mode 100644 index 0000000000..49c4a2a7d7 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed56x16 extends Fixed { + public static final Fixed56x16 DEFAULT = new Fixed56x16(BigInteger.ZERO); + + public Fixed56x16(BigInteger value) { + super(56, 16, value); + } + + public Fixed56x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(56, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x160.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x160.java new file mode 100644 index 0000000000..f0db9f7ed7 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x160.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed56x160 extends Fixed { + public static final Fixed56x160 DEFAULT = new Fixed56x160(BigInteger.ZERO); + + public Fixed56x160(BigInteger value) { + super(56, 160, value); + } + + public Fixed56x160(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(56, 160, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x168.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x168.java new file mode 100644 index 0000000000..3dfdbd4c51 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x168.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed56x168 extends Fixed { + public static final Fixed56x168 DEFAULT = new Fixed56x168(BigInteger.ZERO); + + public Fixed56x168(BigInteger value) { + super(56, 168, value); + } + + public Fixed56x168(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(56, 168, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x176.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x176.java new file mode 100644 index 0000000000..a2374d6039 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x176.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed56x176 extends Fixed { + public static final Fixed56x176 DEFAULT = new Fixed56x176(BigInteger.ZERO); + + public Fixed56x176(BigInteger value) { + super(56, 176, value); + } + + public Fixed56x176(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(56, 176, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x184.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x184.java new file mode 100644 index 0000000000..fbcc635d48 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x184.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed56x184 extends Fixed { + public static final Fixed56x184 DEFAULT = new Fixed56x184(BigInteger.ZERO); + + public Fixed56x184(BigInteger value) { + super(56, 184, value); + } + + public Fixed56x184(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(56, 184, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x192.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x192.java new file mode 100644 index 0000000000..0cd0982d34 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x192.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed56x192 extends Fixed { + public static final Fixed56x192 DEFAULT = new Fixed56x192(BigInteger.ZERO); + + public Fixed56x192(BigInteger value) { + super(56, 192, value); + } + + public Fixed56x192(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(56, 192, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x200.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x200.java new file mode 100644 index 0000000000..2b254470ae --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x200.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed56x200 extends Fixed { + public static final Fixed56x200 DEFAULT = new Fixed56x200(BigInteger.ZERO); + + public Fixed56x200(BigInteger value) { + super(56, 200, value); + } + + public Fixed56x200(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(56, 200, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x24.java new file mode 100644 index 0000000000..2ae8c815b1 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed56x24 extends Fixed { + public static final Fixed56x24 DEFAULT = new Fixed56x24(BigInteger.ZERO); + + public Fixed56x24(BigInteger value) { + super(56, 24, value); + } + + public Fixed56x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(56, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x32.java new file mode 100644 index 0000000000..ade48650b7 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed56x32 extends Fixed { + public static final Fixed56x32 DEFAULT = new Fixed56x32(BigInteger.ZERO); + + public Fixed56x32(BigInteger value) { + super(56, 32, value); + } + + public Fixed56x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(56, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x40.java new file mode 100644 index 0000000000..65aba1c6ff --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed56x40 extends Fixed { + public static final Fixed56x40 DEFAULT = new Fixed56x40(BigInteger.ZERO); + + public Fixed56x40(BigInteger value) { + super(56, 40, value); + } + + public Fixed56x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(56, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x48.java new file mode 100644 index 0000000000..9ea49032bf --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed56x48 extends Fixed { + public static final Fixed56x48 DEFAULT = new Fixed56x48(BigInteger.ZERO); + + public Fixed56x48(BigInteger value) { + super(56, 48, value); + } + + public Fixed56x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(56, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x56.java new file mode 100644 index 0000000000..3bf9bf2db6 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x56.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed56x56 extends Fixed { + public static final Fixed56x56 DEFAULT = new Fixed56x56(BigInteger.ZERO); + + public Fixed56x56(BigInteger value) { + super(56, 56, value); + } + + public Fixed56x56(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(56, 56, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x64.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x64.java new file mode 100644 index 0000000000..a645ec4218 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x64.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed56x64 extends Fixed { + public static final Fixed56x64 DEFAULT = new Fixed56x64(BigInteger.ZERO); + + public Fixed56x64(BigInteger value) { + super(56, 64, value); + } + + public Fixed56x64(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(56, 64, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x72.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x72.java new file mode 100644 index 0000000000..618c15968a --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x72.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed56x72 extends Fixed { + public static final Fixed56x72 DEFAULT = new Fixed56x72(BigInteger.ZERO); + + public Fixed56x72(BigInteger value) { + super(56, 72, value); + } + + public Fixed56x72(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(56, 72, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x8.java new file mode 100644 index 0000000000..8d7762acc6 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed56x8 extends Fixed { + public static final Fixed56x8 DEFAULT = new Fixed56x8(BigInteger.ZERO); + + public Fixed56x8(BigInteger value) { + super(56, 8, value); + } + + public Fixed56x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(56, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x80.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x80.java new file mode 100644 index 0000000000..bf32bf6003 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x80.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed56x80 extends Fixed { + public static final Fixed56x80 DEFAULT = new Fixed56x80(BigInteger.ZERO); + + public Fixed56x80(BigInteger value) { + super(56, 80, value); + } + + public Fixed56x80(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(56, 80, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x88.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x88.java new file mode 100644 index 0000000000..30fc219d36 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x88.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed56x88 extends Fixed { + public static final Fixed56x88 DEFAULT = new Fixed56x88(BigInteger.ZERO); + + public Fixed56x88(BigInteger value) { + super(56, 88, value); + } + + public Fixed56x88(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(56, 88, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x96.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x96.java new file mode 100644 index 0000000000..9e705f200b --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed56x96.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed56x96 extends Fixed { + public static final Fixed56x96 DEFAULT = new Fixed56x96(BigInteger.ZERO); + + public Fixed56x96(BigInteger value) { + super(56, 96, value); + } + + public Fixed56x96(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(56, 96, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x104.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x104.java new file mode 100644 index 0000000000..c9dd31db96 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x104.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed64x104 extends Fixed { + public static final Fixed64x104 DEFAULT = new Fixed64x104(BigInteger.ZERO); + + public Fixed64x104(BigInteger value) { + super(64, 104, value); + } + + public Fixed64x104(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(64, 104, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x112.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x112.java new file mode 100644 index 0000000000..456957c5f2 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x112.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed64x112 extends Fixed { + public static final Fixed64x112 DEFAULT = new Fixed64x112(BigInteger.ZERO); + + public Fixed64x112(BigInteger value) { + super(64, 112, value); + } + + public Fixed64x112(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(64, 112, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x120.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x120.java new file mode 100644 index 0000000000..0e24ceb39a --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x120.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed64x120 extends Fixed { + public static final Fixed64x120 DEFAULT = new Fixed64x120(BigInteger.ZERO); + + public Fixed64x120(BigInteger value) { + super(64, 120, value); + } + + public Fixed64x120(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(64, 120, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x128.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x128.java new file mode 100644 index 0000000000..b8f368aa2a --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x128.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed64x128 extends Fixed { + public static final Fixed64x128 DEFAULT = new Fixed64x128(BigInteger.ZERO); + + public Fixed64x128(BigInteger value) { + super(64, 128, value); + } + + public Fixed64x128(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(64, 128, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x136.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x136.java new file mode 100644 index 0000000000..edd856c99d --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x136.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed64x136 extends Fixed { + public static final Fixed64x136 DEFAULT = new Fixed64x136(BigInteger.ZERO); + + public Fixed64x136(BigInteger value) { + super(64, 136, value); + } + + public Fixed64x136(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(64, 136, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x144.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x144.java new file mode 100644 index 0000000000..8cab58f023 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x144.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed64x144 extends Fixed { + public static final Fixed64x144 DEFAULT = new Fixed64x144(BigInteger.ZERO); + + public Fixed64x144(BigInteger value) { + super(64, 144, value); + } + + public Fixed64x144(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(64, 144, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x152.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x152.java new file mode 100644 index 0000000000..bd3443a584 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x152.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed64x152 extends Fixed { + public static final Fixed64x152 DEFAULT = new Fixed64x152(BigInteger.ZERO); + + public Fixed64x152(BigInteger value) { + super(64, 152, value); + } + + public Fixed64x152(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(64, 152, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x16.java new file mode 100644 index 0000000000..1210cfdc38 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed64x16 extends Fixed { + public static final Fixed64x16 DEFAULT = new Fixed64x16(BigInteger.ZERO); + + public Fixed64x16(BigInteger value) { + super(64, 16, value); + } + + public Fixed64x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(64, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x160.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x160.java new file mode 100644 index 0000000000..c21733af83 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x160.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed64x160 extends Fixed { + public static final Fixed64x160 DEFAULT = new Fixed64x160(BigInteger.ZERO); + + public Fixed64x160(BigInteger value) { + super(64, 160, value); + } + + public Fixed64x160(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(64, 160, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x168.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x168.java new file mode 100644 index 0000000000..0bdbe8f391 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x168.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed64x168 extends Fixed { + public static final Fixed64x168 DEFAULT = new Fixed64x168(BigInteger.ZERO); + + public Fixed64x168(BigInteger value) { + super(64, 168, value); + } + + public Fixed64x168(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(64, 168, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x176.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x176.java new file mode 100644 index 0000000000..ea7d699cb1 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x176.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed64x176 extends Fixed { + public static final Fixed64x176 DEFAULT = new Fixed64x176(BigInteger.ZERO); + + public Fixed64x176(BigInteger value) { + super(64, 176, value); + } + + public Fixed64x176(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(64, 176, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x184.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x184.java new file mode 100644 index 0000000000..6ca1b1cb71 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x184.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed64x184 extends Fixed { + public static final Fixed64x184 DEFAULT = new Fixed64x184(BigInteger.ZERO); + + public Fixed64x184(BigInteger value) { + super(64, 184, value); + } + + public Fixed64x184(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(64, 184, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x192.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x192.java new file mode 100644 index 0000000000..641c9916cb --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x192.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed64x192 extends Fixed { + public static final Fixed64x192 DEFAULT = new Fixed64x192(BigInteger.ZERO); + + public Fixed64x192(BigInteger value) { + super(64, 192, value); + } + + public Fixed64x192(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(64, 192, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x24.java new file mode 100644 index 0000000000..b8869a6d69 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed64x24 extends Fixed { + public static final Fixed64x24 DEFAULT = new Fixed64x24(BigInteger.ZERO); + + public Fixed64x24(BigInteger value) { + super(64, 24, value); + } + + public Fixed64x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(64, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x32.java new file mode 100644 index 0000000000..86576dc5d9 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed64x32 extends Fixed { + public static final Fixed64x32 DEFAULT = new Fixed64x32(BigInteger.ZERO); + + public Fixed64x32(BigInteger value) { + super(64, 32, value); + } + + public Fixed64x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(64, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x40.java new file mode 100644 index 0000000000..19912d51ce --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed64x40 extends Fixed { + public static final Fixed64x40 DEFAULT = new Fixed64x40(BigInteger.ZERO); + + public Fixed64x40(BigInteger value) { + super(64, 40, value); + } + + public Fixed64x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(64, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x48.java new file mode 100644 index 0000000000..29c4e9513b --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed64x48 extends Fixed { + public static final Fixed64x48 DEFAULT = new Fixed64x48(BigInteger.ZERO); + + public Fixed64x48(BigInteger value) { + super(64, 48, value); + } + + public Fixed64x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(64, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x56.java new file mode 100644 index 0000000000..66756740c7 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x56.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed64x56 extends Fixed { + public static final Fixed64x56 DEFAULT = new Fixed64x56(BigInteger.ZERO); + + public Fixed64x56(BigInteger value) { + super(64, 56, value); + } + + public Fixed64x56(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(64, 56, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x64.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x64.java new file mode 100644 index 0000000000..950ba4f7f6 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x64.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed64x64 extends Fixed { + public static final Fixed64x64 DEFAULT = new Fixed64x64(BigInteger.ZERO); + + public Fixed64x64(BigInteger value) { + super(64, 64, value); + } + + public Fixed64x64(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(64, 64, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x72.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x72.java new file mode 100644 index 0000000000..1e293de70e --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x72.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed64x72 extends Fixed { + public static final Fixed64x72 DEFAULT = new Fixed64x72(BigInteger.ZERO); + + public Fixed64x72(BigInteger value) { + super(64, 72, value); + } + + public Fixed64x72(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(64, 72, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x8.java new file mode 100644 index 0000000000..d631657ab5 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed64x8 extends Fixed { + public static final Fixed64x8 DEFAULT = new Fixed64x8(BigInteger.ZERO); + + public Fixed64x8(BigInteger value) { + super(64, 8, value); + } + + public Fixed64x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(64, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x80.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x80.java new file mode 100644 index 0000000000..68ae10df09 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x80.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed64x80 extends Fixed { + public static final Fixed64x80 DEFAULT = new Fixed64x80(BigInteger.ZERO); + + public Fixed64x80(BigInteger value) { + super(64, 80, value); + } + + public Fixed64x80(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(64, 80, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x88.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x88.java new file mode 100644 index 0000000000..b4532b1f7e --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x88.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed64x88 extends Fixed { + public static final Fixed64x88 DEFAULT = new Fixed64x88(BigInteger.ZERO); + + public Fixed64x88(BigInteger value) { + super(64, 88, value); + } + + public Fixed64x88(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(64, 88, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x96.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x96.java new file mode 100644 index 0000000000..585b651634 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed64x96.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed64x96 extends Fixed { + public static final Fixed64x96 DEFAULT = new Fixed64x96(BigInteger.ZERO); + + public Fixed64x96(BigInteger value) { + super(64, 96, value); + } + + public Fixed64x96(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(64, 96, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x104.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x104.java new file mode 100644 index 0000000000..1eada532a8 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x104.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed72x104 extends Fixed { + public static final Fixed72x104 DEFAULT = new Fixed72x104(BigInteger.ZERO); + + public Fixed72x104(BigInteger value) { + super(72, 104, value); + } + + public Fixed72x104(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(72, 104, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x112.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x112.java new file mode 100644 index 0000000000..5529bb244d --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x112.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed72x112 extends Fixed { + public static final Fixed72x112 DEFAULT = new Fixed72x112(BigInteger.ZERO); + + public Fixed72x112(BigInteger value) { + super(72, 112, value); + } + + public Fixed72x112(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(72, 112, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x120.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x120.java new file mode 100644 index 0000000000..a064f0f413 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x120.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed72x120 extends Fixed { + public static final Fixed72x120 DEFAULT = new Fixed72x120(BigInteger.ZERO); + + public Fixed72x120(BigInteger value) { + super(72, 120, value); + } + + public Fixed72x120(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(72, 120, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x128.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x128.java new file mode 100644 index 0000000000..0314fc98a1 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x128.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed72x128 extends Fixed { + public static final Fixed72x128 DEFAULT = new Fixed72x128(BigInteger.ZERO); + + public Fixed72x128(BigInteger value) { + super(72, 128, value); + } + + public Fixed72x128(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(72, 128, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x136.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x136.java new file mode 100644 index 0000000000..040cab76f9 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x136.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed72x136 extends Fixed { + public static final Fixed72x136 DEFAULT = new Fixed72x136(BigInteger.ZERO); + + public Fixed72x136(BigInteger value) { + super(72, 136, value); + } + + public Fixed72x136(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(72, 136, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x144.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x144.java new file mode 100644 index 0000000000..5f72ebedd2 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x144.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed72x144 extends Fixed { + public static final Fixed72x144 DEFAULT = new Fixed72x144(BigInteger.ZERO); + + public Fixed72x144(BigInteger value) { + super(72, 144, value); + } + + public Fixed72x144(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(72, 144, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x152.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x152.java new file mode 100644 index 0000000000..08b26be5e0 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x152.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed72x152 extends Fixed { + public static final Fixed72x152 DEFAULT = new Fixed72x152(BigInteger.ZERO); + + public Fixed72x152(BigInteger value) { + super(72, 152, value); + } + + public Fixed72x152(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(72, 152, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x16.java new file mode 100644 index 0000000000..637b4f0f68 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed72x16 extends Fixed { + public static final Fixed72x16 DEFAULT = new Fixed72x16(BigInteger.ZERO); + + public Fixed72x16(BigInteger value) { + super(72, 16, value); + } + + public Fixed72x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(72, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x160.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x160.java new file mode 100644 index 0000000000..f1b6a64591 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x160.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed72x160 extends Fixed { + public static final Fixed72x160 DEFAULT = new Fixed72x160(BigInteger.ZERO); + + public Fixed72x160(BigInteger value) { + super(72, 160, value); + } + + public Fixed72x160(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(72, 160, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x168.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x168.java new file mode 100644 index 0000000000..531a29e384 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x168.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed72x168 extends Fixed { + public static final Fixed72x168 DEFAULT = new Fixed72x168(BigInteger.ZERO); + + public Fixed72x168(BigInteger value) { + super(72, 168, value); + } + + public Fixed72x168(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(72, 168, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x176.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x176.java new file mode 100644 index 0000000000..7be08cc354 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x176.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed72x176 extends Fixed { + public static final Fixed72x176 DEFAULT = new Fixed72x176(BigInteger.ZERO); + + public Fixed72x176(BigInteger value) { + super(72, 176, value); + } + + public Fixed72x176(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(72, 176, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x184.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x184.java new file mode 100644 index 0000000000..52d3fefdf9 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x184.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed72x184 extends Fixed { + public static final Fixed72x184 DEFAULT = new Fixed72x184(BigInteger.ZERO); + + public Fixed72x184(BigInteger value) { + super(72, 184, value); + } + + public Fixed72x184(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(72, 184, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x24.java new file mode 100644 index 0000000000..4fc18f4b7f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed72x24 extends Fixed { + public static final Fixed72x24 DEFAULT = new Fixed72x24(BigInteger.ZERO); + + public Fixed72x24(BigInteger value) { + super(72, 24, value); + } + + public Fixed72x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(72, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x32.java new file mode 100644 index 0000000000..58d24b1d7c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed72x32 extends Fixed { + public static final Fixed72x32 DEFAULT = new Fixed72x32(BigInteger.ZERO); + + public Fixed72x32(BigInteger value) { + super(72, 32, value); + } + + public Fixed72x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(72, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x40.java new file mode 100644 index 0000000000..b834e073b6 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed72x40 extends Fixed { + public static final Fixed72x40 DEFAULT = new Fixed72x40(BigInteger.ZERO); + + public Fixed72x40(BigInteger value) { + super(72, 40, value); + } + + public Fixed72x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(72, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x48.java new file mode 100644 index 0000000000..ecb22690da --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed72x48 extends Fixed { + public static final Fixed72x48 DEFAULT = new Fixed72x48(BigInteger.ZERO); + + public Fixed72x48(BigInteger value) { + super(72, 48, value); + } + + public Fixed72x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(72, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x56.java new file mode 100644 index 0000000000..2688cf835e --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x56.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed72x56 extends Fixed { + public static final Fixed72x56 DEFAULT = new Fixed72x56(BigInteger.ZERO); + + public Fixed72x56(BigInteger value) { + super(72, 56, value); + } + + public Fixed72x56(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(72, 56, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x64.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x64.java new file mode 100644 index 0000000000..83a8a318fe --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x64.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed72x64 extends Fixed { + public static final Fixed72x64 DEFAULT = new Fixed72x64(BigInteger.ZERO); + + public Fixed72x64(BigInteger value) { + super(72, 64, value); + } + + public Fixed72x64(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(72, 64, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x72.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x72.java new file mode 100644 index 0000000000..0438149a94 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x72.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed72x72 extends Fixed { + public static final Fixed72x72 DEFAULT = new Fixed72x72(BigInteger.ZERO); + + public Fixed72x72(BigInteger value) { + super(72, 72, value); + } + + public Fixed72x72(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(72, 72, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x8.java new file mode 100644 index 0000000000..659128cf4d --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed72x8 extends Fixed { + public static final Fixed72x8 DEFAULT = new Fixed72x8(BigInteger.ZERO); + + public Fixed72x8(BigInteger value) { + super(72, 8, value); + } + + public Fixed72x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(72, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x80.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x80.java new file mode 100644 index 0000000000..7825e42ad9 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x80.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed72x80 extends Fixed { + public static final Fixed72x80 DEFAULT = new Fixed72x80(BigInteger.ZERO); + + public Fixed72x80(BigInteger value) { + super(72, 80, value); + } + + public Fixed72x80(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(72, 80, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x88.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x88.java new file mode 100644 index 0000000000..f8575f3a27 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x88.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed72x88 extends Fixed { + public static final Fixed72x88 DEFAULT = new Fixed72x88(BigInteger.ZERO); + + public Fixed72x88(BigInteger value) { + super(72, 88, value); + } + + public Fixed72x88(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(72, 88, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x96.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x96.java new file mode 100644 index 0000000000..0f4e23433b --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed72x96.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed72x96 extends Fixed { + public static final Fixed72x96 DEFAULT = new Fixed72x96(BigInteger.ZERO); + + public Fixed72x96(BigInteger value) { + super(72, 96, value); + } + + public Fixed72x96(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(72, 96, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x104.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x104.java new file mode 100644 index 0000000000..b046c18b42 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x104.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed80x104 extends Fixed { + public static final Fixed80x104 DEFAULT = new Fixed80x104(BigInteger.ZERO); + + public Fixed80x104(BigInteger value) { + super(80, 104, value); + } + + public Fixed80x104(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(80, 104, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x112.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x112.java new file mode 100644 index 0000000000..32d6bb9f8d --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x112.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed80x112 extends Fixed { + public static final Fixed80x112 DEFAULT = new Fixed80x112(BigInteger.ZERO); + + public Fixed80x112(BigInteger value) { + super(80, 112, value); + } + + public Fixed80x112(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(80, 112, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x120.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x120.java new file mode 100644 index 0000000000..69b78e1b79 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x120.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed80x120 extends Fixed { + public static final Fixed80x120 DEFAULT = new Fixed80x120(BigInteger.ZERO); + + public Fixed80x120(BigInteger value) { + super(80, 120, value); + } + + public Fixed80x120(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(80, 120, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x128.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x128.java new file mode 100644 index 0000000000..ec2c54f833 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x128.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed80x128 extends Fixed { + public static final Fixed80x128 DEFAULT = new Fixed80x128(BigInteger.ZERO); + + public Fixed80x128(BigInteger value) { + super(80, 128, value); + } + + public Fixed80x128(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(80, 128, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x136.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x136.java new file mode 100644 index 0000000000..e486b3ff41 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x136.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed80x136 extends Fixed { + public static final Fixed80x136 DEFAULT = new Fixed80x136(BigInteger.ZERO); + + public Fixed80x136(BigInteger value) { + super(80, 136, value); + } + + public Fixed80x136(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(80, 136, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x144.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x144.java new file mode 100644 index 0000000000..4024a5fa72 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x144.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed80x144 extends Fixed { + public static final Fixed80x144 DEFAULT = new Fixed80x144(BigInteger.ZERO); + + public Fixed80x144(BigInteger value) { + super(80, 144, value); + } + + public Fixed80x144(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(80, 144, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x152.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x152.java new file mode 100644 index 0000000000..c46877b985 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x152.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed80x152 extends Fixed { + public static final Fixed80x152 DEFAULT = new Fixed80x152(BigInteger.ZERO); + + public Fixed80x152(BigInteger value) { + super(80, 152, value); + } + + public Fixed80x152(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(80, 152, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x16.java new file mode 100644 index 0000000000..cc1b6966cb --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed80x16 extends Fixed { + public static final Fixed80x16 DEFAULT = new Fixed80x16(BigInteger.ZERO); + + public Fixed80x16(BigInteger value) { + super(80, 16, value); + } + + public Fixed80x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(80, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x160.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x160.java new file mode 100644 index 0000000000..459e8550d5 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x160.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed80x160 extends Fixed { + public static final Fixed80x160 DEFAULT = new Fixed80x160(BigInteger.ZERO); + + public Fixed80x160(BigInteger value) { + super(80, 160, value); + } + + public Fixed80x160(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(80, 160, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x168.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x168.java new file mode 100644 index 0000000000..37efdf1dad --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x168.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed80x168 extends Fixed { + public static final Fixed80x168 DEFAULT = new Fixed80x168(BigInteger.ZERO); + + public Fixed80x168(BigInteger value) { + super(80, 168, value); + } + + public Fixed80x168(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(80, 168, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x176.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x176.java new file mode 100644 index 0000000000..11dae039ef --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x176.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed80x176 extends Fixed { + public static final Fixed80x176 DEFAULT = new Fixed80x176(BigInteger.ZERO); + + public Fixed80x176(BigInteger value) { + super(80, 176, value); + } + + public Fixed80x176(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(80, 176, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x24.java new file mode 100644 index 0000000000..a1857c0cdd --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed80x24 extends Fixed { + public static final Fixed80x24 DEFAULT = new Fixed80x24(BigInteger.ZERO); + + public Fixed80x24(BigInteger value) { + super(80, 24, value); + } + + public Fixed80x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(80, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x32.java new file mode 100644 index 0000000000..f032a71451 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed80x32 extends Fixed { + public static final Fixed80x32 DEFAULT = new Fixed80x32(BigInteger.ZERO); + + public Fixed80x32(BigInteger value) { + super(80, 32, value); + } + + public Fixed80x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(80, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x40.java new file mode 100644 index 0000000000..2d0a97fdef --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed80x40 extends Fixed { + public static final Fixed80x40 DEFAULT = new Fixed80x40(BigInteger.ZERO); + + public Fixed80x40(BigInteger value) { + super(80, 40, value); + } + + public Fixed80x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(80, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x48.java new file mode 100644 index 0000000000..b20ecbd9ae --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed80x48 extends Fixed { + public static final Fixed80x48 DEFAULT = new Fixed80x48(BigInteger.ZERO); + + public Fixed80x48(BigInteger value) { + super(80, 48, value); + } + + public Fixed80x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(80, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x56.java new file mode 100644 index 0000000000..8f293850b3 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x56.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed80x56 extends Fixed { + public static final Fixed80x56 DEFAULT = new Fixed80x56(BigInteger.ZERO); + + public Fixed80x56(BigInteger value) { + super(80, 56, value); + } + + public Fixed80x56(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(80, 56, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x64.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x64.java new file mode 100644 index 0000000000..99ededc26c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x64.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed80x64 extends Fixed { + public static final Fixed80x64 DEFAULT = new Fixed80x64(BigInteger.ZERO); + + public Fixed80x64(BigInteger value) { + super(80, 64, value); + } + + public Fixed80x64(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(80, 64, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x72.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x72.java new file mode 100644 index 0000000000..727000e6ac --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x72.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed80x72 extends Fixed { + public static final Fixed80x72 DEFAULT = new Fixed80x72(BigInteger.ZERO); + + public Fixed80x72(BigInteger value) { + super(80, 72, value); + } + + public Fixed80x72(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(80, 72, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x8.java new file mode 100644 index 0000000000..36ed85588f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed80x8 extends Fixed { + public static final Fixed80x8 DEFAULT = new Fixed80x8(BigInteger.ZERO); + + public Fixed80x8(BigInteger value) { + super(80, 8, value); + } + + public Fixed80x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(80, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x80.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x80.java new file mode 100644 index 0000000000..9ce39e8436 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x80.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed80x80 extends Fixed { + public static final Fixed80x80 DEFAULT = new Fixed80x80(BigInteger.ZERO); + + public Fixed80x80(BigInteger value) { + super(80, 80, value); + } + + public Fixed80x80(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(80, 80, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x88.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x88.java new file mode 100644 index 0000000000..53abb5efac --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x88.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed80x88 extends Fixed { + public static final Fixed80x88 DEFAULT = new Fixed80x88(BigInteger.ZERO); + + public Fixed80x88(BigInteger value) { + super(80, 88, value); + } + + public Fixed80x88(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(80, 88, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x96.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x96.java new file mode 100644 index 0000000000..50c6a3041a --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed80x96.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed80x96 extends Fixed { + public static final Fixed80x96 DEFAULT = new Fixed80x96(BigInteger.ZERO); + + public Fixed80x96(BigInteger value) { + super(80, 96, value); + } + + public Fixed80x96(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(80, 96, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x104.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x104.java new file mode 100644 index 0000000000..6524823048 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x104.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed88x104 extends Fixed { + public static final Fixed88x104 DEFAULT = new Fixed88x104(BigInteger.ZERO); + + public Fixed88x104(BigInteger value) { + super(88, 104, value); + } + + public Fixed88x104(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(88, 104, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x112.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x112.java new file mode 100644 index 0000000000..3f9edac1db --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x112.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed88x112 extends Fixed { + public static final Fixed88x112 DEFAULT = new Fixed88x112(BigInteger.ZERO); + + public Fixed88x112(BigInteger value) { + super(88, 112, value); + } + + public Fixed88x112(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(88, 112, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x120.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x120.java new file mode 100644 index 0000000000..1d98188e60 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x120.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed88x120 extends Fixed { + public static final Fixed88x120 DEFAULT = new Fixed88x120(BigInteger.ZERO); + + public Fixed88x120(BigInteger value) { + super(88, 120, value); + } + + public Fixed88x120(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(88, 120, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x128.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x128.java new file mode 100644 index 0000000000..11821406b2 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x128.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed88x128 extends Fixed { + public static final Fixed88x128 DEFAULT = new Fixed88x128(BigInteger.ZERO); + + public Fixed88x128(BigInteger value) { + super(88, 128, value); + } + + public Fixed88x128(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(88, 128, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x136.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x136.java new file mode 100644 index 0000000000..9efd57b60f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x136.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed88x136 extends Fixed { + public static final Fixed88x136 DEFAULT = new Fixed88x136(BigInteger.ZERO); + + public Fixed88x136(BigInteger value) { + super(88, 136, value); + } + + public Fixed88x136(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(88, 136, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x144.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x144.java new file mode 100644 index 0000000000..6e4aeb38ed --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x144.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed88x144 extends Fixed { + public static final Fixed88x144 DEFAULT = new Fixed88x144(BigInteger.ZERO); + + public Fixed88x144(BigInteger value) { + super(88, 144, value); + } + + public Fixed88x144(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(88, 144, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x152.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x152.java new file mode 100644 index 0000000000..4eeded31d5 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x152.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed88x152 extends Fixed { + public static final Fixed88x152 DEFAULT = new Fixed88x152(BigInteger.ZERO); + + public Fixed88x152(BigInteger value) { + super(88, 152, value); + } + + public Fixed88x152(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(88, 152, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x16.java new file mode 100644 index 0000000000..ca41ed1a33 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed88x16 extends Fixed { + public static final Fixed88x16 DEFAULT = new Fixed88x16(BigInteger.ZERO); + + public Fixed88x16(BigInteger value) { + super(88, 16, value); + } + + public Fixed88x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(88, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x160.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x160.java new file mode 100644 index 0000000000..ccdaea70f7 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x160.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed88x160 extends Fixed { + public static final Fixed88x160 DEFAULT = new Fixed88x160(BigInteger.ZERO); + + public Fixed88x160(BigInteger value) { + super(88, 160, value); + } + + public Fixed88x160(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(88, 160, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x168.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x168.java new file mode 100644 index 0000000000..2404528012 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x168.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed88x168 extends Fixed { + public static final Fixed88x168 DEFAULT = new Fixed88x168(BigInteger.ZERO); + + public Fixed88x168(BigInteger value) { + super(88, 168, value); + } + + public Fixed88x168(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(88, 168, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x24.java new file mode 100644 index 0000000000..c5869555fd --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed88x24 extends Fixed { + public static final Fixed88x24 DEFAULT = new Fixed88x24(BigInteger.ZERO); + + public Fixed88x24(BigInteger value) { + super(88, 24, value); + } + + public Fixed88x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(88, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x32.java new file mode 100644 index 0000000000..3e9dc72fec --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed88x32 extends Fixed { + public static final Fixed88x32 DEFAULT = new Fixed88x32(BigInteger.ZERO); + + public Fixed88x32(BigInteger value) { + super(88, 32, value); + } + + public Fixed88x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(88, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x40.java new file mode 100644 index 0000000000..5069b13e11 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed88x40 extends Fixed { + public static final Fixed88x40 DEFAULT = new Fixed88x40(BigInteger.ZERO); + + public Fixed88x40(BigInteger value) { + super(88, 40, value); + } + + public Fixed88x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(88, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x48.java new file mode 100644 index 0000000000..f7548f90ec --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed88x48 extends Fixed { + public static final Fixed88x48 DEFAULT = new Fixed88x48(BigInteger.ZERO); + + public Fixed88x48(BigInteger value) { + super(88, 48, value); + } + + public Fixed88x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(88, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x56.java new file mode 100644 index 0000000000..4ad4b49e5f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x56.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed88x56 extends Fixed { + public static final Fixed88x56 DEFAULT = new Fixed88x56(BigInteger.ZERO); + + public Fixed88x56(BigInteger value) { + super(88, 56, value); + } + + public Fixed88x56(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(88, 56, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x64.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x64.java new file mode 100644 index 0000000000..9c0d0dffbf --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x64.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed88x64 extends Fixed { + public static final Fixed88x64 DEFAULT = new Fixed88x64(BigInteger.ZERO); + + public Fixed88x64(BigInteger value) { + super(88, 64, value); + } + + public Fixed88x64(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(88, 64, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x72.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x72.java new file mode 100644 index 0000000000..c8b9757810 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x72.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed88x72 extends Fixed { + public static final Fixed88x72 DEFAULT = new Fixed88x72(BigInteger.ZERO); + + public Fixed88x72(BigInteger value) { + super(88, 72, value); + } + + public Fixed88x72(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(88, 72, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x8.java new file mode 100644 index 0000000000..0078213a64 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed88x8 extends Fixed { + public static final Fixed88x8 DEFAULT = new Fixed88x8(BigInteger.ZERO); + + public Fixed88x8(BigInteger value) { + super(88, 8, value); + } + + public Fixed88x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(88, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x80.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x80.java new file mode 100644 index 0000000000..ffee3e1d9e --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x80.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed88x80 extends Fixed { + public static final Fixed88x80 DEFAULT = new Fixed88x80(BigInteger.ZERO); + + public Fixed88x80(BigInteger value) { + super(88, 80, value); + } + + public Fixed88x80(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(88, 80, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x88.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x88.java new file mode 100644 index 0000000000..91c96633c0 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x88.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed88x88 extends Fixed { + public static final Fixed88x88 DEFAULT = new Fixed88x88(BigInteger.ZERO); + + public Fixed88x88(BigInteger value) { + super(88, 88, value); + } + + public Fixed88x88(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(88, 88, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x96.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x96.java new file mode 100644 index 0000000000..9f1a7e3e44 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed88x96.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed88x96 extends Fixed { + public static final Fixed88x96 DEFAULT = new Fixed88x96(BigInteger.ZERO); + + public Fixed88x96(BigInteger value) { + super(88, 96, value); + } + + public Fixed88x96(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(88, 96, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x104.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x104.java new file mode 100644 index 0000000000..817205494f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x104.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed8x104 extends Fixed { + public static final Fixed8x104 DEFAULT = new Fixed8x104(BigInteger.ZERO); + + public Fixed8x104(BigInteger value) { + super(8, 104, value); + } + + public Fixed8x104(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 104, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x112.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x112.java new file mode 100644 index 0000000000..0fa7b41900 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x112.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed8x112 extends Fixed { + public static final Fixed8x112 DEFAULT = new Fixed8x112(BigInteger.ZERO); + + public Fixed8x112(BigInteger value) { + super(8, 112, value); + } + + public Fixed8x112(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 112, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x120.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x120.java new file mode 100644 index 0000000000..d87804bbbb --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x120.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed8x120 extends Fixed { + public static final Fixed8x120 DEFAULT = new Fixed8x120(BigInteger.ZERO); + + public Fixed8x120(BigInteger value) { + super(8, 120, value); + } + + public Fixed8x120(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 120, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x128.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x128.java new file mode 100644 index 0000000000..7223a1868e --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x128.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed8x128 extends Fixed { + public static final Fixed8x128 DEFAULT = new Fixed8x128(BigInteger.ZERO); + + public Fixed8x128(BigInteger value) { + super(8, 128, value); + } + + public Fixed8x128(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 128, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x136.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x136.java new file mode 100644 index 0000000000..cb57ac7480 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x136.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed8x136 extends Fixed { + public static final Fixed8x136 DEFAULT = new Fixed8x136(BigInteger.ZERO); + + public Fixed8x136(BigInteger value) { + super(8, 136, value); + } + + public Fixed8x136(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 136, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x144.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x144.java new file mode 100644 index 0000000000..75a6a8c791 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x144.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed8x144 extends Fixed { + public static final Fixed8x144 DEFAULT = new Fixed8x144(BigInteger.ZERO); + + public Fixed8x144(BigInteger value) { + super(8, 144, value); + } + + public Fixed8x144(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 144, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x152.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x152.java new file mode 100644 index 0000000000..530ce8fc51 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x152.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed8x152 extends Fixed { + public static final Fixed8x152 DEFAULT = new Fixed8x152(BigInteger.ZERO); + + public Fixed8x152(BigInteger value) { + super(8, 152, value); + } + + public Fixed8x152(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 152, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x16.java new file mode 100644 index 0000000000..fc77367154 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed8x16 extends Fixed { + public static final Fixed8x16 DEFAULT = new Fixed8x16(BigInteger.ZERO); + + public Fixed8x16(BigInteger value) { + super(8, 16, value); + } + + public Fixed8x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x160.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x160.java new file mode 100644 index 0000000000..8ca9495fb2 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x160.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed8x160 extends Fixed { + public static final Fixed8x160 DEFAULT = new Fixed8x160(BigInteger.ZERO); + + public Fixed8x160(BigInteger value) { + super(8, 160, value); + } + + public Fixed8x160(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 160, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x168.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x168.java new file mode 100644 index 0000000000..d5982b68c8 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x168.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed8x168 extends Fixed { + public static final Fixed8x168 DEFAULT = new Fixed8x168(BigInteger.ZERO); + + public Fixed8x168(BigInteger value) { + super(8, 168, value); + } + + public Fixed8x168(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 168, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x176.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x176.java new file mode 100644 index 0000000000..ebf4b235ff --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x176.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed8x176 extends Fixed { + public static final Fixed8x176 DEFAULT = new Fixed8x176(BigInteger.ZERO); + + public Fixed8x176(BigInteger value) { + super(8, 176, value); + } + + public Fixed8x176(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 176, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x184.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x184.java new file mode 100644 index 0000000000..be9e3dfb31 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x184.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed8x184 extends Fixed { + public static final Fixed8x184 DEFAULT = new Fixed8x184(BigInteger.ZERO); + + public Fixed8x184(BigInteger value) { + super(8, 184, value); + } + + public Fixed8x184(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 184, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x192.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x192.java new file mode 100644 index 0000000000..6036206f58 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x192.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed8x192 extends Fixed { + public static final Fixed8x192 DEFAULT = new Fixed8x192(BigInteger.ZERO); + + public Fixed8x192(BigInteger value) { + super(8, 192, value); + } + + public Fixed8x192(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 192, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x200.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x200.java new file mode 100644 index 0000000000..fbe44f7c32 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x200.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed8x200 extends Fixed { + public static final Fixed8x200 DEFAULT = new Fixed8x200(BigInteger.ZERO); + + public Fixed8x200(BigInteger value) { + super(8, 200, value); + } + + public Fixed8x200(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 200, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x208.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x208.java new file mode 100644 index 0000000000..d29519a80d --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x208.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed8x208 extends Fixed { + public static final Fixed8x208 DEFAULT = new Fixed8x208(BigInteger.ZERO); + + public Fixed8x208(BigInteger value) { + super(8, 208, value); + } + + public Fixed8x208(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 208, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x216.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x216.java new file mode 100644 index 0000000000..505f7db089 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x216.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed8x216 extends Fixed { + public static final Fixed8x216 DEFAULT = new Fixed8x216(BigInteger.ZERO); + + public Fixed8x216(BigInteger value) { + super(8, 216, value); + } + + public Fixed8x216(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 216, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x224.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x224.java new file mode 100644 index 0000000000..be191e406d --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x224.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed8x224 extends Fixed { + public static final Fixed8x224 DEFAULT = new Fixed8x224(BigInteger.ZERO); + + public Fixed8x224(BigInteger value) { + super(8, 224, value); + } + + public Fixed8x224(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 224, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x232.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x232.java new file mode 100644 index 0000000000..d9a24ab349 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x232.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed8x232 extends Fixed { + public static final Fixed8x232 DEFAULT = new Fixed8x232(BigInteger.ZERO); + + public Fixed8x232(BigInteger value) { + super(8, 232, value); + } + + public Fixed8x232(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 232, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x24.java new file mode 100644 index 0000000000..62088a1ee9 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed8x24 extends Fixed { + public static final Fixed8x24 DEFAULT = new Fixed8x24(BigInteger.ZERO); + + public Fixed8x24(BigInteger value) { + super(8, 24, value); + } + + public Fixed8x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x240.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x240.java new file mode 100644 index 0000000000..ac0c4f0fa5 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x240.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed8x240 extends Fixed { + public static final Fixed8x240 DEFAULT = new Fixed8x240(BigInteger.ZERO); + + public Fixed8x240(BigInteger value) { + super(8, 240, value); + } + + public Fixed8x240(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 240, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x248.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x248.java new file mode 100644 index 0000000000..77fe19a6e1 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x248.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed8x248 extends Fixed { + public static final Fixed8x248 DEFAULT = new Fixed8x248(BigInteger.ZERO); + + public Fixed8x248(BigInteger value) { + super(8, 248, value); + } + + public Fixed8x248(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 248, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x32.java new file mode 100644 index 0000000000..5a8c2fefb2 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed8x32 extends Fixed { + public static final Fixed8x32 DEFAULT = new Fixed8x32(BigInteger.ZERO); + + public Fixed8x32(BigInteger value) { + super(8, 32, value); + } + + public Fixed8x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x40.java new file mode 100644 index 0000000000..f7cbfe51be --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed8x40 extends Fixed { + public static final Fixed8x40 DEFAULT = new Fixed8x40(BigInteger.ZERO); + + public Fixed8x40(BigInteger value) { + super(8, 40, value); + } + + public Fixed8x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x48.java new file mode 100644 index 0000000000..6ab6fd17a6 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed8x48 extends Fixed { + public static final Fixed8x48 DEFAULT = new Fixed8x48(BigInteger.ZERO); + + public Fixed8x48(BigInteger value) { + super(8, 48, value); + } + + public Fixed8x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x56.java new file mode 100644 index 0000000000..33f4509c8b --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x56.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed8x56 extends Fixed { + public static final Fixed8x56 DEFAULT = new Fixed8x56(BigInteger.ZERO); + + public Fixed8x56(BigInteger value) { + super(8, 56, value); + } + + public Fixed8x56(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 56, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x64.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x64.java new file mode 100644 index 0000000000..5949173212 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x64.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed8x64 extends Fixed { + public static final Fixed8x64 DEFAULT = new Fixed8x64(BigInteger.ZERO); + + public Fixed8x64(BigInteger value) { + super(8, 64, value); + } + + public Fixed8x64(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 64, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x72.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x72.java new file mode 100644 index 0000000000..697d7a1b28 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x72.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed8x72 extends Fixed { + public static final Fixed8x72 DEFAULT = new Fixed8x72(BigInteger.ZERO); + + public Fixed8x72(BigInteger value) { + super(8, 72, value); + } + + public Fixed8x72(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 72, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x8.java new file mode 100644 index 0000000000..68534d62f6 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed8x8 extends Fixed { + public static final Fixed8x8 DEFAULT = new Fixed8x8(BigInteger.ZERO); + + public Fixed8x8(BigInteger value) { + super(8, 8, value); + } + + public Fixed8x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x80.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x80.java new file mode 100644 index 0000000000..171fd58b00 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x80.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed8x80 extends Fixed { + public static final Fixed8x80 DEFAULT = new Fixed8x80(BigInteger.ZERO); + + public Fixed8x80(BigInteger value) { + super(8, 80, value); + } + + public Fixed8x80(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 80, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x88.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x88.java new file mode 100644 index 0000000000..ec92380ed6 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x88.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed8x88 extends Fixed { + public static final Fixed8x88 DEFAULT = new Fixed8x88(BigInteger.ZERO); + + public Fixed8x88(BigInteger value) { + super(8, 88, value); + } + + public Fixed8x88(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 88, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x96.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x96.java new file mode 100644 index 0000000000..37be88eb98 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed8x96.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed8x96 extends Fixed { + public static final Fixed8x96 DEFAULT = new Fixed8x96(BigInteger.ZERO); + + public Fixed8x96(BigInteger value) { + super(8, 96, value); + } + + public Fixed8x96(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 96, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x104.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x104.java new file mode 100644 index 0000000000..79d23fa443 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x104.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed96x104 extends Fixed { + public static final Fixed96x104 DEFAULT = new Fixed96x104(BigInteger.ZERO); + + public Fixed96x104(BigInteger value) { + super(96, 104, value); + } + + public Fixed96x104(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(96, 104, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x112.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x112.java new file mode 100644 index 0000000000..bbf109d33f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x112.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed96x112 extends Fixed { + public static final Fixed96x112 DEFAULT = new Fixed96x112(BigInteger.ZERO); + + public Fixed96x112(BigInteger value) { + super(96, 112, value); + } + + public Fixed96x112(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(96, 112, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x120.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x120.java new file mode 100644 index 0000000000..d17fa31967 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x120.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed96x120 extends Fixed { + public static final Fixed96x120 DEFAULT = new Fixed96x120(BigInteger.ZERO); + + public Fixed96x120(BigInteger value) { + super(96, 120, value); + } + + public Fixed96x120(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(96, 120, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x128.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x128.java new file mode 100644 index 0000000000..438b89e1bc --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x128.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed96x128 extends Fixed { + public static final Fixed96x128 DEFAULT = new Fixed96x128(BigInteger.ZERO); + + public Fixed96x128(BigInteger value) { + super(96, 128, value); + } + + public Fixed96x128(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(96, 128, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x136.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x136.java new file mode 100644 index 0000000000..68e7ba2efa --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x136.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed96x136 extends Fixed { + public static final Fixed96x136 DEFAULT = new Fixed96x136(BigInteger.ZERO); + + public Fixed96x136(BigInteger value) { + super(96, 136, value); + } + + public Fixed96x136(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(96, 136, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x144.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x144.java new file mode 100644 index 0000000000..7e203c9298 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x144.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed96x144 extends Fixed { + public static final Fixed96x144 DEFAULT = new Fixed96x144(BigInteger.ZERO); + + public Fixed96x144(BigInteger value) { + super(96, 144, value); + } + + public Fixed96x144(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(96, 144, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x152.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x152.java new file mode 100644 index 0000000000..83c964fe0a --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x152.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed96x152 extends Fixed { + public static final Fixed96x152 DEFAULT = new Fixed96x152(BigInteger.ZERO); + + public Fixed96x152(BigInteger value) { + super(96, 152, value); + } + + public Fixed96x152(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(96, 152, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x16.java new file mode 100644 index 0000000000..9d731a6f89 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed96x16 extends Fixed { + public static final Fixed96x16 DEFAULT = new Fixed96x16(BigInteger.ZERO); + + public Fixed96x16(BigInteger value) { + super(96, 16, value); + } + + public Fixed96x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(96, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x160.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x160.java new file mode 100644 index 0000000000..f52654fb35 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x160.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed96x160 extends Fixed { + public static final Fixed96x160 DEFAULT = new Fixed96x160(BigInteger.ZERO); + + public Fixed96x160(BigInteger value) { + super(96, 160, value); + } + + public Fixed96x160(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(96, 160, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x24.java new file mode 100644 index 0000000000..f932b682ed --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed96x24 extends Fixed { + public static final Fixed96x24 DEFAULT = new Fixed96x24(BigInteger.ZERO); + + public Fixed96x24(BigInteger value) { + super(96, 24, value); + } + + public Fixed96x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(96, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x32.java new file mode 100644 index 0000000000..4e43b6370c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed96x32 extends Fixed { + public static final Fixed96x32 DEFAULT = new Fixed96x32(BigInteger.ZERO); + + public Fixed96x32(BigInteger value) { + super(96, 32, value); + } + + public Fixed96x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(96, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x40.java new file mode 100644 index 0000000000..0b11ec22fc --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed96x40 extends Fixed { + public static final Fixed96x40 DEFAULT = new Fixed96x40(BigInteger.ZERO); + + public Fixed96x40(BigInteger value) { + super(96, 40, value); + } + + public Fixed96x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(96, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x48.java new file mode 100644 index 0000000000..0d993f6446 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed96x48 extends Fixed { + public static final Fixed96x48 DEFAULT = new Fixed96x48(BigInteger.ZERO); + + public Fixed96x48(BigInteger value) { + super(96, 48, value); + } + + public Fixed96x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(96, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x56.java new file mode 100644 index 0000000000..c87779a8a9 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x56.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed96x56 extends Fixed { + public static final Fixed96x56 DEFAULT = new Fixed96x56(BigInteger.ZERO); + + public Fixed96x56(BigInteger value) { + super(96, 56, value); + } + + public Fixed96x56(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(96, 56, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x64.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x64.java new file mode 100644 index 0000000000..fe1cd59c9c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x64.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed96x64 extends Fixed { + public static final Fixed96x64 DEFAULT = new Fixed96x64(BigInteger.ZERO); + + public Fixed96x64(BigInteger value) { + super(96, 64, value); + } + + public Fixed96x64(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(96, 64, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x72.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x72.java new file mode 100644 index 0000000000..714e5a0966 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x72.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed96x72 extends Fixed { + public static final Fixed96x72 DEFAULT = new Fixed96x72(BigInteger.ZERO); + + public Fixed96x72(BigInteger value) { + super(96, 72, value); + } + + public Fixed96x72(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(96, 72, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x8.java new file mode 100644 index 0000000000..c25eec65a2 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed96x8 extends Fixed { + public static final Fixed96x8 DEFAULT = new Fixed96x8(BigInteger.ZERO); + + public Fixed96x8(BigInteger value) { + super(96, 8, value); + } + + public Fixed96x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(96, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x80.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x80.java new file mode 100644 index 0000000000..41fa1bc05b --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x80.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed96x80 extends Fixed { + public static final Fixed96x80 DEFAULT = new Fixed96x80(BigInteger.ZERO); + + public Fixed96x80(BigInteger value) { + super(96, 80, value); + } + + public Fixed96x80(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(96, 80, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x88.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x88.java new file mode 100644 index 0000000000..998db45950 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x88.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed96x88 extends Fixed { + public static final Fixed96x88 DEFAULT = new Fixed96x88(BigInteger.ZERO); + + public Fixed96x88(BigInteger value) { + super(96, 88, value); + } + + public Fixed96x88(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(96, 88, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x96.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x96.java new file mode 100644 index 0000000000..0684cf39f9 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Fixed96x96.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Fixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Fixed96x96 extends Fixed { + public static final Fixed96x96 DEFAULT = new Fixed96x96(BigInteger.ZERO); + + public Fixed96x96(BigInteger value) { + super(96, 96, value); + } + + public Fixed96x96(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(96, 96, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int104.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int104.java new file mode 100644 index 0000000000..23add28430 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int104.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Int; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Int104 extends Int { + public static final Int104 DEFAULT = new Int104(BigInteger.ZERO); + + public Int104(BigInteger value) { + super(104, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int112.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int112.java new file mode 100644 index 0000000000..0f898f2c3e --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int112.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Int; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Int112 extends Int { + public static final Int112 DEFAULT = new Int112(BigInteger.ZERO); + + public Int112(BigInteger value) { + super(112, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int120.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int120.java new file mode 100644 index 0000000000..e72d93c907 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int120.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Int; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Int120 extends Int { + public static final Int120 DEFAULT = new Int120(BigInteger.ZERO); + + public Int120(BigInteger value) { + super(120, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int128.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int128.java new file mode 100644 index 0000000000..19c37b3afd --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int128.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Int; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Int128 extends Int { + public static final Int128 DEFAULT = new Int128(BigInteger.ZERO); + + public Int128(BigInteger value) { + super(128, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int136.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int136.java new file mode 100644 index 0000000000..b3bc93e722 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int136.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Int; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Int136 extends Int { + public static final Int136 DEFAULT = new Int136(BigInteger.ZERO); + + public Int136(BigInteger value) { + super(136, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int144.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int144.java new file mode 100644 index 0000000000..17db690f91 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int144.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Int; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Int144 extends Int { + public static final Int144 DEFAULT = new Int144(BigInteger.ZERO); + + public Int144(BigInteger value) { + super(144, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int152.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int152.java new file mode 100644 index 0000000000..7d98fdd724 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int152.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Int; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Int152 extends Int { + public static final Int152 DEFAULT = new Int152(BigInteger.ZERO); + + public Int152(BigInteger value) { + super(152, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int16.java new file mode 100644 index 0000000000..d9671e5a82 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int16.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Int; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Int16 extends Int { + public static final Int16 DEFAULT = new Int16(BigInteger.ZERO); + + public Int16(BigInteger value) { + super(16, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int160.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int160.java new file mode 100644 index 0000000000..fdd6c80dfe --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int160.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Int; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Int160 extends Int { + public static final Int160 DEFAULT = new Int160(BigInteger.ZERO); + + public Int160(BigInteger value) { + super(160, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int168.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int168.java new file mode 100644 index 0000000000..ab8f524857 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int168.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Int; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Int168 extends Int { + public static final Int168 DEFAULT = new Int168(BigInteger.ZERO); + + public Int168(BigInteger value) { + super(168, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int176.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int176.java new file mode 100644 index 0000000000..f62753cf3e --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int176.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Int; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Int176 extends Int { + public static final Int176 DEFAULT = new Int176(BigInteger.ZERO); + + public Int176(BigInteger value) { + super(176, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int184.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int184.java new file mode 100644 index 0000000000..3dcf5691f4 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int184.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Int; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Int184 extends Int { + public static final Int184 DEFAULT = new Int184(BigInteger.ZERO); + + public Int184(BigInteger value) { + super(184, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int192.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int192.java new file mode 100644 index 0000000000..6c38bf1538 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int192.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Int; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Int192 extends Int { + public static final Int192 DEFAULT = new Int192(BigInteger.ZERO); + + public Int192(BigInteger value) { + super(192, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int200.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int200.java new file mode 100644 index 0000000000..d6b105751c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int200.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Int; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Int200 extends Int { + public static final Int200 DEFAULT = new Int200(BigInteger.ZERO); + + public Int200(BigInteger value) { + super(200, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int208.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int208.java new file mode 100644 index 0000000000..def2eb4698 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int208.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Int; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Int208 extends Int { + public static final Int208 DEFAULT = new Int208(BigInteger.ZERO); + + public Int208(BigInteger value) { + super(208, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int216.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int216.java new file mode 100644 index 0000000000..0491f7dda5 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int216.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Int; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Int216 extends Int { + public static final Int216 DEFAULT = new Int216(BigInteger.ZERO); + + public Int216(BigInteger value) { + super(216, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int224.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int224.java new file mode 100644 index 0000000000..0f3175550a --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int224.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Int; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Int224 extends Int { + public static final Int224 DEFAULT = new Int224(BigInteger.ZERO); + + public Int224(BigInteger value) { + super(224, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int232.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int232.java new file mode 100644 index 0000000000..b745760ef8 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int232.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Int; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Int232 extends Int { + public static final Int232 DEFAULT = new Int232(BigInteger.ZERO); + + public Int232(BigInteger value) { + super(232, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int24.java new file mode 100644 index 0000000000..27d511d368 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int24.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Int; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Int24 extends Int { + public static final Int24 DEFAULT = new Int24(BigInteger.ZERO); + + public Int24(BigInteger value) { + super(24, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int240.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int240.java new file mode 100644 index 0000000000..a92063f61b --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int240.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Int; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Int240 extends Int { + public static final Int240 DEFAULT = new Int240(BigInteger.ZERO); + + public Int240(BigInteger value) { + super(240, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int248.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int248.java new file mode 100644 index 0000000000..5e8e9f0e9c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int248.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Int; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Int248 extends Int { + public static final Int248 DEFAULT = new Int248(BigInteger.ZERO); + + public Int248(BigInteger value) { + super(248, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int256.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int256.java new file mode 100644 index 0000000000..55455ec289 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int256.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Int; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Int256 extends Int { + public static final Int256 DEFAULT = new Int256(BigInteger.ZERO); + + public Int256(BigInteger value) { + super(256, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int32.java new file mode 100644 index 0000000000..80f0aa6222 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int32.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Int; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Int32 extends Int { + public static final Int32 DEFAULT = new Int32(BigInteger.ZERO); + + public Int32(BigInteger value) { + super(32, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int40.java new file mode 100644 index 0000000000..fd33bd1d99 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int40.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Int; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Int40 extends Int { + public static final Int40 DEFAULT = new Int40(BigInteger.ZERO); + + public Int40(BigInteger value) { + super(40, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int48.java new file mode 100644 index 0000000000..493114e28e --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int48.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Int; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Int48 extends Int { + public static final Int48 DEFAULT = new Int48(BigInteger.ZERO); + + public Int48(BigInteger value) { + super(48, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int56.java new file mode 100644 index 0000000000..1598f7122e --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int56.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Int; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Int56 extends Int { + public static final Int56 DEFAULT = new Int56(BigInteger.ZERO); + + public Int56(BigInteger value) { + super(56, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int64.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int64.java new file mode 100644 index 0000000000..213556a598 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int64.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Int; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Int64 extends Int { + public static final Int64 DEFAULT = new Int64(BigInteger.ZERO); + + public Int64(BigInteger value) { + super(64, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int72.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int72.java new file mode 100644 index 0000000000..fb04b1fd0a --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int72.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Int; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Int72 extends Int { + public static final Int72 DEFAULT = new Int72(BigInteger.ZERO); + + public Int72(BigInteger value) { + super(72, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int8.java new file mode 100644 index 0000000000..f8815daad5 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int8.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Int; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Int8 extends Int { + public static final Int8 DEFAULT = new Int8(BigInteger.ZERO); + + public Int8(BigInteger value) { + super(8, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int80.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int80.java new file mode 100644 index 0000000000..649c7c5bbb --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int80.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Int; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Int80 extends Int { + public static final Int80 DEFAULT = new Int80(BigInteger.ZERO); + + public Int80(BigInteger value) { + super(80, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int88.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int88.java new file mode 100644 index 0000000000..58e2060795 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int88.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Int; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Int88 extends Int { + public static final Int88 DEFAULT = new Int88(BigInteger.ZERO); + + public Int88(BigInteger value) { + super(88, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int96.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int96.java new file mode 100644 index 0000000000..755f4ad501 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Int96.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Int; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Int96 extends Int { + public static final Int96 DEFAULT = new Int96(BigInteger.ZERO); + + public Int96(BigInteger value) { + super(96, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x104.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x104.java new file mode 100644 index 0000000000..d3ec56a684 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x104.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed104x104 extends Ufixed { + public static final Ufixed104x104 DEFAULT = new Ufixed104x104(BigInteger.ZERO); + + public Ufixed104x104(BigInteger value) { + super(104, 104, value); + } + + public Ufixed104x104(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(104, 104, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x112.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x112.java new file mode 100644 index 0000000000..083bfe8309 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x112.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed104x112 extends Ufixed { + public static final Ufixed104x112 DEFAULT = new Ufixed104x112(BigInteger.ZERO); + + public Ufixed104x112(BigInteger value) { + super(104, 112, value); + } + + public Ufixed104x112(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(104, 112, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x120.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x120.java new file mode 100644 index 0000000000..9b1c5c1e55 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x120.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed104x120 extends Ufixed { + public static final Ufixed104x120 DEFAULT = new Ufixed104x120(BigInteger.ZERO); + + public Ufixed104x120(BigInteger value) { + super(104, 120, value); + } + + public Ufixed104x120(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(104, 120, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x128.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x128.java new file mode 100644 index 0000000000..ced3c52eb5 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x128.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed104x128 extends Ufixed { + public static final Ufixed104x128 DEFAULT = new Ufixed104x128(BigInteger.ZERO); + + public Ufixed104x128(BigInteger value) { + super(104, 128, value); + } + + public Ufixed104x128(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(104, 128, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x136.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x136.java new file mode 100644 index 0000000000..2a67761b75 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x136.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed104x136 extends Ufixed { + public static final Ufixed104x136 DEFAULT = new Ufixed104x136(BigInteger.ZERO); + + public Ufixed104x136(BigInteger value) { + super(104, 136, value); + } + + public Ufixed104x136(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(104, 136, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x144.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x144.java new file mode 100644 index 0000000000..6be71dd435 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x144.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed104x144 extends Ufixed { + public static final Ufixed104x144 DEFAULT = new Ufixed104x144(BigInteger.ZERO); + + public Ufixed104x144(BigInteger value) { + super(104, 144, value); + } + + public Ufixed104x144(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(104, 144, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x152.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x152.java new file mode 100644 index 0000000000..a8cc4b2942 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x152.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed104x152 extends Ufixed { + public static final Ufixed104x152 DEFAULT = new Ufixed104x152(BigInteger.ZERO); + + public Ufixed104x152(BigInteger value) { + super(104, 152, value); + } + + public Ufixed104x152(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(104, 152, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x16.java new file mode 100644 index 0000000000..7f4255a78b --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed104x16 extends Ufixed { + public static final Ufixed104x16 DEFAULT = new Ufixed104x16(BigInteger.ZERO); + + public Ufixed104x16(BigInteger value) { + super(104, 16, value); + } + + public Ufixed104x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(104, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x24.java new file mode 100644 index 0000000000..d27afffa19 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed104x24 extends Ufixed { + public static final Ufixed104x24 DEFAULT = new Ufixed104x24(BigInteger.ZERO); + + public Ufixed104x24(BigInteger value) { + super(104, 24, value); + } + + public Ufixed104x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(104, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x32.java new file mode 100644 index 0000000000..cd297cb2c7 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed104x32 extends Ufixed { + public static final Ufixed104x32 DEFAULT = new Ufixed104x32(BigInteger.ZERO); + + public Ufixed104x32(BigInteger value) { + super(104, 32, value); + } + + public Ufixed104x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(104, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x40.java new file mode 100644 index 0000000000..51217aa672 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed104x40 extends Ufixed { + public static final Ufixed104x40 DEFAULT = new Ufixed104x40(BigInteger.ZERO); + + public Ufixed104x40(BigInteger value) { + super(104, 40, value); + } + + public Ufixed104x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(104, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x48.java new file mode 100644 index 0000000000..6b4d163ef7 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed104x48 extends Ufixed { + public static final Ufixed104x48 DEFAULT = new Ufixed104x48(BigInteger.ZERO); + + public Ufixed104x48(BigInteger value) { + super(104, 48, value); + } + + public Ufixed104x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(104, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x56.java new file mode 100644 index 0000000000..045209eafd --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x56.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed104x56 extends Ufixed { + public static final Ufixed104x56 DEFAULT = new Ufixed104x56(BigInteger.ZERO); + + public Ufixed104x56(BigInteger value) { + super(104, 56, value); + } + + public Ufixed104x56(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(104, 56, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x64.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x64.java new file mode 100644 index 0000000000..5b8153e144 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x64.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed104x64 extends Ufixed { + public static final Ufixed104x64 DEFAULT = new Ufixed104x64(BigInteger.ZERO); + + public Ufixed104x64(BigInteger value) { + super(104, 64, value); + } + + public Ufixed104x64(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(104, 64, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x72.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x72.java new file mode 100644 index 0000000000..a36a3fa1e0 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x72.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed104x72 extends Ufixed { + public static final Ufixed104x72 DEFAULT = new Ufixed104x72(BigInteger.ZERO); + + public Ufixed104x72(BigInteger value) { + super(104, 72, value); + } + + public Ufixed104x72(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(104, 72, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x8.java new file mode 100644 index 0000000000..0b69aa7ba3 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed104x8 extends Ufixed { + public static final Ufixed104x8 DEFAULT = new Ufixed104x8(BigInteger.ZERO); + + public Ufixed104x8(BigInteger value) { + super(104, 8, value); + } + + public Ufixed104x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(104, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x80.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x80.java new file mode 100644 index 0000000000..b8eb9e4d2f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x80.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed104x80 extends Ufixed { + public static final Ufixed104x80 DEFAULT = new Ufixed104x80(BigInteger.ZERO); + + public Ufixed104x80(BigInteger value) { + super(104, 80, value); + } + + public Ufixed104x80(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(104, 80, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x88.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x88.java new file mode 100644 index 0000000000..9e7ff5da0f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x88.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed104x88 extends Ufixed { + public static final Ufixed104x88 DEFAULT = new Ufixed104x88(BigInteger.ZERO); + + public Ufixed104x88(BigInteger value) { + super(104, 88, value); + } + + public Ufixed104x88(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(104, 88, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x96.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x96.java new file mode 100644 index 0000000000..3c70093382 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed104x96.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed104x96 extends Ufixed { + public static final Ufixed104x96 DEFAULT = new Ufixed104x96(BigInteger.ZERO); + + public Ufixed104x96(BigInteger value) { + super(104, 96, value); + } + + public Ufixed104x96(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(104, 96, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x104.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x104.java new file mode 100644 index 0000000000..b870211cc2 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x104.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed112x104 extends Ufixed { + public static final Ufixed112x104 DEFAULT = new Ufixed112x104(BigInteger.ZERO); + + public Ufixed112x104(BigInteger value) { + super(112, 104, value); + } + + public Ufixed112x104(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(112, 104, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x112.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x112.java new file mode 100644 index 0000000000..3206ed394e --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x112.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed112x112 extends Ufixed { + public static final Ufixed112x112 DEFAULT = new Ufixed112x112(BigInteger.ZERO); + + public Ufixed112x112(BigInteger value) { + super(112, 112, value); + } + + public Ufixed112x112(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(112, 112, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x120.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x120.java new file mode 100644 index 0000000000..ee17b64e0c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x120.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed112x120 extends Ufixed { + public static final Ufixed112x120 DEFAULT = new Ufixed112x120(BigInteger.ZERO); + + public Ufixed112x120(BigInteger value) { + super(112, 120, value); + } + + public Ufixed112x120(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(112, 120, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x128.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x128.java new file mode 100644 index 0000000000..5c6c6dd516 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x128.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed112x128 extends Ufixed { + public static final Ufixed112x128 DEFAULT = new Ufixed112x128(BigInteger.ZERO); + + public Ufixed112x128(BigInteger value) { + super(112, 128, value); + } + + public Ufixed112x128(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(112, 128, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x136.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x136.java new file mode 100644 index 0000000000..4732473693 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x136.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed112x136 extends Ufixed { + public static final Ufixed112x136 DEFAULT = new Ufixed112x136(BigInteger.ZERO); + + public Ufixed112x136(BigInteger value) { + super(112, 136, value); + } + + public Ufixed112x136(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(112, 136, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x144.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x144.java new file mode 100644 index 0000000000..8011c34ab4 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x144.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed112x144 extends Ufixed { + public static final Ufixed112x144 DEFAULT = new Ufixed112x144(BigInteger.ZERO); + + public Ufixed112x144(BigInteger value) { + super(112, 144, value); + } + + public Ufixed112x144(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(112, 144, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x16.java new file mode 100644 index 0000000000..f8cb6bf6e4 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed112x16 extends Ufixed { + public static final Ufixed112x16 DEFAULT = new Ufixed112x16(BigInteger.ZERO); + + public Ufixed112x16(BigInteger value) { + super(112, 16, value); + } + + public Ufixed112x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(112, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x24.java new file mode 100644 index 0000000000..95c6787eb4 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed112x24 extends Ufixed { + public static final Ufixed112x24 DEFAULT = new Ufixed112x24(BigInteger.ZERO); + + public Ufixed112x24(BigInteger value) { + super(112, 24, value); + } + + public Ufixed112x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(112, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x32.java new file mode 100644 index 0000000000..6f604f8cef --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed112x32 extends Ufixed { + public static final Ufixed112x32 DEFAULT = new Ufixed112x32(BigInteger.ZERO); + + public Ufixed112x32(BigInteger value) { + super(112, 32, value); + } + + public Ufixed112x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(112, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x40.java new file mode 100644 index 0000000000..930e665b73 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed112x40 extends Ufixed { + public static final Ufixed112x40 DEFAULT = new Ufixed112x40(BigInteger.ZERO); + + public Ufixed112x40(BigInteger value) { + super(112, 40, value); + } + + public Ufixed112x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(112, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x48.java new file mode 100644 index 0000000000..fac720898c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed112x48 extends Ufixed { + public static final Ufixed112x48 DEFAULT = new Ufixed112x48(BigInteger.ZERO); + + public Ufixed112x48(BigInteger value) { + super(112, 48, value); + } + + public Ufixed112x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(112, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x56.java new file mode 100644 index 0000000000..5c41fb4ec3 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x56.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed112x56 extends Ufixed { + public static final Ufixed112x56 DEFAULT = new Ufixed112x56(BigInteger.ZERO); + + public Ufixed112x56(BigInteger value) { + super(112, 56, value); + } + + public Ufixed112x56(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(112, 56, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x64.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x64.java new file mode 100644 index 0000000000..e0cd4b7c36 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x64.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed112x64 extends Ufixed { + public static final Ufixed112x64 DEFAULT = new Ufixed112x64(BigInteger.ZERO); + + public Ufixed112x64(BigInteger value) { + super(112, 64, value); + } + + public Ufixed112x64(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(112, 64, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x72.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x72.java new file mode 100644 index 0000000000..ea6bbe6329 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x72.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed112x72 extends Ufixed { + public static final Ufixed112x72 DEFAULT = new Ufixed112x72(BigInteger.ZERO); + + public Ufixed112x72(BigInteger value) { + super(112, 72, value); + } + + public Ufixed112x72(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(112, 72, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x8.java new file mode 100644 index 0000000000..711ec971cb --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed112x8 extends Ufixed { + public static final Ufixed112x8 DEFAULT = new Ufixed112x8(BigInteger.ZERO); + + public Ufixed112x8(BigInteger value) { + super(112, 8, value); + } + + public Ufixed112x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(112, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x80.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x80.java new file mode 100644 index 0000000000..880ff6ca1b --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x80.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed112x80 extends Ufixed { + public static final Ufixed112x80 DEFAULT = new Ufixed112x80(BigInteger.ZERO); + + public Ufixed112x80(BigInteger value) { + super(112, 80, value); + } + + public Ufixed112x80(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(112, 80, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x88.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x88.java new file mode 100644 index 0000000000..2b83e0b3ad --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x88.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed112x88 extends Ufixed { + public static final Ufixed112x88 DEFAULT = new Ufixed112x88(BigInteger.ZERO); + + public Ufixed112x88(BigInteger value) { + super(112, 88, value); + } + + public Ufixed112x88(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(112, 88, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x96.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x96.java new file mode 100644 index 0000000000..55540ac977 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed112x96.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed112x96 extends Ufixed { + public static final Ufixed112x96 DEFAULT = new Ufixed112x96(BigInteger.ZERO); + + public Ufixed112x96(BigInteger value) { + super(112, 96, value); + } + + public Ufixed112x96(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(112, 96, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x104.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x104.java new file mode 100644 index 0000000000..0a5358dcb4 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x104.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed120x104 extends Ufixed { + public static final Ufixed120x104 DEFAULT = new Ufixed120x104(BigInteger.ZERO); + + public Ufixed120x104(BigInteger value) { + super(120, 104, value); + } + + public Ufixed120x104(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(120, 104, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x112.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x112.java new file mode 100644 index 0000000000..40e853f385 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x112.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed120x112 extends Ufixed { + public static final Ufixed120x112 DEFAULT = new Ufixed120x112(BigInteger.ZERO); + + public Ufixed120x112(BigInteger value) { + super(120, 112, value); + } + + public Ufixed120x112(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(120, 112, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x120.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x120.java new file mode 100644 index 0000000000..1b5d9f3d52 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x120.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed120x120 extends Ufixed { + public static final Ufixed120x120 DEFAULT = new Ufixed120x120(BigInteger.ZERO); + + public Ufixed120x120(BigInteger value) { + super(120, 120, value); + } + + public Ufixed120x120(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(120, 120, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x128.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x128.java new file mode 100644 index 0000000000..37d7113d0a --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x128.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed120x128 extends Ufixed { + public static final Ufixed120x128 DEFAULT = new Ufixed120x128(BigInteger.ZERO); + + public Ufixed120x128(BigInteger value) { + super(120, 128, value); + } + + public Ufixed120x128(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(120, 128, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x136.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x136.java new file mode 100644 index 0000000000..49a44b3ad6 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x136.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed120x136 extends Ufixed { + public static final Ufixed120x136 DEFAULT = new Ufixed120x136(BigInteger.ZERO); + + public Ufixed120x136(BigInteger value) { + super(120, 136, value); + } + + public Ufixed120x136(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(120, 136, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x16.java new file mode 100644 index 0000000000..2ad5409c5d --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed120x16 extends Ufixed { + public static final Ufixed120x16 DEFAULT = new Ufixed120x16(BigInteger.ZERO); + + public Ufixed120x16(BigInteger value) { + super(120, 16, value); + } + + public Ufixed120x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(120, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x24.java new file mode 100644 index 0000000000..3f0e2e5658 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed120x24 extends Ufixed { + public static final Ufixed120x24 DEFAULT = new Ufixed120x24(BigInteger.ZERO); + + public Ufixed120x24(BigInteger value) { + super(120, 24, value); + } + + public Ufixed120x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(120, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x32.java new file mode 100644 index 0000000000..dad64d1fea --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed120x32 extends Ufixed { + public static final Ufixed120x32 DEFAULT = new Ufixed120x32(BigInteger.ZERO); + + public Ufixed120x32(BigInteger value) { + super(120, 32, value); + } + + public Ufixed120x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(120, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x40.java new file mode 100644 index 0000000000..1f897b33ce --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed120x40 extends Ufixed { + public static final Ufixed120x40 DEFAULT = new Ufixed120x40(BigInteger.ZERO); + + public Ufixed120x40(BigInteger value) { + super(120, 40, value); + } + + public Ufixed120x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(120, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x48.java new file mode 100644 index 0000000000..4e2b48969a --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed120x48 extends Ufixed { + public static final Ufixed120x48 DEFAULT = new Ufixed120x48(BigInteger.ZERO); + + public Ufixed120x48(BigInteger value) { + super(120, 48, value); + } + + public Ufixed120x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(120, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x56.java new file mode 100644 index 0000000000..19ca7abbd1 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x56.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed120x56 extends Ufixed { + public static final Ufixed120x56 DEFAULT = new Ufixed120x56(BigInteger.ZERO); + + public Ufixed120x56(BigInteger value) { + super(120, 56, value); + } + + public Ufixed120x56(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(120, 56, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x64.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x64.java new file mode 100644 index 0000000000..43bf099aed --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x64.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed120x64 extends Ufixed { + public static final Ufixed120x64 DEFAULT = new Ufixed120x64(BigInteger.ZERO); + + public Ufixed120x64(BigInteger value) { + super(120, 64, value); + } + + public Ufixed120x64(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(120, 64, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x72.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x72.java new file mode 100644 index 0000000000..ba4981dabc --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x72.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed120x72 extends Ufixed { + public static final Ufixed120x72 DEFAULT = new Ufixed120x72(BigInteger.ZERO); + + public Ufixed120x72(BigInteger value) { + super(120, 72, value); + } + + public Ufixed120x72(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(120, 72, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x8.java new file mode 100644 index 0000000000..81b0fa4220 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed120x8 extends Ufixed { + public static final Ufixed120x8 DEFAULT = new Ufixed120x8(BigInteger.ZERO); + + public Ufixed120x8(BigInteger value) { + super(120, 8, value); + } + + public Ufixed120x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(120, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x80.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x80.java new file mode 100644 index 0000000000..fa5dc204f8 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x80.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed120x80 extends Ufixed { + public static final Ufixed120x80 DEFAULT = new Ufixed120x80(BigInteger.ZERO); + + public Ufixed120x80(BigInteger value) { + super(120, 80, value); + } + + public Ufixed120x80(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(120, 80, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x88.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x88.java new file mode 100644 index 0000000000..8a3078ae88 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x88.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed120x88 extends Ufixed { + public static final Ufixed120x88 DEFAULT = new Ufixed120x88(BigInteger.ZERO); + + public Ufixed120x88(BigInteger value) { + super(120, 88, value); + } + + public Ufixed120x88(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(120, 88, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x96.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x96.java new file mode 100644 index 0000000000..d9e5631277 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed120x96.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed120x96 extends Ufixed { + public static final Ufixed120x96 DEFAULT = new Ufixed120x96(BigInteger.ZERO); + + public Ufixed120x96(BigInteger value) { + super(120, 96, value); + } + + public Ufixed120x96(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(120, 96, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed128x104.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed128x104.java new file mode 100644 index 0000000000..d3d4b53018 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed128x104.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed128x104 extends Ufixed { + public static final Ufixed128x104 DEFAULT = new Ufixed128x104(BigInteger.ZERO); + + public Ufixed128x104(BigInteger value) { + super(128, 104, value); + } + + public Ufixed128x104(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(128, 104, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed128x112.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed128x112.java new file mode 100644 index 0000000000..d067c3b357 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed128x112.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed128x112 extends Ufixed { + public static final Ufixed128x112 DEFAULT = new Ufixed128x112(BigInteger.ZERO); + + public Ufixed128x112(BigInteger value) { + super(128, 112, value); + } + + public Ufixed128x112(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(128, 112, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed128x120.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed128x120.java new file mode 100644 index 0000000000..f02105b9fa --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed128x120.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed128x120 extends Ufixed { + public static final Ufixed128x120 DEFAULT = new Ufixed128x120(BigInteger.ZERO); + + public Ufixed128x120(BigInteger value) { + super(128, 120, value); + } + + public Ufixed128x120(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(128, 120, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed128x128.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed128x128.java new file mode 100644 index 0000000000..bb2def697a --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed128x128.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed128x128 extends Ufixed { + public static final Ufixed128x128 DEFAULT = new Ufixed128x128(BigInteger.ZERO); + + public Ufixed128x128(BigInteger value) { + super(128, 128, value); + } + + public Ufixed128x128(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(128, 128, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed128x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed128x16.java new file mode 100644 index 0000000000..09de86af1f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed128x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed128x16 extends Ufixed { + public static final Ufixed128x16 DEFAULT = new Ufixed128x16(BigInteger.ZERO); + + public Ufixed128x16(BigInteger value) { + super(128, 16, value); + } + + public Ufixed128x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(128, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed128x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed128x24.java new file mode 100644 index 0000000000..95c1a77b4b --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed128x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed128x24 extends Ufixed { + public static final Ufixed128x24 DEFAULT = new Ufixed128x24(BigInteger.ZERO); + + public Ufixed128x24(BigInteger value) { + super(128, 24, value); + } + + public Ufixed128x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(128, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed128x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed128x32.java new file mode 100644 index 0000000000..70786c1ce2 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed128x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed128x32 extends Ufixed { + public static final Ufixed128x32 DEFAULT = new Ufixed128x32(BigInteger.ZERO); + + public Ufixed128x32(BigInteger value) { + super(128, 32, value); + } + + public Ufixed128x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(128, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed128x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed128x40.java new file mode 100644 index 0000000000..699443ede3 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed128x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed128x40 extends Ufixed { + public static final Ufixed128x40 DEFAULT = new Ufixed128x40(BigInteger.ZERO); + + public Ufixed128x40(BigInteger value) { + super(128, 40, value); + } + + public Ufixed128x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(128, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed128x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed128x48.java new file mode 100644 index 0000000000..3c0a123035 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed128x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed128x48 extends Ufixed { + public static final Ufixed128x48 DEFAULT = new Ufixed128x48(BigInteger.ZERO); + + public Ufixed128x48(BigInteger value) { + super(128, 48, value); + } + + public Ufixed128x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(128, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed128x56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed128x56.java new file mode 100644 index 0000000000..5f8fbe2311 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed128x56.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed128x56 extends Ufixed { + public static final Ufixed128x56 DEFAULT = new Ufixed128x56(BigInteger.ZERO); + + public Ufixed128x56(BigInteger value) { + super(128, 56, value); + } + + public Ufixed128x56(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(128, 56, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed128x64.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed128x64.java new file mode 100644 index 0000000000..f8330b241b --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed128x64.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed128x64 extends Ufixed { + public static final Ufixed128x64 DEFAULT = new Ufixed128x64(BigInteger.ZERO); + + public Ufixed128x64(BigInteger value) { + super(128, 64, value); + } + + public Ufixed128x64(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(128, 64, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed128x72.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed128x72.java new file mode 100644 index 0000000000..936fc80381 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed128x72.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed128x72 extends Ufixed { + public static final Ufixed128x72 DEFAULT = new Ufixed128x72(BigInteger.ZERO); + + public Ufixed128x72(BigInteger value) { + super(128, 72, value); + } + + public Ufixed128x72(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(128, 72, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed128x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed128x8.java new file mode 100644 index 0000000000..8c07647c91 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed128x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed128x8 extends Ufixed { + public static final Ufixed128x8 DEFAULT = new Ufixed128x8(BigInteger.ZERO); + + public Ufixed128x8(BigInteger value) { + super(128, 8, value); + } + + public Ufixed128x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(128, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed128x80.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed128x80.java new file mode 100644 index 0000000000..2b2ce6b297 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed128x80.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed128x80 extends Ufixed { + public static final Ufixed128x80 DEFAULT = new Ufixed128x80(BigInteger.ZERO); + + public Ufixed128x80(BigInteger value) { + super(128, 80, value); + } + + public Ufixed128x80(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(128, 80, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed128x88.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed128x88.java new file mode 100644 index 0000000000..6997001bf7 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed128x88.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed128x88 extends Ufixed { + public static final Ufixed128x88 DEFAULT = new Ufixed128x88(BigInteger.ZERO); + + public Ufixed128x88(BigInteger value) { + super(128, 88, value); + } + + public Ufixed128x88(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(128, 88, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed128x96.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed128x96.java new file mode 100644 index 0000000000..8b645aa1a9 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed128x96.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed128x96 extends Ufixed { + public static final Ufixed128x96 DEFAULT = new Ufixed128x96(BigInteger.ZERO); + + public Ufixed128x96(BigInteger value) { + super(128, 96, value); + } + + public Ufixed128x96(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(128, 96, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed136x104.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed136x104.java new file mode 100644 index 0000000000..ee7fe7ecc1 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed136x104.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed136x104 extends Ufixed { + public static final Ufixed136x104 DEFAULT = new Ufixed136x104(BigInteger.ZERO); + + public Ufixed136x104(BigInteger value) { + super(136, 104, value); + } + + public Ufixed136x104(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(136, 104, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed136x112.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed136x112.java new file mode 100644 index 0000000000..60bf77fb96 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed136x112.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed136x112 extends Ufixed { + public static final Ufixed136x112 DEFAULT = new Ufixed136x112(BigInteger.ZERO); + + public Ufixed136x112(BigInteger value) { + super(136, 112, value); + } + + public Ufixed136x112(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(136, 112, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed136x120.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed136x120.java new file mode 100644 index 0000000000..c73a87dce5 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed136x120.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed136x120 extends Ufixed { + public static final Ufixed136x120 DEFAULT = new Ufixed136x120(BigInteger.ZERO); + + public Ufixed136x120(BigInteger value) { + super(136, 120, value); + } + + public Ufixed136x120(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(136, 120, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed136x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed136x16.java new file mode 100644 index 0000000000..74a2a35b33 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed136x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed136x16 extends Ufixed { + public static final Ufixed136x16 DEFAULT = new Ufixed136x16(BigInteger.ZERO); + + public Ufixed136x16(BigInteger value) { + super(136, 16, value); + } + + public Ufixed136x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(136, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed136x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed136x24.java new file mode 100644 index 0000000000..f0150a3e7e --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed136x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed136x24 extends Ufixed { + public static final Ufixed136x24 DEFAULT = new Ufixed136x24(BigInteger.ZERO); + + public Ufixed136x24(BigInteger value) { + super(136, 24, value); + } + + public Ufixed136x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(136, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed136x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed136x32.java new file mode 100644 index 0000000000..986d82e29c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed136x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed136x32 extends Ufixed { + public static final Ufixed136x32 DEFAULT = new Ufixed136x32(BigInteger.ZERO); + + public Ufixed136x32(BigInteger value) { + super(136, 32, value); + } + + public Ufixed136x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(136, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed136x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed136x40.java new file mode 100644 index 0000000000..1601802c8a --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed136x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed136x40 extends Ufixed { + public static final Ufixed136x40 DEFAULT = new Ufixed136x40(BigInteger.ZERO); + + public Ufixed136x40(BigInteger value) { + super(136, 40, value); + } + + public Ufixed136x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(136, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed136x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed136x48.java new file mode 100644 index 0000000000..dcd415c39e --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed136x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed136x48 extends Ufixed { + public static final Ufixed136x48 DEFAULT = new Ufixed136x48(BigInteger.ZERO); + + public Ufixed136x48(BigInteger value) { + super(136, 48, value); + } + + public Ufixed136x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(136, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed136x56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed136x56.java new file mode 100644 index 0000000000..ec286620dc --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed136x56.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed136x56 extends Ufixed { + public static final Ufixed136x56 DEFAULT = new Ufixed136x56(BigInteger.ZERO); + + public Ufixed136x56(BigInteger value) { + super(136, 56, value); + } + + public Ufixed136x56(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(136, 56, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed136x64.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed136x64.java new file mode 100644 index 0000000000..2ba389a023 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed136x64.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed136x64 extends Ufixed { + public static final Ufixed136x64 DEFAULT = new Ufixed136x64(BigInteger.ZERO); + + public Ufixed136x64(BigInteger value) { + super(136, 64, value); + } + + public Ufixed136x64(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(136, 64, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed136x72.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed136x72.java new file mode 100644 index 0000000000..16e1b3f0a1 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed136x72.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed136x72 extends Ufixed { + public static final Ufixed136x72 DEFAULT = new Ufixed136x72(BigInteger.ZERO); + + public Ufixed136x72(BigInteger value) { + super(136, 72, value); + } + + public Ufixed136x72(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(136, 72, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed136x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed136x8.java new file mode 100644 index 0000000000..0b02dd3fed --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed136x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed136x8 extends Ufixed { + public static final Ufixed136x8 DEFAULT = new Ufixed136x8(BigInteger.ZERO); + + public Ufixed136x8(BigInteger value) { + super(136, 8, value); + } + + public Ufixed136x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(136, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed136x80.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed136x80.java new file mode 100644 index 0000000000..b9ed16c2f8 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed136x80.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed136x80 extends Ufixed { + public static final Ufixed136x80 DEFAULT = new Ufixed136x80(BigInteger.ZERO); + + public Ufixed136x80(BigInteger value) { + super(136, 80, value); + } + + public Ufixed136x80(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(136, 80, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed136x88.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed136x88.java new file mode 100644 index 0000000000..a57489ff0c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed136x88.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed136x88 extends Ufixed { + public static final Ufixed136x88 DEFAULT = new Ufixed136x88(BigInteger.ZERO); + + public Ufixed136x88(BigInteger value) { + super(136, 88, value); + } + + public Ufixed136x88(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(136, 88, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed136x96.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed136x96.java new file mode 100644 index 0000000000..f69d6bfa1c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed136x96.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed136x96 extends Ufixed { + public static final Ufixed136x96 DEFAULT = new Ufixed136x96(BigInteger.ZERO); + + public Ufixed136x96(BigInteger value) { + super(136, 96, value); + } + + public Ufixed136x96(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(136, 96, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed144x104.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed144x104.java new file mode 100644 index 0000000000..14da527f3a --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed144x104.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed144x104 extends Ufixed { + public static final Ufixed144x104 DEFAULT = new Ufixed144x104(BigInteger.ZERO); + + public Ufixed144x104(BigInteger value) { + super(144, 104, value); + } + + public Ufixed144x104(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(144, 104, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed144x112.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed144x112.java new file mode 100644 index 0000000000..7918da0425 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed144x112.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed144x112 extends Ufixed { + public static final Ufixed144x112 DEFAULT = new Ufixed144x112(BigInteger.ZERO); + + public Ufixed144x112(BigInteger value) { + super(144, 112, value); + } + + public Ufixed144x112(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(144, 112, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed144x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed144x16.java new file mode 100644 index 0000000000..d144dad424 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed144x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed144x16 extends Ufixed { + public static final Ufixed144x16 DEFAULT = new Ufixed144x16(BigInteger.ZERO); + + public Ufixed144x16(BigInteger value) { + super(144, 16, value); + } + + public Ufixed144x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(144, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed144x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed144x24.java new file mode 100644 index 0000000000..ba8c94e0d2 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed144x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed144x24 extends Ufixed { + public static final Ufixed144x24 DEFAULT = new Ufixed144x24(BigInteger.ZERO); + + public Ufixed144x24(BigInteger value) { + super(144, 24, value); + } + + public Ufixed144x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(144, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed144x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed144x32.java new file mode 100644 index 0000000000..a0fa6d213c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed144x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed144x32 extends Ufixed { + public static final Ufixed144x32 DEFAULT = new Ufixed144x32(BigInteger.ZERO); + + public Ufixed144x32(BigInteger value) { + super(144, 32, value); + } + + public Ufixed144x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(144, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed144x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed144x40.java new file mode 100644 index 0000000000..4f506550d5 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed144x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed144x40 extends Ufixed { + public static final Ufixed144x40 DEFAULT = new Ufixed144x40(BigInteger.ZERO); + + public Ufixed144x40(BigInteger value) { + super(144, 40, value); + } + + public Ufixed144x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(144, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed144x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed144x48.java new file mode 100644 index 0000000000..3dc954bab4 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed144x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed144x48 extends Ufixed { + public static final Ufixed144x48 DEFAULT = new Ufixed144x48(BigInteger.ZERO); + + public Ufixed144x48(BigInteger value) { + super(144, 48, value); + } + + public Ufixed144x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(144, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed144x56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed144x56.java new file mode 100644 index 0000000000..a2f0f9d1f5 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed144x56.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed144x56 extends Ufixed { + public static final Ufixed144x56 DEFAULT = new Ufixed144x56(BigInteger.ZERO); + + public Ufixed144x56(BigInteger value) { + super(144, 56, value); + } + + public Ufixed144x56(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(144, 56, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed144x64.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed144x64.java new file mode 100644 index 0000000000..a319b4d034 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed144x64.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed144x64 extends Ufixed { + public static final Ufixed144x64 DEFAULT = new Ufixed144x64(BigInteger.ZERO); + + public Ufixed144x64(BigInteger value) { + super(144, 64, value); + } + + public Ufixed144x64(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(144, 64, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed144x72.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed144x72.java new file mode 100644 index 0000000000..1ce18157df --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed144x72.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed144x72 extends Ufixed { + public static final Ufixed144x72 DEFAULT = new Ufixed144x72(BigInteger.ZERO); + + public Ufixed144x72(BigInteger value) { + super(144, 72, value); + } + + public Ufixed144x72(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(144, 72, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed144x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed144x8.java new file mode 100644 index 0000000000..20cee3e739 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed144x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed144x8 extends Ufixed { + public static final Ufixed144x8 DEFAULT = new Ufixed144x8(BigInteger.ZERO); + + public Ufixed144x8(BigInteger value) { + super(144, 8, value); + } + + public Ufixed144x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(144, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed144x80.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed144x80.java new file mode 100644 index 0000000000..be20c24d19 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed144x80.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed144x80 extends Ufixed { + public static final Ufixed144x80 DEFAULT = new Ufixed144x80(BigInteger.ZERO); + + public Ufixed144x80(BigInteger value) { + super(144, 80, value); + } + + public Ufixed144x80(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(144, 80, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed144x88.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed144x88.java new file mode 100644 index 0000000000..8399dfe555 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed144x88.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed144x88 extends Ufixed { + public static final Ufixed144x88 DEFAULT = new Ufixed144x88(BigInteger.ZERO); + + public Ufixed144x88(BigInteger value) { + super(144, 88, value); + } + + public Ufixed144x88(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(144, 88, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed144x96.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed144x96.java new file mode 100644 index 0000000000..c645a2265a --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed144x96.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed144x96 extends Ufixed { + public static final Ufixed144x96 DEFAULT = new Ufixed144x96(BigInteger.ZERO); + + public Ufixed144x96(BigInteger value) { + super(144, 96, value); + } + + public Ufixed144x96(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(144, 96, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed152x104.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed152x104.java new file mode 100644 index 0000000000..e41789fb82 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed152x104.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed152x104 extends Ufixed { + public static final Ufixed152x104 DEFAULT = new Ufixed152x104(BigInteger.ZERO); + + public Ufixed152x104(BigInteger value) { + super(152, 104, value); + } + + public Ufixed152x104(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(152, 104, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed152x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed152x16.java new file mode 100644 index 0000000000..7e0347f085 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed152x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed152x16 extends Ufixed { + public static final Ufixed152x16 DEFAULT = new Ufixed152x16(BigInteger.ZERO); + + public Ufixed152x16(BigInteger value) { + super(152, 16, value); + } + + public Ufixed152x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(152, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed152x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed152x24.java new file mode 100644 index 0000000000..9f3685eafe --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed152x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed152x24 extends Ufixed { + public static final Ufixed152x24 DEFAULT = new Ufixed152x24(BigInteger.ZERO); + + public Ufixed152x24(BigInteger value) { + super(152, 24, value); + } + + public Ufixed152x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(152, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed152x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed152x32.java new file mode 100644 index 0000000000..b9393bdf57 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed152x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed152x32 extends Ufixed { + public static final Ufixed152x32 DEFAULT = new Ufixed152x32(BigInteger.ZERO); + + public Ufixed152x32(BigInteger value) { + super(152, 32, value); + } + + public Ufixed152x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(152, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed152x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed152x40.java new file mode 100644 index 0000000000..c5679458f5 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed152x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed152x40 extends Ufixed { + public static final Ufixed152x40 DEFAULT = new Ufixed152x40(BigInteger.ZERO); + + public Ufixed152x40(BigInteger value) { + super(152, 40, value); + } + + public Ufixed152x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(152, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed152x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed152x48.java new file mode 100644 index 0000000000..b6be78ea62 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed152x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed152x48 extends Ufixed { + public static final Ufixed152x48 DEFAULT = new Ufixed152x48(BigInteger.ZERO); + + public Ufixed152x48(BigInteger value) { + super(152, 48, value); + } + + public Ufixed152x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(152, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed152x56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed152x56.java new file mode 100644 index 0000000000..8e5d1b5bd5 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed152x56.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed152x56 extends Ufixed { + public static final Ufixed152x56 DEFAULT = new Ufixed152x56(BigInteger.ZERO); + + public Ufixed152x56(BigInteger value) { + super(152, 56, value); + } + + public Ufixed152x56(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(152, 56, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed152x64.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed152x64.java new file mode 100644 index 0000000000..691fa3c3ab --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed152x64.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed152x64 extends Ufixed { + public static final Ufixed152x64 DEFAULT = new Ufixed152x64(BigInteger.ZERO); + + public Ufixed152x64(BigInteger value) { + super(152, 64, value); + } + + public Ufixed152x64(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(152, 64, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed152x72.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed152x72.java new file mode 100644 index 0000000000..666bc5d1f8 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed152x72.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed152x72 extends Ufixed { + public static final Ufixed152x72 DEFAULT = new Ufixed152x72(BigInteger.ZERO); + + public Ufixed152x72(BigInteger value) { + super(152, 72, value); + } + + public Ufixed152x72(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(152, 72, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed152x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed152x8.java new file mode 100644 index 0000000000..fd8f2b9f2e --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed152x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed152x8 extends Ufixed { + public static final Ufixed152x8 DEFAULT = new Ufixed152x8(BigInteger.ZERO); + + public Ufixed152x8(BigInteger value) { + super(152, 8, value); + } + + public Ufixed152x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(152, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed152x80.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed152x80.java new file mode 100644 index 0000000000..1111f68606 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed152x80.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed152x80 extends Ufixed { + public static final Ufixed152x80 DEFAULT = new Ufixed152x80(BigInteger.ZERO); + + public Ufixed152x80(BigInteger value) { + super(152, 80, value); + } + + public Ufixed152x80(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(152, 80, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed152x88.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed152x88.java new file mode 100644 index 0000000000..a1a7879303 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed152x88.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed152x88 extends Ufixed { + public static final Ufixed152x88 DEFAULT = new Ufixed152x88(BigInteger.ZERO); + + public Ufixed152x88(BigInteger value) { + super(152, 88, value); + } + + public Ufixed152x88(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(152, 88, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed152x96.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed152x96.java new file mode 100644 index 0000000000..19061dff71 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed152x96.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed152x96 extends Ufixed { + public static final Ufixed152x96 DEFAULT = new Ufixed152x96(BigInteger.ZERO); + + public Ufixed152x96(BigInteger value) { + super(152, 96, value); + } + + public Ufixed152x96(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(152, 96, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed160x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed160x16.java new file mode 100644 index 0000000000..dc4288fa19 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed160x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed160x16 extends Ufixed { + public static final Ufixed160x16 DEFAULT = new Ufixed160x16(BigInteger.ZERO); + + public Ufixed160x16(BigInteger value) { + super(160, 16, value); + } + + public Ufixed160x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(160, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed160x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed160x24.java new file mode 100644 index 0000000000..058b6ca237 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed160x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed160x24 extends Ufixed { + public static final Ufixed160x24 DEFAULT = new Ufixed160x24(BigInteger.ZERO); + + public Ufixed160x24(BigInteger value) { + super(160, 24, value); + } + + public Ufixed160x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(160, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed160x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed160x32.java new file mode 100644 index 0000000000..f3368eed2a --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed160x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed160x32 extends Ufixed { + public static final Ufixed160x32 DEFAULT = new Ufixed160x32(BigInteger.ZERO); + + public Ufixed160x32(BigInteger value) { + super(160, 32, value); + } + + public Ufixed160x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(160, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed160x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed160x40.java new file mode 100644 index 0000000000..5c2cd872ae --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed160x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed160x40 extends Ufixed { + public static final Ufixed160x40 DEFAULT = new Ufixed160x40(BigInteger.ZERO); + + public Ufixed160x40(BigInteger value) { + super(160, 40, value); + } + + public Ufixed160x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(160, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed160x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed160x48.java new file mode 100644 index 0000000000..609a3a3ab6 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed160x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed160x48 extends Ufixed { + public static final Ufixed160x48 DEFAULT = new Ufixed160x48(BigInteger.ZERO); + + public Ufixed160x48(BigInteger value) { + super(160, 48, value); + } + + public Ufixed160x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(160, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed160x56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed160x56.java new file mode 100644 index 0000000000..fa70d8064d --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed160x56.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed160x56 extends Ufixed { + public static final Ufixed160x56 DEFAULT = new Ufixed160x56(BigInteger.ZERO); + + public Ufixed160x56(BigInteger value) { + super(160, 56, value); + } + + public Ufixed160x56(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(160, 56, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed160x64.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed160x64.java new file mode 100644 index 0000000000..6303af4364 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed160x64.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed160x64 extends Ufixed { + public static final Ufixed160x64 DEFAULT = new Ufixed160x64(BigInteger.ZERO); + + public Ufixed160x64(BigInteger value) { + super(160, 64, value); + } + + public Ufixed160x64(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(160, 64, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed160x72.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed160x72.java new file mode 100644 index 0000000000..6e597728b2 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed160x72.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed160x72 extends Ufixed { + public static final Ufixed160x72 DEFAULT = new Ufixed160x72(BigInteger.ZERO); + + public Ufixed160x72(BigInteger value) { + super(160, 72, value); + } + + public Ufixed160x72(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(160, 72, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed160x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed160x8.java new file mode 100644 index 0000000000..0bd3ff1c14 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed160x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed160x8 extends Ufixed { + public static final Ufixed160x8 DEFAULT = new Ufixed160x8(BigInteger.ZERO); + + public Ufixed160x8(BigInteger value) { + super(160, 8, value); + } + + public Ufixed160x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(160, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed160x80.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed160x80.java new file mode 100644 index 0000000000..520c448479 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed160x80.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed160x80 extends Ufixed { + public static final Ufixed160x80 DEFAULT = new Ufixed160x80(BigInteger.ZERO); + + public Ufixed160x80(BigInteger value) { + super(160, 80, value); + } + + public Ufixed160x80(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(160, 80, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed160x88.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed160x88.java new file mode 100644 index 0000000000..b31fa9b30d --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed160x88.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed160x88 extends Ufixed { + public static final Ufixed160x88 DEFAULT = new Ufixed160x88(BigInteger.ZERO); + + public Ufixed160x88(BigInteger value) { + super(160, 88, value); + } + + public Ufixed160x88(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(160, 88, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed160x96.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed160x96.java new file mode 100644 index 0000000000..8e38ede780 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed160x96.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed160x96 extends Ufixed { + public static final Ufixed160x96 DEFAULT = new Ufixed160x96(BigInteger.ZERO); + + public Ufixed160x96(BigInteger value) { + super(160, 96, value); + } + + public Ufixed160x96(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(160, 96, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed168x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed168x16.java new file mode 100644 index 0000000000..67e6071f27 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed168x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed168x16 extends Ufixed { + public static final Ufixed168x16 DEFAULT = new Ufixed168x16(BigInteger.ZERO); + + public Ufixed168x16(BigInteger value) { + super(168, 16, value); + } + + public Ufixed168x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(168, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed168x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed168x24.java new file mode 100644 index 0000000000..a85631120d --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed168x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed168x24 extends Ufixed { + public static final Ufixed168x24 DEFAULT = new Ufixed168x24(BigInteger.ZERO); + + public Ufixed168x24(BigInteger value) { + super(168, 24, value); + } + + public Ufixed168x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(168, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed168x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed168x32.java new file mode 100644 index 0000000000..ae81e5d78d --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed168x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed168x32 extends Ufixed { + public static final Ufixed168x32 DEFAULT = new Ufixed168x32(BigInteger.ZERO); + + public Ufixed168x32(BigInteger value) { + super(168, 32, value); + } + + public Ufixed168x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(168, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed168x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed168x40.java new file mode 100644 index 0000000000..246be4cc30 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed168x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed168x40 extends Ufixed { + public static final Ufixed168x40 DEFAULT = new Ufixed168x40(BigInteger.ZERO); + + public Ufixed168x40(BigInteger value) { + super(168, 40, value); + } + + public Ufixed168x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(168, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed168x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed168x48.java new file mode 100644 index 0000000000..b18956135f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed168x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed168x48 extends Ufixed { + public static final Ufixed168x48 DEFAULT = new Ufixed168x48(BigInteger.ZERO); + + public Ufixed168x48(BigInteger value) { + super(168, 48, value); + } + + public Ufixed168x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(168, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed168x56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed168x56.java new file mode 100644 index 0000000000..f41150bd0f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed168x56.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed168x56 extends Ufixed { + public static final Ufixed168x56 DEFAULT = new Ufixed168x56(BigInteger.ZERO); + + public Ufixed168x56(BigInteger value) { + super(168, 56, value); + } + + public Ufixed168x56(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(168, 56, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed168x64.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed168x64.java new file mode 100644 index 0000000000..3769dddaa6 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed168x64.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed168x64 extends Ufixed { + public static final Ufixed168x64 DEFAULT = new Ufixed168x64(BigInteger.ZERO); + + public Ufixed168x64(BigInteger value) { + super(168, 64, value); + } + + public Ufixed168x64(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(168, 64, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed168x72.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed168x72.java new file mode 100644 index 0000000000..0ad9942205 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed168x72.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed168x72 extends Ufixed { + public static final Ufixed168x72 DEFAULT = new Ufixed168x72(BigInteger.ZERO); + + public Ufixed168x72(BigInteger value) { + super(168, 72, value); + } + + public Ufixed168x72(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(168, 72, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed168x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed168x8.java new file mode 100644 index 0000000000..eb061f78f5 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed168x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed168x8 extends Ufixed { + public static final Ufixed168x8 DEFAULT = new Ufixed168x8(BigInteger.ZERO); + + public Ufixed168x8(BigInteger value) { + super(168, 8, value); + } + + public Ufixed168x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(168, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed168x80.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed168x80.java new file mode 100644 index 0000000000..8d61a1005b --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed168x80.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed168x80 extends Ufixed { + public static final Ufixed168x80 DEFAULT = new Ufixed168x80(BigInteger.ZERO); + + public Ufixed168x80(BigInteger value) { + super(168, 80, value); + } + + public Ufixed168x80(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(168, 80, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed168x88.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed168x88.java new file mode 100644 index 0000000000..b7eaea87ce --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed168x88.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed168x88 extends Ufixed { + public static final Ufixed168x88 DEFAULT = new Ufixed168x88(BigInteger.ZERO); + + public Ufixed168x88(BigInteger value) { + super(168, 88, value); + } + + public Ufixed168x88(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(168, 88, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x104.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x104.java new file mode 100644 index 0000000000..6ab481cdc0 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x104.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed16x104 extends Ufixed { + public static final Ufixed16x104 DEFAULT = new Ufixed16x104(BigInteger.ZERO); + + public Ufixed16x104(BigInteger value) { + super(16, 104, value); + } + + public Ufixed16x104(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 104, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x112.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x112.java new file mode 100644 index 0000000000..2b4a7b7c55 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x112.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed16x112 extends Ufixed { + public static final Ufixed16x112 DEFAULT = new Ufixed16x112(BigInteger.ZERO); + + public Ufixed16x112(BigInteger value) { + super(16, 112, value); + } + + public Ufixed16x112(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 112, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x120.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x120.java new file mode 100644 index 0000000000..48b6a3dc91 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x120.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed16x120 extends Ufixed { + public static final Ufixed16x120 DEFAULT = new Ufixed16x120(BigInteger.ZERO); + + public Ufixed16x120(BigInteger value) { + super(16, 120, value); + } + + public Ufixed16x120(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 120, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x128.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x128.java new file mode 100644 index 0000000000..7e609e1d92 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x128.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed16x128 extends Ufixed { + public static final Ufixed16x128 DEFAULT = new Ufixed16x128(BigInteger.ZERO); + + public Ufixed16x128(BigInteger value) { + super(16, 128, value); + } + + public Ufixed16x128(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 128, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x136.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x136.java new file mode 100644 index 0000000000..1f715c21bb --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x136.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed16x136 extends Ufixed { + public static final Ufixed16x136 DEFAULT = new Ufixed16x136(BigInteger.ZERO); + + public Ufixed16x136(BigInteger value) { + super(16, 136, value); + } + + public Ufixed16x136(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 136, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x144.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x144.java new file mode 100644 index 0000000000..4811f9f3f4 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x144.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed16x144 extends Ufixed { + public static final Ufixed16x144 DEFAULT = new Ufixed16x144(BigInteger.ZERO); + + public Ufixed16x144(BigInteger value) { + super(16, 144, value); + } + + public Ufixed16x144(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 144, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x152.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x152.java new file mode 100644 index 0000000000..239405c58b --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x152.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed16x152 extends Ufixed { + public static final Ufixed16x152 DEFAULT = new Ufixed16x152(BigInteger.ZERO); + + public Ufixed16x152(BigInteger value) { + super(16, 152, value); + } + + public Ufixed16x152(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 152, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x16.java new file mode 100644 index 0000000000..43d9376af3 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed16x16 extends Ufixed { + public static final Ufixed16x16 DEFAULT = new Ufixed16x16(BigInteger.ZERO); + + public Ufixed16x16(BigInteger value) { + super(16, 16, value); + } + + public Ufixed16x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x160.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x160.java new file mode 100644 index 0000000000..06b99dc4c6 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x160.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed16x160 extends Ufixed { + public static final Ufixed16x160 DEFAULT = new Ufixed16x160(BigInteger.ZERO); + + public Ufixed16x160(BigInteger value) { + super(16, 160, value); + } + + public Ufixed16x160(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 160, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x168.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x168.java new file mode 100644 index 0000000000..a4b30e3564 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x168.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed16x168 extends Ufixed { + public static final Ufixed16x168 DEFAULT = new Ufixed16x168(BigInteger.ZERO); + + public Ufixed16x168(BigInteger value) { + super(16, 168, value); + } + + public Ufixed16x168(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 168, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x176.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x176.java new file mode 100644 index 0000000000..9310bff18b --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x176.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed16x176 extends Ufixed { + public static final Ufixed16x176 DEFAULT = new Ufixed16x176(BigInteger.ZERO); + + public Ufixed16x176(BigInteger value) { + super(16, 176, value); + } + + public Ufixed16x176(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 176, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x184.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x184.java new file mode 100644 index 0000000000..7221d0f2d9 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x184.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed16x184 extends Ufixed { + public static final Ufixed16x184 DEFAULT = new Ufixed16x184(BigInteger.ZERO); + + public Ufixed16x184(BigInteger value) { + super(16, 184, value); + } + + public Ufixed16x184(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 184, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x192.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x192.java new file mode 100644 index 0000000000..8a7b2d1cc7 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x192.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed16x192 extends Ufixed { + public static final Ufixed16x192 DEFAULT = new Ufixed16x192(BigInteger.ZERO); + + public Ufixed16x192(BigInteger value) { + super(16, 192, value); + } + + public Ufixed16x192(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 192, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x200.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x200.java new file mode 100644 index 0000000000..b78dff3c76 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x200.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed16x200 extends Ufixed { + public static final Ufixed16x200 DEFAULT = new Ufixed16x200(BigInteger.ZERO); + + public Ufixed16x200(BigInteger value) { + super(16, 200, value); + } + + public Ufixed16x200(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 200, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x208.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x208.java new file mode 100644 index 0000000000..a0892aa766 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x208.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed16x208 extends Ufixed { + public static final Ufixed16x208 DEFAULT = new Ufixed16x208(BigInteger.ZERO); + + public Ufixed16x208(BigInteger value) { + super(16, 208, value); + } + + public Ufixed16x208(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 208, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x216.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x216.java new file mode 100644 index 0000000000..cd97d6ba7d --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x216.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed16x216 extends Ufixed { + public static final Ufixed16x216 DEFAULT = new Ufixed16x216(BigInteger.ZERO); + + public Ufixed16x216(BigInteger value) { + super(16, 216, value); + } + + public Ufixed16x216(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 216, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x224.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x224.java new file mode 100644 index 0000000000..8404da72bc --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x224.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed16x224 extends Ufixed { + public static final Ufixed16x224 DEFAULT = new Ufixed16x224(BigInteger.ZERO); + + public Ufixed16x224(BigInteger value) { + super(16, 224, value); + } + + public Ufixed16x224(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 224, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x232.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x232.java new file mode 100644 index 0000000000..19a387b23d --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x232.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed16x232 extends Ufixed { + public static final Ufixed16x232 DEFAULT = new Ufixed16x232(BigInteger.ZERO); + + public Ufixed16x232(BigInteger value) { + super(16, 232, value); + } + + public Ufixed16x232(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 232, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x24.java new file mode 100644 index 0000000000..d003273c45 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed16x24 extends Ufixed { + public static final Ufixed16x24 DEFAULT = new Ufixed16x24(BigInteger.ZERO); + + public Ufixed16x24(BigInteger value) { + super(16, 24, value); + } + + public Ufixed16x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x240.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x240.java new file mode 100644 index 0000000000..0951f0213f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x240.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed16x240 extends Ufixed { + public static final Ufixed16x240 DEFAULT = new Ufixed16x240(BigInteger.ZERO); + + public Ufixed16x240(BigInteger value) { + super(16, 240, value); + } + + public Ufixed16x240(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 240, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x32.java new file mode 100644 index 0000000000..602b959561 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed16x32 extends Ufixed { + public static final Ufixed16x32 DEFAULT = new Ufixed16x32(BigInteger.ZERO); + + public Ufixed16x32(BigInteger value) { + super(16, 32, value); + } + + public Ufixed16x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x40.java new file mode 100644 index 0000000000..262253f1fc --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed16x40 extends Ufixed { + public static final Ufixed16x40 DEFAULT = new Ufixed16x40(BigInteger.ZERO); + + public Ufixed16x40(BigInteger value) { + super(16, 40, value); + } + + public Ufixed16x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x48.java new file mode 100644 index 0000000000..0c8e1cf86a --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed16x48 extends Ufixed { + public static final Ufixed16x48 DEFAULT = new Ufixed16x48(BigInteger.ZERO); + + public Ufixed16x48(BigInteger value) { + super(16, 48, value); + } + + public Ufixed16x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x56.java new file mode 100644 index 0000000000..3d675b05ef --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x56.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed16x56 extends Ufixed { + public static final Ufixed16x56 DEFAULT = new Ufixed16x56(BigInteger.ZERO); + + public Ufixed16x56(BigInteger value) { + super(16, 56, value); + } + + public Ufixed16x56(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 56, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x64.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x64.java new file mode 100644 index 0000000000..2173e6b0fa --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x64.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed16x64 extends Ufixed { + public static final Ufixed16x64 DEFAULT = new Ufixed16x64(BigInteger.ZERO); + + public Ufixed16x64(BigInteger value) { + super(16, 64, value); + } + + public Ufixed16x64(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 64, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x72.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x72.java new file mode 100644 index 0000000000..dd6ee6fa95 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x72.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed16x72 extends Ufixed { + public static final Ufixed16x72 DEFAULT = new Ufixed16x72(BigInteger.ZERO); + + public Ufixed16x72(BigInteger value) { + super(16, 72, value); + } + + public Ufixed16x72(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 72, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x8.java new file mode 100644 index 0000000000..03edb19d03 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed16x8 extends Ufixed { + public static final Ufixed16x8 DEFAULT = new Ufixed16x8(BigInteger.ZERO); + + public Ufixed16x8(BigInteger value) { + super(16, 8, value); + } + + public Ufixed16x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x80.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x80.java new file mode 100644 index 0000000000..926740f6a2 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x80.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed16x80 extends Ufixed { + public static final Ufixed16x80 DEFAULT = new Ufixed16x80(BigInteger.ZERO); + + public Ufixed16x80(BigInteger value) { + super(16, 80, value); + } + + public Ufixed16x80(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 80, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x88.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x88.java new file mode 100644 index 0000000000..dffefd5d56 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x88.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed16x88 extends Ufixed { + public static final Ufixed16x88 DEFAULT = new Ufixed16x88(BigInteger.ZERO); + + public Ufixed16x88(BigInteger value) { + super(16, 88, value); + } + + public Ufixed16x88(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 88, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x96.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x96.java new file mode 100644 index 0000000000..eb0f6d7003 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed16x96.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed16x96 extends Ufixed { + public static final Ufixed16x96 DEFAULT = new Ufixed16x96(BigInteger.ZERO); + + public Ufixed16x96(BigInteger value) { + super(16, 96, value); + } + + public Ufixed16x96(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(16, 96, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed176x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed176x16.java new file mode 100644 index 0000000000..37c6fb6b99 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed176x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed176x16 extends Ufixed { + public static final Ufixed176x16 DEFAULT = new Ufixed176x16(BigInteger.ZERO); + + public Ufixed176x16(BigInteger value) { + super(176, 16, value); + } + + public Ufixed176x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(176, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed176x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed176x24.java new file mode 100644 index 0000000000..7704abc7c5 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed176x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed176x24 extends Ufixed { + public static final Ufixed176x24 DEFAULT = new Ufixed176x24(BigInteger.ZERO); + + public Ufixed176x24(BigInteger value) { + super(176, 24, value); + } + + public Ufixed176x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(176, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed176x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed176x32.java new file mode 100644 index 0000000000..f730ec32f2 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed176x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed176x32 extends Ufixed { + public static final Ufixed176x32 DEFAULT = new Ufixed176x32(BigInteger.ZERO); + + public Ufixed176x32(BigInteger value) { + super(176, 32, value); + } + + public Ufixed176x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(176, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed176x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed176x40.java new file mode 100644 index 0000000000..eae9c926cc --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed176x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed176x40 extends Ufixed { + public static final Ufixed176x40 DEFAULT = new Ufixed176x40(BigInteger.ZERO); + + public Ufixed176x40(BigInteger value) { + super(176, 40, value); + } + + public Ufixed176x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(176, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed176x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed176x48.java new file mode 100644 index 0000000000..01c188f270 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed176x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed176x48 extends Ufixed { + public static final Ufixed176x48 DEFAULT = new Ufixed176x48(BigInteger.ZERO); + + public Ufixed176x48(BigInteger value) { + super(176, 48, value); + } + + public Ufixed176x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(176, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed176x56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed176x56.java new file mode 100644 index 0000000000..ccbf591ce1 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed176x56.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed176x56 extends Ufixed { + public static final Ufixed176x56 DEFAULT = new Ufixed176x56(BigInteger.ZERO); + + public Ufixed176x56(BigInteger value) { + super(176, 56, value); + } + + public Ufixed176x56(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(176, 56, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed176x64.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed176x64.java new file mode 100644 index 0000000000..641cdf7700 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed176x64.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed176x64 extends Ufixed { + public static final Ufixed176x64 DEFAULT = new Ufixed176x64(BigInteger.ZERO); + + public Ufixed176x64(BigInteger value) { + super(176, 64, value); + } + + public Ufixed176x64(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(176, 64, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed176x72.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed176x72.java new file mode 100644 index 0000000000..c195b05da5 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed176x72.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed176x72 extends Ufixed { + public static final Ufixed176x72 DEFAULT = new Ufixed176x72(BigInteger.ZERO); + + public Ufixed176x72(BigInteger value) { + super(176, 72, value); + } + + public Ufixed176x72(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(176, 72, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed176x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed176x8.java new file mode 100644 index 0000000000..789667faa0 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed176x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed176x8 extends Ufixed { + public static final Ufixed176x8 DEFAULT = new Ufixed176x8(BigInteger.ZERO); + + public Ufixed176x8(BigInteger value) { + super(176, 8, value); + } + + public Ufixed176x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(176, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed176x80.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed176x80.java new file mode 100644 index 0000000000..e73e735bf9 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed176x80.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed176x80 extends Ufixed { + public static final Ufixed176x80 DEFAULT = new Ufixed176x80(BigInteger.ZERO); + + public Ufixed176x80(BigInteger value) { + super(176, 80, value); + } + + public Ufixed176x80(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(176, 80, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed184x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed184x16.java new file mode 100644 index 0000000000..6b671578b1 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed184x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed184x16 extends Ufixed { + public static final Ufixed184x16 DEFAULT = new Ufixed184x16(BigInteger.ZERO); + + public Ufixed184x16(BigInteger value) { + super(184, 16, value); + } + + public Ufixed184x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(184, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed184x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed184x24.java new file mode 100644 index 0000000000..7bc015ad9f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed184x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed184x24 extends Ufixed { + public static final Ufixed184x24 DEFAULT = new Ufixed184x24(BigInteger.ZERO); + + public Ufixed184x24(BigInteger value) { + super(184, 24, value); + } + + public Ufixed184x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(184, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed184x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed184x32.java new file mode 100644 index 0000000000..448dec0f37 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed184x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed184x32 extends Ufixed { + public static final Ufixed184x32 DEFAULT = new Ufixed184x32(BigInteger.ZERO); + + public Ufixed184x32(BigInteger value) { + super(184, 32, value); + } + + public Ufixed184x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(184, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed184x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed184x40.java new file mode 100644 index 0000000000..2e96d0ab26 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed184x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed184x40 extends Ufixed { + public static final Ufixed184x40 DEFAULT = new Ufixed184x40(BigInteger.ZERO); + + public Ufixed184x40(BigInteger value) { + super(184, 40, value); + } + + public Ufixed184x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(184, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed184x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed184x48.java new file mode 100644 index 0000000000..3735c4ce13 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed184x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed184x48 extends Ufixed { + public static final Ufixed184x48 DEFAULT = new Ufixed184x48(BigInteger.ZERO); + + public Ufixed184x48(BigInteger value) { + super(184, 48, value); + } + + public Ufixed184x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(184, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed184x56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed184x56.java new file mode 100644 index 0000000000..6ac59d5503 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed184x56.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed184x56 extends Ufixed { + public static final Ufixed184x56 DEFAULT = new Ufixed184x56(BigInteger.ZERO); + + public Ufixed184x56(BigInteger value) { + super(184, 56, value); + } + + public Ufixed184x56(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(184, 56, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed184x64.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed184x64.java new file mode 100644 index 0000000000..4e3b365ea6 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed184x64.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed184x64 extends Ufixed { + public static final Ufixed184x64 DEFAULT = new Ufixed184x64(BigInteger.ZERO); + + public Ufixed184x64(BigInteger value) { + super(184, 64, value); + } + + public Ufixed184x64(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(184, 64, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed184x72.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed184x72.java new file mode 100644 index 0000000000..988c518ef2 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed184x72.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed184x72 extends Ufixed { + public static final Ufixed184x72 DEFAULT = new Ufixed184x72(BigInteger.ZERO); + + public Ufixed184x72(BigInteger value) { + super(184, 72, value); + } + + public Ufixed184x72(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(184, 72, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed184x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed184x8.java new file mode 100644 index 0000000000..f55ad1f6cc --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed184x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed184x8 extends Ufixed { + public static final Ufixed184x8 DEFAULT = new Ufixed184x8(BigInteger.ZERO); + + public Ufixed184x8(BigInteger value) { + super(184, 8, value); + } + + public Ufixed184x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(184, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed192x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed192x16.java new file mode 100644 index 0000000000..197a38134b --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed192x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed192x16 extends Ufixed { + public static final Ufixed192x16 DEFAULT = new Ufixed192x16(BigInteger.ZERO); + + public Ufixed192x16(BigInteger value) { + super(192, 16, value); + } + + public Ufixed192x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(192, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed192x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed192x24.java new file mode 100644 index 0000000000..060da71088 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed192x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed192x24 extends Ufixed { + public static final Ufixed192x24 DEFAULT = new Ufixed192x24(BigInteger.ZERO); + + public Ufixed192x24(BigInteger value) { + super(192, 24, value); + } + + public Ufixed192x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(192, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed192x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed192x32.java new file mode 100644 index 0000000000..08882d48f4 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed192x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed192x32 extends Ufixed { + public static final Ufixed192x32 DEFAULT = new Ufixed192x32(BigInteger.ZERO); + + public Ufixed192x32(BigInteger value) { + super(192, 32, value); + } + + public Ufixed192x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(192, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed192x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed192x40.java new file mode 100644 index 0000000000..78dac2ce1a --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed192x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed192x40 extends Ufixed { + public static final Ufixed192x40 DEFAULT = new Ufixed192x40(BigInteger.ZERO); + + public Ufixed192x40(BigInteger value) { + super(192, 40, value); + } + + public Ufixed192x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(192, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed192x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed192x48.java new file mode 100644 index 0000000000..2374872e3f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed192x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed192x48 extends Ufixed { + public static final Ufixed192x48 DEFAULT = new Ufixed192x48(BigInteger.ZERO); + + public Ufixed192x48(BigInteger value) { + super(192, 48, value); + } + + public Ufixed192x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(192, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed192x56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed192x56.java new file mode 100644 index 0000000000..680dd50401 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed192x56.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed192x56 extends Ufixed { + public static final Ufixed192x56 DEFAULT = new Ufixed192x56(BigInteger.ZERO); + + public Ufixed192x56(BigInteger value) { + super(192, 56, value); + } + + public Ufixed192x56(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(192, 56, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed192x64.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed192x64.java new file mode 100644 index 0000000000..698ef47ebe --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed192x64.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed192x64 extends Ufixed { + public static final Ufixed192x64 DEFAULT = new Ufixed192x64(BigInteger.ZERO); + + public Ufixed192x64(BigInteger value) { + super(192, 64, value); + } + + public Ufixed192x64(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(192, 64, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed192x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed192x8.java new file mode 100644 index 0000000000..e4fe8cffd7 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed192x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed192x8 extends Ufixed { + public static final Ufixed192x8 DEFAULT = new Ufixed192x8(BigInteger.ZERO); + + public Ufixed192x8(BigInteger value) { + super(192, 8, value); + } + + public Ufixed192x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(192, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed200x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed200x16.java new file mode 100644 index 0000000000..b04122ec7e --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed200x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed200x16 extends Ufixed { + public static final Ufixed200x16 DEFAULT = new Ufixed200x16(BigInteger.ZERO); + + public Ufixed200x16(BigInteger value) { + super(200, 16, value); + } + + public Ufixed200x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(200, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed200x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed200x24.java new file mode 100644 index 0000000000..5bacff27ae --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed200x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed200x24 extends Ufixed { + public static final Ufixed200x24 DEFAULT = new Ufixed200x24(BigInteger.ZERO); + + public Ufixed200x24(BigInteger value) { + super(200, 24, value); + } + + public Ufixed200x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(200, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed200x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed200x32.java new file mode 100644 index 0000000000..9f719287e2 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed200x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed200x32 extends Ufixed { + public static final Ufixed200x32 DEFAULT = new Ufixed200x32(BigInteger.ZERO); + + public Ufixed200x32(BigInteger value) { + super(200, 32, value); + } + + public Ufixed200x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(200, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed200x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed200x40.java new file mode 100644 index 0000000000..8c1c47dc41 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed200x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed200x40 extends Ufixed { + public static final Ufixed200x40 DEFAULT = new Ufixed200x40(BigInteger.ZERO); + + public Ufixed200x40(BigInteger value) { + super(200, 40, value); + } + + public Ufixed200x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(200, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed200x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed200x48.java new file mode 100644 index 0000000000..164663a199 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed200x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed200x48 extends Ufixed { + public static final Ufixed200x48 DEFAULT = new Ufixed200x48(BigInteger.ZERO); + + public Ufixed200x48(BigInteger value) { + super(200, 48, value); + } + + public Ufixed200x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(200, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed200x56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed200x56.java new file mode 100644 index 0000000000..5694a17b12 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed200x56.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed200x56 extends Ufixed { + public static final Ufixed200x56 DEFAULT = new Ufixed200x56(BigInteger.ZERO); + + public Ufixed200x56(BigInteger value) { + super(200, 56, value); + } + + public Ufixed200x56(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(200, 56, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed200x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed200x8.java new file mode 100644 index 0000000000..d19b56fe17 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed200x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed200x8 extends Ufixed { + public static final Ufixed200x8 DEFAULT = new Ufixed200x8(BigInteger.ZERO); + + public Ufixed200x8(BigInteger value) { + super(200, 8, value); + } + + public Ufixed200x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(200, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed208x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed208x16.java new file mode 100644 index 0000000000..670a08525c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed208x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed208x16 extends Ufixed { + public static final Ufixed208x16 DEFAULT = new Ufixed208x16(BigInteger.ZERO); + + public Ufixed208x16(BigInteger value) { + super(208, 16, value); + } + + public Ufixed208x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(208, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed208x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed208x24.java new file mode 100644 index 0000000000..8ecb2926bf --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed208x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed208x24 extends Ufixed { + public static final Ufixed208x24 DEFAULT = new Ufixed208x24(BigInteger.ZERO); + + public Ufixed208x24(BigInteger value) { + super(208, 24, value); + } + + public Ufixed208x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(208, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed208x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed208x32.java new file mode 100644 index 0000000000..8302a1313c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed208x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed208x32 extends Ufixed { + public static final Ufixed208x32 DEFAULT = new Ufixed208x32(BigInteger.ZERO); + + public Ufixed208x32(BigInteger value) { + super(208, 32, value); + } + + public Ufixed208x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(208, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed208x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed208x40.java new file mode 100644 index 0000000000..2ab567e197 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed208x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed208x40 extends Ufixed { + public static final Ufixed208x40 DEFAULT = new Ufixed208x40(BigInteger.ZERO); + + public Ufixed208x40(BigInteger value) { + super(208, 40, value); + } + + public Ufixed208x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(208, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed208x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed208x48.java new file mode 100644 index 0000000000..4d2169c400 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed208x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed208x48 extends Ufixed { + public static final Ufixed208x48 DEFAULT = new Ufixed208x48(BigInteger.ZERO); + + public Ufixed208x48(BigInteger value) { + super(208, 48, value); + } + + public Ufixed208x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(208, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed208x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed208x8.java new file mode 100644 index 0000000000..8550c9f524 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed208x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed208x8 extends Ufixed { + public static final Ufixed208x8 DEFAULT = new Ufixed208x8(BigInteger.ZERO); + + public Ufixed208x8(BigInteger value) { + super(208, 8, value); + } + + public Ufixed208x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(208, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed216x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed216x16.java new file mode 100644 index 0000000000..2ff34c1851 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed216x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed216x16 extends Ufixed { + public static final Ufixed216x16 DEFAULT = new Ufixed216x16(BigInteger.ZERO); + + public Ufixed216x16(BigInteger value) { + super(216, 16, value); + } + + public Ufixed216x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(216, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed216x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed216x24.java new file mode 100644 index 0000000000..b009901eb8 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed216x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed216x24 extends Ufixed { + public static final Ufixed216x24 DEFAULT = new Ufixed216x24(BigInteger.ZERO); + + public Ufixed216x24(BigInteger value) { + super(216, 24, value); + } + + public Ufixed216x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(216, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed216x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed216x32.java new file mode 100644 index 0000000000..24ecd4ff03 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed216x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed216x32 extends Ufixed { + public static final Ufixed216x32 DEFAULT = new Ufixed216x32(BigInteger.ZERO); + + public Ufixed216x32(BigInteger value) { + super(216, 32, value); + } + + public Ufixed216x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(216, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed216x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed216x40.java new file mode 100644 index 0000000000..59d36821a6 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed216x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed216x40 extends Ufixed { + public static final Ufixed216x40 DEFAULT = new Ufixed216x40(BigInteger.ZERO); + + public Ufixed216x40(BigInteger value) { + super(216, 40, value); + } + + public Ufixed216x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(216, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed216x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed216x8.java new file mode 100644 index 0000000000..c7a37cebc2 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed216x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed216x8 extends Ufixed { + public static final Ufixed216x8 DEFAULT = new Ufixed216x8(BigInteger.ZERO); + + public Ufixed216x8(BigInteger value) { + super(216, 8, value); + } + + public Ufixed216x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(216, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed224x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed224x16.java new file mode 100644 index 0000000000..9c613ac25d --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed224x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed224x16 extends Ufixed { + public static final Ufixed224x16 DEFAULT = new Ufixed224x16(BigInteger.ZERO); + + public Ufixed224x16(BigInteger value) { + super(224, 16, value); + } + + public Ufixed224x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(224, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed224x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed224x24.java new file mode 100644 index 0000000000..129e3afca4 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed224x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed224x24 extends Ufixed { + public static final Ufixed224x24 DEFAULT = new Ufixed224x24(BigInteger.ZERO); + + public Ufixed224x24(BigInteger value) { + super(224, 24, value); + } + + public Ufixed224x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(224, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed224x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed224x32.java new file mode 100644 index 0000000000..85bfc81cae --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed224x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed224x32 extends Ufixed { + public static final Ufixed224x32 DEFAULT = new Ufixed224x32(BigInteger.ZERO); + + public Ufixed224x32(BigInteger value) { + super(224, 32, value); + } + + public Ufixed224x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(224, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed224x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed224x8.java new file mode 100644 index 0000000000..ad0f7b94bc --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed224x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed224x8 extends Ufixed { + public static final Ufixed224x8 DEFAULT = new Ufixed224x8(BigInteger.ZERO); + + public Ufixed224x8(BigInteger value) { + super(224, 8, value); + } + + public Ufixed224x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(224, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed232x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed232x16.java new file mode 100644 index 0000000000..ee97e3d0ab --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed232x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed232x16 extends Ufixed { + public static final Ufixed232x16 DEFAULT = new Ufixed232x16(BigInteger.ZERO); + + public Ufixed232x16(BigInteger value) { + super(232, 16, value); + } + + public Ufixed232x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(232, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed232x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed232x24.java new file mode 100644 index 0000000000..824c7138c4 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed232x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed232x24 extends Ufixed { + public static final Ufixed232x24 DEFAULT = new Ufixed232x24(BigInteger.ZERO); + + public Ufixed232x24(BigInteger value) { + super(232, 24, value); + } + + public Ufixed232x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(232, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed232x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed232x8.java new file mode 100644 index 0000000000..121ad38dd5 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed232x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed232x8 extends Ufixed { + public static final Ufixed232x8 DEFAULT = new Ufixed232x8(BigInteger.ZERO); + + public Ufixed232x8(BigInteger value) { + super(232, 8, value); + } + + public Ufixed232x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(232, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed240x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed240x16.java new file mode 100644 index 0000000000..3a3e12217a --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed240x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed240x16 extends Ufixed { + public static final Ufixed240x16 DEFAULT = new Ufixed240x16(BigInteger.ZERO); + + public Ufixed240x16(BigInteger value) { + super(240, 16, value); + } + + public Ufixed240x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(240, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed240x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed240x8.java new file mode 100644 index 0000000000..2039044adb --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed240x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed240x8 extends Ufixed { + public static final Ufixed240x8 DEFAULT = new Ufixed240x8(BigInteger.ZERO); + + public Ufixed240x8(BigInteger value) { + super(240, 8, value); + } + + public Ufixed240x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(240, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed248x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed248x8.java new file mode 100644 index 0000000000..1987f4470f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed248x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed248x8 extends Ufixed { + public static final Ufixed248x8 DEFAULT = new Ufixed248x8(BigInteger.ZERO); + + public Ufixed248x8(BigInteger value) { + super(248, 8, value); + } + + public Ufixed248x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(248, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x104.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x104.java new file mode 100644 index 0000000000..3fe5694da0 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x104.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed24x104 extends Ufixed { + public static final Ufixed24x104 DEFAULT = new Ufixed24x104(BigInteger.ZERO); + + public Ufixed24x104(BigInteger value) { + super(24, 104, value); + } + + public Ufixed24x104(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 104, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x112.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x112.java new file mode 100644 index 0000000000..c9e63b3f22 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x112.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed24x112 extends Ufixed { + public static final Ufixed24x112 DEFAULT = new Ufixed24x112(BigInteger.ZERO); + + public Ufixed24x112(BigInteger value) { + super(24, 112, value); + } + + public Ufixed24x112(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 112, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x120.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x120.java new file mode 100644 index 0000000000..48a3abf04f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x120.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed24x120 extends Ufixed { + public static final Ufixed24x120 DEFAULT = new Ufixed24x120(BigInteger.ZERO); + + public Ufixed24x120(BigInteger value) { + super(24, 120, value); + } + + public Ufixed24x120(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 120, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x128.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x128.java new file mode 100644 index 0000000000..e491ce82b4 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x128.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed24x128 extends Ufixed { + public static final Ufixed24x128 DEFAULT = new Ufixed24x128(BigInteger.ZERO); + + public Ufixed24x128(BigInteger value) { + super(24, 128, value); + } + + public Ufixed24x128(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 128, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x136.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x136.java new file mode 100644 index 0000000000..23e5c03b59 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x136.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed24x136 extends Ufixed { + public static final Ufixed24x136 DEFAULT = new Ufixed24x136(BigInteger.ZERO); + + public Ufixed24x136(BigInteger value) { + super(24, 136, value); + } + + public Ufixed24x136(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 136, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x144.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x144.java new file mode 100644 index 0000000000..43829b3fe0 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x144.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed24x144 extends Ufixed { + public static final Ufixed24x144 DEFAULT = new Ufixed24x144(BigInteger.ZERO); + + public Ufixed24x144(BigInteger value) { + super(24, 144, value); + } + + public Ufixed24x144(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 144, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x152.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x152.java new file mode 100644 index 0000000000..aab425f3f6 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x152.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed24x152 extends Ufixed { + public static final Ufixed24x152 DEFAULT = new Ufixed24x152(BigInteger.ZERO); + + public Ufixed24x152(BigInteger value) { + super(24, 152, value); + } + + public Ufixed24x152(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 152, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x16.java new file mode 100644 index 0000000000..d4d4cdaf44 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed24x16 extends Ufixed { + public static final Ufixed24x16 DEFAULT = new Ufixed24x16(BigInteger.ZERO); + + public Ufixed24x16(BigInteger value) { + super(24, 16, value); + } + + public Ufixed24x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x160.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x160.java new file mode 100644 index 0000000000..d6b581a093 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x160.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed24x160 extends Ufixed { + public static final Ufixed24x160 DEFAULT = new Ufixed24x160(BigInteger.ZERO); + + public Ufixed24x160(BigInteger value) { + super(24, 160, value); + } + + public Ufixed24x160(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 160, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x168.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x168.java new file mode 100644 index 0000000000..6417571fa6 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x168.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed24x168 extends Ufixed { + public static final Ufixed24x168 DEFAULT = new Ufixed24x168(BigInteger.ZERO); + + public Ufixed24x168(BigInteger value) { + super(24, 168, value); + } + + public Ufixed24x168(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 168, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x176.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x176.java new file mode 100644 index 0000000000..0633aea70a --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x176.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed24x176 extends Ufixed { + public static final Ufixed24x176 DEFAULT = new Ufixed24x176(BigInteger.ZERO); + + public Ufixed24x176(BigInteger value) { + super(24, 176, value); + } + + public Ufixed24x176(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 176, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x184.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x184.java new file mode 100644 index 0000000000..4a4c8de041 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x184.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed24x184 extends Ufixed { + public static final Ufixed24x184 DEFAULT = new Ufixed24x184(BigInteger.ZERO); + + public Ufixed24x184(BigInteger value) { + super(24, 184, value); + } + + public Ufixed24x184(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 184, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x192.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x192.java new file mode 100644 index 0000000000..14be38025f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x192.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed24x192 extends Ufixed { + public static final Ufixed24x192 DEFAULT = new Ufixed24x192(BigInteger.ZERO); + + public Ufixed24x192(BigInteger value) { + super(24, 192, value); + } + + public Ufixed24x192(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 192, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x200.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x200.java new file mode 100644 index 0000000000..01b0d0a5bc --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x200.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed24x200 extends Ufixed { + public static final Ufixed24x200 DEFAULT = new Ufixed24x200(BigInteger.ZERO); + + public Ufixed24x200(BigInteger value) { + super(24, 200, value); + } + + public Ufixed24x200(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 200, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x208.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x208.java new file mode 100644 index 0000000000..4c15c74234 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x208.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed24x208 extends Ufixed { + public static final Ufixed24x208 DEFAULT = new Ufixed24x208(BigInteger.ZERO); + + public Ufixed24x208(BigInteger value) { + super(24, 208, value); + } + + public Ufixed24x208(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 208, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x216.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x216.java new file mode 100644 index 0000000000..9f591ffb9a --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x216.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed24x216 extends Ufixed { + public static final Ufixed24x216 DEFAULT = new Ufixed24x216(BigInteger.ZERO); + + public Ufixed24x216(BigInteger value) { + super(24, 216, value); + } + + public Ufixed24x216(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 216, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x224.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x224.java new file mode 100644 index 0000000000..46774be682 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x224.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed24x224 extends Ufixed { + public static final Ufixed24x224 DEFAULT = new Ufixed24x224(BigInteger.ZERO); + + public Ufixed24x224(BigInteger value) { + super(24, 224, value); + } + + public Ufixed24x224(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 224, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x232.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x232.java new file mode 100644 index 0000000000..3bb018d378 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x232.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed24x232 extends Ufixed { + public static final Ufixed24x232 DEFAULT = new Ufixed24x232(BigInteger.ZERO); + + public Ufixed24x232(BigInteger value) { + super(24, 232, value); + } + + public Ufixed24x232(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 232, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x24.java new file mode 100644 index 0000000000..5886a7c4d4 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed24x24 extends Ufixed { + public static final Ufixed24x24 DEFAULT = new Ufixed24x24(BigInteger.ZERO); + + public Ufixed24x24(BigInteger value) { + super(24, 24, value); + } + + public Ufixed24x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x32.java new file mode 100644 index 0000000000..a96384a6eb --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed24x32 extends Ufixed { + public static final Ufixed24x32 DEFAULT = new Ufixed24x32(BigInteger.ZERO); + + public Ufixed24x32(BigInteger value) { + super(24, 32, value); + } + + public Ufixed24x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x40.java new file mode 100644 index 0000000000..2e0aa764c8 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed24x40 extends Ufixed { + public static final Ufixed24x40 DEFAULT = new Ufixed24x40(BigInteger.ZERO); + + public Ufixed24x40(BigInteger value) { + super(24, 40, value); + } + + public Ufixed24x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x48.java new file mode 100644 index 0000000000..ba903b24e9 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed24x48 extends Ufixed { + public static final Ufixed24x48 DEFAULT = new Ufixed24x48(BigInteger.ZERO); + + public Ufixed24x48(BigInteger value) { + super(24, 48, value); + } + + public Ufixed24x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x56.java new file mode 100644 index 0000000000..aa87689111 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x56.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed24x56 extends Ufixed { + public static final Ufixed24x56 DEFAULT = new Ufixed24x56(BigInteger.ZERO); + + public Ufixed24x56(BigInteger value) { + super(24, 56, value); + } + + public Ufixed24x56(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 56, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x64.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x64.java new file mode 100644 index 0000000000..82f994c7d4 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x64.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed24x64 extends Ufixed { + public static final Ufixed24x64 DEFAULT = new Ufixed24x64(BigInteger.ZERO); + + public Ufixed24x64(BigInteger value) { + super(24, 64, value); + } + + public Ufixed24x64(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 64, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x72.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x72.java new file mode 100644 index 0000000000..f3d9e33434 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x72.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed24x72 extends Ufixed { + public static final Ufixed24x72 DEFAULT = new Ufixed24x72(BigInteger.ZERO); + + public Ufixed24x72(BigInteger value) { + super(24, 72, value); + } + + public Ufixed24x72(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 72, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x8.java new file mode 100644 index 0000000000..b575e5870c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed24x8 extends Ufixed { + public static final Ufixed24x8 DEFAULT = new Ufixed24x8(BigInteger.ZERO); + + public Ufixed24x8(BigInteger value) { + super(24, 8, value); + } + + public Ufixed24x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x80.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x80.java new file mode 100644 index 0000000000..07e6a52ea5 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x80.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed24x80 extends Ufixed { + public static final Ufixed24x80 DEFAULT = new Ufixed24x80(BigInteger.ZERO); + + public Ufixed24x80(BigInteger value) { + super(24, 80, value); + } + + public Ufixed24x80(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 80, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x88.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x88.java new file mode 100644 index 0000000000..f48403fcf8 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x88.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed24x88 extends Ufixed { + public static final Ufixed24x88 DEFAULT = new Ufixed24x88(BigInteger.ZERO); + + public Ufixed24x88(BigInteger value) { + super(24, 88, value); + } + + public Ufixed24x88(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 88, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x96.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x96.java new file mode 100644 index 0000000000..6663e4a321 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed24x96.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed24x96 extends Ufixed { + public static final Ufixed24x96 DEFAULT = new Ufixed24x96(BigInteger.ZERO); + + public Ufixed24x96(BigInteger value) { + super(24, 96, value); + } + + public Ufixed24x96(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(24, 96, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x104.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x104.java new file mode 100644 index 0000000000..cd0a7c8447 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x104.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed32x104 extends Ufixed { + public static final Ufixed32x104 DEFAULT = new Ufixed32x104(BigInteger.ZERO); + + public Ufixed32x104(BigInteger value) { + super(32, 104, value); + } + + public Ufixed32x104(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 104, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x112.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x112.java new file mode 100644 index 0000000000..7dfa7fd914 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x112.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed32x112 extends Ufixed { + public static final Ufixed32x112 DEFAULT = new Ufixed32x112(BigInteger.ZERO); + + public Ufixed32x112(BigInteger value) { + super(32, 112, value); + } + + public Ufixed32x112(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 112, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x120.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x120.java new file mode 100644 index 0000000000..5b8f2f99db --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x120.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed32x120 extends Ufixed { + public static final Ufixed32x120 DEFAULT = new Ufixed32x120(BigInteger.ZERO); + + public Ufixed32x120(BigInteger value) { + super(32, 120, value); + } + + public Ufixed32x120(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 120, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x128.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x128.java new file mode 100644 index 0000000000..903bae5d95 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x128.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed32x128 extends Ufixed { + public static final Ufixed32x128 DEFAULT = new Ufixed32x128(BigInteger.ZERO); + + public Ufixed32x128(BigInteger value) { + super(32, 128, value); + } + + public Ufixed32x128(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 128, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x136.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x136.java new file mode 100644 index 0000000000..2a84380c98 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x136.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed32x136 extends Ufixed { + public static final Ufixed32x136 DEFAULT = new Ufixed32x136(BigInteger.ZERO); + + public Ufixed32x136(BigInteger value) { + super(32, 136, value); + } + + public Ufixed32x136(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 136, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x144.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x144.java new file mode 100644 index 0000000000..c8ea85ff36 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x144.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed32x144 extends Ufixed { + public static final Ufixed32x144 DEFAULT = new Ufixed32x144(BigInteger.ZERO); + + public Ufixed32x144(BigInteger value) { + super(32, 144, value); + } + + public Ufixed32x144(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 144, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x152.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x152.java new file mode 100644 index 0000000000..6d34d7e40b --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x152.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed32x152 extends Ufixed { + public static final Ufixed32x152 DEFAULT = new Ufixed32x152(BigInteger.ZERO); + + public Ufixed32x152(BigInteger value) { + super(32, 152, value); + } + + public Ufixed32x152(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 152, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x16.java new file mode 100644 index 0000000000..9ef4b3fe63 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed32x16 extends Ufixed { + public static final Ufixed32x16 DEFAULT = new Ufixed32x16(BigInteger.ZERO); + + public Ufixed32x16(BigInteger value) { + super(32, 16, value); + } + + public Ufixed32x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x160.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x160.java new file mode 100644 index 0000000000..9ecfa9fc76 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x160.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed32x160 extends Ufixed { + public static final Ufixed32x160 DEFAULT = new Ufixed32x160(BigInteger.ZERO); + + public Ufixed32x160(BigInteger value) { + super(32, 160, value); + } + + public Ufixed32x160(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 160, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x168.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x168.java new file mode 100644 index 0000000000..dc5589bb95 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x168.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed32x168 extends Ufixed { + public static final Ufixed32x168 DEFAULT = new Ufixed32x168(BigInteger.ZERO); + + public Ufixed32x168(BigInteger value) { + super(32, 168, value); + } + + public Ufixed32x168(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 168, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x176.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x176.java new file mode 100644 index 0000000000..ca3e8147a5 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x176.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed32x176 extends Ufixed { + public static final Ufixed32x176 DEFAULT = new Ufixed32x176(BigInteger.ZERO); + + public Ufixed32x176(BigInteger value) { + super(32, 176, value); + } + + public Ufixed32x176(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 176, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x184.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x184.java new file mode 100644 index 0000000000..7b5cfd11d9 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x184.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed32x184 extends Ufixed { + public static final Ufixed32x184 DEFAULT = new Ufixed32x184(BigInteger.ZERO); + + public Ufixed32x184(BigInteger value) { + super(32, 184, value); + } + + public Ufixed32x184(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 184, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x192.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x192.java new file mode 100644 index 0000000000..c73a167fbc --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x192.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed32x192 extends Ufixed { + public static final Ufixed32x192 DEFAULT = new Ufixed32x192(BigInteger.ZERO); + + public Ufixed32x192(BigInteger value) { + super(32, 192, value); + } + + public Ufixed32x192(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 192, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x200.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x200.java new file mode 100644 index 0000000000..d80b2f3ff4 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x200.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed32x200 extends Ufixed { + public static final Ufixed32x200 DEFAULT = new Ufixed32x200(BigInteger.ZERO); + + public Ufixed32x200(BigInteger value) { + super(32, 200, value); + } + + public Ufixed32x200(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 200, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x208.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x208.java new file mode 100644 index 0000000000..205c3c3669 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x208.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed32x208 extends Ufixed { + public static final Ufixed32x208 DEFAULT = new Ufixed32x208(BigInteger.ZERO); + + public Ufixed32x208(BigInteger value) { + super(32, 208, value); + } + + public Ufixed32x208(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 208, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x216.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x216.java new file mode 100644 index 0000000000..5709698561 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x216.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed32x216 extends Ufixed { + public static final Ufixed32x216 DEFAULT = new Ufixed32x216(BigInteger.ZERO); + + public Ufixed32x216(BigInteger value) { + super(32, 216, value); + } + + public Ufixed32x216(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 216, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x224.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x224.java new file mode 100644 index 0000000000..f2b8351657 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x224.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed32x224 extends Ufixed { + public static final Ufixed32x224 DEFAULT = new Ufixed32x224(BigInteger.ZERO); + + public Ufixed32x224(BigInteger value) { + super(32, 224, value); + } + + public Ufixed32x224(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 224, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x24.java new file mode 100644 index 0000000000..614d7f999c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed32x24 extends Ufixed { + public static final Ufixed32x24 DEFAULT = new Ufixed32x24(BigInteger.ZERO); + + public Ufixed32x24(BigInteger value) { + super(32, 24, value); + } + + public Ufixed32x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x32.java new file mode 100644 index 0000000000..9eaf164183 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed32x32 extends Ufixed { + public static final Ufixed32x32 DEFAULT = new Ufixed32x32(BigInteger.ZERO); + + public Ufixed32x32(BigInteger value) { + super(32, 32, value); + } + + public Ufixed32x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x40.java new file mode 100644 index 0000000000..7fd4aeb911 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed32x40 extends Ufixed { + public static final Ufixed32x40 DEFAULT = new Ufixed32x40(BigInteger.ZERO); + + public Ufixed32x40(BigInteger value) { + super(32, 40, value); + } + + public Ufixed32x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x48.java new file mode 100644 index 0000000000..3ba49693a7 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed32x48 extends Ufixed { + public static final Ufixed32x48 DEFAULT = new Ufixed32x48(BigInteger.ZERO); + + public Ufixed32x48(BigInteger value) { + super(32, 48, value); + } + + public Ufixed32x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x56.java new file mode 100644 index 0000000000..4f9cbc511b --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x56.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed32x56 extends Ufixed { + public static final Ufixed32x56 DEFAULT = new Ufixed32x56(BigInteger.ZERO); + + public Ufixed32x56(BigInteger value) { + super(32, 56, value); + } + + public Ufixed32x56(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 56, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x64.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x64.java new file mode 100644 index 0000000000..a9b1acd3b7 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x64.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed32x64 extends Ufixed { + public static final Ufixed32x64 DEFAULT = new Ufixed32x64(BigInteger.ZERO); + + public Ufixed32x64(BigInteger value) { + super(32, 64, value); + } + + public Ufixed32x64(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 64, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x72.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x72.java new file mode 100644 index 0000000000..2a64f6e158 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x72.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed32x72 extends Ufixed { + public static final Ufixed32x72 DEFAULT = new Ufixed32x72(BigInteger.ZERO); + + public Ufixed32x72(BigInteger value) { + super(32, 72, value); + } + + public Ufixed32x72(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 72, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x8.java new file mode 100644 index 0000000000..c8f469100e --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed32x8 extends Ufixed { + public static final Ufixed32x8 DEFAULT = new Ufixed32x8(BigInteger.ZERO); + + public Ufixed32x8(BigInteger value) { + super(32, 8, value); + } + + public Ufixed32x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x80.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x80.java new file mode 100644 index 0000000000..db2785c86e --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x80.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed32x80 extends Ufixed { + public static final Ufixed32x80 DEFAULT = new Ufixed32x80(BigInteger.ZERO); + + public Ufixed32x80(BigInteger value) { + super(32, 80, value); + } + + public Ufixed32x80(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 80, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x88.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x88.java new file mode 100644 index 0000000000..8dd0fe46df --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x88.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed32x88 extends Ufixed { + public static final Ufixed32x88 DEFAULT = new Ufixed32x88(BigInteger.ZERO); + + public Ufixed32x88(BigInteger value) { + super(32, 88, value); + } + + public Ufixed32x88(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 88, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x96.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x96.java new file mode 100644 index 0000000000..9d42b06c3e --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed32x96.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed32x96 extends Ufixed { + public static final Ufixed32x96 DEFAULT = new Ufixed32x96(BigInteger.ZERO); + + public Ufixed32x96(BigInteger value) { + super(32, 96, value); + } + + public Ufixed32x96(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(32, 96, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x104.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x104.java new file mode 100644 index 0000000000..2be764c943 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x104.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed40x104 extends Ufixed { + public static final Ufixed40x104 DEFAULT = new Ufixed40x104(BigInteger.ZERO); + + public Ufixed40x104(BigInteger value) { + super(40, 104, value); + } + + public Ufixed40x104(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 104, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x112.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x112.java new file mode 100644 index 0000000000..1f8d423f4b --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x112.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed40x112 extends Ufixed { + public static final Ufixed40x112 DEFAULT = new Ufixed40x112(BigInteger.ZERO); + + public Ufixed40x112(BigInteger value) { + super(40, 112, value); + } + + public Ufixed40x112(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 112, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x120.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x120.java new file mode 100644 index 0000000000..63a68faf21 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x120.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed40x120 extends Ufixed { + public static final Ufixed40x120 DEFAULT = new Ufixed40x120(BigInteger.ZERO); + + public Ufixed40x120(BigInteger value) { + super(40, 120, value); + } + + public Ufixed40x120(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 120, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x128.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x128.java new file mode 100644 index 0000000000..0a8153190c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x128.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed40x128 extends Ufixed { + public static final Ufixed40x128 DEFAULT = new Ufixed40x128(BigInteger.ZERO); + + public Ufixed40x128(BigInteger value) { + super(40, 128, value); + } + + public Ufixed40x128(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 128, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x136.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x136.java new file mode 100644 index 0000000000..a345cf83a1 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x136.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed40x136 extends Ufixed { + public static final Ufixed40x136 DEFAULT = new Ufixed40x136(BigInteger.ZERO); + + public Ufixed40x136(BigInteger value) { + super(40, 136, value); + } + + public Ufixed40x136(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 136, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x144.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x144.java new file mode 100644 index 0000000000..9762342930 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x144.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed40x144 extends Ufixed { + public static final Ufixed40x144 DEFAULT = new Ufixed40x144(BigInteger.ZERO); + + public Ufixed40x144(BigInteger value) { + super(40, 144, value); + } + + public Ufixed40x144(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 144, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x152.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x152.java new file mode 100644 index 0000000000..11a0472a1b --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x152.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed40x152 extends Ufixed { + public static final Ufixed40x152 DEFAULT = new Ufixed40x152(BigInteger.ZERO); + + public Ufixed40x152(BigInteger value) { + super(40, 152, value); + } + + public Ufixed40x152(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 152, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x16.java new file mode 100644 index 0000000000..d521e85fd9 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed40x16 extends Ufixed { + public static final Ufixed40x16 DEFAULT = new Ufixed40x16(BigInteger.ZERO); + + public Ufixed40x16(BigInteger value) { + super(40, 16, value); + } + + public Ufixed40x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x160.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x160.java new file mode 100644 index 0000000000..df07fd693c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x160.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed40x160 extends Ufixed { + public static final Ufixed40x160 DEFAULT = new Ufixed40x160(BigInteger.ZERO); + + public Ufixed40x160(BigInteger value) { + super(40, 160, value); + } + + public Ufixed40x160(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 160, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x168.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x168.java new file mode 100644 index 0000000000..161c15ddfd --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x168.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed40x168 extends Ufixed { + public static final Ufixed40x168 DEFAULT = new Ufixed40x168(BigInteger.ZERO); + + public Ufixed40x168(BigInteger value) { + super(40, 168, value); + } + + public Ufixed40x168(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 168, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x176.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x176.java new file mode 100644 index 0000000000..b830fb8bb5 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x176.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed40x176 extends Ufixed { + public static final Ufixed40x176 DEFAULT = new Ufixed40x176(BigInteger.ZERO); + + public Ufixed40x176(BigInteger value) { + super(40, 176, value); + } + + public Ufixed40x176(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 176, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x184.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x184.java new file mode 100644 index 0000000000..63f5b87cce --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x184.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed40x184 extends Ufixed { + public static final Ufixed40x184 DEFAULT = new Ufixed40x184(BigInteger.ZERO); + + public Ufixed40x184(BigInteger value) { + super(40, 184, value); + } + + public Ufixed40x184(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 184, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x192.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x192.java new file mode 100644 index 0000000000..f8a61623a0 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x192.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed40x192 extends Ufixed { + public static final Ufixed40x192 DEFAULT = new Ufixed40x192(BigInteger.ZERO); + + public Ufixed40x192(BigInteger value) { + super(40, 192, value); + } + + public Ufixed40x192(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 192, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x200.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x200.java new file mode 100644 index 0000000000..d92ed13df9 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x200.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed40x200 extends Ufixed { + public static final Ufixed40x200 DEFAULT = new Ufixed40x200(BigInteger.ZERO); + + public Ufixed40x200(BigInteger value) { + super(40, 200, value); + } + + public Ufixed40x200(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 200, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x208.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x208.java new file mode 100644 index 0000000000..7702fdb2a7 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x208.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed40x208 extends Ufixed { + public static final Ufixed40x208 DEFAULT = new Ufixed40x208(BigInteger.ZERO); + + public Ufixed40x208(BigInteger value) { + super(40, 208, value); + } + + public Ufixed40x208(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 208, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x216.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x216.java new file mode 100644 index 0000000000..d9a4b81e28 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x216.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed40x216 extends Ufixed { + public static final Ufixed40x216 DEFAULT = new Ufixed40x216(BigInteger.ZERO); + + public Ufixed40x216(BigInteger value) { + super(40, 216, value); + } + + public Ufixed40x216(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 216, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x24.java new file mode 100644 index 0000000000..7b3dd730a3 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed40x24 extends Ufixed { + public static final Ufixed40x24 DEFAULT = new Ufixed40x24(BigInteger.ZERO); + + public Ufixed40x24(BigInteger value) { + super(40, 24, value); + } + + public Ufixed40x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x32.java new file mode 100644 index 0000000000..3999a16b7e --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed40x32 extends Ufixed { + public static final Ufixed40x32 DEFAULT = new Ufixed40x32(BigInteger.ZERO); + + public Ufixed40x32(BigInteger value) { + super(40, 32, value); + } + + public Ufixed40x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x40.java new file mode 100644 index 0000000000..5a944d7b66 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed40x40 extends Ufixed { + public static final Ufixed40x40 DEFAULT = new Ufixed40x40(BigInteger.ZERO); + + public Ufixed40x40(BigInteger value) { + super(40, 40, value); + } + + public Ufixed40x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x48.java new file mode 100644 index 0000000000..cbeb3ec5e8 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed40x48 extends Ufixed { + public static final Ufixed40x48 DEFAULT = new Ufixed40x48(BigInteger.ZERO); + + public Ufixed40x48(BigInteger value) { + super(40, 48, value); + } + + public Ufixed40x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x56.java new file mode 100644 index 0000000000..5306d06044 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x56.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed40x56 extends Ufixed { + public static final Ufixed40x56 DEFAULT = new Ufixed40x56(BigInteger.ZERO); + + public Ufixed40x56(BigInteger value) { + super(40, 56, value); + } + + public Ufixed40x56(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 56, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x64.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x64.java new file mode 100644 index 0000000000..441c350d4d --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x64.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed40x64 extends Ufixed { + public static final Ufixed40x64 DEFAULT = new Ufixed40x64(BigInteger.ZERO); + + public Ufixed40x64(BigInteger value) { + super(40, 64, value); + } + + public Ufixed40x64(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 64, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x72.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x72.java new file mode 100644 index 0000000000..7c7944ea33 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x72.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed40x72 extends Ufixed { + public static final Ufixed40x72 DEFAULT = new Ufixed40x72(BigInteger.ZERO); + + public Ufixed40x72(BigInteger value) { + super(40, 72, value); + } + + public Ufixed40x72(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 72, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x8.java new file mode 100644 index 0000000000..b0a331506e --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed40x8 extends Ufixed { + public static final Ufixed40x8 DEFAULT = new Ufixed40x8(BigInteger.ZERO); + + public Ufixed40x8(BigInteger value) { + super(40, 8, value); + } + + public Ufixed40x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x80.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x80.java new file mode 100644 index 0000000000..5beb5ffcba --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x80.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed40x80 extends Ufixed { + public static final Ufixed40x80 DEFAULT = new Ufixed40x80(BigInteger.ZERO); + + public Ufixed40x80(BigInteger value) { + super(40, 80, value); + } + + public Ufixed40x80(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 80, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x88.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x88.java new file mode 100644 index 0000000000..afa5cf4eed --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x88.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed40x88 extends Ufixed { + public static final Ufixed40x88 DEFAULT = new Ufixed40x88(BigInteger.ZERO); + + public Ufixed40x88(BigInteger value) { + super(40, 88, value); + } + + public Ufixed40x88(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 88, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x96.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x96.java new file mode 100644 index 0000000000..3c3d681f62 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed40x96.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed40x96 extends Ufixed { + public static final Ufixed40x96 DEFAULT = new Ufixed40x96(BigInteger.ZERO); + + public Ufixed40x96(BigInteger value) { + super(40, 96, value); + } + + public Ufixed40x96(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(40, 96, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x104.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x104.java new file mode 100644 index 0000000000..44b8552fd1 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x104.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed48x104 extends Ufixed { + public static final Ufixed48x104 DEFAULT = new Ufixed48x104(BigInteger.ZERO); + + public Ufixed48x104(BigInteger value) { + super(48, 104, value); + } + + public Ufixed48x104(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 104, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x112.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x112.java new file mode 100644 index 0000000000..f47dbab555 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x112.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed48x112 extends Ufixed { + public static final Ufixed48x112 DEFAULT = new Ufixed48x112(BigInteger.ZERO); + + public Ufixed48x112(BigInteger value) { + super(48, 112, value); + } + + public Ufixed48x112(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 112, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x120.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x120.java new file mode 100644 index 0000000000..2ea5eb98b1 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x120.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed48x120 extends Ufixed { + public static final Ufixed48x120 DEFAULT = new Ufixed48x120(BigInteger.ZERO); + + public Ufixed48x120(BigInteger value) { + super(48, 120, value); + } + + public Ufixed48x120(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 120, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x128.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x128.java new file mode 100644 index 0000000000..926f6220f5 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x128.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed48x128 extends Ufixed { + public static final Ufixed48x128 DEFAULT = new Ufixed48x128(BigInteger.ZERO); + + public Ufixed48x128(BigInteger value) { + super(48, 128, value); + } + + public Ufixed48x128(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 128, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x136.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x136.java new file mode 100644 index 0000000000..0d371ffdc2 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x136.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed48x136 extends Ufixed { + public static final Ufixed48x136 DEFAULT = new Ufixed48x136(BigInteger.ZERO); + + public Ufixed48x136(BigInteger value) { + super(48, 136, value); + } + + public Ufixed48x136(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 136, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x144.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x144.java new file mode 100644 index 0000000000..6f0f13601b --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x144.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed48x144 extends Ufixed { + public static final Ufixed48x144 DEFAULT = new Ufixed48x144(BigInteger.ZERO); + + public Ufixed48x144(BigInteger value) { + super(48, 144, value); + } + + public Ufixed48x144(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 144, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x152.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x152.java new file mode 100644 index 0000000000..eaaa69aaff --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x152.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed48x152 extends Ufixed { + public static final Ufixed48x152 DEFAULT = new Ufixed48x152(BigInteger.ZERO); + + public Ufixed48x152(BigInteger value) { + super(48, 152, value); + } + + public Ufixed48x152(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 152, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x16.java new file mode 100644 index 0000000000..f2c595bfa0 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed48x16 extends Ufixed { + public static final Ufixed48x16 DEFAULT = new Ufixed48x16(BigInteger.ZERO); + + public Ufixed48x16(BigInteger value) { + super(48, 16, value); + } + + public Ufixed48x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x160.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x160.java new file mode 100644 index 0000000000..467e81940c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x160.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed48x160 extends Ufixed { + public static final Ufixed48x160 DEFAULT = new Ufixed48x160(BigInteger.ZERO); + + public Ufixed48x160(BigInteger value) { + super(48, 160, value); + } + + public Ufixed48x160(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 160, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x168.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x168.java new file mode 100644 index 0000000000..b57cce7493 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x168.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed48x168 extends Ufixed { + public static final Ufixed48x168 DEFAULT = new Ufixed48x168(BigInteger.ZERO); + + public Ufixed48x168(BigInteger value) { + super(48, 168, value); + } + + public Ufixed48x168(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 168, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x176.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x176.java new file mode 100644 index 0000000000..ba86382f3f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x176.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed48x176 extends Ufixed { + public static final Ufixed48x176 DEFAULT = new Ufixed48x176(BigInteger.ZERO); + + public Ufixed48x176(BigInteger value) { + super(48, 176, value); + } + + public Ufixed48x176(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 176, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x184.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x184.java new file mode 100644 index 0000000000..5b4b398b9c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x184.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed48x184 extends Ufixed { + public static final Ufixed48x184 DEFAULT = new Ufixed48x184(BigInteger.ZERO); + + public Ufixed48x184(BigInteger value) { + super(48, 184, value); + } + + public Ufixed48x184(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 184, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x192.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x192.java new file mode 100644 index 0000000000..be2034cc15 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x192.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed48x192 extends Ufixed { + public static final Ufixed48x192 DEFAULT = new Ufixed48x192(BigInteger.ZERO); + + public Ufixed48x192(BigInteger value) { + super(48, 192, value); + } + + public Ufixed48x192(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 192, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x200.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x200.java new file mode 100644 index 0000000000..c8f9b0ff53 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x200.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed48x200 extends Ufixed { + public static final Ufixed48x200 DEFAULT = new Ufixed48x200(BigInteger.ZERO); + + public Ufixed48x200(BigInteger value) { + super(48, 200, value); + } + + public Ufixed48x200(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 200, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x208.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x208.java new file mode 100644 index 0000000000..9271df03f4 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x208.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed48x208 extends Ufixed { + public static final Ufixed48x208 DEFAULT = new Ufixed48x208(BigInteger.ZERO); + + public Ufixed48x208(BigInteger value) { + super(48, 208, value); + } + + public Ufixed48x208(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 208, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x24.java new file mode 100644 index 0000000000..2e5a70037f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed48x24 extends Ufixed { + public static final Ufixed48x24 DEFAULT = new Ufixed48x24(BigInteger.ZERO); + + public Ufixed48x24(BigInteger value) { + super(48, 24, value); + } + + public Ufixed48x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x32.java new file mode 100644 index 0000000000..ad88fe0bdb --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed48x32 extends Ufixed { + public static final Ufixed48x32 DEFAULT = new Ufixed48x32(BigInteger.ZERO); + + public Ufixed48x32(BigInteger value) { + super(48, 32, value); + } + + public Ufixed48x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x40.java new file mode 100644 index 0000000000..0585ca8d4c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed48x40 extends Ufixed { + public static final Ufixed48x40 DEFAULT = new Ufixed48x40(BigInteger.ZERO); + + public Ufixed48x40(BigInteger value) { + super(48, 40, value); + } + + public Ufixed48x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x48.java new file mode 100644 index 0000000000..66b6fc5ed6 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed48x48 extends Ufixed { + public static final Ufixed48x48 DEFAULT = new Ufixed48x48(BigInteger.ZERO); + + public Ufixed48x48(BigInteger value) { + super(48, 48, value); + } + + public Ufixed48x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x56.java new file mode 100644 index 0000000000..3ccc112a03 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x56.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed48x56 extends Ufixed { + public static final Ufixed48x56 DEFAULT = new Ufixed48x56(BigInteger.ZERO); + + public Ufixed48x56(BigInteger value) { + super(48, 56, value); + } + + public Ufixed48x56(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 56, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x64.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x64.java new file mode 100644 index 0000000000..bfd9cebb8d --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x64.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed48x64 extends Ufixed { + public static final Ufixed48x64 DEFAULT = new Ufixed48x64(BigInteger.ZERO); + + public Ufixed48x64(BigInteger value) { + super(48, 64, value); + } + + public Ufixed48x64(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 64, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x72.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x72.java new file mode 100644 index 0000000000..f2f5009d1a --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x72.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed48x72 extends Ufixed { + public static final Ufixed48x72 DEFAULT = new Ufixed48x72(BigInteger.ZERO); + + public Ufixed48x72(BigInteger value) { + super(48, 72, value); + } + + public Ufixed48x72(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 72, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x8.java new file mode 100644 index 0000000000..db5a411433 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed48x8 extends Ufixed { + public static final Ufixed48x8 DEFAULT = new Ufixed48x8(BigInteger.ZERO); + + public Ufixed48x8(BigInteger value) { + super(48, 8, value); + } + + public Ufixed48x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x80.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x80.java new file mode 100644 index 0000000000..c9a5922f17 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x80.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed48x80 extends Ufixed { + public static final Ufixed48x80 DEFAULT = new Ufixed48x80(BigInteger.ZERO); + + public Ufixed48x80(BigInteger value) { + super(48, 80, value); + } + + public Ufixed48x80(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 80, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x88.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x88.java new file mode 100644 index 0000000000..1a6122fa0c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x88.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed48x88 extends Ufixed { + public static final Ufixed48x88 DEFAULT = new Ufixed48x88(BigInteger.ZERO); + + public Ufixed48x88(BigInteger value) { + super(48, 88, value); + } + + public Ufixed48x88(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 88, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x96.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x96.java new file mode 100644 index 0000000000..9bf2e476c3 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed48x96.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed48x96 extends Ufixed { + public static final Ufixed48x96 DEFAULT = new Ufixed48x96(BigInteger.ZERO); + + public Ufixed48x96(BigInteger value) { + super(48, 96, value); + } + + public Ufixed48x96(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(48, 96, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x104.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x104.java new file mode 100644 index 0000000000..99a237dc52 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x104.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed56x104 extends Ufixed { + public static final Ufixed56x104 DEFAULT = new Ufixed56x104(BigInteger.ZERO); + + public Ufixed56x104(BigInteger value) { + super(56, 104, value); + } + + public Ufixed56x104(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(56, 104, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x112.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x112.java new file mode 100644 index 0000000000..d8560ea982 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x112.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed56x112 extends Ufixed { + public static final Ufixed56x112 DEFAULT = new Ufixed56x112(BigInteger.ZERO); + + public Ufixed56x112(BigInteger value) { + super(56, 112, value); + } + + public Ufixed56x112(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(56, 112, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x120.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x120.java new file mode 100644 index 0000000000..44de8c6916 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x120.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed56x120 extends Ufixed { + public static final Ufixed56x120 DEFAULT = new Ufixed56x120(BigInteger.ZERO); + + public Ufixed56x120(BigInteger value) { + super(56, 120, value); + } + + public Ufixed56x120(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(56, 120, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x128.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x128.java new file mode 100644 index 0000000000..db6a9bf492 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x128.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed56x128 extends Ufixed { + public static final Ufixed56x128 DEFAULT = new Ufixed56x128(BigInteger.ZERO); + + public Ufixed56x128(BigInteger value) { + super(56, 128, value); + } + + public Ufixed56x128(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(56, 128, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x136.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x136.java new file mode 100644 index 0000000000..ed829dce46 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x136.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed56x136 extends Ufixed { + public static final Ufixed56x136 DEFAULT = new Ufixed56x136(BigInteger.ZERO); + + public Ufixed56x136(BigInteger value) { + super(56, 136, value); + } + + public Ufixed56x136(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(56, 136, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x144.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x144.java new file mode 100644 index 0000000000..a64da40c70 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x144.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed56x144 extends Ufixed { + public static final Ufixed56x144 DEFAULT = new Ufixed56x144(BigInteger.ZERO); + + public Ufixed56x144(BigInteger value) { + super(56, 144, value); + } + + public Ufixed56x144(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(56, 144, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x152.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x152.java new file mode 100644 index 0000000000..7d6eb537f2 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x152.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed56x152 extends Ufixed { + public static final Ufixed56x152 DEFAULT = new Ufixed56x152(BigInteger.ZERO); + + public Ufixed56x152(BigInteger value) { + super(56, 152, value); + } + + public Ufixed56x152(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(56, 152, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x16.java new file mode 100644 index 0000000000..527984d91c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed56x16 extends Ufixed { + public static final Ufixed56x16 DEFAULT = new Ufixed56x16(BigInteger.ZERO); + + public Ufixed56x16(BigInteger value) { + super(56, 16, value); + } + + public Ufixed56x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(56, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x160.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x160.java new file mode 100644 index 0000000000..333d42d841 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x160.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed56x160 extends Ufixed { + public static final Ufixed56x160 DEFAULT = new Ufixed56x160(BigInteger.ZERO); + + public Ufixed56x160(BigInteger value) { + super(56, 160, value); + } + + public Ufixed56x160(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(56, 160, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x168.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x168.java new file mode 100644 index 0000000000..2f70d1f560 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x168.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed56x168 extends Ufixed { + public static final Ufixed56x168 DEFAULT = new Ufixed56x168(BigInteger.ZERO); + + public Ufixed56x168(BigInteger value) { + super(56, 168, value); + } + + public Ufixed56x168(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(56, 168, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x176.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x176.java new file mode 100644 index 0000000000..3b6928cd1a --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x176.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed56x176 extends Ufixed { + public static final Ufixed56x176 DEFAULT = new Ufixed56x176(BigInteger.ZERO); + + public Ufixed56x176(BigInteger value) { + super(56, 176, value); + } + + public Ufixed56x176(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(56, 176, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x184.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x184.java new file mode 100644 index 0000000000..23e5100680 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x184.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed56x184 extends Ufixed { + public static final Ufixed56x184 DEFAULT = new Ufixed56x184(BigInteger.ZERO); + + public Ufixed56x184(BigInteger value) { + super(56, 184, value); + } + + public Ufixed56x184(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(56, 184, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x192.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x192.java new file mode 100644 index 0000000000..a2bedb72c1 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x192.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed56x192 extends Ufixed { + public static final Ufixed56x192 DEFAULT = new Ufixed56x192(BigInteger.ZERO); + + public Ufixed56x192(BigInteger value) { + super(56, 192, value); + } + + public Ufixed56x192(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(56, 192, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x200.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x200.java new file mode 100644 index 0000000000..7aee599e81 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x200.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed56x200 extends Ufixed { + public static final Ufixed56x200 DEFAULT = new Ufixed56x200(BigInteger.ZERO); + + public Ufixed56x200(BigInteger value) { + super(56, 200, value); + } + + public Ufixed56x200(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(56, 200, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x24.java new file mode 100644 index 0000000000..62c1e93dfe --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed56x24 extends Ufixed { + public static final Ufixed56x24 DEFAULT = new Ufixed56x24(BigInteger.ZERO); + + public Ufixed56x24(BigInteger value) { + super(56, 24, value); + } + + public Ufixed56x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(56, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x32.java new file mode 100644 index 0000000000..76139d79ab --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed56x32 extends Ufixed { + public static final Ufixed56x32 DEFAULT = new Ufixed56x32(BigInteger.ZERO); + + public Ufixed56x32(BigInteger value) { + super(56, 32, value); + } + + public Ufixed56x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(56, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x40.java new file mode 100644 index 0000000000..2f2c14e6a7 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed56x40 extends Ufixed { + public static final Ufixed56x40 DEFAULT = new Ufixed56x40(BigInteger.ZERO); + + public Ufixed56x40(BigInteger value) { + super(56, 40, value); + } + + public Ufixed56x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(56, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x48.java new file mode 100644 index 0000000000..329581ef39 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed56x48 extends Ufixed { + public static final Ufixed56x48 DEFAULT = new Ufixed56x48(BigInteger.ZERO); + + public Ufixed56x48(BigInteger value) { + super(56, 48, value); + } + + public Ufixed56x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(56, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x56.java new file mode 100644 index 0000000000..cb8eebb05c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x56.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed56x56 extends Ufixed { + public static final Ufixed56x56 DEFAULT = new Ufixed56x56(BigInteger.ZERO); + + public Ufixed56x56(BigInteger value) { + super(56, 56, value); + } + + public Ufixed56x56(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(56, 56, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x64.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x64.java new file mode 100644 index 0000000000..fec301a681 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x64.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed56x64 extends Ufixed { + public static final Ufixed56x64 DEFAULT = new Ufixed56x64(BigInteger.ZERO); + + public Ufixed56x64(BigInteger value) { + super(56, 64, value); + } + + public Ufixed56x64(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(56, 64, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x72.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x72.java new file mode 100644 index 0000000000..d0d29fd11d --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x72.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed56x72 extends Ufixed { + public static final Ufixed56x72 DEFAULT = new Ufixed56x72(BigInteger.ZERO); + + public Ufixed56x72(BigInteger value) { + super(56, 72, value); + } + + public Ufixed56x72(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(56, 72, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x8.java new file mode 100644 index 0000000000..441d98d7ee --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed56x8 extends Ufixed { + public static final Ufixed56x8 DEFAULT = new Ufixed56x8(BigInteger.ZERO); + + public Ufixed56x8(BigInteger value) { + super(56, 8, value); + } + + public Ufixed56x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(56, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x80.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x80.java new file mode 100644 index 0000000000..972bf2814d --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x80.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed56x80 extends Ufixed { + public static final Ufixed56x80 DEFAULT = new Ufixed56x80(BigInteger.ZERO); + + public Ufixed56x80(BigInteger value) { + super(56, 80, value); + } + + public Ufixed56x80(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(56, 80, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x88.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x88.java new file mode 100644 index 0000000000..6554ff8fe7 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x88.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed56x88 extends Ufixed { + public static final Ufixed56x88 DEFAULT = new Ufixed56x88(BigInteger.ZERO); + + public Ufixed56x88(BigInteger value) { + super(56, 88, value); + } + + public Ufixed56x88(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(56, 88, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x96.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x96.java new file mode 100644 index 0000000000..e8c8a57fdc --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed56x96.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed56x96 extends Ufixed { + public static final Ufixed56x96 DEFAULT = new Ufixed56x96(BigInteger.ZERO); + + public Ufixed56x96(BigInteger value) { + super(56, 96, value); + } + + public Ufixed56x96(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(56, 96, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x104.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x104.java new file mode 100644 index 0000000000..4d4b6d3134 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x104.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed64x104 extends Ufixed { + public static final Ufixed64x104 DEFAULT = new Ufixed64x104(BigInteger.ZERO); + + public Ufixed64x104(BigInteger value) { + super(64, 104, value); + } + + public Ufixed64x104(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(64, 104, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x112.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x112.java new file mode 100644 index 0000000000..29b472b5be --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x112.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed64x112 extends Ufixed { + public static final Ufixed64x112 DEFAULT = new Ufixed64x112(BigInteger.ZERO); + + public Ufixed64x112(BigInteger value) { + super(64, 112, value); + } + + public Ufixed64x112(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(64, 112, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x120.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x120.java new file mode 100644 index 0000000000..ba86dddefe --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x120.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed64x120 extends Ufixed { + public static final Ufixed64x120 DEFAULT = new Ufixed64x120(BigInteger.ZERO); + + public Ufixed64x120(BigInteger value) { + super(64, 120, value); + } + + public Ufixed64x120(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(64, 120, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x128.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x128.java new file mode 100644 index 0000000000..a56220be3e --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x128.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed64x128 extends Ufixed { + public static final Ufixed64x128 DEFAULT = new Ufixed64x128(BigInteger.ZERO); + + public Ufixed64x128(BigInteger value) { + super(64, 128, value); + } + + public Ufixed64x128(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(64, 128, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x136.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x136.java new file mode 100644 index 0000000000..9f4f3f5d12 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x136.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed64x136 extends Ufixed { + public static final Ufixed64x136 DEFAULT = new Ufixed64x136(BigInteger.ZERO); + + public Ufixed64x136(BigInteger value) { + super(64, 136, value); + } + + public Ufixed64x136(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(64, 136, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x144.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x144.java new file mode 100644 index 0000000000..fe05a09790 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x144.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed64x144 extends Ufixed { + public static final Ufixed64x144 DEFAULT = new Ufixed64x144(BigInteger.ZERO); + + public Ufixed64x144(BigInteger value) { + super(64, 144, value); + } + + public Ufixed64x144(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(64, 144, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x152.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x152.java new file mode 100644 index 0000000000..2ff418b208 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x152.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed64x152 extends Ufixed { + public static final Ufixed64x152 DEFAULT = new Ufixed64x152(BigInteger.ZERO); + + public Ufixed64x152(BigInteger value) { + super(64, 152, value); + } + + public Ufixed64x152(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(64, 152, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x16.java new file mode 100644 index 0000000000..2b013f7277 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed64x16 extends Ufixed { + public static final Ufixed64x16 DEFAULT = new Ufixed64x16(BigInteger.ZERO); + + public Ufixed64x16(BigInteger value) { + super(64, 16, value); + } + + public Ufixed64x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(64, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x160.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x160.java new file mode 100644 index 0000000000..8b6e31d5f7 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x160.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed64x160 extends Ufixed { + public static final Ufixed64x160 DEFAULT = new Ufixed64x160(BigInteger.ZERO); + + public Ufixed64x160(BigInteger value) { + super(64, 160, value); + } + + public Ufixed64x160(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(64, 160, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x168.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x168.java new file mode 100644 index 0000000000..8d9e5daee4 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x168.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed64x168 extends Ufixed { + public static final Ufixed64x168 DEFAULT = new Ufixed64x168(BigInteger.ZERO); + + public Ufixed64x168(BigInteger value) { + super(64, 168, value); + } + + public Ufixed64x168(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(64, 168, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x176.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x176.java new file mode 100644 index 0000000000..7f1622ac03 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x176.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed64x176 extends Ufixed { + public static final Ufixed64x176 DEFAULT = new Ufixed64x176(BigInteger.ZERO); + + public Ufixed64x176(BigInteger value) { + super(64, 176, value); + } + + public Ufixed64x176(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(64, 176, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x184.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x184.java new file mode 100644 index 0000000000..03de32a0da --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x184.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed64x184 extends Ufixed { + public static final Ufixed64x184 DEFAULT = new Ufixed64x184(BigInteger.ZERO); + + public Ufixed64x184(BigInteger value) { + super(64, 184, value); + } + + public Ufixed64x184(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(64, 184, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x192.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x192.java new file mode 100644 index 0000000000..184308d661 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x192.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed64x192 extends Ufixed { + public static final Ufixed64x192 DEFAULT = new Ufixed64x192(BigInteger.ZERO); + + public Ufixed64x192(BigInteger value) { + super(64, 192, value); + } + + public Ufixed64x192(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(64, 192, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x24.java new file mode 100644 index 0000000000..fb1ba75bda --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed64x24 extends Ufixed { + public static final Ufixed64x24 DEFAULT = new Ufixed64x24(BigInteger.ZERO); + + public Ufixed64x24(BigInteger value) { + super(64, 24, value); + } + + public Ufixed64x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(64, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x32.java new file mode 100644 index 0000000000..6ecc2cc643 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed64x32 extends Ufixed { + public static final Ufixed64x32 DEFAULT = new Ufixed64x32(BigInteger.ZERO); + + public Ufixed64x32(BigInteger value) { + super(64, 32, value); + } + + public Ufixed64x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(64, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x40.java new file mode 100644 index 0000000000..be180e914f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed64x40 extends Ufixed { + public static final Ufixed64x40 DEFAULT = new Ufixed64x40(BigInteger.ZERO); + + public Ufixed64x40(BigInteger value) { + super(64, 40, value); + } + + public Ufixed64x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(64, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x48.java new file mode 100644 index 0000000000..253accf08c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed64x48 extends Ufixed { + public static final Ufixed64x48 DEFAULT = new Ufixed64x48(BigInteger.ZERO); + + public Ufixed64x48(BigInteger value) { + super(64, 48, value); + } + + public Ufixed64x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(64, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x56.java new file mode 100644 index 0000000000..c9df326f2a --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x56.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed64x56 extends Ufixed { + public static final Ufixed64x56 DEFAULT = new Ufixed64x56(BigInteger.ZERO); + + public Ufixed64x56(BigInteger value) { + super(64, 56, value); + } + + public Ufixed64x56(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(64, 56, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x64.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x64.java new file mode 100644 index 0000000000..4ffd00f659 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x64.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed64x64 extends Ufixed { + public static final Ufixed64x64 DEFAULT = new Ufixed64x64(BigInteger.ZERO); + + public Ufixed64x64(BigInteger value) { + super(64, 64, value); + } + + public Ufixed64x64(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(64, 64, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x72.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x72.java new file mode 100644 index 0000000000..a749084831 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x72.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed64x72 extends Ufixed { + public static final Ufixed64x72 DEFAULT = new Ufixed64x72(BigInteger.ZERO); + + public Ufixed64x72(BigInteger value) { + super(64, 72, value); + } + + public Ufixed64x72(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(64, 72, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x8.java new file mode 100644 index 0000000000..1324935a5a --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed64x8 extends Ufixed { + public static final Ufixed64x8 DEFAULT = new Ufixed64x8(BigInteger.ZERO); + + public Ufixed64x8(BigInteger value) { + super(64, 8, value); + } + + public Ufixed64x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(64, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x80.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x80.java new file mode 100644 index 0000000000..60873d9e83 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x80.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed64x80 extends Ufixed { + public static final Ufixed64x80 DEFAULT = new Ufixed64x80(BigInteger.ZERO); + + public Ufixed64x80(BigInteger value) { + super(64, 80, value); + } + + public Ufixed64x80(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(64, 80, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x88.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x88.java new file mode 100644 index 0000000000..e53a88ebda --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x88.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed64x88 extends Ufixed { + public static final Ufixed64x88 DEFAULT = new Ufixed64x88(BigInteger.ZERO); + + public Ufixed64x88(BigInteger value) { + super(64, 88, value); + } + + public Ufixed64x88(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(64, 88, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x96.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x96.java new file mode 100644 index 0000000000..f08f3a058e --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed64x96.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed64x96 extends Ufixed { + public static final Ufixed64x96 DEFAULT = new Ufixed64x96(BigInteger.ZERO); + + public Ufixed64x96(BigInteger value) { + super(64, 96, value); + } + + public Ufixed64x96(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(64, 96, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x104.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x104.java new file mode 100644 index 0000000000..f6f40038f7 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x104.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed72x104 extends Ufixed { + public static final Ufixed72x104 DEFAULT = new Ufixed72x104(BigInteger.ZERO); + + public Ufixed72x104(BigInteger value) { + super(72, 104, value); + } + + public Ufixed72x104(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(72, 104, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x112.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x112.java new file mode 100644 index 0000000000..e293921538 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x112.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed72x112 extends Ufixed { + public static final Ufixed72x112 DEFAULT = new Ufixed72x112(BigInteger.ZERO); + + public Ufixed72x112(BigInteger value) { + super(72, 112, value); + } + + public Ufixed72x112(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(72, 112, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x120.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x120.java new file mode 100644 index 0000000000..80a19658c5 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x120.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed72x120 extends Ufixed { + public static final Ufixed72x120 DEFAULT = new Ufixed72x120(BigInteger.ZERO); + + public Ufixed72x120(BigInteger value) { + super(72, 120, value); + } + + public Ufixed72x120(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(72, 120, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x128.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x128.java new file mode 100644 index 0000000000..0dee6464f4 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x128.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed72x128 extends Ufixed { + public static final Ufixed72x128 DEFAULT = new Ufixed72x128(BigInteger.ZERO); + + public Ufixed72x128(BigInteger value) { + super(72, 128, value); + } + + public Ufixed72x128(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(72, 128, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x136.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x136.java new file mode 100644 index 0000000000..b872f2d488 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x136.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed72x136 extends Ufixed { + public static final Ufixed72x136 DEFAULT = new Ufixed72x136(BigInteger.ZERO); + + public Ufixed72x136(BigInteger value) { + super(72, 136, value); + } + + public Ufixed72x136(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(72, 136, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x144.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x144.java new file mode 100644 index 0000000000..899d9c9558 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x144.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed72x144 extends Ufixed { + public static final Ufixed72x144 DEFAULT = new Ufixed72x144(BigInteger.ZERO); + + public Ufixed72x144(BigInteger value) { + super(72, 144, value); + } + + public Ufixed72x144(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(72, 144, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x152.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x152.java new file mode 100644 index 0000000000..ad8bb2a97e --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x152.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed72x152 extends Ufixed { + public static final Ufixed72x152 DEFAULT = new Ufixed72x152(BigInteger.ZERO); + + public Ufixed72x152(BigInteger value) { + super(72, 152, value); + } + + public Ufixed72x152(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(72, 152, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x16.java new file mode 100644 index 0000000000..7cb57beec0 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed72x16 extends Ufixed { + public static final Ufixed72x16 DEFAULT = new Ufixed72x16(BigInteger.ZERO); + + public Ufixed72x16(BigInteger value) { + super(72, 16, value); + } + + public Ufixed72x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(72, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x160.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x160.java new file mode 100644 index 0000000000..e30bd7ba85 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x160.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed72x160 extends Ufixed { + public static final Ufixed72x160 DEFAULT = new Ufixed72x160(BigInteger.ZERO); + + public Ufixed72x160(BigInteger value) { + super(72, 160, value); + } + + public Ufixed72x160(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(72, 160, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x168.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x168.java new file mode 100644 index 0000000000..f95eb5c321 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x168.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed72x168 extends Ufixed { + public static final Ufixed72x168 DEFAULT = new Ufixed72x168(BigInteger.ZERO); + + public Ufixed72x168(BigInteger value) { + super(72, 168, value); + } + + public Ufixed72x168(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(72, 168, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x176.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x176.java new file mode 100644 index 0000000000..da437f7dc8 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x176.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed72x176 extends Ufixed { + public static final Ufixed72x176 DEFAULT = new Ufixed72x176(BigInteger.ZERO); + + public Ufixed72x176(BigInteger value) { + super(72, 176, value); + } + + public Ufixed72x176(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(72, 176, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x184.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x184.java new file mode 100644 index 0000000000..006f9c882b --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x184.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed72x184 extends Ufixed { + public static final Ufixed72x184 DEFAULT = new Ufixed72x184(BigInteger.ZERO); + + public Ufixed72x184(BigInteger value) { + super(72, 184, value); + } + + public Ufixed72x184(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(72, 184, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x24.java new file mode 100644 index 0000000000..6c928a2da7 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed72x24 extends Ufixed { + public static final Ufixed72x24 DEFAULT = new Ufixed72x24(BigInteger.ZERO); + + public Ufixed72x24(BigInteger value) { + super(72, 24, value); + } + + public Ufixed72x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(72, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x32.java new file mode 100644 index 0000000000..b6424df93c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed72x32 extends Ufixed { + public static final Ufixed72x32 DEFAULT = new Ufixed72x32(BigInteger.ZERO); + + public Ufixed72x32(BigInteger value) { + super(72, 32, value); + } + + public Ufixed72x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(72, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x40.java new file mode 100644 index 0000000000..53b9bab120 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed72x40 extends Ufixed { + public static final Ufixed72x40 DEFAULT = new Ufixed72x40(BigInteger.ZERO); + + public Ufixed72x40(BigInteger value) { + super(72, 40, value); + } + + public Ufixed72x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(72, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x48.java new file mode 100644 index 0000000000..356854819e --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed72x48 extends Ufixed { + public static final Ufixed72x48 DEFAULT = new Ufixed72x48(BigInteger.ZERO); + + public Ufixed72x48(BigInteger value) { + super(72, 48, value); + } + + public Ufixed72x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(72, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x56.java new file mode 100644 index 0000000000..e252dbdb2c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x56.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed72x56 extends Ufixed { + public static final Ufixed72x56 DEFAULT = new Ufixed72x56(BigInteger.ZERO); + + public Ufixed72x56(BigInteger value) { + super(72, 56, value); + } + + public Ufixed72x56(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(72, 56, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x64.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x64.java new file mode 100644 index 0000000000..3a716d235c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x64.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed72x64 extends Ufixed { + public static final Ufixed72x64 DEFAULT = new Ufixed72x64(BigInteger.ZERO); + + public Ufixed72x64(BigInteger value) { + super(72, 64, value); + } + + public Ufixed72x64(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(72, 64, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x72.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x72.java new file mode 100644 index 0000000000..7f81f037cf --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x72.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed72x72 extends Ufixed { + public static final Ufixed72x72 DEFAULT = new Ufixed72x72(BigInteger.ZERO); + + public Ufixed72x72(BigInteger value) { + super(72, 72, value); + } + + public Ufixed72x72(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(72, 72, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x8.java new file mode 100644 index 0000000000..d30a7eb3ce --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed72x8 extends Ufixed { + public static final Ufixed72x8 DEFAULT = new Ufixed72x8(BigInteger.ZERO); + + public Ufixed72x8(BigInteger value) { + super(72, 8, value); + } + + public Ufixed72x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(72, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x80.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x80.java new file mode 100644 index 0000000000..d6e86d1bec --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x80.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed72x80 extends Ufixed { + public static final Ufixed72x80 DEFAULT = new Ufixed72x80(BigInteger.ZERO); + + public Ufixed72x80(BigInteger value) { + super(72, 80, value); + } + + public Ufixed72x80(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(72, 80, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x88.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x88.java new file mode 100644 index 0000000000..56c3b1d41f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x88.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed72x88 extends Ufixed { + public static final Ufixed72x88 DEFAULT = new Ufixed72x88(BigInteger.ZERO); + + public Ufixed72x88(BigInteger value) { + super(72, 88, value); + } + + public Ufixed72x88(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(72, 88, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x96.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x96.java new file mode 100644 index 0000000000..eb31327f10 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed72x96.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed72x96 extends Ufixed { + public static final Ufixed72x96 DEFAULT = new Ufixed72x96(BigInteger.ZERO); + + public Ufixed72x96(BigInteger value) { + super(72, 96, value); + } + + public Ufixed72x96(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(72, 96, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x104.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x104.java new file mode 100644 index 0000000000..66ed7210fb --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x104.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed80x104 extends Ufixed { + public static final Ufixed80x104 DEFAULT = new Ufixed80x104(BigInteger.ZERO); + + public Ufixed80x104(BigInteger value) { + super(80, 104, value); + } + + public Ufixed80x104(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(80, 104, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x112.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x112.java new file mode 100644 index 0000000000..d854e26023 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x112.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed80x112 extends Ufixed { + public static final Ufixed80x112 DEFAULT = new Ufixed80x112(BigInteger.ZERO); + + public Ufixed80x112(BigInteger value) { + super(80, 112, value); + } + + public Ufixed80x112(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(80, 112, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x120.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x120.java new file mode 100644 index 0000000000..1ba7158aa9 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x120.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed80x120 extends Ufixed { + public static final Ufixed80x120 DEFAULT = new Ufixed80x120(BigInteger.ZERO); + + public Ufixed80x120(BigInteger value) { + super(80, 120, value); + } + + public Ufixed80x120(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(80, 120, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x128.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x128.java new file mode 100644 index 0000000000..a549118925 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x128.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed80x128 extends Ufixed { + public static final Ufixed80x128 DEFAULT = new Ufixed80x128(BigInteger.ZERO); + + public Ufixed80x128(BigInteger value) { + super(80, 128, value); + } + + public Ufixed80x128(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(80, 128, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x136.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x136.java new file mode 100644 index 0000000000..389a282d4b --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x136.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed80x136 extends Ufixed { + public static final Ufixed80x136 DEFAULT = new Ufixed80x136(BigInteger.ZERO); + + public Ufixed80x136(BigInteger value) { + super(80, 136, value); + } + + public Ufixed80x136(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(80, 136, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x144.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x144.java new file mode 100644 index 0000000000..65918025c1 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x144.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed80x144 extends Ufixed { + public static final Ufixed80x144 DEFAULT = new Ufixed80x144(BigInteger.ZERO); + + public Ufixed80x144(BigInteger value) { + super(80, 144, value); + } + + public Ufixed80x144(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(80, 144, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x152.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x152.java new file mode 100644 index 0000000000..70f840f638 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x152.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed80x152 extends Ufixed { + public static final Ufixed80x152 DEFAULT = new Ufixed80x152(BigInteger.ZERO); + + public Ufixed80x152(BigInteger value) { + super(80, 152, value); + } + + public Ufixed80x152(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(80, 152, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x16.java new file mode 100644 index 0000000000..77877b10e9 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed80x16 extends Ufixed { + public static final Ufixed80x16 DEFAULT = new Ufixed80x16(BigInteger.ZERO); + + public Ufixed80x16(BigInteger value) { + super(80, 16, value); + } + + public Ufixed80x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(80, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x160.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x160.java new file mode 100644 index 0000000000..6564d60459 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x160.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed80x160 extends Ufixed { + public static final Ufixed80x160 DEFAULT = new Ufixed80x160(BigInteger.ZERO); + + public Ufixed80x160(BigInteger value) { + super(80, 160, value); + } + + public Ufixed80x160(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(80, 160, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x168.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x168.java new file mode 100644 index 0000000000..e6cabab6a0 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x168.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed80x168 extends Ufixed { + public static final Ufixed80x168 DEFAULT = new Ufixed80x168(BigInteger.ZERO); + + public Ufixed80x168(BigInteger value) { + super(80, 168, value); + } + + public Ufixed80x168(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(80, 168, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x176.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x176.java new file mode 100644 index 0000000000..fa63066692 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x176.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed80x176 extends Ufixed { + public static final Ufixed80x176 DEFAULT = new Ufixed80x176(BigInteger.ZERO); + + public Ufixed80x176(BigInteger value) { + super(80, 176, value); + } + + public Ufixed80x176(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(80, 176, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x24.java new file mode 100644 index 0000000000..4bd1d0578a --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed80x24 extends Ufixed { + public static final Ufixed80x24 DEFAULT = new Ufixed80x24(BigInteger.ZERO); + + public Ufixed80x24(BigInteger value) { + super(80, 24, value); + } + + public Ufixed80x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(80, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x32.java new file mode 100644 index 0000000000..19ede4c04d --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed80x32 extends Ufixed { + public static final Ufixed80x32 DEFAULT = new Ufixed80x32(BigInteger.ZERO); + + public Ufixed80x32(BigInteger value) { + super(80, 32, value); + } + + public Ufixed80x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(80, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x40.java new file mode 100644 index 0000000000..315dd10c77 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed80x40 extends Ufixed { + public static final Ufixed80x40 DEFAULT = new Ufixed80x40(BigInteger.ZERO); + + public Ufixed80x40(BigInteger value) { + super(80, 40, value); + } + + public Ufixed80x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(80, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x48.java new file mode 100644 index 0000000000..5865aa222a --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed80x48 extends Ufixed { + public static final Ufixed80x48 DEFAULT = new Ufixed80x48(BigInteger.ZERO); + + public Ufixed80x48(BigInteger value) { + super(80, 48, value); + } + + public Ufixed80x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(80, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x56.java new file mode 100644 index 0000000000..dbe8cdd967 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x56.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed80x56 extends Ufixed { + public static final Ufixed80x56 DEFAULT = new Ufixed80x56(BigInteger.ZERO); + + public Ufixed80x56(BigInteger value) { + super(80, 56, value); + } + + public Ufixed80x56(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(80, 56, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x64.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x64.java new file mode 100644 index 0000000000..1c268d89e1 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x64.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed80x64 extends Ufixed { + public static final Ufixed80x64 DEFAULT = new Ufixed80x64(BigInteger.ZERO); + + public Ufixed80x64(BigInteger value) { + super(80, 64, value); + } + + public Ufixed80x64(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(80, 64, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x72.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x72.java new file mode 100644 index 0000000000..f334d4526d --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x72.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed80x72 extends Ufixed { + public static final Ufixed80x72 DEFAULT = new Ufixed80x72(BigInteger.ZERO); + + public Ufixed80x72(BigInteger value) { + super(80, 72, value); + } + + public Ufixed80x72(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(80, 72, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x8.java new file mode 100644 index 0000000000..1283948452 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed80x8 extends Ufixed { + public static final Ufixed80x8 DEFAULT = new Ufixed80x8(BigInteger.ZERO); + + public Ufixed80x8(BigInteger value) { + super(80, 8, value); + } + + public Ufixed80x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(80, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x80.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x80.java new file mode 100644 index 0000000000..5ef432b11b --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x80.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed80x80 extends Ufixed { + public static final Ufixed80x80 DEFAULT = new Ufixed80x80(BigInteger.ZERO); + + public Ufixed80x80(BigInteger value) { + super(80, 80, value); + } + + public Ufixed80x80(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(80, 80, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x88.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x88.java new file mode 100644 index 0000000000..61bcd47084 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x88.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed80x88 extends Ufixed { + public static final Ufixed80x88 DEFAULT = new Ufixed80x88(BigInteger.ZERO); + + public Ufixed80x88(BigInteger value) { + super(80, 88, value); + } + + public Ufixed80x88(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(80, 88, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x96.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x96.java new file mode 100644 index 0000000000..c1a64fe959 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed80x96.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed80x96 extends Ufixed { + public static final Ufixed80x96 DEFAULT = new Ufixed80x96(BigInteger.ZERO); + + public Ufixed80x96(BigInteger value) { + super(80, 96, value); + } + + public Ufixed80x96(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(80, 96, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x104.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x104.java new file mode 100644 index 0000000000..c7a05fa5eb --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x104.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed88x104 extends Ufixed { + public static final Ufixed88x104 DEFAULT = new Ufixed88x104(BigInteger.ZERO); + + public Ufixed88x104(BigInteger value) { + super(88, 104, value); + } + + public Ufixed88x104(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(88, 104, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x112.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x112.java new file mode 100644 index 0000000000..5fde6a5a45 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x112.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed88x112 extends Ufixed { + public static final Ufixed88x112 DEFAULT = new Ufixed88x112(BigInteger.ZERO); + + public Ufixed88x112(BigInteger value) { + super(88, 112, value); + } + + public Ufixed88x112(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(88, 112, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x120.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x120.java new file mode 100644 index 0000000000..fe463872db --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x120.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed88x120 extends Ufixed { + public static final Ufixed88x120 DEFAULT = new Ufixed88x120(BigInteger.ZERO); + + public Ufixed88x120(BigInteger value) { + super(88, 120, value); + } + + public Ufixed88x120(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(88, 120, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x128.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x128.java new file mode 100644 index 0000000000..1f78d4c7dd --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x128.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed88x128 extends Ufixed { + public static final Ufixed88x128 DEFAULT = new Ufixed88x128(BigInteger.ZERO); + + public Ufixed88x128(BigInteger value) { + super(88, 128, value); + } + + public Ufixed88x128(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(88, 128, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x136.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x136.java new file mode 100644 index 0000000000..03b7ead0df --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x136.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed88x136 extends Ufixed { + public static final Ufixed88x136 DEFAULT = new Ufixed88x136(BigInteger.ZERO); + + public Ufixed88x136(BigInteger value) { + super(88, 136, value); + } + + public Ufixed88x136(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(88, 136, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x144.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x144.java new file mode 100644 index 0000000000..8cd6d3e043 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x144.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed88x144 extends Ufixed { + public static final Ufixed88x144 DEFAULT = new Ufixed88x144(BigInteger.ZERO); + + public Ufixed88x144(BigInteger value) { + super(88, 144, value); + } + + public Ufixed88x144(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(88, 144, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x152.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x152.java new file mode 100644 index 0000000000..6637679281 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x152.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed88x152 extends Ufixed { + public static final Ufixed88x152 DEFAULT = new Ufixed88x152(BigInteger.ZERO); + + public Ufixed88x152(BigInteger value) { + super(88, 152, value); + } + + public Ufixed88x152(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(88, 152, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x16.java new file mode 100644 index 0000000000..3d92611b3c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed88x16 extends Ufixed { + public static final Ufixed88x16 DEFAULT = new Ufixed88x16(BigInteger.ZERO); + + public Ufixed88x16(BigInteger value) { + super(88, 16, value); + } + + public Ufixed88x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(88, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x160.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x160.java new file mode 100644 index 0000000000..986e2a7da1 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x160.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed88x160 extends Ufixed { + public static final Ufixed88x160 DEFAULT = new Ufixed88x160(BigInteger.ZERO); + + public Ufixed88x160(BigInteger value) { + super(88, 160, value); + } + + public Ufixed88x160(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(88, 160, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x168.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x168.java new file mode 100644 index 0000000000..da438ae3e2 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x168.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed88x168 extends Ufixed { + public static final Ufixed88x168 DEFAULT = new Ufixed88x168(BigInteger.ZERO); + + public Ufixed88x168(BigInteger value) { + super(88, 168, value); + } + + public Ufixed88x168(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(88, 168, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x24.java new file mode 100644 index 0000000000..d970c09322 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed88x24 extends Ufixed { + public static final Ufixed88x24 DEFAULT = new Ufixed88x24(BigInteger.ZERO); + + public Ufixed88x24(BigInteger value) { + super(88, 24, value); + } + + public Ufixed88x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(88, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x32.java new file mode 100644 index 0000000000..19cc58432e --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed88x32 extends Ufixed { + public static final Ufixed88x32 DEFAULT = new Ufixed88x32(BigInteger.ZERO); + + public Ufixed88x32(BigInteger value) { + super(88, 32, value); + } + + public Ufixed88x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(88, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x40.java new file mode 100644 index 0000000000..bb29bf6104 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed88x40 extends Ufixed { + public static final Ufixed88x40 DEFAULT = new Ufixed88x40(BigInteger.ZERO); + + public Ufixed88x40(BigInteger value) { + super(88, 40, value); + } + + public Ufixed88x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(88, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x48.java new file mode 100644 index 0000000000..4a8bdf7dec --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed88x48 extends Ufixed { + public static final Ufixed88x48 DEFAULT = new Ufixed88x48(BigInteger.ZERO); + + public Ufixed88x48(BigInteger value) { + super(88, 48, value); + } + + public Ufixed88x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(88, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x56.java new file mode 100644 index 0000000000..cfe46cc1d0 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x56.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed88x56 extends Ufixed { + public static final Ufixed88x56 DEFAULT = new Ufixed88x56(BigInteger.ZERO); + + public Ufixed88x56(BigInteger value) { + super(88, 56, value); + } + + public Ufixed88x56(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(88, 56, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x64.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x64.java new file mode 100644 index 0000000000..8a94d3fb49 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x64.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed88x64 extends Ufixed { + public static final Ufixed88x64 DEFAULT = new Ufixed88x64(BigInteger.ZERO); + + public Ufixed88x64(BigInteger value) { + super(88, 64, value); + } + + public Ufixed88x64(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(88, 64, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x72.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x72.java new file mode 100644 index 0000000000..536726c6fd --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x72.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed88x72 extends Ufixed { + public static final Ufixed88x72 DEFAULT = new Ufixed88x72(BigInteger.ZERO); + + public Ufixed88x72(BigInteger value) { + super(88, 72, value); + } + + public Ufixed88x72(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(88, 72, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x8.java new file mode 100644 index 0000000000..59e9bb4cc0 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed88x8 extends Ufixed { + public static final Ufixed88x8 DEFAULT = new Ufixed88x8(BigInteger.ZERO); + + public Ufixed88x8(BigInteger value) { + super(88, 8, value); + } + + public Ufixed88x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(88, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x80.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x80.java new file mode 100644 index 0000000000..85815e83a6 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x80.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed88x80 extends Ufixed { + public static final Ufixed88x80 DEFAULT = new Ufixed88x80(BigInteger.ZERO); + + public Ufixed88x80(BigInteger value) { + super(88, 80, value); + } + + public Ufixed88x80(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(88, 80, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x88.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x88.java new file mode 100644 index 0000000000..a3b81e9907 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x88.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed88x88 extends Ufixed { + public static final Ufixed88x88 DEFAULT = new Ufixed88x88(BigInteger.ZERO); + + public Ufixed88x88(BigInteger value) { + super(88, 88, value); + } + + public Ufixed88x88(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(88, 88, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x96.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x96.java new file mode 100644 index 0000000000..744d9e151d --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed88x96.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed88x96 extends Ufixed { + public static final Ufixed88x96 DEFAULT = new Ufixed88x96(BigInteger.ZERO); + + public Ufixed88x96(BigInteger value) { + super(88, 96, value); + } + + public Ufixed88x96(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(88, 96, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x104.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x104.java new file mode 100644 index 0000000000..b0bc2af3d4 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x104.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed8x104 extends Ufixed { + public static final Ufixed8x104 DEFAULT = new Ufixed8x104(BigInteger.ZERO); + + public Ufixed8x104(BigInteger value) { + super(8, 104, value); + } + + public Ufixed8x104(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 104, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x112.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x112.java new file mode 100644 index 0000000000..62d8904fa1 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x112.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed8x112 extends Ufixed { + public static final Ufixed8x112 DEFAULT = new Ufixed8x112(BigInteger.ZERO); + + public Ufixed8x112(BigInteger value) { + super(8, 112, value); + } + + public Ufixed8x112(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 112, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x120.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x120.java new file mode 100644 index 0000000000..6b13e462a3 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x120.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed8x120 extends Ufixed { + public static final Ufixed8x120 DEFAULT = new Ufixed8x120(BigInteger.ZERO); + + public Ufixed8x120(BigInteger value) { + super(8, 120, value); + } + + public Ufixed8x120(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 120, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x128.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x128.java new file mode 100644 index 0000000000..f283d73680 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x128.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed8x128 extends Ufixed { + public static final Ufixed8x128 DEFAULT = new Ufixed8x128(BigInteger.ZERO); + + public Ufixed8x128(BigInteger value) { + super(8, 128, value); + } + + public Ufixed8x128(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 128, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x136.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x136.java new file mode 100644 index 0000000000..27de5a877b --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x136.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed8x136 extends Ufixed { + public static final Ufixed8x136 DEFAULT = new Ufixed8x136(BigInteger.ZERO); + + public Ufixed8x136(BigInteger value) { + super(8, 136, value); + } + + public Ufixed8x136(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 136, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x144.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x144.java new file mode 100644 index 0000000000..9829a539ad --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x144.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed8x144 extends Ufixed { + public static final Ufixed8x144 DEFAULT = new Ufixed8x144(BigInteger.ZERO); + + public Ufixed8x144(BigInteger value) { + super(8, 144, value); + } + + public Ufixed8x144(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 144, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x152.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x152.java new file mode 100644 index 0000000000..40d00b7146 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x152.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed8x152 extends Ufixed { + public static final Ufixed8x152 DEFAULT = new Ufixed8x152(BigInteger.ZERO); + + public Ufixed8x152(BigInteger value) { + super(8, 152, value); + } + + public Ufixed8x152(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 152, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x16.java new file mode 100644 index 0000000000..b6b1d9be9c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed8x16 extends Ufixed { + public static final Ufixed8x16 DEFAULT = new Ufixed8x16(BigInteger.ZERO); + + public Ufixed8x16(BigInteger value) { + super(8, 16, value); + } + + public Ufixed8x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x160.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x160.java new file mode 100644 index 0000000000..eafa2c7f3c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x160.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed8x160 extends Ufixed { + public static final Ufixed8x160 DEFAULT = new Ufixed8x160(BigInteger.ZERO); + + public Ufixed8x160(BigInteger value) { + super(8, 160, value); + } + + public Ufixed8x160(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 160, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x168.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x168.java new file mode 100644 index 0000000000..263a81382f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x168.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed8x168 extends Ufixed { + public static final Ufixed8x168 DEFAULT = new Ufixed8x168(BigInteger.ZERO); + + public Ufixed8x168(BigInteger value) { + super(8, 168, value); + } + + public Ufixed8x168(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 168, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x176.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x176.java new file mode 100644 index 0000000000..6ca3c5b110 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x176.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed8x176 extends Ufixed { + public static final Ufixed8x176 DEFAULT = new Ufixed8x176(BigInteger.ZERO); + + public Ufixed8x176(BigInteger value) { + super(8, 176, value); + } + + public Ufixed8x176(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 176, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x184.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x184.java new file mode 100644 index 0000000000..4f7c222803 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x184.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed8x184 extends Ufixed { + public static final Ufixed8x184 DEFAULT = new Ufixed8x184(BigInteger.ZERO); + + public Ufixed8x184(BigInteger value) { + super(8, 184, value); + } + + public Ufixed8x184(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 184, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x192.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x192.java new file mode 100644 index 0000000000..dcc7719526 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x192.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed8x192 extends Ufixed { + public static final Ufixed8x192 DEFAULT = new Ufixed8x192(BigInteger.ZERO); + + public Ufixed8x192(BigInteger value) { + super(8, 192, value); + } + + public Ufixed8x192(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 192, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x200.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x200.java new file mode 100644 index 0000000000..ff1f132e6b --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x200.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed8x200 extends Ufixed { + public static final Ufixed8x200 DEFAULT = new Ufixed8x200(BigInteger.ZERO); + + public Ufixed8x200(BigInteger value) { + super(8, 200, value); + } + + public Ufixed8x200(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 200, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x208.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x208.java new file mode 100644 index 0000000000..b8e7782b5f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x208.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed8x208 extends Ufixed { + public static final Ufixed8x208 DEFAULT = new Ufixed8x208(BigInteger.ZERO); + + public Ufixed8x208(BigInteger value) { + super(8, 208, value); + } + + public Ufixed8x208(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 208, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x216.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x216.java new file mode 100644 index 0000000000..1af44952b2 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x216.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed8x216 extends Ufixed { + public static final Ufixed8x216 DEFAULT = new Ufixed8x216(BigInteger.ZERO); + + public Ufixed8x216(BigInteger value) { + super(8, 216, value); + } + + public Ufixed8x216(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 216, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x224.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x224.java new file mode 100644 index 0000000000..e485ed1353 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x224.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed8x224 extends Ufixed { + public static final Ufixed8x224 DEFAULT = new Ufixed8x224(BigInteger.ZERO); + + public Ufixed8x224(BigInteger value) { + super(8, 224, value); + } + + public Ufixed8x224(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 224, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x232.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x232.java new file mode 100644 index 0000000000..99730283dd --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x232.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed8x232 extends Ufixed { + public static final Ufixed8x232 DEFAULT = new Ufixed8x232(BigInteger.ZERO); + + public Ufixed8x232(BigInteger value) { + super(8, 232, value); + } + + public Ufixed8x232(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 232, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x24.java new file mode 100644 index 0000000000..c3b2e44b4d --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed8x24 extends Ufixed { + public static final Ufixed8x24 DEFAULT = new Ufixed8x24(BigInteger.ZERO); + + public Ufixed8x24(BigInteger value) { + super(8, 24, value); + } + + public Ufixed8x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x240.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x240.java new file mode 100644 index 0000000000..b31680fb2f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x240.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed8x240 extends Ufixed { + public static final Ufixed8x240 DEFAULT = new Ufixed8x240(BigInteger.ZERO); + + public Ufixed8x240(BigInteger value) { + super(8, 240, value); + } + + public Ufixed8x240(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 240, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x248.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x248.java new file mode 100644 index 0000000000..60398591b9 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x248.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed8x248 extends Ufixed { + public static final Ufixed8x248 DEFAULT = new Ufixed8x248(BigInteger.ZERO); + + public Ufixed8x248(BigInteger value) { + super(8, 248, value); + } + + public Ufixed8x248(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 248, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x32.java new file mode 100644 index 0000000000..dcf5b978b7 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed8x32 extends Ufixed { + public static final Ufixed8x32 DEFAULT = new Ufixed8x32(BigInteger.ZERO); + + public Ufixed8x32(BigInteger value) { + super(8, 32, value); + } + + public Ufixed8x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x40.java new file mode 100644 index 0000000000..1987b58fb1 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed8x40 extends Ufixed { + public static final Ufixed8x40 DEFAULT = new Ufixed8x40(BigInteger.ZERO); + + public Ufixed8x40(BigInteger value) { + super(8, 40, value); + } + + public Ufixed8x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x48.java new file mode 100644 index 0000000000..e22966b1e9 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed8x48 extends Ufixed { + public static final Ufixed8x48 DEFAULT = new Ufixed8x48(BigInteger.ZERO); + + public Ufixed8x48(BigInteger value) { + super(8, 48, value); + } + + public Ufixed8x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x56.java new file mode 100644 index 0000000000..97d4b4a540 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x56.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed8x56 extends Ufixed { + public static final Ufixed8x56 DEFAULT = new Ufixed8x56(BigInteger.ZERO); + + public Ufixed8x56(BigInteger value) { + super(8, 56, value); + } + + public Ufixed8x56(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 56, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x64.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x64.java new file mode 100644 index 0000000000..d0e4b30552 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x64.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed8x64 extends Ufixed { + public static final Ufixed8x64 DEFAULT = new Ufixed8x64(BigInteger.ZERO); + + public Ufixed8x64(BigInteger value) { + super(8, 64, value); + } + + public Ufixed8x64(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 64, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x72.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x72.java new file mode 100644 index 0000000000..e99557629e --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x72.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed8x72 extends Ufixed { + public static final Ufixed8x72 DEFAULT = new Ufixed8x72(BigInteger.ZERO); + + public Ufixed8x72(BigInteger value) { + super(8, 72, value); + } + + public Ufixed8x72(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 72, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x8.java new file mode 100644 index 0000000000..92bd166d16 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed8x8 extends Ufixed { + public static final Ufixed8x8 DEFAULT = new Ufixed8x8(BigInteger.ZERO); + + public Ufixed8x8(BigInteger value) { + super(8, 8, value); + } + + public Ufixed8x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x80.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x80.java new file mode 100644 index 0000000000..3db420ed0f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x80.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed8x80 extends Ufixed { + public static final Ufixed8x80 DEFAULT = new Ufixed8x80(BigInteger.ZERO); + + public Ufixed8x80(BigInteger value) { + super(8, 80, value); + } + + public Ufixed8x80(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 80, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x88.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x88.java new file mode 100644 index 0000000000..c446cacc54 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x88.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed8x88 extends Ufixed { + public static final Ufixed8x88 DEFAULT = new Ufixed8x88(BigInteger.ZERO); + + public Ufixed8x88(BigInteger value) { + super(8, 88, value); + } + + public Ufixed8x88(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 88, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x96.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x96.java new file mode 100644 index 0000000000..e1839ef45e --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed8x96.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed8x96 extends Ufixed { + public static final Ufixed8x96 DEFAULT = new Ufixed8x96(BigInteger.ZERO); + + public Ufixed8x96(BigInteger value) { + super(8, 96, value); + } + + public Ufixed8x96(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(8, 96, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x104.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x104.java new file mode 100644 index 0000000000..67a353aece --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x104.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed96x104 extends Ufixed { + public static final Ufixed96x104 DEFAULT = new Ufixed96x104(BigInteger.ZERO); + + public Ufixed96x104(BigInteger value) { + super(96, 104, value); + } + + public Ufixed96x104(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(96, 104, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x112.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x112.java new file mode 100644 index 0000000000..ba1047c6a6 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x112.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed96x112 extends Ufixed { + public static final Ufixed96x112 DEFAULT = new Ufixed96x112(BigInteger.ZERO); + + public Ufixed96x112(BigInteger value) { + super(96, 112, value); + } + + public Ufixed96x112(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(96, 112, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x120.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x120.java new file mode 100644 index 0000000000..d9fbf2e232 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x120.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed96x120 extends Ufixed { + public static final Ufixed96x120 DEFAULT = new Ufixed96x120(BigInteger.ZERO); + + public Ufixed96x120(BigInteger value) { + super(96, 120, value); + } + + public Ufixed96x120(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(96, 120, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x128.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x128.java new file mode 100644 index 0000000000..3287b7ddea --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x128.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed96x128 extends Ufixed { + public static final Ufixed96x128 DEFAULT = new Ufixed96x128(BigInteger.ZERO); + + public Ufixed96x128(BigInteger value) { + super(96, 128, value); + } + + public Ufixed96x128(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(96, 128, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x136.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x136.java new file mode 100644 index 0000000000..1774639830 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x136.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed96x136 extends Ufixed { + public static final Ufixed96x136 DEFAULT = new Ufixed96x136(BigInteger.ZERO); + + public Ufixed96x136(BigInteger value) { + super(96, 136, value); + } + + public Ufixed96x136(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(96, 136, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x144.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x144.java new file mode 100644 index 0000000000..da6d86571b --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x144.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed96x144 extends Ufixed { + public static final Ufixed96x144 DEFAULT = new Ufixed96x144(BigInteger.ZERO); + + public Ufixed96x144(BigInteger value) { + super(96, 144, value); + } + + public Ufixed96x144(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(96, 144, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x152.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x152.java new file mode 100644 index 0000000000..249b44e481 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x152.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed96x152 extends Ufixed { + public static final Ufixed96x152 DEFAULT = new Ufixed96x152(BigInteger.ZERO); + + public Ufixed96x152(BigInteger value) { + super(96, 152, value); + } + + public Ufixed96x152(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(96, 152, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x16.java new file mode 100644 index 0000000000..113237b9b6 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x16.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed96x16 extends Ufixed { + public static final Ufixed96x16 DEFAULT = new Ufixed96x16(BigInteger.ZERO); + + public Ufixed96x16(BigInteger value) { + super(96, 16, value); + } + + public Ufixed96x16(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(96, 16, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x160.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x160.java new file mode 100644 index 0000000000..ee92201891 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x160.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed96x160 extends Ufixed { + public static final Ufixed96x160 DEFAULT = new Ufixed96x160(BigInteger.ZERO); + + public Ufixed96x160(BigInteger value) { + super(96, 160, value); + } + + public Ufixed96x160(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(96, 160, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x24.java new file mode 100644 index 0000000000..46e2dc2caf --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x24.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed96x24 extends Ufixed { + public static final Ufixed96x24 DEFAULT = new Ufixed96x24(BigInteger.ZERO); + + public Ufixed96x24(BigInteger value) { + super(96, 24, value); + } + + public Ufixed96x24(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(96, 24, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x32.java new file mode 100644 index 0000000000..6e649ed4d5 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x32.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed96x32 extends Ufixed { + public static final Ufixed96x32 DEFAULT = new Ufixed96x32(BigInteger.ZERO); + + public Ufixed96x32(BigInteger value) { + super(96, 32, value); + } + + public Ufixed96x32(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(96, 32, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x40.java new file mode 100644 index 0000000000..aa7214cf4a --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x40.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed96x40 extends Ufixed { + public static final Ufixed96x40 DEFAULT = new Ufixed96x40(BigInteger.ZERO); + + public Ufixed96x40(BigInteger value) { + super(96, 40, value); + } + + public Ufixed96x40(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(96, 40, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x48.java new file mode 100644 index 0000000000..efd71cd73a --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x48.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed96x48 extends Ufixed { + public static final Ufixed96x48 DEFAULT = new Ufixed96x48(BigInteger.ZERO); + + public Ufixed96x48(BigInteger value) { + super(96, 48, value); + } + + public Ufixed96x48(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(96, 48, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x56.java new file mode 100644 index 0000000000..45182ad413 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x56.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed96x56 extends Ufixed { + public static final Ufixed96x56 DEFAULT = new Ufixed96x56(BigInteger.ZERO); + + public Ufixed96x56(BigInteger value) { + super(96, 56, value); + } + + public Ufixed96x56(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(96, 56, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x64.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x64.java new file mode 100644 index 0000000000..8297f71b6f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x64.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed96x64 extends Ufixed { + public static final Ufixed96x64 DEFAULT = new Ufixed96x64(BigInteger.ZERO); + + public Ufixed96x64(BigInteger value) { + super(96, 64, value); + } + + public Ufixed96x64(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(96, 64, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x72.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x72.java new file mode 100644 index 0000000000..0cb715a566 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x72.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed96x72 extends Ufixed { + public static final Ufixed96x72 DEFAULT = new Ufixed96x72(BigInteger.ZERO); + + public Ufixed96x72(BigInteger value) { + super(96, 72, value); + } + + public Ufixed96x72(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(96, 72, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x8.java new file mode 100644 index 0000000000..2adb3ce7d7 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x8.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed96x8 extends Ufixed { + public static final Ufixed96x8 DEFAULT = new Ufixed96x8(BigInteger.ZERO); + + public Ufixed96x8(BigInteger value) { + super(96, 8, value); + } + + public Ufixed96x8(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(96, 8, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x80.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x80.java new file mode 100644 index 0000000000..64bdecc280 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x80.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed96x80 extends Ufixed { + public static final Ufixed96x80 DEFAULT = new Ufixed96x80(BigInteger.ZERO); + + public Ufixed96x80(BigInteger value) { + super(96, 80, value); + } + + public Ufixed96x80(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(96, 80, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x88.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x88.java new file mode 100644 index 0000000000..a41f473de8 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x88.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed96x88 extends Ufixed { + public static final Ufixed96x88 DEFAULT = new Ufixed96x88(BigInteger.ZERO); + + public Ufixed96x88(BigInteger value) { + super(96, 88, value); + } + + public Ufixed96x88(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(96, 88, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x96.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x96.java new file mode 100644 index 0000000000..41f7effce2 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Ufixed96x96.java @@ -0,0 +1,22 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Ufixed; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Ufixed96x96 extends Ufixed { + public static final Ufixed96x96 DEFAULT = new Ufixed96x96(BigInteger.ZERO); + + public Ufixed96x96(BigInteger value) { + super(96, 96, value); + } + + public Ufixed96x96(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { + super(96, 96, m, n); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint104.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint104.java new file mode 100644 index 0000000000..f29ad51f70 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint104.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Uint; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Uint104 extends Uint { + public static final Uint104 DEFAULT = new Uint104(BigInteger.ZERO); + + public Uint104(BigInteger value) { + super(104, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint112.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint112.java new file mode 100644 index 0000000000..430ca42665 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint112.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Uint; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Uint112 extends Uint { + public static final Uint112 DEFAULT = new Uint112(BigInteger.ZERO); + + public Uint112(BigInteger value) { + super(112, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint120.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint120.java new file mode 100644 index 0000000000..fefefe7c4a --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint120.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Uint; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Uint120 extends Uint { + public static final Uint120 DEFAULT = new Uint120(BigInteger.ZERO); + + public Uint120(BigInteger value) { + super(120, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint128.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint128.java new file mode 100644 index 0000000000..ab6b8ae4d2 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint128.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Uint; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Uint128 extends Uint { + public static final Uint128 DEFAULT = new Uint128(BigInteger.ZERO); + + public Uint128(BigInteger value) { + super(128, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint136.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint136.java new file mode 100644 index 0000000000..857c9dbd6e --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint136.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Uint; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Uint136 extends Uint { + public static final Uint136 DEFAULT = new Uint136(BigInteger.ZERO); + + public Uint136(BigInteger value) { + super(136, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint144.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint144.java new file mode 100644 index 0000000000..4c8bc80c68 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint144.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Uint; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Uint144 extends Uint { + public static final Uint144 DEFAULT = new Uint144(BigInteger.ZERO); + + public Uint144(BigInteger value) { + super(144, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint152.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint152.java new file mode 100644 index 0000000000..e8395885b9 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint152.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Uint; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Uint152 extends Uint { + public static final Uint152 DEFAULT = new Uint152(BigInteger.ZERO); + + public Uint152(BigInteger value) { + super(152, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint16.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint16.java new file mode 100644 index 0000000000..d5bcef7c24 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint16.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Uint; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Uint16 extends Uint { + public static final Uint16 DEFAULT = new Uint16(BigInteger.ZERO); + + public Uint16(BigInteger value) { + super(16, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint160.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint160.java new file mode 100644 index 0000000000..8306533083 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint160.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Uint; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Uint160 extends Uint { + public static final Uint160 DEFAULT = new Uint160(BigInteger.ZERO); + + public Uint160(BigInteger value) { + super(160, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint168.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint168.java new file mode 100644 index 0000000000..218783c8d2 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint168.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Uint; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Uint168 extends Uint { + public static final Uint168 DEFAULT = new Uint168(BigInteger.ZERO); + + public Uint168(BigInteger value) { + super(168, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint176.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint176.java new file mode 100644 index 0000000000..3d7240724f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint176.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Uint; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Uint176 extends Uint { + public static final Uint176 DEFAULT = new Uint176(BigInteger.ZERO); + + public Uint176(BigInteger value) { + super(176, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint184.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint184.java new file mode 100644 index 0000000000..cf41d49022 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint184.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Uint; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Uint184 extends Uint { + public static final Uint184 DEFAULT = new Uint184(BigInteger.ZERO); + + public Uint184(BigInteger value) { + super(184, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint192.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint192.java new file mode 100644 index 0000000000..319a4237c1 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint192.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Uint; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Uint192 extends Uint { + public static final Uint192 DEFAULT = new Uint192(BigInteger.ZERO); + + public Uint192(BigInteger value) { + super(192, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint200.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint200.java new file mode 100644 index 0000000000..8151be4662 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint200.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Uint; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Uint200 extends Uint { + public static final Uint200 DEFAULT = new Uint200(BigInteger.ZERO); + + public Uint200(BigInteger value) { + super(200, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint208.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint208.java new file mode 100644 index 0000000000..656aecff6e --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint208.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Uint; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Uint208 extends Uint { + public static final Uint208 DEFAULT = new Uint208(BigInteger.ZERO); + + public Uint208(BigInteger value) { + super(208, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint216.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint216.java new file mode 100644 index 0000000000..8805a0f6bc --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint216.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Uint; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Uint216 extends Uint { + public static final Uint216 DEFAULT = new Uint216(BigInteger.ZERO); + + public Uint216(BigInteger value) { + super(216, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint224.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint224.java new file mode 100644 index 0000000000..08063e4de2 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint224.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Uint; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Uint224 extends Uint { + public static final Uint224 DEFAULT = new Uint224(BigInteger.ZERO); + + public Uint224(BigInteger value) { + super(224, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint232.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint232.java new file mode 100644 index 0000000000..28356bebc7 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint232.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Uint; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Uint232 extends Uint { + public static final Uint232 DEFAULT = new Uint232(BigInteger.ZERO); + + public Uint232(BigInteger value) { + super(232, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint24.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint24.java new file mode 100644 index 0000000000..7af24e6fb2 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint24.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Uint; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Uint24 extends Uint { + public static final Uint24 DEFAULT = new Uint24(BigInteger.ZERO); + + public Uint24(BigInteger value) { + super(24, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint240.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint240.java new file mode 100644 index 0000000000..d0cb9ebd28 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint240.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Uint; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Uint240 extends Uint { + public static final Uint240 DEFAULT = new Uint240(BigInteger.ZERO); + + public Uint240(BigInteger value) { + super(240, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint248.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint248.java new file mode 100644 index 0000000000..a8b373b3f1 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint248.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Uint; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Uint248 extends Uint { + public static final Uint248 DEFAULT = new Uint248(BigInteger.ZERO); + + public Uint248(BigInteger value) { + super(248, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint256.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint256.java new file mode 100644 index 0000000000..39767d9d2d --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint256.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Uint; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Uint256 extends Uint { + public static final Uint256 DEFAULT = new Uint256(BigInteger.ZERO); + + public Uint256(BigInteger value) { + super(256, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint32.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint32.java new file mode 100644 index 0000000000..e1c0d22c2b --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint32.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Uint; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Uint32 extends Uint { + public static final Uint32 DEFAULT = new Uint32(BigInteger.ZERO); + + public Uint32(BigInteger value) { + super(32, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint40.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint40.java new file mode 100644 index 0000000000..1e67490b4b --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint40.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Uint; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Uint40 extends Uint { + public static final Uint40 DEFAULT = new Uint40(BigInteger.ZERO); + + public Uint40(BigInteger value) { + super(40, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint48.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint48.java new file mode 100644 index 0000000000..1d566ad764 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint48.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Uint; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Uint48 extends Uint { + public static final Uint48 DEFAULT = new Uint48(BigInteger.ZERO); + + public Uint48(BigInteger value) { + super(48, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint56.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint56.java new file mode 100644 index 0000000000..c6dc0f2d31 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint56.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Uint; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Uint56 extends Uint { + public static final Uint56 DEFAULT = new Uint56(BigInteger.ZERO); + + public Uint56(BigInteger value) { + super(56, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint64.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint64.java new file mode 100644 index 0000000000..0e3036e75e --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint64.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Uint; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Uint64 extends Uint { + public static final Uint64 DEFAULT = new Uint64(BigInteger.ZERO); + + public Uint64(BigInteger value) { + super(64, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint72.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint72.java new file mode 100644 index 0000000000..4563106762 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint72.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Uint; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Uint72 extends Uint { + public static final Uint72 DEFAULT = new Uint72(BigInteger.ZERO); + + public Uint72(BigInteger value) { + super(72, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint8.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint8.java new file mode 100644 index 0000000000..12fdde07aa --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint8.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Uint; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Uint8 extends Uint { + public static final Uint8 DEFAULT = new Uint8(BigInteger.ZERO); + + public Uint8(BigInteger value) { + super(8, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint80.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint80.java new file mode 100644 index 0000000000..0a0a9871d2 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint80.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Uint; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Uint80 extends Uint { + public static final Uint80 DEFAULT = new Uint80(BigInteger.ZERO); + + public Uint80(BigInteger value) { + super(80, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint88.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint88.java new file mode 100644 index 0000000000..b89678adfb --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint88.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Uint; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Uint88 extends Uint { + public static final Uint88 DEFAULT = new Uint88(BigInteger.ZERO); + + public Uint88(BigInteger value) { + super(88, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint96.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint96.java new file mode 100644 index 0000000000..c3aee19e3d --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/abi/datatypes/generated/Uint96.java @@ -0,0 +1,18 @@ +package org.web3j.abi.datatypes.generated; + +import java.math.BigInteger; + +import org.web3j.abi.datatypes.Uint; + +/** + *

Auto generated code.
+ * Do not modifiy!
+ * Please use {@link org.web3j.codegen.AbiTypesGenerator} to update.

+ */ +public class Uint96 extends Uint { + public static final Uint96 DEFAULT = new Uint96(BigInteger.ZERO); + + public Uint96(BigInteger value) { + super(96, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/codegen/AbiTypesGenerator.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/codegen/AbiTypesGenerator.java new file mode 100644 index 0000000000..90345a7d2e --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/codegen/AbiTypesGenerator.java @@ -0,0 +1,190 @@ +package org.web3j.codegen; + +import java.io.IOException; +import java.math.BigInteger; +import java.nio.file.Path; +import java.nio.file.Paths; +import javax.lang.model.element.Modifier; + +import com.squareup.javapoet.ClassName; +import com.squareup.javapoet.FieldSpec; +import com.squareup.javapoet.JavaFile; +import com.squareup.javapoet.MethodSpec; +import com.squareup.javapoet.TypeSpec; + +import org.web3j.abi.datatypes.Bytes; +import org.web3j.abi.datatypes.Fixed; +import org.web3j.abi.datatypes.Int; +import org.web3j.abi.datatypes.Type; +import org.web3j.abi.datatypes.Ufixed; +import org.web3j.abi.datatypes.Uint; + +/** + * Generator class for creating all the different numeric type variants. + */ +public class AbiTypesGenerator { + + private static final String CODEGEN_WARNING = "

Auto generated code.
\n" + + "Do not modifiy!
\n" + + "Please use {@link " + AbiTypesGenerator.class.getName() + "} to update.

\n"; + + private static final String DEFAULT = "DEFAULT"; + + public static void main(String[] args) throws Exception { + AbiTypesGenerator abiTypesGenerator = new AbiTypesGenerator(); + if (args.length == 1) { + abiTypesGenerator.generate(args[0]); + } else { + abiTypesGenerator.generate(System.getProperty("user.dir") + "/src/main/java/"); + } + } + + private void generate(String destinationDir) throws IOException { + Path path = Paths.get(destinationDir); + + generateIntTypes(Int.class, path); + generateIntTypes(Uint.class, path); + generateFixedTypes(Fixed.class, path); + generateFixedTypes(Ufixed.class, path); + generateBytesTypes(Bytes.class, path); + } + + private void generateIntTypes( + Class superclass, Path path) throws IOException { + String packageName = createPackageName(superclass); + ClassName className; + + for (int bitSize = 8; bitSize <= Type.MAX_BIT_LENGTH; bitSize += 8) { + className = ClassName.get(packageName, superclass.getSimpleName() + bitSize); + + MethodSpec constructorSpec = MethodSpec.constructorBuilder() + .addModifiers(Modifier.PUBLIC) + .addParameter(BigInteger.class, "value") + .addStatement("super($L, $N)", bitSize, "value") + .build(); + + FieldSpec defaultFieldSpec = FieldSpec + .builder(className, DEFAULT, Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL) + .initializer("new $T(BigInteger.ZERO)", className) + .build(); + + TypeSpec intType = TypeSpec.classBuilder(className.simpleName()) + .addJavadoc(CODEGEN_WARNING) + .superclass(superclass) + .addModifiers(Modifier.PUBLIC) + .addField(defaultFieldSpec) + .addMethod(constructorSpec) + .build(); + + JavaFile javaFile = JavaFile.builder(packageName, intType) + .skipJavaLangImports(true) + .build(); + + javaFile.writeTo(path); + } + } + + private void generateFixedTypes( + Class superclass, Path path) throws IOException { + String packageName = createPackageName(superclass); + ClassName className; + + for (int mBitSize = 8; mBitSize < Type.MAX_BIT_LENGTH; mBitSize += 8) { + inner: + for (int nBitSize = 8; nBitSize < Type.MAX_BIT_LENGTH; nBitSize += 8) { + + if (mBitSize + nBitSize > Type.MAX_BIT_LENGTH) { + break inner; + } + + MethodSpec constructorSpec1 = MethodSpec.constructorBuilder() + .addModifiers(Modifier.PUBLIC) + .addParameter(BigInteger.class, "value") + .addStatement("super($L, $L, $N)", mBitSize, nBitSize, "value") + .build(); + + MethodSpec constructorSpec2 = MethodSpec.constructorBuilder() + .addModifiers(Modifier.PUBLIC) + .addParameter(int.class, "mBitSize") + .addParameter(int.class, "nBitSize") + .addParameter(BigInteger.class, "m") + .addParameter(BigInteger.class, "n") + .addStatement("super($L, $L, $N, $N)", mBitSize, nBitSize, "m", "n") + .build(); + + className = ClassName.get(packageName, + superclass.getSimpleName() + mBitSize + "x" + nBitSize); + + FieldSpec defaultFieldSpec = FieldSpec + .builder(className, + DEFAULT, + Modifier.PUBLIC, + Modifier.STATIC, + Modifier.FINAL) + .initializer("new $T(BigInteger.ZERO)", className) + .build(); + + TypeSpec fixedType = TypeSpec + .classBuilder(className.simpleName()) + .addJavadoc(CODEGEN_WARNING) + .superclass(superclass) + .addModifiers(Modifier.PUBLIC) + .addField(defaultFieldSpec) + .addMethod(constructorSpec1) + .addMethod(constructorSpec2) + .build(); + + write(packageName, fixedType, path); + } + } + } + + private void generateBytesTypes( + Class superclass, Path path) throws IOException { + String packageName = createPackageName(superclass); + ClassName className; + + for (int byteSize = 1; byteSize <= 32; byteSize++) { + + MethodSpec constructorSpec = MethodSpec.constructorBuilder() + .addModifiers(Modifier.PUBLIC) + .addParameter(byte[].class, "value") + .addStatement("super($L, $N)", byteSize, "value") + .build(); + + className = ClassName.get(packageName, superclass.getSimpleName() + byteSize); + + FieldSpec defaultFieldSpec = FieldSpec + .builder(className, DEFAULT, Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL) + .initializer("new $T(new byte[$L])", className, byteSize) + .build(); + + TypeSpec bytesType = TypeSpec + .classBuilder(className.simpleName()) + .addJavadoc(CODEGEN_WARNING) + .superclass(superclass) + .addModifiers(Modifier.PUBLIC) + .addField(defaultFieldSpec) + .addMethod(constructorSpec) + .build(); + + write(packageName, bytesType, path); + } + } + + private void write(String packageName, TypeSpec typeSpec, Path destination) throws IOException { + JavaFile javaFile = JavaFile.builder(packageName, typeSpec) + .skipJavaLangImports(true) + .build(); + + javaFile.writeTo(destination); + } + + static String createPackageName(Class cls) { + return getPackageName(cls) + ".generated"; + } + + static String getPackageName(Class cls) { + return cls.getPackage().getName(); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/codegen/AbiTypesMapperGenerator.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/codegen/AbiTypesMapperGenerator.java new file mode 100644 index 0000000000..400c9d1eb2 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/codegen/AbiTypesMapperGenerator.java @@ -0,0 +1,160 @@ +package org.web3j.codegen; + +import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; +import javax.lang.model.element.Modifier; + +import com.squareup.javapoet.ClassName; +import com.squareup.javapoet.JavaFile; +import com.squareup.javapoet.MethodSpec; +import com.squareup.javapoet.ParameterizedTypeName; +import com.squareup.javapoet.TypeSpec; +import com.squareup.javapoet.WildcardTypeName; + +import org.web3j.abi.datatypes.Address; +import org.web3j.abi.datatypes.Bool; +import org.web3j.abi.datatypes.Bytes; +import org.web3j.abi.datatypes.DynamicBytes; +import org.web3j.abi.datatypes.Fixed; +import org.web3j.abi.datatypes.Int; +import org.web3j.abi.datatypes.Type; +import org.web3j.abi.datatypes.Ufixed; +import org.web3j.abi.datatypes.Uint; +import org.web3j.abi.datatypes.Utf8String; + +/** + * Generator class for creating all the different numeric type variants. + */ +public class AbiTypesMapperGenerator { + + private static final String CODEGEN_WARNING = "

Auto generated code.
\n" + + "Do not modifiy!
\n" + + "Please use {@link " + AbiTypesMapperGenerator.class.getName() + "} to update.

\n"; + + private static final String TYPE = "type"; + + public static void main(String[] args) throws Exception { + AbiTypesMapperGenerator abiTypesMapperGenerator = new AbiTypesMapperGenerator(); + if (args.length == 1) { + abiTypesMapperGenerator.generate(args[0]); + } else { + abiTypesMapperGenerator.generate(System.getProperty("user.dir") + "/src/main/java/"); + } + } + + private void generate(String destinationDir) throws IOException { + Path path = Paths.get(destinationDir); + + String typesPackageName = "org.web3j.abi.datatypes"; + String autoGeneratedTypesPackageName = typesPackageName + ".generated"; + + MethodSpec constructorSpec = MethodSpec.constructorBuilder() + .addModifiers(Modifier.PRIVATE) + .build(); + + MethodSpec.Builder builder = MethodSpec.methodBuilder("getType") + .addModifiers(Modifier.PUBLIC, Modifier.STATIC) + .addParameter(String.class, TYPE) + .returns( + ParameterizedTypeName.get(ClassName.get(Class.class), + WildcardTypeName.subtypeOf(Object.class)) + ) + .beginControlFlow("switch (type)"); + + builder = addTypes(builder, typesPackageName); + builder = addGeneratedTypes(builder, autoGeneratedTypesPackageName); + builder = builder.addStatement("default:\nthrow new $T($S)", + UnsupportedOperationException.class, + "Unsupported type encountered"); + builder.endControlFlow(); + + MethodSpec methodSpec = builder.build(); + + TypeSpec typeSpec = TypeSpec + .classBuilder("AbiTypes") + .addJavadoc(CODEGEN_WARNING) + .addModifiers(Modifier.PUBLIC, Modifier.FINAL) + .addMethod(constructorSpec) + .addMethod(methodSpec) + .build(); + + write(autoGeneratedTypesPackageName, typeSpec, path); + } + + private void write(String packageName, TypeSpec typeSpec, Path destination) throws IOException { + JavaFile javaFile = JavaFile.builder(packageName, typeSpec) + .skipJavaLangImports(true) + .build(); + + javaFile.writeTo(destination); + } + + private MethodSpec.Builder addTypes(MethodSpec.Builder builder, String packageName) { + builder = addStatement(builder, packageName, + Address.TYPE_NAME, Address.class.getSimpleName()); + + builder = addStatement(builder, packageName, + Bool.TYPE_NAME, Bool.class.getSimpleName()); + + builder = addStatement(builder, packageName, + Utf8String.TYPE_NAME, Utf8String.class.getSimpleName()); + + builder = addStatement(builder, packageName, + DynamicBytes.TYPE_NAME, DynamicBytes.class.getSimpleName()); + + // TODO: Fixed array & dynamic array support + return builder; + } + + private MethodSpec.Builder addGeneratedTypes(MethodSpec.Builder builder, String packageName) { + + builder = generateIntTypes(builder, packageName); + builder = generateFixedTypes(builder, packageName); + builder = generateFixedBytesTypes(builder, packageName); + + return builder; + } + + private MethodSpec.Builder generateIntTypes(MethodSpec.Builder builder, String packageName) { + for (int bitSize = 8; bitSize <= Type.MAX_BIT_LENGTH; bitSize += 8) { + + builder = addStatement(builder, packageName, + Uint.TYPE_NAME + bitSize, Uint.class.getSimpleName() + bitSize); + builder = addStatement(builder, packageName, + Int.TYPE_NAME + bitSize, Int.class.getSimpleName() + bitSize); + } + return builder; + } + + private MethodSpec.Builder generateFixedTypes(MethodSpec.Builder builder, String packageName) { + for (int mBitSize = 8, nBitSize = Type.MAX_BIT_LENGTH - 8; + mBitSize < Type.MAX_BIT_LENGTH && nBitSize > 0; + mBitSize += 8, nBitSize -= 8) { + String suffix = mBitSize + "x" + nBitSize; + builder = addStatement( + builder, packageName, Ufixed.TYPE_NAME + suffix, + Ufixed.class.getSimpleName() + suffix); + builder = addStatement( + builder, packageName, Fixed.TYPE_NAME + suffix, + Fixed.class.getSimpleName() + suffix); + } + return builder; + } + + private MethodSpec.Builder generateFixedBytesTypes(MethodSpec.Builder builder, + String packageName) { + for (int byteSize = 1; byteSize <= 32; byteSize++) { + builder = addStatement(builder, packageName, + Bytes.TYPE_NAME + byteSize, Bytes.class.getSimpleName() + byteSize); + } + return builder; + } + + private MethodSpec.Builder addStatement(MethodSpec.Builder builder, String packageName, + String typeName, String className) { + return builder.addStatement( + "case \"$L\":\nreturn $T.class", typeName, ClassName.get(packageName, className)); + } + +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/codegen/SolidityFunctionWrapperGenerator.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/codegen/SolidityFunctionWrapperGenerator.java new file mode 100644 index 0000000000..759a6e46ee --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/codegen/SolidityFunctionWrapperGenerator.java @@ -0,0 +1,775 @@ +package org.web3j.codegen; + +import java.io.File; +import java.io.IOException; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.Future; +import javax.lang.model.element.Modifier; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.squareup.javapoet.ClassName; +import com.squareup.javapoet.CodeBlock; +import com.squareup.javapoet.FieldSpec; +import com.squareup.javapoet.JavaFile; +import com.squareup.javapoet.MethodSpec; +import com.squareup.javapoet.ParameterSpec; +import com.squareup.javapoet.ParameterizedTypeName; +import com.squareup.javapoet.TypeName; +import com.squareup.javapoet.TypeSpec; +import com.squareup.javapoet.TypeVariableName; +import rx.functions.Func1; + +import org.web3j.abi.EventEncoder; +import org.web3j.abi.EventValues; +import org.web3j.abi.FunctionEncoder; +import org.web3j.abi.TypeReference; +import org.web3j.abi.datatypes.DynamicArray; +import org.web3j.abi.datatypes.Event; +import org.web3j.abi.datatypes.Function; +import org.web3j.abi.datatypes.StaticArray; +import org.web3j.abi.datatypes.Type; +import org.web3j.abi.datatypes.generated.AbiTypes; +import org.web3j.crypto.Credentials; +import org.web3j.protocol.ObjectMapperFactory; +import org.web3j.protocol.Web3j; +import org.web3j.protocol.core.DefaultBlockParameterName; +import org.web3j.protocol.core.methods.request.EthFilter; +import org.web3j.protocol.core.methods.response.AbiDefinition; +import org.web3j.protocol.core.methods.response.Log; +import org.web3j.protocol.core.methods.response.TransactionReceipt; +import org.web3j.tx.Contract; +import org.web3j.tx.TransactionManager; +import org.web3j.utils.Collection; +import org.web3j.utils.Files; +import org.web3j.utils.Strings; +import org.web3j.utils.Version; + +import static org.web3j.utils.Collection.tail; + +/** + * Java wrapper source code generator for Solidity ABI format. + */ +public class SolidityFunctionWrapperGenerator { + + private static final String BINARY = "BINARY"; + private static final String WEB3J = "web3j"; + private static final String CREDENTIALS = "credentials"; + private static final String TRANSACTION_MANAGER = "transactionManager"; + private static final String INITIAL_VALUE = "initialValue"; + private static final String CONTRACT_ADDRESS = "contractAddress"; + private static final String GAS_PRICE = "gasPrice"; + private static final String GAS_LIMIT = "gasLimit"; + + private static final String CODEGEN_WARNING = "

Auto generated code.
\n" + + "Do not modify!
\n" + + "Please use {@link " + SolidityFunctionWrapperGenerator.class.getName() + + "} to update.\n"; + + private static final String USAGE = "solidity generate " + + ".bin .abi " + + "[-p|--package ] " + + "-o|--output "; + + private String binaryFileLocation; + private String absFileLocation; + private File destinationDirLocation; + private String basePackageName; + + private SolidityFunctionWrapperGenerator( + String binaryFileLocation, + String absFileLocation, + String destinationDirLocation, + String basePackageName) { + + this.binaryFileLocation = binaryFileLocation; + this.absFileLocation = absFileLocation; + this.destinationDirLocation = new File(destinationDirLocation); + this.basePackageName = basePackageName; + } + + public static void run(String[] args) throws Exception { + if (args.length < 1 || !args[0].equals("generate")) { + exitError(USAGE); + } else { + main(tail(args)); + } + } + + public static void main(String[] args) throws Exception { + + if (args.length != 6) { + exitError(USAGE); + } + + String binaryFileLocation = parsePositionalArg(args, 0); + String absFileLocation = parsePositionalArg(args, 1); + String destinationDirLocation = parseParameterArgument(args, "-o", "--outputDir"); + String basePackageName = parseParameterArgument(args, "-p", "--package"); + + if (binaryFileLocation.equals("") + || absFileLocation.equals("") + || destinationDirLocation.equals("") + || basePackageName.equals("")) { + exitError(USAGE); + } + + new SolidityFunctionWrapperGenerator( + binaryFileLocation, + absFileLocation, + destinationDirLocation, + basePackageName) + .generate(); + } + + private static String parsePositionalArg(String[] args, int idx) { + if (args != null && args.length > idx) { + return args[idx]; + } else { + return ""; + } + } + + private static String parseParameterArgument(String[] args, String... parameters) { + for (String parameter : parameters) { + for (int i = 0; i < args.length; i++) { + if (args[i].equals(parameter) + && i + 1 < args.length) { + String parameterValue = args[i + 1]; + if (!parameterValue.startsWith("-")) { + return parameterValue; + } + } + } + } + return ""; + } + + private static void exitError(String message) { + System.err.println(message); + System.exit(1); + } + + private void generate() throws IOException, ClassNotFoundException { + + File binaryFile = new File(binaryFileLocation); + if (!binaryFile.exists()) { + exitError("Invalid input binary file specified: " + binaryFileLocation); + } + + byte[] bytes = Files.readBytes(new File(binaryFile.toURI())); + String binary = new String(bytes); + + File absFile = new File(absFileLocation); + if (!absFile.exists() || !absFile.canRead()) { + exitError("Invalid input ABI file specified: " + absFileLocation); + } + String fileName = absFile.getName(); + String contractName = getFileNameNoExtension(fileName); + + List functionDefinitions = loadContractDefinition(absFile); + + if (functionDefinitions.isEmpty()) { + exitError("Unable to parse input ABI file"); + } else { + generateSolidityWrappers(binary, contractName, functionDefinitions, basePackageName); + } + } + + private static List loadContractDefinition(File absFile) + throws IOException { + ObjectMapper objectMapper = ObjectMapperFactory.getObjectMapper(); + AbiDefinition[] abiDefinition = objectMapper.readValue(absFile, AbiDefinition[].class); + return Arrays.asList(abiDefinition); + } + + static String getFileNameNoExtension(String fileName) { + String[] splitName = fileName.split("\\.(?=[^.]*$)"); + return splitName[0]; + } + + private void generateSolidityWrappers( + String binary, String contractName, List functionDefinitions, + String basePackageName) throws IOException, ClassNotFoundException { + + String className = Strings.capitaliseFirstLetter(contractName); + + TypeSpec.Builder classBuilder = createClassBuilder(className, binary); + classBuilder.addMethod(buildConstructor(Credentials.class, CREDENTIALS)); + classBuilder.addMethod(buildConstructor( + TransactionManager.class, TRANSACTION_MANAGER)); + + classBuilder.addMethods(buildFunctionDefinitions(className, classBuilder, + functionDefinitions)); + + classBuilder.addMethod(buildLoad(className, Credentials.class, CREDENTIALS)); + classBuilder.addMethod(buildLoad(className, TransactionManager.class, TRANSACTION_MANAGER)); + + System.out.printf("Generating " + basePackageName + "." + className + " ... "); + JavaFile javaFile = JavaFile.builder(basePackageName, classBuilder.build()) + .indent(" ") // default indentation is two spaces + .build(); + System.out.println("complete"); + + javaFile.writeTo(destinationDirLocation); + System.out.println("File written to " + destinationDirLocation.toString() + "\n"); + } + + private TypeSpec.Builder createClassBuilder(String className, String binary) { + + String javadoc = CODEGEN_WARNING + getWeb3jVersion(); + + return TypeSpec.classBuilder(className) + .addModifiers(Modifier.PUBLIC, Modifier.FINAL) + .addJavadoc(javadoc) + .superclass(Contract.class) + .addField(createBinaryDefinition(binary)); + } + + private static String getWeb3jVersion() { + String version; + + try { + // This only works if run as part of the web3j command line tools which contains + // a version.properties file + version = Version.getVersion(); + } catch (IOException | NullPointerException e) { + version = Version.DEFAULT; + } + return "\n

Generated with web3j version " + version + ".\n"; + } + + private FieldSpec createBinaryDefinition(String binary) { + return FieldSpec.builder(String.class, BINARY) + .addModifiers(Modifier.PRIVATE, Modifier.FINAL, Modifier.STATIC) + .initializer("$S", binary) + .build(); + } + + private static List buildFunctionDefinitions( + String className, + TypeSpec.Builder classBuilder, + List functionDefinitions) throws ClassNotFoundException { + + List methodSpecs = new ArrayList(); + boolean constructor = false; + + for (AbiDefinition functionDefinition : functionDefinitions) { + if (functionDefinition.getType().equals("function")) { + methodSpecs.add(buildFunction(functionDefinition)); + + } else if (functionDefinition.getType().equals("event")) { + buildEventFunctions(functionDefinition, classBuilder); + + } else if (functionDefinition.getType().equals("constructor")) { + constructor = true; + methodSpecs.add(buildDeploy( + className, functionDefinition, Credentials.class, CREDENTIALS)); + methodSpecs.add(buildDeploy( + className, functionDefinition, TransactionManager.class, + TRANSACTION_MANAGER)); + } + } + + // constructor will not be specified in ABI file if its empty + if (!constructor) { + MethodSpec.Builder credentialsMethodBuilder = + getDeployMethodSpec(className, Credentials.class, CREDENTIALS); + methodSpecs.add(buildDeployAsyncNoParams( + credentialsMethodBuilder, className, CREDENTIALS)); + + MethodSpec.Builder transactionManagerMethodBuilder = + getDeployMethodSpec(className, TransactionManager.class, TRANSACTION_MANAGER); + methodSpecs.add(buildDeployAsyncNoParams( + transactionManagerMethodBuilder, className, TRANSACTION_MANAGER)); + } + + return methodSpecs; + } + + private static MethodSpec buildConstructor(Class authType, String authName) { + return MethodSpec.constructorBuilder() + .addModifiers(Modifier.PRIVATE) + .addParameter(String.class, CONTRACT_ADDRESS) + .addParameter(Web3j.class, WEB3J) + .addParameter(authType, authName) + .addParameter(BigInteger.class, GAS_PRICE) + .addParameter(BigInteger.class, GAS_LIMIT) + .addStatement("super($N, $N, $N, $N, $N)", + CONTRACT_ADDRESS, WEB3J, authName, GAS_PRICE, GAS_LIMIT) + .build(); + } + + private static MethodSpec buildDeploy( + String className, AbiDefinition functionDefinition, + Class authType, String authName) { + + MethodSpec.Builder methodBuilder = getDeployMethodSpec(className, authType, authName); + String inputParams = addParameters(methodBuilder, functionDefinition.getInputs()); + + if (!inputParams.isEmpty()) { + return buildDeployAsyncWithParams(methodBuilder, className, inputParams, authName); + } else { + return buildDeployAsyncNoParams(methodBuilder, className, authName); + } + } + + private static MethodSpec buildDeployAsyncWithParams( + MethodSpec.Builder methodBuilder, String className, String inputParams, + String authName) { + + methodBuilder.addStatement("$T encodedConstructor = $T.encodeConstructor(" + + "$T.<$T>asList($L)" + + ")", + String.class, FunctionEncoder.class, Arrays.class, Type.class, inputParams); + methodBuilder.addStatement( + "return deployAsync($L.class, $L, $L, $L, $L, $L, encodedConstructor, $L)", + className, WEB3J, authName, GAS_PRICE, GAS_LIMIT, BINARY, INITIAL_VALUE); + return methodBuilder.build(); + } + + private static MethodSpec buildDeployAsyncNoParams( + MethodSpec.Builder methodBuilder, String className, + String authName) { + methodBuilder.addStatement("return deployAsync($L.class, $L, $L, $L, $L, $L, \"\", $L)", + className, WEB3J, authName, GAS_PRICE, GAS_LIMIT, BINARY, INITIAL_VALUE); + return methodBuilder.build(); + } + + private static MethodSpec.Builder getDeployMethodSpec( + String className, Class authType, String authName) { + return MethodSpec.methodBuilder("deploy") + .addModifiers(Modifier.PUBLIC, Modifier.STATIC) + .returns(ParameterizedTypeName.get( + ClassName.get(Future.class), TypeVariableName.get(className, Type.class))) + .addParameter(Web3j.class, WEB3J) + .addParameter(authType, authName) + .addParameter(BigInteger.class, GAS_PRICE) + .addParameter(BigInteger.class, GAS_LIMIT) + .addParameter(BigInteger.class, INITIAL_VALUE); + } + + private static MethodSpec buildLoad( + String className, Class authType, String authName) { + return MethodSpec.methodBuilder("load") + .addModifiers(Modifier.PUBLIC, Modifier.STATIC) + .returns(TypeVariableName.get(className, Type.class)) + .addParameter(String.class, CONTRACT_ADDRESS) + .addParameter(Web3j.class, WEB3J) + .addParameter(authType, authName) + .addParameter(BigInteger.class, GAS_PRICE) + .addParameter(BigInteger.class, GAS_LIMIT) + .addStatement("return new $L($L, $L, $L, $L, $L)", className, + CONTRACT_ADDRESS, WEB3J, authName, GAS_PRICE, GAS_LIMIT) + .build(); + } + + static String addParameters( + MethodSpec.Builder methodBuilder, List namedTypes) { + + List inputParameterTypes = buildParameterTypes(namedTypes); + methodBuilder.addParameters(inputParameterTypes); + + return org.web3j.utils.Collection.join( + inputParameterTypes, + ", ", + new Collection.Function() { + @Override + public String apply(ParameterSpec parameterSpec) { + return parameterSpec.name; + } + }); + } + + static List buildParameterTypes(List namedTypes) { + List result = new ArrayList(namedTypes.size()); + for (int i = 0; i < namedTypes.size(); i++) { + AbiDefinition.NamedType namedType = namedTypes.get(i); + + String name = createValidParamName(namedType.getName(), i); + String type = namedTypes.get(i).getType(); + + result.add(ParameterSpec.builder(buildTypeName(type), name).build()); + } + return result; + } + + /** + * Public Solidity arrays and maps require an unnamed input parameter - multiple if they + * require a struct type + * + * @param name + * @param idx + * @return non-empty parameter name + */ + static String createValidParamName(String name, int idx) { + if (name.equals("")) { + return "param" + idx; + } else { + return name; + } + } + + static List buildTypeNames(List namedTypes) { + List result = new ArrayList(namedTypes.size()); + for (AbiDefinition.NamedType namedType : namedTypes) { + result.add(buildTypeName(namedType.getType())); + } + return result; + } + + static MethodSpec buildFunction( + AbiDefinition functionDefinition) throws ClassNotFoundException { + String functionName = functionDefinition.getName(); + + MethodSpec.Builder methodBuilder = + MethodSpec.methodBuilder(functionName) + .addModifiers(Modifier.PUBLIC); + + String inputParams = addParameters(methodBuilder, functionDefinition.getInputs()); + + List outputParameterTypes = buildTypeNames(functionDefinition.getOutputs()); + if (functionDefinition.isConstant()) { + buildConstantFunction( + functionDefinition, methodBuilder, outputParameterTypes, inputParams); + } else { + buildTransactionFunction( + functionDefinition, methodBuilder, inputParams); + } + + return methodBuilder.build(); + } + + private static void buildConstantFunction( + AbiDefinition functionDefinition, + MethodSpec.Builder methodBuilder, + List outputParameterTypes, + String inputParams) throws ClassNotFoundException { + + String functionName = functionDefinition.getName(); + + if (outputParameterTypes.isEmpty()) { + throw new RuntimeException("Only transactional methods should have void return types"); + } else if (outputParameterTypes.size() == 1) { + methodBuilder.returns(ParameterizedTypeName.get( + ClassName.get(Future.class), outputParameterTypes.get(0))); + + TypeName typeName = outputParameterTypes.get(0); + methodBuilder.addStatement("$T function = " + + "new $T($S, \n$T.<$T>asList($L), \n$T.<$T>asList(new $T<$T>() {}))", + Function.class, Function.class, functionName, + Arrays.class, Type.class, inputParams, + Arrays.class, TypeReference.class, + TypeReference.class, typeName); + methodBuilder.addStatement("return executeCallSingleValueReturnAsync(function)"); + + } else { + methodBuilder.returns(ParameterizedTypeName.get( + ClassName.get(Future.class), + ParameterizedTypeName.get( + ClassName.get(List.class), ClassName.get(Type.class)))); + + buildVariableLengthReturnFunctionConstructor( + methodBuilder, functionName, inputParams, outputParameterTypes); + + methodBuilder.addStatement("return executeCallMultipleValueReturnAsync(function)"); + } + } + + private static void buildTransactionFunction( + AbiDefinition functionDefinition, + MethodSpec.Builder methodBuilder, + String inputParams) throws ClassNotFoundException { + + String functionName = functionDefinition.getName(); + + methodBuilder.returns(ParameterizedTypeName.get(Future.class, TransactionReceipt.class)); + + methodBuilder.addStatement("$T function = new $T($S, $T.<$T>asList($L), $T" + + ".<$T>emptyList())", + Function.class, Function.class, functionName, + Arrays.class, Type.class, inputParams, Collections.class, + TypeReference.class); + methodBuilder.addStatement("return executeTransactionAsync(function)"); + } + + static TypeSpec buildEventResponseObject(String className, + List indexedParameters, + List nonIndexedParameters) { + + TypeSpec.Builder builder = TypeSpec.classBuilder(className) + .addModifiers(Modifier.PUBLIC, Modifier.STATIC); + + for (NamedTypeName namedType : indexedParameters) { + builder.addField(namedType.getTypeName(), namedType.getName(), Modifier.PUBLIC); + } + + for (NamedTypeName namedType : nonIndexedParameters) { + builder.addField(namedType.getTypeName(), namedType.getName(), Modifier.PUBLIC); + } + + return builder.build(); + } + + static MethodSpec buildEventObservableFunction(String responseClassName, + String functionName, + List indexedParameters, + List nonIndexedParameters) + throws ClassNotFoundException { + + String generatedFunctionName = + Strings.lowercaseFirstLetter(functionName) + "EventObservable"; + ParameterizedTypeName parameterizedTypeName = ParameterizedTypeName.get(ClassName.get(rx + .Observable.class), ClassName.get("", responseClassName)); + + MethodSpec.Builder observableMethodBuilder = MethodSpec.methodBuilder(generatedFunctionName) + .addModifiers(Modifier.PUBLIC) + .returns(parameterizedTypeName); + + + buildVariableLengthEventConstructor( + observableMethodBuilder, functionName, indexedParameters, nonIndexedParameters); + + + TypeSpec converter = TypeSpec.anonymousClassBuilder("") + .addSuperinterface(ParameterizedTypeName.get( + ClassName.get(Func1.class), + ClassName.get(Log.class), + ClassName.get("", responseClassName))) + .addMethod(MethodSpec.methodBuilder("call") + .addAnnotation(Override.class) + .addModifiers(Modifier.PUBLIC) + .addParameter(Log.class, "log") + .returns(ClassName.get("", responseClassName)) + .addStatement("$T eventValues = extractEventParameters(event, log)", + EventValues.class) + .addStatement("$1T typedResponse = new $1T()", + ClassName.get("", responseClassName)) + .addCode(buildTypedResponse("typedResponse", indexedParameters, + nonIndexedParameters)) + .addStatement("return typedResponse") + .build()) + .build(); + + observableMethodBuilder.addStatement("$1T filter = new $1T($2T.EARLIEST,$2T.LATEST, " + + "getContractAddress())", EthFilter.class, DefaultBlockParameterName.class) + .addStatement("filter.addSingleTopic($T.encode(event))", EventEncoder.class) + .addStatement("return web3j.ethLogObservable(filter).map($L)", converter); + + return observableMethodBuilder + .build(); + } + + static MethodSpec buildEventTransactionReceiptFunction(String responseClassName, String + functionName, List indexedParameters, List + nonIndexedParameters) throws + ClassNotFoundException { + ParameterizedTypeName parameterizedTypeName = ParameterizedTypeName.get(ClassName.get + (List.class), ClassName.get("", responseClassName)); + + String generatedFunctionName = "get" + Strings.capitaliseFirstLetter(functionName) + + "Events"; + MethodSpec.Builder transactionMethodBuilder = MethodSpec.methodBuilder + (generatedFunctionName) + .addModifiers(Modifier.PUBLIC) + .addParameter(TransactionReceipt.class, "transactionReceipt") + .returns(parameterizedTypeName); + + buildVariableLengthEventConstructor( + transactionMethodBuilder, functionName, indexedParameters, nonIndexedParameters); + + transactionMethodBuilder.addStatement("$T valueList = extractEventParameters(event," + + "transactionReceipt)", ParameterizedTypeName.get(List.class, EventValues.class)) + .addStatement("$1T responses = new $1T(valueList.size())", + ParameterizedTypeName.get(ClassName.get(ArrayList.class), + ClassName.get("", responseClassName))) + .beginControlFlow("for($T eventValues : valueList)", EventValues.class) + .addStatement("$1T typedResponse = new $1T()", + ClassName.get("", responseClassName)) + .addCode(buildTypedResponse("typedResponse", indexedParameters, + nonIndexedParameters)) + .addStatement("responses.add(typedResponse)") + .endControlFlow(); + + + transactionMethodBuilder.addStatement("return responses"); + return transactionMethodBuilder.build(); + } + + static void buildEventFunctions( + AbiDefinition functionDefinition, + TypeSpec.Builder classBuilder) throws ClassNotFoundException { + + String functionName = functionDefinition.getName(); + List inputs = functionDefinition.getInputs(); + String responseClassName = Strings.capitaliseFirstLetter(functionName) + "EventResponse"; + + List indexedParameters = new ArrayList<>(); + List nonIndexedParameters = new ArrayList<>(); + for (AbiDefinition.NamedType namedType : inputs) { + + if (namedType.isIndexed()) { + indexedParameters.add(new NamedTypeName(namedType.getName(), buildTypeName + (namedType.getType()))); + } else { + nonIndexedParameters.add(new NamedTypeName(namedType.getName(), buildTypeName + (namedType.getType()))); + } + } + + classBuilder.addType(buildEventResponseObject(responseClassName, indexedParameters, + nonIndexedParameters)); + + classBuilder.addMethod(buildEventTransactionReceiptFunction(responseClassName, + functionName, indexedParameters, nonIndexedParameters)); + classBuilder.addMethod(buildEventObservableFunction(responseClassName, functionName, + indexedParameters, nonIndexedParameters)); + } + + static CodeBlock buildTypedResponse(String objectName, + List indexedParameters, + List nonIndexedParameters) { + CodeBlock.Builder builder = CodeBlock.builder(); + for (int i = 0; i < indexedParameters.size(); i++) { + builder.addStatement("$L.$L = ($T)eventValues.getIndexedValues().get($L)", + objectName, + indexedParameters.get(i).getName(), + indexedParameters.get(i).getTypeName(), + i); + } + + for (int i = 0; i < nonIndexedParameters.size(); i++) { + builder.addStatement("$L.$L = ($T)eventValues.getNonIndexedValues().get($L)", + objectName, + nonIndexedParameters.get(i).getName(), + nonIndexedParameters.get(i).getTypeName(), + i); + } + return builder.build(); + } + + static TypeName buildTypeName(String type) { + if (type.endsWith("]")) { + String[] splitType = type.split("\\["); + Class baseType = AbiTypes.getType(splitType[0]); + + TypeName typeName; + if (splitType[1].length() == 1) { + typeName = ParameterizedTypeName.get(DynamicArray.class, baseType); + } else { + // Unfortunately we can't encode it's length as a type + typeName = ParameterizedTypeName.get(StaticArray.class, baseType); + } + return typeName; + } else { + Class cls = AbiTypes.getType(type); + return ClassName.get(cls); + } + } + + private static void buildVariableLengthReturnFunctionConstructor( + MethodSpec.Builder methodBuilder, String functionName, String inputParameters, + List outputParameterTypes) throws ClassNotFoundException { + + List objects = new ArrayList(); + objects.add(Function.class); + objects.add(Function.class); + objects.add(functionName); + + objects.add(Arrays.class); + objects.add(Type.class); + objects.add(inputParameters); + + objects.add(Arrays.class); + objects.add(TypeReference.class); + for (TypeName outputParameterType : outputParameterTypes) { + objects.add(TypeReference.class); + objects.add(outputParameterType); + } + + String asListParams = Collection.join( + outputParameterTypes, + ", ", + new Collection.Function() { + @Override + public String apply(TypeName typeName) { + return "new $T<$T>() {}"; + } + }); + + methodBuilder.addStatement("$T function = new $T($S, \n$T.<$T>asList($L), \n$T" + + ".<$T>asList(" + + asListParams + "))", objects.toArray()); + } + + private static void buildVariableLengthEventConstructor( + MethodSpec.Builder methodBuilder, String eventName, List + indexedParameterTypes, + List nonIndexedParameterTypes) throws ClassNotFoundException { + + List objects = new ArrayList(); + objects.add(Event.class); + objects.add(Event.class); + objects.add(eventName); + + objects.add(Arrays.class); + objects.add(TypeReference.class); + for (NamedTypeName indexedParameterType : indexedParameterTypes) { + objects.add(TypeReference.class); + objects.add(indexedParameterType.getTypeName()); + } + + objects.add(Arrays.class); + objects.add(TypeReference.class); + for (NamedTypeName indexedParameterType : nonIndexedParameterTypes) { + objects.add(TypeReference.class); + objects.add(indexedParameterType.getTypeName()); + } + + String indexedAsListParams = Collection.join( + indexedParameterTypes, + ", ", + new Collection.Function() { + @Override + public String apply(NamedTypeName typeName) { + return "new $T<$T>() {}"; + } + }); + + String nonIndexedAsListParams = Collection.join( + nonIndexedParameterTypes, + ", ", + new Collection.Function() { + @Override + public String apply(NamedTypeName typeName) { + return "new $T<$T>() {}"; + } + }); + + methodBuilder.addStatement("final $T event = new $T($S, \n" + + "$T.<$T>asList(" + indexedAsListParams + "),\n" + + "$T.<$T>asList(" + nonIndexedAsListParams + "))", objects.toArray()); + } + + private static class NamedTypeName { + private final TypeName typeName; + private final String name; + + NamedTypeName(String name, TypeName typeName) { + this.name = name; + this.typeName = typeName; + } + + public String getName() { + return name; + } + + public TypeName getTypeName() { + return typeName; + } + } + +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/console/ConsoleDevice.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/console/ConsoleDevice.java new file mode 100644 index 0000000000..6cda350f31 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/console/ConsoleDevice.java @@ -0,0 +1,26 @@ +package org.web3j.console; + +import java.io.Console; + +/** + * System Console device wrapper. + */ +public class ConsoleDevice implements IODevice { + + private Console console = System.console(); + + @Override + public void printf(String format, Object... args) { + console.printf(format, args); + } + + @Override + public String readLine(String fmt, Object... args) { + return console.readLine(fmt, args); + } + + @Override + public char[] readPassword(String fmt, Object... args) { + return console.readPassword(); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/console/IODevice.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/console/IODevice.java new file mode 100644 index 0000000000..7848ac0249 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/console/IODevice.java @@ -0,0 +1,10 @@ +package org.web3j.console; + +/** + * IO device abstraction. + */ +public interface IODevice { + void printf(String format, Object ... args); + String readLine(String fmt, Object ... args); + char[] readPassword(String fmt, Object ... args); +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/console/KeyImporter.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/console/KeyImporter.java new file mode 100644 index 0000000000..34105e39af --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/console/KeyImporter.java @@ -0,0 +1,83 @@ +package org.web3j.console; + +import java.io.File; +import java.io.IOException; + +import org.web3j.crypto.CipherException; +import org.web3j.crypto.Credentials; +import org.web3j.crypto.WalletUtils; +import org.web3j.utils.Files; + +import static org.web3j.crypto.Keys.PRIVATE_KEY_LENGTH_IN_HEX; +import static org.web3j.utils.Console.exitError; + +/** + * Create Ethereum wallet file from a provided private key. + */ +public class KeyImporter extends WalletManager { + + public KeyImporter() { + } + + public KeyImporter(IODevice console) { + super(console); + } + + public static void main(String[] args) { + if (args.length == 1) { + new KeyImporter().run(args[0]); + } else { + new KeyImporter().run(); + } + } + + static void main(IODevice console) { + new KeyImporter(console).run(); + } + + private void run(String input) { + File keyFile = new File(input); + + if (keyFile.isFile()) { + String privateKey = null; + try { + privateKey = Files.readString(keyFile); + } catch (IOException e) { + exitError("Unable to read file " + input); + } + + createWalletFile(privateKey.trim()); + } else { + createWalletFile(input.trim()); + } + } + + private void run() { + String input = console.readLine( + "Please enter the hex encoded private key or key file location: ").trim(); + run(input); + } + + private void createWalletFile(String privateKey) { + if (!WalletUtils.isValidPrivateKey(privateKey)) { + exitError("Invalid private key specified, must be " + + PRIVATE_KEY_LENGTH_IN_HEX + + " digit hex value"); + } + + Credentials credentials = Credentials.create(privateKey); + String password = getPassword("Please enter a wallet file password: "); + + String destinationDir = getDestinationDir(); + File destination = createDir(destinationDir); + + try { + String walletFileName = WalletUtils.generateWalletFile( + password, credentials.getEcKeyPair(), destination, true); + console.printf("Wallet file " + walletFileName + + " successfully created in: " + destinationDir + "\n"); + } catch (CipherException | IOException e) { + exitError(e); + } + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/console/Runner.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/console/Runner.java new file mode 100644 index 0000000000..43e2320b50 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/console/Runner.java @@ -0,0 +1,47 @@ +package org.web3j.console; + +import org.web3j.codegen.SolidityFunctionWrapperGenerator; +import org.web3j.utils.Console; +import org.web3j.utils.Version; + +import static org.web3j.utils.Collection.tail; + +/** + * Main entry point for running command line utilities. + */ +public class Runner { + + private static String USAGE = "Usage: web3j version|wallet|solidity ..."; + + private static String LOGO = "\n" + // generated at http://patorjk.com/software/taag + " _ _____ _ _ \n" + + " | | |____ (_) (_) \n" + + "__ _____| |__ / /_ _ ___ \n" + + "\\ \\ /\\ / / _ \\ '_ \\ \\ \\ | | | / _ \\ \n" + + " \\ V V / __/ |_) |.___/ / | _ | || (_) |\n" + + " \\_/\\_/ \\___|_.__/ \\____/| |(_)|_| \\___/ \n" + + " _/ | \n" + + " |__/ \n"; + + public static void main(String[] args) throws Exception { + System.out.println(LOGO); + + if (args.length < 1) { + Console.exitError(USAGE); + } else { + switch (args[0]) { + case "wallet": + WalletRunner.run(tail(args)); + break; + case "solidity": + SolidityFunctionWrapperGenerator.run(tail(args)); + break; + case "version": + Console.exitSuccess("Version: " + Version.getVersion() + "\n" + + "Build timestamp: " + Version.getTimestamp()); + default: + Console.exitError(USAGE); + } + } + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/console/WalletCreator.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/console/WalletCreator.java new file mode 100644 index 0000000000..3203d425a7 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/console/WalletCreator.java @@ -0,0 +1,47 @@ +package org.web3j.console; + +import java.io.File; +import java.io.IOException; +import java.security.InvalidAlgorithmParameterException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; + +import org.web3j.crypto.CipherException; +import org.web3j.crypto.WalletUtils; +import org.web3j.utils.Console; + +/** + * Simple class for creating a wallet file. + */ +public class WalletCreator extends WalletManager { + + public WalletCreator() { + } + + public WalletCreator(IODevice console) { + super(console); + } + + public static void main(String[] args) { + new WalletCreator().run(); + } + + static void main(IODevice console) { + new WalletCreator(console).run(); + } + + private void run() { + String password = getPassword("Please enter a wallet file password: "); + String destinationDir = getDestinationDir(); + File destination = createDir(destinationDir); + + try { + String walletFileName = WalletUtils.generateFullNewWalletFile(password, destination); + console.printf("Wallet file " + walletFileName + + " successfully created in: " + destinationDir + "\n"); + } catch (CipherException|IOException|InvalidAlgorithmParameterException| + NoSuchAlgorithmException|NoSuchProviderException e) { + Console.exitError(e); + } + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/console/WalletManager.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/console/WalletManager.java new file mode 100644 index 0000000000..6e9965aafb --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/console/WalletManager.java @@ -0,0 +1,97 @@ +package org.web3j.console; + +import java.io.File; +import java.io.IOException; +import java.util.Arrays; + +import org.web3j.crypto.CipherException; +import org.web3j.crypto.Credentials; +import org.web3j.crypto.WalletUtils; +import org.web3j.utils.Console; + +import static org.web3j.utils.Console.exitError; + +/** + * Common functions used by the wallet console tools. + */ +abstract class WalletManager { + + final IODevice console; + + WalletManager() { + console = new ConsoleDevice(); + + if (console == null) { + Console.exitError("Unable to access console - please ensure you are running " + + "from the command line"); + } + } + + WalletManager(IODevice console) { + this.console = console; + } + + String getPassword(String initialPrompt) { + while (true) { + char[] input1 = console.readPassword(initialPrompt); + char[] input2 = console.readPassword("Please re-enter the password: "); + + if (Arrays.equals(input1, input2)) { + return new String(input1); + } else { + console.printf("Sorry, passwords did not match\n"); + } + } + } + + String getDestinationDir() { + String defaultDir = WalletUtils.getTestnetKeyDirectory(); + String destinationDir = console.readLine( + "Please enter a destination directory location [" + defaultDir + "]: "); + if (destinationDir.equals("")) { + return defaultDir; + } else if (destinationDir.startsWith("~")) { + return System.getProperty("user.home") + destinationDir.substring(1); + } else { + return destinationDir; + } + } + + File createDir(String destinationDir) { + File destination = new File(destinationDir); + + if (!destination.exists()) { + console.printf("Creating directory: " + destinationDir + " ..."); + if (!destination.mkdirs()) { + Console.exitError("Unable to create destination directory [" + + destinationDir + "], exiting..."); + } else { + console.printf("complete\n"); + } + } + + return destination; + } + + Credentials getCredentials(File walletFile) { + if (!walletFile.exists() || !walletFile.isFile()) { + exitError("Unable to read wallet file: " + walletFile); + } + return loadWalletFile(walletFile); + } + + private Credentials loadWalletFile(File walletFile) { + while (true) { + char[] password = console.readPassword( + "Please enter your existing wallet file password: "); + String currentPassword = new String(password); + try { + return WalletUtils.loadCredentials(currentPassword, walletFile); + } catch (CipherException e) { + console.printf("Invalid password specified\n"); + } catch (IOException e) { + exitError("Unable to load wallet file: " + walletFile + "\n" + e.getMessage()); + } + } + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/console/WalletRunner.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/console/WalletRunner.java new file mode 100644 index 0000000000..1a619a23c5 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/console/WalletRunner.java @@ -0,0 +1,39 @@ +package org.web3j.console; + +import org.web3j.utils.Console; + +import static org.web3j.utils.Collection.tail; + +/** + * Class for managing our wallet command line utilities. + */ +public class WalletRunner { + private static final String USAGE = "wallet create|update|send|fromkey"; + + public static void run(String[] args) { + main(args); + } + + public static void main(String[] args) { + if (args.length < 1) { + Console.exitError(USAGE); + } else { + switch (args[0]) { + case "create": + WalletCreator.main(new String[] {}); + break; + case "update": + WalletUpdater.main(tail(args)); + break; + case "send": + WalletSendFunds.main(tail(args)); + break; + case "fromkey": + KeyImporter.main(tail(args)); + break; + default: + Console.exitError(USAGE); + } + } + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/console/WalletSendFunds.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/console/WalletSendFunds.java new file mode 100644 index 0000000000..1878ce494a --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/console/WalletSendFunds.java @@ -0,0 +1,155 @@ +package org.web3j.console; + +import java.io.File; +import java.math.BigDecimal; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +import org.web3j.crypto.Credentials; +import org.web3j.crypto.WalletUtils; +import org.web3j.protocol.Web3j; +import org.web3j.protocol.core.methods.response.TransactionReceipt; +import org.web3j.protocol.core.methods.response.Web3ClientVersion; +import org.web3j.protocol.exceptions.TransactionTimeoutException; +import org.web3j.protocol.http.HttpService; +import org.web3j.protocol.infura.InfuraHttpService; +import org.web3j.tx.Transfer; +import org.web3j.utils.Convert; + +import static org.web3j.utils.Console.exitError; + +/** + * Simple class for creating a wallet file. + */ +public class WalletSendFunds extends WalletManager { + + private static final String USAGE = "send "; + + public static void main(String[] args) { + if (args.length != 2) { + exitError(USAGE); + } else { + new WalletSendFunds().run(args[0], args[1]); + } + } + + private void run(String walletFileLocation, String destinationAddress) { + File walletFile = new File(walletFileLocation); + Credentials credentials = getCredentials(walletFile); + console.printf("Wallet for address " + credentials.getAddress() + " loaded\n"); + + if (!WalletUtils.isValidAddress(destinationAddress)) { + exitError("Invalid destination address specified"); + } + + Web3j web3j = getEthereumClient(); + + BigDecimal amountToTransfer = getAmountToTransfer(); + Convert.Unit transferUnit = getTransferUnit(); + BigDecimal amountInWei = Convert.toWei(amountToTransfer, transferUnit); + + confirmTransfer(amountToTransfer, transferUnit, amountInWei, destinationAddress); + + TransactionReceipt transactionReceipt = performTransfer( + web3j, destinationAddress, credentials, amountInWei); + + console.printf("Funds have been successfully transferred from %s to %s%n" + + "Transaction hash: %s%nMined block number: %s%n", + credentials.getAddress(), + destinationAddress, + transactionReceipt.getTransactionHash(), + transactionReceipt.getBlockNumber()); + } + + private BigDecimal getAmountToTransfer() { + String amount = console.readLine("What amound would you like to transfer " + + "(please enter a numeric value): ") + .trim(); + try { + return new BigDecimal(amount); + } catch (NumberFormatException e) { + exitError("Invalid amount specified"); + } + throw new RuntimeException("Application exit failure"); + } + + private Convert.Unit getTransferUnit() { + String unit = console.readLine("Please specify the unit (ether, wei, ...) [ether]: ") + .trim(); + + Convert.Unit transferUnit; + if (unit.equals("")) { + transferUnit = Convert.Unit.ETHER; + } else { + transferUnit = Convert.Unit.fromString(unit.toLowerCase()); + } + + return transferUnit; + } + + private void confirmTransfer( + BigDecimal amountToTransfer, Convert.Unit transferUnit, BigDecimal amountInWei, + String destinationAddress) { + + console.printf("Please confim that you wish to transfer %s %s (%s %s) to address %s%n", + amountToTransfer.stripTrailingZeros().toPlainString(), transferUnit, + amountInWei.stripTrailingZeros().toPlainString(), + Convert.Unit.WEI, destinationAddress); + String confirm = console.readLine("Please type 'yes' to proceed: ").trim(); + if (!confirm.toLowerCase().equals("yes")) { + exitError("OK, some other time perhaps..."); + } + } + + private TransactionReceipt performTransfer( + Web3j web3j, String destinationAddress, Credentials credentials, + BigDecimal amountInWei) { + + console.printf("Commencing transfer (this may take a few minutes) "); + try { + Future future = Transfer.sendFundsAsync( + web3j, credentials, destinationAddress, amountInWei, Convert.Unit.WEI); + + while(!future.isDone()) { + console.printf("."); + Thread.sleep(500); + } + console.printf("$%n%n"); + return future.get(); + } catch (InterruptedException | ExecutionException | TransactionTimeoutException e) { + exitError("Problem encountered transferring funds: \n" + e.getMessage()); + } + throw new RuntimeException("Application exit failure"); + } + + private Web3j getEthereumClient() { + String clientAddress = console.readLine("" + + "Please confirm address of running Ethereum client you wish to send " + + "the transfer request to [" + HttpService.DEFAULT_URL + "]: ") + .trim(); + + Web3j web3j; + if (clientAddress.equals("")) { + web3j = Web3j.build(new HttpService()); + } else if (clientAddress.contains("infura.io")) { + web3j = Web3j.build(new InfuraHttpService(clientAddress)); + } else { + web3j = Web3j.build(new HttpService(clientAddress)); + } + + try { + Web3ClientVersion web3ClientVersion = web3j.web3ClientVersion().sendAsync().get(); + if (web3ClientVersion.hasError()) { + exitError("Unable to process response from client: " + + web3ClientVersion.getError()); + } else { + console.printf("Connected successfully to client: %s%n", + web3ClientVersion.getWeb3ClientVersion()); + return web3j; + } + } catch (InterruptedException | ExecutionException e) { + exitError("Problem encountered verifying client: " + e.getMessage()); + } + throw new RuntimeException("Application exit failure"); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/console/WalletUpdater.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/console/WalletUpdater.java new file mode 100644 index 0000000000..302972c566 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/console/WalletUpdater.java @@ -0,0 +1,66 @@ +package org.web3j.console; + +import java.io.File; +import java.io.IOException; + +import org.web3j.crypto.CipherException; +import org.web3j.crypto.Credentials; +import org.web3j.crypto.WalletUtils; + +import static org.web3j.utils.Console.exitError; + +/** + * Simple class for creating a wallet file. + */ +public class WalletUpdater extends WalletManager { + + public WalletUpdater() { + } + + public WalletUpdater(IODevice console) { + super(console); + } + + public static void main(String[] args) { + if (args.length != 1) { + exitError("You must provide an existing wallet file"); + } else { + new WalletUpdater().run(args[0]); + } + } + + public static void main(IODevice console, String walletFileLocation) { + new WalletUpdater(console).run(walletFileLocation); + } + + private void run(String walletFileLocation) { + File walletFile = new File(walletFileLocation); + Credentials credentials = getCredentials(walletFile); + + console.printf("Wallet for address " + credentials.getAddress() + " loaded\n"); + + String newPassword = getPassword("Please enter a new wallet file password: "); + + String destinationDir = getDestinationDir(); + File destination = createDir(destinationDir); + + try { + String walletFileName = WalletUtils.generateWalletFile( + newPassword, credentials.getEcKeyPair(), destination, true); + console.printf("New wallet file " + walletFileName + + " successfully created in: " + destinationDir + "\n"); + } catch (CipherException|IOException e) { + exitError(e); + } + + String delete = console.readLine( + "Would you like to delete your existing wallet file (Y/N)? [N]: "); + if (delete.toUpperCase().equals("Y")) { + if (!walletFile.delete()) { + exitError("Unable to remove wallet file\n"); + } else { + console.printf("Deleted previous wallet file: %s\n", walletFile.getName()); + } + } + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/crypto/CipherException.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/crypto/CipherException.java new file mode 100644 index 0000000000..d41e283ab0 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/crypto/CipherException.java @@ -0,0 +1,19 @@ +package org.web3j.crypto; + +/** + * Cipher exception wrapper. + */ +public class CipherException extends Exception { + + public CipherException(String message) { + super(message); + } + + public CipherException(Throwable cause) { + super(cause); + } + + public CipherException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/crypto/Credentials.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/crypto/Credentials.java new file mode 100644 index 0000000000..95b8afd9b2 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/crypto/Credentials.java @@ -0,0 +1,58 @@ +package org.web3j.crypto; + +import org.web3j.utils.Numeric; + +/** + * Credentials wrapper + */ +public class Credentials { + + private final ECKeyPair ecKeyPair; + private final String address; + + private Credentials(ECKeyPair ecKeyPair, String address) { + this.ecKeyPair = ecKeyPair; + this.address = address; + } + + public ECKeyPair getEcKeyPair() { + return ecKeyPair; + } + + public String getAddress() { + return address; + } + + public static Credentials create(ECKeyPair ecKeyPair) { + String address = Numeric.prependHexPrefix(Keys.getAddress(ecKeyPair)); + return new Credentials(ecKeyPair, address); + } + + public static Credentials create(String privateKey, String publicKey) { + return create(new ECKeyPair(Numeric.toBigInt(privateKey), Numeric.toBigInt(publicKey))); + } + + public static Credentials create(String privateKey) { + return create(ECKeyPair.create(Numeric.toBigInt(privateKey))); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Credentials that = (Credentials) o; + + if (ecKeyPair != null ? !ecKeyPair.equals(that.ecKeyPair) : that.ecKeyPair != null) + return false; + return address != null ? address.equals(that.address) : that.address == null; + + } + + @Override + public int hashCode() { + int result = ecKeyPair != null ? ecKeyPair.hashCode() : 0; + result = 31 * result + (address != null ? address.hashCode() : 0); + return result; + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/crypto/ECKeyPair.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/crypto/ECKeyPair.java new file mode 100644 index 0000000000..60e672f7fa --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/crypto/ECKeyPair.java @@ -0,0 +1,76 @@ +package org.web3j.crypto; + +import java.math.BigInteger; +import java.security.KeyPair; +import java.util.Arrays; + +import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey; +import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey; + +import org.web3j.utils.Numeric; + +/** + * Elliptic Curve SECP-256k1 generated key pair. + */ +public class ECKeyPair { + private final BigInteger privateKey; + private final BigInteger publicKey; + + public ECKeyPair(BigInteger privateKey, BigInteger publicKey) { + this.privateKey = privateKey; + this.publicKey = publicKey; + } + + public BigInteger getPrivateKey() { + return privateKey; + } + + public BigInteger getPublicKey() { + return publicKey; + } + + + public static ECKeyPair create(KeyPair keyPair) { + BCECPrivateKey privateKey = (BCECPrivateKey) keyPair.getPrivate(); + BCECPublicKey publicKey = (BCECPublicKey) keyPair.getPublic(); + + BigInteger privateKeyValue = privateKey.getD(); + + // Ethereum does not use encoded public keys like bitcoin - see + // https://en.bitcoin.it/wiki/Elliptic_Curve_Digital_Signature_Algorithm for details + // Additionally, as the first bit is a constant prefix (0x04) we ignore this value + byte[] publicKeyBytes = publicKey.getQ().getEncoded(false); + BigInteger publicKeyValue = + new BigInteger(1, Arrays.copyOfRange(publicKeyBytes, 1, publicKeyBytes.length)); + + return new ECKeyPair(privateKeyValue, publicKeyValue); + } + + public static ECKeyPair create(BigInteger privateKey) { + return new ECKeyPair(privateKey, Sign.publicKeyFromPrivate(privateKey)); + } + + public static ECKeyPair create(byte[] privateKey) { + return create(Numeric.toBigInt(privateKey)); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + ECKeyPair ecKeyPair = (ECKeyPair) o; + + if (privateKey != null ? !privateKey.equals(ecKeyPair.privateKey) : ecKeyPair.privateKey != null) + return false; + return publicKey != null ? publicKey.equals(ecKeyPair.publicKey) : ecKeyPair.publicKey == null; + + } + + @Override + public int hashCode() { + int result = privateKey != null ? privateKey.hashCode() : 0; + result = 31 * result + (publicKey != null ? publicKey.hashCode() : 0); + return result; + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/crypto/Hash.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/crypto/Hash.java new file mode 100644 index 0000000000..337b6181e1 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/crypto/Hash.java @@ -0,0 +1,42 @@ +package org.web3j.crypto; + +import org.bouncycastle.jcajce.provider.digest.Keccak; + +import org.web3j.utils.Numeric; + +/** + * Crypto related functions. + */ +public class Hash { + private Hash() { } + + /** + * Keccak-256 hash function + * + * @param hexInput hex encoded input data with optional 0x prefix + * @return hash value as hex encoded string + */ + public static String sha3(String hexInput) { + byte[] bytes = Numeric.hexStringToByteArray(hexInput); + byte[] result = sha3(bytes); + return Numeric.toHexString(result); + } + + /** + * Keccak-256 hash function + * + * @param input binary encoded input data + * @param offset of start of data + * @param length of data + * @return hash value + */ + public static byte[] sha3(byte[] input, int offset, int length) { + Keccak.DigestKeccak kecc = new Keccak.Digest256(); + kecc.update(input, offset, length); + return kecc.digest(); + } + + public static byte[] sha3(byte[] input) { + return sha3(input, 0, input.length); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/crypto/Keys.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/crypto/Keys.java new file mode 100644 index 0000000000..f000a81c08 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/crypto/Keys.java @@ -0,0 +1,104 @@ +package org.web3j.crypto; + +import java.math.BigInteger; +import java.security.InvalidAlgorithmParameterException; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.SecureRandom; +import java.security.Security; +import java.security.spec.ECGenParameterSpec; +import java.util.Arrays; + +import org.bouncycastle.jce.provider.BouncyCastleProvider; + +import org.web3j.utils.Numeric; +import org.web3j.utils.Strings; + + +/** + * Crypto key utilities. + */ +public class Keys { + + static final int PRIVATE_KEY_SIZE = 32; + static final int PUBLIC_KEY_SIZE = 64; + + public static final int ADDRESS_LENGTH_IN_HEX = 40; + static final int PUBLIC_KEY_LENGTH_IN_HEX = PUBLIC_KEY_SIZE << 1; + public static final int PRIVATE_KEY_LENGTH_IN_HEX = PRIVATE_KEY_SIZE << 1; + + static { + Security.addProvider(new BouncyCastleProvider()); + } + + private Keys() { } + + /** + * Create a keypair using SECP-256k1 curve. + * + * Private keypairs are encoded using PKCS8 + * Private keys are encoded using X.509 + */ + static KeyPair createSecp256k1KeyPair() throws NoSuchProviderException, + NoSuchAlgorithmException, InvalidAlgorithmParameterException { + + KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("ECDSA", "BC"); + ECGenParameterSpec ecGenParameterSpec = new ECGenParameterSpec("secp256k1"); + keyPairGenerator.initialize(ecGenParameterSpec, new SecureRandom()); + return keyPairGenerator.generateKeyPair(); + } + + public static ECKeyPair createEcKeyPair() throws InvalidAlgorithmParameterException, + NoSuchAlgorithmException, NoSuchProviderException { + KeyPair keyPair = createSecp256k1KeyPair(); + return ECKeyPair.create(keyPair); + } + + public static String getAddress(ECKeyPair ecKeyPair) { + return getAddress(ecKeyPair.getPublicKey()); + } + + public static String getAddress(BigInteger publicKey) { + return getAddress( + Numeric.toHexStringWithPrefixZeroPadded(publicKey, PUBLIC_KEY_LENGTH_IN_HEX)); + } + + public static String getAddress(String publicKey) { + String publicKeyNoPrefix = Numeric.cleanHexPrefix(publicKey); + + if (publicKeyNoPrefix.length() < PUBLIC_KEY_LENGTH_IN_HEX) { + publicKeyNoPrefix = Strings.zeros( + PUBLIC_KEY_LENGTH_IN_HEX - publicKeyNoPrefix.length()) + + publicKeyNoPrefix; + } + String hash = Hash.sha3(publicKeyNoPrefix); + return hash.substring(hash.length() - ADDRESS_LENGTH_IN_HEX); // right most 160 bits + } + + public static byte[] getAddress(byte[] publicKey) { + byte[] hash = Hash.sha3(publicKey); + return Arrays.copyOfRange(hash, hash.length - 20, hash.length); // right most 160 bits + } + + public static byte[] serialize(ECKeyPair ecKeyPair) { + byte[] privateKey = Numeric.toBytesPadded(ecKeyPair.getPrivateKey(), PRIVATE_KEY_SIZE); + byte[] publicKey = Numeric.toBytesPadded(ecKeyPair.getPublicKey(), PUBLIC_KEY_SIZE); + + byte[] result = Arrays.copyOf(privateKey, PRIVATE_KEY_SIZE + PUBLIC_KEY_SIZE); + System.arraycopy(publicKey, 0, result, PRIVATE_KEY_SIZE, PUBLIC_KEY_SIZE); + return result; + } + + public static ECKeyPair deserialize(byte[] input) { + if (input.length != PRIVATE_KEY_SIZE + PUBLIC_KEY_SIZE) { + throw new RuntimeException("Invalid input key size"); + } + + BigInteger privateKey = Numeric.toBigInt(input, 0, PRIVATE_KEY_SIZE); + BigInteger publicKey = Numeric.toBigInt(input, PRIVATE_KEY_SIZE, PUBLIC_KEY_SIZE); + + return new ECKeyPair(privateKey, publicKey); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/crypto/Sign.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/crypto/Sign.java new file mode 100644 index 0000000000..1e77ece39e --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/crypto/Sign.java @@ -0,0 +1,311 @@ +package org.web3j.crypto; + +import java.math.BigInteger; +import java.security.SignatureException; +import java.util.Arrays; + +import org.bouncycastle.asn1.x9.X9ECParameters; +import org.bouncycastle.asn1.x9.X9IntegerConverter; +import org.bouncycastle.crypto.digests.SHA256Digest; +import org.bouncycastle.crypto.ec.CustomNamedCurves; +import org.bouncycastle.crypto.params.ECDomainParameters; +import org.bouncycastle.crypto.params.ECPrivateKeyParameters; +import org.bouncycastle.crypto.signers.ECDSASigner; +import org.bouncycastle.crypto.signers.HMacDSAKCalculator; +import org.bouncycastle.math.ec.ECAlgorithms; +import org.bouncycastle.math.ec.ECPoint; +import org.bouncycastle.math.ec.FixedPointCombMultiplier; +import org.bouncycastle.math.ec.custom.sec.SecP256K1Curve; + +import org.web3j.utils.Numeric; + +/** + *

Transaction signing logic.

+ * + *

Adapted from the + * + * BitcoinJ ECKey implementation. + */ +public class Sign { + + private static final X9ECParameters CURVE_PARAMS = CustomNamedCurves.getByName("secp256k1"); + private static final ECDomainParameters CURVE = new ECDomainParameters( + CURVE_PARAMS.getCurve(), CURVE_PARAMS.getG(), CURVE_PARAMS.getN(), CURVE_PARAMS.getH()); + private static final BigInteger HALF_CURVE_ORDER = CURVE_PARAMS.getN().shiftRight(1); + + public static SignatureData signMessage(byte[] message, ECKeyPair keyPair) { + BigInteger privateKey = keyPair.getPrivateKey(); + BigInteger publicKey = keyPair.getPublicKey(); + + byte[] messageHash = Hash.sha3(message); + + ECDSASignature sig = sign(messageHash, privateKey); + // Now we have to work backwards to figure out the recId needed to recover the signature. + int recId = -1; + for (int i = 0; i < 4; i++) { + BigInteger k = recoverFromSignature(i, sig, messageHash); + if (k != null && k.equals(publicKey)) { + recId = i; + break; + } + } + if (recId == -1) + throw new RuntimeException( + "Could not construct a recoverable key. This should never happen."); + int headerByte = recId + 27; + + // 1 header + 32 bytes for R + 32 bytes for S + byte v = (byte) headerByte; + byte[] r = Numeric.toBytesPadded(sig.r, 32); + byte[] s = Numeric.toBytesPadded(sig.s, 32); + + return new SignatureData(v, r, s); + } + + private static ECDSASignature sign(byte[] transactionHash, BigInteger privateKey) { + ECDSASigner signer = new ECDSASigner(new HMacDSAKCalculator(new SHA256Digest())); + + ECPrivateKeyParameters privKey = new ECPrivateKeyParameters(privateKey, CURVE); + signer.init(true, privKey); + BigInteger[] components = signer.generateSignature(transactionHash); + + return new ECDSASignature(components[0], components[1]).toCanonicalised(); + } + + /** + *

Given the components of a signature and a selector value, recover and return the public + * key that generated the signature according to the algorithm in SEC1v2 section 4.1.6.

+ * + *

The recId is an index from 0 to 3 which indicates which of the 4 possible keys is the + * correct one. Because the key recovery operation yields multiple potential keys, the correct + * key must either be stored alongside the + * signature, or you must be willing to try each recId in turn until you find one that outputs + * the key you are expecting.

+ * + *

If this method returns null it means recovery was not possible and recId should be + * iterated.

+ * + *

Given the above two points, a correct usage of this method is inside a for loop from + * 0 to 3, and if the output is null OR a key that is not the one you expect, you try again + * with the next recId.

+ * + * @param recId Which possible key to recover. + * @param sig the R and S components of the signature, wrapped. + * @param message Hash of the data that was signed. + * @return An ECKey containing only the public part, or null if recovery wasn't possible. + */ + private static BigInteger recoverFromSignature(int recId, ECDSASignature sig, byte[] message) { + verifyPrecondition(recId >= 0, "recId must be positive"); + verifyPrecondition(sig.r.signum() >= 0, "r must be positive"); + verifyPrecondition(sig.s.signum() >= 0, "s must be positive"); + verifyPrecondition(message != null, "message cannot be null"); + + // 1.0 For j from 0 to h (h == recId here and the loop is outside this function) + // 1.1 Let x = r + jn + BigInteger n = CURVE.getN(); // Curve order. + BigInteger i = BigInteger.valueOf((long) recId / 2); + BigInteger x = sig.r.add(i.multiply(n)); + // 1.2. Convert the integer x to an octet string X of length mlen using the conversion + // routine specified in Section 2.3.7, where mlen = ⌈(log2 p)/8⌉ or mlen = ⌈m/8⌉. + // 1.3. Convert the octet string (16 set binary digits)||X to an elliptic curve point R + // using the conversion routine specified in Section 2.3.4. If this conversion + // routine outputs “invalid”, then do another iteration of Step 1. + // + // More concisely, what these points mean is to use X as a compressed public key. + BigInteger prime = SecP256K1Curve.q; + if (x.compareTo(prime) >= 0) { + // Cannot have point co-ordinates larger than this as everything takes place modulo Q. + return null; + } + // Compressed keys require you to know an extra bit of data about the y-coord as there are + // two possibilities. So it's encoded in the recId. + ECPoint R = decompressKey(x, (recId & 1) == 1); + // 1.4. If nR != point at infinity, then do another iteration of Step 1 (callers + // responsibility). + if (!R.multiply(n).isInfinity()) + return null; + // 1.5. Compute e from M using Steps 2 and 3 of ECDSA signature verification. + BigInteger e = new BigInteger(1, message); + // 1.6. For k from 1 to 2 do the following. (loop is outside this function via + // iterating recId) + // 1.6.1. Compute a candidate public key as: + // Q = mi(r) * (sR - eG) + // + // Where mi(x) is the modular multiplicative inverse. We transform this into the following: + // Q = (mi(r) * s ** R) + (mi(r) * -e ** G) + // Where -e is the modular additive inverse of e, that is z such that z + e = 0 (mod n). + // In the above equation ** is point multiplication and + is point addition (the EC group + // operator). + // + // We can find the additive inverse by subtracting e from zero then taking the mod. For + // example the additive inverse of 3 modulo 11 is 8 because 3 + 8 mod 11 = 0, and + // -3 mod 11 = 8. + BigInteger eInv = BigInteger.ZERO.subtract(e).mod(n); + BigInteger rInv = sig.r.modInverse(n); + BigInteger srInv = rInv.multiply(sig.s).mod(n); + BigInteger eInvrInv = rInv.multiply(eInv).mod(n); + ECPoint q = ECAlgorithms.sumOfTwoMultiplies(CURVE.getG(), eInvrInv, R, srInv); + + byte[] qBytes = q.getEncoded(false); + // We remove the prefix + return new BigInteger(1, Arrays.copyOfRange(qBytes, 1, qBytes.length)); + } + + private static void verifyPrecondition(boolean assertionResult, String errorMessage) { + if (!assertionResult) { + throw new RuntimeException(errorMessage); + } + } + + /** Decompress a compressed public key (x co-ord and low-bit of y-coord). */ + private static ECPoint decompressKey(BigInteger xBN, boolean yBit) { + X9IntegerConverter x9 = new X9IntegerConverter(); + byte[] compEnc = x9.integerToBytes(xBN, 1 + x9.getByteLength(CURVE.getCurve())); + compEnc[0] = (byte)(yBit ? 0x03 : 0x02); + return CURVE.getCurve().decodePoint(compEnc); + } + + /** + * Given an arbitrary piece of text and an Ethereum message signature encoded in bytes, + * returns the public key that was used to sign it. This can then be compared to the expected + * public key to determine if the signature was correct. + * + * @param message RLP encoded message. + * @param signatureData The message signature components + * @return the public key used to sign the message + * @throws SignatureException If the public key could not be recovered or if there was a + * signature format error. + */ + public static BigInteger signedMessageToKey( + byte[] message, SignatureData signatureData) throws SignatureException { + int header = signatureData.getV() & 0xFF; + // The header byte: 0x1B = first key with even y, 0x1C = first key with odd y, + // 0x1D = second key with even y, 0x1E = second key with odd y + if (header < 27 || header > 34) + throw new SignatureException("Header byte out of range: " + header); + BigInteger r = new BigInteger(1, signatureData.getR()); + BigInteger s = new BigInteger(1, signatureData.getS()); + ECDSASignature sig = new ECDSASignature(r, s); + + byte[] messageHash = Hash.sha3(message); + int recId = header - 27; + BigInteger key = recoverFromSignature(recId, sig, messageHash); + if (key == null) + throw new SignatureException("Could not recover public key from signature"); + return key; + } + + /** + * Returns public key from the given private key. + * + * @param privKey the private key to derive the public key from + * @return BigInteger encoded public key + */ + public static BigInteger publicKeyFromPrivate(BigInteger privKey) { + ECPoint point = publicPointFromPrivate(privKey); + + byte[] encoded = point.getEncoded(false); + return new BigInteger(1, Arrays.copyOfRange(encoded, 1, encoded.length)); // remove prefix + } + + /** + * Returns public key point from the given private key. + */ + private static ECPoint publicPointFromPrivate(BigInteger privKey) { + /* + * TODO: FixedPointCombMultiplier currently doesn't support scalars longer than the group + * order, but that could change in future versions. + */ + if (privKey.bitLength() > CURVE.getN().bitLength()) { + privKey = privKey.mod(CURVE.getN()); + } + return new FixedPointCombMultiplier().multiply(CURVE.getG(), privKey); + } + + private static class ECDSASignature { + private final BigInteger r; + private final BigInteger s; + + ECDSASignature(BigInteger r, BigInteger s) { + this.r = r; + this.s = s; + } + + /** + * Returns true if the S component is "low", that means it is below + * {@link Sign#HALF_CURVE_ORDER}. See + * + * BIP62. + */ + public boolean isCanonical() { + return s.compareTo(HALF_CURVE_ORDER) <= 0; + } + + /** + * Will automatically adjust the S component to be less than or equal to half the curve + * order, if necessary. This is required because for every signature (r,s) the signature + * (r, -s (mod N)) is a valid signature of the same message. However, we dislike the + * ability to modify the bits of a Bitcoin transaction after it's been signed, as that + * violates various assumed invariants. Thus in future only one of those forms will be + * considered legal and the other will be banned. + */ + public ECDSASignature toCanonicalised() { + if (!isCanonical()) { + // The order of the curve is the number of valid points that exist on that curve. + // If S is in the upper half of the number of valid points, then bring it back to + // the lower half. Otherwise, imagine that + // N = 10 + // s = 8, so (-8 % 10 == 2) thus both (r, 8) and (r, 2) are valid solutions. + // 10 - 8 == 2, giving us always the latter solution, which is canonical. + return new ECDSASignature(r, CURVE.getN().subtract(s)); + } else { + return this; + } + } + } + + public static class SignatureData { + private final byte v; + private final byte[] r; + private final byte[] s; + + public SignatureData(byte v, byte[] r, byte[] s) { + this.v = v; + this.r = r; + this.s = s; + } + + public byte getV() { + return v; + } + + public byte[] getR() { + return r; + } + + public byte[] getS() { + return s; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + SignatureData that = (SignatureData) o; + + if (v != that.v) return false; + if (!Arrays.equals(r, that.r)) return false; + return Arrays.equals(s, that.s); + + } + + @Override + public int hashCode() { + int result = (int) v; + result = 31 * result + Arrays.hashCode(r); + result = 31 * result + Arrays.hashCode(s); + return result; + } + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/crypto/TransactionEncoder.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/crypto/TransactionEncoder.java new file mode 100644 index 0000000000..dc2c1b9ad8 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/crypto/TransactionEncoder.java @@ -0,0 +1,91 @@ +package org.web3j.crypto; + +import java.util.ArrayList; +import java.util.List; + +import org.web3j.protocol.core.methods.request.RawTransaction; +import org.web3j.rlp.RlpEncoder; +import org.web3j.rlp.RlpList; +import org.web3j.rlp.RlpString; +import org.web3j.rlp.RlpType; +import org.web3j.utils.Numeric; + +/** + * Create RLP encoded transaction, implementation as per p4 of the + * yellow paper. + */ +public class TransactionEncoder { + + public static byte[] signMessage(RawTransaction rawTransaction, Credentials credentials) { + byte[] encodedTransaction = encode(rawTransaction); + Sign.SignatureData signatureData = Sign.signMessage( + encodedTransaction, credentials.getEcKeyPair()); + + return encode(rawTransaction, signatureData); + } + + public static byte[] signMessage( + RawTransaction rawTransaction, byte chainId, Credentials credentials) { + byte[] encodedTransaction = encode(rawTransaction, chainId); + Sign.SignatureData signatureData = Sign.signMessage( + encodedTransaction, credentials.getEcKeyPair()); + + Sign.SignatureData eip155SignatureData = createEip155SignatureData(signatureData, chainId); + return encode(rawTransaction, eip155SignatureData); + } + + public static Sign.SignatureData createEip155SignatureData( + Sign.SignatureData signatureData, byte chainId) { + byte v = (byte) (signatureData.getV() + (chainId << 1) + 8); + + return new Sign.SignatureData( + v, signatureData.getR(), signatureData.getS()); + } + + public static byte[] encode(RawTransaction rawTransaction) { + return encode(rawTransaction, null); + } + + public static byte[] encode(RawTransaction rawTransaction, byte chainId) { + Sign.SignatureData signatureData = new Sign.SignatureData( + chainId, new byte[] {}, new byte[] {}); + return encode(rawTransaction, signatureData); + } + + private static byte[] encode(RawTransaction rawTransaction, Sign.SignatureData signatureData) { + List values = asRlpValues(rawTransaction, signatureData); + RlpList rlpList = new RlpList(values); + return RlpEncoder.encode(rlpList); + } + + static List asRlpValues( + RawTransaction rawTransaction, Sign.SignatureData signatureData) { + List result = new ArrayList<>(); + + result.add(RlpString.create(rawTransaction.getNonce())); + result.add(RlpString.create(rawTransaction.getGasPrice())); + result.add(RlpString.create(rawTransaction.getGasLimit())); + + // an empty to address (contract creation) should not be encoded as a numeric 0 value + String to = rawTransaction.getTo(); + if (to != null && to.length() > 0) { + result.add(RlpString.create(Numeric.toBigInt(to))); + } else { + result.add(RlpString.create("")); + } + + result.add(RlpString.create(rawTransaction.getValue())); + + // value field will already be hex encoded, so we need to convert into binary first + byte[] data = Numeric.hexStringToByteArray(rawTransaction.getData()); + result.add(RlpString.create(data)); + + if (signatureData != null) { + result.add(RlpString.create(signatureData.getV())); + result.add(RlpString.create(signatureData.getR())); + result.add(RlpString.create(signatureData.getS())); + } + + return result; + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/crypto/Wallet.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/crypto/Wallet.java new file mode 100644 index 0000000000..58bb4dbdc5 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/crypto/Wallet.java @@ -0,0 +1,250 @@ +package org.web3j.crypto; + +import java.security.GeneralSecurityException; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.util.Arrays; +import java.util.UUID; +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; + +import com.lambdaworks.crypto.SCrypt; +import org.bouncycastle.crypto.digests.SHA256Digest; +import org.bouncycastle.crypto.generators.PKCS5S2ParametersGenerator; +import org.bouncycastle.crypto.params.KeyParameter; + +import org.web3j.utils.Numeric; + +import static java.nio.charset.StandardCharsets.UTF_8; + +/** + *

Ethereum wallet file management. For reference, refer to + * + * Web3 Secret Storage Definition or the + * + * Go Ethereum client implementation.

+ * + *

Note: we don't use the Bouncy Castle Scrypt implementation + * {@link org.bouncycastle.crypto.generators.SCrypt}, as the following parameter assertion results + * in failure of the Ethereum reference + * + * Scrypt test vector:

+ * + *
+ * {@code
+ * // Only value of r that cost (as an int) could be exceeded for is 1
+ * if (r == 1 && N_STANDARD > 65536)
+ * {
+ *     throw new IllegalArgumentException("Cost parameter N_STANDARD must be > 1 and < 65536.");
+ * }
+ * }
+ * 
+ */ +public class Wallet { + + private static SecureRandom SECURE_RANDOM = new SecureRandom(); + + private static final int N_LIGHT = 1 << 12; + private static final int P_LIGHT = 6; + + private static final int N_STANDARD = 1 << 18; + private static final int P_STANDARD = 1; + + private static final int R = 8; + private static final int DKLEN = 32; + + private static final int CURRENT_VERSION = 3; + + private static final String CIPHER = "aes-128-ctr"; + static final String AES_128_CTR = "pbkdf2"; + static final String SCRYPT = "scrypt"; + + public static WalletFile create(String password, ECKeyPair ecKeyPair, int n, int p) + throws CipherException { + + byte[] salt = generateRandomBytes(32); + + byte[] derivedKey = generateDerivedScryptKey( + password.getBytes(UTF_8), salt, n, R, p, DKLEN); + + byte[] encryptKey = Arrays.copyOfRange(derivedKey, 0, 16); + byte[] iv = generateRandomBytes(16); + + byte[] privateKeyBytes = + Numeric.toBytesPadded(ecKeyPair.getPrivateKey(), Keys.PRIVATE_KEY_SIZE); + + byte[] cipherText = performCipherOperation( + Cipher.ENCRYPT_MODE, iv, encryptKey, privateKeyBytes); + + byte[] mac = generateMac(derivedKey, cipherText); + + return createWalletFile(ecKeyPair, cipherText, iv, salt, mac, n, p); + } + + public static WalletFile createStandard(String password, ECKeyPair ecKeyPair) + throws CipherException { + return create(password, ecKeyPair, N_STANDARD, P_STANDARD); + } + + public static WalletFile createLight(String password, ECKeyPair ecKeyPair) + throws CipherException { + return create(password, ecKeyPair, N_LIGHT, P_LIGHT); + } + + private static WalletFile createWalletFile( + ECKeyPair ecKeyPair, byte[] cipherText, byte[] iv, byte[] salt, byte[] mac, + int n, int p) { + + WalletFile walletFile = new WalletFile(); + walletFile.setAddress(Keys.getAddress(ecKeyPair)); + + WalletFile.Crypto crypto = new WalletFile.Crypto(); + crypto.setCipher(CIPHER); + crypto.setCiphertext(Numeric.toHexStringNoPrefix(cipherText)); + walletFile.setCrypto(crypto); + + WalletFile.CipherParams cipherParams = new WalletFile.CipherParams(); + cipherParams.setIv(Numeric.toHexStringNoPrefix(iv)); + crypto.setCipherparams(cipherParams); + + crypto.setKdf(SCRYPT); + WalletFile.ScryptKdfParams kdfParams = new WalletFile.ScryptKdfParams(); + kdfParams.setDklen(DKLEN); + kdfParams.setN(n); + kdfParams.setP(p); + kdfParams.setR(R); + kdfParams.setSalt(Numeric.toHexStringNoPrefix(salt)); + crypto.setKdfparams(kdfParams); + + crypto.setMac(Numeric.toHexStringNoPrefix(mac)); + walletFile.setCrypto(crypto); + walletFile.setId(UUID.randomUUID().toString()); + walletFile.setVersion(CURRENT_VERSION); + + return walletFile; + } + + private static byte[] generateDerivedScryptKey( + byte[] password, byte[] salt, int n, int r, int p, int dkLen) throws CipherException { + try { + return SCrypt.scrypt(password, salt, n, r, p, dkLen); + } catch (GeneralSecurityException e) { + throw new CipherException(e); + } + } + + private static byte[] generateAes128CtrDerivedKey( + byte[] password, byte[] salt, int c, String prf) throws CipherException { + + if (!prf.equals("hmac-sha256")) { + throw new CipherException("Unsupported prf:" + prf); + } + + // Java 8 supports this, but you have to convert the password to a character array, see + // http://stackoverflow.com/a/27928435/3211687 + + PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator(new SHA256Digest()); + gen.init(password, salt, c); + return ((KeyParameter) gen.generateDerivedParameters(256)).getKey(); + } + + private static byte[] performCipherOperation( + int mode, byte[] iv, byte[] encryptKey, byte[] text) throws CipherException { + + try { + IvParameterSpec ivParameterSpec = new IvParameterSpec(iv); + Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding"); + + SecretKeySpec secretKeySpec = new SecretKeySpec(encryptKey, "AES"); + cipher.init(mode, secretKeySpec, ivParameterSpec); + return cipher.doFinal(text); + } catch (NoSuchPaddingException|NoSuchAlgorithmException| + InvalidAlgorithmParameterException|InvalidKeyException| + BadPaddingException|IllegalBlockSizeException e) { + throw new CipherException("Error performing cipher operation", e); + } + } + + private static byte[] generateMac(byte[] derivedKey, byte[] cipherText) { + byte[] result = new byte[16 + cipherText.length]; + + System.arraycopy(derivedKey, 16, result, 0, 16); + System.arraycopy(cipherText, 0, result, 16, cipherText.length); + + return Hash.sha3(result); + } + + public static ECKeyPair decrypt(String password, WalletFile walletFile) + throws CipherException { + + validate(walletFile); + + WalletFile.Crypto crypto = walletFile.getCrypto(); + + byte[] mac = Numeric.hexStringToByteArray(crypto.getMac()); + byte[] iv = Numeric.hexStringToByteArray(crypto.getCipherparams().getIv()); + byte[] cipherText = Numeric.hexStringToByteArray(crypto.getCiphertext()); + + byte[] derivedKey; + + WalletFile.KdfParams kdfParams = crypto.getKdfparams(); + if (kdfParams instanceof WalletFile.ScryptKdfParams) { + WalletFile.ScryptKdfParams scryptKdfParams = + (WalletFile.ScryptKdfParams) crypto.getKdfparams(); + int dklen = scryptKdfParams.getDklen(); + int n = scryptKdfParams.getN(); + int p = scryptKdfParams.getP(); + int r = scryptKdfParams.getR(); + byte[] salt = Numeric.hexStringToByteArray(scryptKdfParams.getSalt()); + derivedKey = generateDerivedScryptKey(password.getBytes(UTF_8), salt, n, r, p, dklen); + } else if (kdfParams instanceof WalletFile.Aes128CtrKdfParams) { + WalletFile.Aes128CtrKdfParams aes128CtrKdfParams = + (WalletFile.Aes128CtrKdfParams) crypto.getKdfparams(); + int c = aes128CtrKdfParams.getC(); + String prf = aes128CtrKdfParams.getPrf(); + byte[] salt = Numeric.hexStringToByteArray(aes128CtrKdfParams.getSalt()); + + derivedKey = generateAes128CtrDerivedKey(password.getBytes(UTF_8), salt, c, prf); + } else { + throw new CipherException("Unable to deserialize params: " + crypto.getKdf()); + } + + byte[] derivedMac = generateMac(derivedKey, cipherText); + + if (!Arrays.equals(derivedMac, mac)) { + throw new CipherException("Invalid password provided"); + } + + byte[] encryptKey = Arrays.copyOfRange(derivedKey, 0, 16); + byte[] privateKey = performCipherOperation(Cipher.DECRYPT_MODE, iv, encryptKey, cipherText); + return ECKeyPair.create(privateKey); + } + + static void validate(WalletFile walletFile) throws CipherException { + WalletFile.Crypto crypto = walletFile.getCrypto(); + + if (walletFile.getVersion() != CURRENT_VERSION) { + throw new CipherException("Wallet version is not supported"); + } + + if (!crypto.getCipher().equals(CIPHER)) { + throw new CipherException("Wallet cipher is not supported"); + } + + if (!crypto.getKdf().equals(AES_128_CTR) && !crypto.getKdf().equals(SCRYPT)) { + throw new CipherException("KDF type is not supported"); + } + } + + static byte[] generateRandomBytes(int size) { + byte[] bytes = new byte[size]; + SECURE_RANDOM.nextBytes(bytes); + return bytes; + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/crypto/WalletFile.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/crypto/WalletFile.java new file mode 100644 index 0000000000..9858db0343 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/crypto/WalletFile.java @@ -0,0 +1,278 @@ +package org.web3j.crypto; + + +import java.io.IOException; + +import com.fasterxml.jackson.annotation.JsonSetter; +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; + +/** + * Ethereum wallet file. + */ +public class WalletFile { + private String address; + private Crypto crypto; + private String id; + private int version; + + public WalletFile() { + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public Crypto getCrypto() { + return crypto; + } + + @JsonSetter("crypto") + public void setCrypto(Crypto crypto) { + this.crypto = crypto; + } + + @JsonSetter("Crypto") // older wallet files may have this attribute name + public void setCryptoV1(Crypto crypto) { + setCrypto(crypto); + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public int getVersion() { + return version; + } + + public void setVersion(int version) { + this.version = version; + } + + public static class Crypto { + private String cipher; + private String ciphertext; + private CipherParams cipherparams; + + private String kdf; + private KdfParams kdfparams; + + private String mac; + + public Crypto() { + } + + public String getCipher() { + return cipher; + } + + public void setCipher(String cipher) { + this.cipher = cipher; + } + + public String getCiphertext() { + return ciphertext; + } + + public void setCiphertext(String ciphertext) { + this.ciphertext = ciphertext; + } + + public CipherParams getCipherparams() { + return cipherparams; + } + + public void setCipherparams(CipherParams cipherparams) { + this.cipherparams = cipherparams; + } + + public String getKdf() { + return kdf; + } + + public void setKdf(String kdf) { + this.kdf = kdf; + } + + public KdfParams getKdfparams() { + return kdfparams; + } + + @JsonTypeInfo( + use=JsonTypeInfo.Id.NAME, + include=JsonTypeInfo.As.EXTERNAL_PROPERTY, + property="kdf") + @JsonSubTypes({ + @JsonSubTypes.Type(value = Aes128CtrKdfParams.class, name = Wallet.AES_128_CTR), + @JsonSubTypes.Type(value = ScryptKdfParams.class, name = Wallet.SCRYPT) + }) + // To support my Ether Wallet keys uncomment this annotation & comment out the above +// @JsonDeserialize(using = KdfParamsDeserialiser.class) + // Also add the following to the ObjectMapperFactory + // objectMapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true); + public void setKdfparams(KdfParams kdfparams) { + this.kdfparams = kdfparams; + } + + public String getMac() { + return mac; + } + + public void setMac(String mac) { + this.mac = mac; + } + } + + public static class CipherParams { + private String iv; + + public CipherParams() { + } + + public String getIv() { + return iv; + } + + public void setIv(String iv) { + this.iv = iv; + } + } + + interface KdfParams { + int getDklen(); + String getSalt(); + } + + public static class Aes128CtrKdfParams implements KdfParams { + private int dklen; + private int c; + private String prf; + private String salt; + + public Aes128CtrKdfParams() { + } + + public int getDklen() { + return dklen; + } + + public void setDklen(int dklen) { + this.dklen = dklen; + } + + public int getC() { + return c; + } + + public void setC(int c) { + this.c = c; + } + + public String getPrf() { + return prf; + } + + public void setPrf(String prf) { + this.prf = prf; + } + + public String getSalt() { + return salt; + } + + public void setSalt(String salt) { + this.salt = salt; + } + } + + public static class ScryptKdfParams implements KdfParams { + private int dklen; + private int n; + private int p; + private int r; + private String salt; + + public ScryptKdfParams() { + } + + public int getDklen() { + return dklen; + } + + public void setDklen(int dklen) { + this.dklen = dklen; + } + + public int getN() { + return n; + } + + public void setN(int n) { + this.n = n; + } + + public int getP() { + return p; + } + + public void setP(int p) { + this.p = p; + } + + public int getR() { + return r; + } + + public void setR(int r) { + this.r = r; + } + + public String getSalt() { + return salt; + } + + public void setSalt(String salt) { + this.salt = salt; + } + } + + // If we need to work with MyEtherWallet we'll need to use this deserializer, see the + // following issue https://github.com/kvhnuke/etherwallet/issues/269 + static class KdfParamsDeserialiser extends JsonDeserializer { + + @Override + public KdfParams deserialize( + JsonParser jsonParser, DeserializationContext deserializationContext) + throws IOException { + + ObjectMapper objectMapper = (ObjectMapper) jsonParser.getCodec(); + ObjectNode root = objectMapper.readTree(jsonParser); + KdfParams kdfParams; + + // it would be preferable to detect the class to use based on the kdf parameter in the + // container object instance + JsonNode n = root.get("n"); + if (n == null) { + kdfParams = objectMapper.convertValue(root, Aes128CtrKdfParams.class); + } else { + kdfParams = objectMapper.convertValue(root, ScryptKdfParams.class); + } + + return kdfParams; + } + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/crypto/WalletUtils.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/crypto/WalletUtils.java new file mode 100644 index 0000000000..c6a6b3a783 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/crypto/WalletUtils.java @@ -0,0 +1,122 @@ +package org.web3j.crypto; + +import java.io.File; +import java.io.IOException; +import java.security.InvalidAlgorithmParameterException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import org.web3j.protocol.ObjectMapperFactory; +import org.web3j.utils.Numeric; + +import static org.web3j.crypto.Keys.ADDRESS_LENGTH_IN_HEX; +import static org.web3j.crypto.Keys.PRIVATE_KEY_LENGTH_IN_HEX; + +/** + * Utility functions for working with Wallet files. + */ +public class WalletUtils { + + public static String generateFullNewWalletFile(String password, File destinationDirectory) + throws NoSuchAlgorithmException, NoSuchProviderException, + InvalidAlgorithmParameterException, CipherException, IOException { + + return generateNewWalletFile(password, destinationDirectory, true); + } + + public static String generateLightNewWalletFile(String password, File destinationDirectory) + throws NoSuchAlgorithmException, NoSuchProviderException, + InvalidAlgorithmParameterException, CipherException, IOException { + + return generateNewWalletFile(password, destinationDirectory, false); + } + + public static String generateNewWalletFile( + String password, File destinationDirectory, boolean useFullScrypt) + throws CipherException, IOException, InvalidAlgorithmParameterException, + NoSuchAlgorithmException, NoSuchProviderException { + + ECKeyPair ecKeyPair = Keys.createEcKeyPair(); + return generateWalletFile(password, ecKeyPair, destinationDirectory, useFullScrypt); + } + + public static String generateWalletFile( + String password, ECKeyPair ecKeyPair, File destinationDirectory, boolean useFullScrypt) + throws CipherException, IOException { + + WalletFile walletFile; + if (useFullScrypt) { + walletFile = Wallet.createStandard(password, ecKeyPair); + } else { + walletFile = Wallet.createLight(password, ecKeyPair); + } + + String fileName = getWalletFileName(walletFile); + File destination = new File(destinationDirectory, fileName); + + ObjectMapper objectMapper = ObjectMapperFactory.getObjectMapper(); + objectMapper.writeValue(destination, walletFile); + + return fileName; + } + + public static Credentials loadCredentials(String password, String source) + throws IOException, CipherException { + return loadCredentials(password, new File(source)); + } + + public static Credentials loadCredentials(String password, File source) + throws IOException, CipherException { + ObjectMapper objectMapper = ObjectMapperFactory.getObjectMapper(); + WalletFile walletFile = objectMapper.readValue(source, WalletFile.class); + return Credentials.create(Wallet.decrypt(password, walletFile)); + } + + private static String getWalletFileName(WalletFile walletFile) { + DateTimeFormatter format = DateTimeFormatter.ofPattern( + "'UTC--'yyyy-MM-dd'T'HH-mm-ss.nVV'--'"); + ZonedDateTime now = ZonedDateTime.now(ZoneOffset.UTC); + + return now.format(format) + walletFile.getAddress() + ".json"; + } + + public static String getDefaultKeyDirectory() { + return getDefaultKeyDirectory(System.getProperty("os.name")); + } + + static String getDefaultKeyDirectory(String osName1) { + String osName = osName1.toLowerCase(); + + if (osName.startsWith("mac")) { + return String.format("%s%sLibrary%sEthereum", + System.getProperty("user.home"), File.separator, File.separator); + } else if (osName.startsWith("win")) { + return String.format("%s%sEthereum", System.getenv("APPDATA"), File.separator); + } else { + return String.format("%s%s.ethereum", System.getProperty("user.home"), File.separator); + } + } + + public static String getTestnetKeyDirectory() { + return String.format("%s%stestnet%skeystore", getDefaultKeyDirectory(), File.separator, File.separator); + } + + public static String getMainnetKeyDirectory() { + return String.format("%s%skeystore", getDefaultKeyDirectory(), File.separator); + } + + public static boolean isValidPrivateKey(String privateKey) { + String cleanPrivateKey = Numeric.cleanHexPrefix(privateKey); + return cleanPrivateKey.length() == PRIVATE_KEY_LENGTH_IN_HEX; + } + + public static boolean isValidAddress(String address) { + String addressNoPrefix = Numeric.cleanHexPrefix(address); + return addressNoPrefix.length() == ADDRESS_LENGTH_IN_HEX; + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/ObjectMapperFactory.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/ObjectMapperFactory.java new file mode 100644 index 0000000000..6b05ef22e4 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/ObjectMapperFactory.java @@ -0,0 +1,27 @@ +package org.web3j.protocol; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ObjectReader; + +/** + * Factory for managing our ObjectMapper instances. + */ +public class ObjectMapperFactory { + + private static final ObjectMapper objectMapper = new ObjectMapper(); + + static { + objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true); + objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + } + + public static ObjectMapper getObjectMapper() { + return objectMapper; + } + + public static ObjectReader getObjectReader() { + return objectMapper.reader(); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/Service.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/Service.java new file mode 100644 index 0000000000..20f3a10c0b --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/Service.java @@ -0,0 +1,23 @@ +package org.web3j.protocol; + +import java.util.concurrent.CompletableFuture; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import org.web3j.protocol.core.Request; +import org.web3j.protocol.core.Response; +import org.web3j.utils.Async; + +/** + * Base service implementation + */ +public abstract class Service implements Web3jService{ + + protected final ObjectMapper objectMapper = ObjectMapperFactory.getObjectMapper(); + + @Override + public CompletableFuture sendAsync( + Request jsonRpc20Request, Class responseType) { + return Async.run(() -> send(jsonRpc20Request, responseType)); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/Web3j.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/Web3j.java new file mode 100644 index 0000000000..037696862d --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/Web3j.java @@ -0,0 +1,21 @@ +package org.web3j.protocol; + +import java.util.concurrent.ExecutorService; + +import org.web3j.protocol.core.Ethereum; +import org.web3j.protocol.core.JsonRpc2_0Web3j; +import org.web3j.protocol.rx.Web3jRx; + +/** + * JSON-RPC Request object building factory. + */ +public interface Web3j extends Ethereum, Web3jRx { + static Web3j build(Web3jService web3jService) { + return new JsonRpc2_0Web3j(web3jService); + } + + static Web3j build( + Web3jService web3jService, long pollingInterval, ExecutorService executorService) { + return new JsonRpc2_0Web3j(web3jService, pollingInterval, executorService); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/Web3jService.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/Web3jService.java new file mode 100644 index 0000000000..cf76802aeb --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/Web3jService.java @@ -0,0 +1,18 @@ +package org.web3j.protocol; + +import java.io.IOException; +import java.util.concurrent.CompletableFuture; + +import org.web3j.protocol.core.Request; +import org.web3j.protocol.core.Response; + +/** + * Services API. + */ +public interface Web3jService { + T send( + Request request, Class responseType) throws IOException; + + CompletableFuture sendAsync( + Request request, Class responseType); +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/DefaultBlockParameter.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/DefaultBlockParameter.java new file mode 100644 index 0000000000..45e84d0785 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/DefaultBlockParameter.java @@ -0,0 +1,20 @@ +package org.web3j.protocol.core; + +import java.math.BigInteger; + +/** + * Wrapper for parameter that takes either a block number or block name as input + *

+ * See the specification for further information. + */ +public interface DefaultBlockParameter { + static DefaultBlockParameter valueOf(BigInteger blockNumber) { + return new DefaultBlockParameterNumber(blockNumber); + } + + static DefaultBlockParameter valueOf(String blockName) { + return DefaultBlockParameterName.fromString(blockName); + } + + String getValue(); +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/DefaultBlockParameterName.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/DefaultBlockParameterName.java new file mode 100644 index 0000000000..ba0896f5be --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/DefaultBlockParameterName.java @@ -0,0 +1,36 @@ +package org.web3j.protocol.core; + +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * https://github.com/ethereum/wiki/wiki/JSON-RPC#the-default-block-parameter + */ +public enum DefaultBlockParameterName implements DefaultBlockParameter { + EARLIEST("earliest"), + LATEST("latest"), + PENDING("pending"); + + private String name; + + DefaultBlockParameterName(String name) { + this.name = name; + } + + @JsonValue + @Override + public String getValue() { + return name; + } + + public static DefaultBlockParameterName fromString(String name) { + if (name != null) { + for (DefaultBlockParameterName defaultBlockParameterName: + DefaultBlockParameterName.values()) { + if (name.equalsIgnoreCase(defaultBlockParameterName.name)) { + return defaultBlockParameterName; + } + } + } + return valueOf(name); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/DefaultBlockParameterNumber.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/DefaultBlockParameterNumber.java new file mode 100644 index 0000000000..9b0d5da18b --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/DefaultBlockParameterNumber.java @@ -0,0 +1,25 @@ +package org.web3j.protocol.core; + +import java.math.BigInteger; + +import com.fasterxml.jackson.annotation.JsonValue; + +import org.web3j.utils.Numeric; + +/** + * DefaultBlockParameter implementation that takes a numeric value. + */ +public class DefaultBlockParameterNumber implements DefaultBlockParameter { + + private BigInteger blockNumber; + + public DefaultBlockParameterNumber(BigInteger blockNumber) { + this.blockNumber = blockNumber; + } + + @Override + @JsonValue + public String getValue() { + return Numeric.encodeQuantity(blockNumber); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/Ethereum.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/Ethereum.java new file mode 100644 index 0000000000..b632bbfa2e --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/Ethereum.java @@ -0,0 +1,188 @@ +package org.web3j.protocol.core; + +import java.math.BigInteger; + +import org.web3j.protocol.core.methods.request.ShhFilter; +import org.web3j.protocol.core.methods.response.DbGetHex; +import org.web3j.protocol.core.methods.response.DbGetString; +import org.web3j.protocol.core.methods.response.DbPutHex; +import org.web3j.protocol.core.methods.response.DbPutString; +import org.web3j.protocol.core.methods.response.EthAccounts; +import org.web3j.protocol.core.methods.response.EthBlock; +import org.web3j.protocol.core.methods.response.EthBlockNumber; +import org.web3j.protocol.core.methods.response.EthCoinbase; +import org.web3j.protocol.core.methods.response.EthCompileLLL; +import org.web3j.protocol.core.methods.response.EthCompileSerpent; +import org.web3j.protocol.core.methods.response.EthCompileSolidity; +import org.web3j.protocol.core.methods.response.EthEstimateGas; +import org.web3j.protocol.core.methods.response.EthFilter; +import org.web3j.protocol.core.methods.response.EthGasPrice; +import org.web3j.protocol.core.methods.response.EthGetBalance; +import org.web3j.protocol.core.methods.response.EthGetBlockTransactionCountByHash; +import org.web3j.protocol.core.methods.response.EthGetBlockTransactionCountByNumber; +import org.web3j.protocol.core.methods.response.EthGetCode; +import org.web3j.protocol.core.methods.response.EthGetCompilers; +import org.web3j.protocol.core.methods.response.EthGetStorageAt; +import org.web3j.protocol.core.methods.response.EthGetTransactionCount; +import org.web3j.protocol.core.methods.response.EthGetTransactionReceipt; +import org.web3j.protocol.core.methods.response.EthGetUncleCountByBlockHash; +import org.web3j.protocol.core.methods.response.EthGetUncleCountByBlockNumber; +import org.web3j.protocol.core.methods.response.EthGetWork; +import org.web3j.protocol.core.methods.response.EthHashrate; +import org.web3j.protocol.core.methods.response.EthLog; +import org.web3j.protocol.core.methods.response.EthMining; +import org.web3j.protocol.core.methods.response.EthProtocolVersion; +import org.web3j.protocol.core.methods.response.EthSign; +import org.web3j.protocol.core.methods.response.EthSubmitHashrate; +import org.web3j.protocol.core.methods.response.EthSubmitWork; +import org.web3j.protocol.core.methods.response.EthSyncing; +import org.web3j.protocol.core.methods.response.EthTransaction; +import org.web3j.protocol.core.methods.response.EthUninstallFilter; +import org.web3j.protocol.core.methods.response.NetListening; +import org.web3j.protocol.core.methods.response.NetPeerCount; +import org.web3j.protocol.core.methods.response.NetVersion; +import org.web3j.protocol.core.methods.response.ShhAddToGroup; +import org.web3j.protocol.core.methods.response.ShhHasIdentity; +import org.web3j.protocol.core.methods.response.ShhMessages; +import org.web3j.protocol.core.methods.response.ShhNewFilter; +import org.web3j.protocol.core.methods.response.ShhNewGroup; +import org.web3j.protocol.core.methods.response.ShhNewIdentity; +import org.web3j.protocol.core.methods.response.ShhUninstallFilter; +import org.web3j.protocol.core.methods.response.ShhVersion; +import org.web3j.protocol.core.methods.response.Web3ClientVersion; +import org.web3j.protocol.core.methods.response.Web3Sha3; + +/** + * Core Ethereum JSON-RPC API. + */ +public interface Ethereum { + Request web3ClientVersion(); + + Request web3Sha3(String data); + + Request netVersion(); + + Request netListening(); + + Request netPeerCount(); + + Request ethProtocolVersion(); + + Request ethCoinbase(); + + Request ethSyncing(); + + Request ethMining(); + + Request ethHashrate(); + + Request ethGasPrice(); + + Request ethAccounts(); + + Request ethBlockNumber(); + + Request ethGetBalance(String address, DefaultBlockParameter defaultBlockParameter); + + Request ethGetStorageAt(String address, BigInteger position, + DefaultBlockParameter defaultBlockParameter); + + Request ethGetTransactionCount(String address, DefaultBlockParameter defaultBlockParameter); + + Request ethGetBlockTransactionCountByHash(String blockHash); + + Request ethGetBlockTransactionCountByNumber(DefaultBlockParameter defaultBlockParameter); + + Request ethGetUncleCountByBlockHash(String blockHash); + + Request ethGetUncleCountByBlockNumber(DefaultBlockParameter defaultBlockParameter); + + Request ethGetCode(String address, DefaultBlockParameter defaultBlockParameter); + + Request ethSign(String address, String sha3HashOfDataToSign); + + Request ethSendTransaction(org.web3j.protocol.core.methods.request.Transaction transaction); + + Request ethSendRawTransaction(String signedTransactionData); + + Request ethCall(org.web3j.protocol.core.methods.request.Transaction transaction, DefaultBlockParameter defaultBlockParameter); + + Request ethEstimateGas(org.web3j.protocol.core.methods.request.Transaction transaction); + + Request ethGetBlockByHash(String blockHash, boolean returnFullTransactionObjects); + + Request ethGetBlockByNumber( + DefaultBlockParameter defaultBlockParameter, + boolean returnFullTransactionObjects); + + Request ethGetTransactionByHash(String transactionHash); + + Request ethGetTransactionByBlockHashAndIndex( + String blockHash, BigInteger transactionIndex); + + Request ethGetTransactionByBlockNumberAndIndex( + DefaultBlockParameter defaultBlockParameter, BigInteger transactionIndex); + + Request ethGetTransactionReceipt(String transactionHash); + + Request ethGetUncleByBlockHashAndIndex(String blockHash, BigInteger transactionIndex); + + Request ethGetUncleByBlockNumberAndIndex( + DefaultBlockParameter defaultBlockParameter, BigInteger transactionIndex); + + Request ethGetCompilers(); + + Request ethCompileLLL(String sourceCode); + + Request ethCompileSolidity(String sourceCode); + + Request ethCompileSerpent(String sourceCode); + + Request ethNewFilter(org.web3j.protocol.core.methods.request.EthFilter ethFilter); + + Request ethNewBlockFilter(); + + Request ethNewPendingTransactionFilter(); + + Request ethUninstallFilter(BigInteger filterId); + + Request ethGetFilterChanges(BigInteger filterId); + + Request ethGetFilterLogs(BigInteger filterId); + + Request ethGetLogs(org.web3j.protocol.core.methods.request.EthFilter ethFilter); + + Request ethGetWork(); + + Request ethSubmitWork(String nonce, String headerPowHash, String mixDigest); + + Request ethSubmitHashrate(String hashrate, String clientId); + + Request dbPutString(String databaseName, String keyName, String stringToStore); + + Request dbGetString(String databaseName, String keyName); + + Request dbPutHex(String databaseName, String keyName, String dataToStore); + + Request dbGetHex(String databaseName, String keyName); + + Request shhPost(org.web3j.protocol.core.methods.request.ShhPost shhPost); + + Request shhVersion(); + + Request shhNewIdentity(); + + Request shhHasIdentity(String identityAddress); + + Request shhNewGroup(); + + Request shhAddToGroup(String identityAddress); + + Request shhNewFilter(ShhFilter shhFilter); + + Request shhUninstallFilter(BigInteger filterId); + + Request shhGetFilterChanges(BigInteger filterId); + + Request shhGetMessages(BigInteger filterId); +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/JsonRpc2_0Web3j.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/JsonRpc2_0Web3j.java new file mode 100644 index 0000000000..0766ecc607 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/JsonRpc2_0Web3j.java @@ -0,0 +1,779 @@ +package org.web3j.protocol.core; + + +import java.math.BigInteger; +import java.util.Arrays; +import java.util.Collections; +import java.util.concurrent.ExecutorService; + +import rx.Observable; + +import org.web3j.protocol.Web3j; +import org.web3j.protocol.Web3jService; +import org.web3j.protocol.core.methods.request.ShhFilter; +import org.web3j.protocol.core.methods.request.ShhPost; +import org.web3j.protocol.core.methods.request.Transaction; +import org.web3j.protocol.core.methods.response.DbGetHex; +import org.web3j.protocol.core.methods.response.DbGetString; +import org.web3j.protocol.core.methods.response.DbPutHex; +import org.web3j.protocol.core.methods.response.DbPutString; +import org.web3j.protocol.core.methods.response.EthAccounts; +import org.web3j.protocol.core.methods.response.EthBlock; +import org.web3j.protocol.core.methods.response.EthBlockNumber; +import org.web3j.protocol.core.methods.response.EthCall; +import org.web3j.protocol.core.methods.response.EthCoinbase; +import org.web3j.protocol.core.methods.response.EthCompileLLL; +import org.web3j.protocol.core.methods.response.EthCompileSerpent; +import org.web3j.protocol.core.methods.response.EthCompileSolidity; +import org.web3j.protocol.core.methods.response.EthEstimateGas; +import org.web3j.protocol.core.methods.response.EthFilter; +import org.web3j.protocol.core.methods.response.EthGasPrice; +import org.web3j.protocol.core.methods.response.EthGetBalance; +import org.web3j.protocol.core.methods.response.EthGetBlockTransactionCountByHash; +import org.web3j.protocol.core.methods.response.EthGetBlockTransactionCountByNumber; +import org.web3j.protocol.core.methods.response.EthGetCode; +import org.web3j.protocol.core.methods.response.EthGetCompilers; +import org.web3j.protocol.core.methods.response.EthGetStorageAt; +import org.web3j.protocol.core.methods.response.EthGetTransactionCount; +import org.web3j.protocol.core.methods.response.EthGetTransactionReceipt; +import org.web3j.protocol.core.methods.response.EthGetUncleCountByBlockHash; +import org.web3j.protocol.core.methods.response.EthGetUncleCountByBlockNumber; +import org.web3j.protocol.core.methods.response.EthGetWork; +import org.web3j.protocol.core.methods.response.EthHashrate; +import org.web3j.protocol.core.methods.response.EthLog; +import org.web3j.protocol.core.methods.response.EthMining; +import org.web3j.protocol.core.methods.response.EthProtocolVersion; +import org.web3j.protocol.core.methods.response.EthSign; +import org.web3j.protocol.core.methods.response.EthSubmitHashrate; +import org.web3j.protocol.core.methods.response.EthSubmitWork; +import org.web3j.protocol.core.methods.response.EthSyncing; +import org.web3j.protocol.core.methods.response.EthTransaction; +import org.web3j.protocol.core.methods.response.EthUninstallFilter; +import org.web3j.protocol.core.methods.response.Log; +import org.web3j.protocol.core.methods.response.NetListening; +import org.web3j.protocol.core.methods.response.NetPeerCount; +import org.web3j.protocol.core.methods.response.NetVersion; +import org.web3j.protocol.core.methods.response.ShhAddToGroup; +import org.web3j.protocol.core.methods.response.ShhHasIdentity; +import org.web3j.protocol.core.methods.response.ShhMessages; +import org.web3j.protocol.core.methods.response.ShhNewFilter; +import org.web3j.protocol.core.methods.response.ShhNewGroup; +import org.web3j.protocol.core.methods.response.ShhNewIdentity; +import org.web3j.protocol.core.methods.response.ShhUninstallFilter; +import org.web3j.protocol.core.methods.response.ShhVersion; +import org.web3j.protocol.core.methods.response.Web3ClientVersion; +import org.web3j.protocol.core.methods.response.Web3Sha3; +import org.web3j.protocol.rx.JsonRpc2_0Rx; +import org.web3j.utils.Async; +import org.web3j.utils.Numeric; + +/** + * JSON-RPC 2.0 factory implementation. + */ +public class JsonRpc2_0Web3j implements Web3j { + + protected static final long ID = 1; + static final int BLOCK_TIME = 15 * 1000; + + protected final Web3jService web3jService; + private final JsonRpc2_0Rx web3jRx; + private final long blockTime; + + public JsonRpc2_0Web3j(Web3jService web3jService) { + this(web3jService, BLOCK_TIME, Async.defaultExecutorService()); + } + + public JsonRpc2_0Web3j( + Web3jService web3jService, long pollingInterval, ExecutorService executorService) { + this.web3jService = web3jService; + this.web3jRx = new JsonRpc2_0Rx(this, executorService); + this.blockTime = pollingInterval; + } + + @Override + public Request web3ClientVersion() { + return new Request<>( + "web3_clientVersion", + Collections.emptyList(), + ID, + web3jService, + Web3ClientVersion.class); + } + + @Override + public Request web3Sha3(String data) { + return new Request<>( + "web3_sha3", + Arrays.asList(data), + ID, + web3jService, + Web3Sha3.class); + } + + @Override + public Request netVersion() { + return new Request<>( + "net_version", + Collections.emptyList(), + ID, + web3jService, + NetVersion.class); + } + + @Override + public Request netListening() { + return new Request<>( + "net_listening", + Collections.emptyList(), + ID, + web3jService, + NetListening.class); + } + + @Override + public Request netPeerCount() { + return new Request<>( + "net_peerCount", + Collections.emptyList(), + ID, + web3jService, + NetPeerCount.class); + } + + @Override + public Request ethProtocolVersion() { + return new Request<>( + "eth_protocolVersion", + Collections.emptyList(), + ID, + web3jService, + EthProtocolVersion.class); + } + + @Override + public Request ethCoinbase() { + return new Request<>( + "eth_coinbase", + Collections.emptyList(), + ID, + web3jService, + EthCoinbase.class); + } + + @Override + public Request ethSyncing() { + return new Request<>( + "eth_syncing", + Collections.emptyList(), + ID, + web3jService, + EthSyncing.class); + } + + @Override + public Request ethMining() { + return new Request<>( + "eth_mining", + Collections.emptyList(), + ID, + web3jService, + EthMining.class); + } + + @Override + public Request ethHashrate() { + return new Request<>( + "eth_hashrate", + Collections.emptyList(), + ID, + web3jService, + EthHashrate.class); + } + + @Override + public Request ethGasPrice() { + return new Request<>( + "eth_gasPrice", + Collections.emptyList(), + ID, + web3jService, + EthGasPrice.class); + } + + @Override + public Request ethAccounts() { + return new Request<>( + "eth_accounts", + Collections.emptyList(), + ID, + web3jService, + EthAccounts.class); + } + + @Override + public Request ethBlockNumber() { + return new Request<>( + "eth_blockNumber", + Collections.emptyList(), + ID, + web3jService, + EthBlockNumber.class); + } + + @Override + public Request ethGetBalance( + String address, DefaultBlockParameter defaultBlockParameter) { + return new Request<>( + "eth_getBalance", + Arrays.asList(address, defaultBlockParameter.getValue()), + ID, + web3jService, + EthGetBalance.class); + } + + @Override + public Request ethGetStorageAt( + String address, BigInteger position, DefaultBlockParameter defaultBlockParameter) { + return new Request<>( + "eth_getStorageAt", + Arrays.asList( + address, + Numeric.encodeQuantity(position), + defaultBlockParameter.getValue()), + ID, + web3jService, + EthGetStorageAt.class); + } + + @Override + public Request ethGetTransactionCount( + String address, DefaultBlockParameter defaultBlockParameter) { + return new Request<>( + "eth_getTransactionCount", + Arrays.asList(address, defaultBlockParameter.getValue()), + ID, + web3jService, + EthGetTransactionCount.class); + } + + @Override + public Request ethGetBlockTransactionCountByHash( + String blockHash) { + return new Request<>( + "eth_getBlockTransactionCountByHash", + Arrays.asList(blockHash), + ID, + web3jService, + EthGetBlockTransactionCountByHash.class); + } + + @Override + public Request ethGetBlockTransactionCountByNumber( + DefaultBlockParameter defaultBlockParameter) { + return new Request<>( + "eth_getBlockTransactionCountByNumber", + Arrays.asList(defaultBlockParameter.getValue()), + ID, + web3jService, + EthGetBlockTransactionCountByNumber.class); + } + + @Override + public Request ethGetUncleCountByBlockHash(String blockHash) { + return new Request<>( + "eth_getUncleCountByBlockHash", + Arrays.asList(blockHash), + ID, + web3jService, + EthGetUncleCountByBlockHash.class); + } + + @Override + public Request ethGetUncleCountByBlockNumber( + DefaultBlockParameter defaultBlockParameter) { + return new Request<>( + "eth_getUncleCountByBlockNumber", + Arrays.asList(defaultBlockParameter.getValue()), + ID, + web3jService, + EthGetUncleCountByBlockNumber.class); + } + + @Override + public Request ethGetCode( + String address, DefaultBlockParameter defaultBlockParameter) { + return new Request<>( + "eth_getCode", + Arrays.asList(address, defaultBlockParameter.getValue()), + ID, + web3jService, + EthGetCode.class); + } + + @Override + public Request ethSign(String address, String sha3HashOfDataToSign) { + return new Request<>( + "eth_sign", + Arrays.asList(address, sha3HashOfDataToSign), + ID, + web3jService, + EthSign.class); + } + + @Override + public Request ethSendTransaction( + Transaction transaction) { + return new Request<>( + "eth_sendTransaction", + Arrays.asList(transaction), + ID, + web3jService, + org.web3j.protocol.core.methods.response.EthSendTransaction.class); + } + + @Override + public Request ethSendRawTransaction( + String signedTransactionData) { + return new Request<>( + "eth_sendRawTransaction", + Arrays.asList(signedTransactionData), + ID, + web3jService, + org.web3j.protocol.core.methods.response.EthSendTransaction.class); + } + + @Override + public Request ethCall( + Transaction transaction, DefaultBlockParameter defaultBlockParameter) { + return new Request( + "eth_call", + Arrays.asList(transaction, defaultBlockParameter), + ID, + web3jService, + org.web3j.protocol.core.methods.response.EthCall.class); + } + + @Override + public Request ethEstimateGas(Transaction transaction) { + return new Request<>( + "eth_estimateGas", + Arrays.asList(transaction), + ID, + web3jService, + EthEstimateGas.class); + } + + @Override + public Request ethGetBlockByHash( + String blockHash, boolean returnFullTransactionObjects) { + return new Request<>( + "eth_getBlockByHash", + Arrays.asList( + blockHash, + returnFullTransactionObjects), + ID, + web3jService, + EthBlock.class); + } + + @Override + public Request ethGetBlockByNumber( + DefaultBlockParameter defaultBlockParameter, + boolean returnFullTransactionObjects) { + return new Request<>( + "eth_getBlockByNumber", + Arrays.asList( + defaultBlockParameter.getValue(), + returnFullTransactionObjects), + ID, + web3jService, + EthBlock.class); + } + + @Override + public Request ethGetTransactionByHash(String transactionHash) { + return new Request<>( + "eth_getTransactionByHash", + Arrays.asList(transactionHash), + ID, + web3jService, + EthTransaction.class); + } + + @Override + public Request ethGetTransactionByBlockHashAndIndex( + String blockHash, BigInteger transactionIndex) { + return new Request<>( + "eth_getTransactionByBlockHashAndIndex", + Arrays.asList( + blockHash, + Numeric.encodeQuantity(transactionIndex)), + ID, + web3jService, + EthTransaction.class); + } + + @Override + public Request ethGetTransactionByBlockNumberAndIndex( + DefaultBlockParameter defaultBlockParameter, BigInteger transactionIndex) { + return new Request<>( + "eth_getTransactionByBlockNumberAndIndex", + Arrays.asList( + defaultBlockParameter.getValue(), + Numeric.encodeQuantity(transactionIndex)), + ID, + web3jService, + EthTransaction.class); + } + + @Override + public Request ethGetTransactionReceipt(String transactionHash) { + return new Request<>( + "eth_getTransactionReceipt", + Arrays.asList(transactionHash), + ID, + web3jService, + EthGetTransactionReceipt.class); + } + + @Override + public Request ethGetUncleByBlockHashAndIndex( + String blockHash, BigInteger transactionIndex) { + return new Request<>( + "eth_getUncleByBlockHashAndIndex", + Arrays.asList( + blockHash, + Numeric.encodeQuantity(transactionIndex)), + ID, + web3jService, + EthBlock.class); + } + + @Override + public Request ethGetUncleByBlockNumberAndIndex( + DefaultBlockParameter defaultBlockParameter, BigInteger uncleIndex) { + return new Request<>( + "eth_getUncleByBlockNumberAndIndex", + Arrays.asList( + defaultBlockParameter.getValue(), + Numeric.encodeQuantity(uncleIndex)), + ID, + web3jService, + EthBlock.class); + } + + @Override + public Request ethGetCompilers() { + return new Request<>( + "eth_getCompilers", + Collections.emptyList(), + ID, + web3jService, + EthGetCompilers.class); + } + + @Override + public Request ethCompileLLL(String sourceCode) { + return new Request<>( + "eth_compileLLL", + Arrays.asList(sourceCode), + ID, + web3jService, + EthCompileLLL.class); + } + + @Override + public Request ethCompileSolidity(String sourceCode) { + return new Request<>( + "eth_compileSolidity", + Arrays.asList(sourceCode), + ID, + web3jService, + EthCompileSolidity.class); + } + + @Override + public Request ethCompileSerpent(String sourceCode) { + return new Request<>( + "eth_compileSerpent", + Arrays.asList(sourceCode), + ID, + web3jService, + EthCompileSerpent.class); + } + + @Override + public Request ethNewFilter( + org.web3j.protocol.core.methods.request.EthFilter ethFilter) { + return new Request<>( + "eth_newFilter", + Arrays.asList(ethFilter), + ID, + web3jService, + EthFilter.class); + } + + @Override + public Request ethNewBlockFilter() { + return new Request<>( + "eth_newBlockFilter", + Collections.emptyList(), + ID, + web3jService, + EthFilter.class); + } + + @Override + public Request ethNewPendingTransactionFilter() { + return new Request<>( + "eth_newPendingTransactionFilter", + Collections.emptyList(), + ID, + web3jService, + EthFilter.class); + } + + @Override + public Request ethUninstallFilter(BigInteger filterId) { + return new Request<>( + "eth_uninstallFilter", + Arrays.asList(Numeric.encodeQuantity(filterId)), + ID, + web3jService, + EthUninstallFilter.class); + } + + @Override + public Request ethGetFilterChanges(BigInteger filterId) { + return new Request<>( + "eth_getFilterChanges", + Arrays.asList(Numeric.encodeQuantity(filterId)), + ID, + web3jService, + EthLog.class); + } + + @Override + public Request ethGetFilterLogs(BigInteger filterId) { + return new Request<>( + "eth_getFilterLogs", + Arrays.asList(Numeric.encodeQuantity(filterId)), + ID, + web3jService, + EthLog.class); + } + + @Override + public Request ethGetLogs(org.web3j.protocol.core.methods.request.EthFilter ethFilter) { + return new Request<>( + "eth_getLogs", + Arrays.asList(ethFilter), + ID, + web3jService, + EthLog.class); + } + + @Override + public Request ethGetWork() { + return new Request<>( + "eth_getWork", + Collections.emptyList(), + ID, + web3jService, + EthGetWork.class); + } + + @Override + public Request ethSubmitWork(String nonce, String headerPowHash, String mixDigest) { + return new Request<>( + "eth_submitWork", + Arrays.asList(nonce, headerPowHash, mixDigest), + ID, + web3jService, + EthSubmitWork.class); + } + + @Override + public Request ethSubmitHashrate(String hashrate, String clientId) { + return new Request<>( + "eth_submitHashrate", + Arrays.asList(hashrate, clientId), + ID, + web3jService, + EthSubmitHashrate.class); + } + + @Override + public Request dbPutString( + String databaseName, String keyName, String stringToStore) { + return new Request<>( + "db_putString", + Arrays.asList(databaseName, keyName, stringToStore), + ID, + web3jService, + DbPutString.class); + } + + @Override + public Request dbGetString(String databaseName, String keyName) { + return new Request<>( + "db_getString", + Arrays.asList(databaseName, keyName), + ID, + web3jService, + DbGetString.class); + } + + @Override + public Request dbPutHex(String databaseName, String keyName, String dataToStore) { + return new Request<>( + "db_putHex", + Arrays.asList(databaseName, keyName, dataToStore), + ID, + web3jService, + DbPutHex.class); + } + + @Override + public Request dbGetHex(String databaseName, String keyName) { + return new Request<>( + "db_getHex", + Arrays.asList(databaseName, keyName), + ID, + web3jService, + DbGetHex.class); + } + + @Override + public Request shhPost(ShhPost shhPost) { + return new Request<>( + "shh_post", + Arrays.asList(shhPost), + ID, + web3jService, + org.web3j.protocol.core.methods.response.ShhPost.class); + } + + @Override + public Request shhVersion() { + return new Request<>( + "shh_version", + Collections.emptyList(), + ID, + web3jService, + ShhVersion.class); + } + + @Override + public Request shhNewIdentity() { + return new Request<>( + "shh_newIdentity", + Collections.emptyList(), + ID, + web3jService, + ShhNewIdentity.class); + } + + @Override + public Request shhHasIdentity(String identityAddress) { + return new Request<>( + "shh_hasIdentity", + Arrays.asList(identityAddress), + ID, + web3jService, + ShhHasIdentity.class); + } + + @Override + public Request shhNewGroup() { + return new Request<>( + "shh_newGroup", + Collections.emptyList(), + ID, + web3jService, + ShhNewGroup.class); + } + + @Override + public Request shhAddToGroup(String identityAddress) { + return new Request<>( + "shh_addToGroup", + Arrays.asList(identityAddress), + ID, + web3jService, + ShhAddToGroup.class); + } + + @Override + public Request shhNewFilter(ShhFilter shhFilter) { + return new Request<>( + "shh_newFilter", + Arrays.asList(shhFilter), + ID, + web3jService, + ShhNewFilter.class); + } + + @Override + public Request shhUninstallFilter(BigInteger filterId) { + return new Request<>( + "shh_uninstallFilter", + Arrays.asList(Numeric.encodeQuantity(filterId)), + ID, + web3jService, + ShhUninstallFilter.class); + } + + @Override + public Request shhGetFilterChanges(BigInteger filterId) { + return new Request<>( + "shh_getFilterChanges", + Arrays.asList(Numeric.encodeQuantity(filterId)), + ID, + web3jService, + ShhMessages.class); + } + + @Override + public Request shhGetMessages(BigInteger filterId) { + return new Request<>( + "shh_getMessages", + Arrays.asList(Numeric.encodeQuantity(filterId)), + ID, + web3jService, + ShhMessages.class); + } + + @Override + public Observable ethBlockHashObservable() { + return web3jRx.ethBlockHashObservable(blockTime); + } + + @Override + public Observable ethPendingTransactionHashObservable() { + return web3jRx.ethPendingTransactionHashObservable(blockTime); + } + + @Override + public Observable ethLogObservable( + org.web3j.protocol.core.methods.request.EthFilter ethFilter) { + return web3jRx.ethLogObservable(ethFilter, blockTime); + } + + @Override + public Observable + transactionObservable() { + return web3jRx.transactionObservable(blockTime); + } + + @Override + public Observable + pendingTransactionObservable() { + return web3jRx.pendingTransactionObservable(blockTime); + } + + @Override + public Observable blockObservable(boolean fullTransactionObjects) { + return web3jRx.blockObservable(fullTransactionObjects, blockTime); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/Request.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/Request.java new file mode 100644 index 0000000000..2c16dff13e --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/Request.java @@ -0,0 +1,91 @@ +package org.web3j.protocol.core; + + +import java.io.IOException; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; + +import rx.Observable; + +import org.web3j.protocol.Web3jService; + + +public class Request { + private String jsonrpc = "2.0"; + private String method; + private List params; + private long id; + + private Web3jService web3jService; + + // Unfortunately require an instance of the type too, see + // http://stackoverflow.com/a/3437930/3211687 + private Class responseType; + + public Request() { + } + + public Request(String method, List params, long id, + Web3jService web3jService, Class type) { + this.method = method; + this.params = params; + this.id = id; + this.web3jService = web3jService; + this.responseType = type; + } + + public String getJsonrpc() { + return jsonrpc; + } + + public void setJsonrpc(String jsonrpc) { + this.jsonrpc = jsonrpc; + } + + public String getMethod() { + return method; + } + + public void setMethod(String method) { + this.method = method; + } + + public List getParams() { + return params; + } + + public void setParams(List params) { + this.params = params; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public T send() throws IOException { + return web3jService.send(this, responseType); + } + + public CompletableFuture sendAsync() { + return web3jService.sendAsync(this, responseType); + } + + public Observable observable() { + return Observable.create( + subscriber -> { + try { + subscriber.onNext(sendAsync().get()); + } catch (InterruptedException e) { + subscriber.onError(e); + } catch (ExecutionException e) { + subscriber.onError(e); + } + } + ); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/Response.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/Response.java new file mode 100644 index 0000000000..715ef65323 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/Response.java @@ -0,0 +1,117 @@ +package org.web3j.protocol.core; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + + +@JsonIgnoreProperties(ignoreUnknown = true) +public class Response { + private long id; + private String jsonrpc; + private T result; + private Error error; + + public Response() { + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getJsonrpc() { + return jsonrpc; + } + + public void setJsonrpc(String jsonrpc) { + this.jsonrpc = jsonrpc; + } + + public T getResult() { + return result; + } + + public void setResult(T result) { + this.result = result; + } + + public Error getError() { + return error; + } + + public void setError(Error error) { + this.error = error; + } + + public boolean hasError() { + return error != null; + } + + public static class Error { + private int code; + private String message; + private String data; + + public Error() { + } + + public Error(int code, String message) { + this.code = code; + this.message = message; + } + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public String getData() { + return data; + } + + public void setData(String data) { + this.data = data; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof Error)) { + return false; + } + + Error error = (Error) o; + + if (getCode() != error.getCode()) { + return false; + } + if (getMessage() != null ? !getMessage().equals(error.getMessage()) : error.getMessage() != null) { + return false; + } + return getData() != null ? getData().equals(error.getData()) : error.getData() == null; + } + + @Override + public int hashCode() { + int result = getCode(); + result = 31 * result + (getMessage() != null ? getMessage().hashCode() : 0); + result = 31 * result + (getData() != null ? getData().hashCode() : 0); + return result; + } + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/filters/BlockFilter.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/filters/BlockFilter.java new file mode 100644 index 0000000000..741fdf04fb --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/filters/BlockFilter.java @@ -0,0 +1,37 @@ +package org.web3j.protocol.core.filters; + +import java.util.List; +import java.util.concurrent.ExecutionException; + +import org.web3j.protocol.Web3j; +import org.web3j.protocol.core.methods.response.EthFilter; +import org.web3j.protocol.core.methods.response.EthLog; + +/** + * Handler for working with block filter requests. + */ +public class BlockFilter extends Filter { + + public BlockFilter(Web3j web3j, Callback callback) { + super(web3j, callback); + } + + @Override + EthFilter sendRequest() throws ExecutionException, InterruptedException { + return web3j.ethNewBlockFilter().sendAsync().get(); + } + + @Override + void process(List logResults) { + for (EthLog.LogResult logResult : logResults) { + if (logResult instanceof EthLog.Hash) { + String blockHash = ((EthLog.Hash) logResult).get(); + callback.onEvent(blockHash); + } else { + throw new FilterException( + "Unexpected result type: " + logResult.get() + ", required Hash"); + } + } + } +} + diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/filters/Callback.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/filters/Callback.java new file mode 100644 index 0000000000..32fc0dc57c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/filters/Callback.java @@ -0,0 +1,8 @@ +package org.web3j.protocol.core.filters; + +/** + * Filter callback interface. + */ +public interface Callback { + void onEvent(T value); +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/filters/Filter.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/filters/Filter.java new file mode 100644 index 0000000000..b291e006ff --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/filters/Filter.java @@ -0,0 +1,85 @@ +package org.web3j.protocol.core.filters; + +import java.math.BigInteger; +import java.util.List; +import java.util.concurrent.ExecutionException; + +import org.web3j.protocol.Web3j; +import org.web3j.protocol.core.Response; +import org.web3j.protocol.core.methods.response.EthFilter; +import org.web3j.protocol.core.methods.response.EthLog; +import org.web3j.protocol.core.methods.response.EthUninstallFilter; + + +/** + * Class for creating managed filter requests with callbacks. + */ +public abstract class Filter { + + final Web3j web3j; + final Callback callback; + + private volatile BigInteger filterId; + private volatile boolean canceled = false; + + public Filter(Web3j web3j, Callback callback) { + this.web3j = web3j; + this.callback = callback; + } + + public void run(long blockTime) { + try { + EthFilter ethFilter = sendRequest(); + if (ethFilter.hasError()) { + throwException(ethFilter.getError()); + } + + filterId = ethFilter.getFilterId(); + + while (!canceled) { + EthLog ethLog = web3j.ethGetFilterChanges(filterId).sendAsync().get(); + if (ethLog.hasError()) { + throwException(ethFilter.getError()); + } + + process(ethLog.getLogs()); + + Thread.sleep(blockTime); + } + } catch (InterruptedException | ExecutionException e) { + throwException(e); + } + } + + abstract EthFilter sendRequest() throws ExecutionException, InterruptedException; + + abstract void process(List logResults); + + public void cancel() { + canceled = true; + + EthUninstallFilter ethUninstallFilter = null; + try { + ethUninstallFilter = web3j.ethUninstallFilter(filterId).sendAsync().get(); + } catch (InterruptedException | ExecutionException e) { + throwException(e); + } + + if (ethUninstallFilter.hasError()) { + throwException(ethUninstallFilter.getError()); + } + + if (!ethUninstallFilter.isUninstalled()) { + throwException(ethUninstallFilter.getError()); + } + } + + void throwException(Response.Error error) { + throw new FilterException("Invalid request: " + error.getMessage()); + } + + void throwException(Throwable cause) { + throw new FilterException("Error sending request", cause); + } +} + diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/filters/FilterException.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/filters/FilterException.java new file mode 100644 index 0000000000..f4ec7004d4 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/filters/FilterException.java @@ -0,0 +1,15 @@ +package org.web3j.protocol.core.filters; + +/** + * Filter exception wrapper + */ +public class FilterException extends RuntimeException { + + public FilterException(String message) { + super(message); + } + + public FilterException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/filters/LogFilter.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/filters/LogFilter.java new file mode 100644 index 0000000000..bdc1370ee3 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/filters/LogFilter.java @@ -0,0 +1,42 @@ +package org.web3j.protocol.core.filters; + +import java.util.List; +import java.util.concurrent.ExecutionException; + +import org.web3j.protocol.Web3j; +import org.web3j.protocol.core.methods.response.EthFilter; +import org.web3j.protocol.core.methods.response.EthLog; +import org.web3j.protocol.core.methods.response.Log; + +/** + * Log filter handler + */ +public class LogFilter extends Filter { + + private final org.web3j.protocol.core.methods.request.EthFilter ethFilter; + + public LogFilter( + Web3j web3j, Callback callback, + org.web3j.protocol.core.methods.request.EthFilter ethFilter) { + super(web3j, callback); + this.ethFilter = ethFilter; + } + + @Override + EthFilter sendRequest() throws ExecutionException, InterruptedException { + return web3j.ethNewFilter(ethFilter).sendAsync().get(); + } + + @Override + void process(List logResults) { + for (EthLog.LogResult logResult : logResults) { + if (logResult instanceof EthLog.LogObject) { + Log log = ((EthLog.LogObject) logResult).get(); + callback.onEvent(log); + } else { + throw new FilterException( + "Unexpected result type: " + logResult.get() + " required LogObject"); + } + } + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/filters/PendingTransactionFilter.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/filters/PendingTransactionFilter.java new file mode 100644 index 0000000000..0adfb5f0b6 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/filters/PendingTransactionFilter.java @@ -0,0 +1,37 @@ +package org.web3j.protocol.core.filters; + +import java.util.List; +import java.util.concurrent.ExecutionException; + +import org.web3j.protocol.Web3j; +import org.web3j.protocol.core.methods.response.EthFilter; +import org.web3j.protocol.core.methods.response.EthLog; + +/** + * Handler for working with transaction filter requests. + */ +public class PendingTransactionFilter extends Filter { + + public PendingTransactionFilter(Web3j web3j, Callback callback) { + super(web3j, callback); + } + + @Override + EthFilter sendRequest() throws ExecutionException, InterruptedException { + return web3j.ethNewPendingTransactionFilter().sendAsync().get(); + } + + @Override + void process(List logResults) { + for (EthLog.LogResult logResult : logResults) { + if (logResult instanceof EthLog.Hash) { + String blockHash = ((EthLog.Hash) logResult).get(); + callback.onEvent(blockHash); + } else { + throw new FilterException( + "Unexpected result type: " + logResult.get() + ", required Hash"); + } + } + } +} + diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/request/EthFilter.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/request/EthFilter.java new file mode 100644 index 0000000000..4e061942ce --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/request/EthFilter.java @@ -0,0 +1,49 @@ +package org.web3j.protocol.core.methods.request; + +import java.util.Arrays; +import java.util.List; + +import org.web3j.protocol.core.DefaultBlockParameter; + +/** + * Filter implementation as per docs + */ +public class EthFilter extends Filter { + private DefaultBlockParameter fromBlock; // optional, params - defaults to latest for both + private DefaultBlockParameter toBlock; + private List address; // specification implies this can be single address as string or list + + public EthFilter() { + super(); + } + + public EthFilter(DefaultBlockParameter fromBlock, DefaultBlockParameter toBlock, + List address) { + super(); + this.fromBlock = fromBlock; + this.toBlock = toBlock; + this.address = address; + } + + public EthFilter(DefaultBlockParameter fromBlock, DefaultBlockParameter toBlock, + String address) { + this(fromBlock, toBlock, Arrays.asList(address)); + } + + public DefaultBlockParameter getFromBlock() { + return fromBlock; + } + + public DefaultBlockParameter getToBlock() { + return toBlock; + } + + public List getAddress() { + return address; + } + + @Override + Filter getThis() { + return this; + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/request/Filter.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/request/Filter.java new file mode 100644 index 0000000000..cf1137728b --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/request/Filter.java @@ -0,0 +1,86 @@ +package org.web3j.protocol.core.methods.request; + +import java.util.ArrayList; +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * Filter implementation as per docs + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +public abstract class Filter { + + private T thisObj; + private List topics; + + Filter() { + thisObj = getThis(); + topics = new ArrayList<>(); + } + + public T addSingleTopic(String topic) { + topics.add(new SingleTopic<>(topic)); + return getThis(); + } + + public T addNullTopic() { + topics.add(new SingleTopic<>()); + return getThis(); + } + + // how to pass in null topic? + public T addOptionalTopics(String... optionalTopics) { + topics.add(new ListTopic(optionalTopics)); + return getThis(); + } + + public List getTopics() { + return topics; + } + + abstract T getThis(); + + public interface FilterTopic { + @JsonValue + T getValue(); + } + + public static class SingleTopic implements FilterTopic { + private String topic; + + public SingleTopic() { + this.topic = null; // null topic + } + + public SingleTopic(String topic) { + this.topic = topic; + } + + @Override + public String getValue() { + return topic; + } + } + + public static class ListTopic implements FilterTopic>> { + private List> topics; + + public ListTopic(String... optionalTopics) { + topics = new ArrayList<>(); + for (String topic : optionalTopics) { + if (topic != null) { + topics.add(new SingleTopic<>(topic)); + } else { + topics.add(new SingleTopic<>()); + } + } + } + + @Override + public List> getValue() { + return topics; + } + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/request/RawTransaction.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/request/RawTransaction.java new file mode 100644 index 0000000000..77f879cd73 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/request/RawTransaction.java @@ -0,0 +1,84 @@ +package org.web3j.protocol.core.methods.request; + +import java.math.BigInteger; + +import org.web3j.utils.Numeric; + +/** + *

Transaction class used for signing transactions locally.
+ * For the specification, refer to p4 of the + * yellow paper.

+ */ +public class RawTransaction { + + private BigInteger nonce; + private BigInteger gasPrice; + private BigInteger gasLimit; + private String to; + private BigInteger value; + private String data; + + private RawTransaction(BigInteger nonce, BigInteger gasPrice, BigInteger gasLimit, String to, + BigInteger value, String data) { + this.nonce = nonce; + this.gasPrice = gasPrice; + this.gasLimit = gasLimit; + this.to = to; + this.value = value; + + if (data != null) { + this.data = Numeric.cleanHexPrefix(data); + } + } + + public static RawTransaction createContractTransaction( + BigInteger nonce, BigInteger gasPrice, BigInteger gasLimit, BigInteger value, + String init) { + + return new RawTransaction(nonce, gasPrice, gasLimit, "", value, init); + } + + public static RawTransaction createEtherTransaction( + BigInteger nonce, BigInteger gasPrice, BigInteger gasLimit, String to, + BigInteger value) { + + return new RawTransaction(nonce, gasPrice, gasLimit, to, value, ""); + + } + + public static RawTransaction createTransaction( + BigInteger nonce, BigInteger gasPrice, BigInteger gasLimit, String to, String data) { + return createTransaction(nonce, gasPrice, gasLimit, to, BigInteger.ZERO, data); + } + + public static RawTransaction createTransaction( + BigInteger nonce, BigInteger gasPrice, BigInteger gasLimit, String to, + BigInteger value, String data) { + + return new RawTransaction(nonce, gasPrice, gasLimit, to, value, data); + } + + public BigInteger getNonce() { + return nonce; + } + + public BigInteger getGasPrice() { + return gasPrice; + } + + public BigInteger getGasLimit() { + return gasLimit; + } + + public String getTo() { + return to; + } + + public BigInteger getValue() { + return value; + } + + public String getData() { + return data; + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/request/ShhFilter.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/request/ShhFilter.java new file mode 100644 index 0000000000..9b0c312a7a --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/request/ShhFilter.java @@ -0,0 +1,22 @@ +package org.web3j.protocol.core.methods.request; + +/** + * Filter implementation as per docs + */ +public class ShhFilter extends Filter { + private String to; + + public ShhFilter(String to) { + super(); + this.to = to; + } + + public String getTo() { + return to; + } + + @Override + Filter getThis() { + return this; + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/request/ShhPost.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/request/ShhPost.java new file mode 100644 index 0000000000..25ad42198c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/request/ShhPost.java @@ -0,0 +1,71 @@ +package org.web3j.protocol.core.methods.request; + +import java.math.BigInteger; +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonInclude; + +import org.web3j.utils.Numeric; + +/** + * https://github.com/ethereum/wiki/wiki/JSON-RPC#shh_post + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +public class ShhPost { + private String from; + private String to; + private List topics; + private String payload; + private BigInteger priority; + private BigInteger ttl; + + public ShhPost(List topics, String payload, BigInteger priority, + BigInteger ttl) { + this.topics = topics; + this.payload = payload; + this.priority = priority; + this.ttl = ttl; + } + + public ShhPost(String from, String to, List topics, String payload, + BigInteger priority, BigInteger ttl) { + this.from = from; + this.to = to; + this.topics = topics; + this.payload = payload; + this.priority = priority; + this.ttl = ttl; + } + + public String getFrom() { + return from; + } + + public String getTo() { + return to; + } + + public List getTopics() { + return topics; + } + + public String getPayload() { + return payload; + } + + public String getPriority() { + return convert(priority); + } + + public String getTtl() { + return convert(ttl); + } + + private String convert(BigInteger value) { + if (value != null) { + return Numeric.encodeQuantity(value); + } else { + return null; + } + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/request/Transaction.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/request/Transaction.java new file mode 100644 index 0000000000..d20c3620f9 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/request/Transaction.java @@ -0,0 +1,119 @@ +package org.web3j.protocol.core.methods.request; + +import java.math.BigInteger; + +import com.fasterxml.jackson.annotation.JsonInclude; + +import org.web3j.utils.Numeric; + +/** + * Transaction request object used by: + *
    + *
  1. eth_call
  2. + *
  3. eth_sendTransaction
  4. + *
  5. eth_estimateGas
  6. + *
+ */ +@JsonInclude(JsonInclude.Include.NON_NULL) +public class Transaction { + // default as per https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sendtransaction + public static final BigInteger DEFAULT_GAS = BigInteger.valueOf(9000); + + private String from; + private String to; + private BigInteger gas; + private BigInteger gasPrice; + private BigInteger value; + private String data; + private BigInteger nonce; // nonce field is not present on eth_call/eth_estimateGas + + public Transaction(String from, BigInteger nonce, BigInteger gasPrice, BigInteger gasLimit, + String to, BigInteger value, String data) { + this.from = from; + this.to = to; + this.gas = gasLimit; + this.gasPrice = gasPrice; + this.value = value; + + if (data != null) { + this.data = Numeric.prependHexPrefix(data); + } + + this.nonce = nonce; + } + + public static Transaction createContractTransaction( + String from, BigInteger nonce, BigInteger gasPrice, BigInteger gasLimit, + BigInteger value, String init) { + + return new Transaction(from, nonce, gasPrice, gasLimit, null, value, init); + } + + public static Transaction createContractTransaction( + String from, BigInteger nonce, BigInteger gasPrice, String init) { + + return createContractTransaction(from, nonce, gasPrice, null, null, init); + } + + public static Transaction createEtherTransaction( + String from, BigInteger nonce, BigInteger gasPrice, BigInteger gasLimit, String to, + BigInteger value) { + + return new Transaction(from, nonce, gasPrice, gasLimit, to, value, null); + } + + public static Transaction createFunctionCallTransaction( + String from, BigInteger nonce, BigInteger gasPrice, BigInteger gasLimit, String to, + BigInteger value, String data) { + + return new Transaction(from, nonce, gasPrice, gasLimit, to, value, data); + } + + public static Transaction createFunctionCallTransaction( + String from, BigInteger nonce, BigInteger gasPrice, BigInteger gasLimit, String to, + String data) { + + return new Transaction(from, nonce, gasPrice, gasLimit, to, null, data); + } + + public static Transaction createEthCallTransaction(String to, String data) { + + return new Transaction(null, null, null, null, to, null, data); + } + + public String getFrom() { + return from; + } + + public String getTo() { + return to; + } + + public String getGas() { + return convert(gas); + } + + public String getGasPrice() { + return convert(gasPrice); + } + + public String getValue() { + return convert(value); + } + + public String getData() { + return data; + } + + public String getNonce() { + return convert(nonce); + } + + private static String convert(BigInteger value) { + if (value != null) { + return Numeric.encodeQuantity(value); + } else { + return null; // we don't want the field to be encoded if not present + } + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/AbiDefinition.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/AbiDefinition.java new file mode 100644 index 0000000000..611c9f90b8 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/AbiDefinition.java @@ -0,0 +1,185 @@ +package org.web3j.protocol.core.methods.response; + +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +/** + * AbiDefinition wrapper + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class AbiDefinition { + private boolean constant; + private List inputs; + private String name; + private List outputs; + private String type; + private boolean payable; + + public AbiDefinition() { + } + + public AbiDefinition(boolean constant, List inputs, String name, + List outputs, String type, boolean payable) { + this.constant = constant; + this.inputs = inputs; + this.name = name; + this.outputs = outputs; + this.type = type; + this.payable = false; + } + + public boolean isConstant() { + return constant; + } + + public void setConstant(boolean constant) { + this.constant = constant; + } + + public List getInputs() { + return inputs; + } + + public void setInputs(List inputs) { + this.inputs = inputs; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getOutputs() { + return outputs; + } + + public void setOutputs(List outputs) { + this.outputs = outputs; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public boolean isPayable() { + return payable; + } + + public void setPayable(boolean payable) { + this.payable = payable; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof AbiDefinition)) { + return false; + } + + AbiDefinition that = (AbiDefinition) o; + + if (isConstant() != that.isConstant()) { + return false; + } + if (isPayable() != that.isPayable()) { + return false; + } + if (getInputs() != null ? !getInputs().equals(that.getInputs()) : that.getInputs() != null) { + return false; + } + if (getName() != null ? !getName().equals(that.getName()) : that.getName() != null) { + return false; + } + if (getOutputs() != null ? !getOutputs().equals(that.getOutputs()) : that.getOutputs() != null) { + return false; + } + return getType() != null ? getType().equals(that.getType()) : that.getType() == null; + } + + @Override + public int hashCode() { + int result = (isConstant() ? 1 : 0); + result = 31 * result + (getInputs() != null ? getInputs().hashCode() : 0); + result = 31 * result + (getName() != null ? getName().hashCode() : 0); + result = 31 * result + (getOutputs() != null ? getOutputs().hashCode() : 0); + result = 31 * result + (getType() != null ? getType().hashCode() : 0); + result = 31 * result + (isPayable() ? 1 : 0); + return result; + } + + public static class NamedType { + private String name; + private String type; + private boolean indexed; + + public NamedType() { + } + + public NamedType(String name, String type) { + this.name = name; + this.type = type; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public boolean isIndexed() { + return indexed; + } + + public void setIndexed(boolean indexed) { + this.indexed = indexed; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof NamedType)) { + return false; + } + + NamedType namedType = (NamedType) o; + + if (isIndexed() != namedType.isIndexed()) { + return false; + } + if (getName() != null ? !getName().equals(namedType.getName()) : namedType.getName() != null) { + return false; + } + return getType() != null ? getType().equals(namedType.getType()) : namedType.getType() == null; + } + + @Override + public int hashCode() { + int result = getName() != null ? getName().hashCode() : 0; + result = 31 * result + (getType() != null ? getType().hashCode() : 0); + result = 31 * result + (isIndexed() ? 1 : 0); + return result; + } + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/DbGetHex.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/DbGetHex.java new file mode 100644 index 0000000000..abfa8c2329 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/DbGetHex.java @@ -0,0 +1,13 @@ +package org.web3j.protocol.core.methods.response; + +import org.web3j.protocol.core.Response; + +/** + * db_getHex + */ +public class DbGetHex extends Response { + + public String getStoredValue() { + return getResult(); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/DbGetString.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/DbGetString.java new file mode 100644 index 0000000000..a40faf7f20 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/DbGetString.java @@ -0,0 +1,13 @@ +package org.web3j.protocol.core.methods.response; + +import org.web3j.protocol.core.Response; + +/** + * db_getString + */ +public class DbGetString extends Response { + + public String getStoredValue() { + return getResult(); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/DbPutHex.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/DbPutHex.java new file mode 100644 index 0000000000..8086841295 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/DbPutHex.java @@ -0,0 +1,13 @@ +package org.web3j.protocol.core.methods.response; + +import org.web3j.protocol.core.Response; + +/** + * db_putHex + */ +public class DbPutHex extends Response { + + public boolean valueStored() { + return getResult(); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/DbPutString.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/DbPutString.java new file mode 100644 index 0000000000..c5a2a2d32d --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/DbPutString.java @@ -0,0 +1,13 @@ +package org.web3j.protocol.core.methods.response; + +import org.web3j.protocol.core.Response; + +/** + * db_putString + */ +public class DbPutString extends Response { + + public boolean valueStored() { + return getResult(); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthAccounts.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthAccounts.java new file mode 100644 index 0000000000..f698a6a6d5 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthAccounts.java @@ -0,0 +1,14 @@ +package org.web3j.protocol.core.methods.response; + +import java.util.List; + +import org.web3j.protocol.core.Response; + +/** + * eth_accounts + */ +public class EthAccounts extends Response> { + public List getAccounts() { + return getResult(); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthBlock.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthBlock.java new file mode 100644 index 0000000000..a0bbd486cb --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthBlock.java @@ -0,0 +1,526 @@ +package org.web3j.protocol.core.methods.response; + +import java.io.IOException; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Optional; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.ObjectReader; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +import org.web3j.protocol.ObjectMapperFactory; +import org.web3j.protocol.core.Response; +import org.web3j.utils.Numeric; + +/** + * Block object returned by: + *
    + *
  • eth_getBlockByHash
  • + *
  • eth_getBlockByNumber
  • + *
  • eth_getUncleByBlockHashAndIndex
  • + *
  • eth_getUncleByBlockNumberAndIndex
  • + *
+ * + *

See + * docs + * for further details.

+ * + *

See the following issue for + * details on additional Parity fields present in EthBlock.

+ */ +public class EthBlock extends Response { + + @Override + @JsonDeserialize(using = EthBlock.ResponseDeserialiser.class) + public void setResult(Block result) { + super.setResult(result); + } + + public Block getBlock() { + return getResult(); + } + + public static class Block { + private String number; + private String hash; + private String parentHash; + private String nonce; + private String sha3Uncles; + private String logsBloom; + private String transactionsRoot; + private String stateRoot; + private String receiptsRoot; // geth has this wrong currently, see https://github.com/ethereum/go-ethereum/issues/3084 + private String author; + private String miner; + private String mixHash; + private String difficulty; + private String totalDifficulty; + private String extraData; + private String size; + private String gasLimit; + private String gasUsed; + private String timestamp; + private List transactions; + private List uncles; + private List sealFields; + + public Block() { + } + + public Block(String number, String hash, String parentHash, String nonce, + String sha3Uncles, String logsBloom, String transactionsRoot, + String stateRoot, String receiptsRoot, String author, String miner, + String mixHash, String difficulty, String totalDifficulty, String extraData, + String size, String gasLimit, String gasUsed, String timestamp, + List transactions, List uncles, + List sealFields) { + this.number = number; + this.hash = hash; + this.parentHash = parentHash; + this.nonce = nonce; + this.sha3Uncles = sha3Uncles; + this.logsBloom = logsBloom; + this.transactionsRoot = transactionsRoot; + this.stateRoot = stateRoot; + this.receiptsRoot = receiptsRoot; + this.author = author; + this.miner = miner; + this.mixHash = mixHash; + this.difficulty = difficulty; + this.totalDifficulty = totalDifficulty; + this.extraData = extraData; + this.size = size; + this.gasLimit = gasLimit; + this.gasUsed = gasUsed; + this.timestamp = timestamp; + this.transactions = transactions; + this.uncles = uncles; + this.sealFields = sealFields; + } + + public BigInteger getNumber() { + return Numeric.decodeQuantity(number); + } + + public String getNumberRaw() { + return number; + } + + public void setNumber(String number) { + this.number = number; + } + + public String getHash() { + return hash; + } + + public void setHash(String hash) { + this.hash = hash; + } + + public String getParentHash() { + return parentHash; + } + + public void setParentHash(String parentHash) { + this.parentHash = parentHash; + } + + public BigInteger getNonce() { + return Numeric.decodeQuantity(nonce); + } + + public String getNonceRaw() { + return nonce; + } + + public void setNonce(String nonce) { + this.nonce = nonce; + } + + public String getSha3Uncles() { + return sha3Uncles; + } + + public void setSha3Uncles(String sha3Uncles) { + this.sha3Uncles = sha3Uncles; + } + + public String getLogsBloom() { + return logsBloom; + } + + public void setLogsBloom(String logsBloom) { + this.logsBloom = logsBloom; + } + + public String getTransactionsRoot() { + return transactionsRoot; + } + + public void setTransactionsRoot(String transactionsRoot) { + this.transactionsRoot = transactionsRoot; + } + + public String getStateRoot() { + return stateRoot; + } + + public void setStateRoot(String stateRoot) { + this.stateRoot = stateRoot; + } + + public String getReceiptsRoot() { + return receiptsRoot; + } + + public void setReceiptsRoot(String receiptsRoot) { + this.receiptsRoot = receiptsRoot; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + public String getMiner() { + return miner; + } + + public void setMiner(String miner) { + this.miner = miner; + } + + public String getMixHash() { + return mixHash; + } + + public void setMixHash(String mixHash) { + this.mixHash = mixHash; + } + + public BigInteger getDifficulty() { + return Numeric.decodeQuantity(difficulty); + } + + public String getDifficultyRaw() { + return difficulty; + } + + public void setDifficulty(String difficulty) { + this.difficulty = difficulty; + } + + public BigInteger getTotalDifficulty() { + return Numeric.decodeQuantity(totalDifficulty); + } + + public String getTotalDifficultyRaw() { + return totalDifficulty; + } + + public void setTotalDifficulty(String totalDifficulty) { + this.totalDifficulty = totalDifficulty; + } + + public String getExtraData() { + return extraData; + } + + public void setExtraData(String extraData) { + this.extraData = extraData; + } + + public BigInteger getSize() { + return Numeric.decodeQuantity(size); + } + + public String getSizeRaw() { + return size; + } + + public void setSize(String size) { + this.size = size; + } + + public BigInteger getGasLimit() { + return Numeric.decodeQuantity(gasLimit); + } + + public String getGasLimitRaw() { + return gasLimit; + } + + public void setGasLimit(String gasLimit) { + this.gasLimit = gasLimit; + } + + public BigInteger getGasUsed() { + return Numeric.decodeQuantity(gasUsed); + } + + public String getGasUsedRaw() { + return gasUsed; + } + + public void setGasUsed(String gasUsed) { + this.gasUsed = gasUsed; + } + + public BigInteger getTimestamp() { + return Numeric.decodeQuantity(timestamp); + } + + public String getTimestampRaw() { + return timestamp; + } + + public void setTimestamp(String timestamp) { + this.timestamp = timestamp; + } + + public List getTransactions() { + return transactions; + } + + @JsonDeserialize(using = ResultTransactionDeserialiser.class) + public void setTransactions(List transactions) { + this.transactions = transactions; + } + + public List getUncles() { + return uncles; + } + + public void setUncles(List uncles) { + this.uncles = uncles; + } + + public List getSealFields() { + return sealFields; + } + + public void setSealFields(List sealFields) { + this.sealFields = sealFields; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof Block)) { + return false; + } + + Block block = (Block) o; + + if (getNumberRaw() != null ? !getNumberRaw().equals(block.getNumberRaw()) : block.getNumberRaw() != null) { + return false; + } + if (getHash() != null ? !getHash().equals(block.getHash()) : block.getHash() != null) { + return false; + } + if (getParentHash() != null ? !getParentHash().equals(block.getParentHash()) : block.getParentHash() != null) { + return false; + } + if (getNonceRaw() != null ? !getNonceRaw().equals(block.getNonceRaw()) : block.getNonceRaw() != null) { + return false; + } + if (getSha3Uncles() != null ? !getSha3Uncles().equals(block.getSha3Uncles()) : block.getSha3Uncles() != null) { + return false; + } + if (getLogsBloom() != null ? !getLogsBloom().equals(block.getLogsBloom()) : block.getLogsBloom() != null) { + return false; + } + if (getTransactionsRoot() != null ? !getTransactionsRoot().equals(block.getTransactionsRoot()) : block.getTransactionsRoot() != null) { + return false; + } + if (getStateRoot() != null ? !getStateRoot().equals(block.getStateRoot()) : block.getStateRoot() != null) { + return false; + } + if (getReceiptsRoot() != null ? !getReceiptsRoot().equals(block.getReceiptsRoot()) : block.getReceiptsRoot() != null) { + return false; + } + if (getAuthor() != null ? !getAuthor().equals(block.getAuthor()) : block.getAuthor() != null) { + return false; + } + if (getMiner() != null ? !getMiner().equals(block.getMiner()) : block.getMiner() != null) { + return false; + } + if (getMixHash() != null ? !getMixHash().equals(block.getMixHash()) : block.getMixHash() != null) { + return false; + } + if (getDifficultyRaw() != null ? !getDifficultyRaw().equals(block.getDifficultyRaw()) : block.getDifficultyRaw() != null) { + return false; + } + if (getTotalDifficultyRaw() != null ? !getTotalDifficultyRaw().equals(block.getTotalDifficultyRaw()) : block.getTotalDifficultyRaw() != null) { + return false; + } + if (getExtraData() != null ? !getExtraData().equals(block.getExtraData()) : block.getExtraData() != null) { + return false; + } + if (getSizeRaw() != null ? !getSizeRaw().equals(block.getSizeRaw()) : block.getSizeRaw() != null) { + return false; + } + if (getGasLimitRaw() != null ? !getGasLimitRaw().equals(block.getGasLimitRaw()) : block.getGasLimitRaw() != null) { + return false; + } + if (getGasUsedRaw() != null ? !getGasUsedRaw().equals(block.getGasUsedRaw()) : block.getGasUsedRaw() != null) { + return false; + } + if (getTimestampRaw() != null ? !getTimestampRaw().equals(block.getTimestampRaw()) : block.getTimestampRaw() != null) { + return false; + } + if (getTransactions() != null ? !getTransactions().equals(block.getTransactions()) : block.getTransactions() != null) { + return false; + } + if (getUncles() != null ? !getUncles().equals(block.getUncles()) : block.getUncles() != null) { + return false; + } + return getSealFields() != null ? getSealFields().equals(block.getSealFields()) : block.getSealFields() == null; + } + + @Override + public int hashCode() { + int result = getNumberRaw() != null ? getNumberRaw().hashCode() : 0; + result = 31 * result + (getHash() != null ? getHash().hashCode() : 0); + result = 31 * result + (getParentHash() != null ? getParentHash().hashCode() : 0); + result = 31 * result + (getNonceRaw() != null ? getNonceRaw().hashCode() : 0); + result = 31 * result + (getSha3Uncles() != null ? getSha3Uncles().hashCode() : 0); + result = 31 * result + (getLogsBloom() != null ? getLogsBloom().hashCode() : 0); + result = 31 * result + (getTransactionsRoot() != null ? getTransactionsRoot().hashCode() : 0); + result = 31 * result + (getStateRoot() != null ? getStateRoot().hashCode() : 0); + result = 31 * result + (getReceiptsRoot() != null ? getReceiptsRoot().hashCode() : 0); + result = 31 * result + (getAuthor() != null ? getAuthor().hashCode() : 0); + result = 31 * result + (getMiner() != null ? getMiner().hashCode() : 0); + result = 31 * result + (getMixHash() != null ? getMixHash().hashCode() : 0); + result = 31 * result + (getDifficultyRaw() != null ? getDifficultyRaw().hashCode() : 0); + result = 31 * result + (getTotalDifficultyRaw() != null ? getTotalDifficultyRaw().hashCode() : 0); + result = 31 * result + (getExtraData() != null ? getExtraData().hashCode() : 0); + result = 31 * result + (getSizeRaw() != null ? getSizeRaw().hashCode() : 0); + result = 31 * result + (getGasLimitRaw() != null ? getGasLimitRaw().hashCode() : 0); + result = 31 * result + (getGasUsedRaw() != null ? getGasUsedRaw().hashCode() : 0); + result = 31 * result + (getTimestampRaw() != null ? getTimestampRaw().hashCode() : 0); + result = 31 * result + (getTransactions() != null ? getTransactions().hashCode() : 0); + result = 31 * result + (getUncles() != null ? getUncles().hashCode() : 0); + result = 31 * result + (getSealFields() != null ? getSealFields().hashCode() : 0); + return result; + } + } + + public interface TransactionResult { + T get(); + } + + public static class TransactionHash implements TransactionResult { + private String value; + + public TransactionHash() { + } + + public TransactionHash(String value) { + this.value = value; + } + + @Override + public String get() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof TransactionHash)) return false; + + TransactionHash that = (TransactionHash) o; + + return value != null ? value.equals(that.value) : that.value == null; + + } + + @Override + public int hashCode() { + return value != null ? value.hashCode() : 0; + } + } + + public static class TransactionObject extends Transaction implements TransactionResult { + public TransactionObject() { + } + + public TransactionObject(String hash, String nonce, String blockHash, String blockNumber, + String transactionIndex, String from, String to, String value, + String gasPrice, String gas, String input, String creates, + String publicKey, String raw, String r, String s, int v) { + super(hash, nonce, blockHash, blockNumber, transactionIndex, from, to, value, + gasPrice, gas, input, creates, publicKey, raw, r, s, v); + } + + @Override + public Transaction get() { + return this; + } + } + + public static class ResultTransactionDeserialiser extends JsonDeserializer> { + + private ObjectReader objectReader = ObjectMapperFactory.getObjectReader(); + + @Override + public List deserialize( + JsonParser jsonParser, + DeserializationContext deserializationContext) throws IOException { + + List transactionResults = new ArrayList<>(); + JsonToken nextToken = jsonParser.nextToken(); + + if (nextToken == JsonToken.START_OBJECT) { + Iterator transactionObjectIterator = + objectReader.readValues(jsonParser, TransactionObject.class); + while (transactionObjectIterator.hasNext()) { + transactionResults.add(transactionObjectIterator.next()); + } + } else if (nextToken == JsonToken.VALUE_STRING) { + jsonParser.getValueAsString(); + + Iterator transactionHashIterator = + objectReader.readValues(jsonParser, TransactionHash.class); + while (transactionHashIterator.hasNext()) { + transactionResults.add(transactionHashIterator.next()); + } + } + + return transactionResults; + } + } + + public static class ResponseDeserialiser extends JsonDeserializer { + + private ObjectReader objectReader = ObjectMapperFactory.getObjectReader(); + + @Override + public Block deserialize( + JsonParser jsonParser, + DeserializationContext deserializationContext) throws IOException { + if (jsonParser.getCurrentToken() != JsonToken.VALUE_NULL) { + return objectReader.readValue(jsonParser, Block.class); + } else { + return null; // null is wrapped by Optional in above getter + } + } + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthBlockNumber.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthBlockNumber.java new file mode 100644 index 0000000000..b9544c8473 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthBlockNumber.java @@ -0,0 +1,15 @@ +package org.web3j.protocol.core.methods.response; + +import java.math.BigInteger; + +import org.web3j.protocol.core.Response; +import org.web3j.utils.Numeric; + +/** + * eth_blockNumber + */ +public class EthBlockNumber extends Response { + public BigInteger getBlockNumber() { + return Numeric.decodeQuantity(getResult()); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthCall.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthCall.java new file mode 100644 index 0000000000..f45d54521a --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthCall.java @@ -0,0 +1,12 @@ +package org.web3j.protocol.core.methods.response; + +import org.web3j.protocol.core.Response; + +/** + * eth_call + */ +public class EthCall extends Response { + public String getValue() { + return getResult(); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthCoinbase.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthCoinbase.java new file mode 100644 index 0000000000..76ad41cad6 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthCoinbase.java @@ -0,0 +1,12 @@ +package org.web3j.protocol.core.methods.response; + +import org.web3j.protocol.core.Response; + +/** + * eth_coinbase + */ +public class EthCoinbase extends Response { + public String getAddress() { + return getResult(); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthCompileLLL.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthCompileLLL.java new file mode 100644 index 0000000000..de90722114 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthCompileLLL.java @@ -0,0 +1,12 @@ +package org.web3j.protocol.core.methods.response; + +import org.web3j.protocol.core.Response; + +/** + * eth_compileLLL + */ +public class EthCompileLLL extends Response { + public String getCompiledSourceCode() { + return getResult(); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthCompileSerpent.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthCompileSerpent.java new file mode 100644 index 0000000000..ff65536cc3 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthCompileSerpent.java @@ -0,0 +1,12 @@ +package org.web3j.protocol.core.methods.response; + +import org.web3j.protocol.core.Response; + +/** + * eth_compileSerpent + */ +public class EthCompileSerpent extends Response { + public String getCompiledSourceCode() { + return getResult(); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthCompileSolidity.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthCompileSolidity.java new file mode 100644 index 0000000000..944570d6bd --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthCompileSolidity.java @@ -0,0 +1,247 @@ +package org.web3j.protocol.core.methods.response; + +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import org.web3j.protocol.core.Response; + +/** + * eth_compileSolidity + */ +public class EthCompileSolidity extends Response> { + + public Map getCompiledSolidity() { + return getResult(); + } + + public static class Code { + private String code; + private SolidityInfo info; + + public Code() { + } + + public Code(String code, SolidityInfo info) { + this.code = code; + this.info = info; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public SolidityInfo getInfo() { + return info; + } + + public void setInfo(SolidityInfo info) { + this.info = info; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof Code)) { + return false; + } + + Code code1 = (Code) o; + + if (getCode() != null ? !getCode().equals(code1.getCode()) : code1.getCode() != null) { + return false; + } + return getInfo() != null ? getInfo().equals(code1.getInfo()) : code1.getInfo() == null; + } + + @Override + public int hashCode() { + int result = getCode() != null ? getCode().hashCode() : 0; + result = 31 * result + (getInfo() != null ? getInfo().hashCode() : 0); + return result; + } + } + + public static class SolidityInfo { + private String source; + private String language; + private String languageVersion; + private String compilerVersion; + private String compilerOptions; + private List abiDefinition; + private Documentation userDoc; + private Documentation developerDoc; + + public SolidityInfo() { + } + + public SolidityInfo(String source, String language, String languageVersion, + String compilerVersion, String compilerOptions, + List abiDefinition, Documentation userDoc, + Documentation developerDoc) { + this.source = source; + this.language = language; + this.languageVersion = languageVersion; + this.compilerVersion = compilerVersion; + this.compilerOptions = compilerOptions; + this.abiDefinition = abiDefinition; + this.userDoc = userDoc; + this.developerDoc = developerDoc; + } + + public String getSource() { + return source; + } + + public void setSource(String source) { + this.source = source; + } + + public String getLanguage() { + return language; + } + + public void setLanguage(String language) { + this.language = language; + } + + public String getLanguageVersion() { + return languageVersion; + } + + public void setLanguageVersion(String languageVersion) { + this.languageVersion = languageVersion; + } + + public String getCompilerVersion() { + return compilerVersion; + } + + public void setCompilerVersion(String compilerVersion) { + this.compilerVersion = compilerVersion; + } + + public String getCompilerOptions() { + return compilerOptions; + } + + public void setCompilerOptions(String compilerOptions) { + this.compilerOptions = compilerOptions; + } + + public List getAbiDefinition() { + return abiDefinition; + } + + public void setAbiDefinition(List abiDefinition) { + this.abiDefinition = abiDefinition; + } + + public Documentation getUserDoc() { + return userDoc; + } + + public void setUserDoc(Documentation userDoc) { + this.userDoc = userDoc; + } + + public Documentation getDeveloperDoc() { + return developerDoc; + } + + public void setDeveloperDoc(Documentation developerDoc) { + this.developerDoc = developerDoc; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof SolidityInfo)) { + return false; + } + + SolidityInfo that = (SolidityInfo) o; + + if (getSource() != null ? !getSource().equals(that.getSource()) : that.getSource() != null) { + return false; + } + if (getLanguage() != null ? !getLanguage().equals(that.getLanguage()) : that.getLanguage() != null) { + return false; + } + if (getLanguageVersion() != null ? !getLanguageVersion().equals(that.getLanguageVersion()) : that.getLanguageVersion() != null) { + return false; + } + if (getCompilerVersion() != null ? !getCompilerVersion().equals(that.getCompilerVersion()) : that.getCompilerVersion() != null) { + return false; + } + if (getCompilerOptions() != null ? !getCompilerOptions().equals(that.getCompilerOptions()) : that.getCompilerOptions() != null) { + return false; + } + if (getAbiDefinition() != null ? !getAbiDefinition().equals(that.getAbiDefinition()) : that.getAbiDefinition() != null) { + return false; + } + if (getUserDoc() != null ? !getUserDoc().equals(that.getUserDoc()) : that.getUserDoc() != null) { + return false; + } + return getDeveloperDoc() != null ? getDeveloperDoc().equals(that.getDeveloperDoc()) : that.getDeveloperDoc() == null; + } + + @Override + public int hashCode() { + int result = getSource() != null ? getSource().hashCode() : 0; + result = 31 * result + (getLanguage() != null ? getLanguage().hashCode() : 0); + result = 31 * result + (getLanguageVersion() != null ? getLanguageVersion().hashCode() : 0); + result = 31 * result + (getCompilerVersion() != null ? getCompilerVersion().hashCode() : 0); + result = 31 * result + (getCompilerOptions() != null ? getCompilerOptions().hashCode() : 0); + result = 31 * result + (getAbiDefinition() != null ? getAbiDefinition().hashCode() : 0); + result = 31 * result + (getUserDoc() != null ? getUserDoc().hashCode() : 0); + result = 31 * result + (getDeveloperDoc() != null ? getDeveloperDoc().hashCode() : 0); + return result; + } + } + + public static class Documentation { + // No documentation available + // See https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_compilesolidity + private Map methods; // unknown object type + + public Documentation() { + this.methods = Collections.emptyMap(); + } + + public Map getMethods() { + return methods; + } + + public void setMethods(Map methods) { + this.methods = methods; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof Documentation)) { + return false; + } + + Documentation that = (Documentation) o; + + return getMethods() != null ? getMethods().equals(that.getMethods()) : that.getMethods() == null; + } + + @Override + public int hashCode() { + return getMethods() != null ? getMethods().hashCode() : 0; + } + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthEstimateGas.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthEstimateGas.java new file mode 100644 index 0000000000..04e89e4c4a --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthEstimateGas.java @@ -0,0 +1,15 @@ +package org.web3j.protocol.core.methods.response; + +import java.math.BigInteger; + +import org.web3j.protocol.core.Response; +import org.web3j.utils.Numeric; + +/** + * eth_estimateGas + */ +public class EthEstimateGas extends Response { + public BigInteger getAmountUsed() { + return Numeric.decodeQuantity(getResult()); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthFilter.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthFilter.java new file mode 100644 index 0000000000..5f8b13e865 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthFilter.java @@ -0,0 +1,15 @@ +package org.web3j.protocol.core.methods.response; + +import java.math.BigInteger; + +import org.web3j.protocol.core.Response; +import org.web3j.utils.Numeric; + +/** + * eth_newFilter + */ +public class EthFilter extends Response { + public BigInteger getFilterId() { + return Numeric.decodeQuantity(getResult()); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthGasPrice.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthGasPrice.java new file mode 100644 index 0000000000..a35c472be5 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthGasPrice.java @@ -0,0 +1,15 @@ +package org.web3j.protocol.core.methods.response; + +import java.math.BigInteger; + +import org.web3j.protocol.core.Response; +import org.web3j.utils.Numeric; + +/** + * eth_gasPrice + */ +public class EthGasPrice extends Response { + public BigInteger getGasPrice() { + return Numeric.decodeQuantity(getResult()); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthGetBalance.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthGetBalance.java new file mode 100644 index 0000000000..664df86087 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthGetBalance.java @@ -0,0 +1,15 @@ +package org.web3j.protocol.core.methods.response; + +import java.math.BigInteger; + +import org.web3j.protocol.core.Response; +import org.web3j.utils.Numeric; + +/** + * eth_getBalance + */ +public class EthGetBalance extends Response { + public BigInteger getBalance() { + return Numeric.decodeQuantity(getResult()); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthGetBlockTransactionCountByHash.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthGetBlockTransactionCountByHash.java new file mode 100644 index 0000000000..936b247c75 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthGetBlockTransactionCountByHash.java @@ -0,0 +1,15 @@ +package org.web3j.protocol.core.methods.response; + +import java.math.BigInteger; + +import org.web3j.protocol.core.Response; +import org.web3j.utils.Numeric; + +/** + * eth_getBlockTransactionCountByHash + */ +public class EthGetBlockTransactionCountByHash extends Response { + public BigInteger getTransactionCount() { + return Numeric.decodeQuantity(getResult()); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthGetBlockTransactionCountByNumber.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthGetBlockTransactionCountByNumber.java new file mode 100644 index 0000000000..80f56f4cc1 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthGetBlockTransactionCountByNumber.java @@ -0,0 +1,15 @@ +package org.web3j.protocol.core.methods.response; + +import java.math.BigInteger; + +import org.web3j.protocol.core.Response; +import org.web3j.utils.Numeric; + +/** + * eth_getBlockTransactionCountByNumber + */ +public class EthGetBlockTransactionCountByNumber extends Response { + public BigInteger getTransactionCount() { + return Numeric.decodeQuantity(getResult()); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthGetCode.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthGetCode.java new file mode 100644 index 0000000000..7fda2f0c73 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthGetCode.java @@ -0,0 +1,12 @@ +package org.web3j.protocol.core.methods.response; + +import org.web3j.protocol.core.Response; + +/** + * eth_getCode + */ +public class EthGetCode extends Response { + public String getCode() { + return getResult(); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthGetCompilers.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthGetCompilers.java new file mode 100644 index 0000000000..f43a8749a9 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthGetCompilers.java @@ -0,0 +1,14 @@ +package org.web3j.protocol.core.methods.response; + +import java.util.List; + +import org.web3j.protocol.core.Response; + +/** + * eth_getCompilers + */ +public class EthGetCompilers extends Response> { + public List getCompilers() { + return getResult(); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthGetStorageAt.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthGetStorageAt.java new file mode 100644 index 0000000000..a96b51f298 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthGetStorageAt.java @@ -0,0 +1,12 @@ +package org.web3j.protocol.core.methods.response; + +import org.web3j.protocol.core.Response; + +/** + * eth_getStorageAt + */ +public class EthGetStorageAt extends Response { + public String getData() { + return getResult(); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthGetTransactionCount.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthGetTransactionCount.java new file mode 100644 index 0000000000..d236a3dd97 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthGetTransactionCount.java @@ -0,0 +1,15 @@ +package org.web3j.protocol.core.methods.response; + +import java.math.BigInteger; + +import org.web3j.protocol.core.Response; +import org.web3j.utils.Numeric; + +/** + * eth_getTransactionCount + */ +public class EthGetTransactionCount extends Response { + public BigInteger getTransactionCount() { + return Numeric.decodeQuantity(getResult()); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthGetTransactionReceipt.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthGetTransactionReceipt.java new file mode 100644 index 0000000000..fb58f367a3 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthGetTransactionReceipt.java @@ -0,0 +1,39 @@ +package org.web3j.protocol.core.methods.response; + +import java.io.IOException; +import java.util.Optional; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.ObjectReader; + +import org.web3j.protocol.ObjectMapperFactory; +import org.web3j.protocol.core.Response; + +/** + * eth_getTransactionReceipt + */ +public class EthGetTransactionReceipt extends Response { + + public Optional getTransactionReceipt() { + return Optional.ofNullable(getResult()); + } + + public static class ResponseDeserialiser extends JsonDeserializer { + + private ObjectReader objectReader = ObjectMapperFactory.getObjectReader(); + + @Override + public TransactionReceipt deserialize( + JsonParser jsonParser, + DeserializationContext deserializationContext) throws IOException { + if (jsonParser.getCurrentToken() != JsonToken.VALUE_NULL) { + return objectReader.readValue(jsonParser, TransactionReceipt.class); + } else { + return null; // null is wrapped by Optional in above getter + } + } + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthGetUncleCountByBlockHash.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthGetUncleCountByBlockHash.java new file mode 100644 index 0000000000..78670f8a11 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthGetUncleCountByBlockHash.java @@ -0,0 +1,15 @@ +package org.web3j.protocol.core.methods.response; + +import java.math.BigInteger; + +import org.web3j.protocol.core.Response; +import org.web3j.utils.Numeric; + +/** + * eth_getUncleCountByBlockHash + */ +public class EthGetUncleCountByBlockHash extends Response { + public BigInteger getUncleCount() { + return Numeric.decodeQuantity(getResult()); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthGetUncleCountByBlockNumber.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthGetUncleCountByBlockNumber.java new file mode 100644 index 0000000000..d1451f15c0 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthGetUncleCountByBlockNumber.java @@ -0,0 +1,15 @@ +package org.web3j.protocol.core.methods.response; + +import java.math.BigInteger; + +import org.web3j.protocol.core.Response; +import org.web3j.utils.Numeric; + +/** + * eth_getUncleCountByBlockNumber + */ +public class EthGetUncleCountByBlockNumber extends Response { + public BigInteger getUncleCount() { + return Numeric.decodeQuantity(getResult()); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthGetWork.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthGetWork.java new file mode 100644 index 0000000000..cbe5a79cc6 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthGetWork.java @@ -0,0 +1,23 @@ +package org.web3j.protocol.core.methods.response; + +import java.util.List; + +import org.web3j.protocol.core.Response; + +/** + * eth_getWork + */ +public class EthGetWork extends Response> { + + public String getCurrentBlockHeaderPowHash() { + return getResult().get(0); + } + + public String getSeedHashForDag() { + return getResult().get(1); + } + + public String getBoundaryCondition() { + return getResult().get(2); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthHashrate.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthHashrate.java new file mode 100644 index 0000000000..aea68dbcdd --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthHashrate.java @@ -0,0 +1,15 @@ +package org.web3j.protocol.core.methods.response; + +import java.math.BigInteger; + +import org.web3j.protocol.core.Response; +import org.web3j.utils.Numeric; + +/** + * eth_hashrate + */ +public class EthHashrate extends Response { + public BigInteger getHashrate() { + return Numeric.decodeQuantity(getResult()); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthLog.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthLog.java new file mode 100644 index 0000000000..e8e6025941 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthLog.java @@ -0,0 +1,134 @@ +package org.web3j.protocol.core.methods.response; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.ObjectReader; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +import org.web3j.protocol.ObjectMapperFactory; +import org.web3j.protocol.core.Response; + +/** + * Log object returned by: + *
    + *
  • eth_getFilterChanges
  • + *
  • eth_getFilterLogs
  • + *
  • eth_getLogs
  • + *
+ * + *

See + * docs + * for further details.

+ */ +public class EthLog extends Response> { + + @Override + @JsonDeserialize(using = LogResultDeserialiser.class) + public void setResult(List result) { + super.setResult(result); + } + + public List getLogs() { + return getResult(); + } + + public interface LogResult { + T get(); + } + + public static class LogObject extends Log implements LogResult { + + public LogObject() { + } + + public LogObject(boolean removed, String logIndex, String transactionIndex, + String transactionHash, String blockHash, String blockNumber, + String address, String data, String type, List topics) { + super(removed, logIndex, transactionIndex, transactionHash, blockHash, blockNumber, + address, data, type, topics); + } + + @Override + public Log get() { + return this; + } + } + + public static class Hash implements LogResult { + private String value; + + public Hash() { + } + + public Hash(String value) { + this.value = value; + } + + @Override + public String get() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof Hash)) { + return false; + } + + Hash hash = (Hash) o; + + return value != null ? value.equals(hash.value) : hash.value == null; + } + + @Override + public int hashCode() { + return value != null ? value.hashCode() : 0; + } + } + + + public static class LogResultDeserialiser extends JsonDeserializer> { + + private ObjectReader objectReader = ObjectMapperFactory.getObjectReader(); + + @Override + public List deserialize( + JsonParser jsonParser, + DeserializationContext deserializationContext) throws IOException { + + List logResults = new ArrayList<>(); + JsonToken nextToken = jsonParser.nextToken(); + + if (nextToken == JsonToken.START_OBJECT) { + Iterator logObjectIterator = + objectReader.readValues(jsonParser, LogObject.class); + while (logObjectIterator.hasNext()) { + logResults.add(logObjectIterator.next()); + } + } else if (nextToken == JsonToken.VALUE_STRING) { + jsonParser.getValueAsString(); + + Iterator transactionHashIterator = + objectReader.readValues(jsonParser, Hash.class); + while (transactionHashIterator.hasNext()) { + logResults.add(transactionHashIterator.next()); + } + } + return logResults; + } + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthMining.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthMining.java new file mode 100644 index 0000000000..087d6cd7a8 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthMining.java @@ -0,0 +1,12 @@ +package org.web3j.protocol.core.methods.response; + +import org.web3j.protocol.core.Response; + +/** + * eth_mining + */ +public class EthMining extends Response { + public boolean isMining() { + return getResult(); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthProtocolVersion.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthProtocolVersion.java new file mode 100644 index 0000000000..f5148cc407 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthProtocolVersion.java @@ -0,0 +1,12 @@ +package org.web3j.protocol.core.methods.response; + +import org.web3j.protocol.core.Response; + +/** + * eth_protocolVersion + */ +public class EthProtocolVersion extends Response { + public String getProtocolVersion() { + return getResult(); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthSendRawTransaction.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthSendRawTransaction.java new file mode 100644 index 0000000000..851e2f925b --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthSendRawTransaction.java @@ -0,0 +1,12 @@ +package org.web3j.protocol.core.methods.response; + +import org.web3j.protocol.core.Response; + +/** + * eth_sendRawTransaction + */ +public class EthSendRawTransaction extends Response { + public String getTransactionHash() { + return getResult(); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthSendTransaction.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthSendTransaction.java new file mode 100644 index 0000000000..12aa3bfd71 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthSendTransaction.java @@ -0,0 +1,12 @@ +package org.web3j.protocol.core.methods.response; + +import org.web3j.protocol.core.Response; + +/** + * eth_sendTransaction + */ +public class EthSendTransaction extends Response { + public String getTransactionHash() { + return getResult(); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthSign.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthSign.java new file mode 100644 index 0000000000..71b5990774 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthSign.java @@ -0,0 +1,12 @@ +package org.web3j.protocol.core.methods.response; + +import org.web3j.protocol.core.Response; + +/** + * eth_sign + */ +public class EthSign extends Response { + public String getSignature() { + return getResult(); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthSubmitHashrate.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthSubmitHashrate.java new file mode 100644 index 0000000000..08bb16fb62 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthSubmitHashrate.java @@ -0,0 +1,13 @@ +package org.web3j.protocol.core.methods.response; + +import org.web3j.protocol.core.Response; + +/** + * eth_submitHashrate + */ +public class EthSubmitHashrate extends Response { + + public boolean submissionSuccessful() { + return getResult(); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthSubmitWork.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthSubmitWork.java new file mode 100644 index 0000000000..45f2570a04 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthSubmitWork.java @@ -0,0 +1,13 @@ +package org.web3j.protocol.core.methods.response; + +import org.web3j.protocol.core.Response; + +/** + * eth_submitWork + */ +public class EthSubmitWork extends Response { + + public boolean solutionValid() { + return getResult(); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthSyncing.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthSyncing.java new file mode 100644 index 0000000000..8af1e189f5 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthSyncing.java @@ -0,0 +1,152 @@ +package org.web3j.protocol.core.methods.response; + + +import java.io.IOException; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.ObjectReader; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +import org.web3j.protocol.ObjectMapperFactory; +import org.web3j.protocol.core.Response; + +/** + * eth_syncing + *

+ * Returns an object with data about the sync status or false. + */ +public class EthSyncing extends Response { + + @Override + @JsonDeserialize(using = EthSyncing.ResponseDeserialiser.class) + public void setResult(EthSyncing.Result result) { + super.setResult(result); + } + + public boolean isSyncing() { + return getResult().isSyncing(); + } + + public static class Result { + private boolean isSyncing = true; + + public Result() { + } + + public boolean isSyncing() { + return isSyncing; + } + + public void setSyncing(boolean syncing) { + isSyncing = syncing; + } + } + + @JsonIgnoreProperties({"knownStates", "pulledStates"}) + // these fields although not present in the RPC specification are returned by Geth 1.4.10 + public static class Syncing extends Result { + + private String startingBlock; + private String currentBlock; + private String highestBlock; + private String knownStates; + private String pulledStates; + + public Syncing() { + } + + public Syncing(String startingBlock, String currentBlock, String highestBlock, String knownStates, String pulledStates) { + this.startingBlock = startingBlock; + this.currentBlock = currentBlock; + this.highestBlock = highestBlock; + this.knownStates = knownStates; + this.pulledStates = pulledStates; + } + + public String getStartingBlock() { + return startingBlock; + } + + public void setStartingBlock(String startingBlock) { + this.startingBlock = startingBlock; + } + + public String getCurrentBlock() { + return currentBlock; + } + + public void setCurrentBlock(String currentBlock) { + this.currentBlock = currentBlock; + } + + public String getHighestBlock() { + return highestBlock; + } + + public void setHighestBlock(String highestBlock) { + this.highestBlock = highestBlock; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof Syncing)) { + return false; + } + + Syncing syncing = (Syncing) o; + + if (isSyncing() != syncing.isSyncing()) { + return false; + } + if (getStartingBlock() != null ? !getStartingBlock().equals(syncing.getStartingBlock()) : syncing.getStartingBlock() != null) { + return false; + } + if (getCurrentBlock() != null ? !getCurrentBlock().equals(syncing.getCurrentBlock()) : syncing.getCurrentBlock() != null) { + return false; + } + if (getHighestBlock() != null ? !getHighestBlock().equals(syncing.getHighestBlock()) : syncing.getHighestBlock() != null) { + return false; + } + if (knownStates != null ? !knownStates.equals(syncing.knownStates) : syncing.knownStates != null) { + return false; + } + return pulledStates != null ? pulledStates.equals(syncing.pulledStates) : syncing.pulledStates == null; + } + + @Override + public int hashCode() { + int result = getStartingBlock() != null ? getStartingBlock().hashCode() : 0; + result = 31 * result + Boolean.hashCode(isSyncing()); + result = 31 * result + (getCurrentBlock() != null ? getCurrentBlock().hashCode() : 0); + result = 31 * result + (getHighestBlock() != null ? getHighestBlock().hashCode() : 0); + result = 31 * result + (knownStates != null ? knownStates.hashCode() : 0); + result = 31 * result + (pulledStates != null ? pulledStates.hashCode() : 0); + return result; + } + } + + public static class ResponseDeserialiser extends JsonDeserializer { + + private ObjectReader objectReader = ObjectMapperFactory.getObjectReader(); + + @Override + public Result deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) + throws IOException { + Result result; + if (jsonParser.getCurrentToken() == JsonToken.VALUE_FALSE) { + result = new Result(); + result.setSyncing(jsonParser.getBooleanValue()); + } else { + result = objectReader.readValue(jsonParser, Syncing.class); + } + return result; + } + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthTransaction.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthTransaction.java new file mode 100644 index 0000000000..7fe243cf77 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthTransaction.java @@ -0,0 +1,50 @@ +package org.web3j.protocol.core.methods.response; + +import java.io.IOException; +import java.util.Optional; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.ObjectReader; + +import org.web3j.protocol.ObjectMapperFactory; +import org.web3j.protocol.core.Response; + +/** + * Transaction object returned by: + *

    + *
  • eth_getTransactionByHash
  • + *
  • eth_getTransactionByBlockHashAndIndex
  • + *
  • eth_getTransactionByBlockNumberAndIndex
  • + *
+ * + *

This differs slightly from the request {@link EthSendTransaction} Transaction object.

+ * + *

See + * docs + * for further details.

+ */ +public class EthTransaction extends Response { + + public Optional getTransaction() { + return Optional.ofNullable(getResult()); + } + + public static class ResponseDeserialiser extends JsonDeserializer { + + private ObjectReader objectReader = ObjectMapperFactory.getObjectReader(); + + @Override + public Transaction deserialize( + JsonParser jsonParser, + DeserializationContext deserializationContext) throws IOException { + if (jsonParser.getCurrentToken() != JsonToken.VALUE_NULL) { + return objectReader.readValue(jsonParser, Transaction.class); + } else { + return null; // null is wrapped by Optional in above getter + } + } + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthUninstallFilter.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthUninstallFilter.java new file mode 100644 index 0000000000..7ffb5e2acd --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/EthUninstallFilter.java @@ -0,0 +1,12 @@ +package org.web3j.protocol.core.methods.response; + +import org.web3j.protocol.core.Response; + +/** + * eth_uninstallFilter + */ +public class EthUninstallFilter extends Response { + public boolean isUninstalled() { + return getResult(); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/Log.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/Log.java new file mode 100644 index 0000000000..ccee127176 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/Log.java @@ -0,0 +1,200 @@ +package org.web3j.protocol.core.methods.response; + +import java.math.BigInteger; +import java.util.List; + +import org.web3j.utils.Numeric; + +/** + *

Log object used by {@link EthLog} and {@link EthGetTransactionReceipt}.

+ *

It's not clear in the + * docs + * If only a list of hashes are returned for filters created with eth_newBlockFilter or + * eth_newPendingTransactionFilter.

+ */ +public class Log { + private boolean removed; + private String logIndex; + private String transactionIndex; + private String transactionHash; + private String blockHash; + private String blockNumber; + private String address; + private String data; + private String type; + private List topics; + + public Log() { + } + + public Log(boolean removed, String logIndex, String transactionIndex, String transactionHash, + String blockHash, String blockNumber, String address, String data, String type, + List topics) { + this.removed = removed; + this.logIndex = logIndex; + this.transactionIndex = transactionIndex; + this.transactionHash = transactionHash; + this.blockHash = blockHash; + this.blockNumber = blockNumber; + this.address = address; + this.data = data; + this.type = type; + this.topics = topics; + } + + public boolean isRemoved() { + return removed; + } + + public void setRemoved(boolean removed) { + this.removed = removed; + } + + public BigInteger getLogIndex() { + return convert(logIndex); + } + + public String getLogIndexRaw() { + return logIndex; + } + + public void setLogIndex(String logIndex) { + this.logIndex = logIndex; + } + + public BigInteger getTransactionIndex() { + return convert(transactionIndex); + } + + public String getTransactionIndexRaw() { + return transactionIndex; + } + + public void setTransactionIndex(String transactionIndex) { + this.transactionIndex = transactionIndex; + } + + public String getTransactionHash() { + return transactionHash; + } + + public void setTransactionHash(String transactionHash) { + this.transactionHash = transactionHash; + } + + public String getBlockHash() { + return blockHash; + } + + public void setBlockHash(String blockHash) { + this.blockHash = blockHash; + } + + public BigInteger getBlockNumber() { + return convert(blockNumber); + } + + public String getBlockNumberRaw() { + return blockNumber; + } + + public void setBlockNumber(String blockNumber) { + this.blockNumber = blockNumber; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public String getData() { + return data; + } + + public void setData(String data) { + this.data = data; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public List getTopics() { + return topics; + } + + public void setTopics(List topics) { + this.topics = topics; + } + + private BigInteger convert(String value) { + if (value != null) { + return Numeric.decodeQuantity(value); + } else { + return null; + } + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof Log)) { + return false; + } + + Log log = (Log) o; + + if (isRemoved() != log.isRemoved()) { + return false; + } + if (getLogIndexRaw() != null ? !getLogIndexRaw().equals(log.getLogIndexRaw()) : log.getLogIndexRaw() != null) { + return false; + } + if (getTransactionIndexRaw() != null ? !getTransactionIndexRaw().equals(log.getTransactionIndexRaw()) : log.getTransactionIndexRaw() != null) { + return false; + } + if (getTransactionHash() != null ? !getTransactionHash().equals(log.getTransactionHash()) : log.getTransactionHash() != null) { + return false; + } + if (getBlockHash() != null ? !getBlockHash().equals(log.getBlockHash()) : log.getBlockHash() != null) { + return false; + } + if (getBlockNumberRaw() != null ? !getBlockNumberRaw().equals(log.getBlockNumberRaw()) : log.getBlockNumberRaw() != null) { + return false; + } + if (getAddress() != null ? !getAddress().equals(log.getAddress()) : log.getAddress() != null) { + return false; + } + if (getData() != null ? !getData().equals(log.getData()) : log.getData() != null) { + return false; + } + if (getType() != null ? !getType().equals(log.getType()) : log.getType() != null) { + return false; + } + return getTopics() != null ? getTopics().equals(log.getTopics()) : log.getTopics() == null; + } + + @Override + public int hashCode() { + int result = (isRemoved() ? 1 : 0); + result = 31 * result + (getLogIndexRaw() != null ? getLogIndexRaw().hashCode() : 0); + result = 31 * result + (getTransactionIndexRaw() != null ? getTransactionIndexRaw().hashCode() : 0); + result = 31 * result + (getTransactionHash() != null ? getTransactionHash().hashCode() : 0); + result = 31 * result + (getBlockHash() != null ? getBlockHash().hashCode() : 0); + result = 31 * result + (getBlockNumberRaw() != null ? getBlockNumberRaw().hashCode() : 0); + result = 31 * result + (getAddress() != null ? getAddress().hashCode() : 0); + result = 31 * result + (getData() != null ? getData().hashCode() : 0); + result = 31 * result + (getType() != null ? getType().hashCode() : 0); + result = 31 * result + (getTopics() != null ? getTopics().hashCode() : 0); + return result; + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/NetListening.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/NetListening.java new file mode 100644 index 0000000000..853974f134 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/NetListening.java @@ -0,0 +1,12 @@ +package org.web3j.protocol.core.methods.response; + +import org.web3j.protocol.core.Response; + +/** + * net_listening + */ +public class NetListening extends Response { + public boolean isListening() { + return getResult(); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/NetPeerCount.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/NetPeerCount.java new file mode 100644 index 0000000000..27f648420d --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/NetPeerCount.java @@ -0,0 +1,16 @@ +package org.web3j.protocol.core.methods.response; + +import java.math.BigInteger; + +import org.web3j.protocol.core.Response; +import org.web3j.utils.Numeric; + +/** + * net_peerCount + */ +public class NetPeerCount extends Response { + + public BigInteger getQuantity() { + return Numeric.decodeQuantity(getResult()); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/NetVersion.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/NetVersion.java new file mode 100644 index 0000000000..7039a515ba --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/NetVersion.java @@ -0,0 +1,12 @@ +package org.web3j.protocol.core.methods.response; + +import org.web3j.protocol.core.Response; + +/** + * net_version + */ +public class NetVersion extends Response { + public String getNetVersion() { + return getResult(); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/ShhAddToGroup.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/ShhAddToGroup.java new file mode 100644 index 0000000000..950712a0d8 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/ShhAddToGroup.java @@ -0,0 +1,13 @@ +package org.web3j.protocol.core.methods.response; + +import org.web3j.protocol.core.Response; + +/** + * shh_addToGroup + */ +public class ShhAddToGroup extends Response { + + public boolean addedToGroup() { + return getResult(); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/ShhHasIdentity.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/ShhHasIdentity.java new file mode 100644 index 0000000000..69fa61f104 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/ShhHasIdentity.java @@ -0,0 +1,13 @@ +package org.web3j.protocol.core.methods.response; + +import org.web3j.protocol.core.Response; + +/** + * shh_hasIdentity + */ +public class ShhHasIdentity extends Response { + + public boolean hasPrivateKeyForIdentity() { + return getResult(); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/ShhMessages.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/ShhMessages.java new file mode 100644 index 0000000000..2ac3171713 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/ShhMessages.java @@ -0,0 +1,193 @@ +package org.web3j.protocol.core.methods.response; + +import java.math.BigInteger; +import java.util.List; + +import org.web3j.protocol.core.Response; +import org.web3j.utils.Numeric; + +/** + * Whisper messages returned by: + *
    + *
  • shh_getFilterChanges
  • + *
  • shh_getMessages
  • + *
+ * + *

See + * docs + * for further details.

+ */ +public class ShhMessages extends Response> { + + public List getMessages() { + return getResult(); + } + + public static class SshMessage { + private String hash; + private String from; + private String to; + private String expiry; + private String ttl; + private String sent; + private List topics; + private String payload; + private String workProved; + + public SshMessage() { + } + + public SshMessage(String hash, String from, String to, String expiry, String ttl, + String sent, List topics, String payload, String workProved) { + this.hash = hash; + this.from = from; + this.to = to; + this.expiry = expiry; + this.ttl = ttl; + this.sent = sent; + this.topics = topics; + this.payload = payload; + this.workProved = workProved; + } + + public String getHash() { + return hash; + } + + public void setHash(String hash) { + this.hash = hash; + } + + public String getFrom() { + return from; + } + + public void setFrom(String from) { + this.from = from; + } + + public String getTo() { + return to; + } + + public void setTo(String to) { + this.to = to; + } + + public BigInteger getExpiry() { + return Numeric.decodeQuantity(expiry); + } + + public String getExpiryRaw() { + return expiry; + } + + public void setExpiry(String expiry) { + this.expiry = expiry; + } + + public BigInteger getTtl() { + return Numeric.decodeQuantity(ttl); + } + + public String getTtlRaw() { + return ttl; + } + + public void setTtl(String ttl) { + this.ttl = ttl; + } + + public BigInteger getSent() { + return Numeric.decodeQuantity(sent); + } + + public String getSentRaw() { + return sent; + } + + public void setSent(String sent) { + this.sent = sent; + } + + public List getTopics() { + return topics; + } + + public void setTopics(List topics) { + this.topics = topics; + } + + public String getPayload() { + return payload; + } + + public void setPayload(String payload) { + this.payload = payload; + } + + public BigInteger getWorkProved() { + return Numeric.decodeQuantity(workProved); + } + + public String getWorkProvedRaw() { + return workProved; + } + + public void setWorkProved(String workProved) { + this.workProved = workProved; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof SshMessage)) { + return false; + } + + SshMessage that = (SshMessage) o; + + if (getHash() != null ? !getHash().equals(that.getHash()) : that.getHash() != null) { + return false; + } + if (getFrom() != null ? !getFrom().equals(that.getFrom()) : that.getFrom() != null) { + return false; + } + if (getTo() != null ? !getTo().equals(that.getTo()) : that.getTo() != null) { + return false; + } + if (getExpiryRaw() != null ? !getExpiryRaw().equals(that.getExpiryRaw()) : that.getExpiryRaw() != null) { + return false; + } + if (getTtlRaw() != null ? !getTtlRaw().equals(that.getTtlRaw()) : that.getTtlRaw() != null) { + return false; + } + if (getSentRaw() != null ? !getSentRaw().equals(that.getSentRaw()) : that.getSentRaw() != null) { + return false; + } + if (getTopics() != null ? !getTopics().equals(that.getTopics()) : that.getTopics() != null) { + return false; + } + if (getPayload() != null ? !getPayload().equals(that.getPayload()) : that.getPayload() != null) { + return false; + } + return getWorkProvedRaw() != null ? getWorkProvedRaw().equals(that.getWorkProvedRaw()) : that.getWorkProvedRaw() == null; + } + + @Override + public int hashCode() { + int result = getHash() != null ? getHash().hashCode() : 0; + result = 31 * result + (getFrom() != null ? getFrom().hashCode() : 0); + result = 31 * result + (getTo() != null ? getTo().hashCode() : 0); + result = 31 * result + (getExpiryRaw() != null ? getExpiryRaw().hashCode() : 0); + result = 31 * result + (getTtlRaw() != null ? getTtlRaw().hashCode() : 0); + result = 31 * result + (getSentRaw() != null ? getSentRaw().hashCode() : 0); + result = 31 * result + (getTopics() != null ? getTopics().hashCode() : 0); + result = 31 * result + (getPayload() != null ? getPayload().hashCode() : 0); + result = 31 * result + (getWorkProvedRaw() != null ? getWorkProvedRaw().hashCode() : 0); + return result; + } + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/ShhNewFilter.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/ShhNewFilter.java new file mode 100644 index 0000000000..4c8699217e --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/ShhNewFilter.java @@ -0,0 +1,16 @@ +package org.web3j.protocol.core.methods.response; + +import java.math.BigInteger; + +import org.web3j.protocol.core.Response; +import org.web3j.utils.Numeric; + +/** + * shh_newFilter + */ +public class ShhNewFilter extends Response { + + public BigInteger getFilterId() { + return Numeric.decodeQuantity(getResult()); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/ShhNewGroup.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/ShhNewGroup.java new file mode 100644 index 0000000000..6b949f7556 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/ShhNewGroup.java @@ -0,0 +1,13 @@ +package org.web3j.protocol.core.methods.response; + +import org.web3j.protocol.core.Response; + +/** + * shh_newGroup + */ +public class ShhNewGroup extends Response { + + public String getAddress() { + return getResult(); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/ShhNewIdentity.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/ShhNewIdentity.java new file mode 100644 index 0000000000..4e70ab6a8a --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/ShhNewIdentity.java @@ -0,0 +1,13 @@ +package org.web3j.protocol.core.methods.response; + +import org.web3j.protocol.core.Response; + +/** + * shh_newIdentity + */ +public class ShhNewIdentity extends Response { + + public String getAddress() { + return getResult(); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/ShhPost.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/ShhPost.java new file mode 100644 index 0000000000..5e08a642ed --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/ShhPost.java @@ -0,0 +1,13 @@ +package org.web3j.protocol.core.methods.response; + +import org.web3j.protocol.core.Response; + +/** + * shh_post + */ +public class ShhPost extends Response { + + public boolean messageSent() { + return getResult(); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/ShhUninstallFilter.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/ShhUninstallFilter.java new file mode 100644 index 0000000000..dbbd49daa1 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/ShhUninstallFilter.java @@ -0,0 +1,13 @@ +package org.web3j.protocol.core.methods.response; + +import org.web3j.protocol.core.Response; + +/** + * shh_uninstallFilter + */ +public class ShhUninstallFilter extends Response { + + public boolean isUninstalled() { + return getResult(); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/ShhVersion.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/ShhVersion.java new file mode 100644 index 0000000000..831018b44e --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/ShhVersion.java @@ -0,0 +1,13 @@ +package org.web3j.protocol.core.methods.response; + +import org.web3j.protocol.core.Response; + +/** + * shh_version + */ +public class ShhVersion extends Response { + + public String getVersion() { + return getResult(); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/Transaction.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/Transaction.java new file mode 100644 index 0000000000..6067e3080a --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/Transaction.java @@ -0,0 +1,309 @@ +package org.web3j.protocol.core.methods.response; + +import java.math.BigInteger; + +import org.web3j.utils.Numeric; + +/** + * Transaction object used by both {@link EthTransaction} and {@link EthBlock}. + */ +public class Transaction { + private String hash; + private String nonce; + private String blockHash; + private String blockNumber; + private String transactionIndex; + private String from; + private String to; + private String value; + private String gasPrice; + private String gas; + private String input; + private String creates; + private String publicKey; + private String raw; + private String r; + private String s; + private int v; // see https://github.com/web3j/web3j/issues/44 + + public Transaction() { + } + + public Transaction(String hash, String nonce, String blockHash, String blockNumber, + String transactionIndex, String from, String to, String value, + String gas, String gasPrice, String input, String creates, + String publicKey, String raw, String r, String s, int v) { + this.hash = hash; + this.nonce = nonce; + this.blockHash = blockHash; + this.blockNumber = blockNumber; + this.transactionIndex = transactionIndex; + this.from = from; + this.to = to; + this.value = value; + this.gasPrice = gasPrice; + this.gas = gas; + this.input = input; + this.creates = creates; + this.publicKey = publicKey; + this.raw = raw; + this.r = r; + this.s = s; + this.v = v; + } + + public String getHash() { + return hash; + } + + public void setHash(String hash) { + this.hash = hash; + } + + public BigInteger getNonce() { + return Numeric.decodeQuantity(nonce); + } + + public String getNonceRaw() { + return nonce; + } + + public void setNonce(String nonce) { + this.nonce = nonce; + } + + public String getBlockHash() { + return blockHash; + } + + public void setBlockHash(String blockHash) { + this.blockHash = blockHash; + } + + public BigInteger getBlockNumber() { + return Numeric.decodeQuantity(blockNumber); + } + + public String getBlockNumberRaw() { + return blockNumber; + } + + public void setBlockNumber(String blockNumber) { + this.blockNumber = blockNumber; + } + + public BigInteger getTransactionIndex() { + return Numeric.decodeQuantity(transactionIndex); + } + + public String getTransactionIndexRaw() { + return transactionIndex; + } + + public void setTransactionIndex(String transactionIndex) { + this.transactionIndex = transactionIndex; + } + + public String getFrom() { + return from; + } + + public void setFrom(String from) { + this.from = from; + } + + public String getTo() { + return to; + } + + public void setTo(String to) { + this.to = to; + } + + public BigInteger getValue() { + return Numeric.decodeQuantity(value); + } + + public String getValueRaw() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public BigInteger getGasPrice() { + return Numeric.decodeQuantity(gasPrice); + } + + public String getGasPriceRaw() { + return gasPrice; + } + + public void setGasPrice(String gasPrice) { + this.gasPrice = gasPrice; + } + + public BigInteger getGas() { + return Numeric.decodeQuantity(gas); + } + + public String getGasRaw() { + return gas; + } + + public void setGas(String gas) { + this.gas = gas; + } + + public String getInput() { + return input; + } + + public void setInput(String input) { + this.input = input; + } + + public String getCreates() { + return creates; + } + + public void setCreates(String creates) { + this.creates = creates; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getRaw() { + return raw; + } + + public void setRaw(String raw) { + this.raw = raw; + } + + public String getR() { + return r; + } + + public void setR(String r) { + this.r = r; + } + + public String getS() { + return s; + } + + public void setS(String s) { + this.s = s; + } + + public int getV() { + return v; + } + +// public void setV(byte v) { +// this.v = v; +// } + + // Workaround until Geth & Parity return consistent values. At present + // Parity returns a byte value, Geth returns a hex-encoded string + // https://github.com/ethereum/go-ethereum/issues/3339 + public void setV(Object v) { + if (v instanceof String) { + this.v = Numeric.toBigInt((String) v).intValueExact(); + } else { + this.v = ((Integer) v); + } + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof Transaction)) { + return false; + } + + Transaction that = (Transaction) o; + + if (getV() != that.getV()) { + return false; + } + if (getHash() != null ? !getHash().equals(that.getHash()) : that.getHash() != null) { + return false; + } + if (getNonceRaw() != null ? !getNonceRaw().equals(that.getNonceRaw()) : that.getNonceRaw() != null) { + return false; + } + if (getBlockHash() != null ? !getBlockHash().equals(that.getBlockHash()) : that.getBlockHash() != null) { + return false; + } + if (getBlockNumberRaw() != null ? !getBlockNumberRaw().equals(that.getBlockNumberRaw()) : that.getBlockNumberRaw()!= null) { + return false; + } + if (getTransactionIndexRaw() != null ? !getTransactionIndexRaw().equals(that.getTransactionIndexRaw()) : that.getTransactionIndexRaw() != null) { + return false; + } + if (getFrom() != null ? !getFrom().equals(that.getFrom()) : that.getFrom() != null) { + return false; + } + if (getTo() != null ? !getTo().equals(that.getTo()) : that.getTo() != null) { + return false; + } + if (getValueRaw() != null ? !getValueRaw().equals(that.getValueRaw()) : that.getValueRaw()!= null) { + return false; + } + if (getGasPriceRaw() != null ? !getGasPriceRaw().equals(that.getGasPriceRaw()) : that.getGasPriceRaw() != null) { + return false; + } + if (getGasRaw() != null ? !getGasRaw().equals(that.getGasRaw()) : that.getGasRaw() != null) { + return false; + } + if (getInput() != null ? !getInput().equals(that.getInput()) : that.getInput() != null) { + return false; + } + if (getCreates() != null ? !getCreates().equals(that.getCreates()) : that.getCreates() != null) { + return false; + } + if (getPublicKey() != null ? !getPublicKey().equals(that.getPublicKey()) : that.getPublicKey() != null) { + return false; + } + if (getRaw() != null ? !getRaw().equals(that.getRaw()) : that.getRaw() != null) { + return false; + } + if (getR() != null ? !getR().equals(that.getR()) : that.getR() != null) { + return false; + } + return getS() != null ? getS().equals(that.getS()) : that.getS() == null; + } + + @Override + public int hashCode() { + int result = getHash() != null ? getHash().hashCode() : 0; + result = 31 * result + (getNonceRaw() != null ? getNonceRaw().hashCode() : 0); + result = 31 * result + (getBlockHash() != null ? getBlockHash().hashCode() : 0); + result = 31 * result + (getBlockNumberRaw() != null ? getBlockNumberRaw().hashCode() : 0); + result = 31 * result + (getTransactionIndexRaw() != null ? getTransactionIndexRaw().hashCode() : 0); + result = 31 * result + (getFrom() != null ? getFrom().hashCode() : 0); + result = 31 * result + (getTo() != null ? getTo().hashCode() : 0); + result = 31 * result + (getValueRaw() != null ? getValueRaw().hashCode() : 0); + result = 31 * result + (getGasPriceRaw() != null ? getGasPriceRaw().hashCode() : 0); + result = 31 * result + (getGasRaw() != null ? getGasRaw().hashCode() : 0); + result = 31 * result + (getInput() != null ? getInput().hashCode() : 0); + result = 31 * result + (getCreates() != null ? getCreates().hashCode() : 0); + result = 31 * result + (getPublicKey() != null ? getPublicKey().hashCode() : 0); + result = 31 * result + (getRaw() != null ? getRaw().hashCode() : 0); + result = 31 * result + (getR() != null ? getR().hashCode() : 0); + result = 31 * result + (getS() != null ? getS().hashCode() : 0); + result = 31 * result + getV(); + return result; + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/TransactionReceipt.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/TransactionReceipt.java new file mode 100644 index 0000000000..baf5853152 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/TransactionReceipt.java @@ -0,0 +1,221 @@ +package org.web3j.protocol.core.methods.response; + +import java.math.BigInteger; +import java.util.List; + +import org.web3j.utils.Numeric; + +/** + * TransactionReceipt object used by {@link EthGetTransactionReceipt}. + */ +public class TransactionReceipt { + private String transactionHash; + private String transactionIndex; + private String blockHash; + private String blockNumber; + private String cumulativeGasUsed; + private String gasUsed; + private String contractAddress; // this is present in the spec + private String root; + private String from; + private String to; + private List logs; + private String logsBloom; + + public TransactionReceipt() { + } + + public TransactionReceipt(String transactionHash, String transactionIndex, + String blockHash, String blockNumber, String cumulativeGasUsed, + String gasUsed, String contractAddress, String root, String from, + String to, List logs, String logsBloom) { + this.transactionHash = transactionHash; + this.transactionIndex = transactionIndex; + this.blockHash = blockHash; + this.blockNumber = blockNumber; + this.cumulativeGasUsed = cumulativeGasUsed; + this.gasUsed = gasUsed; + this.contractAddress = contractAddress; + this.root = root; + this.from = from; + this.to = to; + this.logs = logs; + this.logsBloom = logsBloom; + } + + public String getTransactionHash() { + return transactionHash; + } + + public void setTransactionHash(String transactionHash) { + this.transactionHash = transactionHash; + } + + public BigInteger getTransactionIndex() { + return Numeric.decodeQuantity(transactionIndex); + } + + public String getTransactionIndexRaw() { + return transactionIndex; + } + + public void setTransactionIndex(String transactionIndex) { + this.transactionIndex = transactionIndex; + } + + public String getBlockHash() { + return blockHash; + } + + public void setBlockHash(String blockHash) { + this.blockHash = blockHash; + } + + public BigInteger getBlockNumber() { + return Numeric.decodeQuantity(blockNumber); + } + + public String getBlockNumberRaw() { + return blockNumber; + } + + public void setBlockNumber(String blockNumber) { + this.blockNumber = blockNumber; + } + + public BigInteger getCumulativeGasUsed() { + return Numeric.decodeQuantity(cumulativeGasUsed); + } + + public String getCumulativeGasUsedRaw() { + return cumulativeGasUsed; + } + + public void setCumulativeGasUsed(String cumulativeGasUsed) { + this.cumulativeGasUsed = cumulativeGasUsed; + } + + public BigInteger getGasUsed() { + return Numeric.decodeQuantity(gasUsed); + } + + public String getGasUsedRaw() { + return gasUsed; + } + + public void setGasUsed(String gasUsed) { + this.gasUsed = gasUsed; + } + + public String getContractAddress() { + return contractAddress; + } + + public void setContractAddress(String contractAddress) { + this.contractAddress = contractAddress; + } + + public String getRoot() { + return root; + } + + public void setRoot(String root) { + this.root = root; + } + + public String getFrom() { + return from; + } + + public void setFrom(String from) { + this.from = from; + } + + public String getTo() { + return to; + } + + public void setTo(String to) { + this.to = to; + } + + public List getLogs() { + return logs; + } + + public void setLogs(List logs) { + this.logs = logs; + } + + public String getLogsBloom() { + return logsBloom; + } + + public void setLogsBloom(String logsBloom) { + this.logsBloom = logsBloom; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof TransactionReceipt)) { + return false; + } + + TransactionReceipt that = (TransactionReceipt) o; + + if (getTransactionHash() != null ? !getTransactionHash().equals(that.getTransactionHash()) : that.getTransactionHash() != null) { + return false; + } + if (transactionIndex != null ? !transactionIndex.equals(that.transactionIndex) : that.transactionIndex != null) { + return false; + } + if (getBlockHash() != null ? !getBlockHash().equals(that.getBlockHash()) : that.getBlockHash() != null) { + return false; + } + if (blockNumber != null ? !blockNumber.equals(that.blockNumber) : that.blockNumber != null) { + return false; + } + if (cumulativeGasUsed != null ? !cumulativeGasUsed.equals(that.cumulativeGasUsed) : that.cumulativeGasUsed != null) { + return false; + } + if (gasUsed != null ? !gasUsed.equals(that.gasUsed) : that.gasUsed != null) { + return false; + } + if (getContractAddress() != null ? !getContractAddress().equals(that.getContractAddress()) : that.getContractAddress() != null) { + return false; + } + if (getRoot() != null ? !getRoot().equals(that.getRoot()) : that.getRoot() != null) { + return false; + } + if (getFrom() != null ? !getFrom().equals(that.getFrom()) : that.getFrom() != null) { + return false; + } + if (getTo() != null ? !getTo().equals(that.getTo()) : that.getTo() != null) { + return false; + } + if (getLogs() != null ? !getLogs().equals(that.getLogs()) : that.getLogs() != null) { + return false; + } + return getLogsBloom() != null ? getLogsBloom().equals(that.getLogsBloom()) : that.getLogsBloom() == null; + } + + @Override + public int hashCode() { + int result = getTransactionHash() != null ? getTransactionHash().hashCode() : 0; + result = 31 * result + (transactionIndex != null ? transactionIndex.hashCode() : 0); + result = 31 * result + (getBlockHash() != null ? getBlockHash().hashCode() : 0); + result = 31 * result + (blockNumber != null ? blockNumber.hashCode() : 0); + result = 31 * result + (cumulativeGasUsed != null ? cumulativeGasUsed.hashCode() : 0); + result = 31 * result + (gasUsed != null ? gasUsed.hashCode() : 0); + result = 31 * result + (getContractAddress() != null ? getContractAddress().hashCode() : 0); + result = 31 * result + (getRoot() != null ? getRoot().hashCode() : 0); + result = 31 * result + (getFrom() != null ? getFrom().hashCode() : 0); + result = 31 * result + (getTo() != null ? getTo().hashCode() : 0); + result = 31 * result + (getLogs() != null ? getLogs().hashCode() : 0); + result = 31 * result + (getLogsBloom() != null ? getLogsBloom().hashCode() : 0); + return result; + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/VoidResponse.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/VoidResponse.java new file mode 100644 index 0000000000..d6cd4a49bc --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/VoidResponse.java @@ -0,0 +1,16 @@ +package org.web3j.protocol.core.methods.response; + +import org.web3j.protocol.core.Response; + +/** + * Null response object returned by: + *
    + *
  • personal_setAccountName
  • + *
  • personal_setAccountMeta
  • + *
+ */ +public class VoidResponse extends Response { + public boolean isValid() { + return !hasError(); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/Web3ClientVersion.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/Web3ClientVersion.java new file mode 100644 index 0000000000..753a13ca12 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/Web3ClientVersion.java @@ -0,0 +1,13 @@ +package org.web3j.protocol.core.methods.response; + +import org.web3j.protocol.core.Response; + +/** + * web3_clientVersion + */ +public class Web3ClientVersion extends Response { + + public String getWeb3ClientVersion() { + return getResult(); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/Web3Sha3.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/Web3Sha3.java new file mode 100644 index 0000000000..89ba1d78c5 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/core/methods/response/Web3Sha3.java @@ -0,0 +1,9 @@ +package org.web3j.protocol.core.methods.response; + +import org.web3j.protocol.core.Response; + +/** + * web3_sha3 + */ +public class Web3Sha3 extends Response { +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/exceptions/MessageDecodingException.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/exceptions/MessageDecodingException.java new file mode 100644 index 0000000000..80067800ba --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/exceptions/MessageDecodingException.java @@ -0,0 +1,14 @@ +package org.web3j.protocol.exceptions; + +/** + * Encoding exception. + */ +public class MessageDecodingException extends RuntimeException { + public MessageDecodingException(String message) { + super(message); + } + + public MessageDecodingException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/exceptions/MessageEncodingException.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/exceptions/MessageEncodingException.java new file mode 100644 index 0000000000..5a3ace76bb --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/exceptions/MessageEncodingException.java @@ -0,0 +1,14 @@ +package org.web3j.protocol.exceptions; + +/** + * Encoding exception. + */ +public class MessageEncodingException extends RuntimeException { + public MessageEncodingException(String message) { + super(message); + } + + public MessageEncodingException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/exceptions/TransactionTimeoutException.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/exceptions/TransactionTimeoutException.java new file mode 100644 index 0000000000..e5d7d7f6c4 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/exceptions/TransactionTimeoutException.java @@ -0,0 +1,15 @@ +package org.web3j.protocol.exceptions; + +/** + * Transaction timeout exception indicates that we have breached some threshold waiting for a + * transaction to execute. + */ +public class TransactionTimeoutException extends Exception { + public TransactionTimeoutException(String message) { + super(message); + } + + public TransactionTimeoutException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/http/HttpService.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/http/HttpService.java new file mode 100644 index 0000000000..1c8da66614 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/http/HttpService.java @@ -0,0 +1,94 @@ +package org.web3j.protocol.http; + + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.apache.http.Header; +import org.apache.http.HttpEntity; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.ResponseHandler; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.ByteArrayEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.message.BasicHeader; + +import org.web3j.protocol.Service; +import org.web3j.protocol.core.Request; +import org.web3j.protocol.core.Response; + +/** + * HTTP implementation of our services API. + */ +public class HttpService extends Service { + + public static final String DEFAULT_URL = "http://localhost:8545/"; + + private CloseableHttpClient httpClient; + + private final String url; + + public HttpService(String url, CloseableHttpClient httpClient) { + this.url = url; + this.httpClient = httpClient; + } + + public HttpService(String url) { + this(url, HttpClients.custom().setConnectionManagerShared(true).build()); + } + + public HttpService() { + this(DEFAULT_URL); + } + + protected void setHttpClient(CloseableHttpClient httpClient) { + this.httpClient = httpClient; + } + + @Override + public T send( + Request request, Class responseType) throws IOException { + + byte[] payload = objectMapper.writeValueAsBytes(request); + + HttpPost httpPost = new HttpPost(this.url); + httpPost.setEntity(new ByteArrayEntity(payload)); + Header[] headers = buildHeaders(); + httpPost.setHeaders(headers); + + ResponseHandler responseHandler = getResponseHandler(responseType); + try { + return httpClient.execute(httpPost, responseHandler); + } finally { + httpClient.close(); + } + } + + private Header[] buildHeaders() { + List
headers = new ArrayList<>(); + headers.add(new BasicHeader("Content-Type", "application/json; charset=UTF-8")); + addHeaders(headers); + return headers.toArray(new Header[0]); + } + + protected void addHeaders(List
headers) { } + + public ResponseHandler getResponseHandler(Class type) { + return response -> { + int status = response.getStatusLine().getStatusCode(); + if (status >= 200 && status < 300) { + HttpEntity entity = response.getEntity(); + + if (entity != null) { + return objectMapper.readValue(response.getEntity().getContent(), type); + } else { + return null; + } + } else { + throw new ClientProtocolException("Unexpected response status: " + status); + } + }; + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/infura/CertificateManager.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/infura/CertificateManager.java new file mode 100644 index 0000000000..b28f7b584f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/infura/CertificateManager.java @@ -0,0 +1,160 @@ +package org.web3j.protocol.infura; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.security.KeyManagementException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLException; +import javax.net.ssl.SSLSocket; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.X509TrustManager; + +/** + * Certificate manager to simplify working with TLS endpoints. + */ +public class CertificateManager { + + static File buildKeyStore(String url, char[] keyStorePassword) { + KeyStore keyStore; + try { + keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); + keyStore.load(null, keyStorePassword); + + CertificateChainTrustManager certificateChainTrustManager = + createCertificateChainTrustManager(keyStore); + URI endpoint = new URI(url); + SSLSocket sslSocket = createSslSocket(endpoint, certificateChainTrustManager); + + if (!isTrustedEndPoint(sslSocket)) { + X509Certificate[] x509Certificates = certificateChainTrustManager.x509Certificates; + if (x509Certificates == null) { + throw new RuntimeException("Unable to obtain x509 certificate from server"); + } + + for (int i = 0; i < x509Certificates.length; i++) { + keyStore.setCertificateEntry(endpoint.getHost() + i, x509Certificates[i]); + } + } + + SecureRandom random = new SecureRandom(); + File keyFile = File.createTempFile("web3j-", "" + random.nextLong()); + + FileOutputStream fileOutputStream = new FileOutputStream(keyFile); + keyStore.store(fileOutputStream, keyStorePassword); + fileOutputStream.close(); + + deleteFileOnShutdown(keyFile); + + return keyFile; + + } catch (KeyStoreException e) { + throw new RuntimeException(e); + } catch (CertificateException e) { + throw new RuntimeException(e); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException(e); + } catch (IOException e) { + throw new RuntimeException(e); + } catch (KeyManagementException e) { + throw new RuntimeException(e); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + } + + private static CertificateChainTrustManager createCertificateChainTrustManager( + KeyStore keyStore) throws NoSuchAlgorithmException, KeyStoreException { + + TrustManagerFactory trustManagerFactory = + TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + trustManagerFactory.init(keyStore); + X509TrustManager defaultTrustManager = + (X509TrustManager) trustManagerFactory.getTrustManagers()[0]; + return new CertificateChainTrustManager(defaultTrustManager); + } + + private static SSLSocket createSslSocket( + URI endpoint, CertificateChainTrustManager certificateChainTrustManager) + throws NoSuchAlgorithmException, KeyManagementException, IOException, + URISyntaxException, KeyStoreException { + + SSLContext context = SSLContext.getInstance("TLS"); + context.init(null, new TrustManager[]{certificateChainTrustManager}, null); + SSLSocketFactory factory = context.getSocketFactory(); + + SSLSocket sslSocket = (SSLSocket) factory.createSocket( + endpoint.getHost(), 443); + sslSocket.setSoTimeout(10000); + + return sslSocket; + } + + private static boolean isTrustedEndPoint(SSLSocket socket) throws IOException { + try { + socket.startHandshake(); + socket.close(); + return true; + } catch (SSLException e) { + return false; + } + } + + private static void deleteFileOnShutdown(File file) { + Runtime.getRuntime().addShutdownHook(new Thread() { + public void run() { + try { + deleteTempFile(file); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + }); + } + + private static void deleteTempFile(File file) throws IOException { + if (file.exists() && !file.delete()) { + throw new RuntimeException("Unable to remove file: " + file.getCanonicalPath()); + } + } + + /** + * Based on: + * http://blogs.sun.com/andreas/resource/InstallCert.java + */ + private static class CertificateChainTrustManager implements X509TrustManager { + + private final X509TrustManager x509TrustManager; + private X509Certificate[] x509Certificates; + + CertificateChainTrustManager(X509TrustManager x509TrustManager) { + this.x509TrustManager = x509TrustManager; + } + + public X509Certificate[] getAcceptedIssuers() { + // Called by Java 7+ see http://infposs.blogspot.kr/2013/06/installcert-and-java-7.html + return new X509Certificate[0]; + } + + public void checkClientTrusted(X509Certificate[] chain, String authType) + throws CertificateException { + throw new UnsupportedOperationException(); + } + + public void checkServerTrusted(X509Certificate[] chain, String authType) + throws CertificateException { + this.x509Certificates = chain; + x509TrustManager.checkServerTrusted(chain, authType); + } + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/infura/InfuraHttpService.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/infura/InfuraHttpService.java new file mode 100644 index 0000000000..96f1887f55 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/infura/InfuraHttpService.java @@ -0,0 +1,108 @@ +package org.web3j.protocol.infura; + +import java.io.File; +import java.io.IOException; +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableKeyException; +import java.security.cert.CertificateException; +import java.util.List; +import java.util.Optional; +import javax.net.ssl.SSLContext; + +import org.apache.http.Header; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.message.BasicHeader; +import org.apache.http.ssl.SSLContexts; + +import org.web3j.protocol.http.HttpService; + +/** + * HttpService for working with Infura clients. + */ +public class InfuraHttpService extends HttpService { + + private static final String INFURA_ETHEREUM_PREFERRED_CLIENT = + "Infura-Ethereum-Preferred-Client"; + + private static final char[] TEMP_KEY_STORE_PASSWORD = "web3j runtime cert store".toCharArray(); + + private final Optional
clientVersionHeader; + + public InfuraHttpService(String url, String clientVersion, boolean required) { + super(url); + setHttpClient(createTrustTlsHttpClient(url)); + clientVersionHeader = buildHeader(clientVersion, required); + } + + public InfuraHttpService(String url, String clientVersion) { + this(url, clientVersion, true); + } + + public InfuraHttpService(String url) { + this(url, "", false); + } + + @Override + protected void addHeaders(List
headers) { + if (clientVersionHeader.isPresent()) { + headers.add(clientVersionHeader.get()); + } + } + + static Optional
buildHeader(String clientVersion, boolean required) { + if (clientVersion == null || clientVersion.equals("")) { + return Optional.empty(); + } + + if (required) { + return Optional.of(new BasicHeader(INFURA_ETHEREUM_PREFERRED_CLIENT, clientVersion)); + } else { + return Optional.of(new BasicHeader( + INFURA_ETHEREUM_PREFERRED_CLIENT, clientVersion + "; required=false")); + } + } + + /** + * Create an {@link InfuraHttpService} instance with a local keystore that implicitly trusts + * the provided endpoint. + * + * This is achieved by creating a local temporary keystore file which we add the certificate + * of the endpoint to upon application startup. + * + * @param url we wish to connect to + * @return the file containing the keystore + * @throws UnrecoverableKeyException if keystore file cannot be loaded + * @throws NoSuchAlgorithmException if keystore file cannot be loaded + * @throws KeyStoreException if keystore file cannot be loaded + * @throws KeyManagementException if keystore file cannot be loaded + */ + private static CloseableHttpClient createTrustTlsHttpClient(String url) { + + File keyFile = CertificateManager.buildKeyStore(url, TEMP_KEY_STORE_PASSWORD); + + SSLContext sslContext; + try { + sslContext = SSLContexts.custom() + .loadTrustMaterial(keyFile, TEMP_KEY_STORE_PASSWORD) + .build(); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException(e); + } catch (KeyManagementException e) { + throw new RuntimeException(e); + } catch (KeyStoreException e) { + throw new RuntimeException(e); + } catch (CertificateException e) { + throw new RuntimeException(e); + } catch (IOException e) { + throw new RuntimeException(e); + } + + return HttpClients.custom() + .setConnectionManagerShared(true) + .setSSLContext(sslContext) + .build(); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/ipc/IOFacade.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/ipc/IOFacade.java new file mode 100644 index 0000000000..0a0e0f94a6 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/ipc/IOFacade.java @@ -0,0 +1,11 @@ +package org.web3j.protocol.ipc; + +import java.io.IOException; + +/** + * Simple IO facade for the *nix and Windows IPC implementations. + */ +public interface IOFacade { + void write(String payload) throws IOException; + String read() throws IOException; +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/ipc/IpcService.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/ipc/IpcService.java new file mode 100644 index 0000000000..ae15dc4eb9 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/ipc/IpcService.java @@ -0,0 +1,38 @@ +package org.web3j.protocol.ipc; + +import java.io.IOException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.web3j.protocol.Service; +import org.web3j.protocol.core.Request; +import org.web3j.protocol.core.Response; + +/** + * Ipc service implementation. + */ +public class IpcService extends Service { + + private static final Log log = LogFactory.getLog(IpcService.class); + + private final IOFacade ioFacade; + + public IpcService(IOFacade ioFacade) { + super(); + this.ioFacade = ioFacade; + } + + @Override + public T send(Request request, Class responseType) throws IOException { + String payload = objectMapper.writeValueAsString(request); + + ioFacade.write(payload); + log.debug(">> " + payload); + + String result = ioFacade.read(); + log.debug("<< " + result); + + return objectMapper.readValue(result, responseType); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/ipc/UnixDomainSocket.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/ipc/UnixDomainSocket.java new file mode 100644 index 0000000000..a8453c507d --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/ipc/UnixDomainSocket.java @@ -0,0 +1,70 @@ +package org.web3j.protocol.ipc; + +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.nio.CharBuffer; +import java.nio.channels.Channels; + +import jnr.unixsocket.UnixSocketAddress; +import jnr.unixsocket.UnixSocketChannel; + +/** + * Unix domain socket IO implementation for IPC. + */ +public class UnixDomainSocket implements IOFacade { + + private static final int DEFAULT_BUFFER_SIZE = 1024; + + private final int bufferSize; + + private final InputStreamReader reader; + private final PrintWriter writer; + + public UnixDomainSocket(String ipcSocketPath) { + this(ipcSocketPath, DEFAULT_BUFFER_SIZE); + } + + public UnixDomainSocket(String ipcSocketPath, int bufferSize) { + this.bufferSize = bufferSize; + + try { + UnixSocketAddress address = new UnixSocketAddress(ipcSocketPath); + UnixSocketChannel channel = UnixSocketChannel.open(address); + + reader = new InputStreamReader(Channels.newInputStream(channel)); + writer = new PrintWriter(Channels.newOutputStream(channel)); + + } catch (IOException e) { + throw new RuntimeException( + "Provided file socket cannot be opened: " + ipcSocketPath, e); + } + } + + UnixDomainSocket(InputStreamReader reader, PrintWriter writer, int bufferSize) { + this.bufferSize = bufferSize; + this.writer = writer; + this.reader = reader; + } + + @Override + public void write(String payload) throws IOException { + writer.write(payload); + writer.flush(); + } + + @Override + public String read() throws IOException { + CharBuffer response = CharBuffer.allocate(bufferSize); + String result = ""; + + do { + response.clear(); + reader.read(response); + result += new String(response.array(), response.arrayOffset(), response.position()); + } while (response.position() == response.limit() + && response.get(response.limit() - 1) != '\n'); + + return result; + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/ipc/UnixIpcService.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/ipc/UnixIpcService.java new file mode 100644 index 0000000000..c4a8d1cfcc --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/ipc/UnixIpcService.java @@ -0,0 +1,11 @@ +package org.web3j.protocol.ipc; + +/** + * Unix domain socket implementation of our services API. + */ +public class UnixIpcService extends IpcService { + + public UnixIpcService(String ipcSocketPath) { + super(new UnixDomainSocket(ipcSocketPath)); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/ipc/WindowsIpcService.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/ipc/WindowsIpcService.java new file mode 100644 index 0000000000..ee4906c686 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/ipc/WindowsIpcService.java @@ -0,0 +1,13 @@ +package org.web3j.protocol.ipc; + +/** + *

Windows named pipe implementation of our services API. + * + *

This implementation is experimental. + */ +public class WindowsIpcService extends IpcService { + + public WindowsIpcService(String ipcSocketPath) { + super(new WindowsNamedPipe(ipcSocketPath)); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/ipc/WindowsNamedPipe.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/ipc/WindowsNamedPipe.java new file mode 100644 index 0000000000..54d987690f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/ipc/WindowsNamedPipe.java @@ -0,0 +1,31 @@ +package org.web3j.protocol.ipc; + +import java.io.IOException; +import java.io.RandomAccessFile; + +/** + * Windows named pipe IO implementation for IPC. + */ +public class WindowsNamedPipe implements IOFacade { + + private final RandomAccessFile pipe; + + public WindowsNamedPipe(String ipcSocketPath) { + try { + pipe = new RandomAccessFile(ipcSocketPath, "rw"); + } catch (IOException e) { + throw new RuntimeException( + "Provided file pipe cannot be opened: " + ipcSocketPath, e); + } + } + + @Override + public void write(String payload) throws IOException { + pipe.write(payload.getBytes()); + } + + @Override + public String read() throws IOException { + return pipe.readLine(); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/parity/JsonRpc2_0Parity.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/parity/JsonRpc2_0Parity.java new file mode 100644 index 0000000000..643be950c0 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/parity/JsonRpc2_0Parity.java @@ -0,0 +1,183 @@ +package org.web3j.protocol.parity; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import org.web3j.crypto.WalletFile; +import org.web3j.protocol.Web3jService; +import org.web3j.protocol.core.JsonRpc2_0Web3j; +import org.web3j.protocol.core.Request; +import org.web3j.protocol.core.methods.request.Transaction; +import org.web3j.protocol.core.methods.response.EthSendTransaction; +import org.web3j.protocol.core.methods.response.VoidResponse; +import org.web3j.protocol.parity.methods.response.NewAccountIdentifier; +import org.web3j.protocol.parity.methods.response.PersonalAccountsInfo; +import org.web3j.protocol.parity.methods.response.PersonalListAccounts; +import org.web3j.protocol.parity.methods.response.PersonalRejectRequest; +import org.web3j.protocol.parity.methods.response.PersonalRequestsToConfirm; +import org.web3j.protocol.parity.methods.response.PersonalSignerEnabled; +import org.web3j.protocol.parity.methods.response.PersonalUnlockAccount; + +/** + * JSON-RPC 2.0 factory implementation for Parity. + */ +public class JsonRpc2_0Parity extends JsonRpc2_0Web3j implements Parity { + + public JsonRpc2_0Parity(Web3jService web3jService) { + super(web3jService); + } + + @Override + public Request personalSignerEnabled() { + return new Request<>( + "personal_signerEnabled", + Collections.emptyList(), + ID, + web3jService, + PersonalSignerEnabled.class); + } + + @Override + public Request personalListAccounts() { + return new Request<>( + "personal_listAccounts", + Collections.emptyList(), + ID, + web3jService, + PersonalListAccounts.class); + } + + @Override + public Request personalNewAccount(String password) { + return new Request<>( + "personal_newAccount", + Arrays.asList(password), + ID, + web3jService, + NewAccountIdentifier.class); + } + + @Override + public Request personalNewAccountFromPhrase(String phrase, String password) { + return new Request<>( + "personal_newAccountFromPhrase", + Arrays.asList(phrase, password), + ID, + web3jService, + NewAccountIdentifier.class); + } + + @Override + public Request personalNewAccountFromWallet(WalletFile walletFile, String password) { + return new Request<>( + "personal_newAccountFromWallet", + Arrays.asList(walletFile, password), + ID, + web3jService, + NewAccountIdentifier.class); + } + + @Override + public Request personalUnlockAccount( + String accountId, String password, BigInteger duration) { + List attributes = new ArrayList<>(3); + attributes.add(accountId); + attributes.add(password); + + if (duration != null) { + // Parity has a bug where it won't support a duration + // See https://github.com/ethcore/parity/issues/1215 + attributes.add(duration.longValue()); + } else { + attributes.add(null); // we still need to include the null value, otherwise Parity rejects + } + + return new Request<>( + "personal_unlockAccount", + attributes, + ID, + web3jService, + PersonalUnlockAccount.class); + } + + @Override + public Request personalUnlockAccount(String accountId, String password) { + return personalUnlockAccount(accountId, password, null); + } + + @Override + public Request personalSignAndSendTransaction( + Transaction transaction, String password) { + return new Request<>( + "personal_signAndSendTransaction", + Arrays.asList(transaction, password), + ID, + web3jService, + EthSendTransaction.class); + } + + @Override + public Request personalSetAccountName(String accountId, String newAccountName) { + return new Request<>( + "personal_setAccountName", + Arrays.asList(accountId, newAccountName), + ID, + web3jService, + VoidResponse.class); + } + + @Override + public Request personalSetAccountMeta( + String accountId, Map metadata) { + return new Request<>( + "personal_setAccountMeta", + Arrays.asList(accountId, metadata), + ID, + web3jService, + VoidResponse.class); + } + + @Override + public Request personalAccountsInfo() { + return new Request<>( + "personal_accountsInfo", + Collections.emptyList(), + ID, + web3jService, + PersonalAccountsInfo.class); + } + + @Override + public Request personalRequestsToConfirm() { + return new Request<>( + "personal_requestsToConfirm", + Collections.emptyList(), + ID, + web3jService, + PersonalRequestsToConfirm.class); + } + + @Override + public Request personalConfirmRequest(String requestId, Transaction transaction, String password) { + return new Request<>( + "personal_confirmRequest", + Arrays.asList(requestId, transaction, password), + ID, + web3jService, + EthSendTransaction.class); + } + + @Override + public Request personalRejectRequest(String requestId) { + return new Request<>( + "personal_rejectRequest", + Arrays.asList(requestId), + ID, + web3jService, + PersonalRejectRequest.class); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/parity/Parity.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/parity/Parity.java new file mode 100644 index 0000000000..1b23ea20c8 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/parity/Parity.java @@ -0,0 +1,59 @@ +package org.web3j.protocol.parity; + +import java.math.BigInteger; +import java.util.Map; + +import org.web3j.crypto.WalletFile; +import org.web3j.protocol.Web3j; +import org.web3j.protocol.Web3jService; +import org.web3j.protocol.core.Request; +import org.web3j.protocol.core.methods.request.Transaction; +import org.web3j.protocol.core.methods.response.VoidResponse; +import org.web3j.protocol.parity.methods.response.NewAccountIdentifier; +import org.web3j.protocol.parity.methods.response.PersonalAccountsInfo; +import org.web3j.protocol.parity.methods.response.PersonalListAccounts; +import org.web3j.protocol.parity.methods.response.PersonalRejectRequest; +import org.web3j.protocol.parity.methods.response.PersonalRequestsToConfirm; +import org.web3j.protocol.parity.methods.response.PersonalSignerEnabled; +import org.web3j.protocol.parity.methods.response.PersonalUnlockAccount; + +/** + * JSON-RPC Request object building factory for Parity. + */ +public interface Parity extends Web3j { + static Parity build(Web3jService web3jService) { + return new JsonRpc2_0Parity(web3jService); + } + + Request personalSignerEnabled(); + + Request personalListAccounts(); + + Request personalNewAccount(String password); + + Request personalNewAccountFromPhrase(String phrase, String password); + + Request personalNewAccountFromWallet(WalletFile walletFile, String password); + + Request personalUnlockAccount( + String accountId, String password, BigInteger duration); + + Request personalUnlockAccount(String accountId, String password); + + Request personalSignAndSendTransaction( + Transaction transaction, String password); + + Request personalSetAccountName( + String accountId, String newAccountName); + + Request personalSetAccountMeta(String accountId, Map metadata); + + Request personalAccountsInfo(); + + Request personalRequestsToConfirm(); + + Request personalConfirmRequest( + String requestId, Transaction transaction, String password); + + Request personalRejectRequest(String requestId); +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/parity/methods/response/NewAccountIdentifier.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/parity/methods/response/NewAccountIdentifier.java new file mode 100644 index 0000000000..e25520e149 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/parity/methods/response/NewAccountIdentifier.java @@ -0,0 +1,17 @@ +package org.web3j.protocol.parity.methods.response; + +import org.web3j.protocol.core.Response; + +/** + * Account id object returned by: + *
    + *
  • personal_newAccount
  • + *
  • personal_newAccountFromPhrase
  • + *
  • personal_newAccountFromWallet
  • + *
+ */ +public class NewAccountIdentifier extends Response { + public String getAccountId() { + return getResult(); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/parity/methods/response/PersonalAccountsInfo.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/parity/methods/response/PersonalAccountsInfo.java new file mode 100644 index 0000000000..41a516266b --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/parity/methods/response/PersonalAccountsInfo.java @@ -0,0 +1,76 @@ +package org.web3j.protocol.parity.methods.response; + +import java.util.Map; + +import org.web3j.protocol.core.Response; + +/** + * personal_accountsInfo + */ +public class PersonalAccountsInfo extends Response> { + + // we need to use a map type as a string value is returned with the account information + public Map getAccountsInfo() { + return getResult(); + } + + public static class AccountsInfo { + private String name; + private String uuid; + private Map meta; + + public AccountsInfo() { + } + + public AccountsInfo(String name, String uuid, Map meta) { + this.name = name; + this.uuid = uuid; + this.meta = meta; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public Map getMeta() { + return meta; + } + + public void setMeta(Map meta) { + this.meta = meta; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof AccountsInfo)) return false; + + AccountsInfo that = (AccountsInfo) o; + + if (name != null ? !name.equals(that.name) : that.name != null) return false; + if (uuid != null ? !uuid.equals(that.uuid) : that.uuid != null) return false; + return meta != null ? meta.equals(that.meta) : that.meta == null; + + } + + @Override + public int hashCode() { + int result = name != null ? name.hashCode() : 0; + result = 31 * result + (uuid != null ? uuid.hashCode() : 0); + result = 31 * result + (meta != null ? meta.hashCode() : 0); + return result; + } + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/parity/methods/response/PersonalListAccounts.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/parity/methods/response/PersonalListAccounts.java new file mode 100644 index 0000000000..e3fb4a65c5 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/parity/methods/response/PersonalListAccounts.java @@ -0,0 +1,14 @@ +package org.web3j.protocol.parity.methods.response; + +import java.util.List; + +import org.web3j.protocol.core.Response; + +/** + * personal_listAccounts + */ +public class PersonalListAccounts extends Response> { + public List getAccountIds() { + return getResult(); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/parity/methods/response/PersonalRejectRequest.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/parity/methods/response/PersonalRejectRequest.java new file mode 100644 index 0000000000..f3fdc30d78 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/parity/methods/response/PersonalRejectRequest.java @@ -0,0 +1,12 @@ +package org.web3j.protocol.parity.methods.response; + +import org.web3j.protocol.core.Response; + +/** + * personal_rejectRequest + */ +public class PersonalRejectRequest extends Response { + public boolean isRejected() { + return getResult(); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/parity/methods/response/PersonalRequestsToConfirm.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/parity/methods/response/PersonalRequestsToConfirm.java new file mode 100644 index 0000000000..f41e5b5b72 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/parity/methods/response/PersonalRequestsToConfirm.java @@ -0,0 +1,305 @@ +package org.web3j.protocol.parity.methods.response; + +import java.io.IOException; +import java.math.BigInteger; +import java.util.List; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.ObjectReader; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +import org.web3j.protocol.ObjectMapperFactory; +import org.web3j.protocol.core.Response; +import org.web3j.utils.Numeric; + +/** + * personal_requestsToConfirm + */ +public class PersonalRequestsToConfirm extends Response> { + + public List getRequestsToConfirm() { + return getResult(); + } + + public static class RequestsToConfirm { + + private String id; + private PayloadType payload; + + public RequestsToConfirm() { + } + + public RequestsToConfirm(String id, PayloadType payload) { + this.id = id; + this.payload = payload; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public PayloadType getPayload() { + return payload; + } + + @JsonDeserialize(using = ResponseDeserialiser.class) + public void setPayload(PayloadType payload) { + this.payload = payload; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof RequestsToConfirm)) return false; + + RequestsToConfirm that = (RequestsToConfirm) o; + + if (id != null ? !id.equals(that.id) : that.id != null) return false; + return payload != null ? payload.equals(that.payload) : that.payload == null; + + } + + @Override + public int hashCode() { + int result = id != null ? id.hashCode() : 0; + result = 31 * result + (payload != null ? payload.hashCode() : 0); + return result; + } + } + + public interface PayloadType { } + + public static class SignPayload implements PayloadType { + private SignRequest sign; + + public SignPayload() { } + + public SignPayload(SignRequest sign) { + this.sign = sign; + } + + public SignRequest getSign() { + return sign; + } + + public void setSign(SignRequest sign) { + this.sign = sign; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof SignPayload)) return false; + + SignPayload signPayload = (SignPayload) o; + + return sign != null ? sign.equals(signPayload.sign) : signPayload.sign == null; + } + + @Override + public int hashCode() { + return sign != null ? sign.hashCode() : 0; + } + } + + public static class SignRequest { + private String address; + private String hash; + + public SignRequest() { + } + + public SignRequest(String address, String hash) { + this.address = address; + this.hash = hash; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public String getHash() { + return hash; + } + + public void setHash(String hash) { + this.hash = hash; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof SignRequest)) return false; + + SignRequest that = (SignRequest) o; + + if (address != null ? !address.equals(that.address) : that.address != null) + return false; + return hash != null ? hash.equals(that.hash) : that.hash == null; + + } + + @Override + public int hashCode() { + int result = address != null ? address.hashCode() : 0; + result = 31 * result + (hash != null ? hash.hashCode() : 0); + return result; + } + } + + public static class TransactionPayload implements PayloadType { + private TransactionRequestType transaction; + + public TransactionPayload() { } + + public TransactionPayload(TransactionRequestType transaction) { + this.transaction = transaction; + } + + public TransactionRequestType getTransaction() { + return transaction; + } + + public void setTransaction(TransactionRequestType transaction) { + this.transaction = transaction; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof TransactionPayload)) return false; + + TransactionPayload that = (TransactionPayload) o; + + return transaction != null ? transaction.equals(that.transaction) : that.transaction == null; + } + + @Override + public int hashCode() { + return transaction != null ? transaction.hashCode() : 0; + } + } + + // Basically the same as EthSendTransaction + public static class TransactionRequestType { + private String from; + private String to; + private String gas; + private String gasPrice; + private String value; + private String data; + private String nonce; + + public TransactionRequestType() { + } + + public TransactionRequestType(String from, String data) { + this.from = from; + this.data = data; + } + + public TransactionRequestType(String from, String to, + String gas, String gasPrice, + String value, String data, String nonce) { + this.from = from; + this.to = to; + this.gas = gas; + this.gasPrice = gasPrice; + this.value = value; + this.data = data; + this.nonce = nonce; + } + + public String getFrom() { + return from; + } + + public String getTo() { + return to; + } + + public BigInteger getGas() { + return Numeric.decodeQuantity(gas); + } + + public BigInteger getGasPrice() { + return Numeric.decodeQuantity(gasPrice); + } + + public BigInteger getValue() { + return Numeric.decodeQuantity(value); + } + + public String getData() { + return data; + } + + public BigInteger getNonce() { + return Numeric.decodeQuantity(nonce); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof TransactionRequestType)) return false; + + TransactionRequestType that = (TransactionRequestType) o; + + if (from != null ? !from.equals(that.from) : that.from != null) return false; + if (to != null ? !to.equals(that.to) : that.to != null) return false; + if (gas != null ? !gas.equals(that.gas) : that.gas != null) return false; + if (gasPrice != null ? !gasPrice.equals(that.gasPrice) : that.gasPrice != null) + return false; + if (value != null ? !value.equals(that.value) : that.value != null) return false; + if (data != null ? !data.equals(that.data) : that.data != null) return false; + return nonce != null ? nonce.equals(that.nonce) : that.nonce == null; + + } + + @Override + public int hashCode() { + int result = from != null ? from.hashCode() : 0; + result = 31 * result + (to != null ? to.hashCode() : 0); + result = 31 * result + (gas != null ? gas.hashCode() : 0); + result = 31 * result + (gasPrice != null ? gasPrice.hashCode() : 0); + result = 31 * result + (value != null ? value.hashCode() : 0); + result = 31 * result + (data != null ? data.hashCode() : 0); + result = 31 * result + (nonce != null ? nonce.hashCode() : 0); + return result; + } + } + + public static class ResponseDeserialiser extends JsonDeserializer { + + private ObjectReader objectReader = ObjectMapperFactory.getObjectReader(); + + @Override + public PayloadType deserialize( + JsonParser jsonParser, + DeserializationContext deserializationContext) throws IOException { + + if (jsonParser.getCurrentToken() == JsonToken.START_OBJECT) { + jsonParser.nextToken(); + String value = jsonParser.getValueAsString(); + if (value.equals("sign")) { + return objectReader.readValue(jsonParser, SignPayload.class); + } else { + return objectReader.readValue(jsonParser, TransactionPayload.class); + } + } + return null; + } + } + +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/parity/methods/response/PersonalSignerEnabled.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/parity/methods/response/PersonalSignerEnabled.java new file mode 100644 index 0000000000..1cf524e67b --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/parity/methods/response/PersonalSignerEnabled.java @@ -0,0 +1,12 @@ +package org.web3j.protocol.parity.methods.response; + +import org.web3j.protocol.core.Response; + +/** + * personal_signerEnabled + */ +public class PersonalSignerEnabled extends Response { + public boolean isSignerEnabled() { + return getResult(); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/parity/methods/response/PersonalUnlockAccount.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/parity/methods/response/PersonalUnlockAccount.java new file mode 100644 index 0000000000..8727b23e6f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/parity/methods/response/PersonalUnlockAccount.java @@ -0,0 +1,12 @@ +package org.web3j.protocol.parity.methods.response; + +import org.web3j.protocol.core.Response; + +/** + * personal_unlockAccount + */ +public class PersonalUnlockAccount extends Response { + public Boolean accountUnlocked() { + return getResult(); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/rx/JsonRpc2_0Rx.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/rx/JsonRpc2_0Rx.java new file mode 100644 index 0000000000..0c73054652 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/rx/JsonRpc2_0Rx.java @@ -0,0 +1,84 @@ +package org.web3j.protocol.rx; + +import java.util.List; +import java.util.concurrent.ExecutorService; + +import rx.Observable; +import rx.Subscriber; +import rx.subscriptions.Subscriptions; + +import org.web3j.protocol.Web3j; +import org.web3j.protocol.core.filters.BlockFilter; +import org.web3j.protocol.core.filters.LogFilter; +import org.web3j.protocol.core.filters.PendingTransactionFilter; +import org.web3j.protocol.core.methods.response.EthBlock; +import org.web3j.protocol.core.methods.response.Log; +import org.web3j.protocol.core.methods.response.Transaction; + +/** + * web3j reactive API implementation. + */ +public class JsonRpc2_0Rx { + + private final Web3j web3j; + private final ExecutorService executorService; + + public JsonRpc2_0Rx(Web3j web3j, ExecutorService executorService) { + this.web3j = web3j; + this.executorService = executorService; + } + + public Observable ethBlockHashObservable(long pollingInterval) { + return Observable.create(subscriber -> { + BlockFilter blockFilter = new BlockFilter( + web3j, value -> subscriber.onNext(value)); + run(blockFilter, subscriber, pollingInterval); + }); + } + + public Observable ethPendingTransactionHashObservable(long pollingInterval) { + return Observable.create(subscriber -> { + PendingTransactionFilter pendingTransactionFilter = new PendingTransactionFilter( + web3j, value -> subscriber.onNext(value)); + + run(pendingTransactionFilter, subscriber, pollingInterval); + }); + } + + public Observable ethLogObservable( + org.web3j.protocol.core.methods.request.EthFilter ethFilter, long pollingInterval) { + return Observable.create((Subscriber subscriber) -> { + LogFilter logFilter = new LogFilter( + web3j, subscriber::onNext, ethFilter); + + run(logFilter, subscriber, pollingInterval); + }); + } + + private void run( + org.web3j.protocol.core.filters.Filter filter, Subscriber subscriber, + long pollingInterval) { + + executorService.submit(() -> filter.run(pollingInterval)); + subscriber.add(Subscriptions.create(filter::cancel)); + } + + public Observable transactionObservable(long pollingInterval) { + return blockObservable(true, pollingInterval) + .flatMapIterable(ethBlock -> (List) ethBlock.getBlock().getTransactions()); + } + + public Observable pendingTransactionObservable(long pollingInterval) { + return ethPendingTransactionHashObservable(pollingInterval) + .flatMap(transactionHash -> + web3j.ethGetTransactionByHash(transactionHash).observable()) + .map(ethTransaction -> ethTransaction.getTransaction().get()); + } + + public Observable blockObservable( + boolean fullTransactionObjects, long pollingInterval) { + return ethBlockHashObservable(pollingInterval) + .flatMap(blockHash -> + web3j.ethGetBlockByHash(blockHash, fullTransactionObjects).observable()); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/rx/Web3jRx.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/rx/Web3jRx.java new file mode 100644 index 0000000000..9a60e22406 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/protocol/rx/Web3jRx.java @@ -0,0 +1,25 @@ +package org.web3j.protocol.rx; + +import rx.Observable; + +import org.web3j.protocol.core.methods.request.EthFilter; +import org.web3j.protocol.core.methods.response.EthBlock; +import org.web3j.protocol.core.methods.response.Log; +import org.web3j.protocol.core.methods.response.Transaction; + +/** + * The Observables JSON-RPC client event API. + */ +public interface Web3jRx { + Observable ethLogObservable(EthFilter ethFilter); + + Observable ethBlockHashObservable(); + + Observable ethPendingTransactionHashObservable(); + + Observable transactionObservable(); + + Observable pendingTransactionObservable(); + + Observable blockObservable(boolean fullTransactionObjects); +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/rlp/RlpEncoder.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/rlp/RlpEncoder.java new file mode 100644 index 0000000000..1bde8e368e --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/rlp/RlpEncoder.java @@ -0,0 +1,88 @@ +package org.web3j.rlp; + +import java.util.Arrays; +import java.util.List; + +/** + *

Recursive Length Prefix (RLP) encoder.

+ * + *

For the specification, refer to p16 of the + * yellow paper and here.

+ */ +public class RlpEncoder { + + private static final int STRING_OFFSET = 0x80; + private static final int LIST_OFFSET = 0xc0; + + public static byte[] encode(RlpType value) { + if (value instanceof RlpString) { + return encodeString((RlpString) value); + } else { + return encodeList((RlpList) value); + } + } + + static byte[] encodeString(RlpString value) { + return encode(value.getBytes(), STRING_OFFSET); + } + + private static byte[] encode(byte[] bytesValue, int offset) { + if (bytesValue.length == 1 && bytesValue[0] >= (byte) 0x00 && bytesValue[0] <= (byte) 0x7f) { + return bytesValue; + } else if (bytesValue.length < 55) { + byte[] result = new byte[bytesValue.length + 1]; + result[0] = (byte) (offset + bytesValue.length); + System.arraycopy(bytesValue, 0, result, 1, bytesValue.length); + return result; + } else { + byte[] encodedStringLength = toMinimalByteArray(bytesValue.length); + byte[] result = new byte[bytesValue.length + encodedStringLength.length + 1]; + + result[0] = (byte) ( (offset + 0x37) + encodedStringLength.length); + System.arraycopy(encodedStringLength, 0, result, 1, encodedStringLength.length); + System.arraycopy( + bytesValue, 0, result, encodedStringLength.length + 1, bytesValue.length); + return result; + } + } + + private static byte[] toMinimalByteArray(int value) { + byte[] encoded = toByteArray(value); + + for (int i = 0; i < encoded.length; i++) { + if (encoded[i] != 0) { + return Arrays.copyOfRange(encoded, i, encoded.length); + } + } + + return new byte[]{ }; + } + + private static byte[] toByteArray(int value) { + return new byte[] { + (byte) ((value >> 24) & 0xff), + (byte) ((value >> 16) & 0xff), + (byte) ((value >> 8) & 0xff), + (byte) (value & 0xff) + }; + } + + static byte[] encodeList(RlpList value) { + List values = value.getValues(); + if (values.isEmpty()) { + return encode(new byte[]{ }, LIST_OFFSET); + } else { + byte[] result = new byte[0]; + for (RlpType entry:values) { + result = concat(result, encode(entry)); + } + return encode(result, LIST_OFFSET); + } + } + + private static byte[] concat(byte[] b1, byte[] b2) { + byte[] result = Arrays.copyOf(b1, b1.length + b2.length); + System.arraycopy(b2, 0, result, b1.length, b2.length); + return result; + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/rlp/RlpList.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/rlp/RlpList.java new file mode 100644 index 0000000000..dd7d22e04f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/rlp/RlpList.java @@ -0,0 +1,23 @@ +package org.web3j.rlp; + +import java.util.Arrays; +import java.util.List; + +/** + * RLP list type. + */ +public class RlpList implements RlpType { + private final List values; + + public RlpList(RlpType... values) { + this.values = Arrays.asList(values); + } + + public RlpList(List values) { + this.values = values; + } + + public List getValues() { + return values; + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/rlp/RlpString.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/rlp/RlpString.java new file mode 100644 index 0000000000..96d9f75625 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/rlp/RlpString.java @@ -0,0 +1,65 @@ +package org.web3j.rlp; + +import java.math.BigInteger; +import java.util.Arrays; + +import org.web3j.utils.Bytes; + +/** + * RLP string type. + */ +public class RlpString implements RlpType { + private static final byte[] EMPTY = new byte[]{ }; + + private final byte[] value; + + private RlpString(byte[] value) { + this.value = value; + } + + public byte[] getBytes() { + return value; + } + + public static RlpString create(byte[] value) { + return new RlpString(Bytes.trimLeadingZeroes(value)); + } + + public static RlpString create(byte value) { + return new RlpString(new byte[]{ value }); + } + + public static RlpString create(BigInteger value) { + // RLP encoding only supports positive integer values + if (value.signum() < 1) { + return new RlpString(EMPTY); + } else { + byte[] bytes = value.toByteArray(); + if (bytes[0] == 0) { // remove leading zero + return new RlpString(Arrays.copyOfRange(bytes, 1, bytes.length)); + } else { + return new RlpString(bytes); + } + } + } + + public static RlpString create(String value) { + return new RlpString(value.getBytes()); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + RlpString rlpString = (RlpString) o; + + return Arrays.equals(value, rlpString.value); + + } + + @Override + public int hashCode() { + return Arrays.hashCode(value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/rlp/RlpType.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/rlp/RlpType.java new file mode 100644 index 0000000000..211b54424e --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/rlp/RlpType.java @@ -0,0 +1,7 @@ +package org.web3j.rlp; + +/** + * Base RLP type. + */ +public interface RlpType { +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/tx/ChainId.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/tx/ChainId.java new file mode 100644 index 0000000000..a6fe68155f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/tx/ChainId.java @@ -0,0 +1,10 @@ +package org.web3j.tx; + +/** + * Ethereum chain ids. + */ +public class ChainId { + public static final byte NONE = -1; + public static final byte MAIN_NET = 1; + public static final byte TEST_NET = 3; +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/tx/ClientTransactionManager.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/tx/ClientTransactionManager.java new file mode 100644 index 0000000000..8bccaa3f07 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/tx/ClientTransactionManager.java @@ -0,0 +1,52 @@ +package org.web3j.tx; + +import java.math.BigInteger; +import java.util.concurrent.ExecutionException; + +import org.web3j.protocol.Web3j; +import org.web3j.protocol.core.methods.request.Transaction; +import org.web3j.protocol.core.methods.response.EthSendTransaction; +import org.web3j.protocol.exceptions.TransactionTimeoutException; + +/** + *

TransactionManager implementation for using an Ethereum node to transact. + * + *

Note: accounts must be unlocked on the node for transactions to be successful. + */ +public class ClientTransactionManager extends TransactionManager { + + private final Web3j web3j; + private final String fromAddress; + + public ClientTransactionManager( + Web3j web3j, String fromAddress) { + super(web3j); + this.web3j = web3j; + this.fromAddress = fromAddress; + } + + public ClientTransactionManager( + Web3j web3j, String fromAddress, int attempts, int sleepDuration) { + super(web3j, attempts, sleepDuration); + this.web3j = web3j; + this.fromAddress = fromAddress; + } + + @Override + public EthSendTransaction sendTransaction( + BigInteger gasPrice, BigInteger gasLimit, String to, + String data, BigInteger value) + throws ExecutionException, InterruptedException, TransactionTimeoutException { + + Transaction transaction = new Transaction( + fromAddress, null, gasPrice, gasLimit, to, value, data); + + return web3j.ethSendTransaction(transaction) + .sendAsync().get(); + } + + @Override + public String getFromAddress() { + return fromAddress; + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/tx/Contract.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/tx/Contract.java new file mode 100644 index 0000000000..7d4ddb1fd8 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/tx/Contract.java @@ -0,0 +1,267 @@ +package org.web3j.tx; + +import java.lang.reflect.Constructor; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +import org.web3j.abi.EventEncoder; +import org.web3j.abi.EventValues; +import org.web3j.abi.FunctionEncoder; +import org.web3j.abi.FunctionReturnDecoder; +import org.web3j.abi.TypeReference; +import org.web3j.abi.datatypes.Event; +import org.web3j.abi.datatypes.Function; +import org.web3j.abi.datatypes.Type; +import org.web3j.crypto.Credentials; +import org.web3j.protocol.Web3j; +import org.web3j.protocol.core.DefaultBlockParameterName; +import org.web3j.protocol.core.methods.request.Transaction; +import org.web3j.protocol.core.methods.response.Log; +import org.web3j.protocol.core.methods.response.TransactionReceipt; +import org.web3j.protocol.exceptions.TransactionTimeoutException; +import org.web3j.utils.Async; + + +/** + * Solidity contract type abstraction for interacting with smart contracts via native Java types. + */ +public abstract class Contract extends ManagedTransaction { + + // https://www.reddit.com/r/ethereum/comments/5g8ia6/attention_miners_we_recommend_raising_gas_limit/ + public static final BigInteger GAS_LIMIT = BigInteger.valueOf(4_300_000); + + private String contractAddress; + private final BigInteger gasPrice; + private final BigInteger gasLimit; + private TransactionReceipt transactionReceipt; + + protected Contract(String contractAddress, Web3j web3j, TransactionManager transactionManager, + BigInteger gasPrice, BigInteger gasLimit) { + super(web3j, transactionManager); + + this.contractAddress = contractAddress; + this.gasPrice = gasPrice; + this.gasLimit = gasLimit; + } + + protected Contract(String contractAddress, Web3j web3j, Credentials credentials, + BigInteger gasPrice, BigInteger gasLimit) { + this(contractAddress, web3j, new RawTransactionManager(web3j, credentials), + gasPrice, gasLimit); + } + + public void setContractAddress(String contractAddress) { + this.contractAddress = contractAddress; + } + + public String getContractAddress() { + return contractAddress; + } + + public void setTransactionReceipt(TransactionReceipt transactionReceipt) { + this.transactionReceipt = transactionReceipt; + } + + /** + * If this Contract instance was created at deployment, the TransactionReceipt associated + * with the initial creation will be provided, e.g. via a deploy method. This will not persist + * for Contracts instances constructed via a load method. + * + * @return the TransactionReceipt generated at contract deployment + */ + public Optional getTransactionReceipt() { + return Optional.ofNullable(transactionReceipt); + } + + /** + * Execute constant function call - i.e. a call that does not change state of the contract + * + * @param function to call + * @return {@link List} of values returned by function call + * @throws InterruptedException + * @throws ExecutionException + */ + private List executeCall( + Function function) throws InterruptedException, ExecutionException { + String encodedFunction = FunctionEncoder.encode(function); + org.web3j.protocol.core.methods.response.EthCall ethCall = web3j.ethCall( + Transaction.createEthCallTransaction(contractAddress, encodedFunction), + DefaultBlockParameterName.LATEST) + .sendAsync().get(); + + String value = ethCall.getValue(); + return FunctionReturnDecoder.decode(value, function.getOutputParameters()); + } + + protected CompletableFuture executeCallSingleValueReturnAsync( + Function function) { + return Async.run(() -> executeCallSingleValueReturn(function)); + } + + protected CompletableFuture> executeCallMultipleValueReturnAsync( + Function function) { + return Async.run(() -> executeCallMultipleValueReturn(function)); + } + + protected T executeCallSingleValueReturn( + Function function) throws InterruptedException, ExecutionException { + List values = executeCall(function); + return (T) values.get(0); + } + + protected List executeCallMultipleValueReturn( + Function function) throws InterruptedException, ExecutionException { + return executeCall(function); + } + + protected TransactionReceipt executeTransaction(Function function) throws InterruptedException, + ExecutionException, TransactionTimeoutException { + return executeTransaction(FunctionEncoder.encode(function), BigInteger.ZERO); + } + + + /** + * Given the duration required to execute a transaction, asyncronous execution is strongly + * recommended via {@link Contract#executeTransactionAsync}. + * + * @param data to send in transaction + * @param value in Wei to send in transaction + * @return {@link Optional} containing our transaction receipt + * @throws ExecutionException if the computation threw an + * exception + * @throws InterruptedException if the current thread was interrupted + * while waiting + * @throws TransactionTimeoutException if the transaction was not mined while waiting + */ + protected TransactionReceipt executeTransaction( + String data, BigInteger value) + throws ExecutionException, InterruptedException, TransactionTimeoutException { + + return send(contractAddress, data, value, gasPrice, gasLimit); + } + + /** + * Execute the provided function as a transaction asynchronously. + * + * @param function to transact with + * @return {@link Future} containing executing transaction + */ + protected CompletableFuture executeTransactionAsync(Function function) { + return Async.run(() -> executeTransaction(function)); + } + + protected EventValues extractEventParameters( + Event event, Log log) { + + //fix by kelvin, for null topics exception + List topics = log.getTopics(); + if (topics.isEmpty()) { + return null; + } + + String encodedEventSignature = EventEncoder.encode(event); + if (!topics.get(0).equals(encodedEventSignature)) { + return null; + } + + List indexedValues = new ArrayList<>(); + List nonIndexedValues = FunctionReturnDecoder.decode( + log.getData(), event.getNonIndexedParameters()); + + List> indexedParameters = event.getIndexedParameters(); + for (int i = 0; i < indexedParameters.size(); i++) { + Type value = FunctionReturnDecoder.decodeIndexedValue( + topics.get(i + 1), indexedParameters.get(i)); + indexedValues.add(value); + } + return new EventValues(indexedValues, nonIndexedValues); + } + + protected List extractEventParameters( + Event event, TransactionReceipt transactionReceipt) { + + List logs = transactionReceipt.getLogs(); + List values = new ArrayList<>(); + for (Log log : logs) { + EventValues eventValues = extractEventParameters(event, log); + if (eventValues != null) { + values.add(eventValues); + } + } + + return values; + } + + protected static T deploy( + Class type, + Web3j web3j, Credentials credentials, + BigInteger gasPrice, BigInteger gasLimit, + String binary, String encodedConstructor, BigInteger value) throws Exception { + + Constructor constructor = type.getDeclaredConstructor( + String.class, Web3j.class, Credentials.class, + BigInteger.class, BigInteger.class); + constructor.setAccessible(true); + + // we want to use null here to ensure that "to" parameter on message is not populated + T contract = constructor.newInstance(null, web3j, credentials, gasPrice, gasLimit); + + return create(contract, binary, encodedConstructor, value); + } + + protected static T deploy( + Class type, + Web3j web3j, TransactionManager transactionManager, + BigInteger gasPrice, BigInteger gasLimit, + String binary, String encodedConstructor, BigInteger value) throws Exception { + + Constructor constructor = type.getDeclaredConstructor( + String.class, Web3j.class, TransactionManager.class, + BigInteger.class, BigInteger.class); + constructor.setAccessible(true); + + // we want to use null here to ensure that "to" parameter on message is not populated + T contract = constructor.newInstance(null, web3j, transactionManager, gasPrice, gasLimit); + + return create(contract, binary, encodedConstructor, value); + } + + private static T create( + T contract, String binary, String encodedConstructor, BigInteger value) + throws InterruptedException, ExecutionException, TransactionTimeoutException { + TransactionReceipt transactionReceipt = + contract.executeTransaction(binary + encodedConstructor, value); + + String contractAddress = transactionReceipt.getContractAddress(); + if (contractAddress == null) { + throw new RuntimeException("Empty contract address returned"); + } + contract.setContractAddress(contractAddress); + contract.setTransactionReceipt(transactionReceipt); + + return contract; + } + + protected static CompletableFuture deployAsync( + Class type, Web3j web3j, Credentials credentials, + BigInteger gasPrice, BigInteger gasLimit, + String binary, String encodedConstructor, BigInteger value) { + + return Async.run(() -> deploy(type, web3j, credentials, gasPrice, gasLimit, + binary, encodedConstructor, value)); + } + + protected static CompletableFuture deployAsync( + Class type, Web3j web3j, TransactionManager transactionManager, + BigInteger gasPrice, BigInteger gasLimit, + String binary, String encodedConstructor, BigInteger value) { + + return Async.run(() -> deploy(type, web3j, transactionManager, gasPrice, gasLimit, + binary, encodedConstructor, value)); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/tx/FastRawTransactionManager.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/tx/FastRawTransactionManager.java new file mode 100644 index 0000000000..94844b6acd --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/tx/FastRawTransactionManager.java @@ -0,0 +1,46 @@ +package org.web3j.tx; + +import java.math.BigInteger; +import java.util.concurrent.ExecutionException; + +import org.web3j.crypto.Credentials; +import org.web3j.protocol.Web3j; + +/** + * Simple RawTransactionManager derivative that manages nonces to facilitate multiple transactions + * per block. + */ +public class FastRawTransactionManager extends RawTransactionManager { + + private BigInteger nonce = BigInteger.valueOf(-1); + + public FastRawTransactionManager(Web3j web3j, Credentials credentials, byte chainId) { + super(web3j, credentials, chainId); + } + + public FastRawTransactionManager(Web3j web3j, Credentials credentials) { + super(web3j, credentials); + } + + @Override + synchronized BigInteger getNonce() throws InterruptedException, ExecutionException { + if (nonce.signum() == -1) { + nonce = super.getNonce(); + } else { + nonce = nonce.add(BigInteger.ONE); + } + return nonce; + } + + public BigInteger getCurrentNonce() { + return nonce; + } + + public synchronized void resetNonce() throws InterruptedException, ExecutionException { + nonce = super.getNonce(); + } + + public synchronized void setNonce(BigInteger value) { + nonce = value; + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/tx/ManagedTransaction.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/tx/ManagedTransaction.java new file mode 100644 index 0000000000..8ac9b5f012 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/tx/ManagedTransaction.java @@ -0,0 +1,45 @@ +package org.web3j.tx; + +import java.math.BigInteger; +import java.util.Optional; +import java.util.concurrent.ExecutionException; + +import org.web3j.protocol.Web3j; +import org.web3j.protocol.core.methods.response.EthGasPrice; +import org.web3j.protocol.core.methods.response.EthGetTransactionReceipt; +import org.web3j.protocol.core.methods.response.EthSendTransaction; +import org.web3j.protocol.core.methods.response.TransactionReceipt; +import org.web3j.protocol.exceptions.TransactionTimeoutException; + + +/** + * Generic transaction manager. + */ +public abstract class ManagedTransaction { + + // https://www.reddit.com/r/ethereum/comments/5g8ia6/attention_miners_we_recommend_raising_gas_limit/ + public static final BigInteger GAS_PRICE = BigInteger.valueOf(20_000_000_000L); + + protected Web3j web3j; + + private TransactionManager transactionManager; + + protected ManagedTransaction(Web3j web3j, TransactionManager transactionManager) { + this.transactionManager = transactionManager; + this.web3j = web3j; + } + + public BigInteger getGasPrice() throws InterruptedException, ExecutionException { + EthGasPrice ethGasPrice = web3j.ethGasPrice().sendAsync().get(); + + return ethGasPrice.getGasPrice(); + } + + protected TransactionReceipt send( + String to, String data, BigInteger value, BigInteger gasPrice, BigInteger gasLimit) + throws InterruptedException, ExecutionException, TransactionTimeoutException { + + return transactionManager.executeTransaction( + gasPrice, gasLimit, to, data, value); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/tx/RawTransactionManager.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/tx/RawTransactionManager.java new file mode 100644 index 0000000000..9395723df8 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/tx/RawTransactionManager.java @@ -0,0 +1,100 @@ +package org.web3j.tx; + +import java.math.BigInteger; +import java.util.concurrent.ExecutionException; + +import org.web3j.crypto.Credentials; +import org.web3j.crypto.TransactionEncoder; +import org.web3j.protocol.Web3j; +import org.web3j.protocol.core.DefaultBlockParameterName; +import org.web3j.protocol.core.methods.request.RawTransaction; +import org.web3j.protocol.core.methods.response.EthGetTransactionCount; +import org.web3j.protocol.core.methods.response.EthSendTransaction; +import org.web3j.utils.Numeric; + +/** + *

TransactionManager implementation using Ethereum wallet file to create and sign transactions + * locally. + * + *

This transaction manager provides support for specifying the chain id for transactions as per + * EIP155. + */ +public class RawTransactionManager extends TransactionManager { + + private final Web3j web3j; + final Credentials credentials; + + private final byte chainId; + + public RawTransactionManager(Web3j web3j, Credentials credentials, byte chainId) { + super(web3j); + this.web3j = web3j; + this.credentials = credentials; + + this.chainId = chainId; + } + + public RawTransactionManager( + Web3j web3j, Credentials credentials, byte chainId, int attempts, int sleepDuration) { + super(web3j, attempts, sleepDuration); + this.web3j = web3j; + this.credentials = credentials; + + this.chainId = chainId; + } + + public RawTransactionManager(Web3j web3j, Credentials credentials) { + this(web3j, credentials, ChainId.NONE); + } + + public RawTransactionManager( + Web3j web3j, Credentials credentials, int attempts, int sleepDuration) { + this(web3j, credentials, ChainId.NONE, attempts, sleepDuration); + } + + BigInteger getNonce() throws ExecutionException, InterruptedException { + EthGetTransactionCount ethGetTransactionCount = web3j.ethGetTransactionCount( + credentials.getAddress(), DefaultBlockParameterName.LATEST).sendAsync().get(); + + return ethGetTransactionCount.getTransactionCount(); + } + + @Override + public EthSendTransaction sendTransaction( + BigInteger gasPrice, BigInteger gasLimit, String to, + String data, BigInteger value) throws ExecutionException, InterruptedException { + + BigInteger nonce = getNonce(); + + RawTransaction rawTransaction = RawTransaction.createTransaction( + nonce, + gasPrice, + gasLimit, + to, + value, + data); + + return signAndSend(rawTransaction); + } + + public EthSendTransaction signAndSend(RawTransaction rawTransaction) + throws ExecutionException, InterruptedException { + + byte[] signedMessage; + + if (chainId > ChainId.NONE) { + signedMessage = TransactionEncoder.signMessage(rawTransaction, chainId, credentials); + } else { + signedMessage = TransactionEncoder.signMessage(rawTransaction, credentials); + } + + String hexValue = Numeric.toHexString(signedMessage); + + return web3j.ethSendRawTransaction(hexValue).sendAsync().get(); + } + + @Override + public String getFromAddress() { + return credentials.getAddress(); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/tx/TransactionManager.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/tx/TransactionManager.java new file mode 100644 index 0000000000..1ea54d6d4c --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/tx/TransactionManager.java @@ -0,0 +1,105 @@ +package org.web3j.tx; + +import java.math.BigInteger; +import java.util.Optional; +import java.util.concurrent.ExecutionException; + +import org.web3j.protocol.Web3j; +import org.web3j.protocol.core.methods.response.EthGetTransactionReceipt; +import org.web3j.protocol.core.methods.response.EthSendTransaction; +import org.web3j.protocol.core.methods.response.TransactionReceipt; +import org.web3j.protocol.exceptions.TransactionTimeoutException; + +/** + * Transaction manager abstraction for executing transactions with Ethereum client via + * various mechanisms. + */ +public abstract class TransactionManager { + + private static final int SLEEP_DURATION = 15000; + private static final int ATTEMPTS = 40; + + private final int sleepDuration; + private final int attempts; + + private final Web3j web3j; + + protected TransactionManager(Web3j web3j) { + this.web3j = web3j; + this.attempts = ATTEMPTS; + this.sleepDuration = SLEEP_DURATION; + } + + protected TransactionManager(Web3j web3j, int attempts, int sleepDuration) { + this.web3j = web3j; + this.attempts = attempts; + this.sleepDuration = sleepDuration; + } + + TransactionReceipt executeTransaction( + BigInteger gasPrice, BigInteger gasLimit, String to, + String data, BigInteger value) + throws ExecutionException, InterruptedException, TransactionTimeoutException { + + EthSendTransaction ethSendTransaction = sendTransaction(gasPrice, gasLimit, to, data, value); + return processResponse(ethSendTransaction); + } + + public abstract EthSendTransaction sendTransaction( + BigInteger gasPrice, BigInteger gasLimit, String to, + String data, BigInteger value) + throws ExecutionException, InterruptedException, TransactionTimeoutException; + + public abstract String getFromAddress(); + + private TransactionReceipt processResponse(EthSendTransaction transactionResponse) + throws InterruptedException, ExecutionException, TransactionTimeoutException { + if (transactionResponse.hasError()) { + throw new RuntimeException("Error processing transaction request: " + + transactionResponse.getError().getMessage()); + } + + String transactionHash = transactionResponse.getTransactionHash(); + + return waitForTransactionReceipt(transactionHash); + } + + private TransactionReceipt waitForTransactionReceipt( + String transactionHash) throws InterruptedException, ExecutionException, + TransactionTimeoutException { + + return getTransactionReceipt(transactionHash, sleepDuration, attempts); + } + + private TransactionReceipt getTransactionReceipt( + String transactionHash, int sleepDuration, int attempts) + throws InterruptedException, ExecutionException, TransactionTimeoutException { + + Optional receiptOptional = + sendTransactionReceiptRequest(transactionHash); + for (int i = 0; i < attempts; i++) { + if (!receiptOptional.isPresent()) { + Thread.sleep(sleepDuration); + receiptOptional = sendTransactionReceiptRequest(transactionHash); + } else { + return receiptOptional.get(); + } + } + + throw new TransactionTimeoutException("Transaction receipt was not generated after " + + ((sleepDuration * attempts) / 1000 + + " seconds for transaction: " + transactionHash)); + } + + private Optional sendTransactionReceiptRequest( + String transactionHash) throws InterruptedException, ExecutionException { + EthGetTransactionReceipt transactionReceipt = + web3j.ethGetTransactionReceipt(transactionHash).sendAsync().get(); + if (transactionReceipt.hasError()) { + throw new RuntimeException("Error processing request: " + + transactionReceipt.getError().getMessage()); + } + + return transactionReceipt.getTransactionReceipt(); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/tx/Transfer.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/tx/Transfer.java new file mode 100644 index 0000000000..502391ff67 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/tx/Transfer.java @@ -0,0 +1,110 @@ +package org.web3j.tx; + + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Optional; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +import org.web3j.crypto.Credentials; +import org.web3j.protocol.Web3j; +import org.web3j.protocol.core.methods.response.TransactionReceipt; +import org.web3j.protocol.exceptions.TransactionTimeoutException; +import org.web3j.utils.Async; +import org.web3j.utils.Convert; +import org.web3j.utils.Numeric; + + +/** + * Class for performing Ether transactions on the Ethereum blockchain. + */ +public class Transfer extends ManagedTransaction { + + // This is the cost to send Ether between parties + public static final BigInteger GAS_LIMIT = BigInteger.valueOf(21000); + + public Transfer(Web3j web3j, TransactionManager transactionManager) { + super(web3j, transactionManager); + } + + /** + * Given the duration required to execute a transaction, asyncronous execution is strongly + * recommended via {@link Transfer#sendFundsAsync(String, BigDecimal, Convert.Unit)}. + * + * @param toAddress destination address + * @param value amount to send + * @param unit of specified send + * + * @return {@link Optional} containing our transaction receipt + * @throws ExecutionException if the computation threw an + * exception + * @throws InterruptedException if the current thread was interrupted + * while waiting + * @throws TransactionTimeoutException if the transaction was not mined while waiting + */ + private TransactionReceipt send(String toAddress, BigDecimal value, Convert.Unit unit) + throws ExecutionException, InterruptedException, + TransactionTimeoutException { + + BigInteger gasPrice = getGasPrice(); + return send(toAddress, value, unit, gasPrice, GAS_LIMIT); + } + + private TransactionReceipt send( + String toAddress, BigDecimal value, Convert.Unit unit, BigInteger gasPrice, + BigInteger gasLimit) throws ExecutionException, InterruptedException, + TransactionTimeoutException { + + BigDecimal weiValue = Convert.toWei(value, unit); + if (!Numeric.isIntegerValue(weiValue)) { + throw new UnsupportedOperationException( + "Non decimal Wei value provided: " + value + " " + unit.toString() + + " = " + weiValue + " Wei"); + } + + return send(toAddress, "", weiValue.toBigIntegerExact(), gasPrice, gasLimit); + } + + /** + * Execute the provided function as a transaction asynchronously. This is intended for one-off + * fund transfers. For multiple, create an instance. + * + * @param toAddress destination address + * @param value amount to send + * @param unit of specified send + * + * @return {@link Future} containing executing transaction + */ + public Future sendFundsAsync( + String toAddress, BigDecimal value, Convert.Unit unit) { + return Async.run(() -> send(toAddress, value, unit)); + } + + public Future sendFundsAsync( + String toAddress, BigDecimal value, Convert.Unit unit, BigInteger gasPrice, + BigInteger gasLimit) { + return Async.run(() -> send(toAddress, value, unit, gasPrice, gasLimit)); + } + + public static TransactionReceipt sendFunds( + Web3j web3j, Credentials credentials, + String toAddress, BigDecimal value, Convert.Unit unit) throws InterruptedException, + ExecutionException, TransactionTimeoutException { + + TransactionManager transactionManager = new RawTransactionManager(web3j, credentials); + + return new Transfer(web3j, transactionManager).send(toAddress, value, unit); + } + + public static Future sendFundsAsync( + Web3j web3j, Credentials credentials, + String toAddress, BigDecimal value, Convert.Unit unit) throws InterruptedException, + ExecutionException, TransactionTimeoutException { + + TransactionManager transactionManager = new RawTransactionManager(web3j, credentials); + + return new Transfer(web3j, transactionManager) + .sendFundsAsync(toAddress, value, unit); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/utils/Async.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/utils/Async.java new file mode 100644 index 0000000000..a775d43312 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/utils/Async.java @@ -0,0 +1,35 @@ +package org.web3j.utils; + + +import java.util.concurrent.Callable; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +/** + * Async task facilitation. + */ +public class Async { + + public static CompletableFuture run(Callable callable) { + CompletableFuture result = new CompletableFuture<>(); + CompletableFuture.runAsync(() -> { + // we need to explicityly catch any exceptions, + // otherwise they will be silently discarded + try { + result.complete(callable.call()); + } catch (Throwable e) { + result.completeExceptionally(e); + } + }); + return result; + } + + private static int getCpuCount() { + return Runtime.getRuntime().availableProcessors(); + } + + public static ExecutorService defaultExecutorService() { + return Executors.newFixedThreadPool(getCpuCount()); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/utils/Bytes.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/utils/Bytes.java new file mode 100644 index 0000000000..ebc125de1d --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/utils/Bytes.java @@ -0,0 +1,25 @@ +package org.web3j.utils; + +import java.util.Arrays; + +/** + * Byte array utility functions. + */ +public class Bytes { + + private Bytes() {} + + public static byte[] trimLeadingBytes(byte[] bytes, byte b) { + int offset = 0; + for (; offset < bytes.length - 1; offset++) { + if (bytes[offset] != b) { + break; + } + } + return Arrays.copyOfRange(bytes, offset, bytes.length); + } + + public static byte[] trimLeadingZeroes(byte[] bytes) { + return trimLeadingBytes(bytes, (byte) 0); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/utils/Collection.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/utils/Collection.java new file mode 100644 index 0000000000..485c2d453f --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/utils/Collection.java @@ -0,0 +1,49 @@ +package org.web3j.utils; + +import java.util.Arrays; +import java.util.List; + +/** + * Utility functions for working with Collections. + */ +public class Collection { + static String[] EMPTY_STRING_ARRAY = { }; + + public static String[] tail(String[] args) { + if (args.length == 0) { + return EMPTY_STRING_ARRAY; + } else { + return Arrays.copyOfRange(args, 1, args.length); + } + } + + public static T[] create(T... args) { + return args; + } + + public static String join(List list, String separator, Function function) { + String result = ""; + for (int i = 0; i < list.size(); i++) { + result += function.apply(list.get(i)).trim(); + if (i + 1 < list.size()) { + result += separator; + } + } + return result; + } + + public static String join(List list, String separator) { + String result = ""; + for (int i = 0; i < list.size(); i++) { + result += list.get(i).trim(); + if (i + 1 < list.size()) { + result += separator; + } + } + return result; + } + + public interface Function { + S apply(R r); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/utils/Console.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/utils/Console.java new file mode 100644 index 0000000000..f945fdc785 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/utils/Console.java @@ -0,0 +1,20 @@ +package org.web3j.utils; + +/** + * Command line utility classes. + */ +public class Console { + public static void exitError(String message) { + System.err.println(message); + System.exit(1); + } + + public static void exitError(Throwable throwable) { + exitError(throwable.getMessage()); + } + + public static void exitSuccess(String message) { + System.out.println(message); + System.exit(0); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/utils/Convert.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/utils/Convert.java new file mode 100644 index 0000000000..f6ee5e5bbf --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/utils/Convert.java @@ -0,0 +1,67 @@ +package org.web3j.utils; + +import java.math.BigDecimal; + +/** + * Ethereum unit conversion functions. + */ +public final class Convert { + private Convert() { } + + public static BigDecimal fromWei(String number, Unit unit) { + return fromWei(new BigDecimal(number), unit); + } + + public static BigDecimal fromWei(BigDecimal number, Unit unit) { + return number.divide(unit.getWeiFactor()); + } + + public static BigDecimal toWei(String number, Unit unit) { + return toWei(new BigDecimal(number), unit); + } + + public static BigDecimal toWei(BigDecimal number, Unit unit) { + return number.multiply(unit.getWeiFactor()); + } + + public enum Unit { + WEI("wei", 0), + KWEI("kwei", 3), + MWEI("mwei", 6), + GWEI("gwei", 9), + SZABO("szabo", 12), + FINNEY("finney", 15), + ETHER("ether", 18), + KETHER("kether", 21), + METHER("mether", 24), + GETHER("gether", 27); + + private String name; + private BigDecimal weiFactor; + + Unit(String name, int factor) { + this.name = name; + this.weiFactor = BigDecimal.TEN.pow(factor); + } + + public BigDecimal getWeiFactor() { + return weiFactor; + } + + @Override + public String toString() { + return name; + } + + public static Unit fromString(String name) { + if (name != null) { + for (Unit unit : Unit.values()) { + if (name.equalsIgnoreCase(unit.name)) { + return unit; + } + } + } + return Unit.valueOf(name); + } + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/utils/Files.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/utils/Files.java new file mode 100644 index 0000000000..a956fe7447 --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/utils/Files.java @@ -0,0 +1,25 @@ +package org.web3j.utils; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; + +/** + * File utility functions. + */ +public class Files { + + private Files() { } + + public static byte[] readBytes(File file) throws IOException { + byte[] bytes = new byte[(int) file.length()]; + FileInputStream fileInputStream = new FileInputStream(file); + fileInputStream.read(bytes); + fileInputStream.close(); + return bytes; + } + + public static String readString(File file) throws IOException { + return new String(readBytes(file)); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/utils/Numeric.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/utils/Numeric.java new file mode 100644 index 0000000000..990139e5bc --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/utils/Numeric.java @@ -0,0 +1,213 @@ +package org.web3j.utils; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Arrays; + +import org.web3j.protocol.exceptions.MessageDecodingException; +import org.web3j.protocol.exceptions.MessageEncodingException; + +/** + *

Message codec functions.

+ * + *

Implementation as per https://github.com/ethereum/wiki/wiki/JSON-RPC#hex-value-encoding

+ */ +public final class Numeric { + + private static final String HEX_PREFIX = "0x"; + + private Numeric() { + } + + public static String encodeQuantity(BigInteger value) { + if (value.signum() != -1) { + return HEX_PREFIX + value.toString(16); + } else { + throw new MessageEncodingException("Negative values are not supported"); + } + } + + public static BigInteger decodeQuantity(String value) { + if (!isValidHexQuantity(value)) { + throw new MessageDecodingException("Value must be in format 0x[1-9]+[0-9]* or 0x0"); + } + try { + return new BigInteger(value.substring(2), 16); + } catch (NumberFormatException e) { + throw new MessageDecodingException("Negative ", e); + } + } + + private static boolean isValidHexQuantity(String value) { + if (value == null) { + return false; + } + + if (value.length() < 3) { + return false; + } + + if (!value.startsWith(HEX_PREFIX)) { + return false; + } + + // If TestRpc resolves the following issue, we can reinstate this code + // https://github.com/ethereumjs/testrpc/issues/220 +// if (value.length() > 3 && value.charAt(2) == '0') { +// return false; +// } + + return true; + } + + public static String cleanHexPrefix(String input) { + if (containsHexPrefix(input)) { + return input.substring(2); + } else { + return input; + } + } + + public static String prependHexPrefix(String input) { + if (!containsHexPrefix(input)) { + return HEX_PREFIX + input; + } else { + return input; + } + } + + public static boolean containsHexPrefix(String input) { + return input.length() > 1 && input.charAt(0) == '0' && input.charAt(1) == 'x'; + } + + public static BigInteger toBigInt(byte[] value, int offset, int length) { + return toBigInt((Arrays.copyOfRange(value, offset, offset + length))); + } + + public static BigInteger toBigInt(byte[] value) { + return new BigInteger(1, value); + } + + public static BigInteger toBigInt(String hexValue) { + String cleanValue = cleanHexPrefix(hexValue); + return new BigInteger(cleanValue, 16); + } + + public static String toHexStringWithPrefix(BigInteger value) { + return HEX_PREFIX + value.toString(16); + } + + public static String toHexStringNoPrefix(BigInteger value) { + return value.toString(16); + } + + public static String toHexStringWithPrefixZeroPadded(BigInteger value, int size) { + return toHexStringZeroPadded(value, size, true); + } + + public static String toHexStringNoPrefixZeroPadded(BigInteger value, int size) { + return toHexStringZeroPadded(value, size, false); + } + + private static String toHexStringZeroPadded(BigInteger value, int size, boolean withPrefix) { + String result = toHexStringNoPrefix(value); + + int length = result.length(); + if (length > size) { + throw new UnsupportedOperationException( + "Value " + result + "is larger then length " + size); + } else if (value.signum() < 0) { + throw new UnsupportedOperationException("Value cannot be negative"); + } + + if (length < size) { + result = Strings.zeros(size - length) + result; + } + + if (withPrefix) { + return HEX_PREFIX + result; + } else { + return result; + } + } + + public static byte[] toBytesPadded(BigInteger value, int length) { + byte[] result = new byte[length]; + byte[] bytes = value.toByteArray(); + + int bytesLength; + int srcOffset; + if (bytes[0] == 0) { + bytesLength = bytes.length - 1; + srcOffset = 1; + } else { + bytesLength = bytes.length; + srcOffset = 0; + } + + if (bytesLength > length) { + throw new RuntimeException("Input is too large to put in byte array of size " + length); + } + + int destOffset = length - bytesLength; + System.arraycopy(bytes, srcOffset, result, destOffset, bytesLength); + return result; + } + + public static byte[] hexStringToByteArray(String input) { + String cleanInput = cleanHexPrefix(input); + + int len = cleanInput.length(); + + if (len == 0) { + return new byte[] {}; + } + + byte[] data; + int startIdx; + if (len % 2 != 0) { + data = new byte[(len / 2) + 1]; + data[0] = (byte) Character.digit(cleanInput.charAt(0), 16); + startIdx = 1; + } else { + data = new byte[len / 2]; + startIdx = 0; + } + + for (int i = startIdx; i < len; i += 2) { + data[(i + 1) / 2] = (byte) ((Character.digit(cleanInput.charAt(i), 16) << 4) + + Character.digit(cleanInput.charAt(i+1), 16)); + } + return data; + } + + public static String toHexString(byte[] input, int offset, int length, boolean withPrefix) { + StringBuilder stringBuilder = new StringBuilder(); + if (withPrefix) { + stringBuilder.append("0x"); + } + for (int i = offset; i < offset + length; i++) { + stringBuilder.append(String.format("%02x", input[i] & 0xFF)); + } + + return stringBuilder.toString(); + } + + public static String toHexStringNoPrefix(byte[] input) { + return toHexString(input, 0, input.length, false); + } + + public static String toHexString(byte[] input) { + return toHexString(input, 0, input.length, true); + } + + public static byte b(int m, int n) { + return (byte) ( (m << 4) | n); + } + + public static boolean isIntegerValue(BigDecimal value) { + return value.signum() == 0 || + value.scale() <= 0 || + value.stripTrailingZeros().scale() <= 0; + } +} \ No newline at end of file diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/utils/Strings.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/utils/Strings.java new file mode 100644 index 0000000000..b4aadaf55d --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/utils/Strings.java @@ -0,0 +1,50 @@ +package org.web3j.utils; + +import java.util.List; + +/** + * String utility functions. + */ +public class Strings { + + private Strings() {} + + public static String toCsv(List src) { + return join(src, ", "); + } + + public static String join(List src, String delimiter) { + String result = ""; + for (int i = 0; i < src.size(); i++) { + result += src.get(i); + if (i + 1 < src.size()) { + result += delimiter; + } + } + return result; + } + + public static String capitaliseFirstLetter(String string) { + if (string == null || string.length() == 0) { + return string; + } else { + return string.substring(0, 1).toUpperCase() + string.substring(1); + } + } + + public static String lowercaseFirstLetter(String string) { + if (string == null || string.length() == 0) { + return string; + } else { + return string.substring(0, 1).toLowerCase() + string.substring(1); + } + } + + public static String zeros(int n) { + return repeat('0', n); + } + + public static String repeat(char value, int n) { + return new String(new char[n]).replace("\0", String.valueOf(value)); + } +} diff --git a/tool/java/web3j-v2.1.0_src/src/org/web3j/utils/Version.java b/tool/java/web3j-v2.1.0_src/src/org/web3j/utils/Version.java new file mode 100644 index 0000000000..664459ff8e --- /dev/null +++ b/tool/java/web3j-v2.1.0_src/src/org/web3j/utils/Version.java @@ -0,0 +1,31 @@ +package org.web3j.utils; + +import java.io.IOException; +import java.util.Properties; + +/** + * Build version utility method. + */ +public class Version { + + private Version() {} + + public static final String DEFAULT = "none"; + + private static final String TIMESTAMP = "timestamp"; + private static final String VERSION = "version"; + + public static String getVersion() throws IOException { + return loadProperties().getProperty(VERSION); + } + + public static String getTimestamp() throws IOException { + return loadProperties().getProperty(TIMESTAMP); + } + + private static Properties loadProperties() throws IOException { + Properties properties = new Properties(); + properties.load(Version.class.getResourceAsStream("/version.properties")); + return properties; + } +} diff --git a/tool/monitor.js b/tool/monitor.js new file mode 100644 index 0000000000..6447b43162 --- /dev/null +++ b/tool/monitor.js @@ -0,0 +1,72 @@ + +var Web3= require('web3'); +var config=require('./config'); +var fs=require('fs'); +var BigNumber = require('bignumber.js'); +var web3sync = require('./web3sync'); +var post=require('./post'); + +if (typeof web3 !== 'undefined') { + web3 = new Web3(web3.currentProvider); +} else { + web3 = new Web3(new Web3.providers.HttpProvider(config.HttpProvider)); +} + +/* +* npm install --save-dev babel-cli babel-preset-es2017 +* echo '{ "presets": ["es2017"] }' > .babelrc +* npm install secp256k1 keccak rlp +*/ + + +async function getPeerCount() { + + return new Promise((resolve, reject) => { + web3.net.getPeerCount(function(e,d){ + resolve(d); + }); + }); +} + +async function sleep(timeout) { + return new Promise((resolve, reject) => { + setTimeout(function() { + resolve(); + }, timeout); + }); +} + +(async function() { + + + +while(1){ + console.log("已连接节点数:"+ await getPeerCount() ); + var peers=await post.post("admin_peers",[]); + + try{ + peers=JSON.parse(peers); + if( peers.result ) + { + for( var i=0;i=6.10.3", + "npm": ">=3.10.0" + } +} diff --git a/tool/post.js b/tool/post.js new file mode 100644 index 0000000000..5e5bb6b9b4 --- /dev/null +++ b/tool/post.js @@ -0,0 +1,76 @@ + +var Web3= require('web3'); +var config=require('./config'); +var fs=require('fs'); +var BigNumber = require('bignumber.js'); +var web3sync = require('./web3sync'); + +if (typeof web3 !== 'undefined') { + web3 = new Web3(web3.currentProvider); +} else { + web3 = new Web3(new Web3.providers.HttpProvider(config.HttpProvider)); +} + + +var http = require('http'); + + + + + +async function post(method,params) { + + return new Promise((resolve, reject) => { + + //curl -X POST --data '{"jsonrpc":"2.0","method":"admin_peers","params":[],"id":74}' 127.0.0.1:8545 + var post_data = { + "jsonrpc":"2.0", + "method":method, + "params":params, + "id":74 + };//这是需要提交的数据 + + + var content = JSON.stringify(post_data); + + var options = { + hostname: config.HttpProvider.replace("http:\/\/","").replace(/:\d+/,''), + port: config.HttpProvider.replace(/http:.*:/,''), + path: '', + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' + } + }; + + var response=""; + var req = http.request(options, function (res) { + //console.log('STATUS: ' + res.statusCode); + //console.log('HEADERS: ' + JSON.stringify(res.headers)); + + res.setEncoding('utf8'); + res.on('data', function (chunk) { + //console.log('BODY: ' + chunk); + response+=chunk; + }); + res.on('end', function (chunk) { + + resolve(response); + }); + }); + + req.on('error', function (e) { + console.log('problem with request: ' + e.message); + }); + + // write data to request body + req.write(content); + + req.end(); + }); +} + + +exports.post=post; + + diff --git a/tool/readme.txt b/tool/readme.txt new file mode 100644 index 0000000000..09311f78c0 --- /dev/null +++ b/tool/readme.txt @@ -0,0 +1,6 @@ +/* +* npm install +* npm install --save-dev babel-cli babel-preset-es2017 +* echo '{ "presets": ["es2017"] }' > .babelrc +* npm install keccak rlp secp256k1 +*/ diff --git a/tool/sendRawTransaction.js b/tool/sendRawTransaction.js new file mode 100644 index 0000000000..bdebdd92af --- /dev/null +++ b/tool/sendRawTransaction.js @@ -0,0 +1,61 @@ +var fs = require("fs"); +var Web3 = require('web3'); +var net = require('net'); +var conf = require('./config'); +var txm = require('./transactionManager'); +var coder = require('./codeUtils'); + +//init web3 +var web3 = new Web3(); +var client = new net.Socket(); +web3.setProvider(new web3.providers.IpcProvider(conf.ipc_path,client)); + +//sendRawTransaction +function sendRawTransaction() +{ + web3.eth.getBlockNumber(function(e,d){ + console.log(e+','+d); + var blocknumber=d+100; + + var call_fun="add(uint256)"; + var types=['uint256']; + var params=['15']; + var tx_data = coder.codeTxData(call_fun,types,params); + + console.log('account:'+conf.account); + + var postdata = { + data: tx_data, + from: conf.account, + to:conf.contract_addr, + gas: 1000000, + randomid:Math.ceil(Math.random()*100000000), + blockLimit:blocknumber + } + + var signTX = txm.signTransaction(postdata,conf.privKey,null); + console.log("signTX : ",signTX); + web3.eth.sendRawTransaction(signTX, function(err, address) { + console.log(err,address); + if (!err) + { + console.log("发送交易成功!|",address); + process.exit(); + return; + } + else + { + console.log("发送交易失败!",err); + process.exit(); + return; + } + }); + + + }); + + +} + + +sendRawTransaction(); \ No newline at end of file diff --git a/tool/sendTransaction.js b/tool/sendTransaction.js new file mode 100644 index 0000000000..ece0351f69 --- /dev/null +++ b/tool/sendTransaction.js @@ -0,0 +1,192 @@ +var fs = require("fs"); +var Web3 = require('web3'); +var net = require('net'); +var conf = require('./config'); + +//init web3 +var web3 = new Web3(); +var client = new net.Socket(); +web3.setProvider(new web3.providers.IpcProvider(conf.ipc_path,client)); + +//sendTransaction +function sendTransaction() +{ + var postdata = { + data: params_data, + from: conf.account, + to:conf.contract_addr, + value:params_value, + gas: 1000000 + } + //发送交易 + web3.eth.sendTransaction(postdata, function(err, address) { + if (!err) + { + logger.debug(tx_id + " | 发送交易成功!|",address); + process.exit(); + return; + } + else + { + logger.debug(tx_id + "|发送交易失败!",err); + process.exit(); + return; + } + }); +} + +function callContract() +{ + var test_params = ''; + //调用合约 + var abi_obj = conf.abi_arr; + var args = test_params; + console.log(" |args : " + args); + if( typeof(abi_obj) === 'string' || Object.prototype.toString.call(abi_obj) === '[object String]') + { + abi_obj = JSON.parse(abi_obj); + } + if( typeof(args) === 'string' || Object.prototype.toString.call(args) === '[object String]') + { + args = JSON.parse(args); + } + console.log(typeof(abi_obj) + " | " + Object.prototype.toString.call(abi_obj)); + console.log(typeof(args) + " | " + Object.prototype.toString.call(args)); + if(typeof(abi_obj) !== 'object' || Object.prototype.toString.call(abi_obj) !== '[object Array]' || typeof(args) !== 'object' || Object.prototype.toString.call(args) !== '[object Array]') + { + console.log("参数格式不合法! abi_obj : " + JSON.stringify(abi_obj) +" | args : " + JSON.stringify(args)); + process.exit(); + return; + } + else + { + console.log(" |args : " + args + " | " + JSON.stringify(args)); + var breaked = false; + var abi_obj_size = abi_obj.length; + abi_obj.forEach(function (obj,index) + { + if(breaked) return;; + console.log("obj : " + JSON.stringify(obj) + " | " + abi_obj_size + " | " + index); + if(obj.constant !== undefined && obj.name !== undefined && obj.name === fun) + { + console.log("call fun : " + obj.name); + try{ + // creation of contract object + var MyContract = web3.eth.contract(abi_obj); + // initiate contract for an address + if( conf.contract_addr === '' || conf.contract_addr === undefined) + { + console.log("未传入合约地址!"); + process.exit(); + return; + } + var myContractInstance = MyContract.at(conf.contract_addr); + var f = myContractInstance[fun]; + if(obj.constant) + { + console.log(fun+" is a constant function, we should call it."); + if(typeof(f) === 'function') + { + try + { + var call_param = args; + function call_back(err,ret_data){ + console.log("err : " + err + " | ret_data : " + JSON.stringify(ret_data)); + if( !err ) + { + console.log(f + " result : " + JSON.stringify(ret_data)); + process.exit(); + return; + } + else + { + console.log(" 调用合约失败"); + process.exit(); + return; + } + } + call_param.push(call_back); + console.log("f:"+f + " | args : " + JSON.stringify(call_param)); + f.apply(myContractInstance, call_param); + } + catch(e) + { + console.log("exception:"+e.message); + process.exit(); + return; + } + } + else + { + console.log(f + " 不是合约函数!"); + process.exit(); + return; + } + } + else + { + console.log(fun+" is not a constant function, we should send a Transaction."); + if(typeof(f) === 'function') + { + try + { + var call_param = args; + var fromparam = { + from:conf.account, + gas:100000000 + }; + //gas: 1000000000 + call_param.push(fromparam); + function call_back(err,ret_data) + { + console.log("err : " + err + " | ret_data : " + JSON.stringify(ret_data)); + if( !err ) + { + console.log(f + " result : " + JSON.stringify(ret_data)); + process.exit(); + return; + } + else + { + console.log("调用合约失败!"); + process.exit(); + return; + } + } + call_param.push(call_back); + console.log("call_param : " + JSON.stringify(call_param)); + f.apply(myContractInstance, call_param); + } + catch(e) + { + console.log("调用合约失败! | exception:",e); + process.exit(); + return; + } + } + else + { + console.log(f + " 不是合约函数!"); + process.exit(); + return; + } + } + breaked = true; + } + catch(ex) + { + console.log("exception:",ex); + process.exit(); + return; + } + } + if( parseInt(abi_obj_size) === (parseInt(index)+1) && !breaked ) + { + console.log("合约未包含该函数!" + fun); + process.exit(); + return; + } + }); + } +} + diff --git a/tool/sha3.js b/tool/sha3.js new file mode 100644 index 0000000000..03e86683e9 --- /dev/null +++ b/tool/sha3.js @@ -0,0 +1,38 @@ +/* + This file is part of web3.js. + + web3.js is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + web3.js 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with web3.js. If not, see . +*/ +/** + * @file sha3.js + * @author Marek Kotewicz + * @date 2015 + */ + +var CryptoJS = require('crypto-js'); +var sha3 = require('crypto-js/sha3'); + +module.exports = function (value, options) { + if (options && options.encoding === 'hex') { + if (value.length > 2 && value.substr(0, 2) === '0x') { + value = value.substr(2); + } + value = CryptoJS.enc.Hex.parse(value); + } + + return sha3(value, { + outputLength: 256 + }).toString(); +}; + diff --git a/tool/signTransaction.js b/tool/signTransaction.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tool/solc-static-linux b/tool/solc-static-linux new file mode 100644 index 0000000000..1d4f3e8c50 Binary files /dev/null and b/tool/solc-static-linux differ diff --git a/tool/solc-static-linux.1 b/tool/solc-static-linux.1 new file mode 100644 index 0000000000..dde0d7558c Binary files /dev/null and b/tool/solc-static-linux.1 differ diff --git a/tool/transactionManager.js b/tool/transactionManager.js new file mode 100644 index 0000000000..d6f33e9f7d --- /dev/null +++ b/tool/transactionManager.js @@ -0,0 +1,22 @@ +var Tx = require('./transactionObject.js'); + +function signTransaction(tx_data,privKey,callback) +{ + // convert string private key to a Buffer Object + var privateKey = new Buffer(privKey, 'hex'); + var tx = new Tx.Transaction(tx_data); + tx.sign(privateKey); + // Build a serialized hex version of the Tx + var serializedTx = '0x' + tx.serialize().toString('hex'); + if( null !== callback) + { + callback(serializedTx); + return ; + } + else + { + return serializedTx; + } +} + +exports.signTransaction=signTransaction; \ No newline at end of file diff --git a/tool/transactionObject.js b/tool/transactionObject.js new file mode 100644 index 0000000000..a05243dc62 --- /dev/null +++ b/tool/transactionObject.js @@ -0,0 +1,253 @@ +const ethUtil = require('./utils.js') +const BN = ethUtil.BN + +// secp256k1n/2 +const N_DIV_2 = new BN('7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0', 16) + +function Transaction(data) { + data = data || {} + // Define Properties + const fields = [{ + name: 'randomid', + length: 32, + allowLess: true, + default: new Buffer([]) + }, { + name: 'gasPrice', + length: 32, + allowLess: true, + default: new Buffer([]) + }, { + name: 'gasLimit', + alias: 'gas', + length: 32, + allowLess: true, + default: new Buffer([]) + }, { + name: 'blockLimit', + length: 32, + allowLess: true, + default: new Buffer([]) + },{ + name: 'to', + allowZero: true, + length: 20, + default: new Buffer([]) + }, { + name: 'value', + length: 32, + allowLess: true, + default: new Buffer([]) + }, { + name: 'data', + alias: 'input', + allowZero: true, + default: new Buffer([]) + }, { + name: 'v', + length: 1, + default: new Buffer([0x1c]) + }, { + name: 'r', + length: 32, + allowLess: true, + default: new Buffer([]) + }, { + name: 's', + length: 32, + allowLess: true, + default: new Buffer([]) + }] + + /** + * Returns the rlp encoding of the transaction + * @method serialize + * @return {Buffer} + */ + // attached serialize + ethUtil.defineProperties(this, fields, data) + + /** + * @prop {Buffer} from (read only) sender address of this transaction, mathematically derived from other parameters. + */ + Object.defineProperty(this, 'from', { + enumerable: true, + configurable: true, + get: this.getSenderAddress.bind(this) + }) + + // calculate chainId from signature + var sigV = ethUtil.bufferToInt(this.v) + var chainId = Math.floor((sigV - 35) / 2) + if (chainId < 0) chainId = 0 + + // set chainId + this._chainId = chainId || data.chainId || 0 + this._homestead = true + } + + /** + * If the tx's `to` is to the creation address + * @return {Boolean} + */ + Transaction.prototype.toCreationAddress=function () { + return this.to.toString('hex') === '' + } + + /** + * Computes a sha3-256 hash of the serialized tx + * @param {Boolean} [includeSignature=true] whether or not to inculde the signature + * @return {Buffer} + */ + Transaction.prototype.hash=function (includeSignature) { + if (includeSignature === undefined) includeSignature = true + // backup original signature + const rawCopy = this.raw.slice(0) + + // modify raw for signature generation only + if (this._chainId > 0) { + includeSignature = true + this.v = this._chainId + this.r = 0 + this.s = 0 + } + + // generate rlp params for hash + console.log(this.raw.length) + var txRawForHash = includeSignature ? this.raw : this.raw.slice(0, this.raw.length - 3) + //var txRawForHash = includeSignature ? this.raw : this.raw.slice(0, 7) + + // restore original signature + this.raw = rawCopy.slice() + + // create hash + return ethUtil.rlphash(txRawForHash) + } + + /** + * returns the public key of the sender + * @return {Buffer} + */ + Transaction.prototype.getChainId=function() { + return this._chainId + } + + /** + * returns the sender's address + * @return {Buffer} + */ + Transaction.prototype.getSenderAddress = function() { + if (this._from) { + return this._from + } + const pubkey = this.getSenderPublicKey() + this._from = ethUtil.publicToAddress(pubkey) + return this._from + } + + /** + * returns the public key of the sender + * @return {Buffer} + */ + Transaction.prototype.getSenderPublicKey =function() { + if (!this._senderPubKey || !this._senderPubKey.length) { + if (!this.verifySignature()) throw new Error('Invalid Signature') + } + return this._senderPubKey + } + + /** + * Determines if the signature is valid + * @return {Boolean} + */ + Transaction.prototype.verifySignature =function() { + const msgHash = this.hash(false) + // All transaction signatures whose s-value is greater than secp256k1n/2 are considered invalid. + if (this._homestead && new BN(this.s).cmp(N_DIV_2) === 1) { + return false + } + + try { + var v = ethUtil.bufferToInt(this.v) + if (this._chainId > 0) { + v -= this._chainId * 2 + 8 + } + this._senderPubKey = ethUtil.ecrecover(msgHash, v, this.r, this.s) + } catch (e) { + return false + } + + return !!this._senderPubKey + } + + /** + * sign a transaction with a given a private key + * @param {Buffer} privateKey + */ + Transaction.prototype.sign =function(privateKey) { + const msgHash = this.hash(false) + const sig = ethUtil.ecsign(msgHash, privateKey) + if (this._chainId > 0) { + sig.v += this._chainId * 2 + 8 + } + Object.assign(this, sig) + } + + /** + * The amount of gas paid for the data in this tx + * @return {BN} + */ + Transaction.prototype.getDataFee=function() { + const data = this.raw[5] + const cost = new BN(0) + for (var i = 0; i < data.length; i++) { + data[i] === 0 ? cost.iaddn(fees.txDataZeroGas.v) : cost.iaddn(fees.txDataNonZeroGas.v) + } + return cost + } + + /** + * the minimum amount of gas the tx must have (DataFee + TxFee + Creation Fee) + * @return {BN} + */ + Transaction.prototype.getBaseFee =function() { + const fee = this.getDataFee().iaddn(fees.txGas.v) + if (this._homestead && this.toCreationAddress()) { + fee.iaddn(fees.txCreation.v) + } + return fee + } + + /** + * the up front amount that an account must have for this transaction to be valid + * @return {BN} + */ + Transaction.prototype.getUpfrontCost =function() { + return new BN(this.gasLimit) + .imul(new BN(this.gasPrice)) + .iadd(new BN(this.value)) + } + + /** + * validates the signature and checks to see if it has enough gas + * @param {Boolean} [stringError=false] whether to return a string with a dscription of why the validation failed or return a Bloolean + * @return {Boolean|String} + */ + Transaction.prototype.validate =function(stringError) { + const errors = [] + if (!this.verifySignature()) { + errors.push('Invalid Signature') + } + + if (this.getBaseFee().cmp(new BN(this.gasLimit)) > 0) { + errors.push([`gas limit is to low. Need at least ${this.getBaseFee()}`]) + } + + if (stringError === undefined || stringError === false) { + return errors.length === 0 + } else { + return errors.join(' ') + } + } + +exports.Transaction=Transaction; diff --git a/tool/utils.js b/tool/utils.js new file mode 100644 index 0000000000..88a77a5bdc --- /dev/null +++ b/tool/utils.js @@ -0,0 +1,267 @@ +const secp256k1 = require('secp256k1') +const createKeccakHash = require('keccak') +const assert = require('assert') +const rlp = require('rlp') +const BN = require('bn.js') + +function privateToPublic(privateKey) { + privateKey = toBuffer(privateKey) + // skip the type flag and use the X, Y points + return secp256k1.publicKeyCreate(privateKey, false).slice(1) +} + +function privateToAddress(privateKey) { + return publicToAddress(privateToPublic(privateKey)) +} + +function publicToAddress(pubKey, sanitize) { + pubKey = toBuffer(pubKey) + if (sanitize && (pubKey.length !== 64)) { + pubKey = secp256k1.publicKeyConvert(pubKey, false).slice(1) + } + assert(pubKey.length === 64) + // Only take the lower 160bits of the hash + return sha3(pubKey).slice(-20) +} + + +function toBuffer(v) { + if (!Buffer.isBuffer(v)) { + if (Array.isArray(v)) { + v = Buffer.from(v) + } else if (typeof v === 'string') { + if (isHexPrefixed(v)) { + v = Buffer.from(padToEven(stripHexPrefix(v)), 'hex') + } else { + v = Buffer.from(v) + } + } else if (typeof v === 'number') { + v = intToBuffer(v) + } else if (v === null || v === undefined) { + v = Buffer.allocUnsafe(0) + } else if (v.toArray) { + // converts a BN to a Buffer + v = Buffer.from(v.toArray()) + } else { + throw new Error('invalid type') + } + } + return v +} + +function isHexPrefixed(str) { + return str.slice(0, 2) === '0x' +} + +function padToEven(a) { + if (a.length % 2) a = '0' + a + return a +} + +function stripHexPrefix(str) { + if (typeof str !== 'string') { + return str + } + return isHexPrefixed(str) ? str.slice(2) : str +} + +function intToBuffer(i) { + var hex = intToHex(i) + return Buffer.from(hex.slice(2), 'hex') +} + +function intToHex(i) { + assert(i % 1 === 0, 'number is not a integer') + assert(i >= 0, 'number must be positive') + var hex = i.toString(16) + if (hex.length % 2) { + hex = '0' + hex + } + return '0x' + hex +} + +function setLength(msg, length, right) { + var buf = zeros(length) + msg = toBuffer(msg) + if (right) { + if (msg.length < length) { + msg.copy(buf) + return buf + } + return msg.slice(0, length) + } else { + if (msg.length < length) { + msg.copy(buf, length - msg.length) + return buf + } + return msg.slice(-length) + } +} + +function sha3(a, bits) { + a = toBuffer(a) + if (!bits) bits = 256 + return createKeccakHash('keccak' + bits).update(a).digest() +} + +function baToJSON(ba) { + if (Buffer.isBuffer(ba)) { + return '0x' + ba.toString('hex') + } else if (ba instanceof Array) { + var array = [] + for (var i = 0; i < ba.length; i++) { + array.push(baToJSON(ba[i])) + } + return array + } +} + +function zeros(bytes) { + return Buffer.allocUnsafe(bytes).fill(0) +} + +function stripZeros(a) { + a = stripHexPrefix(a) + var first = a[0] + while (a.length > 0 && first.toString() === '0') { + a = a.slice(1) + first = a[0] + } + return a +} + +function defineProperties(self, fields, data) { + self.raw = [] + self._fields = [] + + // attach the `toJSON` + self.toJSON = function (label) { + if (label) { + var obj = {} + self._fields.forEach(function (field) { + obj[field] = '0x' + self[field].toString('hex') + }) + return obj + } + return baToJSON(this.raw) + } + + self.serialize = function serialize () { + return rlp.encode(self.raw) + } + + fields.forEach(function (field, i) { + self._fields.push(field.name) + function getter () { + return self.raw[i] + } + function setter (v) { + v = toBuffer(v) + + if (v.toString('hex') === '00' && !field.allowZero) { + v = Buffer.allocUnsafe(0) + } + + if (field.allowLess && field.length) { + v = stripZeros(v) + assert(field.length >= v.length, 'The field ' + field.name + ' must not have more ' + field.length + ' bytes') + } else if (!(field.allowZero && v.length === 0) && field.length) { + assert(field.length === v.length, 'The field ' + field.name + ' must have byte length of ' + field.length) + } + + self.raw[i] = v + } + + Object.defineProperty(self, field.name, { + enumerable: true, + configurable: true, + get: getter, + set: setter + }) + + if (field.default) { + self[field.name] = field.default + } + + // attach alias + if (field.alias) { + Object.defineProperty(self, field.alias, { + enumerable: false, + configurable: true, + set: setter, + get: getter + }) + } + }) + + // if the constuctor is passed data + if (data) { + if (typeof data === 'string') { + data = Buffer.from(stripHexPrefix(data), 'hex') + } + + if (Buffer.isBuffer(data)) { + data = rlp.decode(data) + } + + if (Array.isArray(data)) { + if (data.length > self._fields.length) { + throw (new Error('wrong number of fields in data')) + } + + // make sure all the items are buffers + data.forEach(function (d, i) { + self[self._fields[i]] = toBuffer(d) + }) + } else if (typeof data === 'object') { + const keys = Object.keys(data) + fields.forEach(function (field) { + if (keys.indexOf(field.name) !== -1) self[field.name] = data[field.name] + if (keys.indexOf(field.alias) !== -1) self[field.alias] = data[field.alias] + }) + } else { + throw new Error('invalid data') + } + } +} + +function bufferToInt(buf) { + return new BN(toBuffer(buf)).toNumber() +} + +function rlphash(a) { + return sha3(rlp.encode(a)) +} + +function ecrecover(msgHash, v, r, s) { + var signature = Buffer.concat([setLength(r, 32), setLength(s, 32)], 64) + var recovery = v - 27 + if (recovery !== 0 && recovery !== 1) { + throw new Error('Invalid signature v value') + } + var senderPubKey = secp256k1.recover(msgHash, signature, recovery) + return secp256k1.publicKeyConvert(senderPubKey, false).slice(1) +} + +function ecsign(msgHash, privateKey) { + var sig = secp256k1.sign(msgHash, privateKey) + + var ret = {} + ret.r = sig.signature.slice(0, 32) + ret.s = sig.signature.slice(32, 64) + ret.v = sig.recovery + 27 + return ret +} + +exports.privateToPublic=privateToPublic +exports.privateToAddress=privateToAddress +exports.publicToAddress=publicToAddress +exports.defineProperties=defineProperties +exports.bufferToInt=bufferToInt +exports.rlphash=rlphash +exports.ecrecover=ecrecover +exports.ecsign=ecsign + +exports.BN = BN +exports.rlp = rlp +exports.secp256k1 = secp256k1 \ No newline at end of file diff --git a/tool/web3sync.js b/tool/web3sync.js new file mode 100644 index 0000000000..6c50408619 --- /dev/null +++ b/tool/web3sync.js @@ -0,0 +1,744 @@ +//var Tx = require('./transactionObject.js'); +//const ethUtil = require('./utils.js') + +const secp256k1 = require('secp256k1') +const createKeccakHash = require('keccak') +const assert = require('assert') +const rlp = require('rlp') +const BN = require('bn.js') +const fs=require('fs'); +const execSync =require('child_process').execSync; +const coder = require('./codeUtils'); +var config=require('./config'); + +/* +var addressjson={}; +try{ + addressjson= JSON.parse(fs.readFileSync(config.Ouputpath+'address.json')); + +}catch(e){ + console.log(e); +}*/ + +function privateToPublic(privateKey) { + privateKey = toBuffer(privateKey) + // skip the type flag and use the X, Y points + return secp256k1.publicKeyCreate(privateKey, false).slice(1) +} + +function privateToAddress(privateKey) { + return publicToAddress(privateToPublic(privateKey)) +} + +function publicToAddress(pubKey, sanitize) { + pubKey = toBuffer(pubKey) + if (sanitize && (pubKey.length !== 64)) { + pubKey = secp256k1.publicKeyConvert(pubKey, false).slice(1) + } + assert(pubKey.length === 64) + // Only take the lower 160bits of the hash + return sha3(pubKey).slice(-20) +} + + +function toBuffer(v) { + if (!Buffer.isBuffer(v)) { + if (Array.isArray(v)) { + v = Buffer.from(v) + } else if (typeof v === 'string') { + if (isHexPrefixed(v)) { + v = Buffer.from(padToEven(stripHexPrefix(v)), 'hex') + } else { + v = Buffer.from(v) + } + } else if (typeof v === 'number') { + v = intToBuffer(v) + } else if (v === null || v === undefined) { + v = Buffer.allocUnsafe(0) + } else if (v.toArray) { + // converts a BN to a Buffer + v = Buffer.from(v.toArray()) + } else { + throw new Error('invalid type') + } + } + return v +} + +function isHexPrefixed(str) { + return str.slice(0, 2) === '0x' +} + +function padToEven(a) { + if (a.length % 2) a = '0' + a + return a +} + +function stripHexPrefix(str) { + if (typeof str !== 'string') { + return str + } + return isHexPrefixed(str) ? str.slice(2) : str +} + +function intToBuffer(i) { + var hex = intToHex(i) + return Buffer.from(hex.slice(2), 'hex') +} + +function intToHex(i) { + assert(i % 1 === 0, 'number is not a integer') + assert(i >= 0, 'number must be positive') + var hex = i.toString(16) + if (hex.length % 2) { + hex = '0' + hex + } + return '0x' + hex +} + +function setLength(msg, length, right) { + var buf = zeros(length) + msg = toBuffer(msg) + if (right) { + if (msg.length < length) { + msg.copy(buf) + return buf + } + return msg.slice(0, length) + } else { + if (msg.length < length) { + msg.copy(buf, length - msg.length) + return buf + } + return msg.slice(-length) + } +} + +function sha3(a, bits) { + a = toBuffer(a) + if (!bits) bits = 256 + return createKeccakHash('keccak' + bits).update(a).digest() +} + +function baToJSON(ba) { + if (Buffer.isBuffer(ba)) { + return '0x' + ba.toString('hex') + } else if (ba instanceof Array) { + var array = [] + for (var i = 0; i < ba.length; i++) { + array.push(baToJSON(ba[i])) + } + return array + } +} + +function zeros(bytes) { + return Buffer.allocUnsafe(bytes).fill(0) +} + +function stripZeros(a) { + a = stripHexPrefix(a) + var first = a[0] + while (a.length > 0 && first.toString() === '0') { + a = a.slice(1) + first = a[0] + } + return a +} + +function defineProperties(self, fields, data) { + self.raw = [] + self._fields = [] + + // attach the `toJSON` + self.toJSON = function (label) { + if (label) { + var obj = {} + self._fields.forEach(function (field) { + obj[field] = '0x' + self[field].toString('hex') + }) + return obj + } + return baToJSON(this.raw) + } + + self.serialize = function serialize () { + return rlp.encode(self.raw) + } + + fields.forEach(function (field, i) { + self._fields.push(field.name) + function getter () { + return self.raw[i] + } + function setter (v) { + v = toBuffer(v) + + if (v.toString('hex') === '00' && !field.allowZero) { + v = Buffer.allocUnsafe(0) + } + + if (field.allowLess && field.length) { + v = stripZeros(v) + assert(field.length >= v.length, 'The field ' + field.name + ' must not have more ' + field.length + ' bytes') + } else if (!(field.allowZero && v.length === 0) && field.length) { + assert(field.length === v.length, 'The field ' + field.name + ' must have byte length of ' + field.length) + } + + self.raw[i] = v + } + + Object.defineProperty(self, field.name, { + enumerable: true, + configurable: true, + get: getter, + set: setter + }) + + if (field.default) { + self[field.name] = field.default + } + + // attach alias + if (field.alias) { + Object.defineProperty(self, field.alias, { + enumerable: false, + configurable: true, + set: setter, + get: getter + }) + } + }) + + // if the constuctor is passed data + if (data) { + if (typeof data === 'string') { + data = Buffer.from(stripHexPrefix(data), 'hex') + } + + if (Buffer.isBuffer(data)) { + data = rlp.decode(data) + } + + if (Array.isArray(data)) { + if (data.length > self._fields.length) { + throw (new Error('wrong number of fields in data')) + } + + // make sure all the items are buffers + data.forEach(function (d, i) { + self[self._fields[i]] = toBuffer(d) + }) + } else if (typeof data === 'object') { + const keys = Object.keys(data) + fields.forEach(function (field) { + if (keys.indexOf(field.name) !== -1) self[field.name] = data[field.name] + if (keys.indexOf(field.alias) !== -1) self[field.alias] = data[field.alias] + }) + } else { + throw new Error('invalid data') + } + } +} + +function bufferToInt(buf) { + return new BN(toBuffer(buf)).toNumber() +} + +function rlphash(a) { + return sha3(rlp.encode(a)) +} + +function ecrecover(msgHash, v, r, s) { + var signature = Buffer.concat([setLength(r, 32), setLength(s, 32)], 64) + var recovery = v - 27 + if (recovery !== 0 && recovery !== 1) { + throw new Error('Invalid signature v value') + } + var senderPubKey = secp256k1.recover(msgHash, signature, recovery) + return secp256k1.publicKeyConvert(senderPubKey, false).slice(1) +} + +function ecsign(msgHash, privateKey) { + var sig = secp256k1.sign(msgHash, privateKey) + + var ret = {} + ret.r = sig.signature.slice(0, 32) + ret.s = sig.signature.slice(32, 64) + ret.v = sig.recovery + 27 + return ret +} + +//const BN = ethUtil.BN + +// secp256k1n/2 +const N_DIV_2 = new BN('7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0', 16) + +function Transaction(data) { + data = data || {} + // Define Properties + const fields = [{ + name: 'randomid', + length: 32, + allowLess: true, + default: new Buffer([]) + }, { + name: 'gasPrice', + length: 32, + allowLess: true, + default: new Buffer([]) + }, { + name: 'gasLimit', + alias: 'gas', + length: 32, + allowLess: true, + default: new Buffer([]) + }, { + name: 'blockLimit', + length: 32, + allowLess: true, + default: new Buffer([]) + },{ + name: 'to', + allowZero: true, + length: 20, + default: new Buffer([]) + }, { + name: 'value', + length: 32, + allowLess: true, + default: new Buffer([]) + }, { + name: 'data', + alias: 'input', + allowZero: true, + default: new Buffer([]) + }, { + name: 'v', + length: 1, + default: new Buffer([0x1c]) + }, { + name: 'r', + length: 32, + allowLess: true, + default: new Buffer([]) + }, { + name: 's', + length: 32, + allowLess: true, + default: new Buffer([]) + }] + + /** + * Returns the rlp encoding of the transaction + * @method serialize + * @return {Buffer} + */ + // attached serialize + defineProperties(this, fields, data) + + /** + * @prop {Buffer} from (read only) sender address of this transaction, mathematically derived from other parameters. + */ + Object.defineProperty(this, 'from', { + enumerable: true, + configurable: true, + get: this.getSenderAddress.bind(this) + }) + + // calculate chainId from signature + var sigV = bufferToInt(this.v) + var chainId = Math.floor((sigV - 35) / 2) + if (chainId < 0) chainId = 0 + + // set chainId + this._chainId = chainId || data.chainId || 0 + this._homestead = true + } + + /** + * If the tx's `to` is to the creation address + * @return {Boolean} + */ + Transaction.prototype.toCreationAddress=function () { + return this.to.toString('hex') === '' + } + + /** + * Computes a sha3-256 hash of the serialized tx + * @param {Boolean} [includeSignature=true] whether or not to inculde the signature + * @return {Buffer} + */ + Transaction.prototype.hash=function (includeSignature) { + if (includeSignature === undefined) includeSignature = true + // backup original signature + const rawCopy = this.raw.slice(0) + + // modify raw for signature generation only + if (this._chainId > 0) { + includeSignature = true + this.v = this._chainId + this.r = 0 + this.s = 0 + } + + // generate rlp params for hash + //console.log(this.raw.length) + var txRawForHash = includeSignature ? this.raw : this.raw.slice(0, this.raw.length - 3) + //var txRawForHash = includeSignature ? this.raw : this.raw.slice(0, 7) + + // restore original signature + this.raw = rawCopy.slice() + + // create hash + return rlphash(txRawForHash) + } + + /** + * returns the public key of the sender + * @return {Buffer} + */ + Transaction.prototype.getChainId=function() { + return this._chainId + } + + /** + * returns the sender's address + * @return {Buffer} + */ + Transaction.prototype.getSenderAddress = function() { + if (this._from) { + return this._from + } + const pubkey = this.getSenderPublicKey() + this._from = publicToAddress(pubkey) + return this._from + } + + /** + * returns the public key of the sender + * @return {Buffer} + */ + Transaction.prototype.getSenderPublicKey =function() { + if (!this._senderPubKey || !this._senderPubKey.length) { + if (!this.verifySignature()) throw new Error('Invalid Signature') + } + return this._senderPubKey + } + + /** + * Determines if the signature is valid + * @return {Boolean} + */ + Transaction.prototype.verifySignature =function() { + const msgHash = this.hash(false) + // All transaction signatures whose s-value is greater than secp256k1n/2 are considered invalid. + if (this._homestead && new BN(this.s).cmp(N_DIV_2) === 1) { + return false + } + + try { + var v = bufferToInt(this.v) + if (this._chainId > 0) { + v -= this._chainId * 2 + 8 + } + this._senderPubKey = ecrecover(msgHash, v, this.r, this.s) + } catch (e) { + return false + } + + return !!this._senderPubKey + } + + /** + * sign a transaction with a given a private key + * @param {Buffer} privateKey + */ + Transaction.prototype.sign =function(privateKey) { + const msgHash = this.hash(false) + const sig = ecsign(msgHash, privateKey) + if (this._chainId > 0) { + sig.v += this._chainId * 2 + 8 + } + Object.assign(this, sig) + } + + /** + * The amount of gas paid for the data in this tx + * @return {BN} + */ + Transaction.prototype.getDataFee=function() { + const data = this.raw[5] + const cost = new BN(0) + for (var i = 0; i < data.length; i++) { + data[i] === 0 ? cost.iaddn(fees.txDataZeroGas.v) : cost.iaddn(fees.txDataNonZeroGas.v) + } + return cost + } + + /** + * the minimum amount of gas the tx must have (DataFee + TxFee + Creation Fee) + * @return {BN} + */ + Transaction.prototype.getBaseFee =function() { + const fee = this.getDataFee().iaddn(fees.txGas.v) + if (this._homestead && this.toCreationAddress()) { + fee.iaddn(fees.txCreation.v) + } + return fee + } + + /** + * the up front amount that an account must have for this transaction to be valid + * @return {BN} + */ + Transaction.prototype.getUpfrontCost =function() { + return new BN(this.gasLimit) + .imul(new BN(this.gasPrice)) + .iadd(new BN(this.value)) + } + + /** + * validates the signature and checks to see if it has enough gas + * @param {Boolean} [stringError=false] whether to return a string with a dscription of why the validation failed or return a Bloolean + * @return {Boolean|String} + */ + Transaction.prototype.validate =function(stringError) { + const errors = [] + if (!this.verifySignature()) { + errors.push('Invalid Signature') + } + + if (this.getBaseFee().cmp(new BN(this.gasLimit)) > 0) { + errors.push([`gas limit is to low. Need at least ${this.getBaseFee()}`]) + } + + if (stringError === undefined || stringError === false) { + return errors.length === 0 + } else { + return errors.join(' ') + } + } + +//exports.Transaction=Transaction; + +function signTransaction(tx_data,privKey,callback) +{ + // convert string private key to a Buffer Object + var privateKey = new Buffer(privKey, 'hex'); + var tx = new Transaction(tx_data); + tx.sign(privateKey); + // Build a serialized hex version of the Tx + var serializedTx = '0x' + tx.serialize().toString('hex'); + if( null !== callback) + { + callback(serializedTx); + return ; + } + else + { + return serializedTx; + } +} + +//exports.signTransaction=signTransaction; + +/* +async function deploy(args,account, filename) { + try{ + execSync("solc --abi --bin -o " + config.Ouputpath + " " + filename + ".sol" + " &>/dev/null"); + + //console.log('编译成功!'); + } catch(e){ + console.log('编译失败!' + e); + } + + var abi=JSON.parse(fs.readFileSync(config.Ouputpath+filename+".sol:"+filename+'.abi', 'utf-8')); + var binary=fs.readFileSync(config.Ouputpath+filename+'.bin', 'utf-8'); + + var contract = web3.eth.contract(abi); + + var initializer = {from: account, data: binary}; + initializer.randomid=Math.ceil(Math.random()*100000000); + + return new Promise((resolve, reject) => { + var callback = function(e, contract){ + if(!e) { + if(!contract.address) { + //console.log("Contract transaction send: TransactionHash: " + contract.transactionHash + " waiting to be mined..."); + } else { + + + console.log(filename+"合约地址 "+contract.address); + + addressjson[filename]= contract.address; + fs.writeFileSync(config.Ouputpath+'address.json', JSON.stringify(addressjson), 'utf-8'); + var deployfilename=filename+'.deploy.js'; + fs.writeFileSync(config.Ouputpath+filename+'.deploy', JSON.stringify({"address":contract.address,"abi":contract.abi}), 'utf-8'); + + var now2=new Date(); + var endtime=now2.getTime(); + + resolve(contract); + } + } + else + { + console.log("Has Error"+e); + } + }; + + var now=new Date(); + var starttime=now.getTime(); + + //部署到网络 + var newcontract=contract.new; + //部署到网络 + //var token = contract.new(args,initializer, callback); + args.push(initializer); + args.push(callback); + var token = newcontract.apply(contract,args); + + }); +}*/ + +async function getBlockNumber() { + + return new Promise((resolve, reject) => { + web3.eth.getBlockNumber(function(e,d){ + //console.log(e+',blocknumber='+d); + resolve(d); + }); + }); +} + +function checkForTransactionResult(hash, callback){ + var count = 0, + callbackFired = false; + + // wait for receipt + //var filter = contract._eth.filter('latest', function(e){ + var filter = web3.eth.filter('latest', function(e){ + if (!e && !callbackFired) { + count++; + + // stop watching after 50 blocks (timeout) + if (count > 50) { + filter.stopWatching(function() {}); + callbackFired = true; + + if (callback) { + callback(new Error('Contract transaction couldn\'t be found after 50 blocks')); + } else { + throw new Error('Contract transaction couldn\'t be found after 50 blocks'); + } + } else { + web3.eth.getTransactionReceipt(hash, function(e, receipt){ + if(receipt && !callbackFired) { + //console.log(receipt); + callback(null, receipt); + filter.stopWatching(function() {}); + } + }); + } + } + }); +}; + +async function unlockAccount(account, password) { + return new Promise((resolve, reject) => { + web3.personal.unlockAccount(account,"123",1,function(err,data){ + resolve(data); + }) + }); +} +async function rawDeploy(account, privateKey,filename) { + + var binary=fs.readFileSync(config.Ouputpath+"./"+filename+".bin",'utf-8'); + + var postdata = { + input: "0x"+binary, + from: account, + to: null, + gas: 100000000, + randomid:Math.ceil(Math.random()*100000000), + blockLimit:await getBlockNumber() + 1000, + } + + var signTX = signTransaction(postdata, privateKey, null); + + return new Promise((resolve, reject) => { + web3.eth.sendRawTransaction(signTX, function(err, address) { + if (!err) { + //console.log("发送交易成功: " + address); + + checkForTransactionResult(address, (err, receipt) => { + var addressjson={}; + if( receipt.contractAddress ){ + + + console.log(filename+"合约地址 "+receipt.contractAddress); + fs.writeFileSync(config.Ouputpath+filename+'.address', receipt.contractAddress, 'utf-8'); + + }//if + + + resolve(receipt); + return; + }); + + return; + } + else { + console.log("发送交易失败!",err); + + return; + } + }); + }); +} + + + +async function sendRawTransaction(account, privateKey, to, func, params) { + var r = /^\w+\((.+)\)$/g.exec(func); + var types = r[1].split(','); + + var tx_data = coder.codeTxData(func,types,params); + + var postdata = { + data: tx_data, + from: account, + to: to, + gas: 1000000, + randomid:Math.ceil(Math.random()*100000000), + blockLimit:await getBlockNumber() + 1000, + } + + var signTX = signTransaction(postdata, privateKey, null); + + return new Promise((resolve, reject) => { + web3.eth.sendRawTransaction(signTX, function(err, address) { + if (!err) { + //console.log("发送交易成功: " + address); + + checkForTransactionResult(address, (err, receipt) => { + resolve(receipt); + }); + + //resolve(address); + } + else { + console.log("发送交易失败!",err); + + return; + } + }); + }); +} + +exports.getBlockNumber=getBlockNumber; +exports.sendRawTransaction=sendRawTransaction; +exports.unlockAccount=unlockAccount; +exports.rawDeploy=rawDeploy; +//exports.deploy=deploy; diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt new file mode 100644 index 0000000000..5b8f289a01 --- /dev/null +++ b/utils/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(libscrypt) diff --git a/utils/json_spirit/CMakeLists.txt b/utils/json_spirit/CMakeLists.txt new file mode 100644 index 0000000000..19cfcf2ceb --- /dev/null +++ b/utils/json_spirit/CMakeLists.txt @@ -0,0 +1,10 @@ +SET(JSON_SPIRIT_SRCS +json_spirit_reader.cpp +json_spirit_value.cpp +json_spirit_writer.cpp) + +FIND_PACKAGE(Boost 1.34 REQUIRED) +INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIR}) + +ADD_LIBRARY(json_spirit STATIC ${JSON_SPIRIT_SRCS}) + diff --git a/utils/json_spirit/JsonSpiritHeaders.h b/utils/json_spirit/JsonSpiritHeaders.h new file mode 100644 index 0000000000..fc7c9daa84 --- /dev/null +++ b/utils/json_spirit/JsonSpiritHeaders.h @@ -0,0 +1,32 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file JsonSpiritHeaders.h + * @author Tim Hughes + * @date 2014 + */ +#pragma once + +#pragma warning(push) +#pragma warning(disable: 4100) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#pragma GCC diagnostic ignored "-Wunused-parameter" +#include "../json_spirit/json_spirit_reader_template.h" +#include "../json_spirit/json_spirit_writer_template.h" +#pragma GCC diagnostic pop +#pragma warning(pop) + diff --git a/utils/json_spirit/json_spirit.h b/utils/json_spirit/json_spirit.h new file mode 100644 index 0000000000..7dac05c360 --- /dev/null +++ b/utils/json_spirit/json_spirit.h @@ -0,0 +1,18 @@ +#ifndef JSON_SPIRIT +#define JSON_SPIRIT + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include "json_spirit_value.h" +#include "json_spirit_reader.h" +#include "json_spirit_writer.h" +#include "json_spirit_utils.h" + +#endif diff --git a/utils/json_spirit/json_spirit.vcproj b/utils/json_spirit/json_spirit.vcproj new file mode 100644 index 0000000000..ed0e5e0c63 --- /dev/null +++ b/utils/json_spirit/json_spirit.vcproj @@ -0,0 +1,209 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/utils/json_spirit/json_spirit_error_position.h b/utils/json_spirit/json_spirit_error_position.h new file mode 100644 index 0000000000..4a535ff517 --- /dev/null +++ b/utils/json_spirit/json_spirit_error_position.h @@ -0,0 +1,54 @@ +#ifndef JSON_SPIRIT_ERROR_POSITION +#define JSON_SPIRIT_ERROR_POSITION + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include + +namespace json_spirit +{ + // An Error_position exception is thrown by the "read_or_throw" functions below on finding an error. + // Note the "read_or_throw" functions are around 3 times slower than the standard functions "read" + // functions that return a bool. + // + struct Error_position + { + Error_position(); + Error_position( unsigned int line, unsigned int column, const std::string& reason ); + bool operator==( const Error_position& lhs ) const; + unsigned int line_; + unsigned int column_; + std::string reason_; + }; + + inline Error_position::Error_position() + : line_( 0 ) + , column_( 0 ) + { + } + + inline Error_position::Error_position( unsigned int line, unsigned int column, const std::string& reason ) + : line_( line ) + , column_( column ) + , reason_( reason ) + { + } + + inline bool Error_position::operator==( const Error_position& lhs ) const + { + if( this == &lhs ) return true; + + return ( reason_ == lhs.reason_ ) && + ( line_ == lhs.line_ ) && + ( column_ == lhs.column_ ); +} +} + +#endif diff --git a/utils/json_spirit/json_spirit_reader.cpp b/utils/json_spirit/json_spirit_reader.cpp new file mode 100644 index 0000000000..8e2fb5e2ab --- /dev/null +++ b/utils/json_spirit/json_spirit_reader.cpp @@ -0,0 +1,137 @@ +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#include "json_spirit_reader.h" +#include "json_spirit_reader_template.h" + +using namespace json_spirit; + +bool json_spirit::read( const std::string& s, Value& value ) +{ + return read_string( s, value ); +} + +void json_spirit::read_or_throw( const std::string& s, Value& value ) +{ + read_string_or_throw( s, value ); +} + +bool json_spirit::read( std::istream& is, Value& value ) +{ + return read_stream( is, value ); +} + +void json_spirit::read_or_throw( std::istream& is, Value& value ) +{ + read_stream_or_throw( is, value ); +} + +bool json_spirit::read( std::string::const_iterator& begin, std::string::const_iterator end, Value& value ) +{ + return read_range( begin, end, value ); +} + +void json_spirit::read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, Value& value ) +{ + begin = read_range_or_throw( begin, end, value ); +} + +#ifndef BOOST_NO_STD_WSTRING + +bool json_spirit::read( const std::wstring& s, wValue& value ) +{ + return read_string( s, value ); +} + +void json_spirit::read_or_throw( const std::wstring& s, wValue& value ) +{ + read_string_or_throw( s, value ); +} + +bool json_spirit::read( std::wistream& is, wValue& value ) +{ + return read_stream( is, value ); +} + +void json_spirit::read_or_throw( std::wistream& is, wValue& value ) +{ + read_stream_or_throw( is, value ); +} + +bool json_spirit::read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value ) +{ + return read_range( begin, end, value ); +} + +void json_spirit::read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value ) +{ + begin = read_range_or_throw( begin, end, value ); +} + +#endif + +bool json_spirit::read( const std::string& s, mValue& value ) +{ + return read_string( s, value ); +} + +void json_spirit::read_or_throw( const std::string& s, mValue& value ) +{ + read_string_or_throw( s, value ); +} + +bool json_spirit::read( std::istream& is, mValue& value ) +{ + return read_stream( is, value ); +} + +void json_spirit::read_or_throw( std::istream& is, mValue& value ) +{ + read_stream_or_throw( is, value ); +} + +bool json_spirit::read( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value ) +{ + return read_range( begin, end, value ); +} + +void json_spirit::read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value ) +{ + begin = read_range_or_throw( begin, end, value ); +} + +#ifndef BOOST_NO_STD_WSTRING + +bool json_spirit::read( const std::wstring& s, wmValue& value ) +{ + return read_string( s, value ); +} + +void json_spirit::read_or_throw( const std::wstring& s, wmValue& value ) +{ + read_string_or_throw( s, value ); +} + +bool json_spirit::read( std::wistream& is, wmValue& value ) +{ + return read_stream( is, value ); +} + +void json_spirit::read_or_throw( std::wistream& is, wmValue& value ) +{ + read_stream_or_throw( is, value ); +} + +bool json_spirit::read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value ) +{ + return read_range( begin, end, value ); +} + +void json_spirit::read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value ) +{ + begin = read_range_or_throw( begin, end, value ); +} + +#endif diff --git a/utils/json_spirit/json_spirit_reader.h b/utils/json_spirit/json_spirit_reader.h new file mode 100644 index 0000000000..a58bfc10fe --- /dev/null +++ b/utils/json_spirit/json_spirit_reader.h @@ -0,0 +1,62 @@ +#ifndef JSON_SPIRIT_READER +#define JSON_SPIRIT_READER + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include "json_spirit_value.h" +#include "json_spirit_error_position.h" +#include + +namespace json_spirit +{ + // functions to reads a JSON values + + bool read( const std::string& s, Value& value ); + bool read( std::istream& is, Value& value ); + bool read( std::string::const_iterator& begin, std::string::const_iterator end, Value& value ); + + void read_or_throw( const std::string& s, Value& value ); + void read_or_throw( std::istream& is, Value& value ); + void read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, Value& value ); + +#ifndef BOOST_NO_STD_WSTRING + + bool read( const std::wstring& s, wValue& value ); + bool read( std::wistream& is, wValue& value ); + bool read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value ); + + void read_or_throw( const std::wstring& s, wValue& value ); + void read_or_throw( std::wistream& is, wValue& value ); + void read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value ); + +#endif + + bool read( const std::string& s, mValue& value ); + bool read( std::istream& is, mValue& value ); + bool read( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value ); + + void read_or_throw( const std::string& s, mValue& value ); + void read_or_throw( std::istream& is, mValue& value ); + void read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value ); + +#ifndef BOOST_NO_STD_WSTRING + + bool read( const std::wstring& s, wmValue& value ); + bool read( std::wistream& is, wmValue& value ); + bool read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value ); + + void read_or_throw( const std::wstring& s, wmValue& value ); + void read_or_throw( std::wistream& is, wmValue& value ); + void read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value ); + +#endif +} + +#endif diff --git a/utils/json_spirit/json_spirit_reader_template.h b/utils/json_spirit/json_spirit_reader_template.h new file mode 100644 index 0000000000..81cded4346 --- /dev/null +++ b/utils/json_spirit/json_spirit_reader_template.h @@ -0,0 +1,612 @@ +#ifndef JSON_SPIRIT_READER_TEMPLATE +#define JSON_SPIRIT_READER_TEMPLATE + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#include "json_spirit_value.h" +#include "json_spirit_error_position.h" + +//#define BOOST_SPIRIT_THREADSAFE // uncomment for multithreaded use, requires linking to boost.thread + +#include +#include +#include + +#if BOOST_VERSION >= 103800 + #include + #include + #include + #include + #include + #define spirit_namespace boost::spirit::classic +#else + #include + #include + #include + #include + #include + #define spirit_namespace boost::spirit +#endif + +namespace json_spirit +{ + const spirit_namespace::int_parser < boost::int64_t > int64_p = spirit_namespace::int_parser < boost::int64_t >(); + const spirit_namespace::uint_parser< boost::uint64_t > uint64_p = spirit_namespace::uint_parser< boost::uint64_t >(); + + template< class Iter_type > + bool is_eq( Iter_type first, Iter_type last, const char* c_str ) + { + for( Iter_type i = first; i != last; ++i, ++c_str ) + { + if( *c_str == 0 ) return false; + + if( *i != *c_str ) return false; + } + + return true; + } + + template< class Char_type > + Char_type hex_to_num( const Char_type c ) + { + if( ( c >= '0' ) && ( c <= '9' ) ) return c - '0'; + if( ( c >= 'a' ) && ( c <= 'f' ) ) return c - 'a' + 10; + if( ( c >= 'A' ) && ( c <= 'F' ) ) return c - 'A' + 10; + return 0; + } + + template< class Char_type, class Iter_type > + Char_type hex_str_to_char( Iter_type& begin ) + { + const Char_type c1( *( ++begin ) ); + const Char_type c2( *( ++begin ) ); + + return ( hex_to_num( c1 ) << 4 ) + hex_to_num( c2 ); + } + + template< class Char_type, class Iter_type > + Char_type unicode_str_to_char( Iter_type& begin ) + { + const Char_type c1( *( ++begin ) ); + const Char_type c2( *( ++begin ) ); + const Char_type c3( *( ++begin ) ); + const Char_type c4( *( ++begin ) ); + + return ( hex_to_num( c1 ) << 12 ) + + ( hex_to_num( c2 ) << 8 ) + + ( hex_to_num( c3 ) << 4 ) + + hex_to_num( c4 ); + } + + template< class String_type > + void append_esc_char_and_incr_iter( String_type& s, + typename String_type::const_iterator& begin, + typename String_type::const_iterator end ) + { + typedef typename String_type::value_type Char_type; + + const Char_type c2( *begin ); + + switch( c2 ) + { + case 't': s += '\t'; break; + case 'b': s += '\b'; break; + case 'f': s += '\f'; break; + case 'n': s += '\n'; break; + case 'r': s += '\r'; break; + case '\\': s += '\\'; break; + case '/': s += '/'; break; + case '"': s += '"'; break; + case 'x': + { + if( end - begin >= 3 ) // expecting "xHH..." + { + s += hex_str_to_char< Char_type >( begin ); + } + break; + } + case 'u': + { + if( end - begin >= 5 ) // expecting "uHHHH..." + { + s += unicode_str_to_char< Char_type >( begin ); + } + break; + } + } + } + + template< class String_type > + String_type substitute_esc_chars( typename String_type::const_iterator begin, + typename String_type::const_iterator end ) + { + typedef typename String_type::const_iterator Iter_type; + + if( end - begin < 2 ) return String_type( begin, end ); + + String_type result; + + result.reserve( end - begin ); + + const Iter_type end_minus_1( end - 1 ); + + Iter_type substr_start = begin; + Iter_type i = begin; + + for( ; i < end_minus_1; ++i ) + { + if( *i == '\\' ) + { + result.append( substr_start, i ); + + ++i; // skip the '\' + + append_esc_char_and_incr_iter( result, i, end ); + + substr_start = i + 1; + } + } + + result.append( substr_start, end ); + + return result; + } + + template< class String_type > + String_type get_str_( typename String_type::const_iterator begin, + typename String_type::const_iterator end ) + { + assert( end - begin >= 2 ); + + typedef typename String_type::const_iterator Iter_type; + + Iter_type str_without_quotes( ++begin ); + Iter_type end_without_quotes( --end ); + + return substitute_esc_chars< String_type >( str_without_quotes, end_without_quotes ); + } + + inline std::string get_str( std::string::const_iterator begin, std::string::const_iterator end ) + { + return get_str_< std::string >( begin, end ); + } + + inline std::wstring get_str( std::wstring::const_iterator begin, std::wstring::const_iterator end ) + { + return get_str_< std::wstring >( begin, end ); + } + + template< class String_type, class Iter_type > + String_type get_str( Iter_type begin, Iter_type end ) + { + const String_type tmp( begin, end ); // convert multipass iterators to string iterators + + return get_str( tmp.begin(), tmp.end() ); + } + + // this class's methods get called by the spirit parse resulting + // in the creation of a JSON object or array + // + // NB Iter_type could be a std::string iterator, wstring iterator, a position iterator or a multipass iterator + // + template< class Value_type, class Iter_type > + class Semantic_actions + { + public: + + typedef typename Value_type::Config_type Config_type; + typedef typename Config_type::String_type String_type; + typedef typename Config_type::Object_type Object_type; + typedef typename Config_type::Array_type Array_type; + typedef typename String_type::value_type Char_type; + + Semantic_actions( Value_type& value ) + : value_( value ) + , current_p_( 0 ) + { + } + + void begin_obj( Char_type c ) + { + assert( c == '{' ); + + begin_compound< Object_type >(); + } + + void end_obj( Char_type c ) + { + assert( c == '}' ); + + end_compound(); + } + + void begin_array( Char_type c ) + { + assert( c == '[' ); + + begin_compound< Array_type >(); + } + + void end_array( Char_type c ) + { + assert( c == ']' ); + + end_compound(); + } + + void new_name( Iter_type begin, Iter_type end ) + { + assert( current_p_->type() == obj_type ); + + name_ = get_str< String_type >( begin, end ); + } + + void new_str( Iter_type begin, Iter_type end ) + { + add_to_current( get_str< String_type >( begin, end ) ); + } + + void new_true( Iter_type begin, Iter_type end ) + { + assert( is_eq( begin, end, "true" ) ); + + add_to_current( true ); + } + + void new_false( Iter_type begin, Iter_type end ) + { + assert( is_eq( begin, end, "false" ) ); + + add_to_current( false ); + } + + void new_null( Iter_type begin, Iter_type end ) + { + assert( is_eq( begin, end, "null" ) ); + + add_to_current( Value_type() ); + } + + void new_int( boost::int64_t i ) + { + add_to_current( i ); + } + + void new_uint64( boost::uint64_t ui ) + { + add_to_current( ui ); + } + + void new_real( double d ) + { + add_to_current( d ); + } + + private: + + Semantic_actions& operator=( const Semantic_actions& ); + // to prevent "assignment operator could not be generated" warning + + Value_type* add_first( const Value_type& value ) + { + assert( current_p_ == 0 ); + + value_ = value; + current_p_ = &value_; + return current_p_; + } + + template< class Array_or_obj > + void begin_compound() + { + if( current_p_ == 0 ) + { + add_first( Array_or_obj() ); + } + else + { + stack_.push_back( current_p_ ); + + Array_or_obj new_array_or_obj; // avoid copy by building new array or object in place + + current_p_ = add_to_current( new_array_or_obj ); + } + } + + void end_compound() + { + if( current_p_ != &value_ ) + { + current_p_ = stack_.back(); + + stack_.pop_back(); + } + } + + Value_type* add_to_current( const Value_type& value ) + { + if( current_p_ == 0 ) + { + return add_first( value ); + } + else if( current_p_->type() == array_type ) + { + current_p_->get_array().push_back( value ); + + return ¤t_p_->get_array().back(); + } + + assert( current_p_->type() == obj_type ); + + return &Config_type::add( current_p_->get_obj(), name_, value ); + } + + Value_type& value_; // this is the object or array that is being created + Value_type* current_p_; // the child object or array that is currently being constructed + + std::vector< Value_type* > stack_; // previous child objects and arrays + + String_type name_; // of current name/value pair + }; + + template< typename Iter_type > + void throw_error( spirit_namespace::position_iterator< Iter_type > i, const std::string& reason ) + { + throw Error_position( i.get_position().line, i.get_position().column, reason ); + } + + template< typename Iter_type > + void throw_error( Iter_type i, const std::string& reason ) + { + throw reason; + } + + // the spirit grammer + // + template< class Value_type, class Iter_type > + class Json_grammer : public spirit_namespace::grammar< Json_grammer< Value_type, Iter_type > > + { + public: + + typedef Semantic_actions< Value_type, Iter_type > Semantic_actions_t; + + Json_grammer( Semantic_actions_t& semantic_actions ) + : actions_( semantic_actions ) + { + } + + static void throw_not_value( Iter_type begin, Iter_type end ) + { + throw_error( begin, "not a value" ); + } + + static void throw_not_array( Iter_type begin, Iter_type end ) + { + throw_error( begin, "not an array" ); + } + + static void throw_not_object( Iter_type begin, Iter_type end ) + { + throw_error( begin, "not an object" ); + } + + static void throw_not_pair( Iter_type begin, Iter_type end ) + { + throw_error( begin, "not a pair" ); + } + + static void throw_not_colon( Iter_type begin, Iter_type end ) + { + throw_error( begin, "no colon in pair" ); + } + + static void throw_not_string( Iter_type begin, Iter_type end ) + { + throw_error( begin, "not a string" ); + } + + template< typename ScannerT > + class definition + { + public: + + definition( const Json_grammer& self ) + { + using namespace spirit_namespace; + + typedef typename Value_type::String_type::value_type Char_type; + + // first we convert the semantic action class methods to functors with the + // parameter signature expected by spirit + + typedef boost::function< void( Char_type ) > Char_action; + typedef boost::function< void( Iter_type, Iter_type ) > Str_action; + typedef boost::function< void( double ) > Real_action; + typedef boost::function< void( boost::int64_t ) > Int_action; + typedef boost::function< void( boost::uint64_t ) > Uint64_action; + + Char_action begin_obj ( boost::bind( &Semantic_actions_t::begin_obj, &self.actions_, _1 ) ); + Char_action end_obj ( boost::bind( &Semantic_actions_t::end_obj, &self.actions_, _1 ) ); + Char_action begin_array( boost::bind( &Semantic_actions_t::begin_array, &self.actions_, _1 ) ); + Char_action end_array ( boost::bind( &Semantic_actions_t::end_array, &self.actions_, _1 ) ); + Str_action new_name ( boost::bind( &Semantic_actions_t::new_name, &self.actions_, _1, _2 ) ); + Str_action new_str ( boost::bind( &Semantic_actions_t::new_str, &self.actions_, _1, _2 ) ); + Str_action new_true ( boost::bind( &Semantic_actions_t::new_true, &self.actions_, _1, _2 ) ); + Str_action new_false ( boost::bind( &Semantic_actions_t::new_false, &self.actions_, _1, _2 ) ); + Str_action new_null ( boost::bind( &Semantic_actions_t::new_null, &self.actions_, _1, _2 ) ); + Real_action new_real ( boost::bind( &Semantic_actions_t::new_real, &self.actions_, _1 ) ); + Int_action new_int ( boost::bind( &Semantic_actions_t::new_int, &self.actions_, _1 ) ); + Uint64_action new_uint64 ( boost::bind( &Semantic_actions_t::new_uint64, &self.actions_, _1 ) ); + + // actual grammer + + json_ + = value_ | eps_p[ &throw_not_value ] + ; + + value_ + = string_[ new_str ] + | number_ + | object_ + | array_ + | str_p( "true" ) [ new_true ] + | str_p( "false" )[ new_false ] + | str_p( "null" ) [ new_null ] + ; + + object_ + = ch_p('{')[ begin_obj ] + >> !members_ + >> ( ch_p('}')[ end_obj ] | eps_p[ &throw_not_object ] ) + ; + + members_ + = pair_ >> *( ',' >> pair_ ) + ; + + pair_ + = string_[ new_name ] + >> ( ':' | eps_p[ &throw_not_colon ] ) + >> ( value_ | eps_p[ &throw_not_value ] ) + ; + + array_ + = ch_p('[')[ begin_array ] + >> !elements_ + >> ( ch_p(']')[ end_array ] | eps_p[ &throw_not_array ] ) + ; + + elements_ + = value_ >> *( ',' >> value_ ) + ; + + string_ + = lexeme_d // this causes white space inside a string to be retained + [ + confix_p + ( + '"', + *lex_escape_ch_p, + '"' + ) + ] + ; + + number_ + = strict_real_p[ new_real ] + | int64_p [ new_int ] + | uint64_p [ new_uint64 ] + ; + } + + spirit_namespace::rule< ScannerT > json_, object_, members_, pair_, array_, elements_, value_, string_, number_; + + const spirit_namespace::rule< ScannerT >& start() const { return json_; } + }; + + private: + + Json_grammer& operator=( const Json_grammer& ); // to prevent "assignment operator could not be generated" warning + + Semantic_actions_t& actions_; + }; + + template< class Iter_type, class Value_type > + Iter_type read_range_or_throw( Iter_type begin, Iter_type end, Value_type& value ) + { + Semantic_actions< Value_type, Iter_type > semantic_actions( value ); + + const spirit_namespace::parse_info< Iter_type > info = + spirit_namespace::parse( begin, end, + Json_grammer< Value_type, Iter_type >( semantic_actions ), + spirit_namespace::space_p ); + + if( !info.hit ) + { + assert( false ); // in theory exception should already have been thrown + throw_error( info.stop, "error" ); + } + + return info.stop; + } + + template< class Iter_type, class Value_type > + void add_posn_iter_and_read_range_or_throw( Iter_type begin, Iter_type end, Value_type& value ) + { + typedef spirit_namespace::position_iterator< Iter_type > Posn_iter_t; + + const Posn_iter_t posn_begin( begin, end ); + const Posn_iter_t posn_end( end, end ); + + read_range_or_throw( posn_begin, posn_end, value ); + } + + template< class Iter_type, class Value_type > + bool read_range( Iter_type& begin, Iter_type end, Value_type& value ) + { + try + { + begin = read_range_or_throw( begin, end, value ); + + return true; + } + catch( ... ) + { + return false; + } + } + + template< class String_type, class Value_type > + void read_string_or_throw( const String_type& s, Value_type& value ) + { + add_posn_iter_and_read_range_or_throw( s.begin(), s.end(), value ); + } + + template< class String_type, class Value_type > + bool read_string( const String_type& s, Value_type& value ) + { + typename String_type::const_iterator begin = s.begin(); + + return read_range( begin, s.end(), value ); + } + + template< class Istream_type > + struct Multi_pass_iters + { + typedef typename Istream_type::char_type Char_type; + typedef std::istream_iterator< Char_type, Char_type > istream_iter; + typedef spirit_namespace::multi_pass< istream_iter > Mp_iter; + + Multi_pass_iters( Istream_type& is ) + { + is.unsetf( std::ios::skipws ); + + begin_ = spirit_namespace::make_multi_pass( istream_iter( is ) ); + end_ = spirit_namespace::make_multi_pass( istream_iter() ); + } + + Mp_iter begin_; + Mp_iter end_; + }; + + template< class Istream_type, class Value_type > + bool read_stream( Istream_type& is, Value_type& value ) + { + Multi_pass_iters< Istream_type > mp_iters( is ); + + return read_range( mp_iters.begin_, mp_iters.end_, value ); + } + + template< class Istream_type, class Value_type > + void read_stream_or_throw( Istream_type& is, Value_type& value ) + { + const Multi_pass_iters< Istream_type > mp_iters( is ); + + add_posn_iter_and_read_range_or_throw( mp_iters.begin_, mp_iters.end_, value ); + } +} + +#endif diff --git a/utils/json_spirit/json_spirit_stream_reader.h b/utils/json_spirit/json_spirit_stream_reader.h new file mode 100644 index 0000000000..a9ceeacf00 --- /dev/null +++ b/utils/json_spirit/json_spirit_stream_reader.h @@ -0,0 +1,70 @@ +#ifndef JSON_SPIRIT_READ_STREAM +#define JSON_SPIRIT_READ_STREAM + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include "json_spirit_reader_template.h" + +namespace json_spirit +{ + // these classes allows you to read multiple top level contiguous values from a stream, + // the normal stream read functions have a bug that prevent multiple top level values + // from being read unless they are separated by spaces + + template< class Istream_type, class Value_type > + class Stream_reader + { + public: + + Stream_reader( Istream_type& is ) + : iters_( is ) + { + } + + bool read_next( Value_type& value ) + { + return read_range( iters_.begin_, iters_.end_, value ); + } + + private: + + typedef Multi_pass_iters< Istream_type > Mp_iters; + + Mp_iters iters_; + }; + + template< class Istream_type, class Value_type > + class Stream_reader_thrower + { + public: + + Stream_reader_thrower( Istream_type& is ) + : iters_( is ) + , posn_begin_( iters_.begin_, iters_.end_ ) + , posn_end_( iters_.end_, iters_.end_ ) + { + } + + void read_next( Value_type& value ) + { + posn_begin_ = read_range_or_throw( posn_begin_, posn_end_, value ); + } + + private: + + typedef Multi_pass_iters< Istream_type > Mp_iters; + typedef spirit_namespace::position_iterator< typename Mp_iters::Mp_iter > Posn_iter_t; + + Mp_iters iters_; + Posn_iter_t posn_begin_, posn_end_; + }; +} + +#endif diff --git a/utils/json_spirit/json_spirit_utils.h b/utils/json_spirit/json_spirit_utils.h new file mode 100644 index 0000000000..7eb338e7c5 --- /dev/null +++ b/utils/json_spirit/json_spirit_utils.h @@ -0,0 +1,61 @@ +#ifndef JSON_SPIRIT_UTILS +#define JSON_SPIRIT_UTILS + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include "json_spirit_value.h" +#include + +namespace json_spirit +{ + template< class Obj_t, class Map_t > + void obj_to_map( const Obj_t& obj, Map_t& mp_obj ) + { + mp_obj.clear(); + + for( typename Obj_t::const_iterator i = obj.begin(); i != obj.end(); ++i ) + { + mp_obj[ i->name_ ] = i->value_; + } + } + + template< class Obj_t, class Map_t > + void map_to_obj( const Map_t& mp_obj, Obj_t& obj ) + { + obj.clear(); + + for( typename Map_t::const_iterator i = mp_obj.begin(); i != mp_obj.end(); ++i ) + { + obj.push_back( typename Obj_t::value_type( i->first, i->second ) ); + } + } + + typedef std::map< std::string, Value > Mapped_obj; + +#ifndef BOOST_NO_STD_WSTRING + typedef std::map< std::wstring, wValue > wMapped_obj; +#endif + + template< class Object_type, class String_type > + const typename Object_type::value_type::Value_type& find_value( const Object_type& obj, const String_type& name ) + { + for( typename Object_type::const_iterator i = obj.begin(); i != obj.end(); ++i ) + { + if( i->name_ == name ) + { + return i->value_; + } + } + + return Object_type::value_type::Value_type::null; + } +} + +#endif diff --git a/utils/json_spirit/json_spirit_value.cpp b/utils/json_spirit/json_spirit_value.cpp new file mode 100644 index 0000000000..dd5b50e5d5 --- /dev/null +++ b/utils/json_spirit/json_spirit_value.cpp @@ -0,0 +1,8 @@ +/* Copyright (c) 2007 John W Wilkinson + + This source code can be used for any purpose as long as + this comment is retained. */ + +// json spirit version 2.00 + +#include "json_spirit_value.h" diff --git a/utils/json_spirit/json_spirit_value.h b/utils/json_spirit/json_spirit_value.h new file mode 100644 index 0000000000..e8be355300 --- /dev/null +++ b/utils/json_spirit/json_spirit_value.h @@ -0,0 +1,532 @@ +#ifndef JSON_SPIRIT_VALUE +#define JSON_SPIRIT_VALUE + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace json_spirit +{ + enum Value_type{ obj_type, array_type, str_type, bool_type, int_type, real_type, null_type }; + + template< class Config > // Config determines whether the value uses std::string or std::wstring and + // whether JSON Objects are represented as vectors or maps + class Value_impl + { + public: + + typedef Config Config_type; + typedef typename Config::String_type String_type; + typedef typename Config::Object_type Object; + typedef typename Config::Array_type Array; + typedef typename String_type::const_pointer Const_str_ptr; // eg const char* + + Value_impl(); // creates null value + Value_impl( Const_str_ptr value ); + Value_impl( const String_type& value ); + Value_impl( const Object& value ); + Value_impl( const Array& value ); + Value_impl( bool value ); + Value_impl( int value ); + Value_impl( boost::int64_t value ); + Value_impl( boost::uint64_t value ); + Value_impl( double value ); + + Value_impl( const Value_impl& other ); + + bool operator==( const Value_impl& lhs ) const; + + Value_impl& operator=( const Value_impl& lhs ); + + Value_type type() const; + + bool is_uint64() const; + bool is_null() const; + + const String_type& get_str() const; + const Object& get_obj() const; + const Array& get_array() const; + bool get_bool() const; + int get_int() const; + boost::int64_t get_int64() const; + boost::uint64_t get_uint64() const; + double get_real() const; + + Object& get_obj(); + Array& get_array(); + + template< typename T > T get_value() const; // example usage: int i = value.get_value< int >(); + // or double d = value.get_value< double >(); + + static const Value_impl null; + + private: + + void check_type( const Value_type vtype ) const; + + typedef boost::variant< String_type, + boost::recursive_wrapper< Object >, boost::recursive_wrapper< Array >, + bool, boost::int64_t, double > Variant; + + Value_type type_; + Variant v_; + bool is_uint64_; + }; + + // vector objects + + template< class Config > + struct Pair_impl + { + typedef typename Config::String_type String_type; + typedef typename Config::Value_type Value_type; + + Pair_impl( const String_type& name, const Value_type& value ); + + bool operator==( const Pair_impl& lhs ) const; + + String_type name_; + Value_type value_; + }; + + template< class String > + struct Config_vector + { + typedef String String_type; + typedef Value_impl< Config_vector > Value_type; + typedef Pair_impl < Config_vector > Pair_type; + typedef std::vector< Value_type > Array_type; + typedef std::vector< Pair_type > Object_type; + + static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value ) + { + obj.push_back( Pair_type( name , value ) ); + + return obj.back().value_; + } + + static String_type get_name( const Pair_type& pair ) + { + return pair.name_; + } + + static Value_type get_value( const Pair_type& pair ) + { + return pair.value_; + } + }; + + // typedefs for ASCII + + typedef Config_vector< std::string > Config; + + typedef Config::Value_type Value; + typedef Config::Pair_type Pair; + typedef Config::Object_type Object; + typedef Config::Array_type Array; + + // typedefs for Unicode + +#ifndef BOOST_NO_STD_WSTRING + + typedef Config_vector< std::wstring > wConfig; + + typedef wConfig::Value_type wValue; + typedef wConfig::Pair_type wPair; + typedef wConfig::Object_type wObject; + typedef wConfig::Array_type wArray; +#endif + + // map objects + + template< class String > + struct Config_map + { + typedef String String_type; + typedef Value_impl< Config_map > Value_type; + typedef std::vector< Value_type > Array_type; + typedef std::map< String_type, Value_type > Object_type; + typedef typename Object_type::value_type Pair_type; + + static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value ) + { + return obj[ name ] = value; + } + + static String_type get_name( const Pair_type& pair ) + { + return pair.first; + } + + static Value_type get_value( const Pair_type& pair ) + { + return pair.second; + } + }; + + // typedefs for ASCII + + typedef Config_map< std::string > mConfig; + + typedef mConfig::Value_type mValue; + typedef mConfig::Object_type mObject; + typedef mConfig::Array_type mArray; + + // typedefs for Unicode + +#ifndef BOOST_NO_STD_WSTRING + + typedef Config_map< std::wstring > wmConfig; + + typedef wmConfig::Value_type wmValue; + typedef wmConfig::Object_type wmObject; + typedef wmConfig::Array_type wmArray; + +#endif + + /////////////////////////////////////////////////////////////////////////////////////////////// + // + // implementation + + template< class Config > + const Value_impl< Config > Value_impl< Config >::null; + + template< class Config > + Value_impl< Config >::Value_impl() + : type_( null_type ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( const Const_str_ptr value ) + : type_( str_type ) + , v_( String_type( value ) ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( const String_type& value ) + : type_( str_type ) + , v_( value ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( const Object& value ) + : type_( obj_type ) + , v_( value ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( const Array& value ) + : type_( array_type ) + , v_( value ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( bool value ) + : type_( bool_type ) + , v_( value ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( int value ) + : type_( int_type ) + , v_( static_cast< boost::int64_t >( value ) ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( boost::int64_t value ) + : type_( int_type ) + , v_( value ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( boost::uint64_t value ) + : type_( int_type ) + , v_( static_cast< boost::int64_t >( value ) ) + , is_uint64_( true ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( double value ) + : type_( real_type ) + , v_( value ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( const Value_impl< Config >& other ) + : type_( other.type() ) + , v_( other.v_ ) + , is_uint64_( other.is_uint64_ ) + { + } + + template< class Config > + Value_impl< Config >& Value_impl< Config >::operator=( const Value_impl& lhs ) + { + Value_impl tmp( lhs ); + + std::swap( type_, tmp.type_ ); + std::swap( v_, tmp.v_ ); + std::swap( is_uint64_, tmp.is_uint64_ ); + + return *this; + } + + template< class Config > + bool Value_impl< Config >::operator==( const Value_impl& lhs ) const + { + if( this == &lhs ) return true; + + if( type() != lhs.type() ) return false; + + return v_ == lhs.v_; + } + + template< class Config > + Value_type Value_impl< Config >::type() const + { + return type_; + } + + template< class Config > + bool Value_impl< Config >::is_uint64() const + { + return is_uint64_; + } + + template< class Config > + bool Value_impl< Config >::is_null() const + { + return type() == null_type; + } + + template< class Config > + void Value_impl< Config >::check_type( const Value_type vtype ) const + { + if( type() != vtype ) + { + std::ostringstream os; + + os << "value type is " << type() << " not " << vtype; + + throw std::runtime_error( os.str() ); + } + } + + template< class Config > + const typename Config::String_type& Value_impl< Config >::get_str() const + { + check_type( str_type ); + + return *boost::get< String_type >( &v_ ); + } + + template< class Config > + const typename Value_impl< Config >::Object& Value_impl< Config >::get_obj() const + { + check_type( obj_type ); + + return *boost::get< Object >( &v_ ); + } + + template< class Config > + const typename Value_impl< Config >::Array& Value_impl< Config >::get_array() const + { + check_type( array_type ); + + return *boost::get< Array >( &v_ ); + } + + template< class Config > + bool Value_impl< Config >::get_bool() const + { + check_type( bool_type ); + + return boost::get< bool >( v_ ); + } + + template< class Config > + int Value_impl< Config >::get_int() const + { + check_type( int_type ); + + return static_cast< int >( get_int64() ); + } + + template< class Config > + boost::int64_t Value_impl< Config >::get_int64() const + { + check_type( int_type ); + + return boost::get< boost::int64_t >( v_ ); + } + + template< class Config > + boost::uint64_t Value_impl< Config >::get_uint64() const + { + check_type( int_type ); + + return static_cast< boost::uint64_t >( get_int64() ); + } + + template< class Config > + double Value_impl< Config >::get_real() const + { + if( type() == int_type ) + { + return is_uint64() ? static_cast< double >( get_uint64() ) + : static_cast< double >( get_int64() ); + } + + check_type( real_type ); + + return boost::get< double >( v_ ); + } + + template< class Config > + typename Value_impl< Config >::Object& Value_impl< Config >::get_obj() + { + check_type( obj_type ); + + return *boost::get< Object >( &v_ ); + } + + template< class Config > + typename Value_impl< Config >::Array& Value_impl< Config >::get_array() + { + check_type( array_type ); + + return *boost::get< Array >( &v_ ); + } + + template< class Config > + Pair_impl< Config >::Pair_impl( const String_type& name, const Value_type& value ) + : name_( name ) + , value_( value ) + { + } + + template< class Config > + bool Pair_impl< Config >::operator==( const Pair_impl< Config >& lhs ) const + { + if( this == &lhs ) return true; + + return ( name_ == lhs.name_ ) && ( value_ == lhs.value_ ); + } + + // converts a C string, ie. 8 bit char array, to a string object + // + template < class String_type > + String_type to_str( const char* c_str ) + { + String_type result; + + for( const char* p = c_str; *p != 0; ++p ) + { + result += *p; + } + + return result; + } + + // + + namespace internal_ + { + template< typename T > + struct Type_to_type + { + }; + + template< class Value > + int get_value( const Value& value, Type_to_type< int > ) + { + return value.get_int(); + } + + template< class Value > + boost::int64_t get_value( const Value& value, Type_to_type< boost::int64_t > ) + { + return value.get_int64(); + } + + template< class Value > + boost::uint64_t get_value( const Value& value, Type_to_type< boost::uint64_t > ) + { + return value.get_uint64(); + } + + template< class Value > + double get_value( const Value& value, Type_to_type< double > ) + { + return value.get_real(); + } + + template< class Value > + typename Value::String_type get_value( const Value& value, Type_to_type< typename Value::String_type > ) + { + return value.get_str(); + } + + template< class Value > + typename Value::Array get_value( const Value& value, Type_to_type< typename Value::Array > ) + { + return value.get_array(); + } + + template< class Value > + typename Value::Object get_value( const Value& value, Type_to_type< typename Value::Object > ) + { + return value.get_obj(); + } + + template< class Value > + bool get_value( const Value& value, Type_to_type< bool > ) + { + return value.get_bool(); + } + } + + template< class Config > + template< typename T > + T Value_impl< Config >::get_value() const + { + return internal_::get_value( *this, internal_::Type_to_type< T >() ); + } +} + +#endif diff --git a/utils/json_spirit/json_spirit_writer.cpp b/utils/json_spirit/json_spirit_writer.cpp new file mode 100644 index 0000000000..f3367b68de --- /dev/null +++ b/utils/json_spirit/json_spirit_writer.cpp @@ -0,0 +1,95 @@ +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#include "json_spirit_writer.h" +#include "json_spirit_writer_template.h" + +void json_spirit::write( const Value& value, std::ostream& os ) +{ + write_stream( value, os, false ); +} + +void json_spirit::write_formatted( const Value& value, std::ostream& os ) +{ + write_stream( value, os, true ); +} + +std::string json_spirit::write( const Value& value ) +{ + return write_string( value, false ); +} + +std::string json_spirit::write_formatted( const Value& value ) +{ + return write_string( value, true ); +} + +#ifndef BOOST_NO_STD_WSTRING + +void json_spirit::write( const wValue& value, std::wostream& os ) +{ + write_stream( value, os, false ); +} + +void json_spirit::write_formatted( const wValue& value, std::wostream& os ) +{ + write_stream( value, os, true ); +} + +std::wstring json_spirit::write( const wValue& value ) +{ + return write_string( value, false ); +} + +std::wstring json_spirit::write_formatted( const wValue& value ) +{ + return write_string( value, true ); +} + +#endif + +void json_spirit::write( const mValue& value, std::ostream& os ) +{ + write_stream( value, os, false ); +} + +void json_spirit::write_formatted( const mValue& value, std::ostream& os ) +{ + write_stream( value, os, true ); +} + +std::string json_spirit::write( const mValue& value ) +{ + return write_string( value, false ); +} + +std::string json_spirit::write_formatted( const mValue& value ) +{ + return write_string( value, true ); +} + +#ifndef BOOST_NO_STD_WSTRING + +void json_spirit::write( const wmValue& value, std::wostream& os ) +{ + write_stream( value, os, false ); +} + +void json_spirit::write_formatted( const wmValue& value, std::wostream& os ) +{ + write_stream( value, os, true ); +} + +std::wstring json_spirit::write( const wmValue& value ) +{ + return write_string( value, false ); +} + +std::wstring json_spirit::write_formatted( const wmValue& value ) +{ + return write_string( value, true ); +} + +#endif diff --git a/utils/json_spirit/json_spirit_writer.h b/utils/json_spirit/json_spirit_writer.h new file mode 100644 index 0000000000..1b67b512df --- /dev/null +++ b/utils/json_spirit/json_spirit_writer.h @@ -0,0 +1,50 @@ +#ifndef JSON_SPIRIT_WRITER +#define JSON_SPIRIT_WRITER + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include "json_spirit_value.h" +#include + +namespace json_spirit +{ + // functions to convert JSON Values to text, + // the "formatted" versions add whitespace to format the output nicely + + void write ( const Value& value, std::ostream& os ); + void write_formatted( const Value& value, std::ostream& os ); + std::string write ( const Value& value ); + std::string write_formatted( const Value& value ); + +#ifndef BOOST_NO_STD_WSTRING + + void write ( const wValue& value, std::wostream& os ); + void write_formatted( const wValue& value, std::wostream& os ); + std::wstring write ( const wValue& value ); + std::wstring write_formatted( const wValue& value ); + +#endif + + void write ( const mValue& value, std::ostream& os ); + void write_formatted( const mValue& value, std::ostream& os ); + std::string write ( const mValue& value ); + std::string write_formatted( const mValue& value ); + +#ifndef BOOST_NO_STD_WSTRING + + void write ( const wmValue& value, std::wostream& os ); + void write_formatted( const wmValue& value, std::wostream& os ); + std::wstring write ( const wmValue& value ); + std::wstring write_formatted( const wmValue& value ); + +#endif +} + +#endif diff --git a/utils/json_spirit/json_spirit_writer_template.h b/utils/json_spirit/json_spirit_writer_template.h new file mode 100644 index 0000000000..5376ef476e --- /dev/null +++ b/utils/json_spirit/json_spirit_writer_template.h @@ -0,0 +1,243 @@ +#ifndef JSON_SPIRIT_WRITER_TEMPLATE +#define JSON_SPIRIT_WRITER_TEMPLATE + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#include "json_spirit_value.h" + +#include +#include +#include + +namespace json_spirit +{ + inline char to_hex_char( unsigned int c ) + { + assert( c <= 0xF ); + + const char ch = static_cast< char >( c ); + + if( ch < 10 ) return '0' + ch; + + return 'A' - 10 + ch; + } + + template< class String_type > + String_type non_printable_to_string( unsigned int c ) + { + String_type result( 6, '\\' ); + + result[1] = 'u'; + + result[ 5 ] = to_hex_char( c & 0x000F ); c >>= 4; + result[ 4 ] = to_hex_char( c & 0x000F ); c >>= 4; + result[ 3 ] = to_hex_char( c & 0x000F ); c >>= 4; + result[ 2 ] = to_hex_char( c & 0x000F ); + + return result; + } + + template< typename Char_type, class String_type > + bool add_esc_char( Char_type c, String_type& s ) + { + switch( c ) + { + case '"': s += to_str< String_type >( "\\\"" ); return true; + case '\\': s += to_str< String_type >( "\\\\" ); return true; + case '\b': s += to_str< String_type >( "\\b" ); return true; + case '\f': s += to_str< String_type >( "\\f" ); return true; + case '\n': s += to_str< String_type >( "\\n" ); return true; + case '\r': s += to_str< String_type >( "\\r" ); return true; + case '\t': s += to_str< String_type >( "\\t" ); return true; + } + + return false; + } + + template< class String_type > + String_type add_esc_chars( const String_type& s ) + { + typedef typename String_type::const_iterator Iter_type; + typedef typename String_type::value_type Char_type; + + String_type result; + + const Iter_type end( s.end() ); + + for( Iter_type i = s.begin(); i != end; ++i ) + { + const Char_type c( *i ); + + if( add_esc_char( c, result ) ) continue; + + const wint_t unsigned_c( ( c >= 0 ) ? c : 256 + c ); + + if( iswprint( unsigned_c ) ) + { + result += c; + } + else + { + result += non_printable_to_string< String_type >( unsigned_c ); + } + } + + return result; + } + + // this class generates the JSON text, + // it keeps track of the indentation level etc. + // + template< class Value_type, class Ostream_type > + class Generator + { + typedef typename Value_type::Config_type Config_type; + typedef typename Config_type::String_type String_type; + typedef typename Config_type::Object_type Object_type; + typedef typename Config_type::Array_type Array_type; + typedef typename String_type::value_type Char_type; + typedef typename Object_type::value_type Obj_member_type; + + public: + + Generator( const Value_type& value, Ostream_type& os, bool pretty ) + : os_( os ) + , indentation_level_( 0 ) + , pretty_( pretty ) + { + output( value ); + } + + private: + + void output( const Value_type& value ) + { + switch( value.type() ) + { + case obj_type: output( value.get_obj() ); break; + case array_type: output( value.get_array() ); break; + case str_type: output( value.get_str() ); break; + case bool_type: output( value.get_bool() ); break; + case int_type: output_int( value ); break; + case real_type: os_ << std::showpoint << std::setprecision( 16 ) + << value.get_real(); break; + case null_type: os_ << "null"; break; + default: assert( false ); + } + } + + void output( const Object_type& obj ) + { + output_array_or_obj( obj, '{', '}' ); + } + + void output( const Array_type& arr ) + { + output_array_or_obj( arr, '[', ']' ); + } + + void output( const Obj_member_type& member ) + { + output( Config_type::get_name( member ) ); space(); + os_ << ':'; space(); + output( Config_type::get_value( member ) ); + } + + void output_int( const Value_type& value ) + { + if( value.is_uint64() ) + { + os_ << value.get_uint64(); + } + else + { + os_ << value.get_int64(); + } + } + + void output( const String_type& s ) + { + os_ << '"' << add_esc_chars( s ) << '"'; + } + + void output( bool b ) + { + os_ << to_str< String_type >( b ? "true" : "false" ); + } + + template< class T > + void output_array_or_obj( const T& t, Char_type start_char, Char_type end_char ) + { + os_ << start_char; new_line(); + + ++indentation_level_; + + for( typename T::const_iterator i = t.begin(); i != t.end(); ++i ) + { + indent(); output( *i ); + + typename T::const_iterator next = i; + + if( ++next != t.end()) + { + os_ << ','; + } + + new_line(); + } + + --indentation_level_; + + indent(); os_ << end_char; + } + + void indent() + { + if( !pretty_ ) return; + + for( int i = 0; i < indentation_level_; ++i ) + { + os_ << " "; + } + } + + void space() + { + if( pretty_ ) os_ << ' '; + } + + void new_line() + { + if( pretty_ ) os_ << '\n'; + } + + Generator& operator=( const Generator& ); // to prevent "assignment operator could not be generated" warning + + Ostream_type& os_; + int indentation_level_; + bool pretty_; + }; + + template< class Value_type, class Ostream_type > + void write_stream( const Value_type& value, Ostream_type& os, bool pretty ) + { + Generator< Value_type, Ostream_type >( value, os, pretty ); + } + + template< class Value_type > + typename Value_type::String_type write_string( const Value_type& value, bool pretty ) + { + typedef typename Value_type::String_type::value_type Char_type; + + std::basic_ostringstream< Char_type > os; + + write_stream( value, os, pretty ); + + return os.str(); + } +} + +#endif diff --git a/utils/libscrypt/CMakeLists.txt b/utils/libscrypt/CMakeLists.txt new file mode 100644 index 0000000000..dbd0bc8a68 --- /dev/null +++ b/utils/libscrypt/CMakeLists.txt @@ -0,0 +1,10 @@ +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") + +aux_source_directory(. SRC_LIST) +file(GLOB HEADERS "*.h") + +add_library(scrypt ${SRC_LIST} ${HEADERS}) + +install(TARGETS scrypt RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib) +install(FILES ${HEADERS} DESTINATION include/scrypt) + diff --git a/utils/libscrypt/LICENSE b/utils/libscrypt/LICENSE new file mode 100644 index 0000000000..5c77131eb7 --- /dev/null +++ b/utils/libscrypt/LICENSE @@ -0,0 +1,9 @@ +Copyright (c) 2013, Joshua Small + All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: +Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/utils/libscrypt/b64.c b/utils/libscrypt/b64.c new file mode 100644 index 0000000000..ebacc299ae --- /dev/null +++ b/utils/libscrypt/b64.c @@ -0,0 +1,313 @@ +/* + * Copyright (c) 1996 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +/* + * Portions Copyright (c) 1995 by International Business Machines, Inc. + * + * International Business Machines, Inc. (hereinafter called IBM) grants + * permission under its copyrights to use, copy, modify, and distribute this + * Software with or without fee, provided that the above copyright notice and + * all paragraphs of this notice appear in all copies, and that the name of IBM + * not be used in connection with the marketing of any product incorporating + * the Software or modifications thereof, without specific, written prior + * permission. + * + * To the extent it has a right to do so, IBM grants an immunity from suit + * under its patents, if any, for the use, sale or manufacture of products to + * the extent that such products are used for performing Domain Name System + * dynamic updates in TCP/IP networks by means of the Software. No immunity is + * granted for any product per se or for any other function of any product. + * + * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, + * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN + * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +/* + * Base64 encode/decode functions from OpenBSD (src/lib/libc/net/base64.c). + */ +#include +#include +#include +#include +#include + +#include "b64.h" + + +static const char Base64[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +static const char Pad64 = '='; + +/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt) + The following encoding technique is taken from RFC 1521 by Borenstein + and Freed. It is reproduced here in a slightly edited form for + convenience. + + A 65-character subset of US-ASCII is used, enabling 6 bits to be + represented per printable character. (The extra 65th character, "=", + is used to signify a special processing function.) + + The encoding process represents 24-bit groups of input bits as output + strings of 4 encoded characters. Proceeding from left to right, a + 24-bit input group is formed by concatenating 3 8-bit input groups. + These 24 bits are then treated as 4 concatenated 6-bit groups, each + of which is translated into a single digit in the base64 alphabet. + + Each 6-bit group is used as an index into an array of 64 printable + characters. The character referenced by the index is placed in the + output string. + + Table 1: The Base64 Alphabet + + Value Encoding Value Encoding Value Encoding Value Encoding + 0 A 17 R 34 i 51 z + 1 B 18 S 35 j 52 0 + 2 C 19 T 36 k 53 1 + 3 D 20 U 37 l 54 2 + 4 E 21 V 38 m 55 3 + 5 F 22 W 39 n 56 4 + 6 G 23 X 40 o 57 5 + 7 H 24 Y 41 p 58 6 + 8 I 25 Z 42 q 59 7 + 9 J 26 a 43 r 60 8 + 10 K 27 b 44 s 61 9 + 11 L 28 c 45 t 62 + + 12 M 29 d 46 u 63 / + 13 N 30 e 47 v + 14 O 31 f 48 w (pad) = + 15 P 32 g 49 x + 16 Q 33 h 50 y + + Special processing is performed if fewer than 24 bits are available + at the end of the data being encoded. A full encoding quantum is + always completed at the end of a quantity. When fewer than 24 input + bits are available in an input group, zero bits are added (on the + right) to form an integral number of 6-bit groups. Padding at the + end of the data is performed using the '=' character. + + Since all base64 input is an integral number of octets, only the + ------------------------------------------------- + following cases can arise: + + (1) the final quantum of encoding input is an integral + multiple of 24 bits; here, the final unit of encoded + output will be an integral multiple of 4 characters + with no "=" padding, + (2) the final quantum of encoding input is exactly 8 bits; + here, the final unit of encoded output will be two + characters followed by two "=" padding characters, or + (3) the final quantum of encoding input is exactly 16 bits; + here, the final unit of encoded output will be three + characters followed by one "=" padding character. +*/ + +int +libscrypt_b64_encode(src, srclength, target, targsize) + unsigned char const *src; + size_t srclength; + char *target; + size_t targsize; +{ + size_t datalength = 0; + unsigned char input[3]; + unsigned char output[4]; + unsigned int i; + + while (2 < srclength) { + input[0] = *src++; + input[1] = *src++; + input[2] = *src++; + srclength -= 3; + + output[0] = input[0] >> 2; + output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); + output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); + output[3] = input[2] & 0x3f; + + if (datalength + 4 > targsize) + return (-1); + target[datalength++] = Base64[output[0]]; + target[datalength++] = Base64[output[1]]; + target[datalength++] = Base64[output[2]]; + target[datalength++] = Base64[output[3]]; + } + + /* Now we worry about padding. */ + if (0 != srclength) { + /* Get what's left. */ + input[0] = input[1] = input[2] = '\0'; + for (i = 0; i < srclength; i++) + input[i] = *src++; + + output[0] = input[0] >> 2; + output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); + output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); + + if (datalength + 4 > targsize) + return (-1); + target[datalength++] = Base64[output[0]]; + target[datalength++] = Base64[output[1]]; + if (srclength == 1) + target[datalength++] = Pad64; + else + target[datalength++] = Base64[output[2]]; + target[datalength++] = Pad64; + } + if (datalength >= targsize) + return (-1); + target[datalength] = '\0'; /* Returned value doesn't count \0. */ + return (int)(datalength); +} + +/* skips all whitespace anywhere. + converts characters, four at a time, starting at (or after) + src from base - 64 numbers into three 8 bit bytes in the target area. + it returns the number of data bytes stored at the target, or -1 on error. + */ + +int +libscrypt_b64_decode(src, target, targsize) + char const *src; + unsigned char *target; + size_t targsize; +{ + int state, ch; + unsigned int tarindex; + unsigned char nextbyte; + char *pos; + + state = 0; + tarindex = 0; + + while ((ch = (unsigned char)*src++) != '\0') { + if (isspace(ch)) /* Skip whitespace anywhere. */ + continue; + + if (ch == Pad64) + break; + + pos = strchr(Base64, ch); + if (pos == 0) /* A non-base64 character. */ + return (-1); + + switch (state) { + case 0: + if (target) { + if (tarindex >= targsize) + return (-1); + target[tarindex] = (pos - Base64) << 2; + } + state = 1; + break; + case 1: + if (target) { + if (tarindex >= targsize) + return (-1); + target[tarindex] |= (pos - Base64) >> 4; + nextbyte = ((pos - Base64) & 0x0f) << 4; + if (tarindex + 1 < targsize) + target[tarindex+1] = nextbyte; + else if (nextbyte) + return (-1); + } + tarindex++; + state = 2; + break; + case 2: + if (target) { + if (tarindex >= targsize) + return (-1); + target[tarindex] |= (pos - Base64) >> 2; + nextbyte = ((pos - Base64) & 0x03) << 6; + if (tarindex + 1 < targsize) + target[tarindex+1] = nextbyte; + else if (nextbyte) + return (-1); + } + tarindex++; + state = 3; + break; + case 3: + if (target) { + if (tarindex >= targsize) + return (-1); + target[tarindex] |= (pos - Base64); + } + tarindex++; + state = 0; + break; + } + } + + /* + * We are done decoding Base-64 chars. Let's see if we ended + * on a byte boundary, and/or with erroneous trailing characters. + */ + + if (ch == Pad64) { /* We got a pad char. */ + ch = (unsigned char)*src++; /* Skip it, get next. */ + switch (state) { + case 0: /* Invalid = in first position */ + case 1: /* Invalid = in second position */ + return (-1); + + case 2: /* Valid, means one byte of info */ + /* Skip any number of spaces. */ + for (; ch != '\0'; ch = (unsigned char)*src++) + if (!isspace(ch)) + break; + /* Make sure there is another trailing = sign. */ + if (ch != Pad64) + return (-1); + ch = (unsigned char)*src++; /* Skip the = */ + /* Fall through to "single trailing =" case. */ + /* FALLTHROUGH */ + + case 3: /* Valid, means two bytes of info */ + /* + * We know this char is an =. Is there anything but + * whitespace after it? + */ + for (; ch != '\0'; ch = (unsigned char)*src++) + if (!isspace(ch)) + return (-1); + + /* + * Now make sure for cases 2 and 3 that the "extra" + * bits that slopped past the last full byte were + * zeros. If we don't check them, they become a + * subliminal channel. + */ + if (target && tarindex < targsize && + target[tarindex] != 0) + return (-1); + } + } else { + /* + * We ended by seeing the end of the string. Make sure we + * have no partial bytes lying around. + */ + if (state != 0) + return (-1); + } + + return (tarindex); +} diff --git a/utils/libscrypt/b64.h b/utils/libscrypt/b64.h new file mode 100644 index 0000000000..d27e79cae9 --- /dev/null +++ b/utils/libscrypt/b64.h @@ -0,0 +1,10 @@ + +/* BASE64 libraries used internally - should not need to be packaged */ + +#define b64_encode_len(A) ((A+2)/3 * 4 + 1) +#define b64_decode_len(A) (A / 4 * 3 + 2) + +int libscrypt_b64_encode(unsigned char const *src, size_t srclength, + /*@out@*/ char *target, size_t targetsize); +int libscrypt_b64_decode(char const *src, /*@out@*/ unsigned char *target, + size_t targetsize); diff --git a/utils/libscrypt/crypto-mcf.c b/utils/libscrypt/crypto-mcf.c new file mode 100644 index 0000000000..f8aefce139 --- /dev/null +++ b/utils/libscrypt/crypto-mcf.c @@ -0,0 +1,73 @@ +#include +#include +#include +#include +#include +#include +#include + +#ifndef S_SPLINT_S /* Including this here triggers a known bug in splint */ +//#include +#endif + +#include "libscrypt.h" + +/* ilog2 for powers of two */ +static uint32_t scrypt_ilog2(uint32_t n) +{ +#ifndef S_SPLINT_S + + /* Check for a valid power of two */ + if (n < 2 || (n & (n - 1))) + return -1; +#endif + uint32_t t = 1; + while (((uint32_t)1 << t) < n) + { + if(t > SCRYPT_SAFE_N) + return (uint32_t) -1; /* Check for insanity */ + t++; + } + + return t; +} + +#ifdef _MSC_VER + #define SNPRINTF _snprintf +#else + #define SNPRINTF snprintf +#endif + +int libscrypt_mcf(uint32_t N, uint32_t r, uint32_t p, const char *salt, + const char *hash, char *mcf) +{ + + uint32_t t, params; + int s; + + if(!mcf || !hash) + return 0; + /* Although larger values of r, p are valid in scrypt, this mcf format + * limits to 8 bits. If your number is larger, current computers will + * struggle + */ + if(r > (uint8_t)(-1) || p > (uint8_t)(-1)) + return 0; + + t = scrypt_ilog2(N); + if (t < 1) + return 0; + + params = (r << 8) + p; + params += (uint32_t)t << 16; + + /* Using snprintf - not checking for overflows. We've already + * determined that mcf should be defined as at least SCRYPT_MCF_LEN + * in length + */ + s = SNPRINTF(mcf, SCRYPT_MCF_LEN, SCRYPT_MCF_ID "$%06x$%s$%s", (unsigned int)params, salt, hash); + if (s > SCRYPT_MCF_LEN) + return 0; + + return 1; +} diff --git a/utils/libscrypt/crypto-scrypt-saltgen.c b/utils/libscrypt/crypto-scrypt-saltgen.c new file mode 100644 index 0000000000..e69de29bb2 diff --git a/utils/libscrypt/crypto_scrypt-check.c b/utils/libscrypt/crypto_scrypt-check.c new file mode 100644 index 0000000000..583bf6a959 --- /dev/null +++ b/utils/libscrypt/crypto_scrypt-check.c @@ -0,0 +1,100 @@ +#include +#include +#include +#include + +#include "b64.h" +#include "slowequals.h" +#include "libscrypt.h" + +#if defined(_WIN32) +/* On windows, strtok uses a thread-local static variable in strtok to + * make strtok thread-safe. It also neglects to provide a strtok_r. */ +#define strtok_r(str, val, saveptr) strtok((str), (val)) +#endif + +int libscrypt_check(char *mcf, const char *password) +{ + /* Return values: + * <0 error + * == 0 password incorrect + * >0 correct password + */ + +#ifndef _WIN32 + char *saveptr = NULL; +#endif + uint32_t params; + uint64_t N; + uint8_t r, p; + int retval; + uint8_t hashbuf[64]; + char outbuf[128]; + uint8_t salt[32]; + char *tok; + + if(memcmp(mcf, SCRYPT_MCF_ID, 3) != 0) + { + /* Only version 0 supported */ + return -1; + } + + tok = strtok_r(mcf, "$", &saveptr); + if ( !tok ) + return -1; + + tok = strtok_r(NULL, "$", &saveptr); + + if ( !tok ) + return -1; + + params = (uint32_t)strtoul(tok, NULL, 16); + if ( params == 0 ) + return -1; + + tok = strtok_r(NULL, "$", &saveptr); + + if ( !tok ) + return -1; + + p = params & 0xff; + r = (params >> 8) & 0xff; + N = params >> 16; + + if (N > SCRYPT_SAFE_N) + return -1; + + N = (uint64_t)1 << N; + + /* Useful debugging: + printf("We've obtained salt 'N' r p of '%s' %d %d %d\n", tok, N,r,p); + */ + + memset(salt, 0, sizeof(salt)); /* Keeps splint happy */ + retval = libscrypt_b64_decode(tok, (unsigned char*)salt, sizeof(salt)); + if (retval < 1) + return -1; + + retval = libscrypt_scrypt((uint8_t*)password, strlen(password), salt, + (uint32_t)retval, N, r, p, hashbuf, sizeof(hashbuf)); + + if (retval != 0) + return -1; + + retval = libscrypt_b64_encode((unsigned char*)hashbuf, sizeof(hashbuf), + outbuf, sizeof(outbuf)); + + if (retval == 0) + return -1; + + tok = strtok_r(NULL, "$", &saveptr); + + if ( !tok ) + return -1; + + if(slow_equals(tok, outbuf) == 0) + return 0; + + return 1; /* This is the "else" condition */ +} + diff --git a/utils/libscrypt/crypto_scrypt-hash.c b/utils/libscrypt/crypto_scrypt-hash.c new file mode 100644 index 0000000000..e69de29bb2 diff --git a/utils/libscrypt/crypto_scrypt-hexconvert.c b/utils/libscrypt/crypto_scrypt-hexconvert.c new file mode 100644 index 0000000000..e1c08f5230 --- /dev/null +++ b/utils/libscrypt/crypto_scrypt-hexconvert.c @@ -0,0 +1,35 @@ +#include +#include +#include +#include + +/* The hexconvert function is only used to test reference vectors against + * known answers. The contents of this file are therefore a component + * to assist with test harnesses only + */ + +int libscrypt_hexconvert(uint8_t *buf, size_t s, char *outbuf, size_t obs) +{ + + size_t i; + int len = 0; + + if (!buf || s < 1 || obs < (s * 2 + 1)) + return 0; + + memset(outbuf, 0, obs); + + + for(i=0; i<=(s-1); i++) + { + /* snprintf(outbuf, s,"%s...", outbuf....) has undefined results + * and can't be used. Using offests like this makes snprintf + * nontrivial. we therefore have use inescure sprintf() and + * lengths checked elsewhere (start of function) */ + /*@ -bufferoverflowhigh @*/ + len += sprintf(outbuf+len, "%02x", (unsigned int) buf[i]); + } + + return 1; +} + diff --git a/utils/libscrypt/crypto_scrypt-hexconvert.h b/utils/libscrypt/crypto_scrypt-hexconvert.h new file mode 100644 index 0000000000..d8d54d249b --- /dev/null +++ b/utils/libscrypt/crypto_scrypt-hexconvert.h @@ -0,0 +1,9 @@ + +#include + +/** + * Converts a binary string to a hex representation of that string + * outbuf must have size of at least buf * 2 + 1. + */ +int libscrypt_hexconvert(const uint8_t *buf, size_t s, char *outbuf, + size_t obs); diff --git a/utils/libscrypt/crypto_scrypt-nosse.c b/utils/libscrypt/crypto_scrypt-nosse.c new file mode 100644 index 0000000000..ca92f70859 --- /dev/null +++ b/utils/libscrypt/crypto_scrypt-nosse.c @@ -0,0 +1,342 @@ +/*- + * Copyright 2009 Colin Percival + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file was originally written by Colin Percival as part of the Tarsnap + * online backup system. + */ + +#include +#ifndef _WIN32 +#include +#endif +#include +#include +#include +#include + +#include "sha256.h" +#include "sysendian.h" + +#include "libscrypt.h" + +static void blkcpy(void *, void *, size_t); +static void blkxor(void *, void *, size_t); +static void salsa20_8(uint32_t[16]); +static void blockmix_salsa8(uint32_t *, uint32_t *, uint32_t *, size_t); +static uint64_t integerify(void *, size_t); +static void smix(uint8_t *, size_t, uint64_t, uint32_t *, uint32_t *); + +static void +blkcpy(void * dest, void * src, size_t len) +{ + size_t * D = dest; + size_t * S = src; + size_t L = len / sizeof(size_t); + size_t i; + + for (i = 0; i < L; i++) + D[i] = S[i]; +} + +static void +blkxor(void * dest, void * src, size_t len) +{ + size_t * D = dest; + size_t * S = src; + size_t L = len / sizeof(size_t); + size_t i; + + for (i = 0; i < L; i++) + D[i] ^= S[i]; +} + +/** + * salsa20_8(B): + * Apply the salsa20/8 core to the provided block. + */ +static void +salsa20_8(uint32_t B[16]) +{ + uint32_t x[16]; + size_t i; + + blkcpy(x, B, 64); + for (i = 0; i < 8; i += 2) { +#define R(a,b) (((a) << (b)) | ((a) >> (32 - (b)))) + /* Operate on columns. */ + x[ 4] ^= R(x[ 0]+x[12], 7); x[ 8] ^= R(x[ 4]+x[ 0], 9); + x[12] ^= R(x[ 8]+x[ 4],13); x[ 0] ^= R(x[12]+x[ 8],18); + + x[ 9] ^= R(x[ 5]+x[ 1], 7); x[13] ^= R(x[ 9]+x[ 5], 9); + x[ 1] ^= R(x[13]+x[ 9],13); x[ 5] ^= R(x[ 1]+x[13],18); + + x[14] ^= R(x[10]+x[ 6], 7); x[ 2] ^= R(x[14]+x[10], 9); + x[ 6] ^= R(x[ 2]+x[14],13); x[10] ^= R(x[ 6]+x[ 2],18); + + x[ 3] ^= R(x[15]+x[11], 7); x[ 7] ^= R(x[ 3]+x[15], 9); + x[11] ^= R(x[ 7]+x[ 3],13); x[15] ^= R(x[11]+x[ 7],18); + + /* Operate on rows. */ + x[ 1] ^= R(x[ 0]+x[ 3], 7); x[ 2] ^= R(x[ 1]+x[ 0], 9); + x[ 3] ^= R(x[ 2]+x[ 1],13); x[ 0] ^= R(x[ 3]+x[ 2],18); + + x[ 6] ^= R(x[ 5]+x[ 4], 7); x[ 7] ^= R(x[ 6]+x[ 5], 9); + x[ 4] ^= R(x[ 7]+x[ 6],13); x[ 5] ^= R(x[ 4]+x[ 7],18); + + x[11] ^= R(x[10]+x[ 9], 7); x[ 8] ^= R(x[11]+x[10], 9); + x[ 9] ^= R(x[ 8]+x[11],13); x[10] ^= R(x[ 9]+x[ 8],18); + + x[12] ^= R(x[15]+x[14], 7); x[13] ^= R(x[12]+x[15], 9); + x[14] ^= R(x[13]+x[12],13); x[15] ^= R(x[14]+x[13],18); +#undef R + } + for (i = 0; i < 16; i++) + B[i] += x[i]; +} + +/** + * blockmix_salsa8(Bin, Bout, X, r): + * Compute Bout = BlockMix_{salsa20/8, r}(Bin). The input Bin must be 128r + * bytes in length; the output Bout must also be the same size. The + * temporary space X must be 64 bytes. + */ +static void +blockmix_salsa8(uint32_t * Bin, uint32_t * Bout, uint32_t * X, size_t r) +{ + size_t i; + + /* 1: X <-- B_{2r - 1} */ + blkcpy(X, &Bin[(2 * r - 1) * 16], 64); + + /* 2: for i = 0 to 2r - 1 do */ + for (i = 0; i < 2 * r; i += 2) { + /* 3: X <-- H(X \xor B_i) */ + blkxor(X, &Bin[i * 16], 64); + salsa20_8(X); + + /* 4: Y_i <-- X */ + /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ + blkcpy(&Bout[i * 8], X, 64); + + /* 3: X <-- H(X \xor B_i) */ + blkxor(X, &Bin[i * 16 + 16], 64); + salsa20_8(X); + + /* 4: Y_i <-- X */ + /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ + blkcpy(&Bout[i * 8 + r * 16], X, 64); + } +} + +/** + * integerify(B, r): + * Return the result of parsing B_{2r-1} as a little-endian integer. + */ +static uint64_t +integerify(void * B, size_t r) +{ + uint32_t * X = (void *)((uintptr_t)(B) + (2 * r - 1) * 64); + + return (((uint64_t)(X[1]) << 32) + X[0]); +} + +/** + * smix(B, r, N, V, XY): + * Compute B = SMix_r(B, N). The input B must be 128r bytes in length; + * the temporary storage V must be 128rN bytes in length; the temporary + * storage XY must be 256r + 64 bytes in length. The value N must be a + * power of 2 greater than 1. The arrays B, V, and XY must be aligned to a + * multiple of 64 bytes. + */ +static void +smix(uint8_t * B, size_t r, uint64_t N, uint32_t * V, uint32_t * XY) +{ + uint32_t * X = XY; + uint32_t * Y = &XY[32 * r]; + uint32_t * Z = &XY[64 * r]; + uint64_t i; + uint64_t j; + size_t k; + + /* 1: X <-- B */ + for (k = 0; k < 32 * r; k++) + X[k] = le32dec(&B[4 * k]); + + /* 2: for i = 0 to N - 1 do */ + for (i = 0; i < N; i += 2) { + /* 3: V_i <-- X */ + blkcpy(&V[i * (32 * r)], X, 128 * r); + + /* 4: X <-- H(X) */ + blockmix_salsa8(X, Y, Z, r); + + /* 3: V_i <-- X */ + blkcpy(&V[(i + 1) * (32 * r)], Y, 128 * r); + + /* 4: X <-- H(X) */ + blockmix_salsa8(Y, X, Z, r); + } + + /* 6: for i = 0 to N - 1 do */ + for (i = 0; i < N; i += 2) { + /* 7: j <-- Integerify(X) mod N */ + j = integerify(X, r) & (N - 1); + + /* 8: X <-- H(X \xor V_j) */ + blkxor(X, &V[j * (32 * r)], 128 * r); + blockmix_salsa8(X, Y, Z, r); + + /* 7: j <-- Integerify(X) mod N */ + j = integerify(Y, r) & (N - 1); + + /* 8: X <-- H(X \xor V_j) */ + blkxor(Y, &V[j * (32 * r)], 128 * r); + blockmix_salsa8(Y, X, Z, r); + } + + /* 10: B' <-- X */ + for (k = 0; k < 32 * r; k++) + le32enc(&B[4 * k], X[k]); +} + +/** + * crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen): + * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r, + * p, buflen) and write the result into buf. The parameters r, p, and buflen + * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32. The parameter N + * must be a power of 2 greater than 1. + * + * Return 0 on success; or -1 on error + */ +int +libscrypt_scrypt(const uint8_t * passwd, size_t passwdlen, + const uint8_t * salt, size_t saltlen, uint64_t N, uint32_t r, uint32_t p, + uint8_t * buf, size_t buflen) +{ + void * B0, * V0, * XY0; + uint8_t * B; + uint32_t * V; + uint32_t * XY; + uint32_t i; + + /* Sanity-check parameters. */ +#if SIZE_MAX > UINT32_MAX + if (buflen > (((uint64_t)(1) << 32) - 1) * 32) { + errno = EFBIG; + goto err0; + } +#endif + if ((uint64_t)(r) * (uint64_t)(p) >= (1 << 30)) { + errno = EFBIG; + goto err0; + } + if (r == 0 || p == 0) { + errno = EINVAL; + goto err0; + } + if (((N & (N - 1)) != 0) || (N < 2)) { + errno = EINVAL; + goto err0; + } + if ((r > SIZE_MAX / 128 / p) || +#if SIZE_MAX / 256 <= UINT32_MAX + (r > SIZE_MAX / 256) || +#endif + (N > SIZE_MAX / 128 / r)) { + errno = ENOMEM; + goto err0; + } + + /* Allocate memory. */ +#ifdef HAVE_POSIX_MEMALIGN + if ((errno = posix_memalign(&B0, 64, 128 * r * p)) != 0) + goto err0; + B = (uint8_t *)(B0); + if ((errno = posix_memalign(&XY0, 64, 256 * r + 64)) != 0) + goto err1; + XY = (uint32_t *)(XY0); +#ifndef MAP_ANON + if ((errno = posix_memalign(&V0, 64, 128 * r * N)) != 0) + goto err2; + V = (uint32_t *)(V0); +#endif +#else + if ((B0 = malloc(128 * r * p + 63)) == NULL) + goto err0; + B = (uint8_t *)(((uintptr_t)(B0) + 63) & ~ (uintptr_t)(63)); + if ((XY0 = malloc(256 * r + 64 + 63)) == NULL) + goto err1; + XY = (uint32_t *)(((uintptr_t)(XY0) + 63) & ~ (uintptr_t)(63)); +#ifndef MAP_ANON + if ((V0 = malloc(128 * r * N + 63)) == NULL) + goto err2; + V = (uint32_t *)(((uintptr_t)(V0) + 63) & ~ (uintptr_t)(63)); +#endif +#endif +#ifdef MAP_ANON + if ((V0 = mmap(NULL, 128 * r * N, PROT_READ | PROT_WRITE, +#ifdef MAP_NOCORE + MAP_ANON | MAP_PRIVATE | MAP_NOCORE, +#else + MAP_ANON | MAP_PRIVATE, +#endif + -1, 0)) == MAP_FAILED) + goto err2; + V = (uint32_t *)(V0); +#endif + + /* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */ + libscrypt_PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, 1, B, p * 128 * r); + + /* 2: for i = 0 to p - 1 do */ + for (i = 0; i < p; i++) { + /* 3: B_i <-- MF(B_i, N) */ + smix(&B[i * 128 * r], r, N, V, XY); + } + + /* 5: DK <-- PBKDF2(P, B, 1, dkLen) */ + libscrypt_PBKDF2_SHA256(passwd, passwdlen, B, p * 128 * r, 1, buf, buflen); + + /* Free memory. */ +#ifdef MAP_ANON + if (munmap(V0, 128 * r * N)) + goto err2; +#else + free(V0); +#endif + free(XY0); + free(B0); + + /* Success! */ + return (0); + +err2: + free(XY0); +err1: + free(B0); +err0: + /* Failure! */ + return (-1); +} diff --git a/utils/libscrypt/libscrypt.h b/utils/libscrypt/libscrypt.h new file mode 100644 index 0000000000..3e2390dc93 --- /dev/null +++ b/utils/libscrypt/libscrypt.h @@ -0,0 +1,56 @@ +/*- + */ +#ifndef _CRYPTO_SCRYPT_H_ +#define _CRYPTO_SCRYPT_H_ + + +#include + +#ifdef __cplusplus +extern "C"{ +#endif + +/** + * crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen): + * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r, + * p, buflen) and write the result into buf. The parameters r, p, and buflen + * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32. The parameter N + * must be a power of 2 greater than 1. + * + * libscrypt_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen): + * password; duh + * N: CPU AND RAM cost (first modifier) + * r: RAM Cost + * p: CPU cost (parallelisation) + * In short, N is your main performance modifier. Values of r = 8, p = 1 are + * standard unless you want to modify the CPU/RAM ratio. + * Return 0 on success; or -1 on error. + */ +int libscrypt_scrypt(const uint8_t *, size_t, const uint8_t *, size_t, uint64_t, + uint32_t, uint32_t, /*@out@*/ uint8_t *, size_t); + +/* Converts a series of input parameters to a MCF form for storage */ +int libscrypt_mcf(uint32_t N, uint32_t r, uint32_t p, const char *salt, + const char *hash, char *mcf); + +/* Checks a given MCF against a password */ +int libscrypt_check(char *mcf, const char *password); + +#ifdef __cplusplus +} +#endif + +/* Sane default values */ +#define SCRYPT_HASH_LEN 64 /* This can be user defined - + *but 64 is the reference size + */ +#define SCRYPT_SAFE_N 30 /* This is much higher than you want. It's just + * a blocker for insane defines + */ +#define SCRYPT_SALT_LEN 16 /* This is just a recommended size */ +#define SCRYPT_MCF_LEN 125 /* mcf is 120 byte + nul */ +#define SCRYPT_MCF_ID "$s1" +#define SCRYPT_N 16384 +#define SCRYPT_r 8 +#define SCRYPT_p 16 +#endif /* !_CRYPTO_SCRYPT_H_ */ diff --git a/utils/libscrypt/libscrypt.version b/utils/libscrypt/libscrypt.version new file mode 100644 index 0000000000..d9c66815ce --- /dev/null +++ b/utils/libscrypt/libscrypt.version @@ -0,0 +1,8 @@ +libscrypt { + global: libscrypt_check; +libscrypt_hash; +libscrypt_mcf; +libscrypt_salt_gen; +libscrypt_scrypt; + local: *; +}; diff --git a/utils/libscrypt/sha256.c b/utils/libscrypt/sha256.c new file mode 100644 index 0000000000..5ba988de32 --- /dev/null +++ b/utils/libscrypt/sha256.c @@ -0,0 +1,411 @@ +/*- + * Copyright 2005,2007,2009 Colin Percival + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +#include +#include + +#include "sysendian.h" + +#include "sha256.h" + +/* + * Encode a length len/4 vector of (uint32_t) into a length len vector of + * (unsigned char) in big-endian form. Assumes len is a multiple of 4. + */ +static void +be32enc_vect(unsigned char *dst, const uint32_t *src, size_t len) +{ + size_t i; + + for (i = 0; i < len / 4; i++) + be32enc(dst + i * 4, src[i]); +} + +/* + * Decode a big-endian length len vector of (unsigned char) into a length + * len/4 vector of (uint32_t). Assumes len is a multiple of 4. + */ +static void +be32dec_vect(uint32_t *dst, const unsigned char *src, size_t len) +{ + size_t i; + + for (i = 0; i < len / 4; i++) + dst[i] = be32dec(src + i * 4); +} + +/* Elementary functions used by SHA256 */ +#define Ch(x, y, z) ((x & (y ^ z)) ^ z) +#define Maj(x, y, z) ((x & (y | z)) | (y & z)) +#define SHR(x, n) (x >> n) +#define ROTR(x, n) ((x >> n) | (x << (32 - n))) +#define S0(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22)) +#define S1(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25)) +#define s0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3)) +#define s1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10)) + +/* SHA256 round function */ +#define RND(a, b, c, d, e, f, g, h, k) \ + t0 = h + S1(e) + Ch(e, f, g) + k; \ + t1 = S0(a) + Maj(a, b, c); \ + d += t0; \ + h = t0 + t1; + +/* Adjusted round function for rotating state */ +#define RNDr(S, W, i, k) \ + RND(S[(64 - i) % 8], S[(65 - i) % 8], \ + S[(66 - i) % 8], S[(67 - i) % 8], \ + S[(68 - i) % 8], S[(69 - i) % 8], \ + S[(70 - i) % 8], S[(71 - i) % 8], \ + W[i] + k) + +/* + * SHA256 block compression function. The 256-bit state is transformed via + * the 512-bit input block to produce a new state. + */ +static void +SHA256_Transform(uint32_t * state, const unsigned char block[64]) +{ + uint32_t W[64]; + uint32_t S[8]; + uint32_t t0, t1; + int i; + + /* 1. Prepare message schedule W. */ + be32dec_vect(W, block, 64); + for (i = 16; i < 64; i++) + W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16]; + + /* 2. Initialize working variables. */ + memcpy(S, state, 32); + + /* 3. Mix. */ + RNDr(S, W, 0, 0x428a2f98); + RNDr(S, W, 1, 0x71374491); + RNDr(S, W, 2, 0xb5c0fbcf); + RNDr(S, W, 3, 0xe9b5dba5); + RNDr(S, W, 4, 0x3956c25b); + RNDr(S, W, 5, 0x59f111f1); + RNDr(S, W, 6, 0x923f82a4); + RNDr(S, W, 7, 0xab1c5ed5); + RNDr(S, W, 8, 0xd807aa98); + RNDr(S, W, 9, 0x12835b01); + RNDr(S, W, 10, 0x243185be); + RNDr(S, W, 11, 0x550c7dc3); + RNDr(S, W, 12, 0x72be5d74); + RNDr(S, W, 13, 0x80deb1fe); + RNDr(S, W, 14, 0x9bdc06a7); + RNDr(S, W, 15, 0xc19bf174); + RNDr(S, W, 16, 0xe49b69c1); + RNDr(S, W, 17, 0xefbe4786); + RNDr(S, W, 18, 0x0fc19dc6); + RNDr(S, W, 19, 0x240ca1cc); + RNDr(S, W, 20, 0x2de92c6f); + RNDr(S, W, 21, 0x4a7484aa); + RNDr(S, W, 22, 0x5cb0a9dc); + RNDr(S, W, 23, 0x76f988da); + RNDr(S, W, 24, 0x983e5152); + RNDr(S, W, 25, 0xa831c66d); + RNDr(S, W, 26, 0xb00327c8); + RNDr(S, W, 27, 0xbf597fc7); + RNDr(S, W, 28, 0xc6e00bf3); + RNDr(S, W, 29, 0xd5a79147); + RNDr(S, W, 30, 0x06ca6351); + RNDr(S, W, 31, 0x14292967); + RNDr(S, W, 32, 0x27b70a85); + RNDr(S, W, 33, 0x2e1b2138); + RNDr(S, W, 34, 0x4d2c6dfc); + RNDr(S, W, 35, 0x53380d13); + RNDr(S, W, 36, 0x650a7354); + RNDr(S, W, 37, 0x766a0abb); + RNDr(S, W, 38, 0x81c2c92e); + RNDr(S, W, 39, 0x92722c85); + RNDr(S, W, 40, 0xa2bfe8a1); + RNDr(S, W, 41, 0xa81a664b); + RNDr(S, W, 42, 0xc24b8b70); + RNDr(S, W, 43, 0xc76c51a3); + RNDr(S, W, 44, 0xd192e819); + RNDr(S, W, 45, 0xd6990624); + RNDr(S, W, 46, 0xf40e3585); + RNDr(S, W, 47, 0x106aa070); + RNDr(S, W, 48, 0x19a4c116); + RNDr(S, W, 49, 0x1e376c08); + RNDr(S, W, 50, 0x2748774c); + RNDr(S, W, 51, 0x34b0bcb5); + RNDr(S, W, 52, 0x391c0cb3); + RNDr(S, W, 53, 0x4ed8aa4a); + RNDr(S, W, 54, 0x5b9cca4f); + RNDr(S, W, 55, 0x682e6ff3); + RNDr(S, W, 56, 0x748f82ee); + RNDr(S, W, 57, 0x78a5636f); + RNDr(S, W, 58, 0x84c87814); + RNDr(S, W, 59, 0x8cc70208); + RNDr(S, W, 60, 0x90befffa); + RNDr(S, W, 61, 0xa4506ceb); + RNDr(S, W, 62, 0xbef9a3f7); + RNDr(S, W, 63, 0xc67178f2); + + /* 4. Mix local working variables into global state */ + for (i = 0; i < 8; i++) + state[i] += S[i]; + + /* Clean the stack. */ + memset(W, 0, 256); + memset(S, 0, 32); + t0 = t1 = 0; +} + +static unsigned char PAD[64] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* Add padding and terminating bit-count. */ +static void +SHA256_Pad(SHA256_CTX * ctx) +{ + unsigned char len[8]; + uint32_t r, plen; + + /* + * Convert length to a vector of bytes -- we do this now rather + * than later because the length will change after we pad. + */ + be32enc_vect(len, ctx->count, 8); + + /* Add 1--64 bytes so that the resulting length is 56 mod 64 */ + r = (ctx->count[1] >> 3) & 0x3f; + plen = (r < 56) ? (56 - r) : (120 - r); + libscrypt_SHA256_Update(ctx, PAD, (size_t)plen); + + /* Add the terminating bit-count */ + libscrypt_SHA256_Update(ctx, len, 8); +} + +/* SHA-256 initialization. Begins a SHA-256 operation. */ +void +libscrypt_SHA256_Init(SHA256_CTX * ctx) +{ + + /* Zero bits processed so far */ + ctx->count[0] = ctx->count[1] = 0; + + /* Magic initialization constants */ + ctx->state[0] = 0x6A09E667; + ctx->state[1] = 0xBB67AE85; + ctx->state[2] = 0x3C6EF372; + ctx->state[3] = 0xA54FF53A; + ctx->state[4] = 0x510E527F; + ctx->state[5] = 0x9B05688C; + ctx->state[6] = 0x1F83D9AB; + ctx->state[7] = 0x5BE0CD19; +} + +/* Add bytes into the hash */ +void +libscrypt_SHA256_Update(SHA256_CTX * ctx, const void *in, size_t len) +{ + uint32_t bitlen[2]; + uint32_t r; + const unsigned char *src = in; + + /* Number of bytes left in the buffer from previous updates */ + r = (ctx->count[1] >> 3) & 0x3f; + + /* Convert the length into a number of bits */ + bitlen[1] = ((uint32_t)len) << 3; + bitlen[0] = (uint32_t)(len >> 29); + + /* Update number of bits */ + if ((ctx->count[1] += bitlen[1]) < bitlen[1]) + ctx->count[0]++; + ctx->count[0] += bitlen[0]; + + /* Handle the case where we don't need to perform any transforms */ + if (len < 64 - r) { + memcpy(&ctx->buf[r], src, len); + return; + } + + /* Finish the current block */ + memcpy(&ctx->buf[r], src, 64 - r); + SHA256_Transform(ctx->state, ctx->buf); + src += 64 - r; + len -= 64 - r; + + /* Perform complete blocks */ + while (len >= 64) { + SHA256_Transform(ctx->state, src); + src += 64; + len -= 64; + } + + /* Copy left over data into buffer */ + memcpy(ctx->buf, src, len); +} + +/* + * SHA-256 finalization. Pads the input data, exports the hash value, + * and clears the context state. + */ +void +libscrypt_SHA256_Final(unsigned char digest[32], SHA256_CTX * ctx) +{ + + /* Add padding */ + SHA256_Pad(ctx); + + /* Write the hash */ + be32enc_vect(digest, ctx->state, 32); + + /* Clear the context state */ + memset((void *)ctx, 0, sizeof(*ctx)); +} + +/* Initialize an HMAC-SHA256 operation with the given key. */ +void +libscrypt_HMAC_SHA256_Init(HMAC_SHA256_CTX * ctx, const void * _K, size_t Klen) +{ + unsigned char pad[64]; + unsigned char khash[32]; + const unsigned char * K = _K; + size_t i; + + /* If Klen > 64, the key is really SHA256(K). */ + if (Klen > 64) { + libscrypt_SHA256_Init(&ctx->ictx); + libscrypt_SHA256_Update(&ctx->ictx, K, Klen); + libscrypt_SHA256_Final(khash, &ctx->ictx); + K = khash; + Klen = 32; + } + + /* Inner SHA256 operation is SHA256(K xor [block of 0x36] || data). */ + libscrypt_SHA256_Init(&ctx->ictx); + memset(pad, 0x36, 64); + for (i = 0; i < Klen; i++) + pad[i] ^= K[i]; + libscrypt_SHA256_Update(&ctx->ictx, pad, 64); + + /* Outer SHA256 operation is SHA256(K xor [block of 0x5c] || hash). */ + libscrypt_SHA256_Init(&ctx->octx); + memset(pad, 0x5c, 64); + for (i = 0; i < Klen; i++) + pad[i] ^= K[i]; + libscrypt_SHA256_Update(&ctx->octx, pad, 64); + + /* Clean the stack. */ + memset(khash, 0, 32); +} + +/* Add bytes to the HMAC-SHA256 operation. */ +void +libscrypt_HMAC_SHA256_Update(HMAC_SHA256_CTX * ctx, const void *in, size_t len) +{ + + /* Feed data to the inner SHA256 operation. */ + libscrypt_SHA256_Update(&ctx->ictx, in, len); +} + +/* Finish an HMAC-SHA256 operation. */ +void +libscrypt_HMAC_SHA256_Final(unsigned char digest[32], HMAC_SHA256_CTX * ctx) +{ + unsigned char ihash[32]; + + /* Finish the inner SHA256 operation. */ + libscrypt_SHA256_Final(ihash, &ctx->ictx); + + /* Feed the inner hash to the outer SHA256 operation. */ + libscrypt_SHA256_Update(&ctx->octx, ihash, 32); + + /* Finish the outer SHA256 operation. */ + libscrypt_SHA256_Final(digest, &ctx->octx); + + /* Clean the stack. */ + memset(ihash, 0, 32); +} + +/** + * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen): + * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and + * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1). + */ +void +libscrypt_PBKDF2_SHA256(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt, + size_t saltlen, uint64_t c, uint8_t * buf, size_t dkLen) +{ + HMAC_SHA256_CTX PShctx, hctx; + size_t i; + uint8_t ivec[4]; + uint8_t U[32]; + uint8_t T[32]; + uint64_t j; + int k; + size_t clen; + + /* Compute HMAC state after processing P and S. */ + libscrypt_HMAC_SHA256_Init(&PShctx, passwd, passwdlen); + libscrypt_HMAC_SHA256_Update(&PShctx, salt, saltlen); + + /* Iterate through the blocks. */ + for (i = 0; i * 32 < dkLen; i++) { + /* Generate INT(i + 1). */ + be32enc(ivec, (uint32_t)(i + 1)); + + /* Compute U_1 = PRF(P, S || INT(i)). */ + memcpy(&hctx, &PShctx, sizeof(HMAC_SHA256_CTX)); + libscrypt_HMAC_SHA256_Update(&hctx, ivec, 4); + libscrypt_HMAC_SHA256_Final(U, &hctx); + + /* T_i = U_1 ... */ + memcpy(T, U, 32); + + for (j = 2; j <= c; j++) { + /* Compute U_j. */ + libscrypt_HMAC_SHA256_Init(&hctx, passwd, passwdlen); + libscrypt_HMAC_SHA256_Update(&hctx, U, 32); + libscrypt_HMAC_SHA256_Final(U, &hctx); + + /* ... xor U_j ... */ + for (k = 0; k < 32; k++) + T[k] ^= U[k]; + } + + /* Copy as many bytes as necessary into buf. */ + clen = dkLen - i * 32; + if (clen > 32) + clen = 32; + memcpy(&buf[i * 32], T, clen); + } + + /* Clean PShctx, since we never called _Final on it. */ + memset(&PShctx, 0, sizeof(HMAC_SHA256_CTX)); +} diff --git a/utils/libscrypt/sha256.h b/utils/libscrypt/sha256.h new file mode 100644 index 0000000000..dbf76dbcfd --- /dev/null +++ b/utils/libscrypt/sha256.h @@ -0,0 +1,70 @@ +/*- + * Copyright 2005,2007,2009 Colin Percival + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libmd/sha256.h,v 1.2 2006/01/17 15:35:56 phk Exp $ + */ + +#ifndef _SHA256_H_ +#define _SHA256_H_ + +#include + +#include + +typedef struct libscrypt_SHA256Context { + uint32_t state[8]; + uint32_t count[2]; + unsigned char buf[64]; +} SHA256_CTX; + +typedef struct libscrypt_HMAC_SHA256Context { + SHA256_CTX ictx; + SHA256_CTX octx; +} HMAC_SHA256_CTX; + +void libscrypt_SHA256_Init(/*@out@*/ SHA256_CTX *); +void libscrypt_SHA256_Update(SHA256_CTX *, const void *, size_t); + +/* Original declaration: + * void SHA256_Final(unsigned char [32], SHA256_CTX *); +*/ +void libscrypt_SHA256_Final(/*@out@*/ unsigned char [], SHA256_CTX *); +void libscrypt_HMAC_SHA256_Init(HMAC_SHA256_CTX *, const void *, size_t); +void libscrypt_HMAC_SHA256_Update(HMAC_SHA256_CTX *, const void *, size_t); + +/* Original declaration: + * void HMAC_SHA256_Final(unsigned char [32], HMAC_SHA256_CTX *); +*/ +void libscrypt_HMAC_SHA256_Final(unsigned char [], HMAC_SHA256_CTX *); + +/** + * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen): + * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and + * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1). + */ +void libscrypt_PBKDF2_SHA256(const uint8_t *, size_t, const uint8_t *, size_t, + uint64_t, uint8_t *, size_t); + +#endif /* !_SHA256_H_ */ diff --git a/utils/libscrypt/slowequals.c b/utils/libscrypt/slowequals.c new file mode 100644 index 0000000000..8133b0c8c0 --- /dev/null +++ b/utils/libscrypt/slowequals.c @@ -0,0 +1,26 @@ +#include + +/* Implements a constant time version of strcmp() + * Will return 1 if a and b are equal, 0 if they are not */ +int slow_equals(const char* a, const char* b) +{ + size_t lena, lenb, diff, i; + lena = strlen(a); + lenb = strlen(b); + diff = strlen(a) ^ strlen(b); + + for(i=0; i we have isn't usable. */ +#if !HAVE_DECL_BE64ENC +#undef HAVE_SYS_ENDIAN_H +#endif + +#ifdef HAVE_SYS_ENDIAN_H + +#include + +#else + +#include +#ifdef _MSC_VER + #define INLINE __inline +#else + #define INLINE inline +#endif + +static INLINE uint32_t +be32dec(const void *pp) +{ + const uint8_t *p = (uint8_t const *)pp; + + return ((uint32_t)(p[3]) + ((uint32_t)(p[2]) << 8) + + ((uint32_t)(p[1]) << 16) + ((uint32_t)(p[0]) << 24)); +} + +static INLINE void +be32enc(void *pp, uint32_t x) +{ + uint8_t * p = (uint8_t *)pp; + + p[3] = x & 0xff; + p[2] = (x >> 8) & 0xff; + p[1] = (x >> 16) & 0xff; + p[0] = (x >> 24) & 0xff; +} + +static INLINE uint64_t +be64dec(const void *pp) +{ + const uint8_t *p = (uint8_t const *)pp; + + return ((uint64_t)(p[7]) + ((uint64_t)(p[6]) << 8) + + ((uint64_t)(p[5]) << 16) + ((uint64_t)(p[4]) << 24) + + ((uint64_t)(p[3]) << 32) + ((uint64_t)(p[2]) << 40) + + ((uint64_t)(p[1]) << 48) + ((uint64_t)(p[0]) << 56)); +} + +static INLINE void +be64enc(void *pp, uint64_t x) +{ + uint8_t * p = (uint8_t *)pp; + + p[7] = x & 0xff; + p[6] = (x >> 8) & 0xff; + p[5] = (x >> 16) & 0xff; + p[4] = (x >> 24) & 0xff; + p[3] = (x >> 32) & 0xff; + p[2] = (x >> 40) & 0xff; + p[1] = (x >> 48) & 0xff; + p[0] = (x >> 56) & 0xff; +} + +static INLINE uint32_t +le32dec(const void *pp) +{ + const uint8_t *p = (uint8_t const *)pp; + + return ((uint32_t)(p[0]) + ((uint32_t)(p[1]) << 8) + + ((uint32_t)(p[2]) << 16) + ((uint32_t)(p[3]) << 24)); +} + +static INLINE void +le32enc(void *pp, uint32_t x) +{ + uint8_t * p = (uint8_t *)pp; + + p[0] = x & 0xff; + p[1] = (x >> 8) & 0xff; + p[2] = (x >> 16) & 0xff; + p[3] = (x >> 24) & 0xff; +} + +static INLINE uint64_t +le64dec(const void *pp) +{ + const uint8_t *p = (uint8_t const *)pp; + + return ((uint64_t)(p[0]) + ((uint64_t)(p[1]) << 8) + + ((uint64_t)(p[2]) << 16) + ((uint64_t)(p[3]) << 24) + + ((uint64_t)(p[4]) << 32) + ((uint64_t)(p[5]) << 40) + + ((uint64_t)(p[6]) << 48) + ((uint64_t)(p[7]) << 56)); +} + +static INLINE void +le64enc(void *pp, uint64_t x) +{ + uint8_t * p = (uint8_t *)pp; + + p[0] = x & 0xff; + p[1] = (x >> 8) & 0xff; + p[2] = (x >> 16) & 0xff; + p[3] = (x >> 24) & 0xff; + p[4] = (x >> 32) & 0xff; + p[5] = (x >> 40) & 0xff; + p[6] = (x >> 48) & 0xff; + p[7] = (x >> 56) & 0xff; +} +#endif /* !HAVE_SYS_ENDIAN_H */ + +#endif /* !_SYSENDIAN_H_ */